这是飞机大战游戏的基础工具类代码及解释,其他的也在博客中
游戏中上层的主要类,统一放在包com.airbattle.game下
游戏的主要逻辑在这个包里实现
类名 | 用途 |
Drawer | 画图,用画笔Graphics,在画板上指定位置处画出img图像,这是静态方法 |
Property | 关于游戏配置的所有常量,包括:设置背景、各个角色的图片,飞机移动速度、飞机开火速度、飞机最大生命值、游戏帧率、游戏的其他配置信息。这里还有变量frame,用于记录游戏帧数 |
Heroplane | 英雄机,即游戏主角 |
BulletArray | 子弹阵列类,游戏产生的所有子弹,放在这个类中。类中是一个类似堆的数据结构,有两个堆,一个存储英雄机的子弹对象,一个存储敌机的子弹对象,还有两个指针,表示每个堆中有多少个子弹对象,指向堆顶 |
HostileArray. | 敌机阵列类,所有的敌机对象存储在这个类中 |
PlaneController | 按键事件处理器,继承了Java类库的KeyAdapter类,用于处理键盘事件 |
Game | 主程序及画图类的继承与实现 |
下面是源代码,命名很清晰,有注释
Drawer类
package com.airbattle.game;
import java.awt.Graphics;
import com.airbattle.gameproperty.Image;
import com.airbattle.gameproperty.Position;
public class Drawer {
//用画笔Graphics,在画板上位置pos处画出img图像
static public void draw(Graphics g, Image img, Position pos) {
g.drawImage(img.img, pos.y, pos.x, null);
}
}
Property类
package com.airbattle.game;
public class Property {
public static final int FRAME_RATE = 100; //帧率,FPS
public static final int SPACE = (int)(1000.0 / FRAME_RATE); //每帧之间的延迟时间,ms
public static final int HERO_FIRE_TIMESPACE = 400; //英雄开火间隔,ms
public static final int HERO_FIRE_FRAME = //英雄机开火间隔的帧数
(int)((double)HERO_FIRE_TIMESPACE / SPACE);
public static final int HERO_MOVE_SPEED = 5; //英雄移动速度
public static final int ENEMY_FIRE_TIMESPACE = 300; //敌军开火间隔,ms
public static final int ENEMY_FIRE_FRAME = //敌军开火间隔的帧数
(int)((double)ENEMY_FIRE_TIMESPACE / SPACE);
public static final int ENEMY_MOVE_SPEED = 1; //敌军移动速度
public static final int ENEMY_MOVE_SPACE = 20; //敌人移动的时间间隔
public static final int ENEMY_MOVE_FRAME = //敌人移动的帧数间隔
(int)((double)ENEMY_MOVE_SPACE / SPACE);
public static final int BULLET_MOVE_SPEED = 2; //子弹移动速度
public static final int BULLET_MOVE_SPACE = 10;//子弹移动的时间间隔
public static final int BULLET_MOVE_FRAME = //敌人移动的帧数间隔
(int)((double)BULLET_MOVE_SPACE / SPACE);
public static final int ENEMY_ARRAY_COL = 20; //敌军阵列的列数
public static final int ENEMY_ARRAY_ROW = 6; //敌军阵列的行数
public static final String HERO_IMAGE_FILEPATH =
"D:\\workspace\\AirBattle\\src\\plane.jpg"; //英雄机图片文件
public static final int HERO_IMAGE_WIDTH = 40;
public static final int HERO_IMAGE_HEIGHT = 40;
public static final String ENEMY_IMAGE_FILEPATH =
"D:\\workspace\\AirBattle\\src\\hostile.jpg"; //敌机图片文件
public static final int ENEMY_IMAGE_WIDTH = 15;
public static final int ENEMY_IMAGE_HEIGHT = 15;
public static final String BACKGROUND_IMAGE_FILEPATH =
"D:\\workspace\\AirBattle\\src\\stars.jpg"; //背景图片文件
public static final int BACKGROUND_IMAGE_WIDTH = 480;
public static final int BACKGROUND_IMAGE_HEIGHT = 640;
public static final String HEROBULLET_IMAGE_FILEPATH =
"D:\\workspace\\AirBattle\\src\\herobullet2.jpg"; //英雄机子弹图片文件
public static final int HEROBULLET_IMAGE_WIDTH = 10;
public static final int HEROBULLET_IMAGE_HEIGHT = 20;
public static final String ENEMYBULLET_IMAGE_FILEPATH =
"D:\\workspace\\AirBattle\\src\\enemybullet.jpg"; //敌军子弹图片文件
public static final int ENEMYBULLET_IMAGE_WIDTH = 5;
public static final int ENEMYBULLET_IMAGE_HEIGHT = 10;
public static final int ENEMYARRAY_SPACE_X = 30; //敌军阵列的x,y间距
public static final int ENEMYARRAY_SPACE_Y = 5;
public static final int BULLET_BUFFER_SIZE = 10000; //子弹缓冲区大小,太小会发生溢出
public static final int MAX_HERO_HEALTH = 10; //英雄机的最大生命值
public static int frame = 0; //总帧数
public Property() {
}
}
Heroplane类
package com.airbattle.game;
import com.airbattle.gameinterface.HeroplaneInterface;
import com.airbattle.gameobject.Aircraft;
import com.airbattle.gameobject.Bullet;
import com.airbattle.gameproperty.Image;
import com.airbattle.gameproperty.Position;
import com.airbattle.gameproperty.Rect;
public class Heroplane extends Aircraft implements HeroplaneInterface{
//英雄机形态,没有实现相关功能
int form;
//有僚机时的图像,没有实现相关功能
Image wingmanImg;
//是否无敌,没有实现相关功能
boolean matchless;
//攻击力,没有实现相关功能
int damage;
//生命值
int health;
//得分
int score;
//飞机的宽和高
public static final int width = Property.HERO_IMAGE_WIDTH;
public static final int height = Property.HERO_IMAGE_HEIGHT;
public Heroplane() {
this.form = 0;
this.matchless = false;
this.damage = 1;
this.health = Property.MAX_HERO_HEALTH;
this.score = 0;
//System.out.println("英雄机初始化完成,图像已加载到内存");
}
//设置飞机位置,因为键盘事件处理程序在图像类中,所以需要从图像类中更新飞机的位置信息
public void setPos(Position pos) {
this.pos = pos;
}
//开火,从英雄机当前位置生成一颗飞向敌机阵列的子弹
public Bullet fire() {
return new Bullet(1, new Position(this.pos.x, this.pos.y + Property.HERO_IMAGE_WIDTH/2));
};
//获取飞机的外接矩形框,用于判断飞机是否和敌人子弹的矩形框接触
public Rect getRect() {
return new Rect(this.pos.x, this.pos.y,
height, width);
}
//被子弹打中,减生命值
public void onHit(int numHit) {
this.health -= numHit;
//System.out.println("英雄生命值已扣除");
};
//变形,未实现
public void transform() {
};
public int getHealth() {
return this.health;
};
public int getScore() {
return this.score;
};
public void moveStep() {
}
}
BulletArray类
package com.airbattle.game;
import com.airbattle.gameinterface.GameObjectInterface;
import com.airbattle.gameobject.Bullet;
import com.airbattle.gameproperty.Rect;
/**
*
* @author William
*子弹阵列类,游戏产生的所有子弹,放在这个类中。
*类中是一个类似堆的数据结构,有两个堆,
*一个存储英雄机的子弹对象,一个存储敌机的子弹对象,
*还有两个指针,表示每个堆中有多少个子弹对象,指向堆顶
*/
public class BulletArray implements GameObjectInterface{
Bullet[] enemyBullet = new Bullet[Property.BULLET_BUFFER_SIZE];
Bullet[] heroBullet = new Bullet[Property.BULLET_BUFFER_SIZE];
public int pointerEnemy = 0;
public int pointerHero = 0;
//构造器,刚开始没有子弹,指针全都指向null
public BulletArray() {
for (int i = 0; i < enemyBullet.length; i++) {
enemyBullet[i] = null;
}
for (int i = 0; i < heroBullet.length; i++) {
heroBullet[i] = null;
}
//System.out.println("子弹图像已加载到内存");
//System.out.println("子弹初始化完毕");
}
//敌军开火时,添加敌军子弹
public void addEnemyBullet(Bullet bullet) {
enemyBullet[pointerEnemy++] = bullet;
//System.out.println("新增的子弹已经加入敌人子弹阵列 ");
}
//英雄机开火时,添加敌军子弹
public void addHeroBullet(Bullet bullet) {
heroBullet[pointerHero++] = bullet;
//System.out.println("新增的子弹已经加入英雄子弹阵列");
}
//子弹移动
public void bulletMove() {
//System.out.println("英雄子弹移动...");
for (int i = 0; i < pointerHero; i++) {
heroBullet[i].moveStep(-Property.BULLET_MOVE_SPEED);
}
//System.out.println("敌人子弹移动...");
for (int i = 0; i < pointerEnemy; i++) {
enemyBullet[i].moveStep(Property.BULLET_MOVE_SPEED);
}
}
//删除已经出界的子弹,清理内存空间
public void deleteInvalidBullet() {
for (int i = 0; i < pointerHero; i++) {
if (heroBullet[i].pos.x < 0 || heroBullet[i].pos.x > 640) {
deleteHeroBullet(i);
}
}
for (int i = 0; i < pointerEnemy; i++) {
if (enemyBullet[i].pos.x < 0 || enemyBullet[i].pos.x > 640) {
deleteEnemyBullet(i);
//System.out.println("Actually deleted!");
}
}
//System.out.println("无效子弹已删除");
}
//删除堆中特定的子弹
public void deleteHeroBullet(int i) {
heroBullet[i] = null;
for (int j = i; j < pointerHero-1; j++) {
heroBullet[j] = heroBullet[j+1];
heroBullet[j+1] = null;
}
pointerHero--;
}
public void deleteEnemyBullet(int i) {
enemyBullet[i] = null;
for (int j = i; j < pointerEnemy-1; j++) {
enemyBullet[j] = enemyBullet[j+1];
enemyBullet[j+1] = null;
}
pointerEnemy--;
}
public void moveStep() {
}
//根据给定的英雄机的外界矩形,判断有几个敌军子弹打到了英雄机
//打到之后进行计数,然后将敌军子弹删除
public int heroInRange(Rect rect) {
int hitCnt = 0;
for (int i = 0; i < pointerEnemy; i++) {
Rect bulletRect = new Rect(enemyBullet[i].pos.x,
enemyBullet[i].pos.y,
Property.ENEMYBULLET_IMAGE_HEIGHT,
Property.ENEMYBULLET_IMAGE_WIDTH);
if (rect.hit(bulletRect) == true) {
hitCnt++;
deleteEnemyBullet(i);
}
}
return hitCnt;
}
//根据给定的敌机的外界矩形,判断有几个英雄机子弹打到了英雄机
//打到之后返回非0值,并将英雄机子弹删除
public int enemyInRange(Rect rect) {
int hitCnt = 0;
for (int i = 0; i < pointerHero; i++) {
Rect bulletRect = new Rect(heroBullet[i].pos.x,
heroBullet[i].pos.y,
Property.HEROBULLET_IMAGE_HEIGHT,
Property.HEROBULLET_IMAGE_WIDTH);
if (rect.hit(bulletRect) == true) {
hitCnt++;
deleteHeroBullet(i);
}
}
return hitCnt;
}
}
HostileArray类
package com.airbattle.game;
import java.util.Random;
import com.airbattle.gameinterface.GameObjectInterface;
import com.airbattle.gameobject.Bullet;
import com.airbattle.gameobject.HostilePlane;
import com.airbattle.gameproperty.Image;
import com.airbattle.gameproperty.Position;
/**
*
* @author William
* 敌军阵列类
* 阵列大小在配置文件中指定
* 阵列的样式在主函数中传入一个和阵列相同形状的矩阵
* 非0值代表该位置有敌机,0代表没有敌机
*/
public class HostileArray implements GameObjectInterface{
//敌机阵列数组
HostilePlane[][] planes = new HostilePlane[Property.ENEMY_ARRAY_ROW][Property.ENEMY_ARRAY_COL];
//阵列的位置(左上角坐标)
Position pos = new Position(0, 0);
//移动速度(负代表向左,正代表向右)
public int moveDir = Property.ENEMY_MOVE_SPEED;
public HostileArray(short[][] array) {
int cnt = 0;
for (int i = 0; i < planes.length; i++)
for (int j = 0; j < planes[i].length; j++) {
if (array[i][j] != 0) {
planes[i][j] = new HostilePlane(
new Position(i*Property.ENEMYARRAY_SPACE_X, 20)
);
cnt++;
}
else
planes[i][j] = null;
}
//System.out.println("敌机图像已加载到内存");
//System.out.println("敌机阵列初始化完毕,共初始化 " + cnt +" 台敌机");
}
//实例化敌军阵列对象,
//按照arrayDefine数组提供的规则初始化敌军阵列
public Bullet randomFire() {
Random rand = new Random();
int firingMark = -1;
int col = -1, row = -1;
while (firingMark == -1) {
int random_fire = rand.nextInt(Property.ENEMY_ARRAY_ROW * Property.ENEMY_ARRAY_COL);
row = random_fire/Property.ENEMY_ARRAY_COL;
col = random_fire%Property.ENEMY_ARRAY_COL;
if (planes[row][col] != null)
firingMark = random_fire;
}
return new Bullet(1, new Position(row, planes[row][col].pos.y));
}
//判断阵列是否碰到了窗体边界,如果碰到了返回true
private boolean isCollide() {
if (this.pos.y + this.moveDir <= 0 ||
this.pos.y + this.moveDir +
Property.ENEMY_ARRAY_COL*Property.ENEMY_IMAGE_WIDTH
+ Property.ENEMYARRAY_SPACE_Y * (Property.ENEMY_ARRAY_COL + 1)
>= Property.BACKGROUND_IMAGE_WIDTH
)
return true;
return false;
}
//移动到下一个位置
//先判断敌军阵列下次移动会不会移出窗体,如果能,向相反方向运动
public void nextPos() {
if (this.isCollide())
moveDir *= -1;
this.pos.y += moveDir;
//System.out.println("敌军阵列移动完成,当前位置:"+ pos.x + ", " + pos.y + ")");
}
public void moveStep() {
}
//因为更新敌军位置时都是更新阵列左上角的坐标
//想要获取每个敌机的具体位置时,需要进行计算
public void refreshPos() {
for (int i=0; i<Property.ENEMY_ARRAY_ROW; i++)
for (int j=0; j<Property.ENEMY_ARRAY_COL; j++)
if (planes[i][j] != null) {
Position pos = planes[i][j].pos;
pos.y = this.pos.y + j*(Property.ENEMY_IMAGE_WIDTH + Property.ENEMYARRAY_SPACE_Y);
}
}
}
PlaneController类
package com.airbattle.game;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class PlaneController extends KeyAdapter{
public MyJPanel jpanel;
public PlaneController(MyJPanel jpanel) {
this.jpanel = jpanel;
}
//重写这个函数,定义按下左键、右键时英雄机移动
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
//System.out.println("按键按下,键值:" + code);
switch(code) {
case 37:
if (jpanel.heroPos.y > 0)
jpanel.heroPos.y-=Property.HERO_MOVE_SPEED;
break;
case 39:
if (jpanel.heroPos.y + Property.HERO_MOVE_SPEED + Property.HERO_IMAGE_WIDTH
< Property.BACKGROUND_IMAGE_WIDTH)
jpanel.heroPos.y+=5;
else jpanel.heroPos.y = Property.BACKGROUND_IMAGE_WIDTH - Property.HERO_IMAGE_WIDTH;
break;
}
}
}
Game类
package com.airbattle.game;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import com.airbattle.gameobject.Bullet;
import com.airbattle.gameproperty.Image;
import com.airbattle.gameproperty.Position;
import com.airbattle.gameproperty.Rect;
import com.airbattle.game.Property;
public class Game {
static public void main(String[] argv) throws InterruptedException {
//System.out.println("游戏开始——————————————");
//实例化英雄机对象
Heroplane hero = new Heroplane();
//定义一个数组,用于确定敌军阵列的阵型
//数组中数字不为0,代表该点有敌军,在构造函数中将新建一个敌军对象放在该位置
//如果是0,则该位置没有敌军,初始化为null
short[][] arrayDefine = new short[Property.ENEMY_ARRAY_ROW][Property.ENEMY_ARRAY_COL];
//将数组全部设置为1,如果需要设置敌军阵型,只需要修改这个数组
for (int i=0; i<Property.ENEMY_ARRAY_ROW; i++)
for (int j=0; j<Property.ENEMY_ARRAY_COL; j++) {
arrayDefine[i][j] = 1;
}
//实例化敌军阵列对象,其中包含一个敌机数组,按照arrayDefine数组提供的规则初始化敌军阵列
HostileArray hostile = new HostileArray(
arrayDefine);
//System.out.println("-------------- 敌机阵列初始化 --------------");
//实例化子弹阵列对象,其中是一个类似堆的数据结构
//有两个堆,一个存储英雄机的子弹对象,一个存储敌机的子弹对象
//还有两个指针,表示每个堆中有多少个子弹对象
BulletArray bullet = new BulletArray();
//System.out.println("-------------- 子弹阵列初始化 --------------");
//定义窗口对象
JFrame jFrame = new JFrame();
//定义画板对象,在该对象的paint函数中实现绘图
MyJPanel jpanel = new MyJPanel(hostile, bullet);
//设置窗口标题
jFrame.setTitle("飞机大战-WilliamCode");
//将画板对象加入窗体中
jFrame.add(jpanel);
// 设置画框大小(宽度,高度),默认都为0
//这里设置为背景图片的宽和高
jFrame.setSize(Property.BACKGROUND_IMAGE_WIDTH, Property.BACKGROUND_IMAGE_HEIGHT);
// 将画框展示出来。true设置可见
jFrame.setVisible(true);
//向窗体加入按键事件监听器
//PlaneController是一个监听器,继承了java类库中的KeyAdapter
//需要重写其中的KeyPressed方法,在其中定义按键按下时的操作
jFrame.addKeyListener(new PlaneController(jpanel));
//主循环开始
while(true) {
//游戏帧数计数器,提供游戏从开始运行一共渲染了多少帧
Property.frame ++;
//System.out.println("\n\n-------------- 游戏帧开始 --------------");
//System.out.println("正在检测敌军是否被英雄子弹击中,击中减生命值,到0则销毁对象");
//刷新敌机阵列的位置信息
hostile.refreshPos();
//遍历敌军阵列,判断敌军是否被子弹打中
//如果打中,将该敌机销毁
for (int i=0; i<Property.ENEMY_ARRAY_ROW; i++)
for (int j=0; j<Property.ENEMY_ARRAY_COL; j++){
if (hostile.planes[i][j] != null) {
Rect r = hostile.planes[i][j].getRect();
//System.out.println(r.x1 + " " + r.x2 + " " + r.y1 + " " + r.y2);
int numHit = bullet.enemyInRange(hostile.planes[i][j].getRect());
if (numHit != 0) {
hostile.planes[i][j] = null;
jpanel.score++;
}
}
}
//判断敌军子弹是否机中英雄机,返回击中的子弹数目
int numHit = bullet.heroInRange(hero.getRect());
//System.out.println("正在检测英雄机是否被敌军子弹击中,击中减生命值,到0则游戏结束");
//英雄机被击中,扣除生命值,并更新到窗体中
//System.out.println("击中英雄机的子弹数量:" + numHit);
hero.onHit(numHit);
jpanel.health = hero.health;
//System.out.println("正在布置敌军开火");
//判断是否到达帧数,到达一定帧数时,敌机开火
if (Property.frame % Property.ENEMY_FIRE_FRAME == 0) {
//任选一个敌机开火,返回子弹文件
Bullet newBullet = hostile.randomFire();
//将子弹加入子弹阵列中
bullet.addEnemyBullet(newBullet);
}
//判断是否到达帧数,到达一定帧数时,敌军移动
if (Property.frame % Property.ENEMY_MOVE_FRAME == 0) {
//System.out.println("正在更新敌军移动");
//这里只需要更改敌军的左上角的x,y坐标,敌机阵列作为一个整体移动
//因为每个敌机的具体坐标在使用前,都会使用refreshPos函数进行计算
hostile.nextPos();
}
//System.out.println("正在布置友军开火");
//判断是否到达帧数,到达一定帧数时,友军开火
if (Property.frame % Property.HERO_FIRE_FRAME == 0) {
//友军开火,返回一个子弹对象,该子弹从英雄机所在位置发出,垂直打向敌机阵列
Bullet newBullet = hero.fire();
//将子弹加入子弹阵列
bullet.addHeroBullet(newBullet);
}
//System.out.println("正在更新友军移动");
//按键监听器存储在JPanel对象中,所以英雄机的位置信息暂存在JPanel中
//使用前需要把位置信息更新到英雄机对象
hero.setPos(jpanel.heroPos);
//System.out.println("正在布置背景移动");
//System.out.println("背景暂时不用移动");
//判断是否到达帧数,到达一定帧数时,进行子弹的移动和删除
if (Property.frame % Property.BULLET_MOVE_FRAME == 0) {
//System.out.println("正在更新子弹移动");
//子弹的移动,敌军子弹向英雄机移动,英雄机子弹向敌军移动
bullet.bulletMove();
//System.out.println("出界子弹处理");
//处理出界的子弹,直接从子弹的堆中删除,防止内存溢出和泄露
bullet.deleteInvalidBullet();
}
//System.out.println("游戏帧结束,准备渲染下一帧(按Enter继续)");
//System.out.println("+++++++++++");
//System.out.println("英雄机血量" + hero.health);
//System.out.println("敌机子弹数量" + bullet.pointerEnemy);
//System.out.println("英雄机子弹数量" + bullet.pointerHero);
//等待一定时间
Thread.sleep(Property.SPACE);
}
}
}
//继承的JPanel对象
//在创建对象时,自动调用一次paint方法
//我们在paint方法结束时,新启动了一个进程
//在改进程中重新启动了画图,即调用了repaint方法
//repaint方法会调用一系列方法,确保画图时不会发生窗口闪烁等问题
//最后,repaint方法会自动调用paint方法,重新画图
//我们只需要修改paint方法中画图时用到的对象即可,画图会自己进行
class MyJPanel extends JPanel{
//需要显示的英雄机生命值、得分
public int health = 0;
public int score = 0;
//因为键盘事件监听器放在对象中,所以这里存放了英雄机的位置信息
Position heroPos = new Position((int)((Property.BACKGROUND_IMAGE_HEIGHT+0.1)*0.8), Property.BACKGROUND_IMAGE_WIDTH/2-Property.HERO_IMAGE_WIDTH/2);
//各种游戏元素的图片文件
static Image heroImage = new Image(Property.HERO_IMAGE_FILEPATH, Property.HERO_IMAGE_WIDTH, Property.HERO_IMAGE_HEIGHT);
static Image hostileImage = new Image(Property.ENEMY_IMAGE_FILEPATH, Property.ENEMY_IMAGE_WIDTH, Property.ENEMY_IMAGE_HEIGHT);
static Image backgroundImage = new Image(Property.BACKGROUND_IMAGE_FILEPATH, Property.BACKGROUND_IMAGE_WIDTH, Property.BACKGROUND_IMAGE_HEIGHT);
static Image enemyBulletImage = new Image(Property.ENEMYBULLET_IMAGE_FILEPATH, Property.ENEMYBULLET_IMAGE_WIDTH, Property.ENEMYBULLET_IMAGE_HEIGHT);
static Image heroBulletImage = new Image(Property.HEROBULLET_IMAGE_FILEPATH, Property.HEROBULLET_IMAGE_WIDTH, Property.HEROBULLET_IMAGE_HEIGHT);
//定义敌军阵列、子弹阵列的引用,和主函数中引用同一对象
HostileArray hostile;
BulletArray bullet;
//构造函数,将上述两个引用在构造对象时赋值
public MyJPanel(HostileArray hostile, BulletArray bullet) {
super();
this.hostile = hostile;
this.bullet = bullet;
}
//画图函数,这是JPanel对象规定的方法,每次在画图时,这个函数将会被调用
public void paint(Graphics graphics) {
// 必须先调用父类的paint方法
super.paint(graphics);
//画背景图片
//Drawer是自己实现的一个类
//使用画笔graphics在画板上画图,draw是静态方法
Drawer.draw(graphics, backgroundImage, new Position(0,0));
//画英雄机
Drawer.draw(graphics, heroImage, heroPos);
//遍历敌军子弹阵列,画子弹
for (int i=0; i<bullet.pointerEnemy; i++) {
Drawer.draw(graphics, enemyBulletImage, bullet.enemyBullet[i].pos);
}
//遍历友军子弹阵列,画子弹
for (int i=0; i<bullet.pointerHero; i++) {
Drawer.draw(graphics, heroBulletImage, bullet.heroBullet[i].pos);
}
//更新敌军阵列的所有敌机的位置信息
hostile.refreshPos();
//遍历敌军阵列,画敌军
for (int i=0; i<Property.ENEMY_ARRAY_ROW; i++)
for (int j=0; j<Property.ENEMY_ARRAY_COL; j++) {
if(hostile.planes[i][j] != null) {
Drawer.draw(graphics, hostileImage, hostile.planes[i][j].pos);
}
}
//java.awt.Image image = new ImageIcon(file).getImage();
// 用画笔Graphics,在画板JPanel上画一个小人
//graphics.drawImage(heroImage.img,x++,y++,this);// 头部(画圆形)
//显示生命值和得分
graphics.setFont(new Font("微软雅黑", Font.BOLD, 20));
graphics.setColor(Color.white);
graphics.drawString("HP:" + health, 10, Property.BACKGROUND_IMAGE_HEIGHT-50);
graphics.drawString("Score:" + score, 10, Property.BACKGROUND_IMAGE_HEIGHT-70);
new updateClass().start();
}
//这个进程用于重画图像
//这个内部类在paint方法调用完成时进行了run方法的调用
class updateClass extends Thread{
public void run() {
repaint();
}
}
}