J2ME 2D小游戏入门之旅介绍
favoyang
转载请联系作者 响应www.j2medev.com站长mingjava的号召,我也和大家一起分享一下我的经验,希望大家指教。同时www.j2medev.com 欢迎各位高手的原创文章。前几天看到tony在csdn上发布自己的学习作品“是男人就坚持60s”,觉得创意虽然简单但是却很耐玩,是学习手机游戏制作的入门经典,于是一时兴起,clone了一下,图片依然使用的是tony的图片,纯粹学习之用。如果大家对这个游戏感兴趣可以与tony联系或访问他的blog(他的blog:blog.csdn.net/yesming)。
从发展趋势上说midp2.0是趋势,最便宜的midp2.0手机如ot735i,已经1700元左右;而西门子一年前的高端机cx65,现在也只有2500左右;并且2500-3000这个价位的midp2.0手机有多种选择,西门子、se、N机都有。我个人挺喜欢cx65,如果将来手机制造商成本不断降低,相信1500元的midp将不是梦…当然还要看应用是否丰富了。
言归正传,我们将使用midp 2.0 来开发我们的游戏,代号fly。开发工具jbulider。等文章全写完了,会提供src下载。
目录:
一、游戏的框架
二、完善周边工具类(图象、GameObject、Font)
三、控制飞机的移动
四、加入子弹群,实现碰撞运算
五、实现爆炸效果、并加入道具导弹
六、不足多多,你认为呢?
七、源码
一、游戏的框架
我们的游戏需要一个通用的游戏框架,也方便以后的开发,但实现一个引擎是复杂的。作为初学者如果要你考虑太多的问题,恐怕会让你偏离主线,这里只给出canvas的代码,不理解可以参看本站的另外一篇系列文章《使用MIDP2.0开发游戏》。
使用singlon实现,因为每个gamecanvas都需要很多的内存空间。另外对我们来说,只要改写gameInit(),gameMain(),一次性初始化的代码写在构造函数中。
public class MyGameCanvas extends GameCanvas implements Runnable, CommandListener{ private static MyGameCanvas instance; Graphics g; boolean running; Thread t; Command startcmd,exitcmd,restartcmd; int keystate; boolean keyevent; boolean key_up,key_down,key_left,key_right,key_fire; private boolean allowinput; public int screenwidth; public int screenheight; boolean gameover; //define your variable here //define your variable endprotected MyGameCanvas() { super(true); g=getGraphics(); running=false; t=null; addCommand(startcmd=new Command("start",Command.OK,1)); addCommand(exitcmd=new Command("exit",Command.EXIT,1)); setCommandListener(this); screenwidth=getWidth(); screenheight=getHeight();
//put your init once code here //put your init once code end } synchronized public static MyGameCanvas getInstance() { if (instance == null) { instance = new MyGameCanvas(); System.out.println("new MyGameCanvas"); } return instance; }
public void run(){ System.out.println("MyGameCanvas run start"); long st=0,et=0,diff=0; int rate=50;//16-17 frame per second while(running){ st=System.currentTimeMillis(); gameinput(); gameMain(); et=System.currentTimeMillis(); diff=et-st; if(diff<rate){ //System.out.println("Sleep "+(rate-diff)); try { Thread.sleep(rate - diff); } catch (InterruptedException ex) {} }else{ //System.out.println("rush , and the frame using time: á"+diff); } } System.out.println("MyGameCanvas run end"); }
public void start(){ if(!running){ running=true; t=new Thread(this); t.start(); } }
private void gameMain() { g.setColor(0,0,0);//clear screen g.fillRect(0,0,getWidth(),getHeight());
background.paint(g);//draw background //g.setColor(255,255,255); //g.drawString("hello",1,1,g.TOP|g.LEFT); flushGraphics(); }
private void gameInit() { gameover=false; gametime=0; gametimeoffset=System.currentTimeMillis(); allowinput=true; key_up=key_down=key_left=key_right=key_fire=false; }
public void stop(){ if(running){ running = false; } }
public void commandAction(Command c, Displayable d) { String cmdstr=c.getLabel(); if(cmdstr.equals("start")){ gameInit(); start(); removeCommand(startcmd); addCommand(restartcmd=new Command("restart",Command.OK,1)); }else if(cmdstr.equals("restart")){ stop(); while(t.isAlive()); gameInit(); start(); }else if(cmdstr.equals("exit")){ stop(); Navigate.midlet.destroyApp(false); Navigate.midlet.notifyDestroyed(); } }
private void gameinput() { if(allowinput){ keystate=getKeyStates(); keyevent=false; if((keystate & UP_PRESSED)!=0){//up key_up=true;keyevent=true; //deal your unstop job code here //System.out.println("up press"); //deal your unstop job code end }else if((keystate & UP_PRESSED)==0){//release key if(key_up==true){ key_up=false; //deal your one press-one job code here //System.out.println("up release"); //deal your one press-one job code end } }
if((keystate & DOWN_PRESSED)!=0){//down key_down=true;keyevent=true; //deal your unstop job code here //System.out.println("down press"); //deal your unstop job code end }else if((keystate & DOWN_PRESSED)==0){//release key if(key_down==true){ key_down=false; //deal your one press-one job code here //System.out.println("down release"); //deal your one press-one job code end } }
if((keystate & LEFT_PRESSED)!=0){//left key_left=true;keyevent=true; //deal your unstop job code here //System.out.println("left press"); //deal your unstop job code end }else if((keystate & LEFT_PRESSED)==0){//release key if(key_left==true){ key_left=false; //deal your one press-one job code here //System.out.println("left release"); //deal your one press-one job code end } }
if((keystate & RIGHT_PRESSED)!=0){//right key_right=true;keyevent=true; //deal your unstop job code here //System.out.println("right press"); //deal your unstop job code end }else if((keystate & RIGHT_PRESSED)==0){//release key if(key_right==true){ key_right=false; //deal your one press-one job code here //System.out.println("right release"); //deal your one press-one job code end } }
if((keystate & FIRE_PRESSED)!=0){//fire key_fire=true;keyevent=true; //deal your unstop job code here //System.out.println("fire press"); //deal your unstop job code end }else if((keystate & FIRE_PRESSED)==0){//release key if(key_fire==true){ key_fire=false; //deal your one press-one job code here //System.out.println("fire release"); //deal your one press-one job code end } } if(!keyevent){ //no keyevent here //System.out.println("NO KEY press"); //no keyevent end } } }
public static void cleanJob(){ instance=null; }
}