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개인건가요??  그럼 그 안에 숫자 값들은 왜 이런 값들이 주어진거에요?

 

 

스테이지 만들기 부분에서요

   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 을 준거에요??