📄 maincanvas.java
字号:
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.Graphics;
//import com.nokia.mid.ui.FullCanvas;
final class MainCanvas
extends Canvas
implements Runnable {
//______________公用的控制变量及常量__________________________
static private final int MILLIS_PER_TICK = 120;
public a aMidlet = null;
public int screenW = 0, screenH = 0; //屏幕宽高
public final int CHARW = 17, CHARH = 17; //单个字的宽高
public Font font;
public static final byte
STATE_NONE = 0
, STATE_ERROR = 1
, STATE_LODING = 2
, STATE_SPLASH = 3
, STATE_MENU = 4
, STATE_GAMERUN = 5
, STATE_EXIT = 7
, STATE_HELP = 8
, STATE_OPTION = 9
, STATE_ABOUT = 10
;
long timeTaken; //run()的一个周期所用的时间
private volatile Thread self;
//各种不同的按键状态
static public final byte //在isPressed()中作为参数使用
MASK_NUM0 = 0
, MASK_NUM1 = 1
, MASK_NUM2 = 2
, MASK_NUM3 = 3
, MASK_NUM4 = 4
, MASK_NUM5 = 5
, MASK_NUM6 = 6
, MASK_NUM7 = 7
, MASK_NUM8 = 8
, MASK_NUM9 = 9
, MASK_LEFT = 10
, MASK_UP = 11
, MASK_RIGHT = 12
, MASK_DOWN = 13
, MASK_FIRE = 14
, MASK_STAR = 15
, MASK_POUND = 16
, MASK_SOFT1 = 17
, MASK_SOFT2 = 18
, MASK_SOFT3 = 19
;
int keyFlag = 0; //用来存放键是否被按下,用位来表示,当键按下时把相应位置1,直到按键释放才置0
int keyFlagIm = 0;
//_______________用户自定义的变量及常量_________________________
TicTacToe pg;
//--------------------------------------------------------------------------------------
// 方法
//--------------------------------------------------------------------------------------
/**
* 构造方法
* @param aMidlet a 向当前画布传入一个MIDlet实例
*/
public MainCanvas(a aMidlet) {
this.aMidlet = aMidlet;
screenW = this.getWidth();
screenH = this.getHeight();
font = Font.getDefaultFont(); //moto303
//做相应的初始化操作
pg = new TicTacToe(this);
}
/**
* 启动线程
*/
synchronized public void begin() {
self = new Thread(this);
self.start();
}
/**
* 结束线程
*/
synchronized public void stop() {
self = null;
}
/**
* 线程体
*/
public void run() {
final Thread currentThread = Thread.currentThread(); //
while (currentThread == self) {
try {
final long startTime = System.currentTimeMillis();
if (isShown()) {
repaint(); //所有游戏的绘制和逻辑均在里面实现
serviceRepaints(); //写屏
}
timeTaken = System.currentTimeMillis() - startTime;
if (timeTaken < MILLIS_PER_TICK) {
synchronized (this) {
wait(MILLIS_PER_TICK - timeTaken); //使每个周期大致相等
}
}
else {
currentThread.yield(); //让出控制权,防止饿死其它线程
}
}
catch (Exception ex) {
// won't be thrown
}
}
//release
}
/**
* 绘制方法
* @param g Graphics 系统调度线程调度时传入的图像句柄
*/
public void paint(Graphics g) { //由此触发Canvas的重绘。
try {
g.setColor(0x000000);
g.fillRect(0, 0, screenW, screenH); //清屏
pg.draw(g);
//debug
int drawY = 10;
g.setColor(0x0000ff);
g.drawString("MSPF:" + timeTaken, 0, drawY += 18, g.TOP | g.LEFT);
g.drawString("keyFlag:" + keyFlag, 0, drawY += 18, g.TOP | g.LEFT);
g.drawString("keyFlagIm:" + keyFlagIm, 0, drawY += 18, g.TOP | g.LEFT);
//end debug
}
catch (Exception e) {}
finally {
keyFlagIm = 0; //在每个paint()的最后,把临时键标志强行复位,因为下个周期,他已不再有作用
}
}
//;----------------------------------------------------------------------
//; 按键处理机制 a simple key process arch
//;----------------------------------------------------------------------
/**
* 实现的按键方法 ,override Canvas keyPressed
* @param keyCode int 系统事件调度线程传入的键码
*/
protected void keyPressed(int keyCode) {
switch (keyCode) {
case Canvas.KEY_NUM0:
keyFlag |= (0x00000001 << MASK_NUM0); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM1:
keyFlag |= (0x00000001 << MASK_NUM1); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM2:
keyFlag |= (0x00000001 << MASK_NUM2); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM3:
keyFlag |= (0x00000001 << MASK_NUM3); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM4:
keyFlag |= (0x00000001 << MASK_NUM4); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM5:
keyFlag |= (0x00000001 << MASK_NUM5); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM6:
keyFlag |= (0x00000001 << MASK_NUM6); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM7:
keyFlag |= (0x00000001 << MASK_NUM7); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM8:
keyFlag |= (0x00000001 << MASK_NUM8); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM9:
keyFlag |= (0x00000001 << MASK_NUM9); // 向左移N位后,即该位置1
break;
case Canvas.KEY_STAR:
keyFlag |= (0x00000001 << MASK_STAR); // 向左移N位后,即该位置1
break;
case Canvas.KEY_POUND:
keyFlag |= (0x00000001 << MASK_POUND); // 向左移N位后,即该位置1
break;
}
switch (getGameAction(keyCode)) {
case Canvas.UP:
keyFlag |= (0x00000001 << MASK_UP); // 向左移N位后,即该位置1
break;
case Canvas.DOWN:
keyFlag |= (0x00000001 << MASK_DOWN); // 向左移N位后,即该位置1
break;
case Canvas.LEFT:
keyFlag |= (0x00000001 << MASK_LEFT); // 向左移N位后,即该位置1
break;
case Canvas.RIGHT:
keyFlag |= (0x00000001 << MASK_RIGHT); // 向左移N位后,即该位置1
break;
case Canvas.FIRE:
keyFlag |= (0x00000001 << MASK_FIRE); // 向左移N位后,即该位置1
break;
}
//给即时按键标志赋值,用这个变量可在isPressed()中检测到是否有短时按键产生
//set temp key flag value
keyFlagIm = keyFlag;
}
/**
* 释放键的方法, override Canvas keyReleased method
* @param keyCode int
*/
protected void keyReleased(int keyCode) {
switch (keyCode) {
case Canvas.KEY_NUM0:
keyFlag &= ~ (0x00000001 << MASK_NUM0); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM1:
keyFlag &= ~ (0x00000001 << MASK_NUM1); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM2:
keyFlag &= ~ (0x00000001 << MASK_NUM2); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM3:
keyFlag &= ~ (0x00000001 << MASK_NUM3); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM4:
keyFlag &= ~ (0x00000001 << MASK_NUM4); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM5:
keyFlag &= ~ (0x00000001 << MASK_NUM5); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM6:
keyFlag &= ~ (0x00000001 << MASK_NUM6); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM7:
keyFlag &= ~ (0x00000001 << MASK_NUM7); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM8:
keyFlag &= ~ (0x00000001 << MASK_NUM8); // 向左移N位后,即该位置1
break;
case Canvas.KEY_NUM9:
keyFlag &= ~ (0x00000001 << MASK_NUM9); // 向左移N位后,即该位置1
break;
case Canvas.KEY_STAR:
keyFlag &= ~ (0x00000001 << MASK_STAR); // 向左移N位后,即该位置1
break;
case Canvas.KEY_POUND:
keyFlag &= ~ (0x00000001 << MASK_POUND); // 向左移N位后,即该位置1
break;
}
switch (getGameAction(keyCode)) {
case Canvas.UP:
keyFlag &= ~ (0x00000001 << MASK_UP); // 向左移N位后,即该位置1
break;
case Canvas.DOWN:
keyFlag &= ~ (0x00000001 << MASK_DOWN); // 向左移N位后,即该位置1
break;
case Canvas.LEFT:
keyFlag &= ~ (0x00000001 << MASK_LEFT); // 向左移N位后,即该位置1
break;
case Canvas.RIGHT:
keyFlag &= ~ (0x00000001 << MASK_RIGHT); // 向左移N位后,即该位置1
break;
case Canvas.FIRE:
keyFlag &= ~ (0x00000001 << MASK_FIRE); // 向左移N位后,即该位置1
break;
}
}
/**
* 用来标示是否某个键被按了,这里采用增加一个标志位,可以有效防止在tick()栓测的过程中,短暂按键不能被程序知道的问题 参考岳振的思想
* to determine what key pressed in this game cycle
*
* @param keyLabel int
* @return boolean
*/
public boolean isPressed(byte keyLabel) {
if ( ( (keyFlagIm >>> keyLabel) & 0x00000001) == 1) { //曾按过也返回真
keyFlagIm &= (~ (0x00000001 << keyLabel)); //把相应的位置为0;
// keyFlagIm = 0; //取一次后把所有的位置0,这种处理方式不支持多键同按的系统,否则应使用上面一句
return true;
}
if ( ( (keyFlag >>> keyLabel) & 0x00000001) == 1) { //如果此标志位为1则返回真
return true;
}
return false;
}
/**
* 复位键状态,在使用这个键后,有时候,我们并不想这个键值在下一个循环中仍有效,因此我们将其复位,防止后
* 面的操作也被这个键值所作用。
*
* reset all key flags
*/
public final void resetKey() {
keyFlag = keyFlagIm = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -