📄 gamecanvas.java
字号:
/*
* GameCanvas.java
*
* Copyright 2001 SkyArts. All Rights Reserved.
*/
import javax.microedition.lcdui.*;
import java.util.*;
/**
* PocketBoxing的游戏内容描绘与操作所用的类
*
* @author Hideki Yonekawa
* @version 1.0
*/
class GameCanvas extends Canvas implements Runnable, CommandListener {
/** 用来储存横向长度的变量 */
private int screenWidth;
/** 用来储存纵向长度的变量 */
private int screenHeight;
/** 储存PocketBoxing对象的变量 */
private PocketBoxing boxing;
/** Start指令变量 */
private Command startCmd = new Command("Start", Command.SCREEN, 5);
/** Exit指令变量 */
private Command exitCmd = new Command("Exit", Command.SCREEN, 1);
/** Pause指令变量 */
private Command pauseCmd = new Command("Pause", Command.SCREEN, 5);
/** Resume指令变量 */
private Command resumeCmd = new Command("Resume", Command.SCREEN, 5);
/** Quit指令变量 */
private Command quitCmd = new Command("Quit", Command.SCREEN, 1);
/**储存默认字体的变量 */
private Font defFont = Font.getDefaultFont();
/** 代表标题显示状态的常量 */
private static final short TITLE = 0;
/** 代表回合开始显示状态的常量 */
private static final short ROUND_START = 1;
/** 代表比赛显示状态的常量 */
private static final short FIGHTING = 2;
/** 代表回合结束显示状态的常量 */
private static final short ROUND_END = 9;
/** 代表全部回合过关状态的常量 */
private static final short ALL_ROUND_CLEAR = 10;
/** 储存现在显示状态的变量 */
private short gameState;
/** 代表玩家胜利状态的常量 */
private static final int WIN = 0;
/** 代表玩家失败状态的常量 */
private static final int LOSE = 2;
/** 储存玩家胜败结果的变量 */
private int result;
/** 储存默认生命点数的定数 */
private static final long DRAW_INTERVAL = 100;
/** 决定对手动作时所使用的Random变量 */
private Random random = new Random();
/** 代表玩家的变量 */
private Boxer player;
/** 代表对手的变量 */
private Enemy enemy;
/** 停止描绘线程的标志变量 */
private boolean isStopped;
/** 代表暂停状态的标志 */
private boolean isPaused;
/** 代表对手是否为挥出拳击的标志变量 */
private boolean isEnemyPanch;
/** 储存使用在标题画面上的变量 */
private Image titleImg;
/** 储存在每一回合中对手之拳击力的数组常量 */
private static final int[] DAMAGES = new int[] {
5, 8, 10, 12, 15
};
/** 储存现在回合的变量 */
private int round;
/** 储存回合数的常量 */
private static final int MAX_ROUND = DAMAGES.length;
/**
* 构造函数
* @param boxing PocketBoxing对象
*/
GameCanvas(PocketBoxing boxing) {
this.boxing = boxing;
//取得画面的描绘范围
screenWidth = getWidth();
screenHeight = getHeight();
try {
//初始化玩家
player = new Boxer();
player.setDrawX((screenWidth - 120) /2);
player.setDrawY(screenHeight - player.getHeight());
//初始化对手
enemy = new Enemy();
enemy.setDrawX(screenWidth - ((screenWidth - 120) /2));
enemy.setDrawY(screenHeight - enemy.getHeight());
//取得标题图像
titleImg = Image.createImage("/title.png");
}catch(Exception e) {}
//登录指令监听
setCommandListener(this);
//将游戏状态显示到标题
gameState = TITLE;
}
/** 对游戏中所使用之值进行初始化的常量 */
private void doGameInit() {
round = 1;
doRoundInit();
isPaused = false;
}
/** 对使用在各回合之值进行初始化的常量 */
private void doRoundInit() {
gameState = ROUND_START;
result = WIN;
player.doInitialize();
enemy.doInitialize();
isEnemyPanch = false;
//清除描绘线程停止标志
isStopped = false;
}
/** MIDlet的startApp()被调用出来时所调用的方法 */
void doStartApp() {
//根据现在的状态来操作运作
switch(gameState) {
case TITLE: //显示标题时
doTitle();
break;
case ROUND_START: //回合开始时
case FIGHTING: //回合进行中
//进行暂停
isPaused = true;
//停止游戏循环
isStopped = true;
//以防万一先删除关卡中的指令
removeCommand(pauseCmd);
removeCommand(resumeCmd);
//新增Resume指令
addCommand(resumeCmd);
break;
default: //上述情形以外时
//解除暂停
isPaused = false;
break;
}
}
/** 进行标题显示的方法 */
private void doTitle() {
//将游戏状态显示到标题
gameState = TITLE;
//以防万一先删除关卡中的指令
removeCommand(pauseCmd);
removeCommand(resumeCmd);
removeCommand(quitCmd);
//显示标题画面
repaint();
//新增指令
addCommand(exitCmd);
addCommand(startCmd);
}
/** MIDlet的pauseApp()方法被调用出来时所调用的方法 */
void doPauseApp() {
switch(gameState) {
case TITLE: //显示标题时
break;
default: //上述情形以外时
//暂停
isPaused = true;
//停止游戏循环
isStopped = true;
break;
}
}
/** 启动描绘线程的方法 */
private void doThreadStart() {
new Thread(this).start();
}
/** 结束游戏的方法 */
void doGameStop() {
isStopped= true;
}
/** 用来进行暂停或是重新开始的方法 */
void doPauseOrResume() {
if(isPaused) {
//暂停时
//重新开始
isPaused = false;
isStopped = false;
doThreadStart();
}else {
//不是暂停的时候
//进行暂停
isPaused = true;
doGameStop();
}
repaint();
}
/**
* 进行描绘的方法,一般不会直接从类本身来调用
* @param g Graphics对象
*/
protected void paint(Graphics g) {
//以白色来清除背景
g.setColor(0x00FFFFFF);
g.fillRect(0, 0, screenWidth, screenHeight);
//设定字体
g.setFont(defFont);
String drawSt;
String drawSt2 = null;
int drawX, drawY, stWidth, drawHeight;
int stHeight = defFont.getHeight();
//依照游戏状态变更描绘内容
switch(gameState) {
case TITLE: //标题显示时
//描绘标题画面
drawX = (screenWidth - titleImg.getWidth()) /2;
g.drawImage(titleImg, drawX, 0, Graphics.TOP|Graphics.LEFT);
//着作权的显示
g.setColor(0x00000000);
drawSt = "Copyright 2001";
drawX = (screenWidth - defFont.stringWidth(drawSt)) / 2;
drawY = getHeight() - stHeight *2;
g.drawString(drawSt, drawX, drawY, Graphics.TOP|Graphics.LEFT);
drawSt = "SkyArts.com";
drawX = (screenWidth - defFont.stringWidth(drawSt)) / 2;
drawY = drawY + stHeight;
g.drawString(drawSt, drawX, drawY, Graphics.TOP|Graphics.LEFT);
return;
case ROUND_START: //回合开始时
g.setColor(0x00000000);
drawSt = "Round " + String.valueOf(round);
drawX = (screenWidth - defFont.stringWidth(drawSt)) /2;
drawY = (screenHeight - stHeight * 2) / 2;
g.drawString(drawSt, drawX, drawY, Graphics.TOP|Graphics.LEFT);
drawSt = "Ready fight!";
drawX = (screenWidth - defFont.stringWidth(drawSt)) /2;
drawY = drawY + stHeight;
g.drawString(drawSt, drawX, drawY, Graphics.TOP|Graphics.LEFT);
return;
}
//描绘玩家与对手的生命点数
g.setColor(0x00000000);
drawSt = "You:" + String.valueOf(player.getLifePoint());
g.drawString(drawSt, 0, 0, Graphics.TOP|Graphics.LEFT);
drawSt = "Com:" + String.valueOf(enemy.getLifePoint());
g.drawString(drawSt, screenWidth - defFont.stringWidth(drawSt), 0, Graphics.TOP|Graphics.LEFT);
//描绘对手与玩家
enemy.doDraw(g);
player.doDraw(g);
//在暂停时等在画面显示字符串
switch(gameState) {
case FIGHTING: //回合中
if(isPaused) {
//显示代表暂停的字符串
drawSt = "Pause";
}else {
//不是暂停时为return
return;
}
break;
case ROUND_END: //回合结束时
drawSt = "Round " + String.valueOf(round);
switch(result) {
case WIN: //胜利
drawSt2 = "You win!";
break;
case LOSE: //失败
drawSt2 = "You lose!";
break;
}
break;
case ALL_ROUND_CLEAR://全回合过关时
drawSt = "You are Champion!";
break;
}
//描绘文本框
stWidth = defFont.stringWidth(drawSt);
if(drawSt2 == null) {
drawHeight = stHeight;
}else {
int tmpStWidth = defFont.stringWidth(drawSt2);
stWidth = (stWidth > tmpStWidth ? stWidth : tmpStWidth);
drawHeight = stHeight * 2;
}
drawX = (screenWidth-stWidth) / 2;
drawY = (screenHeight - (drawHeight)) / 2;
//输出第一行的消息
g.setColor(0x00BBBBBB);
g.fillRoundRect(drawX-2, drawY+2, stWidth+9, drawHeight+2, 5, 5);
g.setColor(0x00000000);
g.fillRoundRect(drawX-6, drawY-2, stWidth+11, drawHeight+4, 5, 5);
g.setColor(0x00FFFFFF);
g.fillRoundRect(drawX-4, drawY, stWidth+7, drawHeight, 5, 5);
//输出第一行的消息
g.setColor(0x00000000);
drawX = (screenWidth -defFont.stringWidth(drawSt)) / 2;
g.drawString(drawSt, drawX, drawY, Graphics.TOP|Graphics.LEFT);
//输出第二行的消息
if(drawSt2 != null) {
drawX = (screenWidth -defFont.stringWidth(drawSt2)) / 2;
drawY = drawY + stHeight;
g.drawString(drawSt2, drawX, drawY, Graphics.TOP|Graphics.LEFT);
}
}
/** 指令的事件发生时所调用的方法 */
public void commandAction(Command c, Displayable s) {
if(c == startCmd) {//Start指令
//初始化游戏以开始游戏
doGameInit();
gameState = ROUND_START;
//先将标题指令删除
removeCommand(startCmd);
removeCommand(exitCmd);
doThreadStart();
}else if(c == exitCmd) {//Exit指令
//调用出PocketBoxing类的doExit方法,将MIDlet本身结束
boxing.doExit();
}else if(c == pauseCmd) {//Pause指令
//交换Pause指令与Resume指令,调用出Pause、Resume处理方法
removeCommand(pauseCmd);
addCommand(resumeCmd);
doPauseOrResume();
}else if(c == resumeCmd) {//Resume指令
//交换Resume指令与Pause指令,调用出Pause、Resume处理方法
removeCommand(resumeCmd);
addCommand(pauseCmd);
doPauseOrResume();
}else if(c == quitCmd) {//Quit指令
//调用出游戏结束方法
doGameStop();
//删除指令
removeCommand(pauseCmd);
removeCommand(resumeCmd);
removeCommand(quitCmd);
//显示标题
doTitle();
}
}
/** 按键按下事件发生时所调用的方法 */
protected synchronized void keyPressed(int keyCode) {
if( gameState != FIGHTING ||
(gameState == FIGHTING && isPaused)) {
//回合中以外,或是在回合中暂停时为return
return;
}
//为清除按键的时候就不处理
if(keyCode == 0) return; //for KDDI
//玩家为拳击中时就是return
switch(player.getCurrentState()) {
case Boxer.PANCH_UP:
case Boxer.PANCH_DOWN:
return;
}
switch(keyCode) {
case KEY_NUM1: //按键1
case KEY_NUM4: //按键4
//进行防御时
switch(player.getCurrentState()) {
case Boxer.GUARD_UP:
case Boxer.GUARD_DOWN:
//让玩家拳击手后退
player.setCurrentState(Boxer.BACK_STEP);
break;
}
break;
case KEY_NUM2: //按键2
switch(player.getCurrentState()) {
case Boxer.BACK_STEP:
case Boxer.GUARD_DOWN:
//后退或是进行下段防御时
//让玩家的拳击手进行上段防御
player.setCurrentState(Boxer.GUARD_UP);
break;
}
break;
case KEY_NUM5: //按键5
switch(player.getCurrentState()) {
case Boxer.BACK_STEP:
case Boxer.GUARD_UP:
//进行后退或是上段防御时
//让玩家拳击手进行下段防御
player.setCurrentState(Boxer.GUARD_DOWN);
break;
}
break;
case KEY_NUM3: //按键3
switch(player.getCurrentState()) {
case Boxer.BACK_STEP:
case Boxer.GUARD_UP:
case Boxer.GUARD_DOWN:
//后退或是进行防御时
//让玩家的拳击手进行上段拳击
player.setCurrentState(Boxer.PANCH_UP);
//根据对手的状态来减少生命点数
doLifepointCheck4Enemy();
break;
}
break;
case KEY_NUM6: //按键6
switch(player.getCurrentState()) {
case Boxer.BACK_STEP:
case Boxer.GUARD_UP:
case Boxer.GUARD_DOWN:
//后退或是进行防御时
//让玩家拳击手进行下段拳击
player.setCurrentState(Boxer.PANCH_DOWN);
//根据对手的状态来减少生命点数
doLifepointCheck4Enemy();
break;
}
break;
}
}
/** 按键按下状态时被重复调用的方法 */
protected void keyRepeated(int keyCode) {
keyPressed(keyCode);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -