Java基础飞机大战小游戏完整代码
先来展示一下代码实现结果图
主函数ShootGame
初始化游戏原始背景图片,游戏人物图片,游戏开始结束图片;构建产生敌人算法;产生英雄机算法;发射子弹算法;判断是否相撞算法(子弹与敌机相撞,英雄机与敌机相撞);击落敌人奖励算法;绘制游戏中人物算法;鼠标控制移动算法;
import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Random; import java.util.Timer; import java.util.TimerTask; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; public class ShootGame extends JPanel implements MouseMotionListener,MouseListener{ //继承JPanel类 public static final int width = 400; public static final int height = 600; //设置对象图片名称(与源文件名称一致) public static Image background; public static Image airplane; public static Image bee; public static Image bullet; public static Image gameover; public static Image hero0; public static Image hero1; public static Image pause; public static Image start; //定义游戏的四种状态 public static final int START = 0; //开始状态 public static final int RUNNING = 1; //运行状态 public static final int PAUSE = 3; //暂停状态 public static final int GAMEOVER =4; //结束状态 int state =START; //创建对象----------------------------------------------------------------------------------------------- Hero hero = new Hero(); //创建英雄机对象 Bullet[] bullets = {}; //子弹(众多),定义子弹数组 FlyingObject[] flyings = {}; //小敌机(众多),定义小敌机数组 //ShootGame无惨构造方法(给创建对象初始化) /*public ShootGame() { flyings = new FlyingObject[2]; //多态 夫妇 flyings[0] = new Airplane();//小敌机 flyings[1] = new Bee();//小蜜蜂 bullets = new Bullet[2]; bullets[0] = new Bullet(130,250); bullets[1] = new Bullet(100,120); }*/ //静态代码块内容加载 static { try { //导入图片文件----------------------------------------------------------------------------------- //将图片文件赋给图片对象 background = ImageIO.read(new File("image\\background.png")); airplane = ImageIO.read(new File("image\\airplane.png")); bee = ImageIO.read(new File("image\\bee.png")); bullet = ImageIO.read(new File("image\\bullet.png")); gameover = ImageIO.read(new File("image\\gameover.png")); hero0 = ImageIO.read(new File("image\\hero0.png")); hero1 = ImageIO.read(new File("image\\hero1.png")); pause = ImageIO.read(new File("image\\pause.png")); start = ImageIO.read(new File("image\\start.png")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //产生敌人方法------------------------------------------------------------------------------------------- public FlyingObject nextOne() { FlyingObject f; //小敌机类型 Random r = new Random(); //随机产生数 int random = r.nextInt(20); //产生[0,20)随机数 if(random > 3) { f = new Airplane(); //随机数为[4,20) 产生小敌机 }else { f = new Bee(); //随机数为[0,3] 产生小蜜蜂 } return f; //返回小敌机 } int flyingEnterIndex = 0; //敌人对象初始化为0 //把产生的敌人添加到敌人数组中方法------------------------------------------------------------------------ public void enterAction() { flyingEnterIndex++; //敌人对象自加 if(flyingEnterIndex % 50 == 0) { //50 100...每隔50毫秒执行一次,用于控制敌人出现速度 //1、创建敌人对象 FlyingObject one = nextOne(); //创建敌人对象,赋值给 One //2.将敌人对象添加到flyings敌人数组中 flyings = Arrays.copyOf(flyings, flyings.length+1); //扩容+1(增加小敌机) flyings[flyings.length-1] = one; //把产的敌人one赋值(添加)给最后一个数组元素 } } //游戏中各个对象的移动方式-------------------------------------------------------------------------------- public void stepAction() { //敌人的移动(敌人处于敌人数组中,调用数组) for(int i=0; i<flyings.length; i++) { //通过循环实现每个敌人移动 flyings[i].step(); //调用step方法,实现敌人的移动 } //子弹移动(子弹处于子弹数组中,调用子弹数组) for(int i=0; i<bullets.length; i++) { //通过循环实现每个子弹移动 bullets[i].step(); //调用step方法,实现子弹的移动 } //英雄机的移动 hero.step(); //调用step方法,实现英雄机的移动 } int shootIndex =0; //英雄机发射子弹方法------------------------------------------------------------------------------------- public void shootAction() { shootIndex++; if(shootIndex % 30 == 0) { //10*30=300毫秒 Bullet[] bs = hero.shoot(); //用数组存放子弹 //扩容(将bs存放至bullets子弹数组中) bullets = Arrays.copyOf(bullets, bullets.length+bs.length); //子弹数组+新生成对象 //将子弹对象添加至子弹数组中 System.arraycopy(bs,0,bullets,bullets.length-bs.length,bs.length); } } int score = 0; //子弹与敌人相撞----------------------------------------------------------------------------------------- public void hitAction() { //遍历所有子弹 for(int i= 0; i<bullets.length; i++) { Bullet b = bullets[i]; //记录当前子弹 //遍历所有敌人 for(int j = 0; j<flyings.length; j++) { FlyingObject f = flyings[j]; //记录当前敌人 //判断是否相撞 if(f.hitBy(b)) { //敌人消失 //1,当前敌人与最后一个数组元素交换 FlyingObject temp = flyings[j]; flyings[j] = flyings[flyings.length-1]; flyings[flyings.length-1] = temp; //2.扩容-1(消灭敌人) flyings=Arrays.copyOf(flyings, flyings.length-1); //子弹消失 //1.当前子弹与最后一个数组元素交换 Bullet t =bullets[i]; bullets[i] = bullets[bullets.length-1]; bullets[bullets.length-1] = t; //2.扩容-1(子弹消失) bullets=Arrays.copyOf(bullets, bullets.length-1); //得到加分或奖励,需要区分是小敌机还是小蜜蜂 if(f instanceof Airplane) { //是小敌机 score += hero.getScore(); //加奖励分 } if(f instanceof Bee) { //是小蜜蜂,根据奖励类型增加火力还是生命 Bee bee = (Bee)f; //向下转型Bee int award = bee.getAwardType(); switch(award) { case 0: hero.addDoubleFire(); //增加火力 break; case 1: hero.addLife(); //增加生命值 break; } } } } } } //英雄机与敌人相撞方法------------------------------------------------------------------------------------ public void duangAction() { //遍历所有敌人 for(int i = 0; i<flyings.length; i++) { if(hero.duang(flyings[i])) { //敌人消失 FlyingObject temp = flyings[i]; flyings[i] = flyings[flyings.length-1]; flyings[flyings.length-1] = temp; flyings=Arrays.copyOf(flyings, flyings.length-1); //扩容,减掉敌人 //英雄机减掉生命值,火力清零 hero.life--; hero.doubleFire = 0; } } } //检测英雄机生命值方法------------------------------------------------------------------------------------ public void checkGame() { if(hero.life <= 0) { state = GAMEOVER; } } //游戏中的各种行为方法----------------------------------------------------------------------------------- public void action() { //添加定时器(每隔多久出现一次) Timer timer = new Timer();//utill包下 //安排指定任务从指定的延迟后开始进行重复的固定延迟执行 timer.schedule(new TimerTask() { @Override public void run() { // TODO Auto-generated method stub if(state == RUNNING) { //处于运行状态执行操作 enterAction(); //敌人入场 stepAction(); //设置对象的移动方式 shootAction(); //英雄机发射子弹 hitAction(); //子弹与敌人相撞 duangAction(); //英雄机与敌人撞 checkGame(); //检测英雄机生命值 } repaint(); //重新绘制(产生新的小敌机) }}, 10,10); } //绘制分数方法------------------------------------------------------------------------------------------- public void paintScore(Graphics g) { g.setFont(new Font("黑体",Font.BOLD,20)); //颜色,字体,字号 g.drawString("SCORE:"+score, 30, 30); //绘制SCORE:分数(坐标位置) g.drawString("LIFE:"+hero.life,30,60); //绘制LIFE: 生命值(坐标位置) g.drawString("FIRE:"+hero.doubleFire, 30, 90); //FIRE:火力值(坐标位置) } //绘制状态图方法----------------------------------------------------------------------------------------- public void paintState(Graphics g) { switch(state) { case START: g.drawImage(start, 0, 0, null); //绘制start图片,坐标(0,0) break; case PAUSE: g.drawImage(pause, 0, 0, null); //绘制pause图片,坐标(0,0) break; case GAMEOVER: g.drawImage(gameover, 0, 0, null); //绘制gameover图片,坐标(0,0) break; } } //绘图方法----------------------------------------------------------------------------------------------- public void paint(Graphics g) { //Jpanel类下paint方法 super.paint(g); g.drawImage(background,0,0,null); //通过背景图片进行绘画,从坐标(0,0)开始绘画 //g.drawImage(airplane, 100, 100, null);绘制小敌机固定位置图像 //通过方法调用实现动态实时绘图 //绘制敌人 paintFlying(g); //绘制子弹 paintBullet(g); //绘制英雄机 paintHero(g); //绘制分值 paintScore(g); //绘制状态图 paintState(g); } //绘制英雄机方法----------------------------------------------------------------------------------------- public void paintHero(Graphics g) { // TODO Auto-generated method stub g.drawImage(hero.image, hero.x, hero.y, null); } //绘制子弹方法------------------------------------------------------------------------------------------- public void paintBullet(Graphics g) { // TODO Auto-generated method stub for(int i = 0; i<bullets.length; i++) { g.drawImage(bullets[i].image, bullets[i].x, bullets[i].y, null); } } //绘制敌人方法------------------------------------------------------------------------------------------- public void paintFlying(Graphics g) { // TODO Auto-generated method stub for(int i = 0; i<flyings.length; i++) { g.drawImage(flyings[i].image, flyings[i].x, flyings[i].y, null); } } //主方法 public static void main(String[] args) { //飞机大战窗体制作 JFrame jf = new JFrame("飞机大战"); jf.setSize(width, height); //设置窗体宽高 jf.setLocationRelativeTo(null); //窗体居中 jf.setVisible(true); //窗体可见 jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //导入背景图片 ShootGame game = new ShootGame(); //创建ShootGame对象 jf.add(game); //在窗体中添加背景图片 game.action(); //游戏中的各种操作 jf.addMouseMotionListener(game); //添加监听器(对对象实时监控) jf.addMouseListener(game); //添加监听器(对鼠标实时监控) } @Override public void mouseDragged(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseMoved(MouseEvent e) { //鼠标移动 // TODO Auto-generated method stub if(state == RUNNING) { //在运行状态下执行操作 hero.x =e.getX()-hero.width/2; //鼠标的具体坐标(x,y) hero.y =e.getY()-hero.height/2; //根据鼠标的位置确定英雄机的位置 } } //鼠标单击启动 @Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub if(state == START) { state = RUNNING; //开始运行 } if(state == GAMEOVER) { state = START; //返回开始状态 hero = new Hero(); flyings = new FlyingObject[] {}; bullets = new Bullet[] {}; score = 0; } } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } //鼠标进入 @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub if(state == PAUSE) { state = RUNNING; //修改为运行 } } //鼠标退出 @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub if(state == RUNNING) { state = PAUSE; //修改为暂停 } } }
所有类的父类FlyingObject
概括所有对象的共性,统一调用
import java.awt.Image; //父类(英雄机,小敌机,小蜜蜂,子弹) public abstract class FlyingObject { //抽象方法必须为抽象类 int x,y; //定位 int width,height; //对象宽度和高度 Image image; //定义图像 //让每一个子类移动的方法---------------------------------------------------------------------------------- public abstract void step(); //由于每个子类的移动方法不一样,定为抽象方法 //判断子弹是否与敌人相撞方法------------------------------------------------------------------------------- public boolean hitBy(Bullet bullet) { int x = bullet.x; //子弹x 坐标 int y = bullet.y; return x>this.x && x<this.x+this.width && y>this.y && y<this.y+height; //子弹与敌人相撞的临界状态 } }
英雄机Hero类
主要包括英雄机出现位置,英雄机大小,生命值,火力值的设置算法;英雄机发射子弹算法;英雄机与敌机相撞判定算法;英雄机打到小蜜蜂的奖励算法。
import java.awt.Image; //英雄机 public class Hero extends FlyingObject{ int life; //英雄机生命 int doubleFire; //英雄机火力值0/1 Image[] images = {}; //图片数组(两张图片切换动画) public Hero() { image = ShootGame.hero0; //使用第一张英雄机图片 width = image.getWidth(null); //获得英雄机宽度 height = image.getHeight(null); //获得英雄机宽度 x = 150; //英雄机初始高度宽度 y = 450; life = 3; //初始生命 doubleFire = 0; //开始英雄机单倍火力 images =new Image[] {ShootGame.hero0,ShootGame.hero1}; //两张图片 } int index = 0; //实现抽象父类中对象移动的方法 @Override public void step() { // TODO Auto-generated method stub image = images[index++/10%images.length];//图片数组切换,形成英雄机动画,最后赋值给image } //发射子弹的方法------------------------------------------------------------------------------------------ public Bullet[] shoot() { Bullet[] bs = {}; //子弹数组,初值为空 if(doubleFire ==0) { //单倍火力 bs = new Bullet[1]; bs[0] = new Bullet( x+width/2-4,y-14); //一颗子弹的坐标计算 }else { //双倍火力 bs =new Bullet[2]; bs[0] = new Bullet(x+width/4-4,y-14); //英雄机的宽度1/4-子弹宽度的一半 bs[1] = new Bullet(x+width*3/4-4,y-14); doubleFire -= 2; } return bs; } //获取得分------------------------------------------------------------------------------------------------ public int getScore() { return 5; } //增加火力------------------------------------------------------------------------------------------------ public void addDoubleFire() { doubleFire +=40; } //增加生命------------------------------------------------------------------------------------------------ public void addLife() { life += 1; } //判断英雄机是否与敌人相撞方法----------------------------------------------------------------------------- public boolean duang(FlyingObject f) { int x = this.x; int y = this.y; //获得英雄机当前位置 int x1 = f.x - this.width; //敌人x坐标-英雄机宽度 int x2 = f.x + f.width; //敌人x坐标+敌人宽度 int y1 = f.y - this.height; //敌人y坐标-英雄机高度 int y2 = f.y + f.height; //敌人y坐标+敌人高度 return x>x1 && x<x2 &&y>y1 && y<y2; //临介条件 } }
小敌机Airplane类
设置小敌机出现位置,移动限制
//小敌机 public class Airplane extends FlyingObject { int ySpeed; //向下速度 public Airplane() { image = ShootGame.airplane; //小敌机图片 width = image.getWidth(null); //小敌机宽度 height = image.getHeight(null); //小敌机高度 x = (int) (Math.random()*ShootGame.width); //小敌机出现x坐标,背景屏幕宽度 y = -height; //小敌机的y坐标 ySpeed = 1; //向下移动速度 } //实现抽象父类中对象移动的方法----------------------------------------------------------------------------- @Override public void step() { // TODO Auto-generated method stub y += ySpeed; //一次递增一个速度 } }
小蜜蜂Bee类
小蜜蜂奖励算法;小蜜蜂出现算法;
//小蜜蜂 public class Bee extends FlyingObject{ int ySpeed;//向下速度 int xSpeed;//左右速度 int awardType; public Bee() { image = ShootGame.bee; //调用小蜜蜂图片 width = image.getWidth(null); //获取图片宽度 height = image.getHeight(null); //获取图片高度 x = (int) (Math.random()*ShootGame.width); //小蜜蜂x坐标(随机进入) y = -height; //小蜜蜂高度,设为窗体下方,方便提前看到小蜜蜂 xSpeed = 1; //小蜜蜂x轴方向速度 ySpeed = 1; //小蜜蜂y轴方向速度 awardType = (int) (Math.random()*2); //得分(随机性) } //实现抽象父类中对象移动的方法----------------------------------------------------------------------------- @Override public void step() { // TODO Auto-generated method stub y += ySpeed; x += xSpeed; if(x > ShootGame.width - width) { //大于屏幕宽度-x宽度小蜜蜂大于右边界 xSpeed =-1; } if(x<=0) { xSpeed = 1; //小蜜蜂移动至左边界,向右移动 } } //获取得分方法-------------------------------------------------------------------------------------------- public int getAwardType() { return awardType; } }
子弹Bullet类
包括对发射子弹初始化,子弹移动的设置
//子弹 public class Bullet extends FlyingObject{ int ySpeed; //子弹向下速度 public Bullet(int x,int y) { image = ShootGame.bullet; //调用子弹图片 width = image.getWidth(null); //获得子弹宽度 height = image.getHeight(null); //获得子弹高度 this.x = x; //子弹实时坐标(随英雄机变换) this.y = y; ySpeed = 3; } //实现抽象父类中对象移动的方法 @Override public void step() { // TODO Auto-generated method stub y -= ySpeed; } }
## 游戏规则 ```java 飞机大战游戏规则(游戏需求) 通过鼠标点击游戏Start界面开始游戏;鼠标控制英雄机移动; 父类FlyingObject(提取共同属性,制作父类) 属性 x,y width,height img 小敌机Airplane 属性 x,y(定位其位置) width,height(定义图片高度宽度) img(图片属性) ySpeed=1(只能上下移动,下移速度为1) 小蜜蜂Bee 属性 x,y(定位其位置) width,height(定义图片高度宽度) img(图片属性) ySpeed=1(可以上下移动,下移速度为1) XSpeed(可以左右移动) awardType(被打到时奖励0/1分)0:奖励单倍火力 1:奖励双倍火力(随机性) 英雄机(随鼠标移动) 属性 x,y(定位其位置) width,height(定义图片高度宽度) img(图片属性) life(生命值) doubleFire(火力值)0:发射一个子弹 1:发射两个子弹 行为 发射子弹,鼠标移动 子弹 属性 x,y(定位其位置) width,height(定义图片高度宽度) img(图片属性) ySpeed(只能上移)
游戏基础人物构造图片
图片需要统一放在image文件夹中,方便调用。image文件放入创建的Java项目包下。
结束语
若想获得更多的编程干货,关注博主,持续更新福利。