📄 snakecanvas.java~175~
字号:
package snake;
import java.io.*;
import java.util.*;
import javax.microedition.lcdui.*;
public class SnakeCanvas extends Canvas implements Runnable, CommandListener {
public final static int CELL_SIZE = 5; //蛇的宽度
public final static int BACK_COLOR = 0x00e0f0f0; //背景颜色
public final static int PANEL_COLOR = 0x00e8d8ba; //面板颜色
public final static int FOOD_COLOR = 0x00308020; //豆子颜色
public final static int SNAKE_COLOR = 0x000000FF; //蛇的颜色
private final static int WAIT_PERIOD = 300; //默认最长的刷新时间间隔
private final static int MAX_LEVEL = 4; //游戏的最高等级
private final static int PANEL_YPOS = 50; //面板的起点纵坐标
private final static int [] nLevelNum = {32,64,128,256};
public final static byte GAME_INIT = 1;
public final static byte GAME_RUN = 2;
public final static byte GAME_PAUSE = 3;
public final static byte GAME_OVER = 4;
private int nWidth, nHeight; //游戏区域的宽和高
private int xCellNum, yCellNum; //游戏区域x,y方向的单元格数目
private int wWhite = 0; //屏幕横向的空白区域宽度
private int nLevel = 1; //游戏等级
private int nScore = 0; //游戏得分
private int nFoodEaten = 0; //游戏当中总共吃到的豆子的数目
private String user = ""; //游戏者信息
private byte nState = GAME_INIT; //游戏运行状态
private boolean bRefreshAll = true; //是否需要全部刷新
private Snake snake; //贪吃蛇
private Food food; //豆子
private Thread thread;
private Image imgBox; //用于显示信息的方框
private Font ft; //系统字体
private boolean bGameOver = false; //标识游戏是否结束
private Command exit; //退出命令
private Command pause; //暂停命令
private Command start; //开始命令
private Command TopScore; //查看积分榜命令
public SnakeCanvas(int level, String name) {
nLevel = level;
user = name;
//处理游戏区域大小
try {
imgBox = Image.createImage("/res/box.png");
}
catch (IOException ex) {
}
ft = Font.getFont(Font.FACE_PROPORTIONAL,
Font.STYLE_BOLD, Font.SIZE_MEDIUM);
int nPanelWidth = imgBox.getWidth();
int temp = (getWidth() - nPanelWidth) % CELL_SIZE;
wWhite = temp + nPanelWidth;
nWidth = getWidth() - wWhite;
nHeight = getHeight();
xCellNum = nWidth / CELL_SIZE;
yCellNum = nHeight / CELL_SIZE;
thread = new Thread(this);
thread.start();
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**
* 初始化可能出现异常的数据
* @throws Exception
*/
private void jbInit() throws Exception {
setCommandListener(this);
exit = new Command("exit", Command.EXIT, 0);
pause = new Command("pause", Command.OK, 1);
start = new Command("start", Command.OK, 1);
TopScore = new Command("TopScore", Command.OK, 1);
// add command
addCommand(exit);
addCommand(pause);
snake = new Snake(this);
food = new Food(this);
int x = food.getX();
int y = food.getY();
//确保所产生的食物不在蛇身上
while(snake.isPtInSnake(x,y)){
food.createFood();
x = food.getX();
y = food.getY();
}
}
/**
* 命令响应函数
* @param command Command
* @param displayable Displayable
*/
public void commandAction(Command command, Displayable displayable) {
switch(command.getCommandType()){
case Command.EXIT:
SnakeMIDlet.quitApp();
break;
case Command.OK:
if (command == pause && nState == GAME_RUN) {
nState = GAME_PAUSE;
removeCommand(pause);
addCommand(start);
}
else if (command == start) {
nState = GAME_RUN;
removeCommand(start);
addCommand(pause);
} else if(command == TopScore){
viewScore();
}
break;
}
}
/**
* 创建积分榜查看界面,显示最高分信息
*/
private void viewScore() {
ScoreRecordStore srs = new ScoreRecordStore();
Vector v = new Vector();
v = srs.loadScoreRecord("SnakeScore10");
ScoreRecordView srv = new ScoreRecordView(v);
SnakeMIDlet.setCurrent(srv);
}
/**
* 响应键盘操作
* @param keyCode int
*/
protected void keyPressed(int keyCode){
int action = getGameAction(keyCode);
switch(action){
case Canvas.DOWN:
case Canvas.KEY_NUM8:
snake.setDirection(Snake.DOWN);
break;
case Canvas.UP:
case Canvas.KEY_NUM2:
snake.setDirection(Snake.UP);
break;
case Canvas.LEFT:
case Canvas.KEY_NUM4:
snake.setDirection(Snake.LEFT);
break;
case Canvas.RIGHT:
case Canvas.KEY_NUM6:
snake.setDirection(Snake.RIGHT);
break;
}
}
/**
* 绘制函数
* @param g Graphics
*/
protected void paint(Graphics g) {
switch (nState) {
case GAME_INIT:
g.setColor(this.BACK_COLOR);
g.fillRect(0, 0, nWidth, nHeight);
g.setColor(this.PANEL_COLOR);
g.fillRect(getWidth()-wWhite, 0, wWhite, getHeight());
drawPanel(g);
nState = GAME_RUN;
break;
case GAME_RUN:
if (bRefreshAll) {
bRefreshAll = false;
snake.paint(g);
food.paint(g);
drawPanel(g);
}
else {
g.setClip(0, 0, nWidth, nHeight);
snake.update(g);
}
//是否吃到食物
if (food.getX() == snake.getXHead() &&
food.getY() == snake.getYHead()) {
snake.eat();
nScore += nLevel;
nFoodEaten++;
bRefreshAll = true;
//是否过关
if (nFoodEaten > nLevelNum[nLevel - 1]) {
nFoodEaten = 0;
nLevel++;
if (nLevel > MAX_LEVEL)
nState = GAME_OVER;
}
//重新产生食物
food.createFood();
int x = food.getX();
int y = food.getY();
//确保所产生的食物不在蛇身上
while (snake.isPtInSnake(x, y)) {
food.createFood();
x = food.getX();
y = food.getY();
}
food.paint(g);
}
break;
case GAME_PAUSE:
break;
case GAME_OVER:
removeCommand(pause);
addCommand(TopScore);
g.setColor(255, 0, 0);
g.setFont(Font.getDefaultFont());
g.drawString("Game Over", nWidth/2, nHeight/2,
Graphics.HCENTER | Graphics.BASELINE);
saveScore();
break;
default:
break;
}
}
/**
* 保存分数记录
*/
private void saveScore() {
if(nScore <=0)
return;
ScoreRecordStore srs = new ScoreRecordStore();
Vector v = new Vector();
v = srs.loadScoreRecord("SnakeScore10");
if (v.size() < 10) {
Record r = new Record( (short) nScore, user);
v.addElement(r);
srs.saveScoreRecord(v, "SnakeScore10");
}
else {
Record rt = (Record) v.lastElement();
if (nScore > rt.nScore) {
v.removeElementAt(9);
Record r = new Record( (short) nScore, user);
v.addElement(r);
srs.saveScoreRecord(v, "SnakeScore10");
}
}
}
/**
* 绘制左侧的面板
*/
private void drawPanel(Graphics g) {
int yPos = PANEL_YPOS;
int x,y;
String str;
g.setFont(ft);
g.setColor(255, 0, 0);
int ftHeight = ft.getHeight();
int imgSpace = imgBox.getHeight();
int space = ftHeight + imgSpace + 15;
//绘制用户名
g.drawString("user", nWidth, yPos, Graphics.LEFT|Graphics.TOP);
g.drawImage(imgBox, nWidth, yPos + ftHeight, Graphics.LEFT | Graphics.TOP);
x = nWidth + imgBox.getWidth()/2;
y = yPos +ftHeight + 5;
str = user;
g.drawString(user, x, y, Graphics.HCENTER | Graphics.TOP);
//绘制LEVEL
yPos += space;
g.drawString("level", nWidth, yPos, Graphics.LEFT|Graphics.TOP);
g.drawImage(imgBox, nWidth, yPos + ftHeight, Graphics.LEFT | Graphics.TOP);
str = "" + nLevel;
y = yPos +ftHeight + 5;
g.drawString(str, x, y, Graphics.HCENTER | Graphics.TOP);
//绘制分数
yPos += space;
g.drawString("score", nWidth, yPos, Graphics.LEFT|Graphics.TOP);
g.drawImage(imgBox, nWidth, yPos + ftHeight, Graphics.LEFT | Graphics.TOP);
str = "" + nScore;
y = yPos +ftHeight + 5;
g.drawString(str, x, y, Graphics.HCENTER | Graphics.TOP);
}
public int getXCellNum(){
return xCellNum;
}
public int getYCellNum(){
return yCellNum;
}
public void run() {
while(!bGameOver){
synchronized (snake) {
try {
thread.sleep(WAIT_PERIOD - 50 * nLevel);
}
catch (InterruptedException ex) {
}
repaint();
}
}
}
/**
* 测试蛇是否超出游戏区域
* @param x int
* @param y int
* @return boolean
*/
public boolean isPtInBound(int x, int y){
if(x<0 || x > xCellNum)
return false;
if(y<0 || y > yCellNum)
return false;
return true;
}
/**
* 设置游戏结束标志
*/
public void setGameOver() {
bGameOver = true;
nState = GAME_OVER;
repaint();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -