오른쪽 왼쪽은 먹히는대...
밑으로 내리는 건 안먹힙니다..
어덯게 하면 될까요??
package com.hanback.tetris;
import java.util.ArrayList;
import java.util.Random;
import com.hanback.tetris.TileView.Coordinate;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Toast;
public class TetrisView extends TileView {
private final static int TILE_SIZE=24;
protected static final int UMODE_ADD_BLOCK = 0;
protected static final int UMODE_TIME = 1;
protected static final int UMODE_LEFT = 2;
protected static final int UMODE_RIGHT = 3;
protected static final int UMODE_ROTATE = 4;
protected static final int UMODE_DOWN = 5; //테트리스 막대를 밑으로
private int mScore = 0;
private int mStage = 0;
Random mRnd = new Random();
private Context mCtx;
private long mMoveDelay = 1000;
private RefreshHandler mRedrawHandler = new RefreshHandler();
class RefreshHandler extends Handler {
@Override
public void handleMessage(Message msg) {
TetrisView.this.update();
// TODO Auto-generated method stub
//super.handleMessage(msg);
}
public void sleep(long delayMillis) {
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0), delayMillis);
}
}
public TetrisView(Context context, AttributeSet attrs) {
super(context, attrs);
mCtx = context;
this.setFocusable(true);
initGame();
}
public void initGame(){
resetTiles(NUM_OF_TILE);
clearTiles();
mScore = 0;
mGameOver=false;
mRedrawHandler.sleep(mMoveDelay);
}
public void update() {
updateBlock(UMODE_TIME);
invalidate();
if (mGameOver==false) mRedrawHandler.sleep(mMoveDelay);
else System.exit(0);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//Toast.makeText(mCtx, "KEY", Toast.LENGTH_SHORT ).show();
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER){
//Toast.makeText(mCtx, "C", Toast.LENGTH_SHORT ).show();
updateBlock(UMODE_ROTATE);
invalidate();
return true;
}
else if (keyCode == KeyEvent.KEYCODE_ENTER){
updateBlock(UMODE_ROTATE);
invalidate();
return true;
}
else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT){
//Toast.makeText(mCtx, "L", Toast.LENGTH_SHORT ).show();
updateBlock(UMODE_LEFT);
invalidate();
return true;
}
else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT){
//Toast.makeText(mCtx, "R", Toast.LENGTH_SHORT ).show();
updateBlock(UMODE_RIGHT);
invalidate();
return true;
}
else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN){
//Toast.makeText(mCtx, "D", Toast.LENGTH_SHORT ).show();
updateBlock(UMODE_DOWN);
invalidate();
return true;
}
// TODO Auto-generated method stub
return super.onKeyDown(keyCode, event);
}
private void updateBlock(int uMode) {
boolean collisionX, collisionY;
int newBlockState, newBlockX, newBlockY;
ArrayList<Coordinate> mNewBlockCoords = new ArrayList<Coordinate>();
switch (uMode) {
case UMODE_TIME :
if (mBlockCoords.isEmpty()){ //add new block
mBlockNum = 1+ mRnd.nextInt(NUM_OF_TILE-1);
newBlockState = mBlockState = 0;
newBlockX = mBlockX = mXTileCount/2;
newBlockY = mBlockY = -1;
} else { //block is falling
newBlockState = mBlockState;
newBlockX = mBlockX;
newBlockY = mBlockY+1;
}
break;
case UMODE_LEFT :
if (mBlockCoords.isEmpty()) return;
newBlockState = mBlockState;
newBlockX = mBlockX-1;
newBlockY = mBlockY;
break;
case UMODE_RIGHT :
if (mBlockCoords.isEmpty()) return;
newBlockState = mBlockState;
newBlockX = mBlockX+1;
newBlockY = mBlockY;
break;
case UMODE_ROTATE :
if (mBlockCoords.isEmpty()) return;
newBlockState = mBlockState+1<4?mBlockState+1:0;
newBlockX = mBlockX;
newBlockY = mBlockY;
break;
case UMODE_DOWN :
if (mBlockCoords.isEmpty()) return;
newBlockState = mBlockState;
newBlockX = mBlockX;
newBlockY = mBlockY++;
break;
default :
return;
}
switch (mBlockNum) {
case 1:
switch (newBlockState) {
case 2:
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY+1));
break;
case 3:
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY+1));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY-1));
break;
case 0:
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY-1));
break;
case 1:
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY+1));
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY+1));
break;
}
break;
case 2: //|-
switch (newBlockState) {
case 2:
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY+1));
break;
case 3:
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY+1));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY+1));
break;
case 0:
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY-1));
break;
case 1:
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY+1));
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY-1));
break;
}
break;
case 3: //-|-
switch (newBlockState) {
case 0:
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
break;
case 1:
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY+1));
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY));
break;
case 2:
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY+1));
break;
case 3:
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY+1));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY));
break;
}
break;
case 4:
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY));
break;
case 5:
switch (newBlockState) {
case 0:
case 2:
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY));
break;
case 1:
case 3:
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY+1));
break;
}
break;
case 6:
switch (newBlockState) {
case 0:
case 2:
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY-1));
break;
case 1:
case 3:
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY+1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY-1));
break;
}
break;
case 7: //----
switch (newBlockState) {
case 0:
case 2:
mNewBlockCoords.add(new Coordinate(newBlockX-1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+1, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX+2, newBlockY));
break;
case 1:
case 3:
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-2));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY-1));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY));
mNewBlockCoords.add(new Coordinate(newBlockX, newBlockY+1));
break;
}
break;
}
collisionX = collisionY = false;
for (int i=0; i<mNewBlockCoords.size(); i++) {
Coordinate cidx = mNewBlockCoords.get(i);
if (cidx.x<0 || cidx.x>mXTileCount-1) collisionX = true;
if (cidx.y>mYTileCount-1 || getTile(cidx.x, cidx.y)>0) collisionY = true;
}
if (mBlockCoords.isEmpty()) mBlockCoords.addAll(mNewBlockCoords);
switch (uMode) {
case UMODE_TIME :
if (collisionY) {
for (Coordinate cidx : mBlockCoords) {
setTile(mBlockNum, cidx.x, cidx.y);
}
int cnt = updateTile();
if (cnt>0) {
mScore += cnt;
for (;mScore/10 > mStage;) {
mMoveDelay = (long)(mMoveDelay * 0.9);
mStage++;
if (mStage==10) {
mGameOver = true;
Toast.makeText(mCtx, "END", Toast.LENGTH_SHORT ).show();
}
else {
Toast.makeText(mCtx, "STAGE : "+mStage, Toast.LENGTH_SHORT ).show();
}
}
}
for (Coordinate cidx : mBlockCoords) {
if (cidx.y<0) {
if (cidx.y+cnt<0) {
mGameOver = true;
}else {
setTile(mBlockNum, cidx.x, cidx.y);
}
}
}
mBlockCoords.clear();
//if (mGameOver) goAlert();
if (mGameOver) Toast.makeText(mCtx, "--", Toast.LENGTH_LONG ).show();
return;
}
break;
case UMODE_LEFT :
case UMODE_RIGHT :
case UMODE_ROTATE :
if (collisionX || collisionY) return;
break;
default :
return;
}
mBlockState = newBlockState;
mBlockX = newBlockX;
mBlockY = newBlockY;
mBlockCoords.clear();
mBlockCoords.addAll(mNewBlockCoords);
}
private void goAlert() {
AlertDialog.Builder alert = new AlertDialog.Builder(mCtx);
alert.setTitle("Game Over");
alert.setMessage("AGAIN?");
//alert.setIcon(R.drawable.info);
alert.setCancelable(false);
alert.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id){
dialog.dismiss();
initGame();
}
});
alert.setNegativeButton("No", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id){
dialog.cancel();
//mGameOver = true;
System.exit(0);
}
});
alert.show();
}
}
if (mBlockCoords.isEmpty()) return;
newBlockState = mBlockState;
newBlockX = mBlockX;
newBlockY = mBlockY++;
break;
++mBlockY