正文

[转]6 GAME API 22006-08-07 09:30:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/sword2008/17354.html

分享到:

/*

 * Author: Huang ye(www.hyweb.net)

 * 代码开源, 引用请注明出处

 *

 * 创建日期 2005-2-24

*/

package net.hyweb;

 

import javax.microedition.lcdui.*;

import javax.microedition.lcdui.game.GameCanvas;

import javax.microedition.lcdui.game.*;

import javax.microedition.lcdui.game.LayerManager;

 

 

import java.util.*;

 

/**

 * @author Huang ye

     */

 

public class SubCanvas extends GameCanvas implements Runnable, CommandListener {

 

    /**

     *

     * @uml.property name="subMIDlet"

     * @uml.associationEnd multiplicity="(0 1)"

     */

   

    private Controller controller;

   

   private Graphics  graphics;

   private Thread    thread;

   private boolean   threadAlive = false;

  

   private Command startCommand;

   private Command exitCommand;

   private Command pauseCommand;

  

    //图层数据

   private LayerManager layerManager;

   private TiledLayer   layerSeaback;

  

   private Sprite       spriteMap;

  

   public final int GAME_INIT  = 0;              //游戏初始状态

   public final int GAME_RUN   = 1;              //游戏运行状态

   public final int GAME_OVER  = 4;              //游戏结束状态

   public final int GAME_PAUSE = 5;

   public final int GAME_SUSPEND      = 9;       //暂停状态

   public   boolean COMMAND_ADD_FLAG  = false;   //是否已经添加Command标识

  

   public static final int TROOP_PLAYER  = 0;   //敌我标识

    public static final int TROOP_ENEMY   = 1;

   

    public static       int PLAYER_LEVEL        = 1;                    //当前玩家水平

    public static       int ENEMY_MAX           = PLAYER_LEVEL * 10;    //最大敌人数量

    public static       int ENEMY_CURRENT       = 0;                    //当前敌人数量

    public static       int ENEMY_CURRENT_LIMIT = 0;                    //当前敌人数量限制

   

   protected           int     TRIGGER_COUNT = 0;                //拖延标识,避免敌人新潜艇同一时刻全部产生

   protected           int     TICK_COUNT    = 0;

  

   public  static int mainWidth;                 //屏幕宽度

   public  static int mainHeight;                //屏幕高度

   public         int gameState;                 //游戏状态

  

   public final static int TILE_WIDTH  = 10;     //背景 单元宽度 10px

   public final static int TILE_HEIGHT = 10;     //背景 单元高度 10px

  

   /** 动画变化频率(200ms)

    * <code>MILLIS_PER_TICK</code> 的注释

    */

   public  final static int MILLIS_PER_TICK = 200;

  

   private final static int WIDTH_IN_TILES  = 45;     //游戏域宽度(以单元宽度计算) 16 .. N

   private final static int HEIGHT_IN_TILES = 24;     //游戏域高度(以单元高度计算)

   private final static int NUM_DENSITY_LAYERS = 4;   //海面密度(背景图层)

  

   private int[] rotations = {

           Sprite.TRANS_NONE,

           Sprite.TRANS_MIRROR,

           Sprite.TRANS_MIRROR_ROT90,

           Sprite.TRANS_MIRROR_ROT180,

           Sprite.TRANS_MIRROR_ROT270,

           Sprite.TRANS_ROT90,

           Sprite.TRANS_ROT180,

           Sprite.TRANS_ROT270

   };

 

   /** 整个游戏背景宽度(以象素计算 : 宽度单元数 * 宽度单元象素)

    * <code>WORLD_WIDTH</code> 的注释

    */

   public final static int WORLD_WIDTH = WIDTH_IN_TILES * TILE_WIDTH;  

  

  

   /** 整个游戏背景高度(以象素计算 : 高度单元数 * 高度单元象素)

    * <code>WORLD_HEIGHTH</code> 的注释

    */

   public  final static int WORLD_HEIGHT = HEIGHT_IN_TILES * TILE_HEIGHT;

  

   private final static int NUM_DENSITY_LAYER_TILES     = 4;   //每一个密度层的TILE单元数

   private final static int FRACT_DENSITY_LAYER_ANIMATE = 20;

  

   private int   SEABACK_DENSITY;                          //游戏初始海水密度为0

  

  

    //private final  Vector oceanLayersVector       = new Vector();

    private        Vector fishCollectionVector    = new Vector();

    public         Vector enemyCollectionVector   = new Vector();

    public         Vector tinfishCollectionVector = new Vector();

 

    /**

     *

     * @uml.property name="mySub"

     * @uml.associationEnd multiplicity="(0 1)"

     */

    private Sub mySub  = null;

    private Runtime rt = null;

   

    //初始化为不使用窗口区域视野

    private boolean userViewWindow = false;

   

    //创建不稳定的动画线程

    private volatile Thread animationThread = null;

   

    //LayerManager的偏移坐标

    private int xViewWindow;

    private int yViewWindow;

    private int wViewWindow;

    private int hViewWindow;

   

 

   public SubCanvas(Controller controller){

       //不屏蔽键盘事件(潜艇运动采用主动轮询,而开火则采用捕获方式)

       super(false);

      

       this.controller   = controller;

       this.graphics     = getGraphics();

       this.layerManager = new LayerManager();

      

       //决定图层显示方式

       init();

      

       //画布构造即建立玩家潜艇

       //初始位置为屏幕的(1/3, 1/3)位置

       mySub = new Sub(this, SubMIDlet.createImage("/res/sub.png"), mainWidth / 3, mainHeight / 3, layerManager);

      

      

       //监测运行时,以便及时运行垃圾回收

       rt = Runtime.getRuntime();

      

       startCommand = new Command("Start", Command.OK, 1);

       pauseCommand = new Command("Pause", Command.OK, 1);

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

      

      

       //初始化其它类及图层

      

       //初始化游戏状态

       this.gameState = this.GAME_INIT;      //游戏处于demo画面状态

      

      

       //启动应用程序

       threadAlive = true;

       thread = new Thread(this);

       thread.start();

      

   }

 

   /**

    * 初始化地图数据 地图窗口显示方式

    */

   private void init(){

       //清理数据

       this.clearData();

      

       mainWidth  = getWidth();

       mainHeight = getHeight();

      

       //判断是否使用预览模式窗口

       //根据显示设备,设置合适的最大区和显示视野

       this.xViewWindow = 0;

       if(WORLD_WIDTH > mainWidth){

           //现有设备不能容纳所有游戏区域

           userViewWindow = true;

           this.wViewWindow = mainWidth;

       }else{

           //现有设备可以容纳所有游戏区域

           this.wViewWindow = WORLD_WIDTH;

       }

      

       this.yViewWindow = 0;

       if(WORLD_HEIGHT > mainHeight){

           userViewWindow = true;

           this.hViewWindow = mainHeight;

       }else{

           this.hViewWindow = WORLD_HEIGHT;

       }

      

       //设定图层显示方式

       if(userViewWindow){

           this.layerManager.setViewWindow(xViewWindow, yViewWindow, wViewWindow, hViewWindow);

       }

   }

  

   protected void clearData(){

      

       PLAYER_LEVEL    = 1;

       ENEMY_MAX       = PLAYER_LEVEL * 10; 

       ENEMY_CURRENT   = 0;

       TRIGGER_COUNT   = 0;

       SEABACK_DENSITY = 0;

       ENEMY_CURRENT_LIMIT = PLAYER_LEVEL * 2;

   }

  

   /**

    *  程序作为线程, 50ms运行刷新一次

    */

   public void run() {

       //利用条件驱动线程

       while(threadAlive){

           try {

               Thread.sleep(25);

           } catch (InterruptedException e) {

               e.printStackTrace();

           }

          

           //分离对玩家潜艇和普通物体的响应速度(一倍)

           if(gameState == GAME_RUN){

               mySub.movePosition(getKeyStates());

           }

          

           if((TICK_COUNT % 2) == 0){

               // 重画事件

               this.paintCanvas(graphics);

               this.tick();

           }

          

           TICK_COUNT ++;

       }

      

   }

  

   protected synchronized void keyPressed(int keyCode){

       int action = getGameAction(keyCode);

      

       if(action == Canvas.FIRE && gameState == GAME_RUN){

           //玩家潜艇开火

           if(mySub != null){

               mySub.fire();

           }

       }

   }

  

   /**

    *  秒触发器

    */

   public synchronized void tick(){

       //主动查询状态

       int keyState = getKeyStates();

      

       if(gameState != GAME_OVER){

           //执行鱼类图形运动

           this.tickFishes();

          

           //执行鱼雷触发

           this.tickTinfish();

          

           if(gameState == GAME_RUN){

               //替代Canvas中的KeyPressed()捕获事件

               //mySub.movePosition(keyState);

              

               //创建并执行敌人潜艇行为

               this.tickSub();

               this.tickEnemySub();

              

               if(ENEMY_CURRENT ==0 && ENEMY_MAX == 0){

                   gameState = GAME_SUSPEND;

               }

              

           }

       }

   }

 

 

    /**

     * 鱼类图形运动

     */

    private void tickFishes() {

       for(int i = 0; i < fishCollectionVector.size(); i++){

           FishCollection collection = (FishCollection)fishCollectionVector.elementAt(i);

           collection.tick();

       }

    }

 

 

    /**

     * 执行鱼雷触发

     */

    protected void tickTinfish() {

        //鱼雷 图形运动

       //如果某个鱼雷元素已经结束生命周期, 则置null, 并从数组中删除

       for(int j = 0; j < tinfishCollectionVector.size(); j++){

           Tinfish tinfish = (Tinfish)tinfishCollectionVector.elementAt(j);

          

           //当生命周期结束

           if(!tinfish.isLifeState()){

               tinfishCollectionVector.removeElementAt(j);

               this.layerManager.remove(tinfish);

               tinfish = null;

           }else{

               tinfish.tick();

           }

       }

    }

   

 

    /**

     * 玩家潜艇运动及生命状态

     */

    private void tickSub() {

        if(!mySub.isLifeState()){      

            gameState = GAME_OVER;

        }

    }

 

   

    /**

    * 创建并执行敌人潜艇的运行操作

    */

   protected void tickEnemySub(){

       

       //当敌人剩余最大数量大于0,并且敌人当前数量小于并行敌人上限时

       //可以添加新的敌人潜艇

       if(ENEMY_MAX >= 0 && ENEMY_CURRENT <= ENEMY_CURRENT_LIMIT && ENEMY_CURRENT < 10){

           int iLeft = ENEMY_MAX - ENEMY_CURRENT;

          

           //当剩余敌人量(最大量 - 当前量)大于0的时候

           if(iLeft > 0){

               int n = SubMIDlet.createRandom(iLeft) + 1;

               Image image = SubMIDlet.createImage("/res/enemysub_f.png");

 

               int xPosition = 0;

                int yPosition = (SubMIDlet.createRandom(5) * WORLD_HEIGHT) / 5;

               for(int i = 0; i < n; i++){

                  

                   //拖延标识,避免敌人新潜艇同一时刻全部产生

                   if(TRIGGER_COUNT >= 20){

                      

                       yPosition = (WORLD_HEIGHT * (i % 5)) / 5;

                      

                       if(i % 2 == 0){

                           xPosition = 0;

                       }else{

                           xPosition = WORLD_WIDTH - image.getWidth();

                       }

                      

                       //创建一艘敌人潜艇, 同时更新监听数组

                       EnemySub enemySub = new EnemySub(this, image, xPosition, yPosition, PLAYER_LEVEL);

 

                       ENEMY_CURRENT++;

                      

                       layerManager.insert(enemySub, 0);

                       this.enemyCollectionVector.addElement(enemySub);

                       TRIGGER_COUNT = 0;

                      

                   }else{

                       TRIGGER_COUNT++;

                      

                   }

               }

               image = null;

           }

       }

      

       //对所有已经存在的敌人潜艇进行tick触发

       Image imageDestroyed = null;

       for(int j = 0; j < enemyCollectionVector.size(); j++){

           EnemySub enemySub = (EnemySub)enemyCollectionVector.elementAt(j);

           int iCount = 0;

           //当生命周期结束

           if(!enemySub.isLifeState()){

              

               imageDestroyed = SubMIDlet.createImage("/res/enemysub_die.png");

               enemySub.setImage(imageDestroyed, imageDestroyed.getWidth(), imageDestroyed.getHeight());

               if(enemySub.getVx() >= 0){

                   enemySub.setTransform(Sprite.TRANS_NONE);

               }else{

                   enemySub.setTransform(Sprite.TRANS_MIRROR);

               }

               enemyCollectionVector.removeElementAt(j);

              

                //消灭一艘敌人潜艇同时更新监听数组

               SpriteChanged spriteChanged = new SpriteChanged(enemySub, layerManager);

               spriteChanged.start();

               

               spriteChanged = null;

               enemySub = null;

              

              

               ENEMY_CURRENT--;

               ENEMY_MAX--;

           }else{

               enemySub.tick();

           }

       }

       imageDestroyed = null;

       

   }

  

阅读(2371) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册