?? tetriscanvas.java
字號(hào):
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: 該類為游戲畫(huà)布</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; /* 游戲運(yùn)行狀態(tài) */
protected TetrisBlock block; /* 當(dāng)前下墜物*/
protected TetrisMap map; /*游戲地圖*/
protected TetrisBlock blockOther;
protected TetrisMap mapOther;
protected Thread thread; /* 重畫(huà)線程,該線程實(shí)現(xiàn)游戲畫(huà)布重畫(huà)機(jī)制 */
/*counter,maxCount這2個(gè)變量是用來(lái)控制游戲速度 */
protected int counter;
protected int maxCount;
boolean GAME_CLEAR_SCREEN = false;
protected boolean startDemoFlag; /*是否已經(jīng)顯示過(guò)開(kāi)始畫(huà)面*/
public static int mainWidth; /*屏幕寬度,在sun gray emulator上=180*/
public static int mainHeight; /*屏幕高度,在sun gray emulator上=177*/
public static int GAMEAREA_X; //游戲區(qū)域左上角x坐標(biāo),游戲區(qū)域?yàn)樽筮叺挠螒蛉萜鲄^(qū)域和右邊的下一個(gè)下墜物顯示區(qū)域組成
public static int GAMEAREA_Y; //游戲區(qū)域左上角y坐標(biāo)
public static int BRICK_WIDTH; //小磚塊的邊長(zhǎng)
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; /* 傳輸給遠(yuǎn)端玩家,自己按了開(kāi)始鍵 */
// protected static final int PRESSED_EXITCOMMAND = 101; /* 傳輸給遠(yuǎn)端玩家,自己按了退出鍵 */
// 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; /*自身先按了,等待遠(yuǎn)程用戶,主屏顯示等待*/
protected static final int GAME_WAIT_REMOTE = 105;/*遠(yuǎn)程用戶先按了,等待本榿用戶,附屏顯示等待*/
protected static final int GAME_INIT = 106; /* 游戲初始狀態(tài) */
protected static final int GAME_RUN = 107; /* 游戲運(yùn)行狀態(tài) */
protected static final int GAME_OVER = 108; /* 游戲結(jié)束狀態(tài) */
protected static final int GAME_START_DEMO = 109; /* demo狀態(tài),顯示demo的畫(huà)面 */
protected static final int GAME_SUSPEND = 110; /* 掛起狀態(tài),值與demo狀態(tài)同 */
protected static final int GAME_EXIT = 111;
protected static final int GAME_WIN = 112;
protected static final int GAME_DISCONNECTED = 113; /* 斷開(kāi)狀態(tài),為gameState_Remote所獨(dú)有 */
protected static final int SEND_MAPDATA = 114;
//edit wts 20060911
public static int GAMEAREA_X_REMOTE;//附屏的X坐標(biāo)
public static int GAMEAREA_Y_REMOTE;//附屏的Y坐標(biāo)
public static int BRICK_WIDTH_REMOTE;
public static int mainWidth_Remote;
public static int mainHeight_Remote;
protected int gameState_Remote; /* 游戲運(yùn)行狀態(tài) */
protected TetrisBlock block_Remote; /* 當(dāng)前下墜物*/
protected TetrisMap map_Remote; /*游戲地圖*/
protected boolean startDemoFlag_Remote;
/*counter_2,maxCount_2這2個(gè)變量是用來(lái)控制遠(yuǎn)端用戶的游戲速度 */
protected int counter_Remote;
//protected int maxCount_Remote; masCount_Remote不需要它
public static int offSet ; //計(jì)算主屏位置的偏移值
protected byte[] data;
protected int pattern_Remote;
protected int next_Remote;
//聯(lián)機(jī)版
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;
// 計(jì)算小磚塊寬度
int min = mainWidth;
//比較,使用高和寬中最小一個(gè)來(lái)計(jì)算
if (mainHeight < min) {
min = mainHeight;
}
//游戲區(qū)域應(yīng)該能被16整除
for (; min >= 0; min--) {
if (min % 16 == 0) {
break;
}
}
//游戲區(qū)域?yàn)閙in的方形,且min為16的倍數(shù)
BRICK_WIDTH = min / 16; //磚塊厚度
GAMEAREA_X = (mainWidth - min) / 2 ;
GAMEAREA_Y = (mainHeight - min) / 2;
startDemoFlag = false; //還沒(méi)有顯示開(kāi)始畫(huà)面
gameState = GAME_START_DEMO; //游戲處于demo畫(huà)面狀態(tài)
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設(shè)置的是主屏,false設(shè)置的是附屏
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("開(kāi)始", 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("開(kāi)始", Command.OK, 0);
exitCmd = new Command("退出", Command.EXIT, 0);
addCommand(startCmd);
addCommand(exitCmd);
setCommandListener(this);
}
/* 初始化,顯示demo畫(huà)面所需的設(shè)置 */
protected void init() {
//假設(shè)主屏所占用的是屏幕的2/3(下部),則寬度不變,高度取2/3,再加一個(gè)高度1/3的偏移值即可!!
mainHeight = getHeight() * 2 / 3;
offSet = mainHeight / 3 + mainHeight * 2 / 15;
mainWidth = getWidth() ;
//計(jì)算小磚塊寬度
int min = mainWidth;
//比較,使用高和寬中最小一個(gè)來(lái)計(jì)算
if (mainHeight < min) {
min = mainHeight;
}
//游戲區(qū)域應(yīng)該能被16整除
for (; min >= 0; min--) {
if (min % 16 == 0) {
break;
}
}
//游戲區(qū)域?yàn)閙in的方形,且min為16的倍數(shù)
BRICK_WIDTH = min / 16; //磚塊厚度
GAMEAREA_X = (mainWidth - min) / 2 ;
GAMEAREA_Y = (mainHeight - min) / 2 + offSet;
startDemoFlag = false; //還沒(méi)有顯示開(kāi)始畫(huà)面
gameState = GAME_START_DEMO; //游戲處于demo畫(huà)面狀態(tài)
initRemote();
}
public void initRemote()
{
//附屏占用的是屏幕的1/5(上部),則寬度不變,高度取1/5
mainHeight_Remote = getHeight() * 1 / 5;
mainWidth_Remote = getWidth() ;
// 計(jì)算小磚塊寬度
int min_2 = mainWidth_Remote;
if (mainHeight_Remote < min_2) {
min_2 = mainHeight_Remote;
}
//游戲區(qū)域應(yīng)該能被16整除
for (; min_2 >= 0; min_2--) {
if (min_2 % 16 == 0) {
break;
}
}
//游戲區(qū)域?yàn)閙in的方形,且min為16的倍數(shù)
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) {
//還沒(méi)有開(kāi)始游戲或者游戲已結(jié)束
if (startDemoFlag == false||gameState == GAME_OVER|| gameState == GAME_WIN) {
startDemoFlag = true;
//game = GAME_INIT;
gameState = GAME_WAIT;
//如果遠(yuǎn)端主機(jī)己經(jīng)在等待,則不必顯示等待畫(huà)面,直接進(jìn)入游戲
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) {
//如果處于掛起狀態(tài),則進(jìn)入運(yùn)行狀態(tài)
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();
}
}
//將信息傳給遠(yuǎn)端用戶
transmitMsg(action);
}
//繪制主屏的任務(wù)全部放這里
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畫(huà)面狀態(tài) */
if (!startDemoFlag) {
//游戲還沒(méi)開(kāi)始,顯示demo畫(huà)面
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);
}
/* 游戲第一次啟動(dòng) */
//第一次啟動(dòng)顯示開(kāi)始畫(huà)面,
//之后都是直接顯示(直接開(kāi)始),
}
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());
//畫(huà)出游戲地圖(容器部分)
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);
}
//無(wú)論是否有行被消,均要傳送
//將map數(shù)據(jù)傳遞給遠(yuǎn)程用戶,在遠(yuǎn)程用戶的附屏上顯示它.
//實(shí)現(xiàn)serialize接口
sendMapdata();
block.generatePN();
sendPN();
block.init();
y = block.getY();
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -