【小白学习之路】Java实现简单的飞机大战小游戏 您所在的位置:网站首页 飞机大战游戏功能介绍图片 【小白学习之路】Java实现简单的飞机大战小游戏

【小白学习之路】Java实现简单的飞机大战小游戏

2023-12-11 22:34| 来源: 网络整理| 查看: 265

飞机大战小游戏

在这里插入图片描述 目录

项目介绍框架搭建代码实现总结分析

前言: 前一段时间写了一个仿QQ的聊天室,主要涉及Java通信有关的知识,今天写的这个飞机大战主要是复习之前写过的,这次我会加入一些其他的元素和对界面进行一些完善。

这篇博客我会写的比较通透,主要是自己用来复习和巩固知识点的,所以大家如果感兴趣的话,可以参考我的这篇博客!特别是正在学习Java的同学哦!!!

项目介绍

实现飞机大战设计的知识点还是比较多的,所以特别推荐编程小白先上手这种简单的游戏,这样既可以巩固简单的Java基础知识,又可以实现自己编写的小作品,展现自己的能力,何乐而不为呢?下面我就简单地介绍一下实现飞机大战要了解和使用的相关知识吧ƪ(˘⌣˘)ʃ

继承机制 一. 为什么要用继承? 简单说:首先要实现飞机大战,根据Java面向对象编程的特性,我们就必须明白整个游戏有哪几个对象?不难知道有:自己的战机、敌机、子弹(敌机和我机子弹)和背景。观察这几个对象可以知道,它们都有一些共同的属性,如战机和敌机的血量、它们的坐标和移动的方法等等。 由上所述,我们可以合理地采用接口或者抽象类来让子类继承,这样可以充分地复用代码,大大地减少了代码的冗余。让我们更快地完成飞机大战这个小游戏。 二.如何使用继承? 对于为什么要用继承上面我已经说明了,下面就详详细说一下接口和抽象类。我们都知道,但我们用extends去继承一个类的时候,子类就拥有了父类的属性和方法,自然就可以去调用。同时我们也可以覆写父类的方法(如果父类的方法比较不具体),这里就有一个名词:抽象类,该类本身就要声明为abstract,同时抽象的方法也要声明。如果我们就是想要一个十分抽象的类,该类中的方法全部是抽象的方法(只是定义了方法的名称,没有方法体的方法),目的是为了子类可以继承该类从而覆写其中的的所有方法,我们把这个类称为接口,我们用interface来定义接口,implement来实现接口。 接口和抽象类的比较: 从上面可知,按抽象的程度来比较,一般的类 //控制飞机上下左右移动 boolean up=false; boolean down=false; boolean left=false; boolean right=false; private int x,y; //得分和血量 private int scores; private int hp; //我机图片 private Image image_myfeiji; public MyFeiJi(){ image_myfeiji=new ImageIcon("D:\\常用\\图片\\" + "Camera Roll\\image\\战机.png").getImage(); } //移动界限 public void move() { if(x x=1790; } if(y y=910; } //移动速度 if(up){ y-=3; } if(down){ y+=3; } if(left){ x-=4; } if(right){ x+=3; } } public void draw(Graphics g) { g.setFont(new Font("黑体",Font.BOLD, 35)); g.setColor(Color.RED); g.drawString("我的血量:"+hp,30,90); g.setFont(new Font("黑体",Font.BOLD, 35)); g.setColor(Color.RED); g.drawString("我的得分:"+scores,30,140); g.drawImage(image_myfeiji, x, y, null); } //判断是否输赢 public boolean isDefeat(){ if(hp return false; } } //设置和获得坐标的方法 public void setX(int startX) { this.x=startX; } public void setY(int startY) { this.y=startY; } public int getX() { return x; } public int getY() { return y; } //检测我的飞机是否被敌机子弹击中 public boolean isShootByDiJiBullet(DiJiBullet dijibullet){ int x1=this.x;//我的飞机x坐标 int y1=this.y;//我的飞机y坐标 int width1=this.image_myfeiji.getWidth(null);//我机的宽度 int height1=this.image_myfeiji.getHeight(null);//我机的高度 int x11=x1+width1/2; int y11=y1+height1/2;//确定中心位置 //敌机的横纵坐标和高度 int x2=dijibullet.getX(); int y2=dijibullet.getY(); int width2=dijibullet.getDiJiBulletWidth(); int height2=dijibullet.getDiJiBulletHeight(); int x22=x2+width2/2; int y22=y2+height2/2; //计算距离 int distanceX=Math.abs(x22-x11); int distanceY=Math.abs(y22-y11); //是否碰撞 if(distanceX return false; } } //检测我的飞机是否被敌机碰撞 public boolean isShootByDiJi(Diji diji){ int x1=this.x;//我的飞机x坐标 int y1=this.y;//我的飞机y坐标 int width1=this.image_myfeiji.getWidth(null);//我机的宽度 int height1=this.image_myfeiji.getHeight(null);//我机的高度 int x11=x1+width1/2; int y11=y1+height1/2;//确定中心位置 //敌机的横纵坐标和高度 int x2=diji.getX(); int y2=diji.getY(); int width2=diji.getDiJiWidth(); int height2=diji.getDiJiHeight(); int x22=x2+width2/2; int y22=y2+height2/2; //计算距离 int distanceX=Math.abs(x22-x11); int distanceY=Math.abs(y22-y11); //是否碰撞 if(distanceX return false; } } //掉血方法 public void subBlood(){ this.hp--; } public void subDoubleBlood(){ this.hp-=5; } //加分方法 public void addScores(){ scores+=5; } public void addDoubleScores(){ scores+=10; } //设置血量 public void setHP(int hp){ this.hp=hp; } public int getHP(){ return hp; } } DiJi.java:敌机类 /** * 敌机类 * @author 梦想少年 * 实现接口中的方法,随机产生敌机并设置敌机相关的一些属性 */ public class Diji implements Entity{//敌机 private int x,y; //控制敌机可以追踪战机 private int automaticMove; //判断敌机是否爆炸 private boolean isDied; //爆炸音乐 File musicFile; //敌机图片 private Image dijiImage; //爆炸图片 private Image diedImage; //产生子弹的数量 private int dijiBulletCount; //初始化 public Diji(){ musicFile=new File("C:\\Users\\梦想少年\\Music\\" + "AudioConvert\\大爆炸.wav"); dijiImage=new ImageIcon("D:\\常用\\图片\\" + "Camera Roll\\image\\diji.png").getImage(); diedImage=new ImageIcon("D:\\常用\\图片\\" + "Camera Roll\\image\\1\\7.png").getImage(); Random random=new Random(); x=random.nextInt(100)+1900; y=random.nextInt(800)+80; } //移动方法 public void move() { if(automaticMove==1){ y--; } if(automaticMove==2){ y++; } x-=2; } //画出敌机 public void draw(Graphics g) { g.drawImage(dijiImage,x,y,128,128,null); if(isDied){ g.drawImage(diedImage, x, y, null); } } //判断是否越界 public boolean isOutBounds(){ if(x return false; } } //设置飞机炮炸的方法 public void Blast(){ isDied=true; } //打开敌机炮炸音乐 @SuppressWarnings("deprecation") public void startMusic(){ URL url; try { url = musicFile.toURL(); AudioClip aud; aud=Applet.newAudioClip(url); aud.play(); try { Thread.sleep(1000); } catch (InterruptedException e) { //TODO Auto-generated catch block e.printStackTrace(); } aud.stop(); } catch (MalformedURLException e) { //e.printStackTrace(); } } //获得和设置坐标 public void setX(int startX) { this.x=startX; } public void setY(int startY) { this.y=startY; } public int getX() { return x; } public int getY() { return y; } //发射子弹计数器和获得产生子弹的数量 public void addBulletCount(){ dijiBulletCount++; } public int getBulletCount(){ return dijiBulletCount; } //获得敌机子弹的高度和宽度 public int getDiJiHeight(){ return dijiImage.getHeight(null); } public int getDiJiWidth(){ return dijiImage.getWidth(null); } } MyFeiJiBullet.java:战机炮弹类 /** * 飞机子弹类 * @author 梦想少年 * 实现接口中的方法,检测是否攻击到敌方 */ public class MyFeiJiBullet implements Entity { //子弹类型 private int bulletType; //坐标 private int x,y; //子弹图片 Image image; //初始化图片 public MyFeiJiBullet(){ image=new ImageIcon("D:\\常用\\图片\\" + "Camera Roll\\image\\bullet2.png").getImage(); } //移动 public void move() { x+=7; } //画图 public void draw(Graphics g) { if(bulletType==1){ g.drawImage(image, x, y, 100, 100, null); } } //检测是否越界 public boolean isOutBounds(){ if(x>1920){ return true; }else{ return false; } } //设置子弹类型的方法 public void setBulletType(int bulletType){ this.bulletType=bulletType; } //设置和获得坐标的方法 public void setX(int startX) { this.x=startX; } public void setY(int startY) { this.y=startY; } public int getX() { return x; } public int getY() { return y; } //检测我的飞机是否被敌机子弹击中 public boolean isShootDiJiBullet(DiJiBullet dijibullet){ int x1=this.x;//我的子弹x坐标 int y1=this.y;//我的子弹y坐标 int width1=this.image.getWidth(null);//我的子弹宽度 int height1=this.image.getHeight(null);//我的子弹高度 int x11=x1+width1/2; int y11=y1+height1/2;//确定中心位置 //敌机的横纵坐标和高度 int x2=dijibullet.getX(); int y2=dijibullet.getY(); int width2=dijibullet.getDiJiBulletWidth(); int height2=dijibullet.getDiJiBulletHeight(); int x22=x2+width2/2; int y22=y2+height2/2; //计算距离 int distanceX=Math.abs(x22-x11); int distanceY=Math.abs(y22-y11); //是否碰撞 if(distanceX return false; } } //检测我的飞机是否被敌机碰撞 public boolean isShootDiJi(Diji diji){ int x1=this.x;//我的子弹x坐标 int y1=this.y;//我的子弹y坐标 int width1=this.image.getWidth(null);//我的子弹宽度 int height1=this.image.getHeight(null);//我的子弹高度 int x11=x1+width1/2; int y11=y1+height1/2;//确定中心位置 //敌机的横纵坐标和高度 int x2=diji.getX(); int y2=diji.getY(); int width2=diji.getDiJiWidth(); int height2=diji.getDiJiHeight(); int x22=x2+width2/2; int y22=y2+height2/2; //计算距离 int distanceX=Math.abs(x22-x11); int distanceY=Math.abs(y22-y11); //是否碰撞 if(distanceX return false; } } } DiJiBullet.java:敌机炮弹类 /** * 敌机子弹类 * @author 梦想少年 * 实现接口中的全部方法,同时要控制边界 */ public class DiJiBullet implements Entity { private int x,y; private Image image; //初始化 public DiJiBullet(){ image=new ImageIcon("D:\\常用\\图片\\" + "Camera Roll\\image\\1\\5.PNG").getImage(); } //移动的方法 public void move() { x-=3; } //画图的方法 public void draw(Graphics g) { g.drawImage(image, x, y, null); } //检测是否越界 public boolean isOutBounds(){ if(x return false; } } //设置和获得坐标的方法 public void setX(int startX) { this.x=startX; } public void setY(int startY) { this.y=startY; } public int getX() { return x; } public int getY() { return y; } //获得敌机子弹的高度和宽度 public int getDiJiBulletHeight(){ return image.getHeight(null); } public int getDiJiBulletWidth(){ return image.getWidth(null); } } BackGroundPhotosMusic.java:背景图片类 /** * 背景图片音乐类 * @author 梦想少年 * 实现接口中的方法,画出移动的图片、一些界面的设置 */ public class BackGroundPhotosMusic implements Entity{//添加背景 private int x,y; private Image image; //背景音乐(一定要wav格式的音乐才有效) private AudioClip audio; //播放关闭音乐字符串和状态 private boolean isMusic; private String musicString; //游戏状态 private boolean isGame; private String gameString; //初始化背景图片 public BackGroundPhotosMusic(){ image=new ImageIcon("D:\\常用\\图片\\" + "Camera Roll\\image\\bg11.jpg").getImage(); File musicFile=new File("C:\\Users\\梦想少年\\Music\\" + "AudioConvert\\薛之谦 - 天后 (Live).wav"); try { audio=Applet.newAudioClip(musicFile.toURI().toURL()); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //移动背景 public void move() { x--; } //画出背景 public void draw(Graphics g) { if((x+image.getWidth(null)} public void setY(int startY){} public int getX() { return 0; } public int getY() { return 0; } //播放音乐 public void startMusic(){ if(!isMusic){ audio.loop(); musicString="暂停音乐"; isMusic=true; }else{ audio.stop(); musicString="打开音乐"; isMusic=false; } } //游戏停止 public void StartGame(){ if(!isGame){ gameString="暂停游戏"; isGame=true; }else{ gameString="开始游戏"; isGame=false; } } //返回游戏状态 public boolean gameState(){ return isGame; } } MainUI.java:主界面类 /** * 主界面类 * @author 梦想少年 * 创建队列控制所有的对象的移动和画图,同时实现键盘监听器控制战机的移动和发射炮弹 * 其他功能(1.开始界面2.游戏界面3.背景音乐和爆炸音乐) */ public class MainUI implements KeyListener,MouseListener{ //创建主队列 ArrayList wholelist=new ArrayList(); public static void main(String[] args){ MainUI ui=new MainUI(); ui.showUI(); } //创建飞机对象 MyFeiJi myfeiji=new MyFeiJi(); //创建背景对象 BackGroundPhotosMusic background=new BackGroundPhotosMusic(); //主界面 public void showUI(){ JFrame jframe=new JFrame("雷霆战机"); jframe.setSize(1920, 1080); jframe.setLayout(new FlowLayout()); jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jframe.setLocationRelativeTo(null); jframe.addKeyListener(this); jframe.addMouseListener(this); jframe.setVisible(true); //将背景对象加入主队列 background.startMusic(); background.StartGame(); wholelist.add(background); //将玩家飞机加入队列,注意顺序,避免画图覆盖 myfeiji.setX(300); myfeiji.setY(500); myfeiji.setHP(100); wholelist.add(myfeiji); //开启清除线程 RemoveThread remove=new RemoveThread(wholelist); remove.start(); //定时产生敌机&&&及它的子弹 Timer timer=new Timer(); timer.schedule(new TimerTask() { public void run(){ //敌机 Diji diji1=new Diji(); wholelist.add(diji1); //敌机子弹 for(int i=0;i Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if(diji1.getBulletCount()==5){ break; } } } },1,1); //双缓冲改善画面 Graphics g=jframe.getGraphics(); BufferedImage bufferedimage=new BufferedImage(jframe.getWidth(), jframe.getHeight(), BufferedImage.TYPE_3BYTE_BGR); Graphics bufferG=bufferedimage.getGraphics(); //不断遍历主队列并不断调用主方法,画出所有图像 while(true){ for(int i=0;i whole.move(); }else if(myfeiji.getHP() System.exit(0); } } } //画出缓存图片 g.drawImage(bufferedimage,0,0,null); try { Thread.sleep(5); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void keyPressed(KeyEvent e){ //获得键盘事件 int code=e.getKeyCode(); if(code==KeyEvent.VK_F){ //子弹1 MyFeiJiBullet myfeijibullet1=new MyFeiJiBullet(); //设置坐标 myfeijibullet1.setX(myfeiji.getX()+100); myfeijibullet1.setY(myfeiji.getY()-10); //设置子弹类型 myfeijibullet1.setBulletType(1); //加入队列 wholelist.add(myfeijibullet1); //子弹2 MyFeiJiBullet myfeijibullet2=new MyFeiJiBullet(); //设置坐标 myfeijibullet2.setX(myfeiji.getX()+100); myfeijibullet2.setY(myfeiji.getY()+55); //设置子弹类型 myfeijibullet2.setBulletType(1); //加入队列 wholelist.add(myfeijibullet2); } //上下左右控制飞机移动 if(code==KeyEvent.VK_UP){ myfeiji.up=true; } if(code==KeyEvent.VK_DOWN){ myfeiji.down=true; } if(code==KeyEvent.VK_LEFT){ myfeiji.left=true; } if(code==KeyEvent.VK_RIGHT){ myfeiji.right=true; } } public void keyTyped(KeyEvent e){} public void keyReleased(KeyEvent e){ int code=e.getKeyCode(); if(code==KeyEvent.VK_UP){ myfeiji.up=false; } if(code==KeyEvent.VK_DOWN){ myfeiji.down=false; } if(code==KeyEvent.VK_LEFT){ myfeiji.left=false; } if(code==KeyEvent.VK_RIGHT){ myfeiji.right=false; } } //游戏菜单相关设置 public void mouseClicked(MouseEvent e){} public void mousePressed(MouseEvent e){ //获得点击的X和Y坐标 int x=e.getX(); int y=e.getY(); //音乐开停 if(x>=35&&x=200&&y background.StartGame(); }else if(x>=35&&x=260&&y} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} } RemoveThread.java:去除线程类 /** * 去除线程类 * @author 梦想少年 * 创建线程来实现对越界子弹敌机的去除,控制飞机的碰撞 */ public class RemoveThread extends Thread{ //各个对象的队列 ArrayList list; //攻击后我机的加分判断 private boolean isShootDiJiBullet; private boolean isShootDiJi; //初始化 public RemoveThread(ArrayList list) { this.list=list; } public void run(){ while(true){ //休息一下 try { Thread.sleep(2); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //清除所有的越界敌机、飞机子弹、敌机子弹 for(int i=0;i Diji diji=(Diji)entity; if(diji.isOutBounds()){ list.remove(diji); } //清除我机子弹 }else if(entity instanceof MyFeiJiBullet){ MyFeiJiBullet myfeijibullet=(MyFeiJiBullet)entity; if(myfeijibullet.isOutBounds()){ list.remove(myfeijibullet); } //清除敌机子弹 }else if(entity instanceof DiJiBullet){ DiJiBullet dijibullet=(DiJiBullet)entity; if(dijibullet.isOutBounds()){ list.remove(dijibullet); } } //------------------------------------------------------ } //清除和处理碰撞 for(int i=0;i Entity entity2=list.get(j); if(entity1 instanceof MyFeiJi){ MyFeiJi myfeiji=(MyFeiJi)entity1; //设置一个加分的开关 if(isShootDiJi){ myfeiji.addDoubleScores(); isShootDiJi=false; }else if(isShootDiJiBullet){ myfeiji.addScores(); isShootDiJiBullet=false; } //------------------------------- if(entity2 instanceof DiJiBullet){ DiJiBullet dijibullet=(DiJiBullet)entity2; if(myfeiji.isShootByDiJiBullet(dijibullet)){ list.remove(dijibullet);//清除敌机子弹 myfeiji.subBlood();//我机掉血 } }//以上是敌机子弹范围 else if(entity2 instanceof Diji){ Diji diji=(Diji)entity2; if(myfeiji.isShootByDiJi(diji)){ diji.Blast();//敌机爆炸 diji.startMusic();//播放爆炸音乐 list.remove(diji);//去除敌机 myfeiji.subDoubleBlood();//我机掉多倍的血量 } }//以上是敌机范围 }//我的飞机范围 else if(entity1 instanceof MyFeiJiBullet){ MyFeiJiBullet myfeijibullet=(MyFeiJiBullet)entity1; if(entity2 instanceof DiJiBullet){ DiJiBullet dijibullet=(DiJiBullet)entity2; if(myfeijibullet.isShootDiJiBullet(dijibullet)&& i Diji diji=(Diji)entity2; if(myfeijibullet.isShootDiJi(diji)&& i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有