前文已经将角色实现,终于要结束了,小激动。
其实还有很多想法没写完,但是这就是个坑啊,新的idea不停冒出来,永远都写不完,所以就停了吧。
在这里为了帮GameCLient节省一些代码,写了一个游戏控制器,将常用的方法放在这里:
public class GameController {
static Random r;
static {
r = new Random();
}
public static int createX() {
int x = r.nextInt(GameConstant.FrameData.WIN_WIDTH
- GameConstant.NormalPcPlaneData.RADIUS);
return x;
}
public static int createBossX() {
int x = r.nextInt(GameConstant.FrameData.WIN_WIDTH
- GameConstant.BossPcPlaneData.RADIUS);
return x;
}
public static int createBossY() {
int y = -r.nextInt(600) - 20;
System.out.println("boss y is" + y);
return y;
}
public static int createY() {
int y = -r.nextInt(300) - 20;
return y;
}
// 创造出一个普通的敌方飞机
public static void createNormalPcPlane(GameObserver observer) {
NormalPcPlane normalPcPlane = new NormalPcPlane(observer);
observer.onNormalPcPlaneAppear(normalPcPlane);//注意这里的观察者
}
// 创造出一个BOSS飞机
public static void createBossPcPlane(GameObserver observer) {
BossPcPlane bossPcPlane = new BossPcPlane(observer);
observer.onBossAppear(bossPcPlane);<span style="font-family: Arial, Helvetica, sans-serif;">//注意这里的观察者</span>
}
}
最后就是GameClient游戏客户端的代码:
public class GameClient extends Frame implements GameObserver {
// 两波飞机出现的时间间隔
private int gapTime = 250;
private int bossGapTime = 25 * 2000;
// 我方飞机
private MainPlane mainPlane = new MainPlane(
GameConstant.MainPlaneData.FIRST_X,
GameConstant.MainPlaneData.FIRST_Y, GameClient.this);
// 敌方飞机
private List<NormalPcPlane> normalpPcPlanes = new ArrayList<NormalPcPlane>();
private List<BossPcPlane> bossPcPlanes = new ArrayList<BossPcPlane>();
// 子弹
private List<Bullet> bullets = new ArrayList<Bullet>();
private Image offScreanImage = null;
// 刷新的线程
private PaintThread paintThread = new PaintThread();
private AttackThread attack = new AttackThread();
private FireThread fire = new FireThread();
private BossAttackThread bossAttackThread = new BossAttackThread();
// 主函数
public static void main(String[] args) {
GameClient gameClient = new GameClient();
gameClient.launchFrame();
}
// 启动窗口
private void launchFrame() {
// 位置,大小,添加按键监听
this.setLocation(GameConstant.FrameData.WIN_X,
GameConstant.FrameData.WIN_Y);
this.setSize(GameConstant.FrameData.WIN_WIDTH,
GameConstant.FrameData.WIN_HEIGHT);
this.setResizable(false);
this.setTitle(GameConstant.GameStr.GAME_NAME);
this.setBackground(GameConstant.ColorHelper.GAMEBKCOLOR);
this.addWindowListener(new MyWindowAdapter());
this.addKeyListener(new KeyMonitor());
setVisible(true);
new Thread(paintThread).start();
new Thread(attack).start();
new Thread(fire).start();
new Thread(bossAttackThread).start();
}
// 将游戏角色画在窗口中
public void paint(Graphics g) {
mainPlane.appears(g);
for (int i = 0; i < bullets.size(); i++) {
Bullet currentBullet = bullets.get(i);
currentBullet.move();
currentBullet.paint(g);
for (int j = 0; j < normalpPcPlanes.size(); j++) {
currentBullet.hit(normalpPcPlanes.get(j));
}
for (int k = 0; k < bossPcPlanes.size(); k++) {
currentBullet.hit(bossPcPlanes.get(k));
}
}
for (int i = 0; i < bossPcPlanes.size(); i++) {
bossPcPlanes.get(i).move();
bossPcPlanes.get(i).paint(g);
bossPcPlanes.get(i).hit(mainPlane);
bossPcPlanes.get(i).showMsg();
}
for (int i = 0; i < normalpPcPlanes.size(); i++) {
normalpPcPlanes.get(i).move();
normalpPcPlanes.get(i).paint(g);
normalpPcPlanes.get(i).hit(mainPlane);
}
g.drawString("current pcPlanes are" + normalpPcPlanes.size(), 20, 50);
g.drawString("current bullets are" + bullets.size(), 20, 100);
g.drawString("current bossPcPlanes are" + bossPcPlanes.size(), 20, 150);
}
// 重写update方法,在父类repaint()方法调用的时候会调用这个方法
public void update(Graphics g) {
if (offScreanImage == null) {
offScreanImage = this.createImage(GameConstant.FrameData.WIN_WIDTH,
GameConstant.FrameData.WIN_HEIGHT);
}
Graphics gOffScrean = offScreanImage.getGraphics();
Color preColor = gOffScrean.getColor();
gOffScrean.setColor(GameConstant.ColorHelper.GAMEBKCOLOR);
gOffScrean.fillRect(0, 0, GameConstant.FrameData.WIN_WIDTH,
GameConstant.FrameData.WIN_HEIGHT);
gOffScrean.setColor(preColor);
paint(gOffScrean);
g.drawImage(offScreanImage, 0, 0, null);
}
// 不断刷新画面的线程
private class PaintThread implements Runnable {
public void run() {
while (true) {
// 每隔15ms,调用父类的repaint()方法
repaint();
try {
Thread.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 不断产生敌方普通飞机的线程
private class AttackThread implements Runnable {
public void run() {
while (true) {
try {
GameController.createNormalPcPlane(GameClient.this);
Thread.sleep(gapTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 不断产生敌方BOSS飞机的线程
private class BossAttackThread implements Runnable {
public void run() {
while (true) {
try {
GameController.createBossPcPlane(GameClient.this);
Thread.sleep(bossGapTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 我方开火线程
public class FireThread implements Runnable {
long fireGaptime = 150;
public void run() {
while (true) {
try {
Thread.sleep(fireGaptime);
mainPlane.getState().fire();
} catch (Exception e) {
}
}
}
}
// 按键监听
private class KeyMonitor extends KeyAdapter {
public void keyPressed(KeyEvent keyEvent) {
mainPlane.onkeyPressed(keyEvent);
}
}
/*------------敌方普通飞机------------*/
// 敌方普通飞机出现后调用该方法
public void onNormalPcPlaneAppear(NormalPcPlane pcPlane) {
normalpPcPlanes.add(pcPlane);
}
// 当敌方普通飞机死亡之后,调用该回调方法
public void onNormalPcPlaneDie(NormalPcPlane pcPlane) {
if (normalpPcPlanes.indexOf(pcPlane) >= 0) {
normalpPcPlanes.remove(pcPlane);
}
}
/*------------子弹------------*/
// 非三射状态下,我方飞机射出子弹
public void onBulletAppear(Bullet newBullet) {
bullets.add(newBullet);
}
// 在三射状态下,我方飞机射出子弹
public void onBulletsAppear(List<Bullet> newBullets) {
bullets.addAll(newBullets);
}
// 子弹超出范围或者爆炸之后,调用该回调方法
public void onBulletDisapper(Bullet missle) {
if (bullets.indexOf(missle) >= 0) {
bullets.remove(missle);
}
}
/*------------敌方BOSS飞机------------*/
// 敌方boss飞机出现后调用该方法
public void onBossAppear(BossPcPlane bossPcPlane) {
bossPcPlanes.add(bossPcPlane);
}
// 敌方boss飞机死亡后调用该方法
public void onBossDie(BossPcPlane bossPcPlane) {
if (bossPcPlanes.indexOf(bossPcPlane) >= 0) {
bossPcPlanes.remove(bossPcPlane);
}
}
// 当我方飞机死亡后,调用该回调方法
public void onMainPlaneDie() {
}
}
没有计分,也没有我放飞机死亡之后的操作,事实上我方飞机不会死亡。
END。
游戏源码:
http://download.csdn.net/detail/u011248571/8427317