前言
飞机大战是一个非常经典的案例,因为它包含了多种新手需要掌握的概念,是一个非常契合面向对象思想的入门练习案例
程序分析:
在此游戏中共有六个对象:
小敌机Airplane,大敌机BigAirplane,小蜜蜂Bee,天空Sky,英雄机Hero,子弹Bullet
其次我们还需要三个类:
超类Flyer,图片类Images,测试类World
还需:
英雄机2张,小敌机,大敌机,小蜜蜂,子弹,天空各1张,爆炸图4张,游戏开始,暂停,游戏结束各1张,共14张图片放入与图片类Images同包中
超类Flyer:
此类是用来封装所有对象共有的行为及属性的
不管是写什么程序,都建议遵循两点:数据私有化,行为公开化
import java.util.Random;
import java.awt.image.BufferedImage;public abstract class Flyer {//所有对象都有三种状态:活着的,死了的,及删除的//这里之所以选择用常量表示状态是因为首先状态是一个不需要去修改的值//其次状态需要反复使用所以结合这两个特点,我选择了使用常量表示//state是用来表示当前状态的,每个对象都有一个实时的状态,此状态是会改变的,且初始状态都是活着的public static final int LIVE = 0;//活着的public static final int DEAD = 1;//死了的public static final int REMOVE = 2;//删除的protected int state = LIVE;//当前状态(默认状态为活着的)每个对象都是一张图片,既然是图片那么就一定有宽高,其次因为每个对象都是会随时移动的 即为都有x,y坐标protected int width;//宽protected int height;//高protected int x;//左右移动(x坐标)protected int y;//上下移动(y坐标)/*** 飞行物移动(抽象)* 每个飞行物都是会移动的,但是移动方式不同* 所以这里就将共有的行为抽到了超类中* 但是设置成了抽象方法,实现了多态的效果*/public abstract void step();/*** 获取图片(抽象)* 所有对象都是图片但图片不相同所以抽象化了*/public abstract BufferedImage getImage();/*** 判断对象是否是活着的*/public boolean isLive(){return state == LIVE;}/*** 判断对象是否是死了的*/public boolean isDead(){return state == DEAD;}/*** 判断对象是否删除了*/public boolean isRemove(){return state == REMOVE;}/*** 判断对象(大敌机,小敌机,小蜜蜂)是否越界* 当敌人越界我们就需要删除它否则程序越执行越卡,会出现内存泄露的问题,此方法就是为后续删除越界对象做铺垫的* @return*/public boolean isOutOfBounds(){return y >= World.HEIGHT;}/*** 给小/大敌机,小蜜蜂提供的* 因为三种飞行物的宽,高不同所以不能写死。* 若三种飞行物的宽,高相同,那么就可以将宽,高写死*/public Flyer(int width,int height){Random rand = new Random();this.width = width;this.height = height;x = rand.nextInt(World.WIDTH-width);//x:0到负的width长度的之间的随机数y = -height;//y:负的height高度}/*** 给天空,子弹,英雄机提供的* 因为英雄机,子弹,天空的宽,高,x,y都是不同的,所以数据不能写死,需要传参*/public Flyer(int width,int height,int x,int y){this.width = width;this.height = height;this.x = x;this.y = y;}/***检测碰撞* this:敌人(小敌机/小蜜蜂/大敌机)* other:子弹/英雄机*@return*/public boolean isHit(Flyer other){int x1 = this.x - other.width;//x1:敌人的x-英雄机/子弹的宽int x2 = this.x + this.width;//x2:敌人的x加上敌人的宽int y1 = this.y - other.height;//y1:敌人的y-英雄机/子弹的高int y2 = this.y + this.height;//y2:敌人的y加上敌人的高int x = other.x;//x:英雄机/子弹的xint y = other.y;//y:英雄机/子弹的y/*x在x1与x2之间 并且 y在y1与y2之间,即为撞上了*/return x>x1 && x<=x2 && y>=y1 && y<=y2;}/*** 飞行物死亡*/public void goDead(){state = DEAD;//将当前状态修改为死了的}
}
图片工具类Images:
此类用来获取每个对象对应的图片
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
/*** 图片工具类*/
public class Images {
// 公开的 静态的 图片数据类型 变量名/*** 对象图片*/public static BufferedImage sky;//天空public static BufferedImage bullet;//子弹public static BufferedImage[] heros;//英雄机public static BufferedImage[] airs;//小敌机public static BufferedImage[] bairs;//大敌机public static BufferedImage[] bees;//小蜜蜂/*** 状态图片*/public static BufferedImage start;//启动状态图public static BufferedImage pause;//暂停状态图public static BufferedImage gameover;//游戏结束状态图static {//初始化静态图片sky = readImage("background01.png");//天空bullet = readImage("bullet.png");//子弹heros = new BufferedImage[2];//英雄机图片数组heros[0] = readImage("hero0.png");//英雄机图片1heros[1] = readImage("hero1.png");//英雄机图片2airs = new BufferedImage[5];//小敌机图片数组bairs = new BufferedImage[5];//大敌机图片数组bees = new BufferedImage[5];//小蜜蜂图片数组airs[0] = readImage("airplane.png");//小敌机图片读取bairs[0] = readImage("bigairplane.png");//大敌机图片读取bees[0] = readImage("bee01.png");//小蜜蜂图片读取/**爆炸图迭代读取*/for (int i=1;i<5;i++){//遍历/迭代赋值airs[i] = readImage("bom"+i+".png");//小敌机图片数组其余元素赋值爆炸图bairs[i] = readImage("bom"+i+".png");//大敌机图片数组其余元素赋值爆炸图bees[i] = readImage("bom"+i+".png");//小蜜蜂图片数组其余元素赋值爆炸图}start = readImage("start.png");//启动状态图pause = readImage("pause.png");//暂停状态图gameover = readImage("gameover.png");//游戏结束状态图}/*** 读取图片* 此处的fileName:图片文件名** try.....catch:异常的一种处理方法*/public static BufferedImage readImage(String fileName){try{BufferedImage img = ImageIO.read(Flyer.class.getResource(fileName)); //读取与Flyer在同一个包中的图片return img;}catch(Exception e){e.printStackTrace();throw new RuntimeException();}}
}
世界窗口类/测试类 World:
此类用来集合所有类进行排序及具体的操作,和程序的最终运行
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.nio.Buffer;
//定时器
import java.util.Timer;
//定时器任务
import java.util.TimerTask;
//打开随机类
import java.util.Random;
//扩容类
import java.util.Arrays;
/*** 世界测试类(整个游戏窗口)*/
public class World extends JPanel{public static final int WIDTH = 400;//窗口宽public static final int HEIGHT = 700;//窗口高public static final int START = 0;//启动状态public static final int RUNNING = 1;//运行状态public static final int PAUSE = 2;//暂停状态public static final int GAME_OVER = 3;//游戏结束状态private int state = START;//当前状态默认是启动状态/*** 声明每个类具体的对象* 如下为:窗口中所看到的对象*/private Sky s = new Sky();//天空对象private Hero h = new Hero();//英雄机对象private Flyer[] enemies ={};//敌人对象,分别是大敌机,小敌机,小蜜蜂所以写成了数组private Bullet[] bt ={};//子弹也是有很多的所以写成了数组/*** 生成敌人对象(小敌机,大敌机,小蜜蜂)*/public Flyer nextOne(){Random rand = new Random();int type = rand.nextInt(20);//0-19之间的随机数if (type < 5){//当随机数小于5return new Bee();//返回小蜜蜂}else if (type < 13){//当随机数小于13return new Airplane();//返回小敌机}else{//大于十三则return new BigAirplane();//返回大敌机}}private int enterIndex = 0;/*** 敌人(大敌机,小敌机,小蜜蜂)入场*/public void enterAction() {//每10毫秒走一次enterIndex++;if (enterIndex%40 == 0 ){//四百毫秒走一次Flyer fl = nextOne();//获取敌人对象enemies = Arrays.copyOf(enemies,enemies.length+1);//扩容(每产生一个敌人数组就扩容1)enemies[enemies.length-1] = fl;//将生成的敌人fl放置enemies数组的末尾}}int shootIndex = 0;/*** 子弹入场*/public void shootAction(){//10毫秒走一次shootIndex++;if (shootIndex%30 == 0){//每300毫秒走一次Bullet[] bs = h.shoot();//获取子弹数组对象bt = Arrays.copyOf(bt,bt.length+bs.length);//扩容子弹数组(每入场一个子弹就加一个元素)System.arraycopy(bs,0,bt,bt.length-bs.length,bs.length);//数组的追加}}/*** 让除去英雄机外的所有对象(小敌机,大敌机,小蜜蜂,子弹,天空)移动*/public void setpAction() {//每10毫秒走一次s.step();//天空移动for (int i=0;i<enemies.length;i++) {//遍历所有敌人enemies[i].step();//敌人移动}for (int i=0;i<bt.length;i++){//遍历所有子弹bt[i].step();//子弹移动}}/*** 重写outOfBoundsAction(方法)*/public void outOfBoundsAction() {//每10毫秒走一次for (int i=0;i<enemies.length;i++){//遍历所有敌人if (enemies[i].isOutOfBounds() || enemies[i].isRemove()){enemies[i] = enemies[enemies.length-1];//最后一个敌人和越界敌人替换enemies = Arrays.copyOf(enemies,enemies.length-1);//缩容}}for (int i=0;i<bt.length;i++){//迭代所有子弹if (bt[i].isOutOfBounds() || bt[i].isRemove()){bt[i] = bt[bt.length-1];//用最后一个子弹替换出界的子弹bt = Arrays.copyOf(bt,bt.length-1);//缩容}}}private int score = 0;//玩家的得分/*** 子弹与敌人的碰撞*/public void bulletBangAction() {//每10毫秒走一次for (int i=0;i<bt.length;i++){//遍历所有子弹Bullet b = bt[i];//获取每一个子弹for (int j=0;j<enemies.length;j++){//迭代每一个敌人Flyer f = enemies[j];//获取每一个敌人if (b.isLive() && f.isLive() && f.isHit(b)){//若子弹活着的,敌人活着的,并且两个对象相撞b.goDead();//子弹当前状态修改为死亡f.goDead();//敌人当前状态修改为死亡if (f instanceof EnemyScore) {//判断死亡的敌人类型能否强转为得分接口类型EnemyScore es = (EnemyScore) f;//将死亡敌人向下造型score += es.getScore();//调用具体的敌人对象的得分接口的getScore()加分方法}if (f instanceof EnemyAward){//判断死亡的敌人类型能否强转为奖励值接口类型EnemyAward ea = (EnemyAward) f;//将死亡敌人强转为奖励值接口类型int type = ea.getAwardType();//将具体的奖励值赋值给typeswitch (type){case EnemyAward.FIRE://火力值h.addFier();//返回增加火力值break;case EnemyAward.LIFE://生命值h.addLife();//返回增加生命值break;}}}}}}/*** 英雄机与敌人的碰撞*/private void heroBangAction() {//每10毫秒走一次for (int i=0;i<enemies.length;i++){//迭代所有敌人Flyer f = enemies[i];//获取每个敌人if (f.isLive() && h.isLive() && f.isHit(h)){//判断碰撞f.goDead();//敌人死亡h.subtractLife();//英雄机减生命值h.clearFier();//英雄机清空火力值}}}/*** 检测游戏结束*/private void checkGameOverAction() {//每10毫秒走一次if (h.getLife() <= 0) {//若英雄机生命值为0或小于0state = GAME_OVER;//将状态修改为GAME_OVER游戏结束状态}}/*** 启动程序的执行*/public void action() {//测试代码MouseAdapter m = new MouseAdapter() {/*** 重写mouseMoved()鼠标移动事件* @param e*/@Overridepublic void mouseMoved(MouseEvent e) {if (state == RUNNING){//仅在运行状态下执行int x = e.getX();//获取鼠标的x坐标int y = e.getY();//获取鼠标的y坐标h.moveTo(x,y);//接收鼠标具体坐标}}/*** 重写mouseClicked() 鼠标点击事件* @param e*/public void mouseClicked(MouseEvent e){switch (state){//根据当前状态做不同的处理case START://启动状态时state = RUNNING;//鼠标点击后改成运行状态break;case GAME_OVER://游戏结束状态时/*清理战场(将所有数据初始化)*/score = 0;//总分归零s = new Sky();//天空初始化所有属性h = new Hero();//英雄机初始化所有属性enemies = new Flyer[0];//敌人初始化所有属性bt = new Bullet[0];//子弹初始化所有属性state = START;//鼠标点击后修改为启动状态break;}}/*** 鼠标移出窗口事件* @param e*/public void mouseExited(MouseEvent e){if (state == RUNNING){//若状态为运行state = PAUSE;//则将当前状态修改为暂停}}/*** 鼠标的进入窗口事件* @param e*/public void mouseEntered(MouseEvent e){if (state == PAUSE){//若当前状态为暂停state = RUNNING;//则将当前状态修改为运行}}};this.addMouseListener(m);this.addMouseMotionListener(m);Timer timer = new Timer();//定时器对象int interval = 10;//定时的间隔(此间隔是以毫秒为单位)timer.schedule(new TimerTask() {@Overridepublic void run() {//定时干的事(每10毫秒自动执行此方法当中的所有方法)if (state == RUNNING){//只在运行状态下执行enterAction();//敌人(大敌机,小敌机,小蜜蜂)入场shootAction();//子弹入场setpAction();//飞行物移动outOfBoundsAction();//删除越界的敌人bulletBangAction();//子弹与敌人的碰撞heroBangAction();//英雄机与敌人的碰撞checkGameOverAction();//检测游戏结束}repaint();//重新调用paint()方法(重画)}}, interval, interval);//定时计划表}/*** 重写paint方法,在窗口中画图片* @param g:画笔*/public void paint(Graphics g){//每10毫秒走一次g.drawImage(s.getImage(), s.x, s.y, null);//画天空g.drawImage(s.getImage(), s.x, s.getY1(), null);//画第二张天空g.drawImage(h.getImage(),h.x,h.y,null);//画英雄机for (int i=0;i<enemies.length;i++){//遍历所有敌人Flyer f = enemies[i];//获取每一个敌人g.drawImage(f.getImage(),f.x,f.y,null);//画敌人}for (int i = 0; i<bt.length; i++){//遍历所有子弹Bullet b = bt[i];//获取所有子弹g.drawImage(b.getImage(),b.x,b.y,null);//画子弹}g.drawString("SCORE:"+score,10,25);//在窗口右上角画分数g.drawString("HP:"+h.getLife(),10,45);//在窗口右上角画出英雄机的生命值switch (state){//画状态图case START:g.drawImage(Images.start,0,0,null);//启动状态图break;case PAUSE:g.drawImage(Images.pause,0,0,null);//暂停图break;case GAME_OVER:g.drawImage(Images.gameover,0,0,null);//游戏结束图break;}}/*** 主执行方法* @param args*/public static void main(String[] args) {JFrame frame = new JFrame();World world = new World();frame.add(world);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(WIDTH,HEIGHT);frame.setLocationRelativeTo(null);frame.setVisible(true);//1)设置窗口可见 2)尽快调用paint()方法world.action();//启动程序的执行}
}
/*** 1.问:为什么要将引用设计再main方法的外面?* 答:因为若将引用设计在main中,则引用只能在main中使用,其他方法都不能访问,* 为了能在其他方法中也能访问这些引用,所以将引用设计在main外** 2.问:为什么要单独创建action方法来测试?* 答:因为main方法时static的,在main方法中是无法访问引用的,* 所以需要单独创建非static的方法来测试** 3.问:为什么在main中要先创建world对象,然后再调用action()方法?* 答:因为main方法是static的,再main中是无法调用action()方法的* 所以要先创建world对象,然后再调用action()方法*/
小敌机类Airplane:
此类存储小敌机特有的属性及行为:
移动速度,分值,及图片的切换
继承超类,且实现得分接口
package cn.tedu.shoot;import java.awt.image.BufferedImage;/*** 小敌机*/
public class Airplane extends Flyer implements EnemyScore{// 移动速度private int speed;public Airplane(){super(66,89);speed = 2;//小敌机的下落速度}/**重写step方法(移动)*/public void step(){y += speed;//y+表示向下}int index = 1;/*** 重写getImage()获取对象图片* @return*/public BufferedImage getImage() {if (isLive()){//若活着 则返回airs[0]图片return Images.airs[0];}else if (isDead()){//若死了 则返回airs[1~4]图片BufferedImage img = Images.airs[index++];//获取爆破图if (index == Images.airs.length){//若index到了5 则表示到了最后一张state = REMOVE;//将当前状态修改为REMOVE删除的}return img;//返回爆炸图/*index = 110M isLive返回true 则 return返回airs[0]图片20M isLive返回false 则 执行isDead返回true img = airs[1] index = 2 返回airs[1]图片30M isLive返回false 则 执行isDead返回true img = airs[2] index = 3 返回airs[2]图片40M isLive返回false 则 执行isDead返回true img = airs[3] index = 4 返回airs[3]图片50M isLive返回false 则 执行isDead返回true img = airs[4] index = 5 state修改为REMOVE 返回airs[4]图片60M isLive返回false 则 执行isDead返回false return返回null空值(不返回图片)*/}return null;}/*** 重写getScore()方法* @return:分值*/public int getScore(){return 1;}
}
大敌机类BigAirplane:
大敌机与小敌机几乎无差别
同样要继承超类,且实现得分接口
package cn.tedu.shoot;import java.awt.image.BufferedImage;
import java.util.Random;/*** 大敌机*/
public class BigAirplane extends Flyer implements EnemyScore{
// 移动速度private int speed;public BigAirplane(){//初始化默认属性super(203,211);//图片宽,高speed = 2;//移动速度}/**重写step方法(移动)*/public void step(){y += speed;//y+表示直线向下移动}int index = 1;@Overridepublic BufferedImage getImage() {if (isLive()){//若活着 则返回airs[0]图片return Images.bairs[0];}else if (isDead()){//若死了 则返回airs[1~4]图片BufferedImage img = Images.bairs[index++];//获取爆破图if (index == Images.bairs.length){//若index到了5 则表示到了最后一张state = REMOVE;//将当前状态修改为REMOVE删除的}return img;}return null;}/*** 重写getScore()方法* @return:分值*/public int getScore(){return 3;}
}
小蜜蜂类Bee:
此类虽也可以算作敌人类,但是与小/大敌机有所不同,它是实现奖励值接口
package cn.tedu.shoot;import java.awt.image.BufferedImage;
import java.util.Random;/*** 小蜜蜂*/
public class Bee extends Flyer implements EnemyAward{// x坐标移动速度,y坐标移动速度,private int xSpeed;//x坐标移动速度private int ySpeed;//y坐标移动速度private int awardType;//奖励类型public Bee(){//初始化属性super(48,50);//图片宽,高Random rand = new Random();awardType = rand.nextInt(2);//随机奖励值类型0~2之间(不包括2)0表示火力值,1表示生命值xSpeed = 1;//平行移动ySpeed = 2;//垂直移动}/**重写step方法(移动)*/public void step() {y += ySpeed;//y+:向下移动x += xSpeed;//x+:随机向左或是向右移动if (x <= 0 || x >= World.WIDTH - width) {xSpeed *= -1;//到达边界后反方向移动(正负为负,负负为正)}}int index = 1;public BufferedImage getImage() {if (isLive()){//若活着 则返回airs[0]图片return Images.bees[0];//返回小蜜蜂图}else if (isDead()){//若死了 则返回airs[1~4]图片BufferedImage img = Images.bees[index++];//获取爆破图if (index == Images.bees.length){//若index到了5 则表示到了最后一张state = REMOVE;//将当前状态修改为REMOVE删除的}return img;//返回爆炸图}return null;}/*** 重写getAwardType()方法* @return*/public int getAwardType(){return awardType;//返回奖励类型}
}
天空类Sky:
这里有一点需要强调,就是为了实现天空图片向下移动后会出现移动过的位置出现图片丢失的情况,就使用了两张图上下拼接起来,当第某张天空图完全移出窗口的时候会让它重新出现在窗口上方继续向下移动
package cn.tedu.shoot;import java.awt.image.BufferedImage;/*** 天空*/
public class Sky extends Flyer{// 移动速度,y1private int y1;//第二张图片的y坐标private int speed;//移动速度public Sky(){//设置初始值(默认值)//此处的宽高用常量是因为天空的宽高和窗口是一致的,x轴和y轴为若不为0就和窗口不匹配了super(World.WIDTH,World.HEIGHT,0,0);//初始化图片坐标及宽,高speed = 1;//初始化移动速度y1 = -World.HEIGHT;//第二张图片设置在第一张图片上方}/**重写step方法(移动)*/public void step(){y += speed;//第一张图向下移动y1 += speed;//第二张图向下移动if (y >= World.HEIGHT){//若y>=窗口的高y = -World.HEIGHT;//将移动出去的第一张天空挪到窗口上方}if (y1 >= World.HEIGHT){//若第二张天空挪出窗口y1 = -World.HEIGHT;//将第二张天空挪到窗口上方}}/**重写getImage()获取对象图片*/@Overridepublic BufferedImage getImage() {//10毫秒走一次return Images.sky;//返回天空图片即可}/*** 获取y1坐标*/public int getY1(){return y1;//返回y1}
}
英雄机类Hero:
package cn.tedu.shoot;import java.awt.image.BufferedImage;
/*** 英雄机*/
public class Hero extends Flyer {// 命数,火力值private int life;//命数private int fire;//火力/*** 初始化英雄机坐标机具体数据*/public Hero() {super(97,139,140,400);//宽,高,及初始坐标fire = 0;//初始火力值 0:单倍火力life = 3;//初始生命值}/**重写step方法(移动)*/public void step(){//每10毫秒走一次//因为英雄机是跟随鼠标移动的,而鼠标是在窗口上的所以这里就没有写具体的方法,而是在窗口类中去用鼠标的具体坐标计算出英雄机的移动位置}int index = 0;//下标/**重写getImage()获取对象图片*/@Overridepublic BufferedImage getImage() {//每10毫秒走一次return Images.heros[index++ % Images.heros.length];//heros[0]和heros[1]来回切换/*过程index = 010M 返回heros[0] index = 120M 返回heros[1] index = 230M 返回heros[0] index = 340M 返回heros[1] index = 450M 返回heros[0] index = 560M 返回heros[1] index = 6...........*/}/*** 英雄机发射子弹(生成子弹对象)*/public Bullet[] shoot(){int xStep = this.width/4;//子弹x坐标int yStep = 5;//子弹y坐标System.out.println(this.x+"\t"+this.y);if (fire>0){//双倍火力Bullet[] bs = new Bullet[3];//2发子弹bs[0] = new Bullet(this.x+1*xStep,this.y-yStep);//子弹坐标1bs[1] = new Bullet(this.x+3*xStep,this.y-yStep);//子弹坐标2bs[2] = new Bullet(this.x+2*xStep,this.y-yStep);fire -= 2;//发射一次双倍活力,则火力值-2return bs;} else {//单倍火力Bullet[] bs = new Bullet[1];//1发子弹bs[0] = new Bullet(this.x+2*xStep,this.y-yStep);//x:英雄机的x+2/4英雄机的宽,y:英雄机的y-return bs;}}/*** 英雄机移动*/public void moveTo(int x,int y){//形参列表:鼠标的x坐标,y坐标this.x = x - this.width/2;//英雄机的x = 鼠标的x减1/2英雄机的宽this.y = y - this.height/2;//英雄机的y = 鼠标的y减1/2英雄机的高}/*** 英雄机增生命值*/public void addLife(){life++;//生命值+1}/*** 获取英雄机生命值* @return*/public int getLife(){return life;//返回生命值}/*** 英雄机减少生命值*/public void subtractLife(){life--;//生命值减1}/*** 英雄机增火力值*/public void addFier(){fire += 40;//火力值+40}/*** 清空火力值*/public void clearFier(){fire = 0;//火力值归零}
}
子弹类Bullet:
package cn.tedu.shoot;import java.awt.image.BufferedImage;/*** 子弹*/
public class Bullet extends Flyer {// 移动速度private int speed;public Bullet(int x,int y) {//子弹有多个,每个子弹的初始坐标都不同,所以要写活super(8,20,x,y);speed = 3;//初始移动速度}/**重写step方法(移动)*/public void step(){y -= speed;//y-:表示直线向上移动}/*** 重写getImage()获取对象图片* @return*/@Overridepublic BufferedImage getImage() {//10毫秒走一次if (isLive()){//若活着则返回bullet图片return Images.bullet;}else if (isDead()){//若死了则将state修改为REMOVEstate = REMOVE;}return null;//死了的和删除的都返回null空值/*** 若活着 则返回bullet图片* 若死了 则修改REMOVE 再返回空值* 若删除 则返回空值*/}/*** 判断子弹是否越界* @return*/public boolean isOutOfBounds(){return y <= -height;若子弹的y轴坐标小于自己的高则说明移动到了窗口外部}
}
奖励值接口 EnemyAward:
package cn.tedu.shoot;/*** 奖励值接口*/
public interface EnemyAward {public int FIRE = 0;//火力public int LIFE = 1;//生命值/*** 获取奖励值类型* @return*/int getAwardType();
}
得分接口 EnemyScore:
package cn.tedu.shoot;
/*得分接口*/
public interface EnemyScore {/*得分*/public int getScore();
}