안드로이드 개발 질문/답변
(글 수 45,052)
패들과 볼 그리고 블록 으로 패들이 공을 튕기면서 블록을 맞추어 모든 블록을 깨는 고전 게임인데요
책을 구입해서 예제 코드를 수정 해볼려고하는데 잘안되네요 ...
모든 블록이 한방에 다 깨지는데 .. 두방에 때기게 하는 블록을 만들고 싶거든요??
일단 모든 코드 구요.... 빨간색 글씨로 된 부분만 좀 봐주세요 ^^
-----------------------block.java ---------------파일 입니다----------
package com.Project6;
import android.content.*;
import android.graphics.*;
import android.graphics.*;
//-----------------------------
// Block
//-----------------------------
class Block {
public int x1, y1, x2, y2, score; // 블록 좌표, 점수
public Bitmap imgBlk; // 이미지
public int cnt=0; // 블록의 카운터를 주기 위한 변수
//-----------------------------
// 생성자 (Constructor)
//-----------------------------
public Block(Context context, float x, float y, float num , int b_cnt ) {
cnt = b_cnt; //매개인자로 전달 받은 값 , 한방에 안깨지게하는 블록의 생명력과같은
x1 = (int) (MyGameView.M_left + x * MyGameView.B_width);
y1 = (int) (MyGameView.M_top + y * MyGameView.B_height);
x2 = x1 + MyGameView.B_width - 3;
y2 = y1 + MyGameView.B_height - 3;
score = (int) (num + 1) * 50;
imgBlk = BitmapFactory.decodeResource(context.getResources(), R.drawable.k0 + (int) num);
imgBlk = Bitmap.createScaledBitmap(imgBlk, MyGameView.B_width, MyGameView.B_height, true);
}
}
//-----------------------------------------------------
//-----------------------------
// Ball
//-----------------------------
class Ball {
public int x, y, bw, bh; // 공의 위치, 크기
public int sx, sy; // 공의 속도
public boolean isMove = false; // 이동중인가
public Bitmap imgBall; // 이미지
y2 = y1 + MyGameView.B_height - 3;
score = (int) (num + 1) * 50;
imgBlk = BitmapFactory.decodeResource(context.getResources(), R.drawable.k0 + (int) num);
imgBlk = Bitmap.createScaledBitmap(imgBlk, MyGameView.B_width, MyGameView.B_height, true);
}
}
//-----------------------------------------------------
//-----------------------------
// Ball
//-----------------------------
class Ball {
public int x, y, bw, bh; // 공의 위치, 크기
public int sx, sy; // 공의 속도
public boolean isMove = false; // 이동중인가
public Bitmap imgBall; // 이미지
private int width, height;
//-----------------------------
// 생성자 (Constructor)
//-----------------------------
public Ball(Context context, int _x, int _y, int _width, int _height) {
x = _x;
y = _y;
width = _width;
height = _height;
sx = 3; // 초기 속도
sy = -4;
imgBall = BitmapFactory.decodeResource(context.getResources(), R.drawable.ball);
bw = imgBall.getWidth() / 2;
bh = bw;
}
//-----------------------------
// Move
//-----------------------------
public boolean Move() {
if (isMove == false) return true;
x += sx;
if (x < bw || x > width - bw) { // 좌우 벽
sx = -sx;
x += sx;
}
y += sy;
if (y >= height + bh) return false; // 바닥
if (y < bh) { // 천정
sy = -sy;
y += sy;
}
return true;
}
}
//-----------------------------------------------------
//-----------------------------
// 생성자 (Constructor)
//-----------------------------
public Ball(Context context, int _x, int _y, int _width, int _height) {
x = _x;
y = _y;
width = _width;
height = _height;
sx = 3; // 초기 속도
sy = -4;
imgBall = BitmapFactory.decodeResource(context.getResources(), R.drawable.ball);
bw = imgBall.getWidth() / 2;
bh = bw;
}
//-----------------------------
// Move
//-----------------------------
public boolean Move() {
if (isMove == false) return true;
x += sx;
if (x < bw || x > width - bw) { // 좌우 벽
sx = -sx;
x += sx;
}
y += sy;
if (y >= height + bh) return false; // 바닥
if (y < bh) { // 천정
sy = -sy;
y += sy;
}
return true;
}
}
//-----------------------------------------------------
//-----------------------------
// 패들
//-----------------------------
class Paddle {
public int x, y, pw, ph; // 좌표
public Bitmap imgPdl; // 이미지
public int sx;
// 패들
//-----------------------------
class Paddle {
public int x, y, pw, ph; // 좌표
public Bitmap imgPdl; // 이미지
public int sx;
private int width;
//-----------------------------
// 생성자 (Constructor)
//-----------------------------
public Paddle(Context context, int _x, int _y, int _width) {
x = _x; // 패들 현재 좌표
y = _y;
width = _width;
pw = MyGameView.B_width * 4 / 6; // 패들 폭 - 블록의 4/3크기
ph = MyGameView.B_width / 6; // 패들 높이 - 블록 높이 1/3
//-----------------------------
// 생성자 (Constructor)
//-----------------------------
public Paddle(Context context, int _x, int _y, int _width) {
x = _x; // 패들 현재 좌표
y = _y;
width = _width;
pw = MyGameView.B_width * 4 / 6; // 패들 폭 - 블록의 4/3크기
ph = MyGameView.B_width / 6; // 패들 높이 - 블록 높이 1/3
imgPdl = BitmapFactory.decodeResource(context.getResources(), R.drawable.paddle);
imgPdl = Bitmap.createScaledBitmap(imgPdl, pw * 2, ph * 2, true);
}
//-----------------------------
// Move
//-----------------------------
public void Move() {
x += sx;
if (x < pw || x > width - pw ) sx = 0;
}
}
imgPdl = Bitmap.createScaledBitmap(imgPdl, pw * 2, ph * 2, true);
}
//-----------------------------
// Move
//-----------------------------
public void Move() {
x += sx;
if (x < pw || x > width - pw ) sx = 0;
}
}
=---------------------MyGameView.java----------------파일입니다------
import java.util.*;
import android.content.*;
import android.graphics.*;
import android.util.*;
import android.view.*;
import android.view.SurfaceHolder.Callback;
import android.graphics.*;
import android.util.*;
import android.view.*;
import android.view.SurfaceHolder.Callback;
public class MyGameView extends SurfaceView implements Callback {
GameThread mThread;
SurfaceHolder mHolder;
Context mContext;
GameThread mThread;
SurfaceHolder mHolder;
Context mContext;
Block bk;
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; // 상단 여백
static Paddle mPaddle;
//-------------------------------------
// 생성자
//-------------------------------------
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);
}
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; // 상단 여백
static Paddle mPaddle;
//-------------------------------------
// 생성자
//-------------------------------------
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 surfaceCreated(SurfaceHolder holder) {
mThread.start();
}
//-------------------------------------
// SurfaceView가 바뀔 때 실행되는 부분
//-------------------------------------
public void surfaceChanged(SurfaceHolder arg0, int format, int width, int height) {
}
// 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(); // 스레드 중지
// 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; // 볼
// // 패들
float Stage[][][][]= { // x, y, 블록번호 //cnt 값을 넣기위해 [] 하나더 추가 했습니다
{
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; // 볼
// // 패들
float Stage[][][][]= { // x, y, 블록번호 //cnt 값을 넣기위해 [] 하나더 추가 했습니다
{
{
//먼저 첫번째 스테이지 경우에만 적용하기 위하여 4번째 값(블록의 cnt 값)을 추가했습니다
{0, 0, 0, 1}, {1, 0, 0, 1 }, {2, 0, 0, 1}, {3, 0, 0, 1}, {4, 0, 0, 1},
{0, 1, 0, 1}, {1, 1, 1, 1}, {2, 1, 1, 1}, {3, 1, 1, 1}, {4, 1, 0, 1},
{0, 2, 0, 1}, {1, 2, 1, 1}, {2, 2, 2, 1}, {3, 2, 1, 1}, {4, 2, 0, 1},
{0, 3, 0, 1}, {1, 3, 1, 1}, {2, 3, 2, 1}, {3, 3, 1, 1}, {4, 3, 0, 1},
{0, 4, 0, 1}, {1, 4, 1, 1}, {2, 4, 1, 1}, {3, 4, 1, 1}, {4, 4, 0, 1},
{0, 5, 0, 2}, {1, 5, 0, 2}, {2, 5, 0, 2}, {3, 5, 0, 2}, {4, 5, 0, 2}
},
{ {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}
},
//먼저 첫번째 스테이지 경우에만 적용하기 위하여 4번째 값(블록의 cnt 값)을 추가했습니다
{0, 0, 0, 1}, {1, 0, 0, 1 }, {2, 0, 0, 1}, {3, 0, 0, 1}, {4, 0, 0, 1},
{0, 1, 0, 1}, {1, 1, 1, 1}, {2, 1, 1, 1}, {3, 1, 1, 1}, {4, 1, 0, 1},
{0, 2, 0, 1}, {1, 2, 1, 1}, {2, 2, 2, 1}, {3, 2, 1, 1}, {4, 2, 0, 1},
{0, 3, 0, 1}, {1, 3, 1, 1}, {2, 3, 2, 1}, {3, 3, 1, 1}, {4, 3, 0, 1},
{0, 4, 0, 1}, {1, 4, 1, 1}, {2, 4, 1, 1}, {3, 4, 1, 1}, {4, 4, 0, 1},
{0, 5, 0, 2}, {1, 5, 0, 2}, {2, 5, 0, 2}, {3, 5, 0, 2}, {4, 5, 0, 2}
},
{ {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의 세로 높이
{-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; // 상단 여백
ballCnt = 4;
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; // 상단 여백
ballCnt = 4;
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); //createScaledBitmap 크기 조절
}
//-------------------------------------
// Stage 만들기
//-------------------------------------
public void MakeStage() {
for (int i = 0; i < Stage[stgNum].length; i++)
mBlock.add(new Block(mContext, Stage[stgNum][i][0][bk.cnt], Stage[stgNum][i][1][bk.cnt], Stage[stgNum][i][2][bk.cnt])); //블록이 한방에 안깨지게 하기 위해 cnt 값을 위해 [] 하나더 추가했습니다 이부분 에러 나거든요 ㅠ x 표시 뜨면서.. 이부분 은 솔직히 어떻게 돌아가는지 잘 모르겟어요
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); //createScaledBitmap 크기 조절
}
//-------------------------------------
// Stage 만들기
//-------------------------------------
public void MakeStage() {
for (int i = 0; i < Stage[stgNum].length; i++)
mBlock.add(new Block(mContext, Stage[stgNum][i][0][bk.cnt], Stage[stgNum][i][1][bk.cnt], Stage[stgNum][i][2][bk.cnt])); //블록이 한방에 안깨지게 하기 위해 cnt 값을 위해 [] 하나더 추가했습니다 이부분 에러 나거든요 ㅠ x 표시 뜨면서.. 이부분 은 솔직히 어떻게 돌아가는지 잘 모르겟어요
도와주세요
ResetPosition(); // 패들과 볼을 화면 중심으로 이동
mBall.sy = -(4 + stgNum); // 스테이지마다 1씩 속도 증가
// 배경
imgBack = BitmapFactory.decodeResource(getResources(), R.drawable.back4 + stgNum);
imgBack = Bitmap.createScaledBitmap(imgBack, width, height, false);
}
//-------------------------------------
// 공과 패들을 초기 위치로 이동 - 공을 잃은 후
//-------------------------------------
public void ResetPosition() {
mPaddle.x = width / 2;
mPaddle.y = height - B_height;
mPaddle.sx = 0;
ResetPosition(); // 패들과 볼을 화면 중심으로 이동
mBall.sy = -(4 + stgNum); // 스테이지마다 1씩 속도 증가
// 배경
imgBack = BitmapFactory.decodeResource(getResources(), R.drawable.back4 + 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){
bk.cnt--; //cnt 카운터를 --
mBall.sx = - mBall.sx;
}
else
bk.cnt--; // cnt 카운터를 --
mBall.sy = - mBall.sy; // 상하 충돌
tot += tmp.score; // 득점
score++;
if(bk.cnt == 0){ // cnt 카운터가 0 이 되면 제거합니다..
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() {
// 게임 오버는 여기에서 처리힌다
// 아직 게임 오버 없음
// 볼의 갯수를 다시 4개로...
InitGame();
}
//-------------------------------------
// 스레드 본체
//-------------------------------------
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
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){
bk.cnt--; //cnt 카운터를 --
mBall.sx = - mBall.sx;
}
else
bk.cnt--; // cnt 카운터를 --
mBall.sy = - mBall.sy; // 상하 충돌
tot += tmp.score; // 득점
score++;
if(bk.cnt == 0){ // cnt 카운터가 0 이 되면 제거합니다..
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() {
// 게임 오버는 여기에서 처리힌다
// 아직 게임 오버 없음
// 볼의 갯수를 다시 4개로...
InitGame();
}
//-------------------------------------
// 스레드 본체
//-------------------------------------
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
} // SurfaceView
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
} // SurfaceView