Java基础飞机大战小游戏完整代码

Dear 丶 2023-02-20 06:55 89阅读 0赞

Java基础飞机大战小游戏完整代码

先来展示一下代码实现结果图
代码结果图1
代码结果图2

主函数ShootGame

初始化游戏原始背景图片,游戏人物图片,游戏开始结束图片;构建产生敌人算法;产生英雄机算法;发射子弹算法;判断是否相撞算法(子弹与敌机相撞,英雄机与敌机相撞);击落敌人奖励算法;绘制游戏中人物算法;鼠标控制移动算法;

  1. import java.awt.Font;
  2. import java.awt.Graphics;
  3. import java.awt.Image;
  4. import java.awt.event.MouseEvent;
  5. import java.awt.event.MouseListener;
  6. import java.awt.event.MouseMotionListener;
  7. import java.io.File;
  8. import java.io.IOException;
  9. import java.util.Arrays;
  10. import java.util.Random;
  11. import java.util.Timer;
  12. import java.util.TimerTask;
  13. import javax.imageio.ImageIO;
  14. import javax.swing.JFrame;
  15. import javax.swing.JPanel;
  16. public class ShootGame extends JPanel implements MouseMotionListener,MouseListener{
  17. //继承JPanel类
  18. public static final int width = 400;
  19. public static final int height = 600;
  20. //设置对象图片名称(与源文件名称一致)
  21. public static Image background;
  22. public static Image airplane;
  23. public static Image bee;
  24. public static Image bullet;
  25. public static Image gameover;
  26. public static Image hero0;
  27. public static Image hero1;
  28. public static Image pause;
  29. public static Image start;
  30. //定义游戏的四种状态
  31. public static final int START = 0; //开始状态
  32. public static final int RUNNING = 1; //运行状态
  33. public static final int PAUSE = 3; //暂停状态
  34. public static final int GAMEOVER =4; //结束状态
  35. int state =START;
  36. //创建对象-----------------------------------------------------------------------------------------------
  37. Hero hero = new Hero(); //创建英雄机对象
  38. Bullet[] bullets = {
  39. }; //子弹(众多),定义子弹数组
  40. FlyingObject[] flyings = {
  41. }; //小敌机(众多),定义小敌机数组
  42. //ShootGame无惨构造方法(给创建对象初始化)
  43. /*public ShootGame() {
  44. flyings = new FlyingObject[2];
  45. //多态 夫妇
  46. flyings[0] = new Airplane();//小敌机
  47. flyings[1] = new Bee();//小蜜蜂
  48. bullets = new Bullet[2];
  49. bullets[0] = new Bullet(130,250);
  50. bullets[1] = new Bullet(100,120);
  51. }*/
  52. //静态代码块内容加载
  53. static {
  54. try {
  55. //导入图片文件-----------------------------------------------------------------------------------
  56. //将图片文件赋给图片对象
  57. background = ImageIO.read(new File("image\\background.png"));
  58. airplane = ImageIO.read(new File("image\\airplane.png"));
  59. bee = ImageIO.read(new File("image\\bee.png"));
  60. bullet = ImageIO.read(new File("image\\bullet.png"));
  61. gameover = ImageIO.read(new File("image\\gameover.png"));
  62. hero0 = ImageIO.read(new File("image\\hero0.png"));
  63. hero1 = ImageIO.read(new File("image\\hero1.png"));
  64. pause = ImageIO.read(new File("image\\pause.png"));
  65. start = ImageIO.read(new File("image\\start.png"));
  66. } catch (IOException e) {
  67. // TODO Auto-generated catch block
  68. e.printStackTrace();
  69. }
  70. }
  71. //产生敌人方法-------------------------------------------------------------------------------------------
  72. public FlyingObject nextOne() {
  73. FlyingObject f; //小敌机类型
  74. Random r = new Random(); //随机产生数
  75. int random = r.nextInt(20); //产生[0,20)随机数
  76. if(random > 3) {
  77. f = new Airplane(); //随机数为[4,20) 产生小敌机
  78. }else {
  79. f = new Bee(); //随机数为[0,3] 产生小蜜蜂
  80. }
  81. return f; //返回小敌机
  82. }
  83. int flyingEnterIndex = 0; //敌人对象初始化为0
  84. //把产生的敌人添加到敌人数组中方法------------------------------------------------------------------------
  85. public void enterAction() {
  86. flyingEnterIndex++; //敌人对象自加
  87. if(flyingEnterIndex % 50 == 0) {
  88. //50 100...每隔50毫秒执行一次,用于控制敌人出现速度
  89. //1、创建敌人对象
  90. FlyingObject one = nextOne(); //创建敌人对象,赋值给 One
  91. //2.将敌人对象添加到flyings敌人数组中
  92. flyings = Arrays.copyOf(flyings, flyings.length+1); //扩容+1(增加小敌机)
  93. flyings[flyings.length-1] = one; //把产的敌人one赋值(添加)给最后一个数组元素
  94. }
  95. }
  96. //游戏中各个对象的移动方式--------------------------------------------------------------------------------
  97. public void stepAction() {
  98. //敌人的移动(敌人处于敌人数组中,调用数组)
  99. for(int i=0; i<flyings.length; i++) {
  100. //通过循环实现每个敌人移动
  101. flyings[i].step(); //调用step方法,实现敌人的移动
  102. }
  103. //子弹移动(子弹处于子弹数组中,调用子弹数组)
  104. for(int i=0; i<bullets.length; i++) {
  105. //通过循环实现每个子弹移动
  106. bullets[i].step(); //调用step方法,实现子弹的移动
  107. }
  108. //英雄机的移动
  109. hero.step(); //调用step方法,实现英雄机的移动
  110. }
  111. int shootIndex =0;
  112. //英雄机发射子弹方法-------------------------------------------------------------------------------------
  113. public void shootAction() {
  114. shootIndex++;
  115. if(shootIndex % 30 == 0) {
  116. //10*30=300毫秒
  117. Bullet[] bs = hero.shoot(); //用数组存放子弹
  118. //扩容(将bs存放至bullets子弹数组中)
  119. bullets = Arrays.copyOf(bullets, bullets.length+bs.length); //子弹数组+新生成对象
  120. //将子弹对象添加至子弹数组中
  121. System.arraycopy(bs,0,bullets,bullets.length-bs.length,bs.length);
  122. }
  123. }
  124. int score = 0;
  125. //子弹与敌人相撞-----------------------------------------------------------------------------------------
  126. public void hitAction() {
  127. //遍历所有子弹
  128. for(int i= 0; i<bullets.length; i++) {
  129. Bullet b = bullets[i]; //记录当前子弹
  130. //遍历所有敌人
  131. for(int j = 0; j<flyings.length; j++) {
  132. FlyingObject f = flyings[j]; //记录当前敌人
  133. //判断是否相撞
  134. if(f.hitBy(b)) {
  135. //敌人消失
  136. //1,当前敌人与最后一个数组元素交换
  137. FlyingObject temp = flyings[j];
  138. flyings[j] = flyings[flyings.length-1];
  139. flyings[flyings.length-1] = temp;
  140. //2.扩容-1(消灭敌人)
  141. flyings=Arrays.copyOf(flyings, flyings.length-1);
  142. //子弹消失
  143. //1.当前子弹与最后一个数组元素交换
  144. Bullet t =bullets[i];
  145. bullets[i] = bullets[bullets.length-1];
  146. bullets[bullets.length-1] = t;
  147. //2.扩容-1(子弹消失)
  148. bullets=Arrays.copyOf(bullets, bullets.length-1);
  149. //得到加分或奖励,需要区分是小敌机还是小蜜蜂
  150. if(f instanceof Airplane) {
  151. //是小敌机
  152. score += hero.getScore(); //加奖励分
  153. }
  154. if(f instanceof Bee) {
  155. //是小蜜蜂,根据奖励类型增加火力还是生命
  156. Bee bee = (Bee)f; //向下转型Bee
  157. int award = bee.getAwardType();
  158. switch(award) {
  159. case 0:
  160. hero.addDoubleFire(); //增加火力
  161. break;
  162. case 1:
  163. hero.addLife(); //增加生命值
  164. break;
  165. }
  166. }
  167. }
  168. }
  169. }
  170. }
  171. //英雄机与敌人相撞方法------------------------------------------------------------------------------------
  172. public void duangAction() {
  173. //遍历所有敌人
  174. for(int i = 0; i<flyings.length; i++) {
  175. if(hero.duang(flyings[i])) {
  176. //敌人消失
  177. FlyingObject temp = flyings[i];
  178. flyings[i] = flyings[flyings.length-1];
  179. flyings[flyings.length-1] = temp;
  180. flyings=Arrays.copyOf(flyings, flyings.length-1); //扩容,减掉敌人
  181. //英雄机减掉生命值,火力清零
  182. hero.life--;
  183. hero.doubleFire = 0;
  184. }
  185. }
  186. }
  187. //检测英雄机生命值方法------------------------------------------------------------------------------------
  188. public void checkGame() {
  189. if(hero.life <= 0) {
  190. state = GAMEOVER;
  191. }
  192. }
  193. //游戏中的各种行为方法-----------------------------------------------------------------------------------
  194. public void action() {
  195. //添加定时器(每隔多久出现一次)
  196. Timer timer = new Timer();//utill包下
  197. //安排指定任务从指定的延迟后开始进行重复的固定延迟执行
  198. timer.schedule(new TimerTask() {
  199. @Override
  200. public void run() {
  201. // TODO Auto-generated method stub
  202. if(state == RUNNING) {
  203. //处于运行状态执行操作
  204. enterAction(); //敌人入场
  205. stepAction(); //设置对象的移动方式
  206. shootAction(); //英雄机发射子弹
  207. hitAction(); //子弹与敌人相撞
  208. duangAction(); //英雄机与敌人撞
  209. checkGame(); //检测英雄机生命值
  210. }
  211. repaint(); //重新绘制(产生新的小敌机)
  212. }}, 10,10);
  213. }
  214. //绘制分数方法-------------------------------------------------------------------------------------------
  215. public void paintScore(Graphics g) {
  216. g.setFont(new Font("黑体",Font.BOLD,20)); //颜色,字体,字号
  217. g.drawString("SCORE:"+score, 30, 30); //绘制SCORE:分数(坐标位置)
  218. g.drawString("LIFE:"+hero.life,30,60); //绘制LIFE: 生命值(坐标位置)
  219. g.drawString("FIRE:"+hero.doubleFire, 30, 90); //FIRE:火力值(坐标位置)
  220. }
  221. //绘制状态图方法-----------------------------------------------------------------------------------------
  222. public void paintState(Graphics g) {
  223. switch(state) {
  224. case START:
  225. g.drawImage(start, 0, 0, null); //绘制start图片,坐标(0,0)
  226. break;
  227. case PAUSE:
  228. g.drawImage(pause, 0, 0, null); //绘制pause图片,坐标(0,0)
  229. break;
  230. case GAMEOVER:
  231. g.drawImage(gameover, 0, 0, null); //绘制gameover图片,坐标(0,0)
  232. break;
  233. }
  234. }
  235. //绘图方法-----------------------------------------------------------------------------------------------
  236. public void paint(Graphics g) {
  237. //Jpanel类下paint方法
  238. super.paint(g);
  239. g.drawImage(background,0,0,null); //通过背景图片进行绘画,从坐标(0,0)开始绘画
  240. //g.drawImage(airplane, 100, 100, null);绘制小敌机固定位置图像
  241. //通过方法调用实现动态实时绘图
  242. //绘制敌人
  243. paintFlying(g);
  244. //绘制子弹
  245. paintBullet(g);
  246. //绘制英雄机
  247. paintHero(g);
  248. //绘制分值
  249. paintScore(g);
  250. //绘制状态图
  251. paintState(g);
  252. }
  253. //绘制英雄机方法-----------------------------------------------------------------------------------------
  254. public void paintHero(Graphics g) {
  255. // TODO Auto-generated method stub
  256. g.drawImage(hero.image, hero.x, hero.y, null);
  257. }
  258. //绘制子弹方法-------------------------------------------------------------------------------------------
  259. public void paintBullet(Graphics g) {
  260. // TODO Auto-generated method stub
  261. for(int i = 0; i<bullets.length; i++) {
  262. g.drawImage(bullets[i].image, bullets[i].x, bullets[i].y, null);
  263. }
  264. }
  265. //绘制敌人方法-------------------------------------------------------------------------------------------
  266. public void paintFlying(Graphics g) {
  267. // TODO Auto-generated method stub
  268. for(int i = 0; i<flyings.length; i++) {
  269. g.drawImage(flyings[i].image, flyings[i].x, flyings[i].y, null);
  270. }
  271. }
  272. //主方法
  273. public static void main(String[] args) {
  274. //飞机大战窗体制作
  275. JFrame jf = new JFrame("飞机大战");
  276. jf.setSize(width, height); //设置窗体宽高
  277. jf.setLocationRelativeTo(null); //窗体居中
  278. jf.setVisible(true); //窗体可见
  279. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  280. //导入背景图片
  281. ShootGame game = new ShootGame(); //创建ShootGame对象
  282. jf.add(game); //在窗体中添加背景图片
  283. game.action(); //游戏中的各种操作
  284. jf.addMouseMotionListener(game); //添加监听器(对对象实时监控)
  285. jf.addMouseListener(game); //添加监听器(对鼠标实时监控)
  286. }
  287. @Override
  288. public void mouseDragged(MouseEvent e) {
  289. // TODO Auto-generated method stub
  290. }
  291. @Override
  292. public void mouseMoved(MouseEvent e) {
  293. //鼠标移动
  294. // TODO Auto-generated method stub
  295. if(state == RUNNING) {
  296. //在运行状态下执行操作
  297. hero.x =e.getX()-hero.width/2; //鼠标的具体坐标(x,y)
  298. hero.y =e.getY()-hero.height/2; //根据鼠标的位置确定英雄机的位置
  299. }
  300. }
  301. //鼠标单击启动
  302. @Override
  303. public void mouseClicked(MouseEvent e) {
  304. // TODO Auto-generated method stub
  305. if(state == START) {
  306. state = RUNNING; //开始运行
  307. }
  308. if(state == GAMEOVER) {
  309. state = START; //返回开始状态
  310. hero = new Hero();
  311. flyings = new FlyingObject[] {
  312. };
  313. bullets = new Bullet[] {
  314. };
  315. score = 0;
  316. }
  317. }
  318. @Override
  319. public void mousePressed(MouseEvent e) {
  320. // TODO Auto-generated method stub
  321. }
  322. @Override
  323. public void mouseReleased(MouseEvent e) {
  324. // TODO Auto-generated method stub
  325. }
  326. //鼠标进入
  327. @Override
  328. public void mouseEntered(MouseEvent e) {
  329. // TODO Auto-generated method stub
  330. if(state == PAUSE) {
  331. state = RUNNING; //修改为运行
  332. }
  333. }
  334. //鼠标退出
  335. @Override
  336. public void mouseExited(MouseEvent e) {
  337. // TODO Auto-generated method stub
  338. if(state == RUNNING) {
  339. state = PAUSE; //修改为暂停
  340. }
  341. }
  342. }

