论坛首页 移动开发技术论坛

游戏入门之三 雷电 Game

浏览 11927 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-12-03  
       这里介绍的是Game的逻辑类,主要控制游戏的动作,以及绘制。
       详细里面代码有注释
java 代码
 
  1. /******************************************************************** 
  2.  * 项目名称             :j2me学习          
     
  3.  *  
  4.  * Copyright 2005-2006 Wuhua. All rights reserved 
  5.  ********************************************************************/  
  6. package org.wuhua.battleplan;  
  7.   
  8. import java.util.Stack;  
  9.   
  10. import javax.microedition.lcdui.Graphics;  
  11. import javax.microedition.lcdui.Image;  
  12.   
  13. import org.wuhua.game.GameCanvas;  
  14. import org.wuhua.game.model.Fairy;  
  15. import org.wuhua.game.util.Log;  
  16.   
  17.    
  18. /** 
  19.  * 类名:Game.java 
     
     
  20.  * 编写日期: 2006-11-30 
     
  21.  * 程序功能描述:游戏的主体类。游戏的绘制,状态的改变都在这边。 
     
  22.  * Demo: 
     
  23.  * Bug: 
     
  24.  *  
  25.  * 程序变更日期 :
     
     
  26.  * 变更作者 :
     
     
  27.  * 变更说明 :
     
  28.  *  
  29.  * @author wuhua 
     
     
  30.  */  
  31. public class Game extends GameCanvas {  
  32.     static Log log = Log.getLog("Game");  
  33.     private Hero hero;  
  34.       
  35.     private Stack balls;  
  36.     private Stack foes;  
  37.       
  38.     private Stack balst;  
  39.     /** 
  40.      * 爆炸效果索引 
  41.      */  
  42.     private int balstIndex;  
  43.       
  44.     /** 
  45.      * if time = 3 的时候建立一个 
  46.      */  
  47.     private int genaratBallTime;  
  48.       
  49.     private int genaratFoeTime;  
  50.       
  51.       
  52.     Game(){  
  53.         super();  
  54.         this.setFullScreenMode(true);  
  55.     }  
  56.       
  57.     void init(){  
  58.           
  59.         WIDTH = getWidth();  
  60.         HEIGHT = getHeight();  
  61.         log.debug("WIDTH=" + WIDTH);  
  62.         log.debug("hegiht=" + HEIGHT);  
  63.         this.bufferImage = Image.createImage(WIDTH, HEIGHT);  
  64.            
  65.         Platform.WIDTH = this.getWidth();  
  66.         Platform.HEIGHT = this.getHeight();  
  67.           
  68.           
  69.         hero = Hero.createHero(Platform.WIDTH/2, Platform.HEIGHT -30);  
  70.        
  71.         balst = new Stack();  
  72.            
  73.     }  
  74.       
  75.     /** 
  76.      * 产生爆炸效果 
  77.      * @param x 
  78.      * @param y 
  79.      */  
  80.     void genaratorBalst(int x, int y){  
  81.         balst.addElement(new Fairy(Resources.BLAST[0], x, y));  
  82.         balst.addElement(new Fairy(Resources.BLAST[1], x, y));  
  83.         balst.addElement(new Fairy(Resources.BLAST[2], x, y));  
  84.         balst.addElement(new Fairy(Resources.BLAST[3], x, y));  
  85.         balst.addElement(new Fairy(Resources.BLAST[4], x, y));  
  86.     }  
  87.       
  88.     /** 
  89.      * 碰撞。实在没有好的实现。 我想不出来了. 
  90.      * 逻辑是遍历所有子弹,然后再遍历所有敌机,再判断是否碰撞,如果碰撞,则产生一个爆炸实例. 
  91.      * 最后删除子弹跟飞机. 
  92.      * 
  93.      */  
  94.     void collides(){  
  95.         if(balls == null   
  96.                 || foes == null)  
  97.             return ;  
  98.         for(int i = 0; i < balls.size(); i ++){  
  99.             Ball b = (Ball) balls.elementAt(i);  
  100.             for(int j =0; j < foes.size(); j ++){  
  101.                 Foe f = (Foe) foes.elementAt(j);  
  102.                 if(b.collidesWith(f)){  
  103.                     this.genaratorBalst(f.getX(), f.getY());  
  104.                     balls.removeElement(b);  
  105.                     foes.removeElement(f);  
  106.                     return;  
  107.                 }  
  108.                
  109.             }  
  110.         }  
  111.     }  
  112.       
  113.     /** 
  114.      * 绘制游戏场景跟Hero 
  115.      * 
  116.      */  
  117.     void drawGame(){  
  118.         if(Platform.HEIGHT < this.getHEIGHT()){  
  119.             Platform.HEIGHT = this.getHEIGHT();  
  120.         }  
  121.           
  122.         Graphics g = this.getGraphics();  
  123.         if(g == null)  
  124.             return;  
  125.         fillFullScreen(g,0x349293);  
  126.         paintHeroAndBall(g);  
  127.           
  128.         paintFoe(g);  
  129.           
  130.         paintBalst(g);  
  131.         this.flushGraphics();  
  132.     }  
  133.   
  134.     /** 
  135.      * 绘制爆炸效果 
  136.      * @param g 
  137.      */  
  138.     private void paintBalst(Graphics g) {  
  139.            
  140.         if(balst == null   
  141.                 || balst.size() == 0)  
  142.             return;  
  143.           
  144.         Fairy bf = (Fairy) balst.elementAt(balstIndex);  
  145.         bf.paint(g);  
  146.         if(balstIndex >= 4){  
  147.             balstIndex = 0;  
  148.             balst.removeAllElements();  
  149.         }  
  150.               
  151.         balstIndex++;  
  152.     }  
  153.   
  154.     /** 
  155.      * 绘制敌机 
  156.      * @param g 
  157.      */  
  158.     private void paintFoe(Graphics g) {  
  159.         if(foes == null)  
  160.             return ;  
  161.         for(int i=0; i < foes.size(); i++){  
  162.             Foe foe = (Foe) foes.elementAt(i);  
  163.             foe.paint(g);  
  164.         }  
  165.           
  166.     }  
  167.       
  168.     /** 
  169.      * 制造敌飞机 
  170.      * 
  171.      */  
  172.     public void genaratorFoe(){  
  173.         if(this.genaratFoeTime == 5){             
  174.             FoeManager.addFoe(FoeManager.genarator());  
  175.             FoeManager.clearFoesIsOut();  
  176.             foes = FoeManager.getFoes();  
  177.             genaratFoeTime = 0;  
  178.         }  
  179.           
  180.         genaratFoeTime++;  
  181.     }  
  182.       
  183.     /** 
  184.      * 敌机飞行 
  185.      * 
  186.      */  
  187.     public void foeFly(){  
  188.         if(foes == null)  
  189.             return ;  
  190.         for(int i = 0; i < foes.size(); i++){  
  191.             Foe foe = (Foe) foes.elementAt(i);  
  192.             foe.fly();  
  193.         }  
  194.     }  
  195.   
  196.     private void paintHeroAndBall(Graphics g) {  
  197.         hero.paint(g);  
  198.         paintBalls(g);  
  199.     }  
  200.   
  201.     /** 
  202.      * 绘制子弹 
  203.      * @param g 
  204.      */  
  205.     private void paintBalls(Graphics g) {  
  206.         if(balls == null)  
  207.             return ;  
  208.         for(int i = 0; i < balls.size(); i++){  
  209.             Ball ball = (Ball) balls.elementAt(i);  
  210.             ball.paint(g);  
  211.         }  
  212.           
  213.     }  
  214.       
  215.     /** 
  216.      * 子弹的飞行 
  217.      * 
  218.      */  
  219.     public void ballFly(){  
  220.         if(balls == null)  
  221.             return ;  
  222.         for(int i = 0; i < balls.size(); i++){  
  223.             Ball ball = (Ball) balls.elementAt(i);  
  224.             ball.fly();  
  225.         }  
  226.     }  
  227.       
  228.     /** 
  229.      * 飞机的动作 
  230.      * 
  231.      */  
  232.     public void heroAction(){  
  233.         checkHeroIsExists();  
  234.         int keyCode = this.getKeyStates();  
  235.            
  236.         switch(keyCode){  
  237.         case Platform.KEY_LEFT: hero.moveLeft(); break;  
  238.         case Platform.KEY_RIGHT: hero.moveRight(); break;  
  239.         case Platform.KEY_UP: hero.moveUp(); break;  
  240.         case Platform.KEY_DOWN: hero.moveDown(); break;  
  241.         case Platform.KEY_FIRE: genaratorBall(); break;  
  242.         }  
  243.     }  
  244.   
  245.     /** 
  246.      * 创建子弹 
  247.      * 
  248.      */  
  249.     private void genaratorBall() {  
  250.        
  251.         if(this.genaratBallTime == 3){  
  252.             checkHeroIsExists();  
  253.               
  254.             BallManager.addBall(BallManager.genarator(hero.getX(), hero.getY()));  
  255.             BallManager.clearBallsIsOut();  
  256.             balls = BallManager.getBalls();  
  257.             genaratBallTime = 0;  
  258.         }  
  259.           
  260.         genaratBallTime++;  
  261.           
  262.           
  263.     }  
  264.   
  265.     private void checkHeroIsExists() {  
  266.         if(hero == null){  
  267.             throw new java.lang.NullPointerException("Hero is Null");  
  268.         }  
  269.     }  
  270.   
  271.     /** 
  272.      * 游戏的run。控制游戏个各个方面 
  273.      * 
  274.      */  
  275.     public void run(){  
  276.         this.collides();  
  277.         this.heroAction();  
  278.         this.ballFly();  
  279.         this.genaratorFoe();  
  280.         this.foeFly();  
  281.           
  282.         this.drawGame();  
  283.         this.setKeyStates(1000);  
  284.     }  
  285. }  


