Java版本飞机大战
1.关于这个飞机大战
学Java有一段时间了,然后通过Java开发了一些简易安卓APP。最近很想实现以前自己很想写的飞机大战,也练练手。代码和界面参考(抄袭 )了许多,毕竟天下码农一家亲。
游戏大概长下面这样,鼠标点击即开始游戏,然后用鼠标操作飞机移动(鼠标到哪飞机移动到哪,超出游戏界面就暂停)。
2.代码实现
- 首先写几个bean。GameStateBean里面存放了一些游戏状态的常量,ImgBean里面存放了游戏所用到的图片资源,这些图片和代码放在同一个包下。
package xyz.xinghai.game.bean;public class GameStateBean {//游戏启动public static final int START = 0;//游戏运行public static final int RUNNING = 1;//游戏暂停public static final int PAUSE = 2;//游戏结束public static final int GAMEOVER = 3;
}
package xyz.xinghai.game.bean;import java.awt.image.BufferedImage;
import java.io.IOException;import javax.imageio.ImageIO;public class ImgBean {public static BufferedImage backgroundImg;//游戏启动图public static BufferedImage startImg;//游戏暂停图public static BufferedImage pauseImg;//游戏结束图public static BufferedImage gameOverImg;//敌机图public static BufferedImage enemyImg;public static BufferedImage beeImg;//子弹图public static BufferedImage bulletImg;public static BufferedImage hero0Img;public static BufferedImage hero1Img;public static BufferedImage bigBeeImg;static {try {backgroundImg = ImageIO.read(ImgBean.class.getResource("background.png"));startImg = ImageIO.read(ImgBean.class.getResource("start.png"));pauseImg = ImageIO.read(ImgBean.class.getResource("pause.png"));gameOverImg = ImageIO.read(ImgBean.class.getResource("gameover.png"));enemyImg = ImageIO.read(ImgBean.class.getResource("airplane.png"));beeImg = ImageIO.read(ImgBean.class.getResource("bee.png"));bulletImg = ImageIO.read(ImgBean.class.getResource("bullet.png"));hero0Img = ImageIO.read(ImgBean.class.getResource("hero0.png"));hero1Img = ImageIO.read(ImgBean.class.getResource("hero1.png"));bigBeeImg = ImageIO.read(ImgBean.class.getResource("bigBee.png"));} catch (IOException e) {e.printStackTrace();}}
}
- 游戏中的飞行物体都有显示图片、高度、宽度、在游戏界面中的坐标(x、y)属性和移动(move)、是否飞出游戏界面(outOfBounds)方法。基于这些共同点编写飞行物体的抽象类FlyingObject,所有飞行的物体都继承这个类。
package xyz.xinghai.game;import java.awt.image.BufferedImage;/*** 飞行物体的抽象类*/
public abstract class FlyingObject {//飞行物的图片protected BufferedImage image; //飞行物的宽度protected int width;//飞行物的高度protected int height;//飞行物的x坐标protected int x;//飞行物的y坐标protected int y;//飞行物的移动public abstract void move();//是否飞出游戏界面public abstract boolean outOfBounds();//判断是否被击中 这个不是所有飞行物都有 所以不是抽象方法public boolean shootBy(Bullet bullet) {int x = bullet.x;int y = bullet.y;return (x > this.x && x < (this.x + this.width)) && (y > this.y && y < (this.y + this.height));}
}
- 编写游戏中的子弹类和主飞机类。继承自FlyingObject,获得了它的Object属性然后重新abstract方法。因为子弹由主飞机从下面打到上面的,所有子弹移动的时候就是y的坐标根据速度减,判断是否超出了游戏界面也就是直接判断它的y坐标是否小于它的-height。编写主飞机类时,加了doubleFire(值越大飞机打子弹越多)、life(飞机生命)等属性。因为使用鼠标控制主飞机,所以它在移动的时候只是改变了了显示图片,鼠标移到哪里直接调用moveTo方法移动到鼠标的位置即可。
package xyz.xinghai.game;import xyz.xinghai.game.bean.ImgBean;/*** 子弹类**/
public class Bullet extends FlyingObject {//子弹速度private int speed = 3;/*** @param x 游戏界面上的x坐标* @param y 游戏界面上的y坐标*/public Bullet(int x, int y) {this.image = ImgBean.bulletImg;this.width = this.image.getWidth();this.height = this.image.getHeight();this.x = x;this.y = y;}@Overridepublic void move() {this.y -= speed;}@Overridepublic boolean outOfBounds() {return this.y <= -this.height;}
}
package xyz.xinghai.game;import java.awt.image.BufferedImage;import xyz.xinghai.game.bean.ImgBean;public class Hero extends FlyingObject {private int life;private int doubleFire;private BufferedImage[] images;private int index;public Hero() {this.image = ImgBean.hero0Img;this.width = this.image.getWidth();this.height = this.image.getHeight();x = 150;y = 400;life = 3;doubleFire = 0;images = new BufferedImage[]{ImgBean.hero0Img,ImgBean.hero1Img};index = 0;}@Overridepublic void move() {image = images[index++/10%images.length];}@Overridepublic boolean outOfBounds() {return false;}/*** 根据doubleFire的值打不同数目的子弹* @return 子弹数组*/public Bullet[] shoot() {int xSpeed = this.width / 4;int ySpeed = 20;if (doubleFire >= 100) {//三粒子弹 子弹的初始位置不同Bullet[] bs=new Bullet[3];bs[0] = new Bullet(this.x + 1 * xSpeed, this.y - ySpeed);bs[1] = new Bullet(this.x + 2 * xSpeed, this.y - ySpeed);bs[2] = new Bullet(this.x + 3 * xSpeed, this.y - ySpeed);doubleFire -= 2;return bs;} else if (doubleFire < 100 && doubleFire > 0) {Bullet[] bs=new Bullet[2];//两粒子弹bs[0]=new Bullet(this.x + 1* xSpeed, this.y - ySpeed);bs[1]=new Bullet(this.x + 3* xSpeed, this.y - ySpeed);doubleFire -= 2;return bs;} else{//一粒子弹Bullet[] bs = new Bullet[1];bs[0] = new Bullet(this.x + 2 * xSpeed, this.y - ySpeed);return bs;}}/*** 飞机移到指定坐标去* @param x x坐标* @param y y坐标*/public void moveTo(int x, int y) {this.x=x-this.width/2;this.y=y-this.height/2; }public void addLife(){life+=2;}public int getLife(){return life;}/*** 加火力*/public void addDoubleFire(){doubleFire += 20;}public int getDoubleFire(){return doubleFire;}/*** 生命减少*/public void subtractLife(){life--;}/*** 回到最初的发子弹速度*/public void clealDoubleFire(){doubleFire = 0;}/*** 是否发生碰撞* @param other 其他继承自FlyingObject的飞行物* @return*/public boolean hit(FlyingObject other) {int x1 = other.x - this.width/2;int x2 = other.x + this.width/2 + other.width;int y1 = other.y - this.height/2;int y2 = other.y + this.height/2 + other.height;int x = this.x + this.width/2;int y = this.y + this.height;return (x>x1&&x<x2) && (y>y1&&y<y2);}
}
- 编写敌人(打败敌机获得分数)和游戏中奖励(打败带有奖励的敌人获得奖励)的接口。
package xyz.xinghai.game;/*** 敌人接口**/
public interface Enemy {public int getScore();
}
package xyz.xinghai.game;/**1. 奖励接口2. */
public interface Award {int DOUBLE_FIRE = 0;int LIFE = 1;//生命public int getType();
}
- 编写敌机类、游戏中击败有奖励敌机(击败后子弹打得更多)和游戏中较强的敌机(击败后得分更多)。敌机添加了速度和击败得分属性,由于敌机是从游戏界面上面移动到下面的,所以在移动的时候y坐标要随着速度增大。
package xyz.xinghai.game;import java.util.Random;import xyz.xinghai.game.bean.ImgBean;/*** 敌机类**/
public class EnemyPlane extends FlyingObject implements Enemy {//速度private int speed = 2;//得分private int score = 5;public EnemyPlane() {this.image = ImgBean.enemyImg;this.width = this.image.getWidth();this.height = this.image.getHeight();//随机初始化敌机位置Random random = new Random();x = random.nextInt(AircraftBattle.WIDTH - this.width);y = -this.height;}public int getScore() {return score;}@Overridepublic void move() {y += speed;}@Overridepublic boolean outOfBounds() {return this.y >= AircraftBattle.HEIGHT;}public void setScore(int score) {this.score = score;}
}
package xyz.xinghai.game;import java.util.Random;import xyz.xinghai.game.bean.ImgBean;/*** 打败后奖励积分更多**/
public class BigBee extends FlyingObject implements Enemy {private int speed = 1;public BigBee() {this.image = ImgBean.bigBeeImg;this.width = this.image.getWidth();this.height = this.image.getHeight();Random random = new Random();x = random.nextInt(AircraftBattle.WIDTH - this.width);y = -this.height;}@Overridepublic void move() {y += speed;}@Overridepublic boolean outOfBounds() {return this.y >= AircraftBattle.HEIGHT;}@Overridepublic int getScore() {return 40;}
}
package xyz.xinghai.game;import java.util.Random;import xyz.xinghai.game.bean.ImgBean;/**1. 打败后获得子弹加成2. @author 153213. */
public class Bee extends FlyingObject implements Award {private int xSpeed = 1;private int ySpeed = 2;private int awardType;public int getType() {return awardType;}public Bee() {this.image = ImgBean.beeImg;this.width = this.image.getWidth();this.height = this.image.getHeight();Random rand=new Random();this.x = rand.nextInt(AircraftBattle.WIDTH-this.width);this.y = -this.height;awardType=rand.nextInt(2);}@Overridepublic void move() {y += ySpeed;x += xSpeed;if(x >= AircraftBattle.WIDTH-this.width){xSpeed =-1;}if(x <= 0){xSpeed =1;}}@Overridepublic boolean outOfBounds() {return this.height >= AircraftBattle.HEIGHT;}
}
- 编写游戏主窗口。主窗口和背景图片一样大,继承自JPanel主要是想重写paint方法。由于其他类已经写好,剩下的就是在游戏窗口中的逻辑处理了。用数组存储显示在界面上的各种物体,然后开启一个定时器每10ms扫描一次界面上的元素,当有事件发生时就调用对应方法。
package xyz.xinghai.game;import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;import javax.swing.JFrame;
import javax.swing.JPanel;import xyz.xinghai.game.bean.GameStateBean;
import xyz.xinghai.game.bean.ImgBean;/**1. 主程序类2. @author 153213. */
public class AircraftBattle extends JPanel {private static final long serialVersionUID = 1L;//游戏界面宽度public static final int WIDTH = 400;//游戏界面高度public static final int HEIGHT = 645;private int state = GameStateBean.START;//主飞机private Hero hero = new Hero();//敌机数组private FlyingObject[] flyings = {};//子弹数组private Bullet[] bullets = {};//得分private int score = 0;@Overridepublic void paint(Graphics g) {g.drawImage(ImgBean.backgroundImg, 0, 0, null);paintHero(g);paintFlyingObjects(g);paintBullets(g);paintScoreAndLife(g);patintState(g);}/*** 画得分和生命* @param g 画笔*/private void paintScoreAndLife(Graphics g) {g.setColor(new Color(0xFF0000));g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,30));g.drawString("SCORE:" + score, 10, 25);g.drawString("LIFE:"+ hero.getLife(), 10, 50);g.drawString("DoubleFire:" + hero.getDoubleFire(), 10, 75);}/*** 画主飞机* @param g 画笔*/private void paintHero(Graphics g) {g.drawImage(hero.image, hero.x, hero.y, null);}/*** 画屏幕中的敌机等飞行物体* @param g 画笔*/private void paintFlyingObjects(Graphics g){for(FlyingObject f : flyings)g.drawImage(f.image, f.x, f.y, null);}/*** 画子弹* @param g 画笔*/private void paintBullets(Graphics g){for(Bullet b : bullets)g.drawImage(b.image, b.x, b.y, null);}/*** 绘制游戏状态 * @param g 画笔*/private void patintState(Graphics g) {switch(state){case GameStateBean.START:g.drawImage(ImgBean.startImg, 0, 0, null);break;case GameStateBean.PAUSE:g.drawImage(ImgBean.pauseImg, 0, 0, null);break;case GameStateBean.GAMEOVER:g.drawImage(ImgBean.gameOverImg, 0, 0, null);}}/*** 生成敌机* @return 敌机*/private FlyingObject nextOne() {Random rand = new Random();int type = rand.nextInt(20);if(type < 4) {return new BigBee();} else if (type == 5) {return new Bee();} else {return new EnemyPlane();}}//敌机入场的indexint flyEnteredIndex = 0;/*** 敌机入场的action*/private void enterAction() {flyEnteredIndex++;if(flyEnteredIndex % 40 ==0){FlyingObject obj = nextOne();//更新敌机数组 flyings = Arrays.copyOf(flyings, flyings.length+1);flyings[flyings.length-1] = obj;}}//子弹入场的indexint shootIndex = 0;/*** 主飞机发射子弹的Action 主飞机返回子弹数组 把返回的数组加到游戏子弹数组即可*/private void shootAction(){shootIndex++;if (shootIndex % 30 == 0) {Bullet[] bs = hero.shoot();//更新子弹数组bullets = Arrays.copyOf(bullets, bullets.length+bs.length);System.arraycopy(bs, 0, bullets, bullets.length-bs.length, bs.length);} }/***飞行物移动的action 调用各自的移动方法即可*/private void moveAction(){hero.move();for(FlyingObject f : flyings) f.move();for(Bullet b : bullets)b.move();}/*** 飞行物飞出界面的action 就是把飞出界面的飞行物从数组中去掉*/private void outOfBoundsAction() {int index = 0;FlyingObject[] flyingLives = new FlyingObject[flyings.length];for(FlyingObject f : flyings) if(!f.outOfBounds()) flyingLives[index++] = f;flyings=Arrays.copyOf(flyingLives, index);index = 0;Bullet[] bulletLives = new Bullet[bullets.length];for(Bullet b : bullets) if(!b.outOfBounds()) bulletLives[index++] = b;bullets=Arrays.copyOf(bulletLives, index);}int j = 0;/*** 碰撞的action*/private void collisionAction() {for(int i=0;i < bullets.length;i++){collision(bullets[i],i);}}/*** 碰撞* @param b 子弹* @param bu 碰撞的子弹在子弹数组中的index*/private void collision(Bullet b, int bu) {int index = -1;for(int i=0;i<flyings.length;i++){FlyingObject f = flyings[i];if (f.shootBy(b)) {index = i;break;} }if(index != -1) {FlyingObject one = flyings[index];if(one instanceof EnemyPlane){Enemy e = (Enemy)one;score += e.getScore();FlyingObject t = flyings[index];flyings[index] = flyings[flyings.length-1];flyings[flyings.length-1] = t;flyings=Arrays.copyOf(flyings, flyings.length-1);//去掉被子弹撞上的敌人}if(one instanceof BigBee){//打五下才会挂j++; if(j==5){Enemy e = (Enemy)one;score += e.getScore();j = 0;FlyingObject t = flyings[index];flyings[index] = flyings[flyings.length-1];flyings[flyings.length-1] = t;flyings = Arrays.copyOf(flyings, flyings.length-1);//去掉被子弹撞上的敌人}}if(one instanceof Award){Award a = (Award)one;int type = a.getType();switch(type){case Award.DOUBLE_FIRE://奖励为火力值hero.addDoubleFire();break;case Award.LIFE://奖励为生命hero.addLife();break;}FlyingObject t = flyings[index];flyings[index] = flyings[flyings.length-1];flyings[flyings.length-1] = t;flyings = Arrays.copyOf(flyings, flyings.length-1);//去掉被子弹撞上的敌人}Bullet tBullet = bullets[bu];bullets[bu] = bullets[bullets.length-1];bullets[bullets.length-1] = tBullet;bullets=Arrays.copyOf(bullets, bullets.length-1);//去掉子弹}}/*** 检查游戏是否结束*/public void checkGameOverAction(){if(GameOver()){state = GameStateBean.GAMEOVER;}}private boolean GameOver() {for(int i=0; i<flyings.length; i++){FlyingObject f = flyings[i];if(hero.hit(f)){hero.subtractLife();hero.clealDoubleFire();FlyingObject t = flyings[i];//将被撞敌人与最后的一个元素交换flyings[i] = flyings[flyings.length-1];flyings[flyings.length-1] = t;flyings = Arrays.copyOf(flyings, flyings.length-1);//去掉被子弹撞上的敌人}}return hero.getLife() <= 0;//命数小于等于0结束}/*** 启动程序的action*/public void action(){MouseAdapter l = new MouseAdapter() {//重写鼠标移动事件public void mouseMoved(MouseEvent e){if(state == GameStateBean.RUNNING){hero.moveTo(e.getX(),e.getY());}}//鼠标点击事件public void mouseClicked(MouseEvent e){switch(state){case GameStateBean.START:state= GameStateBean.RUNNING;break;case GameStateBean.GAMEOVER:state = GameStateBean.START;//清理现场score = 0;hero = new Hero();flyings = new FlyingObject[0];bullets = new Bullet[0];break;}}//鼠标移除public void mouseExited(MouseEvent e){if(state == GameStateBean.RUNNING){state = GameStateBean.PAUSE;}}//鼠标移入public void mouseEntered(MouseEvent e){if(state == GameStateBean.PAUSE){state = GameStateBean.RUNNING;}}};this.addMouseListener(l);//处理鼠标操作事件this.addMouseMotionListener(l);//鼠标的滑动Timer timer = new Timer();//定时器int intervel = 10;//定时间隔(以毫秒为单位)timer.schedule(new TimerTask() {public void run(){if(state == GameStateBean.RUNNING){enterAction();//敌人入场moveAction();//敌人移动shootAction();//子弹入场collisionAction();//子弹与敌人相撞outOfBoundsAction();//删除越界的敌人和子弹checkGameOverAction();//敌人和英雄机相撞 }repaint();//重新绘制界面}}, intervel, intervel);}public static void main(String[] args) {JFrame gameFrame = new JFrame();gameFrame.setTitle("AircraftBattle");AircraftBattle game = new AircraftBattle();gameFrame.getContentPane().add(game);gameFrame.setSize(new Dimension(WIDTH, HEIGHT));gameFrame.setAlwaysOnTop(true);gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);gameFrame.setLocationRelativeTo(null);gameFrame.setVisible(true);game.action();}
}
3.总结
- 代码还是要靠自己动手写才能提升(ಥ﹏ಥ)。
- 完整的工程在我的GitHub。戳这里。
Java版本飞机大战相关推荐
- 基于Java的飞机大战游戏的设计与实现论文
源码下载 http://www.byamd.xyz/hui-zong-1/ 摘 要 现如今,随着智能手机的兴起与普及,加上4G(the 4th Generation mobile communicat ...
- 基于Java的飞机大战游戏的设计与实现(含源文件)
欢迎添加微信互相交流学习哦! 项目源码:https://gitee.com/oklongmm/biye 基于Java的飞机大战游戏的设计与实现 摘 要 现如今,随着智能手机的兴起与普及,加上4G( ...
- 基于Java的飞机大战游戏的设计与实现(论文+源码)
毕业设计(论文)任务书 第1页 毕业设计(论文)题目:基于Java的飞机大战游戏的设计与实现毕业设计(论文)要求及原始数据(资料):1.综述基于Java的飞机大战游戏的现状:2.深入了解Java的设计 ...
- java版飞机大战代码
java版飞机大战代码 前言 Plane PlaneStatus类 Power类 Gift Diji play类 over类 MainFrame主类 MyZiDan DijiZiDan Before ...
- 【Java】Java基础飞机大战小游戏完整代码
Java基础飞机大战小游戏完整代码 先来展示一下代码实现结果图 主函数ShootGame 初始化游戏原始背景图片,游戏人物图片,游戏开始结束图片:构建产生敌人算法:产生英雄机算法:发射子弹算法:判断是 ...
- 毕业设计 基于Java的飞机大战游戏的设计与实现
文章目录 前言 一.项目设计 1. 模块设计 功能需求 游戏状态控制功能模块 游戏难度的调整模块 游戏界面绘画功能模块 玩家游戏控制功能模块 2. 实现效果 二.部分源码 项目源码 前言 今天学长向大 ...
- 基于Java的飞机大战游戏的设计与实现
项目介绍 飞机大战主要需要我方飞机和敌方飞机,还有子弹,特殊nPC,开始背景,结束背景,以及背景音乐.我方飞机可以随意移动,敌方飞机无规律出现.游戏玩家通过鼠标移动控制飞机移动,我方飞机在游戏开始时就 ...
- 基于Java Swing 飞机大战游戏
一.项目概要: 基于Java Swing飞机大战游戏,打死飞机,可以随机出现加血包.子弹升级包.并支持根据游戏的分数,调整游戏难度. 二.界面展示: 三.主要代码: package com.maoxu ...
- Java实现飞机大战(有图片素材)
http://[[尚学堂]Java飞机大战3.0重制版,1小时快速上手掌握,源码_课件_资料,基础小白必学项目,毕设练手项目经验_Java项目_java入门_游戏开发]https://www.bili ...
最新文章
- SPU表管理之删除SPU表数据
- 名校算法博士找工作两月无果,因本科是不知名学校被婉拒
- Linux之telnet命令使用详解—网络故障定位(四)
- Jmeter工具笔记-Jmeter+influxdb+grafanas设置性能监控过程
- 批量正则替换某文件夹中代码(div id=XXXX替换为div id=XXXX)
- 【白话机器学习】算法理论+实战之朴素贝叶斯
- nginx lua示例
- Linux Qt使用POSIX多线程条件变量、互斥锁(量)
- C#中的程序集和命名空间
- linux 系统调试工具,Linux 系统调试...
- JS实现弹性漂浮广告代码
- Windows安装补丁_勒索病毒_补丁号
- 封装系统(以封装Windows 7为例)
- bean named 'transactionManager' available: No matching PlatformTransactionManager bean found for qua
- 实现TCP协议端到端的可靠传输 RDT
- layim框架+websocket即时通讯功能
- 取消GitHub邮箱订阅
- 怎么拿到签到王者的勋章?
- WAP 2.0 VS WEB 2.0
- 解决中端投资痛点,“轻中端”能否抢占投资价值高地?