J2ME 2D小游戏入门之旅(一)游戏的框架

原创 2005年05月24日 14:32:00

作者:favoyang 文章来源:J2ME开发网

   前几天看到tony在csdn上发布自己的学习作品“是男人就坚持60s”,觉得创意虽然简单但是却很耐玩,是学习手机游戏制作的入门经典,于是一时兴起,clone了一下,图片依然使用的是tony的图片,纯粹学习之用。如果大家对这个游戏感兴趣可以与tony联系或访问他的blog。

     从发展趋势上说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 end


  protected 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;
  }


}

     从发展趋势上说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 end


  protected 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;
  }


}

   

java j2me 月光战机 手机小游戏

  • 2009年07月10日 12:42
  • 78KB
  • 下载

自制j2me小游戏贪食蛇源代码

  • 2009年10月28日 09:27
  • 152KB
  • 下载

j2me手机游戏开发

从Java EE到Java ME的通讯 前言   本文源于 2005 年底一个真实的手机项目。很早就想为那个项目写点什么了,至今才提笔,也算是了却一个心愿。虽然时隔两年,但技术本身并没有发...

j2me猜数字小游戏

  • 2010年12月18日 13:12
  • 21KB
  • 下载

浅谈J2me游戏如何快速移植到Android

前言   小白:“老大,你让做的三个J2me游戏搞定了,请看DEMO。” 老大:“恩,不错,小白,你知道Android这个平台吧?” 小白:“恩,听过。听说和J2ME有很多共同点。” 老大:...

j2me小游戏

  • 2012年09月26日 11:18
  • 32.05MB
  • 下载

J2ME坦克小游戏代码

  • 2008年12月01日 14:49
  • 7KB
  • 下载

J2ME 拼图游戏 快速开发 全过程 之代码祥解(1 )——程序入口与控制器开发

程序入口,代码: /*  * TilePuzzle.java  *  * Created on 2012年3月14日, 下午3:19  */ package cn.edu.xtu....

j2me手机扫雷小游戏

  • 2009年07月24日 22:52
  • 118KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:J2ME 2D小游戏入门之旅(一)游戏的框架
举报原因:
原因补充:

(最多只允许输入30个字)