📄 tetriscanvas.java
字号:
package game.tetris;
//Work Canvas
import game.bluetooth.*;
import game.tetris.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.lcdui.*;
/**
* <p>Title: </p>
* <p>Description: 该类为游戏画布</p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: www.jagie.com</p>
* @author: an unknown Japanese,Jagie
* @version 1.0
*/
public class TetrisCanvas
extends Canvas
implements CommandListener, Runnable {
//Midlet
protected MainMIDlet midlet;
protected Command exitCmd;
protected Command startCmd;
protected int gameState; /* 游戏运行状态 */
protected TetrisBlock block; /* 当前下坠物*/
protected TetrisMap map; /*游戏地图*/
protected TetrisBlock blockOther;
protected TetrisMap mapOther;
protected Thread thread; /* 重画线程,该线程实现游戏画布重画机制 */
/*counter,maxCount这2个变量是用来控制游戏速度 */
protected int counter;
protected int maxCount;
boolean GAME_CLEAR_SCREEN = false;
protected boolean startDemoFlag; /*是否已经显示过开始画面*/
public static int mainWidth; /*屏幕宽度,在sun gray emulator上=180*/
public static int mainHeight; /*屏幕高度,在sun gray emulator上=177*/
public static int GAMEAREA_X; //游戏区域左上角x坐标,游戏区域为左边的游戏容器区域和右边的下一个下坠物显示区域组成
public static int GAMEAREA_Y; //游戏区域左上角y坐标
public static int BRICK_WIDTH; //小砖块的边长
public static final int BACKGROUND = 0x00000000; //背景颜色
//edit wts 20060910
private BluetoothConnection[] btConnections;
private String role;
// protected static final int PRESSED_KEY = 99;
// protected static final int PRESSED_STARTCOMMAND = 100; /* 传输给远端玩家,自己按了开始键 */
// protected static final int PRESSED_EXITCOMMAND = 101; /* 传输给远端玩家,自己按了退出键 */
// protected static final int REMOTE_GAME_EXIT = 102;
protected static final int SEND_PN = 103;/*传送和接收ketrisBlock的pattern和next值*/
protected static final int GAME_WAIT = 104; /*自身先按了,等待远程用户,主屏显示等待*/
protected static final int GAME_WAIT_REMOTE = 105;/*远程用户先按了,等待本桤用户,附屏显示等待*/
protected static final int GAME_INIT = 106; /* 游戏初始状态 */
protected static final int GAME_RUN = 107; /* 游戏运行状态 */
protected static final int GAME_OVER = 108; /* 游戏结束状态 */
protected static final int GAME_START_DEMO = 109; /* demo状态,显示demo的画面 */
protected static final int GAME_SUSPEND = 110; /* 挂起状态,值与demo状态同 */
protected static final int GAME_EXIT = 111;
protected static final int GAME_WIN = 112;
protected static final int GAME_DISCONNECTED = 113; /* 断开状态,为gameState_Remote所独有 */
protected static final int SEND_MAPDATA = 114;
//edit wts 20060911
public static int GAMEAREA_X_REMOTE;//附屏的X坐标
public static int GAMEAREA_Y_REMOTE;//附屏的Y坐标
public static int BRICK_WIDTH_REMOTE;
public static int mainWidth_Remote;
public static int mainHeight_Remote;
protected int gameState_Remote; /* 游戏运行状态 */
protected TetrisBlock block_Remote; /* 当前下坠物*/
protected TetrisMap map_Remote; /*游戏地图*/
protected boolean startDemoFlag_Remote;
/*counter_2,maxCount_2这2个变量是用来控制远端用户的游戏速度 */
protected int counter_Remote;
//protected int maxCount_Remote; masCount_Remote不需要它
public static int offSet ; //计算主屏位置的偏移值
protected byte[] data;
protected int pattern_Remote;
protected int next_Remote;
//联机版
public TetrisCanvas( MainMIDlet _midlet, BluetoothConnection[] btConns , String _role )
{
midlet = _midlet;
btConnections = btConns;
role = _role;
bug.println(role);
if( !( Role.ROLE_SINGLE == role ))
{
setCanvas();
setReceiveThread();
}else
{
setSingleCanvas();
}
}
// public TetrisCanvas( MainMIDlet _midlet, String _role)
// {
// midlet = _midlet;
//
// role = _role;
//
// setSingleCanvas();
//
// }
public void setSingleCanvas()
{
mainHeight = getHeight();
mainWidth = getWidth();
offSet = 0;
// 计算小砖块宽度
int min = mainWidth;
//比较,使用高和宽中最小一个来计算
if (mainHeight < min) {
min = mainHeight;
}
//游戏区域应该能被16整除
for (; min >= 0; min--) {
if (min % 16 == 0) {
break;
}
}
//游戏区域为min的方形,且min为16的倍数
BRICK_WIDTH = min / 16; //砖块厚度
GAMEAREA_X = (mainWidth - min) / 2 ;
GAMEAREA_Y = (mainHeight - min) / 2;
startDemoFlag = false; //还没有显示开始画面
gameState = GAME_START_DEMO; //游戏处于demo画面状态
map = new TetrisMap(this,true);
block = new TetrisBlock(map,true);
map.setTetrisBlock(block);
addCommand();
thread = new Thread(this);
thread.start();
}
public void setCanvas( )
{
init();
//true设置的是主屏,false设置的是附屏
map = new TetrisMap(this , true);
block = new TetrisBlock(map ,true);
map.setTetrisBlock(block);
//edit wts 20060911
map_Remote = new TetrisMap(this,false);
block_Remote = new TetrisBlock(map_Remote,false);
map_Remote.setTetrisBlock(block_Remote);
addCommand();
// startCmd = new Command("开始", Command.OK, 0);
// exitCmd = new Command("退出", Command.EXIT, 0);
// addCommand(startCmd);
// addCommand(exitCmd);
// setCommandListener(this);
thread = new Thread(this);
thread.start();
bug.println(role);
}
private void addCommand()
{
startCmd = new Command("开始", Command.OK, 0);
exitCmd = new Command("退出", Command.EXIT, 0);
addCommand(startCmd);
addCommand(exitCmd);
setCommandListener(this);
}
/* 初始化,显示demo画面所需的设置 */
protected void init() {
//假设主屏所占用的是屏幕的2/3(下部),则宽度不变,高度取2/3,再加一个高度1/3的偏移值即可!!
mainHeight = getHeight() * 2 / 3;
offSet = mainHeight / 3 + mainHeight * 2 / 15;
mainWidth = getWidth() ;
//计算小砖块宽度
int min = mainWidth;
//比较,使用高和宽中最小一个来计算
if (mainHeight < min) {
min = mainHeight;
}
//游戏区域应该能被16整除
for (; min >= 0; min--) {
if (min % 16 == 0) {
break;
}
}
//游戏区域为min的方形,且min为16的倍数
BRICK_WIDTH = min / 16; //砖块厚度
GAMEAREA_X = (mainWidth - min) / 2 ;
GAMEAREA_Y = (mainHeight - min) / 2 + offSet;
startDemoFlag = false; //还没有显示开始画面
gameState = GAME_START_DEMO; //游戏处于demo画面状态
initRemote();
}
public void initRemote()
{
//附屏占用的是屏幕的1/5(上部),则宽度不变,高度取1/5
mainHeight_Remote = getHeight() * 1 / 5;
mainWidth_Remote = getWidth() ;
// 计算小砖块宽度
int min_2 = mainWidth_Remote;
if (mainHeight_Remote < min_2) {
min_2 = mainHeight_Remote;
}
//游戏区域应该能被16整除
for (; min_2 >= 0; min_2--) {
if (min_2 % 16 == 0) {
break;
}
}
//游戏区域为min的方形,且min为16的倍数
BRICK_WIDTH_REMOTE = min_2 / 16; //砖块厚度
GAMEAREA_X_REMOTE = (mainWidth_Remote - min_2) / 2 ;
GAMEAREA_Y_REMOTE = (mainHeight_Remote - min_2) / 2;
startDemoFlag_Remote = false;
gameState_Remote = GAME_START_DEMO;
outputParameters();
}
public void outputParameters()
{
bug.println("mainWidth = " + mainWidth);
bug.println("mainHeight = " + mainHeight);
bug.println("BRICK_WIDTH = "+ BRICK_WIDTH);
bug.println("GAMEAREA_X = "+ GAMEAREA_X);
bug.println("GAMEAREA_Y = "+ GAMEAREA_Y);
bug.println("mainWidth_2 = " + mainWidth_Remote);
bug.println("mainHeight_2 = " + mainHeight_Remote);
bug.println("BRICK_WIDTH_2 = "+BRICK_WIDTH_REMOTE);
bug.println("GAMEAREA_X_2 = "+ GAMEAREA_X_REMOTE);
bug.println("GAMEAREA_Y_2 = "+ GAMEAREA_Y_REMOTE);
}
public void setReceiveThread()
{
for( int i=0; i<btConnections.length; i++ )
{ // loop through all connections
ReceiveThread rt = new ReceiveThread( i );
rt.start();
}
}
public void run() {
while (true) {
try {
thread.sleep(50);
}
catch (InterruptedException e) {
break;
}
repaint();
}
}
public synchronized void commandAction(Command c, Displayable d) {
if (c == exitCmd) {
midlet.destroyApp(false);
midlet.notifyDestroyed();
transmitMsg( GAME_EXIT );
bug.println("send GAME_EXIT state!" );
// add by wts 20060912
//transmitMsg( PRESSED_EXITCOMMAND );
}
else if (c == startCmd) {
//还没有开始游戏或者游戏已结束
if (startDemoFlag == false||gameState == GAME_OVER|| gameState == GAME_WIN) {
startDemoFlag = true;
//game = GAME_INIT;
gameState = GAME_WAIT;
//如果远端主机己经在等待,则不必显示等待画面,直接进入游戏
if( gameState_Remote == GAME_WAIT_REMOTE || Role.ROLE_SINGLE == role)
{
gameState = GAME_INIT;
gameState_Remote = GAME_INIT;
transmitMsg( GAME_INIT );
}
else
{
transmitMsg( GAME_WAIT );
}
sendPN();
}
else if( gameState == GAME_WAIT )
{
if( gameState_Remote == GAME_WAIT_REMOTE )
{
gameState = GAME_INIT;
gameState_Remote = GAME_INIT;
transmitMsg( GAME_INIT );
}
}
else {
//处于游戏中
if (gameState == GAME_SUSPEND) {
//如果处于挂起状态,则进入运行状态
gameState = GAME_RUN;
transmitMsg( GAME_RUN );
}
else if (gameState == GAME_RUN) {
gameState = GAME_SUSPEND;
transmitMsg( GAME_SUSPEND );
}
}
}//end else if : 按下的是startCmd
}
protected synchronized void keyPressed(int keyCode) {
int action = getGameAction(keyCode);
bug.println(" key action code = " + action);
if (action == Canvas.LEFT && gameState == GAME_RUN) { /* 左移 */
if (block.checkMove(1)) {
block.move(1);
}
}
else if (action == Canvas.RIGHT && gameState == GAME_RUN) { /* 右移 */
if (block.checkMove(2)) {
block.move(2);
}
}
else if (action == Canvas.UP && gameState == GAME_RUN) { /* 下坠块变化 */
if (block.checkRot()) {
block.rotBlock();
}
}
else if (action == Canvas.DOWN && gameState == GAME_RUN) { /* 下移 */
if (block.checkDown()) {
block.down();
}
}
else if (action == Canvas.FIRE && gameState == GAME_RUN) { /* 下坠块变化 */
if (block.checkRot()) {
block.rotBlock();
}
}
//将信息传给远端用户
transmitMsg(action);
}
//绘制主屏的任务全部放这里
public void paint(Graphics g) {
if ( ! GAME_CLEAR_SCREEN )
{
GAME_CLEAR_SCREEN = true;
g.setColor(BACKGROUND);
g.fillRect(0,offSet,getWidth(), getHeight());
return;
}
if (gameState == GAME_START_DEMO) { /* 游戏处于demo画面状态 */
if (!startDemoFlag) {
//游戏还没开始,显示demo画面
g.setColor(BACKGROUND);
g.fillRect(0, 0, this.mainWidth, this.mainHeight);
g.setColor(0, 255, 0);
g.setFont(Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,
Font.SIZE_LARGE));
g.drawString("m俄罗斯方块", mainWidth / 2, this.mainHeight / 4 + offSet,
g.BASELINE | g.HCENTER);
Font f2 = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN,
Font.SIZE_MEDIUM);
}
/* 游戏第一次启动 */
//第一次启动显示开始画面,
//之后都是直接显示(直接开始),
}
else if ( gameState == GAME_WAIT )
{
if( gameState_Remote == GAME_WAIT_REMOTE)
{
gameState = GAME_INIT;
gameState_Remote = GAME_INIT;
}else
{
g.setColor(BACKGROUND);
g.fillRect(0, 0, this.mainWidth, this.mainHeight+ offSet);
g.setColor(0, 255, 0);
g.setFont(Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,
Font.SIZE_LARGE));
g.drawString("m等待", mainWidth / 2, mainHeight / 4 + offSet,
g.BASELINE | g.HCENTER);
Font f2 = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN,
Font.SIZE_MEDIUM);
}
}
else if (gameState == GAME_INIT) {
g.setColor(BACKGROUND);
g.fillRect(0,0, getWidth(), getHeight());
//画出游戏地图(容器部分)
map.init();
map.paint(g);
block.init();
block.drawBlock(g);
block.drawNextBlock(g);
counter = 0;
maxCount = 8;
gameState = GAME_RUN;
}
else if (gameState == GAME_RUN) {
counter++;
if (counter >= maxCount) {
if (block.checkDown()) {
block.down();
block.paint(g);
}
else {
int y = block.getY();
block.paint(g);
block.fixBlock();
if (map.check(g, y)) {
map.repaintMap(g);
}
//无论是否有行被消,均要传送
//将map数据传递给远程用户,在远程用户的附屏上显示它.
//实现serialize接口
sendMapdata();
block.generatePN();
sendPN();
block.init();
y = block.getY();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -