canvas教程

J2ME游戏开发技巧(1)

字号+ 作者:H5之家 来源:H5之家 2018-01-26 18:02 我要评论( )

J2ME游戏开发技巧(1)_臻狼_新浪博客,臻狼,

 (转载自j2medev.com)

双缓冲技术是编写J2ME游戏程序的关键技术之一。实际上,双缓冲技术是计算机动画的一项传统技术。造成屏幕闪烁的主要原因在于,画面在显示的同时,程序又在改变它...

不久前我曾用J2ME开发了一个MotoT720下的彩色游戏—宝石方块(GridOne)。开发过程中积累了一些经验,现在写出来与大家分享。

  使用双缓冲避免屏幕闪烁

  双缓冲技术是编写J2ME游戏程序的关键技术之一。实际上,双缓冲技术是计算机动画的一项传统技术。造成屏幕闪烁的主要原因在于,画面在显示的同时,程序又在改变它,于是画面闪烁。解决办法就是在内存中开辟一片区域作为后台画面,程序对它更新,修改,完成后再显示它。这样被显示的图像永远是已经完全画好的图像,程序修改的将不是正在被显示的图像。当然还有其它方法可以解决屏幕闪烁问题,但使用双缓冲技术是一种值得推荐的解决方案。具体方法可参见如下代码:

  public class BlocksCanvas extends Canvas implements Runnable

  {

  Graphics bg;Image buf;public BlocksCanvas()

  {height = getHeight();

  width = getWidth();

  //按屏幕大小建立缓冲对象

  buf = Image.createImage(width, height);

  //将缓冲对象的Graphics附给bgbg = buf.getGraphics();

  ......}

   public void run()

  {

  ......for(i=0;i{for(j=0;

  j

  {//画方块drawBlock(x,y);}}

  repaint();}private void drawBlock(int block_x, int block_y)

  {

  //取得方块的坐标

  int x = getLeft(block_x);int y = getTop(block_y);

  //取得方块的颜色

  int c= board[block_x][block_y];

   bg.drawImage(imgs[c], x, y, Graphics.TOP   Graphics.LEFT);

  }

  public void paint(Graphics g)

  {

  g.drawImage(buf, 0, 0, Graphics.TOP   Graphics.LEFT);

  }}

  由上面代码可见,双缓冲思想体现在程序上就是要依次完成以下几步工作:

  1.定义一个Graphics对象bg和一个Image对象buf,按屏幕大小建立一个缓冲对象附给buf,然后取得buf的Graphics对象附给bg。在这里,Graphics对象可以理解为缓冲的屏幕,Image对象则可当成缓冲屏幕上的图片。

  2.在bg(缓冲屏幕)上用drawImage()和drawString等语句画图,相当于在缓冲屏幕上画图。

  3.调用repaint()语句,它的功能是告知系统调用paint()来完成真实屏幕的显示。这里需要注意的是,paint()是一个系统调用语句,不能手工调用,只能通过paint()语句来调用。

  4.在paint(Graphics g)函数里,将buf(缓冲屏幕上的图片)画到真实屏幕上。

  以上的步骤虽然看似繁琐,但是效果还是很不错的。如果想要在屏幕上显示什么东西,只管画在bg上,然后调用repaint()将其显示出来就可以了。 编写自己的断点函数

  



  图1:断点测试

  在开发J2ME程序过程中,最困扰人的问题就是程序容易莫名其妙地死机。当使用JBuilder或者CodeWarrior设置断点功能来查找程序错误时,死机的概率就更大了。即使不死机,也会担心程序受到了意外的干扰,所以一般不推荐使用开发工具自带的断点功能。但有时候又需要一个功能来显示当前各变量的值,以便查错时做出正确的判断。于是我想了一个办法,就是编写自己的断点函数。具体代码如下:

  public class BlocksCanvas extends Canvas implements Runnable{

  private boolean stopFlag=false;

  //调试标志......public void run()

  {//断点位置1testFun(“x:”+x+“y:”+y);

  ......//断点位置2testFun(“”);......

  }private void testFun(String str)

  {

  stopFlag=true;//画一个白色长方形

  bg.setGrayScale(255);

  bg.fillRect(0,0, fontW, fontH);//在白色长方形上显示str的内容

  bg.setGrayScale(0);

  bg.drawString(str, 0,0, Graphics.TOP   Graphics.LEFT);

  repaint();

  while(stopFlag)

  {}}

  public void keyPressed(int keyCode)

  { stopFlag=false;} }

  首先定义一个boolean类型的stopFlag变量来记录调试标志。一开始它的值为false,进入testFun()函数后,值设为true。显示完str的内容后,因为stopFlag的值为true,所以while语句进入了死循环,程序停了下来。这时可以仔细地看清楚变量的值。然后当按下任意键时,keyPressed()函数捕捉到这一事件,将stopFlag设为false,死循环自动解开。使用此方法非常方便,只要在需要断点的地方放置testFun()语句即可,一个程序可以放置多个testFun()语句,在循环语句中也可以放置testFun()语句。程序运行到testFun()语句会自动停下显示变量值,按任意键程序又会自动运行,程序也不会受到意外的干扰。图1是调试时的截图。

  还有一点需要说明,此方法的testFun()语句必须放在run()函数中或者run()函数运行时调用的函数中,否则就会因为while()占用了所有CPU时间而导致keyPressed()函数无法捕捉按键事件,最后导致死机。

  此方法只要稍加修改,就可以用做游戏的暂停功能,而且比sleep()方法好,毕竟理论上sleep()方法不能无限期暂停下去。下面给出相应的代码:

  public class BlocksCanvas extends Canvas implements Runnable

  {private boolean stopFlag=false;//暂停标志

  ......public void run()

  {......testFun();......}

  private void testFun()

  { while(stopFlag){}}public void keyPressed(int keyCode)

  {

   int action = getGameAction(keyCode);

  if(action== FIRE)stopFlag=!stopFlag;}

  }

  该程序段的功能为,当使用者按下FIRE键时,游戏暂停;再次按下FIRE键,游戏继续运行


 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • opengl非全屏绘图的简单使用总结

    opengl非全屏绘图的简单使用总结

    2018-01-25 08:02

  • Android 画板(canvas)画bitmap的时候怎么指定绘画时的起始位置

    Android 画板(canvas)画bitmap的时候怎么指定绘画时的起始位置

    2018-01-22 10:05

  • Unity5.4 Canvas的bug

    Unity5.4 Canvas的bug

    2018-01-19 17:00

  • Unity3D学习笔记之uGUI(1):Canvas简述

    Unity3D学习笔记之uGUI(1):Canvas简述

    2018-01-18 08:04

网友点评