📄 russiangamedisplayable.java
字号:
package russiangame;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.GameCanvas;
/**
* <p>Title: 俄罗斯方块</p>
*
* <p>Description: 俄罗斯方块游戏</p>
*
* <p>Copyright: Copyright (c) 2005</p>
*
* <p>Company: Star Group</p>
*
* @author: Part of this programe comes from a open-source project in the Web(www.hyweb.net).
* Our group makes some remakeble improvement to it.
* @version 1.0
*/
public class RussianGameDisplayable extends GameCanvas implements Runnable,
CommandListener {
private UIController controller;
private Command startCommand;
private Command exitCommand;
private Command pauseCommand;
protected int nState; //游戏状态
protected GameBlock block; //当前下坠物
protected GameMap map; //游戏地图
protected Thread thread; //游戏重画线程
protected int nCount; //游戏速度计数
protected int nSpeed; //游戏当前速度
protected final int GAME_INIT = 0; //游戏初始状态
protected final int GAME_RUN = 1; //游戏运行状态
protected final int GAME_SUSPEND = 3; //挂起状态
protected final int GAME_OVER = 4; //游戏结束状态
protected final int GAME_NEXT_ROUND = 5; //游戏过关状态
private static int mainWidth; //屏幕宽度
private static int mainHeight; //屏幕高度
/**游戏区域左上角x坐标
*/
public static int GAMEAREA_X;
/**游戏区域左上角y坐标
*/
public static int GAMEAREA_Y;
/**小砖块边长
*/
public static int BRICK_WIDTH;
/**背景颜色
*/
public static final int BACKGROUND = 0x00000000;
private Graphics graphics;
public RussianGameDisplayable(UIController controller) {
super(false);
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
this.controller = controller;
this.graphics = this.getGraphics();
map = new GameMap();
block = new GameBlock(map);
startCommand = new Command("开始", Command.OK, 1);
pauseCommand = new Command("暂停", Command.OK, 1);
exitCommand = new Command("退出", Command.EXIT, 0);
this.addCommand(pauseCommand);
this.addCommand(exitCommand);
this.setCommandListener(this);
//启动应用程序
thread = new Thread(this);
thread.start();
}
private void jbInit() throws Exception {
mainWidth = getWidth();
mainHeight = getHeight();
//取min为长与宽中更小的值
//确保游戏域能够被16整除
int min = (mainWidth <= mainHeight) ? mainWidth : mainHeight;
for (; min >= 0; min--) {
if (min % GameMap.MAP_ROW == 0) {
break;
}
}
//小砖块边长(厚度)
BRICK_WIDTH = min / GameMap.MAP_ROW;
GAMEAREA_X = (mainWidth - min) / 2;
GAMEAREA_Y = (mainHeight - min) / 2;
this.nState = this.GAME_INIT; //游戏处于INIT状态
}
/**清屏,重绘 全屏背景 和 游戏背景
* @param g
*/
public static void Clear(Graphics g) {
//设置全屏背景
g.setColor(0xffffff);
g.fillRect(0, 0, mainWidth, mainHeight);
//设置游戏区域背景
g.setColor(BACKGROUND);
g.fillRect(GAMEAREA_X, GAMEAREA_Y, GameMap.MAP_ROW * BRICK_WIDTH, GameMap.MAP_ROW * BRICK_WIDTH);
}
public void run() {
while (true) {
try {
//每50ms重画一次
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.keyPressedState();
this.paintCanvas(this.graphics);
}
}
/**
* 响应键盘事件的回调函数, 除了down请求以外, 其他移动及转向都需要由击键一次,而不是根据状态
*/
protected synchronized void keyPressed(int keyCode) {
int action = getGameAction(keyCode);
if(nState == GAME_RUN){
switch(action){
case Canvas.LEFT://左移
if (this.block.checkMove(GameBlock.MOVE_LEFT)) {
block.move(GameBlock.MOVE_LEFT);
}
break;
case Canvas.RIGHT://右移
if (this.block.checkMove(GameBlock.MOVE_RIGHT)) {
block.move(GameBlock.MOVE_RIGHT);
}
break;
case Canvas.UP://下坠物形状变化
case Canvas.FIRE://下坠物变化
if (this.block.checkRot()) {
block.rotBlock();
}
break;
default:
break;
}
}
}
/**
* 主动查询按键状态
*/
public synchronized void keyPressedState() {
//主动查询状态
int keyState = getKeyStates();
if ((keyState & DOWN_PRESSED) != 0 && nState == GAME_RUN) {
if (this.block.checkDown()) {
block.down();
}
}
}
/**
* 画布重画事件,替代Canvas中的paint()事件, 根据不同的游戏状态(nState)画出游戏画面
* 本方法由thread每次重新启动, 最后执行flushGraphics()重画缓冲区
*/
public synchronized void paintCanvas(Graphics g) {
switch(nState){
case GAME_INIT://游戏第一次启动
//画出游戏逻辑地图(容器部分)
g.setColor(BACKGROUND);
g.fillRect(0, 0, mainWidth, mainHeight);
map.init();
map.paint(g);
//根据产生的砖块类型(随机数),逻辑上初始化下坠物
block.init();
//图形上绘制当前和下一个下坠物
block.drawBlock(g);
block.drawNextBlock(g);
//设置游戏速度和下一步游戏状态
this.nCount = 0;
this.nSpeed = 10-map.getLevel()*2;
nState = GAME_RUN;
break;
case GAME_RUN:
this.nCount++;
if (this.nCount >= this.nSpeed) {
//每停顿nSpeed次检查下降一次,随着nSpeed的变小,下降的速度会越来越大
if (block.checkDown()) {
//是否能够下降(自动)
block.down();
//清除旧图形,画出新下坠物,同时将当前坐标另存为旧值
block.paint(g);
} else {
//不再能够下降(消行 / Game over)
//画出图形,设置坐标
int y = block.getYBrick();
//不再下降,而是直接重新画出下坠物
block.paint(g);
//根据下坠物位置画出当前 逻辑地图数据
block.fixBlock();
//检查从y开始一下4行是否有消去行为
if (map.check(g, y)) {
map.repaintMap(g);
}
//根据产生的砖块类型(随机数),重新在 逻辑上 初始化下坠物
block.init();
//判断是否游戏结束
if (block.getYBrick() < 0) {
nState = GAME_OVER;
}
block.drawBlock(g);
block.drawNextBlock(g);
}
this.nCount = 0;
} else {
block.paint(g);
}
if(map.getScore() >= map.getLevelScroe(map.getLevel())){
if(map.getLevel() > map.getMaxLevel())
nState = GAME_OVER;
else
nState = GAME_NEXT_ROUND;
}
break;
case GAME_NEXT_ROUND:
StringBuffer str = new StringBuffer("Level"+" "+(map.getLevel()+1));
Splash nr = new Splash(this.controller,str);
controller.setNextRoundSplash(nr);
controller.handleEvent(UIController.EventID.EVENT_NEXTROUND);
nState = GAME_INIT;
break;
case GAME_OVER://游戏结束
g.setColor(255, 255, 255);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(BACKGROUND);
g.fillRect(this.GAMEAREA_X, this.GAMEAREA_Y,
GameMap.MAP_ROW * this.BRICK_WIDTH, GameMap.MAP_ROW * this.BRICK_WIDTH);
g.setColor(255, 0, 0);
g.setFont(Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD,
Font.SIZE_LARGE));
g.drawString("Game Over", this.GAMEAREA_X + (GameMap.MAP_ROW / 2)* this.BRICK_WIDTH,
this.GAMEAREA_Y + (GameMap.MAP_ROW / 4)* this.BRICK_WIDTH,
Graphics.BASELINE | Graphics.HCENTER);
this.removeCommand(this.pauseCommand);
this.addCommand(startCommand);
break;
default:
break;
}
//在缓冲区重画
this.flushGraphics();
}
public void commandAction(Command command, Displayable displayable) {
if (command == startCommand) {
if (this.nState == GAME_OVER)
nState = GAME_INIT;
else
nState = GAME_RUN;
this.removeCommand(this.startCommand);
this.addCommand(pauseCommand);
} else if (command == pauseCommand) {
nState = GAME_SUSPEND;
this.removeCommand(this.pauseCommand);
this.addCommand(startCommand);
} else if (command == exitCommand) {
controller.handleEvent(UIController.EventID.EVENT_EXIT);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -