?? subcanvas.java
字號:
/*
* Author: Huang ye(www.hyweb.net)
* 代碼開源, 引用請注明出處
*
* 創建日期 2005-2-24
*
* TODO 要更改此生成的文件的模板,請轉至
* 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板
*/
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 user
*
* TODO 要更改此生成的類型注釋的模板,請轉至
* 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板 */
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);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -