Java基础飞机大战小游戏完整代码
初始化游戏原始背景图片,游戏人物图片,游戏开始结束图片;构建产生敌人算法;产生英雄机算法;发射子弹算法;判断是否相撞算法(子弹与敌机相撞,英雄机与敌机相撞);击落敌人奖励算法;绘制游戏中人物算法;鼠标控制移动算法;
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; //修改为暂停
}
}
}
概括所有对象的共性,统一调用
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; //子弹与敌人相撞的临界状态
}
}
主要包括英雄机出现位置,英雄机大小,生命值,火力值的设置算法;英雄机发射子弹算法;英雄机与敌机相撞判定算法;英雄机打到小蜜蜂的奖励算法。
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; //临介条件
}
}
设置小敌机出现位置,移动限制
//小敌机
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; //一次递增一个速度
}
}
小蜜蜂奖励算法;小蜜蜂出现算法;
//小蜜蜂
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;
}
}
包括对发射子弹初始化,子弹移动的设置
//子弹
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项目包下。
若想获得更多的编程干货,关注博主,持续更新福利。