简单Java飞机大战制作(小白)_归长安_

1 篇文章 1 订阅
1 篇文章 0 订阅

哈喽,大家好~~~我先简单的自我介绍一下下吧,我是一枚大学生JAVA小小白,今天也是突发其想写下这一个博客,这个只对于想学JAVA和想做一个简单的JAVA小程序写的,本博客涉及到的也是小白简单的知识和算法,因为本人也是小白,想以最简单易懂的话语写出JAVA飞机大战。话不多说,上干货…不懂的可以联系我,我力所能及的的给你解答,同时也欢迎学习Java的同学一起讨论“姿”识~ 写的不好,多多包涵下下 嘿嘿

下面是JAVA飞机大战的项目结构和思维导图(大概)一定认真看哦 ,直接代码 (有注释的)
这里是GITHUB的项目链接:https://github.com/chenjie1024/Game
这里有源码和图片哦
在这里插入图片描述
结构图
在这里插入图片描述
运行图
在这里插入图片描述
暂停图
在这里插入图片描述
开始图
在这里插入图片描述
结束图
游戏结束

火力值
在这里插入图片描述
飞行类

package game;

import java.awt.image.BufferedImage;
/*
 * 
 * 飞行物的共性累  
 * 抽象类 (每个事物是不同的 英雄类 向上飞  敌机 向下 子弹上下)
 * 		 都有自己的图片 宽高 
 * 
 * */
public abstract class FlyingObject {
//	描述飞机的共性内容
//	图片   protected 受保护的
	protected BufferedImage image;
//	宽高坐标
	protected int width;
	protected int height;
	protected int x;
	protected int y;
	
	protected int speed;
//	移动方法
	public abstract void step();
		
//	检测飞行类是否出界
	public abstract boolean outOf();

//	检测敌人是否被子弹击中
	public boolean shootBy(Bullet b){
		int x1 = this.x;
		int x2 = this.x+this.width;
		
		int y1 = this.y;
		int y2 = this.y+this.height;
		
		int x = b.x;
		int y = b.y;
		return x>=x1 && x<=x2 && y>=y1 && y<=y2;
	}
}


我方飞机

package game;


import java.awt.image.BufferedImage;

/*
 * 
 * 
 * 小飞机(我方)英雄类
 * 
 * 
 * */
public class Hero extends FlyingObject{
	
	public int doubleFire;//火力值
	public int life;//生命
	public static BufferedImage[] heroImg ;//第一个图片
	public static BufferedImage[] heroImgBlowup ;//第二个图片
	public BufferedImage image;//
	public int index = 0;//图片下标
	
	public Hero(){
//		加载图片
		image = Game.hero0;
//		宽带等于图片宽带
		width = image.getWidth();
		height = image.getHeight();
//		初始位置
		x = 150;
		y = 530;
//		初始火力 生命
		doubleFire = 0;
		life = 3;
		
		heroImg = new BufferedImage[]{Game.hero0,Game.hero1};
		
		heroImgBlowup = new BufferedImage[]{Game.hero2,Game.hero3,Game.hero4};
		
		index = 0;
		
	}

	public void step() {
//		图片切换
		image = heroImg[index++/10%heroImg.length];
		
		
	}
//	移动
	public void moveTo(int x,int y){
		this.x = x -this.width/2;//
		this.y = y -this.height/2;//
	}
//	发射子弹
	public Bullet[] shoot(){
		int xstep = -1+this.width/4;
		int ystep = 20;
		
		if(doubleFire>0){
//			子弹数组   
			Bullet[] bs = new Bullet[2];
			
			bs[0] = new Bullet(this.x+1*xstep-15,this.y-ystep);//英雄4/1的宽度,高度
			bs[1] = new Bullet(this.x+4*xstep-1,this.y-ystep);//英雄3/1的宽度,高度不变
			doubleFire-=2;
			
			return bs;
		}else{
			Bullet[] bs = new Bullet[1];
			bs[0] = new Bullet(this.x+2*xstep,this.y-ystep);//英雄4/2宽
			return bs;
		}
		
	}

	public boolean outOf() {
		
		return false;//永不越界
	}
	

//	英雄机增命
	
	public void addLife(){
		life++;
		
	}
//	获取命数
	public int getLife(){
		return life;
		
	}
//	减命
	public void subLife(){
		life--;
		
	}
//	加火力值
	public void addDoubleFire(){
		doubleFire += 40;
		
	}
//	清空火力值
	public void subDoubleFire(){
		doubleFire  = 0;
		
	}
//	判断 飞行物 和 飞机是否发生碰撞
	public boolean hit(FlyingObject f){
		
		int x1 = f.x - this.width/2;
		int x2 = f.x + f.width + this.width/2;
		
		int y1 = f.y - this.height/2;
		int y2 = f.y + f.height - this.height/2;
		
		int x = this.x + this.width/2;
		int y = this.y + this.height/2;
			return x>x1 && x<x2 && y>=y1 && y<=y2;//碰到减分
		
	}
//	两张图片切换
	public void Blowup(){
		image = heroImgBlowup[index++/10%heroImgBlowup.length];
	}
	

}

敌方飞机

package game;

import java.util.Random;
/*
 * 
 * 
 * 小飞机(敌)   继承飞行类(飞行物)          实现接口 奖励 获得奖励 
 * 
 * */
public class AirPlane extends FlyingObject implements Enemy{
	private ChecKpoint Checkpoints = new ChecKpoint();
	//	移动速度
	 
//	飞机一旦创建就有自己的累类型
	public AirPlane(){
//		获取图片
		System.out.println("速度:"+Checkpoints.ckt);
		
		if(Checkpoints.ckt>=1){
			Checkpoints.ckt++;
			speed += Checkpoints.ckt*2;
			System.out.println("敌机速度:"+speed);
		}else {
			
				speed = 0;
			
		}
		image = Game.airplane;
//		获取图片自己的大小
		width = image.getWidth();
		height = image.getHeight();
//		取随机数 随机小飞机飞行
		Random rand = new Random();
//		随机小飞机飞行位置   游戏宽高减去小飞机的宽高
		x = rand.nextInt(Game.WIDTH - this.width);
		y = -this.height;
		
	}
//	重写得分方法 击败得分
	public int getScore(){
		return 66;
	}

	//	重写移动方法  从上往下   y增大
	public void step() {
		y+=speed;//向下
		
	
	}
	//出界方法
	public boolean outOf() {
		
		
		return this.y>=Game.HEIGHT;
		
	}
	

}

蜜蜂

package game;

import java.util.Random;
/*
 * 
 * 蜜蜂 方法 
 * 
 * */
public class Bee extends FlyingObject implements Award{
	
	private int xSpeed = 1;
	private int ySpeed = 2;
	
	private int awardType;
	
	public Bee(){
		
		Random rand = new Random();
		
		awardType = rand.nextInt(2);
		
		if(awardType==0){
			image = Game.prop_type;
		}else{
			image = Game.bee;
		}
		
//		获取图片自己的大小
		width = image.getWidth();
		height = image.getHeight();
//		width = 40;
//		height = 50;
//		取随机数
		x = rand.nextInt(Game.WIDTH - this.width);
		y = - this.height;
		
	}
	//取奖励类型
	public int getType(){
		return awardType;
	}
	//飞行方向
	public void step() {
		x+=xSpeed;//向左或向右
		y+=ySpeed;//向下
		if(x>=Game.WIDTH-this.width){
			xSpeed = -1;
		}
		if(x<=0){
			xSpeed = 1;
		}
	}
	//判断越界
	public boolean outOf() {
		
		return y>=Game.HEIGHT;
	}
	
}

子弹

package game;


/*
 * 
 * 子弹
 * 
 * */

public class Bullet extends FlyingObject{
//	速度
	private ChecKpoint Checkpoints = new ChecKpoint();
	 
	
	public Bullet(int x,int y){
		if(Checkpoints.ckt>=1){
			speed = Checkpoints.ckt*2;
			System.out.println("子弹速度:"+speed);
		}else {
			
				speed = 0;
			
		}
//		图片
		image = Game.bullet;
//		子弹大小 位置
		width = image.getWidth();
		height = image.getHeight();
		this.x = x;
		this.y = y;
	
	}
	public void step(){
		y-=speed;//向上走
	}
	
	public boolean outOf() {
		
		return this.y <= -this.height;
	}
	
	
}

关卡

package game;
/**
 * 关卡类 用分数判断
 * @author Administrator
 *
 */
public class ChecKpoint {
	
	
	public int score = 0;//分数
	public int ckt = 1;//关卡返回数组
	
