📄 game.java
字号:
/*
* 创建日期 2007-3-17 @author caipiz
*/
package com.cpiz.poptang;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.TiledLayer;
import javax.microedition.media.Manager;
import javax.microedition.media.Player;
/**
* 游戏场景类
* @author caipiz
*
*/
public class Game extends GameCanvas implements Runnable
{
private PopTang midlet = null;
public static Hashtable bombs = null;
public static int clock = 0;
public static Map map = null;
public static int score = 0;// 游戏分数
// 画面绘制锚点
private int anchorX = 0;
private int anchorY = 0;
private TiledLayer buildingsLayer = null;
private Vector enemies = null;
private TiledLayer floorLayer = null;
private Graphics g = null;
private Character hero = null;
private boolean isPause = true;// 暂停标志
private boolean isLoading = true;// 装载标志
private TiledLayer itemsLayer = null;
private LayerManager layerManager = null;
private Player player = null;
private int screenHeight = 0;
private int screenWidth = 0;
private Stage stage = null;
private Thread thread = null;
private int loadPercent = 0;
private Font font = null;
private int loadingStageIndex = PopTang.FIRST_STAGE; // 正在加载的关卡
private int completedStageIndex = 0; // 刚刚完成的关卡
/**
* 构造器
* @param midlet 游戏midlet
*/
public Game(PopTang midlet)
{
super(false);
this.midlet = midlet;
this.setFullScreenMode(true);
screenWidth = getWidth();
screenHeight = getHeight();
anchorX = (screenWidth - PopTang.GAME_WIDTH) / 2;
anchorY = (screenHeight - PopTang.GAME_HEIGHT) / 2;
g = getGraphics();
font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL);
g.setFont(font);
start();
}
/**
* 装载关卡
* @param stageIndex 关卡序号
*/
private void loadStage(int stageIndex)
{
loadPercent = 0;
loadingStageIndex = stageIndex;
bombs = null;
bombs = new Hashtable();
enemies = null;
enemies = new Vector();
loadPercent = 10;
try
{
stage = null;
stage = Stage.loadStage(stageIndex);
}
catch(Exception ex)
{
ex.printStackTrace();
}
loadPercent = 20;
map = null;
map = new Map(stage);
hero = null;
hero = Character.createCharacter(Character.HERO, stage.heroPosition[0], stage.heroPosition[1]);
layerManager = null;
layerManager = new LayerManager();
layerManager.append(hero);// 添加主角层
loadPercent = 30;
// 加入敌人
int i = 0;
while(stage.enemyPosition[i] >= 0)
{
if(i % 2 == 1)
{
Character enemy = Character.createCharacter(Character.ENEMY,
stage.enemyPosition[i - 1], stage.enemyPosition[i]);
enemies.addElement(enemy);
layerManager.append(enemy);// 添加敌人层
}
i++;
}
loadPercent = 40;
itemsLayer = map.getBombsAndToolsLayer();
floorLayer = map.getFloorLayer();
buildingsLayer = map.getBuildingsLayer();
layerManager.append(buildingsLayer);// 添加建筑层
layerManager.append(itemsLayer);// 添加道具层
layerManager.append(floorLayer);// 添加地表层
loadPercent = 50;
try
{
if (player != null)
{
player.close();
player = null;
}
player = Manager.createPlayer(getClass().getResourceAsStream("/mid/" + stage.midIndex + ".mid"), "audio/midi");
player.setLoopCount(-1);// 音乐循环
loadPercent = 70;
player.start();
loadPercent = 90;
}
catch (Exception ex)
{
ex.printStackTrace();
}
System.gc();
loadPercent = 100;
try
{
Thread.sleep(200);
}
catch(Exception ex)
{
ex.printStackTrace();
}
loadingStageIndex = stage.stageIndex;
}
// /**
// * 绘制胜利画面
// * @param g
// */
// private void drawWin(Graphics g)
// {
//
// }
/**
* 绘制屏幕,将当前帧绘制在屏幕上
* @param g
*/
private void drawScreen(Graphics g)
{
if (!isLoading)
{
if (!isPause)
{
// 正常状态
g.setColor(PopTang.COLOR_GRAY);
g.fillRect(anchorX, anchorY, PopTang.GAME_WIDTH, PopTang.GAME_HEIGHT);
layerManager.setViewWindow(0, -8, getWidth(), getHeight());
layerManager.paint(g, anchorX, anchorY);
g.setColor(PopTang.COLOR_BLACK);
g.drawRect(anchorX, anchorY, PopTang.GAME_WIDTH, PopTang.GAME_HEIGHT);
}
else
{
drawPauseFrame(g);
}
}
else
{
// 加载状态
drawLoadingFrame(g);
}
flushGraphics();
}
/**
* 绘制暂停框
* @param g 画布
*/
private void drawPauseFrame(Graphics g)
{
int tempColor = g.getColor();
int pauseWidth = 60;
int pauseHeight = 30;
int x, y;
x = anchorX + (PopTang.GAME_WIDTH - pauseWidth) / 2;
y = anchorY + (PopTang.GAME_HEIGHT - pauseHeight) / 2;
// 绘制消息框
g.setColor(PopTang.HELP_BGCOLOR);
g.fillRect(x, y, pauseWidth, pauseHeight);
g.setColor(0x000000);
g.drawRect(x, y, pauseWidth, pauseHeight);
// 绘制消息文字
y = y + (pauseHeight - font.getHeight()) / 2;
g.setColor(PopTang.COLOR_YELLOW);
g.drawString("Paused", screenWidth / 2, y, Graphics.HCENTER | Graphics.TOP);
g.setColor(tempColor);
System.gc();
}
/**
* 绘制装载消息框
* @param g 画布
*/
private void drawLoadingFrame(Graphics g)
{
int tempColor = g.getColor();
int x, y;
int msgTopMargin = 40;
int barWidth = 56;
int barHeight = 6;
int barBottomMargin = 20;
// 清屏
g.setColor(PopTang.COLOR_WHITE);
g.fillRect(0, 0, screenWidth, screenHeight);
// 绘制消息框
g.setColor(PopTang.HELP_BGCOLOR);
g.fillRect(anchorX, anchorY, PopTang.GAME_WIDTH, PopTang.GAME_HEIGHT);
g.setColor(0x000000);
g.drawRect(anchorX, anchorY, PopTang.GAME_WIDTH, PopTang.GAME_HEIGHT);
// 绘制消息文字
x = screenWidth / 2;
y = anchorY + msgTopMargin;
g.setColor(PopTang.COLOR_YELLOW);
if (completedStageIndex >= PopTang.FIRST_STAGE)
{
g.drawString(PopTang.COMPLETED_TIP[0] + PopTang.COMPLETED_TIP[1] + completedStageIndex, x, y, Graphics.HCENTER | Graphics.TOP);
y += font.getHeight() + 2;
}
g.drawString(PopTang.LOADING_TIP[0] + PopTang.LOADING_TIP[1] + loadingStageIndex, x, y, Graphics.HCENTER | Graphics.TOP);
// 绘制进度条
x = (screenWidth - barWidth) / 2;
y = anchorY + PopTang.GAME_HEIGHT - barBottomMargin;
g.setColor(PopTang.COLOR_YELLOW);
g.fillRect(x, y, (barWidth * loadPercent) / 100, barHeight);
g.setColor(PopTang.COLOR_RED);
g.drawRect(x, y, barWidth, barHeight);
g.setColor(tempColor);
System.gc();
}
/**
* 接收键盘事件
*/
private void keyAction()
{
int keyStates = getKeyStates();
if ((keyStates & LEFT_PRESSED) != 0)
{
hero.walk(Character.FACE_WEST);
}// 左
else if ((keyStates & RIGHT_PRESSED) != 0)
{
hero.walk(Character.FACE_EAST);
}// 右
else if ((keyStates & UP_PRESSED) != 0)
{
hero.walk(Character.FACE_NORTH);
}// 上
else if ((keyStates & DOWN_PRESSED) != 0)
{
hero.walk(Character.FACE_SOUTH);
}// 下
if((keyStates & FIRE_PRESSED) != 0)
{
hero.setBomb();
}// 放炸弹
}
/**
* 线程运行
*/
public void run()
{
while (true)
{
// 开始绘制时间
long startTime = System.currentTimeMillis();
// 时钟计时
if(clock < 10000)// 防止溢出
clock++;
else
clock = 0;
if (!isLoading && !isPause)
{
update();
keyAction();// 接收键盘输入
}
drawScreen(g);
// 绘制消耗时间
long takenTime = System.currentTimeMillis() - startTime;
/* FPS控制
* 使用SPF(每帧所用时间)控制绘制速度,规定一个SPF值,
* 当上一绘制时间未超过设定SPF,则线程休眠SPF-上帧时间,
* 否则立刻进行下一次绘制
*/
if (takenTime < PopTang.GAME_MSPF)
{
try
{
Thread.sleep(PopTang.GAME_MSPF - takenTime);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}
/**
* 开始游戏线程
*/
public void start()
{
isPause = false;
if (thread == null)
{
thread = new Thread(this);
thread.start();
}
}
/**
* 更新状态<br>
* 更新精灵,地图,炸弹等
*/
private void update()
{
// 英雄重生
if(!hero.isEnabled)
{
hero = null;
hero = Character.createCharacter(Character.HERO, stage.heroPosition[0], stage.heroPosition[1]);
layerManager.insert(hero, 0);
}
// 更新英雄
hero.update();
// 更新敌人
Enumeration enu = enemies.elements();
while(enu.hasMoreElements())
{
Character enemy = (Character)enu.nextElement();
if (enemy.isEnabled)
{
enemy.update();
}
else
{
enemies.removeElement(enemy);
enemy = null;
// 如果敌人杀光了则进入下一关
if(enemies.size() == 0)
{
nextStage();
}
}
}
// 更新地图
map.update();
// 更新炸弹
enu = bombs.elements();
while(enu.hasMoreElements())// 遍历炸弹集合
{
Bomb bomb = ((Bomb)enu.nextElement());
if (bomb.isVisible)
{
bomb.update();
}
else
{
String key = "" + (bomb.col * 10 + bomb.row);
bombs.remove(key);// 移除不可用的炸弹
bomb = null;
}
}
// 更新NPC
}
/**
* 暂停
* @return 是否成功暂停
*/
private boolean pause()
{
isPause = !isPause;
try
{
if (isPause)
player.stop();
else
player.start();
}
catch(Exception ex)
{
ex.printStackTrace();
}
return isPause;
}
/**
* 转至下一关
*
*/
private void nextStage()
{
completedStageIndex = stage.stageIndex;
startPlay(Math.min(stage.stageIndex + 1, PopTang.LAST_STAGE));
}
/**
* 转至上一关
*
*/
private void preStage()
{
completedStageIndex = stage.stageIndex;
startPlay(Math.max(stage.stageIndex - 1, PopTang.FIRST_STAGE));
}
protected void keyPressed(int key)
{
try
{
switch(key)
{
case 35:// #键
nextStage();
break;
case 42:// *键
preStage();
break;
case -6:// 左软键
try
{
player.stop();
}
catch(Exception ex)
{
ex.printStackTrace();
}
midlet.menu.showMe();
break;
case -7:// 右软键
pause();
break;
default:
break;
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
/**
* 开始指定关卡
* @param stageIndex 关卡号
*/
public void startPlay(int stageIndex)
{
new Loading(stageIndex);
start();
}
/**
* 资源装载类<br>
* 创建一个内部线程来装载资源
* @author caipiz
*/
class Loading implements Runnable
{
// 内线程
Thread innerThread = null;
int stageIndex = 1;
public Loading(int stageIndex)
{
this.stageIndex = stageIndex;
innerThread = new Thread(this);
innerThread.start();
}
public void run()
{
isLoading = true;
loadStage(stageIndex);
System.gc();
isLoading = false;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -