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

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

글쓴이 : 미나나113                   날짜 : 2012-06-07 (목) 19:51 조회 : 12221
글주소 : http://www.androidside.com/820/162
 
  벽돌깨기게임 이벤트 모비
벽돌깨기게임 이벤트, 프리미엄 게임쿠폰 제공, 한정판 레어아이템 이벤트
www.mobi.co.kr
  FLASH전문 플래시온
당근송 제작사, 스토리텔링 애니메이션, FLASH게임 전문, 저렴한 제작 즉시상담
www.flashon.co.kr
  서울게임아카데미
추천게임학원, 2018년 한국 소비자만족지수 1위, 고용노동부국비지원, 수강료조회
www.seoulgame.co.kr
신청하기


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 5098
53 독자 Q&A  6장 슬라이딩 퍼즐 질문입니다 2 쏘드라가쏜다 11-05 4574
52 독자 Q&A  Chapter 4 초원위의 용 2 잉여잉간 03-19 5417
51 독자 Q&A  7장 슈팅게임 비행기 터치로 이동방법 3 슈퍼다니엘 02-13 6625
50 정오표  3쇄 페이지 283 / 페이지 288 오탈자 1 Mechanic 02-11 4731
49 독자 Q&A  스타워즈 슈팅게임 게임속도를 느리게 할수… 2 브릿지 11-18 6662
48 자유  안녕하세요 unity3d 메인메뉴를 만들려고해요 1 맹꽁이조으다 10-25 6467
47 독자 Q&A  Ch 2. 터치로 캐릭터 이동방향 변경하기 관련 … 2 redriver 08-06 7488
46 독자 Q&A  질문이요! 이상합니다!. 1 몽쉐루루 06-28 6802
45 독자 Q&A  getContext, getHolder 1 대구촌동네 06-13 8092
44 독자 Q&A  벽돌 깨기 게임에서요 스테이지 만드는 부분… 3 미나나113 06-07 12222
43 독자 Q&A  짝맞추기 게임 ㅜ.ㅜ 3 맘순이 05-11 11439
42 독자 Q&A  6장 슬라이딩 퍼즐 궁금한게 있어서요. 1 카라아이즈 03-30 7832
41 독자 Q&A  챕터3 풍선터뜨리기... 2 박건휘 03-26 8443
40 독자 Q&A  게임 개발편 제2장 Project_12 질문입니다. 2 세이크라인 03-22 8013
39 독자 Q&A  챕터5, 배경 스크롤링 문의드립니다. 2 실베스테인 03-17 7146
38 독자 Q&A  Chapter 4 _ project_2 초원위의 용 1 Conu 03-04 7220
37 독자 Q&A  책을 읽다가 궁금한게 생겨서 질문 드려요. 4 yamma 02-28 7104
36 정오표  2쇄 page 8 1 전종욱 01-17 7611
35 독자 Q&A  6장 퍼즐 게임 질문입니다 1 무영기사 01-05 9537
 1  2  3  맨끝
 


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