Java飞机大战项目

短命女 2022-02-25 11:50 421阅读 0赞

飞机大战游戏是一款十分有趣的射击类小游戏,流畅的画面,高难度的挑战。游戏中,玩家驾驶英雄机,在空中进行战斗。点击并移动自己的英雄机,发射炮弹,打掉敌飞机以及蜜蜂,来获得分数和奖励,打掉一架敌飞机赢得5分,打掉一只蜜蜂赢得1条命或是获得20次双倍火力,如果撞上敌飞机或小蜜蜂,将减少命、双倍火力清零。每撞到一次蜜蜂或是敌飞机命减1,当命数为0时,则游戏结束。游戏界面如下图所示

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hvdWp1bmthbmczNjM_size_16_color_FFFFFF_t_70

下面就是教大家怎么用java来写出这个项目来。

数据建模:使用一个数据模型,描述对象的关系。使用绘图坐标系作为参考模型,英雄机、敌飞机、蜜蜂、子弹都是矩形区域。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hvdWp1bmthbmczNjM_size_16_color_FFFFFF_t_70 1

类的设计

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hvdWp1bmthbmczNjM_size_16_color_FFFFFF_t_70 2

完整代码:

Airplane类的完整代码如下所示:

  1. package com.itkzhan.shoot;
  2. import java.util.Random;
  3. /** 敌机*/
  4. public class Airplane extends FlyingObject implements Enemy{
  5. private int speed=2;//走步的步数
  6. public Airplane(){
  7. image=ShootGame.airplane;
  8. width=image.getWidth();
  9. height=image.getHeight();
  10. Random rand=new Random();
  11. x=rand.nextInt(ShootGame.WIDTH-this.width);
  12. y=-height;//y坐标
  13. }
  14. public int getScore() {
  15. return 5;
  16. }
  17. public void step() {
  18. y+=speed;
  19. }
  20. public boolean outBounds() {
  21. return this.y>ShootGame.HEIGHT;
  22. }
  23. }

Award类的完整代码如下所示:

  1. package com.itkzhan.shoot;
  2. /** 奖励*/
  3. public interface Award {
  4. int DOUBLE_FIRE=0;//双倍火力值
  5. int LIFE=1;//命
  6. int getType();//得奖励类型(0或1)
  7. }

Bee类的完整代码如下所示:

  1. package com.itkzhan.shoot;
  2. import java.util.Random;
  3. /** 蜜蜂*/
  4. public class Bee extends FlyingObject implements Award{
  5. private int xSpeed=1;//x坐标走步步数
  6. private int ySpeed=2;//y坐标走步步数
  7. private int awardType;//奖励类型
  8. /** Bee构造方法*/
  9. public Bee(){
  10. image=ShootGame.bee;//图片
  11. width=image.getWidth();//图片的宽
  12. height=image.getHeight();//图片的高
  13. Random rand=new Random();
  14. x=rand.nextInt(ShootGame.WIDTH-this.width);
  15. y=-this.height;
  16. awardType=rand.nextInt(2);
  17. }
  18. public int getType() {//奖励类型
  19. return awardType;
  20. }
  21. public void step() {
  22. x+=xSpeed;
  23. y+=ySpeed;
  24. if(this.x>=ShootGame.WIDTH-this.width){
  25. xSpeed=-1;
  26. }
  27. if(x<=0){
  28. xSpeed=1;
  29. }
  30. }
  31. public boolean outBounds() {
  32. return this.y>ShootGame.HEIGHT;
  33. }
  34. }

Bullet类的完整代码如下所示:

  1. package com.itkzhan.shoot;
  2. /** 子弹*/
  3. public class Bullet extends FlyingObject{
  4. private int speed=3;//走步的步数
  5. /** Bullet构造方法*/
  6. public Bullet(int x,int y){
  7. image=ShootGame.bullet;
  8. width=image.getWidth();
  9. height=image.getHeight();
  10. this.x=x;//x坐标
  11. this.y=y;//y坐标
  12. }
  13. public void step() {
  14. y-=speed;
  15. }
  16. public boolean outBounds() {
  17. return this.y<-height;
  18. }
  19. }

Enemy类的完整代码如下所示:

  1. package com.itkzhan.shoot;
  2. public interface Enemy {
  3. int getScore();
  4. }

FlyingObject类的完整代码如下所示:

  1. package com.itkzhan.shoot;
  2. import java.awt.image.BufferedImage;
  3. /**
  4. * 飞行物
  5. * @author HP
  6. *
  7. */
  8. public abstract class FlyingObject {
  9. protected int x;
  10. protected int y;
  11. protected int width;
  12. protected int height;
  13. protected BufferedImage image;
  14. public int getX() {
  15. return x;
  16. }
  17. public void setX(int x) {
  18. this.x = x;
  19. }
  20. public int getY() {
  21. return y;
  22. }
  23. public void setY(int y) {
  24. this.y = y;
  25. }
  26. public int getWidth() {
  27. return width;
  28. }
  29. public void setWidth(int width) {
  30. this.width = width;
  31. }
  32. public int getHeight() {
  33. return height;
  34. }
  35. public void setHeight(int height) {
  36. this.height = height;
  37. }
  38. public BufferedImage getImage() {
  39. return image;
  40. }
  41. public void setImage(BufferedImage image) {
  42. this.image = image;
  43. }
  44. public abstract void step();
  45. //敌人被子弹打
  46. public boolean shootBy(Bullet bullet){
  47. int x=bullet.x;//子弹的x
  48. int y=bullet.y;//子弹的y
  49. return x>this.x&&x<this.x+this.width
  50. &&
  51. y>this.y&&y<this.y+this.height;
  52. };
  53. public abstract boolean outBounds();
  54. }

Hero类的完整代码如下所示:

  1. package com.itkzhan.shoot;
  2. import java.awt.image.BufferedImage;
  3. /** 英雄机:是飞行物*/
  4. public class Hero extends FlyingObject{
  5. private int life;//命
  6. private int doubleFire;//火力值
  7. private BufferedImage[] images;//图片
  8. private int index;//图片切换的频率
  9. /** Hero构造方法*/
  10. public Hero(){
  11. image=ShootGame.hero0;//图片
  12. width=image.getWidth();//宽
  13. height=image.getHeight();//高
  14. x=150;//固定150
  15. y=400;//固定的400
  16. life=3;//命值为3
  17. doubleFire=0;//火力值为0,单倍火力
  18. images=new BufferedImage[]{ShootGame.hero0,ShootGame.hero1};
  19. index=0;
  20. }
  21. public void step() {
  22. index++;
  23. int a=index/10;//每100m b=0,1
  24. int b=a%2;
  25. image=images[b];
  26. image=images[b];
  27. }
  28. /** 发射子弹*/
  29. public Bullet[] shoot(){
  30. int xStep=this.width/4;//1/4英雄机的宽度
  31. int yStep=20;//子弹离飞机的距离
  32. if(doubleFire>0){//双倍火力
  33. Bullet[] bullets=new Bullet[2];
  34. bullets[0]=new Bullet(this.x+xStep,this.y-yStep);
  35. bullets[1]=new Bullet(this.x+3*xStep,this.y-yStep);
  36. doubleFire-=-2;
  37. return bullets;
  38. }else{//单倍火力
  39. Bullet[] bullets=new Bullet[1];
  40. bullets[0]=new Bullet(this.x+2*xStep,this.y-yStep);
  41. return bullets;
  42. }
  43. }
  44. /** 英雄机随着鼠标移动x:鼠标的x坐标 y鼠标的y坐标*/
  45. public void moveTo(int x,int y){
  46. this.x=x-this.width/2;
  47. this.y=y-this.height/2;
  48. }
  49. /**获取命*/
  50. public int getLife(){
  51. return life;
  52. }
  53. /** 减命*/
  54. public void subtractLife(){
  55. life--;
  56. }
  57. public void addLife(){
  58. life++;
  59. }
  60. /** 增火力值*/
  61. public void addDoubleFire(){
  62. doubleFire+=40;
  63. }
  64. /** 设置火力值*/
  65. public void setDoubleFire(int doubleFire){
  66. this.doubleFire=doubleFire;
  67. }
  68. @Override
  69. public boolean outBounds() {
  70. return false;//永不越界
  71. }
  72. public boolean hit(FlyingObject other){
  73. int x1=other.x-this.width/2;
  74. int x2=other.x+other.width+this.width/2;
  75. int y1=other.y-this.height/2;
  76. int y2=other.y+other.height/2;
  77. int hx=this.x+this.width/2;//
  78. int hy=this.y+this.height/2;
  79. return hx>x1 && hx<x2
  80. &&
  81. hy>y1 && hy<y2;
  82. }
  83. }

ShootGame类的完整代码如下所示:

  1. package com.itkzhan.shoot;
  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import java.awt.Graphics;
  5. import java.awt.event.MouseAdapter;
  6. import java.awt.event.MouseEvent;
  7. import java.awt.image.BufferedImage;
  8. import java.util.Arrays;
  9. import java.util.Random;
  10. import java.util.Timer;
  11. import java.util.TimerTask;
  12. import javax.imageio.ImageIO;
  13. import javax.swing.JFrame;
  14. import javax.swing.JPanel;
  15. public class ShootGame extends JPanel{//面板
  16. public static final int WIDTH=400;
  17. public static final int HEIGHT=654;
  18. public static BufferedImage background;
  19. public static BufferedImage start;
  20. public static BufferedImage airplane;
  21. public static BufferedImage bee;
  22. public static BufferedImage bullet;
  23. public static BufferedImage hero0;
  24. public static BufferedImage hero1;
  25. public static BufferedImage pause;
  26. public static BufferedImage gameover;
  27. public Hero hero=new Hero();//英雄机对象
  28. private FlyingObject[] flyings={};//敌人数组(敌机+蜜蜂)
  29. private Bullet[] bullets={};//子弹数组
  30. public static final int START=0;//启动状态
  31. public static final int RUNNING=1;//运行
  32. public static final int PAUSE=2;//暂停
  33. public static final int GAME_OVER=3;//结束
  34. private int state=0; //存储当前状态
  35. static { // 静态代码块,初始化图片资源
  36. try {
  37. background = ImageIO.read(ShootGame.class
  38. .getResource("background.png"));
  39. start = ImageIO.read(ShootGame.class.getResource("start.png"));
  40. airplane = ImageIO
  41. .read(ShootGame.class.getResource("airplane.png"));
  42. bee = ImageIO.read(ShootGame.class.getResource("bee.png"));
  43. bullet = ImageIO.read(ShootGame.class.getResource("bullet.png"));
  44. hero0 = ImageIO.read(ShootGame.class.getResource("hero0.png"));
  45. hero1 = ImageIO.read(ShootGame.class.getResource("hero1.png"));
  46. pause = ImageIO.read(ShootGame.class.getResource("pause.png"));
  47. gameover = ImageIO
  48. .read(ShootGame.class.getResource("gameover.png"));
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. /** 随机生成敌人对象(敌机、小蜜蜂)*/
  54. public static FlyingObject nextOne(){
  55. Random rand=new Random();
  56. int type=rand.nextInt(20);//生成[0,20)随机数
  57. if(type==0){
  58. return new Bee();//若为0则返回蜜蜂对象
  59. }else{
  60. return new Airplane();//1到19则返回敌机对象
  61. }
  62. }
  63. private Timer timer;//声明定时器对象
  64. private int intervel=10;//定时器的时间间隔(以毫秒为单位)
  65. int flyEnteredIndex=0;//敌人入场计数
  66. /** 敌人入场(敌机、小蜜蜂)*/
  67. public void enterAction(){//10毫秒走一次
  68. flyEnteredIndex++;
  69. if(flyEnteredIndex%40==0){//每400毫秒走一次
  70. FlyingObject o=nextOne();
  71. flyings=Arrays.copyOf(flyings, flyings.length+1);//扩容
  72. flyings[flyings.length-1]=o;//将对象加入到数组中
  73. }
  74. }
  75. /** 飞行物走一步*/
  76. public void stepAction(){
  77. hero.step();
  78. for(FlyingObject f:flyings){
  79. f.step();
  80. }
  81. for(Bullet b:bullets){
  82. b.step();
  83. }
  84. }
  85. int shootIndex=0;//子弹发射计数
  86. /** 英雄机发射子弹--子弹入场*/
  87. public void shootAction(){
  88. shootIndex++;
  89. if(shootIndex%30==0){
  90. Bullet[] bs=hero.shoot();
  91. bullets=Arrays.copyOf(bullets, bullets.length+bs.length);
  92. System.arraycopy(bs,0,bullets, bullets.length-bs.length,bs.length);
  93. }
  94. }
  95. int score=0;
  96. /**所有子弹与所有敌人的碰撞 */
  97. public void bangAction(){
  98. for(Bullet b:bullets){
  99. bang(b);//
  100. }
  101. }
  102. /** 一发子弹和所有敌人的碰撞*/
  103. public void bang(Bullet bullet){
  104. int index=-1;
  105. for(int i=0;i<flyings.length;i++){
  106. FlyingObject obj=flyings[i];
  107. if(obj.shootBy(bullet)){
  108. index=i;
  109. break;
  110. }
  111. }
  112. if(index!=-1){//被撞上了
  113. FlyingObject one=flyings[index];
  114. if(one instanceof Enemy){//敌机
  115. Enemy e=(Enemy)one;
  116. score+=e.getScore();
  117. }
  118. if(one instanceof Award){//奖励
  119. Award a=(Award)one;
  120. int type=a.getType();
  121. switch (type) {
  122. case Award.DOUBLE_FIRE:
  123. hero.addDoubleFire();
  124. break;
  125. case Award.LIFE:
  126. hero.addLife();
  127. break;
  128. }
  129. }
  130. FlyingObject t=flyings[index];
  131. flyings[index]=flyings[flyings.length-1];
  132. flyings[flyings.length-1]=t;
  133. flyings=Arrays.copyOf(flyings, flyings.length-1);//缩容
  134. }
  135. }
  136. public void outOfBoundsAction(){
  137. //越界飞行物
  138. FlyingObject[] flyingLives=new FlyingObject[flyings.length];//活着的
  139. int index=0;
  140. for(int i=0;i<flyings.length;i++){
  141. FlyingObject obj=flyings[i];
  142. if(!obj.outBounds()){//不越界
  143. flyingLives[index]=obj;//存储在flyingLives
  144. index++;
  145. }
  146. }
  147. flyings=Arrays.copyOf(flyingLives, index);
  148. index=0;
  149. Bullet[] bulletLives=new Bullet[bullets.length];
  150. for(int i=0;i<bullets.length;i++){
  151. Bullet b=bullets[i];
  152. if(!b.outBounds()){
  153. bulletLives[index]=b;
  154. index++;
  155. }
  156. }
  157. bullets=Arrays.copyOf(bulletLives, index);
  158. }
  159. /** 检查游戏结束*/
  160. public void checkGameOverAction(){
  161. if(isGameOver()){//若游戏结束
  162. state=GAME_OVER;
  163. }
  164. }
  165. /** 判断游戏是否结束*/
  166. public boolean isGameOver(){
  167. for(int i=0;i<flyings.length;i++){
  168. int index=-1;
  169. FlyingObject f=flyings[i];
  170. if(hero.hit(f)){
  171. hero.subtractLife();
  172. hero.setDoubleFire(0);
  173. index=i;
  174. }
  175. if(index!=-1){
  176. //将被撞的敌人删除
  177. FlyingObject t=flyings[index];
  178. flyings[index]=flyings[flyings.length-1];
  179. flyings[flyings.length-1]=t;
  180. flyings=Arrays.copyOf(flyings, flyings.length-1);
  181. }
  182. }
  183. return hero.getLife()<=0;
  184. }
  185. /** 主程序流程控制*/
  186. public void action(){
  187. //鼠标操作事件
  188. MouseAdapter l=new MouseAdapter() {
  189. /** 鼠标移动事件*/
  190. public void mouseMoved(MouseEvent e) {
  191. if(state==RUNNING){
  192. int x=e.getX();//获取鼠标的x坐标
  193. int y=e.getY();//获取鼠标的y坐标
  194. hero.moveTo(x, y);//英雄机随鼠标移动
  195. }
  196. }
  197. public void mouseClicked(MouseEvent e) {//鼠标点击事件
  198. switch (state) {//判断当前状态
  199. case START:
  200. state=RUNNING;
  201. break;
  202. case GAME_OVER:
  203. flyings = new FlyingObject[0]; // 清空飞行物
  204. bullets = new Bullet[0]; // 清空子弹
  205. hero = new Hero(); // 重新创建英雄机
  206. score = 0; // 清空成绩
  207. state = START; // 状态设置为启动
  208. }
  209. }
  210. public void mouseExited(MouseEvent e) {//鼠标移开事件
  211. if(state==RUNNING){
  212. state=PAUSE;
  213. }
  214. }
  215. public void mouseEntered(MouseEvent e) {//移入事件
  216. if(state==PAUSE){
  217. state=RUNNING;
  218. }
  219. }
  220. };
  221. this.addMouseListener(l);//处理鼠标一般操作
  222. this.addMouseMotionListener(l);//处理鼠标滑动
  223. timer=new Timer();//创建定时器对象
  224. timer.schedule(new TimerTask(){
  225. public void run() {
  226. if(state==RUNNING){
  227. enterAction();//敌人入场
  228. stepAction();//飞行物走一步
  229. shootAction();//英雄机发子弹
  230. bangAction();//子弹和敌人的碰撞
  231. outOfBoundsAction();//删除出界对象
  232. checkGameOverAction();//检查游戏结束
  233. }
  234. repaint();
  235. }}, intervel,intervel);//第一个intervel:程序启动到第一次干事的间隔
  236. //第二个intervel:每次干事的间隔
  237. }
  238. //g:画笔
  239. public void paint(Graphics g) {
  240. g.drawImage(background,0,0,null);//第四个参数不需要管,跟程序无关
  241. paintHero(g);
  242. paintFlyingObjects(g);
  243. paintBullets(g);
  244. paintScore(g);
  245. paintState(g);//画状态
  246. }
  247. //画子弹
  248. private void paintBullets(Graphics g) {
  249. for(Bullet b:bullets){
  250. g.drawImage(b.image,b.x,b.y,null);
  251. }
  252. }
  253. //画敌人
  254. private void paintFlyingObjects(Graphics g) {
  255. for(FlyingObject f:flyings){
  256. g.drawImage(f.image,f.x,f.y,null);
  257. }
  258. }
  259. //画英雄机
  260. private void paintHero(Graphics g) {
  261. g.drawImage(hero.image,hero.x,hero.y,null);
  262. }
  263. //画分和画命
  264. private void paintScore(Graphics g){
  265. g.setColor(new Color(0xFF0000));//设置颜色--红色
  266. g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,20));//字体,加粗,字号
  267. g.drawString("SCORE: "+score, 10, 25);
  268. g.drawString("LIFE: "+hero.getLife(), 10, 45);
  269. }
  270. //画状态
  271. public void paintState(Graphics g){
  272. switch (state) {//判断状态
  273. case START:
  274. g.drawImage(start,0,0,null);
  275. break;
  276. case PAUSE:
  277. g.drawImage(pause,0,0,null);
  278. break;
  279. case GAME_OVER:
  280. g.drawImage(gameover,0,0,null);
  281. break;
  282. }
  283. }
  284. public static void main(String[] args) {
  285. JFrame frame=new JFrame("Fly");
  286. ShootGame game=new ShootGame();
  287. frame.add(game);//将面板添加到窗口中
  288. frame.setSize(WIDTH,HEIGHT);
  289. frame.setAlwaysOnTop(true);//总是居顶
  290. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置默认关闭操作
  291. frame.setLocationRelativeTo(null);//设置位置相对与,默认相对位置就是中间点
  292. frame.setVisible(true);//1.设置窗口可见 2.尽快调用paint()方法
  293. game.action();//启动执行
  294. }
  295. }

关注公众号,回复”飞机大战”即可获取视频及图片

" class="reference-link">watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hvdWp1bmthbmczNjM_size_16_color_FFFFFF_t_70 3

发表评论

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

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

相关阅读

    相关 Java飞机大战项目

    飞机大战游戏是一款十分有趣的射击类小游戏,流畅的画面,高难度的挑战。游戏中,玩家驾驶英雄机,在空中进行战斗。点击并移动自己的英雄机,发射炮弹,打掉敌飞机以及蜜蜂,来获得分数和奖