	//	关卡
	public int Checkpoints(){
		if(score>=500){
			
			ckt=2;
		}
		if(score>=1000){
			
			ckt=3;
		}
		if(score>=1500){
			
			ckt=4;
		}
		if(score>=3000){
			
			ckt=0;
		}
		return ckt;
	}
	
}

奖励类型 接口

package game;

public interface Award {
//	击败蜜蜂获得奖励 不同的奖励
	//	火力
	public int DOUBLE_FIRE = 0;
//	生命
	public int LIFE = 1;
	
//	获取奖励类型
	public int getType();
	
}

得分

package game;

public interface Enemy {
//	得分   都有着不同的得分 接口  
	
	public int getScore();
		
	
}

接下来就是最最最主方法 Game 大部分方法也都在这个类实现的

package game;
/*
 * 可升级 动态背景 开始界面 加入关卡 加入Boss 加背景音乐 
 * */
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
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 Game extends JPanel{
	
	

	/**
	 * 
	 */
	private static final long serialVersionUID = 3233689943517353386L;
	
	

	public static final int WIDTH = 400;
	
	public static final int HEIGHT = 700;
	
	//	创建IO流 加入图片
	public static BufferedImage logoImg;//logo图片
	public static BufferedImage bgImg;//背景图片
	public static BufferedImage logoImg1;//背景图片
	
	public static BufferedImage play;//开始
	public static BufferedImage pause;//暂停
	public static BufferedImage gameover;//游戏结束
	
	public static BufferedImage hero0;//英雄机
	public static BufferedImage hero1;//英雄机 
	public static BufferedImage hero2;//英雄机
	public static BufferedImage hero3;//英雄机
	public static BufferedImage hero4;//英雄机 
	
	public static BufferedImage airplane;//敌机
	public static BufferedImage emenmy;
	public static BufferedImage bee;//蜜蜂
	public static BufferedImage prop_type;//蜜蜂
	public static BufferedImage bullet;//子弹
	
	public static BufferedImage zty;//
	
//	创建调用Hero方法函数
	private Hero hero = new Hero();
	
	private ChecKpoint Checkpoints = new ChecKpoint();
	
	private FlyingObject[] flyings = {};//一堆敌人(敌机+小蜜蜂)
	private Bullet[] bullets = {};//一堆子弹
	
	
	public static final int START = 0;//启动状态
	public static final int RUNNING = 1;//运行状态
	public static final int PAUSE = 2;//暂停状态
	public static final int GAME_OVER = 3;//游戏结束
	
	public int state = START;//默认启动状态
	
	
	
	public String[] Checkpoint = new String[]{"结束","第一关","第二关","第三关","第四关","第五关"};
	
	
	
//	main运行一次 方法也也允许一次   匿名类部类
	static{
//		抛异常
		try {
//			IO读入图片
			logoImg = ImageIO.read(Game.class.getClassLoader().getResource("logo.jpg"));
			logoImg1 = ImageIO.read(Game.class.getClassLoader().getResource("Logo.png"));
			bgImg = ImageIO.read(Game.class.getClassLoader().getResource("background.png"));
			
			play = ImageIO.read(Game.class.getClassLoader().getResource("Play.png"));
			pause = ImageIO.read(Game.class.getClassLoader().getResource("pause.png"));
			gameover = ImageIO.read(Game.class.getClassLoader().getResource("gameover.png"));
			
			hero0 = ImageIO.read(Hero.class.getClassLoader().getResource("hero0.png"));
			hero1 = ImageIO.read(Hero.class.getClassLoader().getResource("hero1.png"));
			hero2 = ImageIO.read(Hero.class.getClassLoader().getResource("hero_blowup2.png"));
			hero3 = ImageIO.read(Hero.class.getClassLoader().getResource("hero_blowup3.png"));
			hero3 = ImageIO.read(Hero.class.getClassLoader().getResource("hero_blowup4.png"));
			
			airplane = ImageIO.read(Hero.class.getClassLoader().getResource("airplane.png"));
			emenmy = ImageIO.read(Hero.class.getClassLoader().getResource("enemy1.png"));
			bee = ImageIO.read(Hero.class.getClassLoader().getResource("bee.png"));
			prop_type = ImageIO.read(Hero.class.getClassLoader().getResource("prop_type.png"));
			bullet = ImageIO.read(Hero.class.getClassLoader().getResource("bullet.png"));
			
			zty = ImageIO.read(Hero.class.getClassLoader().getResource("ZTY.png"));
			
		} catch (IOException e) {
			
			e.printStackTrace();
		}
	}
//	主方法
	public static void main(String[] args) {
//		创建窗口
		JFrame frame = new JFrame("归长安—Java飞机大战");
//		窗口默认关闭   退出应用程序默认窗口关闭操作。
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//		设置窗口的大小 单位 PX 
		frame.setSize(Game.WIDTH, Game.HEIGHT);
		
		frame.setLocationRelativeTo(null);
		
		Game g = new Game();
//		加载类
		frame.add(g);
		
		frame.setVisible(true);
		
		g.action();
		
		
		
	}
	
	public void paint(Graphics g){
//		窗口加载背景 logo 图片 
		g.drawImage(bgImg, 0, 0, null);
//		g.drawImage(logoImg, 0, 0, null);
		paintHero(g);
		
		paintFlying(g);
		
		paintBullsets(g);
		
		paintSL(g);
		
		paintState(g);//加载状态图
		
	}
	public void action(){
//		创建鼠标监听器
		MouseAdapter l = new MouseAdapter() {

//			鼠标移动
			@Override
			public void mouseMoved(MouseEvent e) {
				if(state==RUNNING){//运行状态
					int x =e.getX();
					int y =e.getY();//获取鼠标的x和y
					hero.moveTo(x,y);
				}
			}
		
			
			
			//	鼠标点击
			@Override
			public void mouseClicked(MouseEvent e) {
				
				switch (state) {
				case START://
					state = RUNNING;运行状态
					break;
				case GAME_OVER://结束
					Checkpoints.score = 0;//
					hero = new Hero();//重新调用
					flyings = new FlyingObject[0]; //飞行类数组清零
					bullets = new Bullet[0];//子弹数组清零
					state = START;//启动状态
					break;
			
				}
				
			}


//   	鼠标移除
			@Override
			public void mouseExited(MouseEvent e) {
				if(state==RUNNING){
					state=PAUSE;//暂停
				}
			}


//	   	鼠标移入
			
			public void mouseEntered(MouseEvent e) {
				if(state==PAUSE){
					state=RUNNING;//运行
				}
			}

		
		};
//		添加鼠标监听事件
		this.addMouseListener(l);
//		处理鼠标滑动事件
		this.addMouseMotionListener(l);
		
//		启用定时器
		Timer t = new Timer();
//		调用  重写TimerTask   中的 run 方法
		t.schedule(new TimerTask() {
			
			public void run() {
				if(state==RUNNING){
//					checkImg();//清除图片
					enterAction();//画敌机
					stepAction();//画飞行物
					shootAction();//画子弹
					outOfAction();//越界飞行物 删除
					checkHitAction();//	检测子弹与敌人是否发生碰撞
					hitAction();//英雄机发生碰撞
					Checkpoints.Checkpoints();//判断关卡
					checkGameOverAction();//判断游戏是否结束
				}
				
//				调用Hero的repanint方法
				repaint();//画英雄机
				
				
				
			}
		}, 10,10);
	}
//	检测子弹与敌人是否发生碰撞
	public void checkHitAction(){
		for(int i = 0; i<bullets.length;i++){
			Bullet b = bullets[i];
			check(b);
		}
		
	}
	

	public void check(Bullet b){
		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 f = flyings[index];
			if(f instanceof Enemy){
				Enemy e =  (Enemy)f;
				Checkpoints.score += e.getScore();
				
			}
			if (f instanceof Award){
				Award a = (Award)f;
				int type = a.getType();
				switch(type){
				case Award.DOUBLE_FIRE:
					hero.addDoubleFire();
					break;
				case Award.LIFE:
					hero.addLife();
					
				
				}
			
			}
			FlyingObject t = flyings[index];
			flyings[index] = flyings[flyings.length-1];//数组移除
			flyings[flyings.length-1] = t;
//			缩容
			flyings = Arrays.copyOf(flyings, flyings.length-1);
		}
	}
