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

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

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

先来展示一下代码实现结果图
代码结果图1
代码结果图2
博主不喜欢废话,直接上干货。

主函数ShootGame

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

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;											//修改为暂停
			
		}
	}

}

所有类的父类FlyingObject

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

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;				//子弹与敌人相撞的临界状态
	
	}
}

英雄机Hero类

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

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;								//临介条件
	}

}

小敌机Airplane类

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

//小敌机
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;										//一次递增一个速度
		
		
	}
}

小蜜蜂Bee类

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

//小蜜蜂
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;
	}
}

子弹Bullet类

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

//子弹
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项目包下。
飞机大战开始字体界面
英雄机图片1
飞机大战背景图片
游戏结束界面
游戏暂停界面
小敌机图片
英雄机图片2
游戏背景图片
小蜜蜂图片
子弹图片

结束语

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

猜你喜欢

转载自blog.csdn.net/weixin_48701521/article/details/106939574