文章来源:J2ME开发网
接着我们来设计Piece这个类,它的作用是什么呢,它是存储单个方块信息的类,(我们的药丸由两个方块组成,即两个Piece的随机组合)该类的核心之一便是如何判断在方块落下之后和左右上下相邻的方块之间的颜色是否相同,相同即消去之间的边界线,不相同即需要在它们之间描绘上一条边界线。这样一个设计需要4个布尔值来进行判断,还需要定义好方块的高度和宽度(不同的手机的屏幕大小不一,在实际开发过程当中要注意好这样的问题)。
在看代码之前 大家先看一下UML图对整个类有个大致的了解~
核心代码如下:
/*
*
* @author 夏彦端
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
import javax.microedition.lcdui.*;
class Piece
{
int currentcolor=0x00ffffff;
/**
* 先定义四种基本颜色的常量,当然如果你认为让游戏更复杂一些才好玩,可以在这里适当的加上
* 其他的颜色~
*/
static final int red=0x00ff0000;
static final int green=0x0000ff00;
static final int blue=0x000000ff;
static final int yellow=0x00ffff00;
/**
* 下面需要定义我们的四个布尔函数值,来进行和周围方块的判别
*
*/
boolean isup =false;
boolean isdown=false;
boolean isleft=false;
boolean isright=false;
/**
* 下面需要定义方块的宽度和高度,注意这里的宽度和高度需要是可被你游戏实际屏幕的高度和宽度
* 整除的数字,否则会带来不必要的麻烦~
*
*/
static int width=12;
static int height=12;
void drawPiece(Graphics g,int x,int y)
{
g.setColor(this.currentcolor);
g.fillRect(x,y,width,height);
g.setColor(0,0,0);
if(!isup)
{
g.drawLine(x,y,x+width,y);
}
if(!isdown)
{
g.drawLine(x,y+height,x+width,y+height);
}
if(!isright)
{
g.drawLine(x+width,y,x+width,y+height);
}
if(!isleft)
{
g.drawLine(x,y,x,y+height);
}
}
}
这里我并没将currentcolor以及四个布尔值这些变量设置为封装访问,或许一些OO设计的FANS会质疑我的做法,但是因为我们这是在手机上写程序,而不是在PC上,有充足的处理机供你调度,我们如果另外再写个方法来给外部访问currentcolor的话,会给程序在手机上运行造成不必要的负担,所以我们没有对currentcolor这个变量进行任何额外的特殊处理。
OK,现在我们进入本游戏最核心的设计部分,GameCanvas类的设计!
毋庸质疑我们的GameCanvas会实现Runnable,CommandListener这两个接口,还必须定义好几个和游戏状态相关的常量,并对游戏的初始化进行处理,这里我想提一下初始化,这是曾经最让我头痛的地方,因为这里要设置好N多的变量,而且必须要对他们进行适当的初始化,否则整个程序都会出问题,拿这个游戏来说,我们必须定义好如下几个常量:
存储分数的变量,Piece数组,方块组落下速度调整变量speed,方块组落下时间的变量time,落下次数count,循环标志isstop,判断是否需要下一个方块组落下的变量isfall,判断按键是否有效的变量iskey。
怎么样,是否头很大?):在进行游戏设计之前我们必须设计好一些必须的变量,并且对其初始化,从而实现对整个游戏的流程控制。
接下来,我们需要对游戏的命令处理部分进行设计,正如我们前面流程图所画的过程,我们的几个必须命令为开始命令start,离开命令exit,暂停命令pause,继续命令resume,还有一个离开命令quit。(exit是在标题画面的是否和start配对使用,而quit则是对整个游戏的退出时起作用。)
命令部分的代码如下:
private Command start = new Command("Start", Command.SCREEN, 2);
private Command exit = new Command("Exit", Command.SCREEN, 1);
private Command pause = new Command("Pause", Command.SCREEN, 2);
private Command resume = new Command("Resume", Command.SCREEN, 2);
private Command quit = new Command("Quit", Command.SCREEN, 1);
相应的命令处理部分为:
public void commandAction(Command c, Displayable s) {
if(c == start) {
doGameInit();
gameState = GAME_START;
doThreadStart();
}else if(c == exit) {
square.Exit();
}else if(c == pause) {
removeCommand(pause);
addCommand(resume);
doPauseOrResume();
}else if(c == resume) {
removeCommand(resume);
addCommand(pause);
doPauseOrResume();
}else if(c == quit) {
doGameStop();
removeCommand(pause);
removeCommand(resume);
removeCommand(quit);
doTitle();
}
}
我们需要特别注意的是同一时刻能够在屏幕上同时显示的命令有哪几个,比如说当我们在按下quit后屏幕上就无须显示pause,resume,quit,因为此时我们已经基本上选择了离开游戏,还有在命令处理函数里面我们在每个命令按下后都会出发相应的处理函数,我们留在下一篇文章介绍这些函数的写法。