총 게시물 54건, 최근 0 건 안내 RSS 글쓰기
이전글  다음글  목록 글쓰기
[독자 Q&A]

벽돌 깨기 게임에서요 스테이지 만드는 부분이랑 블록 부분 어떻게 돌아가는지 설명좀해주세요

글쓴이 : 미나나113                   날짜 : 2012-06-07 (목) 19:51 조회 : 11870
글주소 : http://www.androidside.com/820/162
 
  벽돌깨기게임 이벤트 모비
벽돌깨기게임 이벤트, 프리미엄 게임쿠폰 제공, 한정판 레어아이템 이벤트
www.mobi.co.kr
  플레쉬 컴스쿨닷컴
플레쉬 인강만으로 합격가능, 단기완성, 무한반복 전 강좌 스마트폰 학습가능
www.컴스쿨.com
  SBS아카데미컴퓨터학원송강인
플레쉬방학특강단기속성과정, 방학할인이벤트최대40%할인, 강남역연결편리한위치
sbsartcenter.net
신청하기


public class MyGameView extends SurfaceView implements Callback {
 GameThread    mThread;
 SurfaceHolder mHolder;
 Context    mContext;
 final int LEFT = 1;
 final int RIGHT = 2;
 final int STOP = 3;
 
 static int B_width;  // 블록의 폭
 static int B_height; // 블록의 높이
 static int M_left;  // 좌측 여백
 static int M_top;  // 상단 여백
 
 //-------------------------------------
 //  생성자
 //-------------------------------------
 public MyGameView(Context context, AttributeSet attrs) {
  super(context, attrs);
  SurfaceHolder holder = getHolder();
  holder.addCallback(this);
  mHolder = holder;  // holder와 Context 보존
  mContext = context;
  mThread = new GameThread(holder, context);
  
  setFocusable(true);
 }
 //-------------------------------------
    //  SurfaceView가 생성될 때 실행되는 부분
    //-------------------------------------
 public void surfaceCreated(SurfaceHolder holder) {
  mThread.start();
 }
 //-------------------------------------
    //  SurfaceView가 바뀔 때 실행되는 부분
    //-------------------------------------
 public void surfaceChanged(SurfaceHolder arg0, int format, int width, int height) {
 }
 //-------------------------------------
    //  SurfaceView가 해제될 때 실행되는 부분
    //-------------------------------------
 public void surfaceDestroyed(SurfaceHolder holder) {
  boolean done = true;
     while (done) {
      try {
       mThread.join();           // 스레드가 현재 step을 끝낼 때 까지 대기
       done = false;
    } catch (InterruptedException e) {  // 인터럽트 신호가 오면?  
     // 그 신호 무시 - 아무것도 않음
    }
     } // while
 }
 
 //-------------------------------------
 //  스레드 완전 정지
 //-------------------------------------
 public void StopGame() {
  mThread.StopThread();
 }
 //-------------------------------------
 //  스레드 일시 정지
 //-------------------------------------
 public void PauseGame() {
  mThread.PauseNResume(true);
 }
 //-------------------------------------
 //  스레드 재기동
 //-------------------------------------
 public void ResumeGame() {
  mThread.PauseNResume(false);
 }
 //-------------------------------------
 //  게임 초기화
 //-------------------------------------
 public void RestartGame() {
  mThread.StopThread();  // 스레드 중지
  // 현재의 스레드를 비우고 다시 생성
     mThread = null;  
  mThread = new GameThread(mHolder, mContext);
  mThread.start();
 }
//----------------------------------------------------------------
 
 //-------------------------------------
 //  GameThread Class
 //-------------------------------------
 class GameThread extends Thread {
  SurfaceHolder mHolder;   // SurfaceHolder를 저장할 변수
  Context mContext;
  boolean canRun = true;   // 스레드 제어용
  boolean isWait = false;
  int width, height;    // 화면의 크기
  
  final int STAGE_COUNTER = 4; // 전체 스테이지 갯수
  int ballCnt = 4;    // 볼의 갯수(0~5)
  int stgNum = 0;     // 스테이지 번호
  int tot = 0;     // 득점 합계
  int score = 0;     // 격파한 블록 갯수
  int sx[] = {-3, -2, 2, 3};  // 패들에 충돌 후의 볼의 반사 방향을 바꿈
  Random rnd = new Random();  // 위의 처리를 하기 위한 난수
  Paint paint = new Paint();  // 점수 표시용
  Bitmap imgBack;     // 배경
  Bitmap imgSball;    // 남은 공 갯수 표시용
  
  ArrayList<Block> mBlock = new ArrayList<Block>(); // 블록
  Ball   mBall;  // 볼
  Paddle mPaddle;  // 패들       
   
  float Stage[][][] = {  // x, y, 블록번호
  {  
   {0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, {4, 0, 0},
   {0, 1, 0}, {1, 1, 1}, {2, 1, 1}, {3, 1, 1}, {4, 1, 0},
   {0, 2, 0}, {1, 2, 1}, {2, 2, 2}, {3, 2, 1}, {4, 2, 0},
   {0, 3, 0}, {1, 3, 1}, {2, 3, 2}, {3, 3, 1}, {4, 3, 0},
   {0, 4, 0}, {1, 4, 1}, {2, 4, 1}, {3, 4, 1}, {4, 4, 0},
   {0, 5, 0}, {1, 5, 0}, {2, 5, 0}, {3, 5, 0}, {4, 5, 0}
  }, 
  
  { {1.5f, 0, 0}, {2.5f, 0, 0},
   {1, 1, 0},    {2, 1, 1},    {3, 1, 0},
   {0.5f, 2, 0}, {1.5f, 2, 1}, {2.5f, 2, 1}, {3.5f, 2, 0},
   {0, 3, 0},    {1, 3, 1},    {2, 3, 2},    {3, 3, 1},    {4, 3, 0},
   {0.5f, 4, 0}, {1.5f, 4, 1}, {2.5f, 4, 1}, {3.5f, 4, 0},
   {1, 5, 0},    {2, 5, 1},    {3, 5, 0},
   {1.5f, 6, 0}, {2.5f, 6, 0} 
    }, 
    { {-0.5f, 0, 0}, {0.5f, 0, 0}, {1.5f, 0, 0}, {2.5f, 0, 0}, {3.5f, 0, 0}, {4.5f, 0, 0},
     {-0.5f, 1, 0}, {4.5f, 1, 0},
     {-0.5f, 2, 0}, {1, 2, 1}, {2, 2, 1}, {3, 2, 1}, {4.5f, 2, 0},
     {-0.5f, 3, 0}, {1, 3, 1}, {2, 3, 2}, {3, 3, 1}, {4.5f, 3, 0},
     {-0.5f, 4, 0}, {1, 4, 1}, {2, 4, 1}, {3, 4, 1}, {4.5f, 4, 0},
     {-0.5f, 5, 0}, {4.5f, 5, 0},
      {-0.5f, 6, 0}, {0.5f, 6, 0}, {1.5f, 6, 0}, {2.5f, 6, 0}, {3.5f, 6, 0}, {4.5f, 6, 0},
    },
    
    { {-0.5f, 0, 0}, {0.5f, 0, 0}, {1.5f, 0, 0}, {2.5f, 0, 0}, {3.5f, 0, 0}, {4.5f, 0, 0},
   {0, 1, 0},     {1, 1, 1},    {2, 1, 1},    {3, 1, 1},    {4, 1, 0},
   {0.5f, 2, 0}, {1.5f, 2, 1}, {2.5f, 2, 1},  {3.5f, 2, 0},
   {1, 3, 0},    {2, 3, 0},    {3, 3, 0},
   {1.5f, 4, 2}, {2.5f, 4, 2},
   {1, 5, 0},    {2, 5, 0},    {3, 5, 0},
   {0.5f, 6, 0}, {1.5f, 6, 1}, {2.5f, 6, 1},  {3.5f, 6, 0},
   {0, 7, 0},     {1, 7, 1},    {2, 7, 1},    {3, 7, 1},    {4, 7, 0},
   {-0.5f, 8, 0}, {0.5f, 8, 0}, {1.5f, 8, 0}, {2.5f, 8, 0}, {3.5f, 8, 0}, {4.5f, 8, 0},
    } 
  };
   
  //-------------------------------------
  //  생성자
  //-------------------------------------
  public GameThread(SurfaceHolder holder, Context context) {
   mHolder = holder;     // SurfaceHolder 보존
   mContext = context;
   
   Display display = ((WindowManager) context.getSystemService (Context.WINDOW_SERVICE)).getDefaultDisplay();
   width = display.getWidth();   // View의 가로 폭
   height = display.getHeight() - 50;  // View의 세로 높이
   InitGame();
   MakeStage();
  }
  //-------------------------------------
  //  게임 초기화
  //-------------------------------------
  public void InitGame() {
   B_width = width / 6;     // 블록의 폭
   B_height = B_width / 2;     // 블록의 폭
   M_left = (width - B_width * 5) / 2;  // 왼쪽 여백
   M_top = B_width * 4 / 5;    // 상단 여백
   mPaddle = new Paddle(mContext, width / 2, height - B_height, width);
   mBall = new Ball(mContext, width / 2, mPaddle.y - 17, width, height);
   
   paint.setAntiAlias(true);
   paint.setColor(Color.WHITE);
   paint.setTextSize(15);
   
   // 남은 볼 갯수 표시용
   imgSball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
   imgSball = Bitmap.createScaledBitmap(imgSball, 10, 14, false);
  }
  //-------------------------------------
  //  Stage 만들기
  //-------------------------------------
  public void MakeStage() {
   for (int i = 0; i < Stage[stgNum].length; i++)
    mBlock.add(new Block(mContext, Stage[stgNum][i][0], Stage[stgNum][i][1], Stage[stgNum][i][2]));
   ResetPosition();   // 패들과 볼을 화면 중심으로 이동
   mBall.sy = -(4 + stgNum); // 스테이지마다 1씩 속도 증가  
   
   // 배경
   imgBack = BitmapFactory.decodeResource(getResources(), R.drawable.back0 + stgNum);
   imgBack = Bitmap.createScaledBitmap(imgBack, width, height, false);
  }
  //-------------------------------------
  //  공과 패들을 초기 위치로 이동 - 공을 잃은 후
  //-------------------------------------
  public void ResetPosition() {
   mPaddle.x = width / 2;
   mPaddle.y = height - B_height;
   mPaddle.sx = 0;
   mBall.x = width / 2;
   mBall.y = mPaddle.y - 17;
   mBall.sy = -Math.abs(mBall.sy);
   mBall.isMove = false;
  }
  //-------------------------------------
  //  패들 이동 - Key Event에서 호출
  //-------------------------------------
  public void MovePaddle(int direction) {
   switch (direction) {
   case LEFT :
    mPaddle.sx = -4;
    break;
   case RIGHT :
    mPaddle.sx = 4;
    break;
   case STOP :
    mPaddle.sx = 0;
   }
  }
  
  //-------------------------------------
  //  Ball 발사  - Key Event에서 호출
  //-------------------------------------
  public void ShootBall() {
   mBall.isMove = true;
  }
  
  //-------------------------------------
  //  Ball과 패들 이동 - run()에서 호출
  //-------------------------------------
  public void MoveBall() {
   mPaddle.Move();
   if (mBall.isMove == false) // 초기 모드는
    mBall.x = mPaddle.x; // 패들과 볼이 같이 이동
   if (mBall.Move() == false) {
    ballCnt--;
    if (ballCnt < 0) {  // 볼을 모두 잃으면 게임 오버
     GameOver();
     return;
    }
    ResetPosition();  // 패들, 공 초기 위치로
   }
  }
  //-------------------------------------
  //  충돌 판정 - run()에서 호출
  //-------------------------------------
  public void CheckCollision() {
   if (mBlock.size() == 0) {   // 이 판을 클리어 했으면
    stgNum++;      // 다음 스테이지로
    if (stgNum >= STAGE_COUNTER) // 스테이지 끝은 처음 스테이지
     stgNum = 0;
    MakeStage();     // 새로운 스테이지 만들기
    return;
   }
   // 패들과 충돌
   if (Math.abs(mBall.x - mPaddle.x) <= mPaddle.pw
     && mBall.y >= (mPaddle.y - 17) && mBall.y < mPaddle.y) {
    mBall.sx = sx[rnd.nextInt(4)];  // 난수로 각도 지정
    mBall.sy = -Math.abs(mBall.sy);  // 무조건 반사
   }
   
   // 블록과 충돌
   for (Block tmp : mBlock) {
    // 충돌 없음
    if (mBall.x + mBall.bw < tmp.x1 || mBall.x - mBall.bw > tmp.x2  
      || mBall.y + mBall.bw < tmp.y1 || mBall.y - mBall.bw > tmp.y2) {
     continue;
    } 
    // 양쪽 벽과의 충돌인지 판정
    if (tmp.x1 - mBall.x >= mBall.bw || mBall.x - tmp.x2 >= mBall.bw)
     mBall.sx = - mBall.sx;
    else           // 상하 충돌
     mBall.sy = - mBall.sy;
    tot += tmp.score;        // 득점
    score++;
    mBlock.remove(tmp);        // 블록 제거
    break;
   }
  }
  //-------------------------------------
  //  Canvas에 그리기 - run()에서 호출
  //-------------------------------------
  public void DrawCharacters(Canvas canvas) {
   // 배경
   canvas.drawBitmap(imgBack, 0, 0, null);
   // 남은 공 수
   for (int i = 0; i <= ballCnt; i++)
    canvas.drawBitmap(imgSball, i * 12 + 5, height - 20, null);
   // 블록
   for (Block tmp : mBlock)
    canvas.drawBitmap(tmp.imgBlk, tmp.x1, tmp.y1, null);
   // Ball
   canvas.drawBitmap(mBall.imgBall, mBall.x - mBall.bw, mBall.y- mBall.bh, null);
   // Paddle
   canvas.drawBitmap(mPaddle.imgPdl, mPaddle.x - mPaddle.pw , mPaddle.y - mPaddle.ph, null);
   // 점수
   canvas.drawText("Stage" + stgNum, 5, 18, paint);
   canvas.drawText("블록 : " + score, width / 2 - 40, 18, paint);
   canvas.drawText("득점 : " + tot, width - 80, 18, paint);
  }
  
  //-------------------------------------
  //  Game Over
  //-------------------------------------
  private void GameOver() {
   // 게임 오버는 여기에서 처리힌다
   // 아직 게임 오버 없음
   ballCnt = 4; // 볼의 갯수를 다시 4개로...
  }
  
  //-------------------------------------
  //  스레드 본체
  //-------------------------------------
  public void run() {
   Canvas canvas = null;      // canvas를 만든다
   while (canRun) {
    canvas = mHolder.lockCanvas();  // canvas를 잠그고 버퍼 할당
    try {
     synchronized (mHolder) {  // 동기화 유지
      MoveBall();     // 볼 이동하고
      CheckCollision();   // 충돌 판정 후
      DrawCharacters(canvas);  // Canvas에 그리기
     }
    } finally {       // 버퍼 작업이 끝나면
     if (canvas != null)    // 버퍼의 내용을 View에 전송
      mHolder.unlockCanvasAndPost(canvas);
    } // try
    // 스레드 일시 정지
    synchronized (this) {
              if (isWait)    // Pause 모드이면
               try {
                wait();   // 스레드 대기
               } catch (Exception e) {
       // nothing
      }
       } // sync
    
   } // while
  } // run
 
  //-------------------------------------
  //  스레드 완전 정지
  //-------------------------------------
  public void StopThread() {
   canRun = false;
         synchronized (this) {
          this.notify();
   }
  }
  
  //-------------------------------------
  //  스레드 일시정지 / 재기동
  //-------------------------------------
  public void PauseNResume(boolean wait) {
   isWait = wait;
         synchronized (this) {
          this.notify();
   }
  }
  
 } // GameThread 끝
 //-------------------------------------
 //  onKeyDown
 //-------------------------------------
 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
  synchronized (mHolder) {
   if (event.getAction() == KeyEvent.ACTION_DOWN) {
    switch (keyCode) {
    case KeyEvent.KEYCODE_DPAD_LEFT:
     mThread.MovePaddle(LEFT);  // 패들을 왼쪽으로
     break;
    case KeyEvent.KEYCODE_DPAD_RIGHT:
     mThread.MovePaddle(RIGHT);  // 패들을 오른쪽으로
     break;
    case KeyEvent.KEYCODE_DPAD_DOWN:
     mThread.MovePaddle(STOP);  // 패들 정지
     break;
    case KeyEvent.KEYCODE_DPAD_UP:  // 볼 발사
     mThread.ShootBall();
    }
   }  
   return super.onKeyDown(keyCode, event);
  } // sync
 } // onKeyDown
} // SurfaceView
 
 
일단 코드 구요~
float Stage[][][] = { }  이 부분에 많은 배열값 들이 있는데요 왜 이런 값을 줬으며 4개 의 배열이 선언 되어 있는거에요??
스테이지는 4개 니깐 4개인건가요??  그럼 그 안에 숫자 값들은 0~9까지 많은 숫자 중에서 왜 이런 값들이 주어진거에요?
주석으로 x, y 블록 번호 라고 되어있는데 책에도 자세한 설명은 없어서요 ㅠㅠ
 
 
스테이지 만들기 부분에서요
   for (int i = 0; i < Stage[stgNum].length; i++)
    mBlock.add(new Block(mContext, Stage[stgNum][i][0], Stage[stgNum][i][1], Stage[stgNum][i][2]));
 이 부분 돌아가는 해석좀 도와주세요 ㅠㅠ
 
 
  int sx[] = {-3, -2, 2, 3};  // 패들에 충돌 후의 볼의 반사 방향을 바꿈
이부분에서요 볼이 패들에 충돌후 볼의 반사 방향을 바꾸는 것에서 값은 또 왜 저렇게 -3, -2 ,2 , 3 을 준거에요??




추천/비추천 클릭하면 추천받으신 분, 추천하신 분 모두에게 포인트가 지급됩니다.

 
 
몽쉐루루 2012-06-28 (목) 18:39
이 소스를 어디에다가 넣으면 되는 건가요?
댓글주소
 
 
빈스한 2012-11-13 (화) 17:24
이거 자바 소스인거 맞죠?ㅠㅠ
댓글주소
 
 
이카루스031 2015-05-06 (수) 17:47
잘 읽고 갑니다~
댓글주소
이전글  다음글  목록 글쓰기

총 게시물 54건, 최근 0 건 안내 RSS
번호 분류 제목 글쓴이 날짜 조회
54 독자 Q&A  캐릭터 이동방향과 속도값 구하기 2 뚱이괴물 04-01 4822
53 독자 Q&A  6장 슬라이딩 퍼즐 질문입니다 2 쏘드라가쏜다 11-05 4383
52 독자 Q&A  Chapter 4 초원위의 용 2 잉여잉간 03-19 5240
51 독자 Q&A  7장 슈팅게임 비행기 터치로 이동방법 3 슈퍼다니엘 02-13 6422
50 정오표  3쇄 페이지 283 / 페이지 288 오탈자 1 Mechanic 02-11 4613
49 독자 Q&A  스타워즈 슈팅게임 게임속도를 느리게 할수… 2 브릿지 11-18 6497
48 자유  안녕하세요 unity3d 메인메뉴를 만들려고해요 1 맹꽁이조으다 10-25 6339
47 독자 Q&A  Ch 2. 터치로 캐릭터 이동방향 변경하기 관련 … 2 redriver 08-06 7272
46 독자 Q&A  질문이요! 이상합니다!. 1 몽쉐루루 06-28 6677
45 독자 Q&A  getContext, getHolder 1 대구촌동네 06-13 7910
44 독자 Q&A  벽돌 깨기 게임에서요 스테이지 만드는 부분… 3 미나나113 06-07 11871
43 독자 Q&A  짝맞추기 게임 ㅜ.ㅜ 3 맘순이 05-11 11148
42 독자 Q&A  6장 슬라이딩 퍼즐 궁금한게 있어서요. 1 카라아이즈 03-30 7634
41 독자 Q&A  챕터3 풍선터뜨리기... 2 박건휘 03-26 8261
40 독자 Q&A  게임 개발편 제2장 Project_12 질문입니다. 2 세이크라인 03-22 7851
39 독자 Q&A  챕터5, 배경 스크롤링 문의드립니다. 2 실베스테인 03-17 6981
38 독자 Q&A  Chapter 4 _ project_2 초원위의 용 1 Conu 03-04 7009
37 독자 Q&A  책을 읽다가 궁금한게 생겨서 질문 드려요. 4 yamma 02-28 6971
36 정오표  2쇄 page 8 1 전종욱 01-17 7481
35 독자 Q&A  6장 퍼즐 게임 질문입니다 1 무영기사 01-05 9337
 1  2  3  맨끝
 


Copyright ⓒ www.androidside.com. All rights reserved.
채팅 권한: 글쓰기 1개
2레벨 이상만 대화 가능
공개 채팅: 평일 !(9시 ~ 17시),토,일
안사2 변경사항 보러가기 챗방이 잘 안보이면 크롬에서 접속해주세요
챗방 숨기기 |  챗방 보이기