飞机大战
飞机大战小游戏历经10天完成,主要用到的就是我们面向对象部分的知识:类,封装,继承,多态,静态代码块等等内容+swing部分内容。所以即使你是java小白,也不用担心欧!
游戏说明:游戏有3种敌机(大敌机,小敌机,小蜜蜂)和一个英雄机,子弹,天空;英雄机随鼠标移动,可以发射子弹,其它三种敌机不能发射子弹,但是可以移动,加载图片都有自己的大小,所以我们定义一个飞行物的抽象类,把这些飞行物的共有属性和行为给封装起来,让子类去继承,重写!
飞行物类抽象类
:
//飞行物public abstract class FlyingObject {public static final int LIVE = 0;//活着的public static final int DEAD = 1;//死亡public static final int REMOVE = 2;//删除protected int state = LIVE;//默认状态 活着的protected int width;//宽protected int hight;//高//坐标protected int x;protected int y;//专门给小/大敌机和小蜜蜂用的public FlyingObject(int width,int hight) {this.width = width;this.hight = hight;Random r = new Random();x = r.nextInt(World.WIDTH-width);//敌机x的活动范围y = -hight;}//专门给英雄机,天空,子弹public FlyingObject(int width, int hight, int x, int y) {this.width = width;this.hight = hight;this.x = x;this.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;}/*判断敌人越界*/public boolean isOutOfBounds(){return y>=World.HEIGHT;}/*检测敌人碰撞 子弹/英雄机*/public boolean isHit(FlyingObject object){int x1 = this.x-object.width;int x2 = this.x+this.width;int y1 = this.y-object.hight;int y2 = this.y+this.hight;int x = object.x;int y = object.y;return x>=x1 && x<=x2 && y>=y1 && y<=y2;}/*飞行物去死*/public void goDead(){state = DEAD;}}
大敌机
:
//大敌机public class BigAirplane extends FlyingObject implements EnemyScore{private int speed;//速度//构造public BigAirplane() {super(66,89);speed = 2;}//飞行物移动public void step(){y+=speed;}int index = 1;public BufferedImage getImage() {if (isLive()){return Images.bigairplanes[0];}else if (isDead()){BufferedImage img = Images.bigairplanes[index++];if (index==Images.bigairplanes.length){state = REMOVE;}return img;}return null;}@Overridepublic int getScore() {return 3;}}
小敌机:
//小敌机public class Airplane extends FlyingObject implements EnemyScore{private int speed;//速度//构造public Airplane() {super(49,50);speed = 2;}//飞行物移动public void step(){y+=speed;}int index = 1;public BufferedImage getImage() {if (isLive()){return Images.airplanes[0];}else if (isDead()){BufferedImage img = Images.airplanes[index++];if (index==Images.airplanes.length){state = REMOVE;}return img;}return null;}@Overridepublic int getScore() {return 1;}}
小蜜蜂
:
public class Bee extends FlyingObject implements EnemyAward{private int xspeed;//速度private int yspeed;private int awardType;//构造public Bee() {super(60,51);xspeed = 1;yspeed = 2;Random r = new Random();awardType = r.nextInt(2);}//飞行物移动public void step(){x+=xspeed;y+=yspeed;if (x<=0 || x>=World.WIDTH-this.width){xspeed*=-1;}}int index = 1;public BufferedImage getImage() {if (isLive()){return Images.bees[0];}else if (isDead()){BufferedImage img = Images.bees[index++];if (index==Images.bees.length){state = REMOVE;}return img;}return null;}@Overridepublic int getAward() {return awardType;}}
英雄机
:
//英雄机public class Hero extends FlyingObject {private int lift;//命private int fire;//火力值//无参构造public Hero() {super(97,139,140,400);lift = 3;fire = 0;//单倍火力}//飞行物移动public void step(){}int index = 0;public BufferedImage getImage() {return Images.heros[index++%Images.heros.length];}/*** 生成子弹对象*/public Bullet[] shoot(){int xStep = this.width/4;//把英雄机 宽度默认分四分int yStep = 20;//单双子弹 和 火力有关系if (fire>0){Bullet []bt = new Bullet[2];//双bt[0] = new Bullet(this.x+xStep,this.y-yStep);//位置bt[1] = new Bullet(this.x+3*xStep,this.y-yStep);//位置fire-=2;return bt;}Bullet[]bt = new Bullet[1];//单发bt[0] = new Bullet(this.x+2*xStep,this.y-yStep);return bt;}/*英雄级随着鼠标动*/public void moveTo(int x,int y){this.x = x-this.width/2;this.y = y-this.hight/2;}public int getLift() {return lift;}//减命public void subtractLife(){lift--;}//清空活力public void clearFire(){fire = 0;}//加子弹public void addFire(){fire+=40;}//加命public void addLife(){lift++;}}
子弹
:
//子弹public class Bullet extends FlyingObject{private int speed;//速度//构造public Bullet(int x,int y){super(8,20,x,y);speed = 3;}//飞行物移动public void step(){y-=speed;}//获取图片@Overridepublic BufferedImage getImage() {if (isLive()){return Images.bullet;}else if (isDead()){state = REMOVE;}return null;}//判断越界public boolean isOutOfBounds(){return y<-hight;}}
天空
:
这里说明下,我们天空做的时候用的两张图片,游戏开始,两个天空图同步向下运行,当底下的天空图刚好出窗口时候,又回到窗口上方,继续同步的向下运动!
//天空public class Sky extends FlyingObject{private int y1;//我们两张图片切换使用private int speed;//速度//构造public Sky() {super(World.WIDTH,World.HEIGHT,0,0);speed = 1;y1 = -World.HEIGHT;}//飞行物移动public void step(){y+=speed;y1+=speed;if (y>=World.HEIGHT){y = -World.HEIGHT;}if (y1>=World.HEIGHT){y1 = -World.HEIGHT;}}//获取图片public BufferedImage getImage() {return Images.sky;}public int getY1() {return y1;}}
我们既然要加载图片,那就要定义一个初始化图片的类,放在静态代码块里面,在类加载的时候就会把我们这些图片加载进来:Images
类
public class Images {public static BufferedImage sky;public static BufferedImage bullet;public static BufferedImage[] airplanes;public static BufferedImage[] bigairplanes;public static BufferedImage[] bees;public static BufferedImage[] heros;//状态图public static BufferedImage start;//启动图public static BufferedImage pause;//启动图public static BufferedImage gameover;//启动图static{start = loadImage("start.png");pause = loadImage("pause.png");gameover = loadImage("gameover.png");sky = loadImage("background.png");bullet = loadImage("bullet.png");heros = new BufferedImage[2];heros[0] = loadImage("hero0.png");heros[1] = loadImage("hero1.png");airplanes = new BufferedImage[5];bigairplanes = new BufferedImage[5];bees = new BufferedImage[5];airplanes[0] = loadImage("airplane.png");bigairplanes[0] = loadImage("bigairplane.png");bees[0] = loadImage("bee.png");for(int i=1;i<airplanes.length;i++){airplanes[i] = loadImage("bom"+i+".png");bigairplanes[i] = loadImage("bom"+i+".png");bees[i] = loadImage("bom"+i+".png");}}public static BufferedImage loadImage(String fileName){try{BufferedImage img = ImageIO.read(FlyingObject.class.getResource(fileName));return img;}catch(Exception e){e.printStackTrace();throw new RuntimeException();}}}
最后是我们的核心类:
我们游戏所有的核心代码:碰撞,删除打死的敌人和出界敌人,鼠标移动,飞行物入场等代码,都在这个类实现:
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 PAUSH = 2;//暂停public static final int GOME_OVER = 3;//游戏结束public int state = START;//默认启动Sky s = new Sky();Hero hero = new Hero() ;Bullet[] bullets= {};FlyingObject[] enemies = {};/*** 专门生成敌人对象 随机数范围生成*/public FlyingObject nextOne(){Random r = new Random();int type = r.nextInt(20);if (type<4){return new Bee();}else if (type <13){return new Airplane();}else {return new BigAirplane();}}/*** 敌人入场*/int enterIndex = 0;public void enterAction(){enterIndex++;if (enterIndex%40==0){FlyingObject obj = nextOne();enemies = Arrays.copyOf(enemies,enemies.length+1);enemies[enemies.length-1] = obj;}}/*** 子弹入场*/int shootIndex = 0;public void shootAction(){shootIndex++;if (shootIndex%30==0){Bullet []bt = hero.shoot();bullets = Arrays.copyOf(bullets,bullets.length+bt.length);System.arraycopy(bt,0,bullets,bullets.length-bt.length,bt.length);}}//飞行物移动public void stepAction(){//10毫秒s.step();for (int i = 0;i<enemies.length;i++){enemies[i].step();}for (int i = 0;i<bullets.length;i++){bullets[i].step();}}//删除越界飞行物public void outOfBoundsAction(){//飞行物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<bullets.length;i++){if (bullets[i].isOutOfBounds()|| bullets[i].isRemove()){bullets[i] = bullets[bullets.length-1];bullets = Arrays.copyOf(bullets,bullets.length-1);}}}private int score = 0;//玩家得分/*** 子弹与敌人碰撞*/public void BulletBangAvtion(){for (int i = 0;i<bullets.length;i++){Bullet b = bullets[i];//取出每一个子弹for (int j = 0;j<enemies.length;j++){FlyingObject f = enemies[j];//f 飞行物if (b.isLive() && f.isLive() && f.isHit(b)){b.goDead();f.goDead();if (f instanceof EnemyScore){EnemyScore e = (EnemyScore)f;score+=e.getScore();}if (f instanceof EnemyAward){EnemyAward s = (EnemyAward)f;int ward = s.getAward();switch (ward) {case EnemyAward.FIRE:hero.addFire();break;case EnemyAward.LIFE:hero.addLife();break;}}}}}}//英雄级和敌人碰撞public void heroBangAction(){for(int i = 0;i<enemies.length;i++){FlyingObject f = enemies[i];if (f.isLive() && hero.isLive() && f.isHit(hero)){f.goDead();hero.subtractLife();//减命hero.clearFire();//清空活力}}}//英雄机 没命了 ->游戏结束public void checkGameOverAction(){if (hero.getLift()<=0){state = GOME_OVER;}}//业务处理void action(){//倾侦听器对象MouseAdapter m = new MouseAdapter() {@Overridepublic void mouseMoved(MouseEvent e) {if (state == RUNNING) {int x = e.getX();int y = e.getY();hero.moveTo(x, y);}}//鼠标点击public void mouseClicked(MouseEvent e) {switch (state){case START:state = RUNNING;break;case GOME_OVER:score = 0;s = new Sky();hero = new Hero();enemies = new FlyingObject[0];bullets = new Bullet[0];state = START;break;}}//鼠标移出5public void mouseExited(MouseEvent e) {if (state == RUNNING){state = PAUSH;}}//鼠标移出public void mouseEntered(MouseEvent e) {if (state == PAUSH){state = RUNNING;}}};this.addMouseListener(m);//处理鼠标操作this.addMouseMotionListener(m);//处理鼠标滑动Timer timer = new Timer();//定时器int interVel = 10;//定时间隔 10(毫秒)timer.schedule(new TimerTask() {@Overridepublic void run() {if (state == RUNNING) {enterAction();//敌人入场shootAction();//子弹入场stepAction();//飞行物移动outOfBoundsAction();//飞行物移动BulletBangAvtion();//子弹与敌人碰撞heroBangAction();//英雄级和敌人碰撞checkGameOverAction();}repaint();}}, interVel, interVel);}public void paint(Graphics g){//画 对象g.drawImage(Images.sky,s.x,s.y,null);g.drawImage(Images.sky,s.x,s.getY1(),null);g.drawImage(hero.getImage(),hero.x,hero.y,null);for (int i = 0;i<enemies.length;i++){FlyingObject f = enemies[i];g.drawImage(f.getImage(),f.x,f.y,null);}for (int i = 0;i<bullets.length;i++){Bullet b = bullets[i];g.drawImage(b.getImage(),b.x,b.y,null);}//画 分g.drawString("SCORE"+score,10,25);//画命g.drawString("LIFE:"+hero.getLift(),10,45);switch (state){case START:g.drawImage(Images.start,0,0,null);break;case PAUSH:g.drawImage(Images.pause,0,0,null);break;case GOME_OVER:g.drawImage(Images.gameover,0,0,null);break;}}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);world.action();}}
代码呢,我就上传到百度网盘,考虑到大家可视化工具的不一致问题,我就上传了两份项目代码:idea和eclipse,下载后,导入项目即可畅玩,下面有运行图欧!
提取码:4897
eclipse:
/s/1xv94T3jWy_K0wchB97-slw
idea:
/s/1itHG2ScWLjmourPsiIzg0A
以下是飞机大战运行图: