?? ketrisblock.java
字號:
import javax.microedition.lcdui.*;
import java.util.Random;
/**
*
* <p>Title: </p>
* <p>Description: 該類為封裝下墜物對象及其操作</p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: </p>
* @author: an unknown Japanese,Jagie
* @version 1.0
*/
public class KetrisBlock {
//各種磚塊,1-7為活動磚塊顏色,8為墻磚顏色
public static final int[] BRICK_COLORS = {
0x00FF0000, 0x0000FF00, 0x00FFFF00, 0x000000FF, 0x00FF00FF, 0x0000FFFF,
0x00C0DCC0, 0x00808080};
/**
* blockpattern的編碼規則:blockpattern表示一個下墜物體的形狀,一種下墜物的顏色是固定的。
* 對于一個下墜物,用一個三維數祖表示,第一維用rot表示(旋轉值),第二維用x(也就是行),第三維用y表示(也就是列)。
* 所以 blockpattern1:田字及四種旋轉形狀
* blockpattern2:反L字及四種旋轉形狀
* blockpattern3:L字及四種旋轉形狀
* blockpattern4:1字及四種旋轉形狀
* ........................
*/
protected int blockpattern1[][][] = {
{
{
0, 0, 0, 0}
, {
0, 1, 1, 0}
, {
0, 1, 1, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 0, 0}
, {
0, 1, 1, 0}
, {
0, 1, 1, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 0, 0}
, {
0, 1, 1, 0}
, {
0, 1, 1, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 0, 0}
, {
0, 1, 1, 0}
, {
0, 1, 1, 0}
, {
0, 0, 0, 0}
}
};
protected int blockpattern2[][][] = {
{
{
0, 0, 1, 0}
, {
0, 0, 1, 0}
, {
0, 1, 1, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 0, 0}
, {
0, 1, 0, 0}
, {
0, 1, 1, 1}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 0, 0}
, {
0, 1, 1, 0}
, {
0, 1, 0, 0}
, {
0, 1, 0, 0}
}
, {
{
0, 0, 0, 0}
, {
, {
0, 0, 1, 0}
, {
0, 0, 0, 0}
}
};
protected int blockpattern3[][][] = {
{
{
0, 1, 0, 0}
, {
0, 1, 0, 0}
, {
0, 1, 1, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 0, 0}
, {
0, 1, 1, 1}
, {
0, 1, 0, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 0, 0}
, {
0, 1, 1, 0}
, {
0, 0, 1, 0}
, {
0, 0, 1, 0}
}
, {
{
0, 0, 0, 0}
, {
0, 0, 1, 0}
, {
1, 1, 1, 0}
, {
0, 0, 0, 0}
}
};
protected int blockpattern4[][][] = {
{
{
0, 0, 1, 0}
, {
0, 0, 1, 0}
, {
0, 0, 1, 0}
, {
0, 0, 1, 0}
}
, {
{
0, 0, 0, 0}
, {
0, 0, 0, 0}
, {
1, 1, 1, 1}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 1, 0}
, {
0, 0, 1, 0}
, {
0, 0, 1, 0}
, {
0, 0, 1, 0}
}
, {
{
0, 0, 0, 0}
, {
0, 0, 0, 0}
, {
1, 1, 1, 1}
, {
0, 0, 0, 0}
}
};
protected int blockpattern5[][][] = {
{
{
0, 0, 0, 0}
, {
1, 1, 0, 0}
, {
0, 1, 1, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 1, 0}
, {
0, 1, 1, 0}
, {
0, 1, 0, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 0, 0}
, {
1, 1, 0, 0}
, {
0, 1, 1, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 1, 0}
, {
0, 1, 1, 0}
, {
0, 1, 0, 0}
, {
0, 0, 0, 0}
}
};
protected int blockpattern6[][][] = {
{
{
0, 0, 0, 0}
, {
0, 1, 1, 0}
, {
1, 1, 0, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 1, 0, 0}
, {
0, 1, 1, 0}
, {
0, 0, 1, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 0, 0, 0}
, {
0, 1, 1, 0}
, {
1, 1, 0, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 1, 0, 0}
, {
0, 1, 1, 0}
, {
0, 0, 1, 0}
, {
0, 0, 0, 0}
}
};
protected int blockpattern7[][][] = {
{
{
0, 0, 0, 0}
, {
1, 1, 1, 0}
, {
0, 1, 0, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 1, 0, 0}
, {
1, 1, 0, 0}
, {
0, 1, 0, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 1, 0, 0}
, {
1, 1, 1, 0}
, {
0, 0, 0, 0}
, {
0, 0, 0, 0}
}
, {
{
0, 1, 0, 0}
, {
0, 1, 1, 0}
, {
0, 1, 0, 0}
, {
0, 0, 0, 0}
}
};
private int blockpattern[][][]; /* 當前墜物形狀,為以上定義的七個下墜物之一 */
private int blockNextpattern[][]; /* 下一個墜物形狀,顯示在游戲容器的右邊 */
private int x; //blockpattern左上角x坐標,x=i表示左上角距離游戲容器左上角x軸上i個小磚塊單位
private int y; //blockpattern左上角y坐標,y=i表示左上角距離游戲容器左上角y軸上i個小磚塊單位
private int oldx; //x的舊值
private int oldy; //y的舊值
private int rot; //旋轉值,0-3
private int oldrot; //旋轉舊值
private int pattern; /* 組成當前墜物所用小磚塊id(1-7),同時也表示一種下墜物形狀 */
private int next; /* 組成下一個墜物所用小磚塊id(1-7),同時也表示一種下墜物形狀 */
private KetrisMap map;
protected Random rand;
/* 構造,保存map,初始化blockimage,rand,next */
public KetrisBlock(KetrisMap map) {
this.map = map;
rand = new Random();
next =Math.abs(rand.nextInt()) % 7 + 1;
}
/* 初始化 */
protected void init() {
pattern = next;
next = Math.abs(rand.nextInt()) % 7 + 1;
/* 得到當前下墜物 */
switch (pattern) {
case 1:
readPattern(blockpattern1);
break;
case 2:
readPattern(blockpattern2);
break;
case 3:
readPattern(blockpattern3);
break;
case 4:
readPattern(blockpattern4);
break;
case 5:
readPattern(blockpattern5);
break;
case 6:
readPattern(blockpattern6);
break;
case 7:
readPattern(blockpattern7);
break;
}
/* 得到下一個下墜物 */
switch (next) {
case 1:
readNextPattern(blockpattern1);
break;
case 2:
readNextPattern(blockpattern2);
break;
case 3:
readNextPattern(blockpattern3);
break;
case 4:
readNextPattern(blockpattern4);
break;
case 5:
readNextPattern(blockpattern5);
break;
case 6:
readNextPattern(blockpattern6);
break;
case 7:
readNextPattern(blockpattern7);
break;
}
x = 5; /* 游戲容器內徑的一半 */
y = 0; /* y坐標 */
rot = 0;
//判斷map數據,決定y的真正值,之所以這么處理,是因為當game over的時候,最后一個下墜物,可能只能畫出一部分
//為了達到這個效果,必須讓y成為一個恰當的負值
while (isCrashAtBegin()) {
y--;
if(y<-4){
break;
}
}
oldx = x;
oldy = y;
oldrot = rot;
}
/**
* 設置當前下墜物變量的內容
* @param nowblock int[][][] 7種下墜物常量之一
*/
private void readPattern(int[][][] nowblock) {
blockpattern = new int[4][4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int k = 0; k < 4; k++) {
blockpattern[i][j][k] = nowblock[i][j][k];
}
}
}
}
/**
* 設置下一個下墜物變量的內容。只需要包存4中旋轉變化中的第一種即可,所以rot維值=0
* @param nowblock int[][][] 7種下墜物常量之一
*/
private void readNextPattern(int[][][] nowblock) {
blockNextpattern = new int[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
blockNextpattern[i][j] = nowblock[0][i][j];
}
}
}
/* 旋轉下墜物 */
protected void rotBlock() {
rot++;
if (rot == 4) {
rot = 0;
}
}
/**
* 繪制下墜物,包括清除下墜物的舊圖像,調用繪制下墜物新圖像的函數
* @param g Graphics
*/
public synchronized void paint(Graphics g) {
//如果3維都沒有變化,則無需重畫
if ( (oldrot != rot) || (oldx != x) || (oldy != y)) {
//清除舊圖形
g.setColor(KetrisCanvas.BACKGROUD);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (blockpattern[oldrot][i][j] == 1) {
g.fillRect(KetrisCanvas.GAMEAREA_X +
(oldx + j) * KetrisCanvas.BRICK_WIDTH,
KetrisCanvas.GAMEAREA_Y +
(oldy + i) * KetrisCanvas.BRICK_WIDTH,
KetrisCanvas.BRICK_WIDTH, KetrisCanvas.BRICK_WIDTH);
}
}
}
drawBlock(g);
oldrot = rot;
oldx = x;
oldy = y;
}
}
/**
* 繪制下墜物
* @param g Graphics
*/
public void drawBlock(Graphics g) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (blockpattern[rot][i][j] == 1) {
drawBrick(KetrisCanvas.GAMEAREA_X +
(x + j) * KetrisCanvas.BRICK_WIDTH,
KetrisCanvas.GAMEAREA_Y +
(y + i) * KetrisCanvas.BRICK_WIDTH, g, pattern - 1);
}
}
}
}
/**
* 判斷下墜物是不是和map中已有的磚塊重疊,為了處理gameover的時候,只需畫出部分下墜物的情況
@return true:有重疊,false:無重疊
*/
public boolean isCrashAtBegin() {
//行
for (int i = 3; i >= 0; i--) {
//列
for (int j = 0; j < 4; j++) {
int mx = x + j;
int my = y + i;
if (my < 0) {
my = 0;
}
if (blockpattern[rot][i][j] == 1 && map.get(mx, my) != 8 &&
map.get(mx, my) != 0) {
return true;
}
}
}
return false;
}
/**
* 畫小磚塊
* @param px x坐標
* @param py y坐標
* @param g Graphics
* @param colorIndex 顏色索引值
*/
public static void drawBrick(int px, int py, Graphics g, int colorIndex) {
//畫白邊
g.setColor(255, 255, 255);
g.fillRect(px, py, 1, KetrisCanvas.BRICK_WIDTH);
g.fillRect(px, py, KetrisCanvas.BRICK_WIDTH, 1);
//畫中心
int color = BRICK_COLORS[colorIndex];
g.setColor(color);
g.fillRect(px + 1, py + 1, KetrisCanvas.BRICK_WIDTH - 1,
KetrisCanvas.BRICK_WIDTH - 1);
//畫灰邊
g.setColor(0x00c0c0c0);
g.fillRect(px + KetrisCanvas.BRICK_WIDTH - 1, py + 1, 1,
KetrisCanvas.BRICK_WIDTH - 1);
g.fillRect(px + 1, py + KetrisCanvas.BRICK_WIDTH - 1,
KetrisCanvas.BRICK_WIDTH - 2, 1);
}
/**
* 在游戲容器的右邊繪出下一個下墜物
* @param g Graphics
*/
public void drawNextBlock(Graphics g) {
//清除繪制區域
g.setColor(KetrisCanvas.BACKGROUD);
int px = KetrisCanvas.GAMEAREA_X + 12 * KetrisCanvas.BRICK_WIDTH;
int py = KetrisCanvas.GAMEAREA_Y + 2 * KetrisCanvas.BRICK_WIDTH;
int width = KetrisCanvas.BRICK_WIDTH * 4;
g.fillRect(px, py, width, width);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (blockNextpattern[i][j] == 1) {
drawBrick(px + j * KetrisCanvas.BRICK_WIDTH,
py + i * KetrisCanvas.BRICK_WIDTH, g, next - 1);
}
}
}
}
/**
* 判斷下墜物是否能下移
* @param kyouseiflag boolean true:自動下移 false:人工按鍵下移
* @return boolean
*/
public boolean checkDown(boolean kyouseiflag) {
boolean check = true;
/* 分別掃描下墜物的4行,從最下面的那行開始 */
for (int i = 0; i < 4; i++) {
int row = 3;
while (row >= 0) {
if (blockpattern[rot][row][i] == 1) {
if (map.get(x + i, y + row + 1) != 0) {
check = false;
}
row = -1; /* 終止循環 */
}
else {
row--;
}
}
}
return check;
}
/* 下墜物下移1行 */
public void down() {
y = y + 1;
}
/* 判斷是否能旋轉 */
public boolean checkRot() {
boolean check = true;
int tmpRot = rot + 1;
if (tmpRot == 4) {
tmpRot = 0;
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (blockpattern[tmpRot][i][j] == 1) {
if (map.get(x + j, y + i) != 0) {
check = false;
}
}
}
}
return check;
}
/* 判斷下墜物是否可以移動 */
public boolean checkMove(int direct) {
boolean check = true;
/* 分別掃描下墜物的4行 */
for (int i = 0; i < 4; i++) {
if (direct == 1) { /* 左移 */
int row = 0;
while (row <= 3) {
if (blockpattern[rot][i][row] == 1) {
if (map.get(x + row - 1, y + i) != 0) {
check = false;
}
row = 4; /* 終止循環 */
}
else {
row++;
}
}
}
else { /* 右移 */
int row = 3;
while (row >= 0) {
if (blockpattern[rot][i][row] == 1) {
if (map.get(x + row + 1, y + i) != 0) {
check = false;
}
row = -1; /* 終止循環 */
}
else {
row--;
}
}
}
}
return check;
}
/* 左右移動 */
public void move(int direct) {
if (direct == 1) {
x = x - 1;
}
else {
x = x + 1;
}
}
public int getY() {
return y;
}
/* 根據下墜物的當前位置設置地圖數據 */
public void fixBlock() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (blockpattern[rot][i][j] == 1) {
map.set(x + j, y + i, pattern);
}
}
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -