|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
微软什么都提供了。你可以试想一下,如果你是新手,你是希望你点一下按钮程序就能运行那,还是想自己一点一点的组织结构,然后打包发部,调错再打包......yinowl
2005年2月
媒介
我的上一篇也是第一篇文章《J2ME-MIDP1.0小游戏进门-五子棋》贴出今后,有很多多少的伴侣发邮件、加QQ、加MSN和我聊有关J2ME的内容,我很高兴也很感伤,高兴并非由于本人文章写得怎样怎样而有良多人接洽我,而是有这么多的伴侣在学J2ME,我本来觉得如今已没有人再见接洽文章的作者,看来我错了;感伤是由于,我晓得我的第一篇文章实在很差的,从人人的反响,我能感到出网上的原创材料的缺少,官方大概书本固然威望且,但总感到学的时分和实践的情形有点间隔,我在看这些材料的时分,也常常会想,实践游戏开辟公司里为怎样处置、会怎样写这个代码、程序的布局流程会怎样等等。原创文章的最年夜有点就是它包括了作者的履历,实践开辟中的履历。介于人人对我的撑持而且网上原创文章无限,我十分愿意持续写一些本人的履历和手艺,充分我们的中文资本。以是我接着写了这篇文档,文档内容即程序的开辟历程都是实在的,不是为写文章而写文章,完整是近一段工夫里先完成的程序,如今再把它写成教授教养文章。愿人人学J顺遂,多多交换(MSN:yinowl@163.comQQ:47599318E-mail:yinowl@163.com)
注重
平台:这个游戏我是在Nokia的平台上计划的,也就是说利用了FullCanvas类和针对Nokia-60系列(7650)的屏幕计划的,稍作修正就可以运转在其他型号的手机上(我已制造了Siemens-C65,Nokia-7210,和一切撑持尺度midp1.0/2.0、屏幕128x128的手机的几个移植版本,有必要能够和我接洽)
代码:同我的前一篇文章《J2ME-MIDP1.0小游戏进门-五子棋》一样,代码列出注释的情势模仿《J2MEGameProgramming》一书,依照程序功效思绪给出相干代码,一个文件的代码会依据功效在分歧的大节给出,文章停止了,代码也就完全了。这分歧于一般书中的代码以文件为单元一次全体给出,我以为如许更有助于让人人懂得一个程序从计划到最初完成的思绪。
游戏先容
扫雷这个游戏人人必定再熟习不外了,但这个双人扫雷游戏的扫雷新弄法人人大概就没见过了,实在这就是MSN软件中的一个收集联机小游戏,人人天天在利用MSN,但都很少注重或玩MSN中的游戏吧,能够说我就是把MSN上的联机双人扫雷移植到的手机上,千篇一律。假如你如今不便利上彀大概没有人和你联机看一下这个游戏的界面和弄法,不妨,我如今就来先容一下,游戏区(雷区)中一共有16x16共256个格子,个中有52颗雷,操纵除高低摆布键(固然电脑上是用鼠标点的)只必要一个挖雷键,你要做的是挖出雷,而不是用另外一个键往标示雷。两个玩家,一方入手下手挖雷,假如挖到(点到)雷,则加一分,没挖到,就和典范的扫雷一样,显现这个地位四周一圈有几个雷,假如一个雷都没有,和典范的扫雷一样,会把和这一格相连的一切四周没有雷的格子和再表面一圈格子翻开,然后另外一位玩家挖雷,谁先挖到对折以上(年夜于26颗)的雷谁就得胜,实在很复杂吧,游戏的界面以下:
游戏逻辑计划
数据布局:这个游戏属于二维棋类游戏,以是我们天然而然想到计划一个Bomb类暗示每颗雷位,用一个Bomb范例的二维数组暗示全部雷区的一切雷位,每个雷位(即每个Bomb实例)包括一个暗示该雷位是不是是雷的boolean范例的变量,一个暗示该雷位是不是已被挖的boolean范例的变量,一个暗示是不是是被玩家一挖的boolean范例的变量(否暗示是被玩家二挖),一个暗示该雷位四周八个雷位共有几颗雷的int范例变量。如许全部雷区的形态就完整被形貌出来了,然后就依据这个二维表来绘制游戏界面
游戏流程:全部游戏只利用独一一个FullCanvas类,用独一一个暗示形态的变量来把持全部游戏的形态,全部游戏也只利用自己的独一线程
玩家切换:用一个boolean范例的变量来暗示以后实行的玩家,用游戏的外框色彩及右下角的旌旗色彩来暗示出来
接上去就入手下手具体先容并列出游戏程序的各部分代码,文章的停止,全部游戏也就完成了
使用程序类:MiningMIDlet.java
起首就是一个MIDlet类。MiningMIDlet类承继自MIDlet类,用于毗连设备的使用程序办理器(ApplicationManager),经由过程办法startApp,pauseApp,destroyApp来关照游戏的入手下手,停息和烧毁停止。源代码以下:
packagecom.imy.yinowl.miningscroll;
importjavax.microedition.lcdui.Display;
importjavax.microedition.midlet.MIDlet;
publicclassMiningMIDletextendsMIDlet{
MiningCanvasminingCanvas;
//界说游戏界面的FullCanvas类MiningCanvas的对象miningCanvas
publicMiningMIDlet(){
display=Display.getDisplay(this);
miningCanvas=newMiningCanvas(this);
//天生MiningCanvas类的对象miningCanvas
}
protectedvoidstartApp(){
MiningMIDlet.display.setCurrent(miningCanvas);
//在屏幕上绘出游戏会晤miningCanvas
}
protectedvoidpauseApp(){
}
protectedvoiddestroyApp(booleanarg0){
notifyDestroyed();
}
}
地雷类:Bomb.java
Bomb类界说了二维雷区内每个雷位的一切信息,如许用一个Bomb范例的二维表就可以完整形貌全部雷区的形态。我在Bomb类中,用了三个boolean型变量和一个int型变量来形貌一个雷位:boolean型变量isBomb:形貌这个地位是不是是雷;boolean型变量hasFound:形貌这个地位是不是已被发掘;boolean型变量isPlayer1:形貌假如这个地位是雷,并且已被发掘,那末是不是是玩家一发掘,假如值是false,暗示是被玩家二发掘,只要在isBomb和hasFound都为true时,这个变量的值才成心义;int型变量bombaround:形貌此地位四周八个地位共有几颗雷,这个变量除用来告知玩家四周雷数还能够用来翻开成片的非雷地区。经由过程这四个变量共同分歧的图片就能够把全部雷区的分歧形态的图形界面出现在玩家眼前。Bomb类的源代码以下:
packagecom.imy.yinowl.miningscroll;
publicclassBomb{
intbombaround;
booleanisPlayer1;
booleanhasFound;
booleanisBomb;
publicBomb(){
bombaround=0;
isBomb=false;
hasFound=false;
isPlayer1=true;
}
}
界面逻辑类框架:MiningCanvas.java
一样平常游戏会呈现良多的界面,比方游戏的LOGO(也称作闪屏或启动界面)、入手下手菜单(主菜单)、设置界面、游戏界面、匡助界面、关于界面、游戏时匡助菜单等等,我的这个游戏不必要设置以是没有设置界面,一切的这些界面我们都整合在这一承继自Nokia-API中的FullCanvas类中,我们要尽量的较少类的数量以削减资本的开支,详细是怎样整合的,我们会再稍候具体先容。FullCanvas不撑持Command及CommandListener,以是我们不克不及再利用本来的命令办法;我们会必要经由过程线程把持启动界面的停止工夫,以是会用到游戏本人的主线程。
全部游戏我们经由过程一个int型变量gamestate共同switch布局来把持游戏中所处的界面形态,也就是以后所显现界面,在switch布局中依据gamestate分歧的值,绘制分歧的界面,在响应的工夫改动gamestate的值,然后repaint,也就改动了接上去玩家所瞥见的界面,也一样用这个办法在keyPressed办法中把持玩家按键的响应
框架源代码以下:
packagecom.imy.yinowl.miningscroll;
importjava.io.IOException;
importjava.util.Random;
importjava.util.Vector;
importjavax.microedition.lcdui.Alert;
importjavax.microedition.lcdui.AlertType;
importjavax.microedition.lcdui.Font;
importjavax.microedition.lcdui.Graphics;importjavax.microedition.lcdui.Image;importcom.nokia.mid.ui.FullCanvas;
publicclassMiningCanvasextendsFullCanvasimplementsRunnable{
MiningMIDletminingMIDlet;
intgamestate;
staticfinalintGAMESTATE_SPLASH=0;
staticfinalintGAMESTATE_MENU=1;
staticfinalintGAMESTATE_GAMEING=2;
staticfinalintGAMESTATE_HELP=3;
staticfinalintGAMESTATE_SETTING=4;
staticfinalintGAMESTATE_ABOUT=5;
staticfinalintGAMESTATE_GAMEMENU=6;
staticfinalintGAMESTATE_COUNT=7;
publicMiningCanvas(MiningMIDletminingMIDlet){
super();
this.miningMIDlet=miningMIDlet;
gamestate=0;//游戏加载时默许界面为启动界面
}
protectedvoidpaint(Graphicsg){
g.setColor(0x00FFFFFF);
g.fillRect(0,0,canvasW,canvasH);
switch(gamestate){
caseGAMESTATE_SPLASH:
paintSplashScreen(g);//绘制游戏启动界面
break;
caseGAMESTATE_MENU:
paintMenuScreen(g);//绘制游戏主菜单
break;
caseGAMESTATE_HELP:
paintHelpScreen(g);//绘制匡助界面
break;
caseGAMESTATE_GAMEING:
paintGameScreen(g);//绘制游戏界面
break;
caseGAMESTATE_GAMEMENU:
paintGameMenuScreen(g);//绘制游戏时菜单界面
break;
default:
paintMenuScreen(g);//绘制游戏主菜单
break;
}
publicvoidrun(){
}
protectedsynchronizedvoidkeyPressed(intkeyCode){
intaction=getGameAction(keyCode);
switch(gamestate){
}
}
}
接上去就入手下手计划绘制游戏的每个界面了
启动画面
一样平常启动画面是一个静态的或静态的图片(静态占多数),显现了游戏的LOGO和游戏的刊行或制造商的称号,停止工夫为三秒,并且不克不及经由过程按键跳过,假如游戏必要举行一些费时的初始化,能够在这三秒中同时举行。这停止的三秒经由过程把持本线程来完成。图片:源代码以下:
在MiningCanvas.java中增加以下代码
Threadthread;
ImagesplashImage;
intsplashDelayTime;
publicMiningCanvas(MiningMIDletminingMIDlet){
...
splashDelayTime=3000;
try{
splashImage=Image.createImage("/occo.png");
}catch(IOExceptione){}
thread=newThread(this);
thread.start();
}
privatevoidpaintSplashScreen(Graphicsg){
g.setColor(0x00000000);
g.drawImage(splashImage,getWidth()/2,getHeight()/2-5,Graphics.HCENTER|Graphics.VCENTER);
}
publicvoidrun(){
try{
Thread.sleep(splashDelayTime);
}catch(InterruptedExceptione){}
gamestate=GAMESTATE_MENU;//在启动动画停止3秒后,改动游戏形态变量值,跳转到主菜单形态
repaint();
}
游戏主菜单界面
主菜单经由过程分歧巨细的两种字体来显现选中和未选中的菜单项,用一个int型变量暗示以后选中的菜单项,用一个String型的一维数组贮存菜单项的内容,在keyPresseed办法中依据菜单选项变量menuIdx来响应的改动游戏的形态,从而使游戏跳转到响应的形态。需增加的源代码以下:
在MiningCanvas.java中增加以下代码
staticfinalFontlowFont=Font.getFont(Font.FACE_MONOSPACE,Font.STYLE_PLAIN,Font.SIZE_SMALL);
staticfinalFonthighFont=Font.getFont(Font.FACE_MONOSPACE,Font.STYLE_BOLD,Font.SIZE_MEDIUM);
//两种字体,分离是未选中和选中形态的字体
staticfinalintlowColor=0x000000FF;//未选中形态的色彩staticfinalinthighColor=0x00FF0000;//选中形态的色彩staticfinalinthighBGColor=0x00CCCCCC;//选中形态的背景色彩
staticfinalintMAIN_NEW_GAME=0;staticfinalintMAIN_SETTINGS=1;staticfinalintMAIN_HELP=2;staticfinalintMAIN_ABOUT=3;staticfinalintMAIN_EXIT=4;staticfinalintMAIN_MENU_ITEM_COUNT=5;staticString[]mainMenu=newString[MAIN_MENU_ITEM_COUNT];
staticintcanvasW;//屏幕宽staticintcanvasH;//屏幕高staticintstartHeight;//菜单列表的肇端高度staticintspacing;//菜单项间宽度staticintmenuIdx;//以后选中的菜单项
publicMiningCanvas(MiningMIDletminingMIDlet){
...
menuIdx=0;
canvasW=getWidth();canvasH=getHeight();
spacing=highFont.getHeight()/2;
startHeight=(canvasH-(lowFont.getHeight()*mainMenu.length)-(mainMenu.length-1)*spacing)/2;
mainMenu[0]="NewGame";
mainMenu[1]="Settings";
mainMenu[2]="Help";
mainMenu[3]="About";
mainMenu[4]="Exit";
}
privatevoidpaintMenuScreen(Graphicsg){
for(inti=0;i<mainMenu.length;i++){
if(i==menuIdx){
g.setColor(highBGColor);
g.fillRect(0,startHeight+i*(lowFont.getHeight()+spacing)-(highFont.getHeight()
-lowFont.getHeight())/2,canvasW,highFont.getHeight());
g.setFont(highFont);
g.setColor(highColor);
g.drawString(mainMenu[i],(canvasW-highFont.stringWidth(mainMenu[i]))/2,
startHeight+i*(lowFont.getHeight()+spacing)-(highFont.getHeight()-lowFont.getHeight())/2,
Graphics.TOP|Graphics.LEFT);
}else{
g.setFont(lowFont);
g.setColor(lowColor);
g.drawString(mainMenu[i],(canvasW-lowFont.stringWidth(mainMenu[i]))/2,
startHeight+i*(lowFont.getHeight()+spacing),Graphics.TOP|Graphics.LEFT);
}
}
}
在keyPressed办法中的switch布局中增加
caseGAMESTATE_MENU:
{
if(getGameAction(keyCode)==FullCanvas.UP&&menuIdx-1>=0){
menuIdx--;
}
elseif(getGameAction(keyCode)==FullCanvas.DOWN&&menuIdx+1<mainMenu.length){
menuIdx++;
}
elseif(getGameAction(keyCode)==FullCanvas.FIRE){
switch(menuIdx){//选中后,依照选项值改动游戏形态值,跳转到响应的形态
caseMAIN_NEW_GAME:
gamestate=GAMESTATE_GAMEING;
break;
caseMAIN_SETTINGS:
gamestate=GAMESTATE_SETTING;
break;
caseMAIN_HELP:
gamestate=GAMESTATE_HELP;
break;
caseMAIN_ABOUT:
gamestate=GAMESTATE_ABOUT;
break;
caseMAIN_EXIT:
miningMIDlet.destroyApp(false);
break;
}
}
break;
}
}
微软什么都提供了。你可以试想一下,如果你是新手,你是希望你点一下按钮程序就能运行那,还是想自己一点一点的组织结构,然后打包发部,调错再打包...... |
|