代码就是上面的,如果有什么好的建议,请评论。下面的一课,我将介绍GameThread。
   发表时间:2006-12-04  
“checkHeroIsExists(); ”

语法错误了。。。Exists就不需要Is了。。。
要用Is就该成checkHeroIsPresent。。。
0 请登录后投票
   发表时间:2006-12-04  
呵呵。兄弟这么仔细啊。佩服
0 请登录后投票
   发表时间:2006-12-04  
提几个小建议:
以下这些绝对不是我自己瞎想出来的
也是从各个高手那里学来的
不知道对楼主是否有帮助
:)


1 为了减少循环次数
将绘制敌机 绘制hero子弹 判断敌机与hero子弹是否碰撞
放到一个方法里
这样一个双层循环就可以搞定一切,同时还可以减少不必要的绘制
虽然 for循环内if的次数增多 会损失些性能
但和带来的性能提升比 可以忽略

2 避免使用 Stack 改用数组
敌机数量 子弹数量不是固定的
但是同时产生的数量是有上限的 所以做一个足够大的数组(通常64或128就足够了) 这样对性能也是有好处的

如果一个关卡中有1000个敌人
但1000个肯定不是同时生成的 可以每128个生成一次
如果怕中间有断档 可以利用双数组。


3 使用递减的循环 不要使用递增的循环
例如遍历子弹 请使用:
for(int i = balls.size()-1; i>=0;i--){
}

原因:速度更快,这点速度在pc上可以忽略,在手机上不可以

4 多使用2的幂作为常量 这样可以更好的利用位运算
例如 飞机的大小不要 10*5 可以做成 8*4 以次类推

5 解藕的思想在j2me里很多时候是反对的
原因很简单 过多的类 和类之间的调用对性能有损伤。
所以oo在j2me里只能适当的使用。
如果多看看商业j2me游戏的源代码就可以发现,他们都使用了“超级类”(一个大类,里面几乎做了所有的事情)

呵呵 先说这些吧
毕竟楼主这个是个简单的入门程序 涉及的东西比较少
而且为了便于大家理解 楼主肯定也没有考虑太多复杂的东西

以后希望可以和楼主以及所有喜欢游戏编程的朋友继续切磋
其实我相信,任何一个男程序员 心里都有一个编写游戏的情结 都有一颗游戏的心 一个游戏的梦
大家不要让结断 心死 梦破碎啊

加油 加油!





1 请登录后投票
   发表时间:2006-12-04  
楼主见解深刻
受教了。有空一起探讨下商业游戏的制作。
0 请登录后投票
   发表时间:2006-12-04  
我也没弄过商业游戏
对于商业游戏的接触只是反编译过一些游戏的代码
他们中绝大多数代码混淆了 但是有的却没有
当初我是弄了 1000多个国外的比较优秀的j2me游戏
里面有20多个没混淆 这个只能靠运气了 同一家公司的作品都是有的混有的没混
我印象中 s40版的 call of duty没有混淆 可以学习

0 请登录后投票
   发表时间:2006-12-04  
原来你狂热的学习啊
佩服
0 请登录后投票
   发表时间:2006-12-04  
刚才又重新证实了一下
cod s40确实没混淆
现在上传给大家 感兴趣的下来反编译吧 研究研究吧 (我是没研究过 只是粗略的看了一点)
能学到不少东西。

我以前研究过另外一个国外的rpg游戏的代码 忘了叫什么了 没找到 无法上传给大家了

0 请登录后投票
   发表时间:2006-12-04  
wuhua 写道
原来你狂热的学习啊
佩服

谈不上狂热 就是总想编游戏
从小学那会 第一次用basic开始 就梦想着自己遍游戏
但却离那条路越来越远(超级讨厌数学和c语言 呵呵 虽然小时候学的很好 哈哈 自夸一下)
感谢j2me 让我找到了一个简单便捷的重拾梦想的机会(呵呵 说实话 用j2me编游戏真的不难,难的是编好游戏 这点没人反对吧 呵呵)
0 请登录后投票
   发表时间:2006-12-05  
是啊,一直想做个三国的游戏...-.-#可惜至今仍在玩KOEI的系列...鄙视一下...  fins的几个建议都很好.  J2ME是效率性能第一,编程美观就靠边吧...哈哈,怎么快就怎么做.
0 请登录后投票
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics