밑에 테트리스를 보고 만들어 보고 있는 학생입니다..궁금한 것이 생겨서 질문을 올립니다..ㅠㅠ저는 테트리스를 하는 중간중간에 폭탄이라는 블럭이 내려와 쌓여있는 블럭에 닿으면 일정범위가 사라지게 하는 기능을 추가하려고 하는데요...일단 addPattern으로 블록 하나를 추가하여 그것을 폭탄으로 사용하는데까지는 되었습니다..그 다음에 닿았을때 일정범위가 사라지게 하는부분이 막혀서 질문 올립니다...제가 생각하는 방식은 메소드를 하나 더 추가하여 그 메소드에 새로 추가한 블록이 닿으면 닿은 일정 범위에 색깔이 검은색으로 바뀌게 하려하는 방식입니다...WhiteAT 님의 의견을 듣고 싶습니다....ㅠㅠ
소스 바뀐부분은 올려드리겠습니다...빨간색 부분이 추가 한 부분입니다....
import javax.microedition.lcdui.*;
import java.io.*;
import java.util.Random;
class TetrisTask extends Thread {
int mode;
final int MODE_NORMAL = 1;
final int MODE_GAMEOVER = 2;
final int MODE_START = 3;
final int CELL_WIDTH = 10;
final int CELL_HEIGHT = 15;
final int ROTATE_TYPE_0X0 = 0;
final int ROTATE_TYPE_3X3 = 1;
final int ROTATE_TYPE_4X4 = 2;
final int NOBLOCK = 9;
final int COLOR_INIT = 3;
final int COLOR_BLACK = 7;
final int COLOR_R = 0, COLOR_G = 1, COLOR_B = 2;
Random random = new Random();
GameCanvas canvas;
int blockNumber = 0;
int nextBlock;
final int TOTAL_BLOCK = 8;
int backBoard[][] = new int[CELL_WIDTH][CELL_HEIGHT];
int blockDataBase[][][] = new int[TOTAL_BLOCK][4][4];
int blockRotateType[] = new int[TOTAL_BLOCK];
int mbx;
int mby;
int movingBlock[][] = new int[4][4];
int movingBlockRotateType;
Image overImage;
Image numberImage[] = new Image[10];
Image scoreImage;
Image nextImage;
int score = 0; int speed = 1;
int colorTable[][] = {
{204, 255, 102}, {255, 0, 153},
{255, 255, 51}, { 0, 102, 255},
{ 0, 204, 153}, { 51, 153, 51},
{ 51, 255, 204}, { 0, 0, 0}
};
public TetrisTask(GameCanvas canvas) {
this.canvas = canvas;
try {
overImage = Image.createImage("/go.png");
scoreImage = Image.createImage("/gs.png");
for (int i=0; i<10; i++) {
numberImage[i] = Image.createImage("/" + i + ".png");
}
nextImage = Image.createImage("/gn.png");
} catch(IOException ioe) {
System.out.println("FILE IO ERROR: " + ioe);
}
int blockPattern0[][] = {
{ 9, 9, 9, 9 },
{ 9, 9, 9, 9 },
{ 0, 0, 0, 0 },
{ 9, 9, 9, 9 }
};
addPattern(blockPattern0, ROTATE_TYPE_4X4);
int blockPattern1[][] = { { 9, 9, 9, 9 },
{ 1, 9, 9, 9 },
{ 1, 1, 1, 9 },
{ 9, 9, 9, 9 } };
addPattern(blockPattern1, ROTATE_TYPE_3X3);
int blockPattern2[][] = { { 9, 9, 9, 9 },
{ 9, 9, 2, 9 },
{ 2, 2, 2, 9 },
{ 9, 9, 9, 9 } };
addPattern(blockPattern2, ROTATE_TYPE_3X3);
int blockPattern3[][] = { { 9, 9, 9, 9 },
{ 3, 3, 9, 9 },
{ 9, 3, 3, 9 },
{ 9, 9, 9, 9 } };
addPattern(blockPattern3, ROTATE_TYPE_3X3);
int blockPattern4[][] = { { 9, 9, 9, 9 },
{ 9, 4, 4, 9 },
{ 4, 4, 9, 9 },
{ 9, 9, 9, 9 } };
addPattern(blockPattern4, ROTATE_TYPE_3X3);
int blockPattern5[][] = { { 9, 9, 9, 9 },
{ 9, 5, 5, 9 },
{ 9, 5, 5, 9 },
{ 9, 9, 9, 9 }};
addPattern(blockPattern5, ROTATE_TYPE_0X0);
int blockPattern6[][] = { { 9, 9, 9, 9 },
{ 9, 6, 9, 9 },
{ 6, 6, 6, 9 },
{ 9, 9, 9, 9 }};
addPattern(blockPattern6, ROTATE_TYPE_3X3);
int blockPatten7[][] = {
{ 9, 1, 2, 9 },
{ 9, 3, 4, 9 },
{ 9, 9, 9, 9 },
{ 9, 9, 9, 9 }
};
addPattern(blockPatten7, ROTATE_TYPE_0X0);
updateMovingBlock();
mode = MODE_START;
for(int i=0; i<CELL_WIDTH; i++) {
for(int ii=0; ii<CELL_HEIGHT; ii++) {
backBoard[i][ii] = COLOR_INIT;
}
}
}
public void addPattern(int ptrn[][], int rflag) {
if(blockNumber >= TOTAL_BLOCK) return;
for(int i=0; i<4; i++) {
for(int ii=0; ii<4; ii++) {
blockDataBase[blockNumber][i][ii] = ptrn[i][ii];
}
}
blockRotateType[blockNumber] = rflag;
blockNumber++;
}
void updateMovingBlock() {
for(int i=0; i<4; i++) {
for(int ii=0; ii<4; ii++) {
movingBlock[i][ii] = blockDataBase[nextBlock][i][ii];
movingBlockRotateType = blockRotateType[nextBlock];
}
}
mbx = 4;
mby = 0;
nextBlock = (int)(Math.abs(random.nextInt()) % blockNumber);
}
protected void paint(Graphics g) {
try {
sleep(100);
} catch(Exception e) { }
g.setColor(0, 0, 0);
g.fillRect(0, 0,canvas.getWidth(),canvas.getHeight());
try {
for(int i=0; i<CELL_WIDTH; i++) {
for(int ii=0; ii<CELL_HEIGHT; ii++) {
if(backBoard[i][ii] != NOBLOCK)
drawCell(g, backBoard[i][ii], i * 6 + 1, ii * 6 + 10, 5, 5);
else
drawCell(g, COLOR_BLACK, i * 6 + 1, ii * 6 + 10, 5, 5);
}
}
} catch(Exception e) {}
g.setColor(255, 255, 0);
g.drawLine(61, 10, 61, 100);
drawScore(g);
drawNextBlock(g);
drawMovingBlock(g);
if(mode == MODE_GAMEOVER) {
g.drawImage(overImage,canvas.getWidth()/4,5+canvas.getHeight()/4,
g.HCENTER | g.VCENTER);
}
}
void drawCell(Graphics g,int cindex,int x,int y,int sx,int sy) {
g.setColor(colorTable[cindex][COLOR_R],colorTable[cindex][COLOR_G],
colorTable[cindex][COLOR_B]);
g.fillRect(x, y, sx, sy);
}
void drawNextBlock(Graphics g) {
g.drawImage(nextImage, 65, 10, g.LEFT | g.TOP);
for(int i=0; i<4; i++) {
for(int ii=0; ii<4; ii++) {
if(blockDataBase[nextBlock][i][ii] != NOBLOCK)
drawCell(g, blockDataBase[nextBlock][i][ii],
(i * 6) + 67, (ii * 6) + 25, 5, 5);
}
}
}
void drawMovingBlock(Graphics g) {
for(int i=0; i<4; i++) {
for(int ii=0; ii<4; ii++) {
if(movingBlock[i][ii] != NOBLOCK) {
drawCell(g, movingBlock[i][ii], (i+mbx)*6 + 1,
(ii+mby)*6 + 10, 5, 5);
}
}
}
}
void drawFloatingBlock(Graphics g) {
for(int i=0; i<4; i++) {
for(int ii=0; ii<4; ii++) {
if(movingBlock[i][ii] != NOBLOCK) {
drawCell(g, movingBlock[i][ii], (i+mbx)*6 + 1,
(ii+mby)*6 + 10, 5, 5);
}
}
}
}
public void run() {
try {
while(true) {
switch(mode) {
case MODE_START:
startProc();
break;
case MODE_NORMAL:
normalProc();
break;
case MODE_GAMEOVER:
break;
}
Thread.sleep((int)(1000 / speed));
}
} catch(Exception e) {
e.printStackTrace();
}
}
boolean moveOK() {
try {
for(int i=0; i<4; i++) {
for(int ii=0; ii<4; ii++) {
if(movingBlock[i][ii] != NOBLOCK) {
if((i+mbx < 0) || (i+mbx >= CELL_WIDTH)
|| (ii+mby < 0)|| (ii+mby >= CELL_HEIGHT)) {
return false;
}
if(backBoard[i+mbx][ii+mby] != NOBLOCK) {
return false;
}
}
}
}
} catch(Exception e) {
System.out.println("Exception in moveOK");
}
return true;
}
void startProc() {
for(int i=0; i<CELL_WIDTH; i++) {
for(int ii=0; ii<CELL_HEIGHT; ii++) {
backBoard[i][ii] = NOBLOCK;
}
}
mode = MODE_NORMAL;
canvas.repaint();
}
void normalProc() {
mby++;
if (!moveOK()) {
mby--;
freezeMovingBlock();
}
canvas.repaint();
formALine();
int w = (int)((score % 5000) / 1000);
w++;
speed = w;
}
void freezeMovingBlock() {
for(int i=0; i<4; i++) {
for(int ii=0; ii<4; ii++) {
if(movingBlock[i][ii] != NOBLOCK) {
backBoard[i+mbx][ii+mby] = movingBlock[i][ii];
}
}
}
updateMovingBlock();
canvas.repaint();
if(!moveOK()) mode = MODE_GAMEOVER;
}
protected void keyHandler(int action) {
switch(action) {
case Canvas.RIGHT:
if (mode != MODE_NORMAL) return;
mbx++;
if(!moveOK()) mbx--;
canvas.repaint();
break;
case Canvas.LEFT:
if(mode != MODE_NORMAL) return;
mbx--;
if(!moveOK()) mbx++;
canvas.repaint();
break;
case Canvas.DOWN:
if(mode == MODE_NORMAL)
normalProc();
break;
case Canvas.UP:
case Canvas.FIRE:
switch(mode) {
case MODE_NORMAL:
int tempBlock[][] = new int[4][4];
for(int i=0; i<4; i++) {
for(int ii=0; ii<4; ii++) {
tempBlock[i][ii] = movingBlock[i][ii];
}
}
int w;
if(movingBlockRotateType == ROTATE_TYPE_3X3) {
w = movingBlock[2][0];
movingBlock[2][0] = movingBlock[2][2];
movingBlock[2][2] = movingBlock[0][2];
movingBlock[0][2] = movingBlock[0][0];
movingBlock[0][0] = w;
w = movingBlock[1][0];
movingBlock[1][0] = movingBlock[2][1];
movingBlock[2][1] = movingBlock[1][2];
movingBlock[1][2] = movingBlock[0][1];
movingBlock[0][1] = w;
}
if(movingBlockRotateType == ROTATE_TYPE_4X4) {
w = movingBlock[2][0];
movingBlock[2][0] = movingBlock[0][2];
movingBlock[2][1] = movingBlock[0][2];
movingBlock[2][3] = movingBlock[0][2];
movingBlock[0][2] = w;
movingBlock[1][2] = w;
movingBlock[3][2] = w;
}
if(!moveOK()) {
for(int i=0; i<4; i++) {
for(int ii=0; ii<4; ii++) {
movingBlock[i][ii]=tempBlock[i][ii];
}
}
} else {
canvas.repaint();
}
break;
}
}
}
void formALine() {
boolean flg;
int lscore = 0;
for(int i=(CELL_HEIGHT-1); i>=0; i--) {
flg = true;
for(int ii=0; ii<CELL_WIDTH; ii++)
if(backBoard[ii][i] == NOBLOCK) flg = false;
if(flg) {
for(int y=i; y>=1; y--)
for(int x=0; x<CELL_WIDTH; x++)
backBoard[x][y] = backBoard[x][y-1];
i++;
lscore++;
canvas.repaint();
try {
sleep(100);
} catch(InterruptedException ie) { }
}
}
switch(lscore) {
case 1:
score += 100;
break;
case 2:
score += 200;
break;
case 3:
score += 500;
break;
case 4:
score += 1000;
break;
}
if(lscore > 0) {
canvas.repaint();
try {
sleep(100);
} catch(InterruptedException ie) { }
}
}
void drawScore(Graphics g) {
int w, s = 0;
g.drawImage(scoreImage, 65, 52, g.LEFT | g.TOP);
for(int i=4, j=0; i>=0; i--, j++) {
w = (int)((score - s) / pow(10, i));
s += (w * pow(10, i));
g.drawImage(numberImage[w], 68 + (5 * j), 70,
g.LEFT | g.TOP);
}
}
int pow(int v, int n) {
n--;
if (n < 1) return 1;
return pow(v, n) * v;
}
}
벽돌이 끝까지 내려갔을 경우에 실행되는 함수 freezeMovingBlock()
for 문이 2겹인데, 벽돌의 정보를 보드에 복사하는 것인데, 이를 조금만 변경하면 될겁니다.
if(패턴7인가?)
{
// 패턴 7이다. 폭탄을 터뜨리자.. // 4 x 4 배열에 폭탄이 터지는 값을 넣어 주자.
for(int i=0; i<4; i++) { // 적당한 숫자를 넣자
for(int ii=0; ii<4; ii++) {
if(movingBlock[i][ii] != NOBLOCK) {
backBoard[i+mbx][ii+mby] = 1; // 적당한 벽돌정보를 넣어준다.
}
}
else
{
// 일반벽돌처리부분 , 원래의 것 그냥 사용하면 되겠죠?
}