所有类的父类FlyingObject

概括所有对象的共性,统一调用

  1. import java.awt.Image;
  2. //父类(英雄机,小敌机,小蜜蜂,子弹)
  3. public abstract class FlyingObject {
  4. //抽象方法必须为抽象类
  5. int x,y; //定位
  6. int width,height; //对象宽度和高度
  7. Image image; //定义图像
  8. //让每一个子类移动的方法----------------------------------------------------------------------------------
  9. public abstract void step(); //由于每个子类的移动方法不一样,定为抽象方法
  10. //判断子弹是否与敌人相撞方法-------------------------------------------------------------------------------
  11. public boolean hitBy(Bullet bullet) {
  12. int x = bullet.x; //子弹x 坐标
  13. int y = bullet.y;
  14. return x>this.x && x<this.x+this.width
  15. &&
  16. y>this.y && y<this.y+height; //子弹与敌人相撞的临界状态
  17. }
  18. }

英雄机Hero类

主要包括英雄机出现位置,英雄机大小,生命值,火力值的设置算法;英雄机发射子弹算法;英雄机与敌机相撞判定算法;英雄机打到小蜜蜂的奖励算法。

  1. import java.awt.Image;
  2. //英雄机
  3. public class Hero extends FlyingObject{
  4. int life; //英雄机生命
  5. int doubleFire; //英雄机火力值0/1
  6. Image[] images = {
  7. }; //图片数组(两张图片切换动画)
  8. public Hero() {
  9. image = ShootGame.hero0; //使用第一张英雄机图片
  10. width = image.getWidth(null); //获得英雄机宽度
  11. height = image.getHeight(null); //获得英雄机宽度
  12. x = 150; //英雄机初始高度宽度
  13. y = 450;
  14. life = 3; //初始生命
  15. doubleFire = 0; //开始英雄机单倍火力
  16. images =new Image[] {
  17. ShootGame.hero0,ShootGame.hero1}; //两张图片
  18. }
  19. int index = 0;
  20. //实现抽象父类中对象移动的方法
  21. @Override
  22. public void step() {
  23. // TODO Auto-generated method stub
  24. image = images[index++/10%images.length];//图片数组切换,形成英雄机动画,最后赋值给image
  25. }
  26. //发射子弹的方法------------------------------------------------------------------------------------------
  27. public Bullet[] shoot() {
  28. Bullet[] bs = {
  29. }; //子弹数组,初值为空
  30. if(doubleFire ==0) {
  31. //单倍火力
  32. bs = new Bullet[1];
  33. bs[0] = new Bullet( x+width/2-4,y-14); //一颗子弹的坐标计算
  34. }else {
  35. //双倍火力
  36. bs =new Bullet[2];
  37. bs[0] = new Bullet(x+width/4-4,y-14); //英雄机的宽度1/4-子弹宽度的一半
  38. bs[1] = new Bullet(x+width*3/4-4,y-14);
  39. doubleFire -= 2;
  40. }
  41. return bs;
  42. }
  43. //获取得分------------------------------------------------------------------------------------------------
  44. public int getScore() {
  45. return 5;
  46. }
  47. //增加火力------------------------------------------------------------------------------------------------
  48. public void addDoubleFire() {
  49. doubleFire +=40;
  50. }
  51. //增加生命------------------------------------------------------------------------------------------------
  52. public void addLife() {
  53. life += 1;
  54. }
  55. //判断英雄机是否与敌人相撞方法-----------------------------------------------------------------------------
  56. public boolean duang(FlyingObject f) {
  57. int x = this.x;
  58. int y = this.y; //获得英雄机当前位置
  59. int x1 = f.x - this.width; //敌人x坐标-英雄机宽度
  60. int x2 = f.x + f.width; //敌人x坐标+敌人宽度
  61. int y1 = f.y - this.height; //敌人y坐标-英雄机高度
  62. int y2 = f.y + f.height; //敌人y坐标+敌人高度
  63. return x>x1 && x<x2
  64. &&y>y1 && y<y2; //临介条件
  65. }
  66. }

小敌机Airplane类

设置小敌机出现位置,移动限制

  1. //小敌机
  2. public class Airplane extends FlyingObject {
  3. int ySpeed; //向下速度
  4. public Airplane() {
  5. image = ShootGame.airplane; //小敌机图片
  6. width = image.getWidth(null); //小敌机宽度
  7. height = image.getHeight(null); //小敌机高度
  8. x = (int) (Math.random()*ShootGame.width); //小敌机出现x坐标,背景屏幕宽度
  9. y = -height; //小敌机的y坐标
  10. ySpeed = 1; //向下移动速度
  11. }
  12. //实现抽象父类中对象移动的方法-----------------------------------------------------------------------------
  13. @Override
  14. public void step() {
  15. // TODO Auto-generated method stub
  16. y += ySpeed; //一次递增一个速度
  17. }
  18. }

小蜜蜂Bee类

小蜜蜂奖励算法;小蜜蜂出现算法;

  1. //小蜜蜂
  2. public class Bee extends FlyingObject{
  3. int ySpeed;//向下速度
  4. int xSpeed;//左右速度
  5. int awardType;
  6. public Bee() {
  7. image = ShootGame.bee; //调用小蜜蜂图片
  8. width = image.getWidth(null); //获取图片宽度
  9. height = image.getHeight(null); //获取图片高度
  10. x = (int) (Math.random()*ShootGame.width); //小蜜蜂x坐标(随机进入)
  11. y = -height; //小蜜蜂高度,设为窗体下方,方便提前看到小蜜蜂
  12. xSpeed = 1; //小蜜蜂x轴方向速度
  13. ySpeed = 1; //小蜜蜂y轴方向速度
  14. awardType = (int) (Math.random()*2); //得分(随机性)
  15. }
  16. //实现抽象父类中对象移动的方法-----------------------------------------------------------------------------
  17. @Override
  18. public void step() {
  19. // TODO Auto-generated method stub
  20. y += ySpeed;
  21. x += xSpeed;
  22. if(x > ShootGame.width - width) {
  23. //大于屏幕宽度-x宽度小蜜蜂大于右边界
  24. xSpeed =-1;
  25. }
  26. if(x<=0) {
  27. xSpeed = 1; //小蜜蜂移动至左边界,向右移动
  28. }
  29. }
  30. //获取得分方法--------------------------------------------------------------------------------------------
  31. public int getAwardType() {
  32. return awardType;
  33. }
  34. }

子弹Bullet类

包括对发射子弹初始化,子弹移动的设置

  1. //子弹
  2. public class Bullet extends FlyingObject{
  3. int ySpeed; //子弹向下速度
  4. public Bullet(int x,int y) {
  5. image = ShootGame.bullet; //调用子弹图片
  6. width = image.getWidth(null); //获得子弹宽度
  7. height = image.getHeight(null); //获得子弹高度
  8. this.x = x; //子弹实时坐标(随英雄机变换)
  9. this.y = y;
  10. ySpeed = 3;
  11. }
  12. //实现抽象父类中对象移动的方法
  13. @Override
  14. public void step() {
  15. // TODO Auto-generated method stub
  16. y -= ySpeed;
  17. }
  18. }
  19. ## 游戏规则
  20. ```java
  21. 飞机大战游戏规则(游戏需求)
  22. 通过鼠标点击游戏Start界面开始游戏;鼠标控制英雄机移动;
  23. 父类FlyingObject(提取共同属性,制作父类)
  24. 属性
  25. x,y
  26. width,height
  27. img
  28. 小敌机Airplane
  29. 属性
  30. x,y(定位其位置)
  31. width,height(定义图片高度宽度)
  32. img(图片属性)
  33. ySpeed=1(只能上下移动,下移速度为1)
  34. 小蜜蜂Bee
  35. 属性
  36. x,y(定位其位置)
  37. width,height(定义图片高度宽度)
  38. img(图片属性)
  39. ySpeed=1(可以上下移动,下移速度为1)
  40. XSpeed(可以左右移动)
  41. awardType(被打到时奖励0/1分)0:奖励单倍火力
  42. 1:奖励双倍火力(随机性)
  43. 英雄机(随鼠标移动)
  44. 属性
  45. x,y(定位其位置)
  46. width,height(定义图片高度宽度)
  47. img(图片属性)
  48. life(生命值)
  49. doubleFire(火力值)0:发射一个子弹
  50. 1:发射两个子弹
  51. 行为
  52. 发射子弹,鼠标移动
  53. 子弹
  54. 属性
  55. x,y(定位其位置)
  56. width,height(定义图片高度宽度)
  57. img(图片属性)
  58. ySpeed(只能上移)

游戏基础人物构造图片

图片需要统一放在image文件夹中,方便调用。image文件放入创建的Java项目包下。
飞机大战开始字体界面
英雄机图片1
飞机大战背景图片
游戏结束界面
游戏暂停界面
小敌机图片
英雄机图片2
游戏背景图片
小蜜蜂图片
子弹图片

结束语

若想获得更多的编程干货,关注博主,持续更新福利。

发表评论

表情:
评论列表 (有 0 条评论,89人围观)

还没有评论,来说两句吧...

相关阅读

    相关 飞机大战Java完整

    这是一款闯关的射击游戏,人物在不同的关 卡里面会触发不同的技能与对应的特效操作,有三个关卡与四个随机事件,每个关卡里面都会触发不同数量的怪物与能量血瓶,通过打败怪物与 到达特点

    相关 java飞机游戏完整代码

    技术源于分享,所以今天抽空把自己之前用java做过的小游戏整理贴出来给大家参考学习。java确实不适合写桌面应用,这里只是通过这个游戏让大家理解oop面向对象编程的过程,纯属娱

    相关 飞机大战(微信游戏

    依旧是熟悉的期末作业,是微信小游戏官网的Demo来着,然后我边百度边对它做了一些改动 说起来好久没更新博客了......最近在用unity做游戏准备参加计算机设计大赛,花了好