?? 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 + -