//	
	public void paintSL(Graphics g){
		g.setColor(Color.BLUE);
		g.setFont(new Font("宋体",3,16));
		g.drawString("分数:" + Checkpoints.score, 10, 20);
		g.drawString("命数:" + hero.getLife(), 10, 40);
		g.drawString("火力:" + hero.doubleFire, 10, 60);
		g.drawString("关卡:" + Checkpoint[Checkpoints.ckt], 10, 80);
	}
//	画英雄对象方法
	public void paintHero(Graphics g){
		g.drawImage(hero.image, hero.x, hero.y, null);
	}
//	画敌人方法
	public void paintFlying(Graphics g){
		for (int i = 0; i < flyings.length; i++) {
			FlyingObject f = flyings[i];
			g.drawImage(f.image, f.x, f.y, null);
		}
	}
//	画子弹方法
	public void paintBullsets(Graphics g){
		for (int i = 0; i < bullets.length; i++) {
			Bullet b = bullets[i];
			g.drawImage(b.image, b.x, b.y, null);
		}
	}
//	画状态
	public void paintState(Graphics g){
		
		switch (state) {//不同状态不同图
		case START:
			
			
			g.drawImage(logoImg, 0, 0, null);
			g.drawImage(logoImg1,45, Game.HEIGHT/3,300,100, null);
			
			g.drawImage(play,50,Game.HEIGHT/2, 300,100,null);
//			g.drawImage(zty, 0, 0, 40,50,null);
			
			break;
		case PAUSE:
			g.drawImage(pause, 0, 0, null);
			break;
		case GAME_OVER:
			g.drawImage(gameover, 0, 0, null);
			break;

		
		}
	}

// 敌人入场
	int flyIndex = 0;//敌人入场次数
	
	public void enterAction(){
		flyIndex++;
//		小于取余加入敌机
		if (flyIndex%40==0) {
			
			FlyingObject obj = nextOne();//获取敌人对象
//			获取敌机数组
			flyings = Arrays.copyOf(flyings,flyings.length+1);
			flyings[flyings.length-1] = obj; 
		}
	}
//	生成敌机对象
	public FlyingObject nextOne(){
//		调用随机数方法
		Random rand = new Random();
//		随机生成0-19
		int type = rand.nextInt(50);
//		如果随机数小于4 出蜜蜂 否则 出敌机
		if(type<4){
			return new Bee();
		}else{	
			
			return new AirPlane(); 			
		}
		
	}
	
//	飞行物(敌机 蜜蜂 子弹)
	public void stepAction(){
		hero.step();
		for(int i= 0;i<flyings.length;i++){
			flyings[i].step();//敌人
		}
		
		for(int i=0;i<bullets.length;i++){
			bullets[i].step();//子弹
		}
		
		
		
	}
//	子弹入场
	int shootIndex = 0;//射击次数
	public 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);//数组追加
			
		}
	}
//	越界飞行物 删除 
	public void outOfAction(){
		int index = 0;//不越界飞行物下标
		
		FlyingObject[] lives = new FlyingObject[flyings.length];//不越界敌人数组
		
		for(int i = 0;i<flyings.length;i++){
			FlyingObject f = flyings[i];
			if(!f.outOf()){ // 越界 true  不越界返回false
				//将不越界的敌人对象添加到活的敌人数组中
				lives[index] = f;
				index++;
			}
			
		}
//		将不越界的敌人数组复制到flyings  长度为index(不越界个数)
		flyings = Arrays.copyOf(lives, index);
		
		index = 0;
		
		Bullet[] bulives = new Bullet[bullets.length];
		
		for(int i=0;i<bullets.length;i++){
//			获取每个子弹对象
			Bullet b = bullets[i];
			if(!b.outOf()){
				bulives[index] = b;
				index++;
			}
		}
		bullets = Arrays.copyOf(bulives, index);	
		
	}
//	英雄机发生碰撞
	public void hitAction(){
		for(int i =0;i<flyings.length;i++){
			FlyingObject f = flyings[i];
			if(hero.hit(f)){
				
				hero.subLife();//清除命
				hero.Blowup();//清除命动画
				hero.subDoubleFire();//清除火力
				
				FlyingObject t = flyings[i];
				flyings[i] = flyings[flyings.length-1];
				flyings[flyings.length-1] = t;
				flyings = Arrays.copyOf(flyings, flyings.length - 1);
				
			}
		}
	}
//	判断游戏结束
	public void checkGameOverAction(){
		if(hero.getLife()<=0){
			state = GAME_OVER;
			
		}
	}

	
//	清除图片
//	public void checkImg(Graphics g){
//		if(state == START){
//			g.drawImage(logoImg, 0, 0, null);
//		}
//	}
	
}
  • 25
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值