明辉手游网中心:是一个免费提供流行视频软件教程、在线学习分享的学习平台!

J2me手机游戏编程初体验

[摘要]出发   学习J2me已经有一段时间了,按书上说的例子也做了无数,虽然基本理解了J2me的整体编程思想,但做游戏程序却仍然感到毫无头绪。   本想试着照扒游戏【魔塔】,反复考虑了很长时间,感觉其中复杂度较高,而且部分细节如关卡的设置、与敌人对战等程序也都没有接触过,所以决定做一个简易的推箱子游戏,...
出发

  学习J2me已经有一段时间了,按书上说的例子也做了无数,虽然基本理解了J2me的整体编程思想,但做游戏程序却仍然感到毫无头绪。

  本想试着照扒游戏【魔塔】,反复考虑了很长时间,感觉其中复杂度较高,而且部分细节如关卡的设置、与敌人对战等程序也都没有接触过,所以决定做一个简易的推箱子游戏,有两关即可。

  虽说是简单很多,但真正想要做起来的时候却无从下手;想了好久,脑袋里仍然是乱糟糟的,反正也没有思路,不如静下来,做个简单的设计吧。

  设计

  由于需求简易,就直接进入设计吧。^_^

  首先,一定要有个主应用程序类,相信大家都应改知道;其次,不可避免,一定要有画布,为了把程序的画面呈现出来;其中,我觉得还是把地图跟画布分开,这样对地图管理比较容易,而且增加或修改地图比较方便;然后一定要有主角对吧,总要找个推箱子的人;说到箱子,也许箱子也需要管理吧。

  制作图片

  我一向认为我自己没有什么审美观点,不过做程序总要些图片,没办法,只有映着头皮做吧,多亏前一阵学了些简单的PhotoShop处理,做起来也不是十分困难,只不过选择的图片稍微差了点,对付着用吧。

  开工

  所谓万事具备只欠东风,虽然我们的设计虽然简单,总可以对付着用吧^_^。

  绘制背景

  先抛开箱子(BoxSprite)和推箱子的人(PlayerSprite)两个类,把全部经历集中到绘制地图上(其实不过是第一幅地图)。

  这其中需要先了解几个类,GameCanvas 、LayerManager和TiledLayer等几个类。我们这里主要用TiledLayer这种方法构造背景。

  GameCanvas 类:GameCanvas实际上就是屏幕上一个可绘制区域。但每个GameCanvas类都有一个独立的buffer,从而不但减少了堆的使用率,也可以使用单独的堆控制程序。

  LayerManager 类:这个类用来管理图像的各个层,它将按正确的位置和次序渲染所有在它控制下的土层。

  TiledLayer 类:通过使用这个函数可以定义游戏背景的特定区域,并且可以重复利用它们生成一个完整的图像。

  具体参考相关资料。

  主程序

  import javax.microedition.lcdui.*;

  import javax.microedition.midlet.MIDlet;

  public class myBox extends MIDlet implements CommandListener

  {

   private BoxCanvas boxCanvas;

   protected Display display;

  

   public void startApp()

   {

   display = Display.getDisplay(this);

   try{

   boxCanvas = new BoxCanvas(this);

   boxCanvas.start();

  

   Command exitCommand = new Command("Exit", Command.EXIT, 1);

   boxCanvas.addCommand(exitCommand);

   boxCanvas.setCommandListener(this);

   }catch(Exception e){

   }

   display.setCurrent(boxCanvas);

   }

  

   public Display getDisplay()

   {

   return display;

   }

  

   public void pauseApp(){

   }

  

   public void destroyApp(boolean unconditional){

   System.gc();

   notifyDestroyed();

   }

  

   public void commandAction(Command c, Displayable s) {

   if (c.getCommandType() == Command.EXIT) {

   destroyApp(true);

   notifyDestroyed();

   }

   }

  }
  
  BoxCanvas类

  import javax.microedition.lcdui.*;

  import javax.microedition.lcdui.game.*;

  import java.util.*;

  public class BoxCanvas extends GameCanvas implements Runnable

  {

   private myBox midlet;

   private BoxMaps boxMaps;

  

   private Thread gameThread = null;

   private LayerManager layerManager;

   private TiledLayer tl_ground;

  

   private static final int MILLIS_PER_TICK = 50;

  

   public BoxCanvas(myBox midlet) throws Exception

   {

   super(true);

   this.midlet = midlet;

  

   boxMaps = new BoxMaps();

   tl_ground = boxMaps.getTiled();

  

   layerManager = new LayerManager();

   layerManager.append(tl_ground);

   }

  

   public void start()

   {

   gameThread = new Thread(this);

   gameThread.start();

   }

  

   public void stop()

   {

   gameThread = null;

   }

  

   public void run()

   {

   Graphics g = getGraphics();

  

   Thread currentThread = Thread.currentThread();

   try{

   while (currentThread == gameThread) {

   long startTime = System.currentTimeMillis();

   if (isShown()) {

   //tick();

   //input();

   render(g);

   }

   long timeTake = System.currentTimeMillis() - startTime;

   if (timeTake < millis_per_tick)="" {="">

   synchronized (this) {

   wait(MILLIS_PER_TICK - timeTake);

   }

   } else {

   currentThread.yield();

   }

   }

   }catch (InterruptedException ex) {

   // won't be thrown

   }

   }

  

   private void render(Graphics g) {

   //g.setColor(0xF8DDBD);

   int w = getWidth();

   int h = getHeight();

  

   int x = (w - 192) / 2;

   int y = (h - 192) / 2;

  

   g.setColor(boxMaps.getGroundColor());

   g.fillRect(0,0,getWidth(),getHeight());

   g.setColor(0x0000ff);

  

   tl_ground = boxMaps.getTiled();

  

   layerManager.paint(g,x,y);

   flushGraphics();

   }

  }