飞机大战Java版完整版

本文介绍了使用Java开发的飞机大战游戏,包含三个关卡和四个随机事件,玩家需击败怪物并通过时间点来通关。文章提供了项目演示地址、界面及关卡绘制类、素材资源,并强调仅供学习交流,禁止未经授权的转载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

           这是一款闯关的射击游戏,人物在不同的关 卡里面会触发不同的技能与对应的特效操作,有三个关卡与四个随机事件,每个关卡里面都会触发不同数量的怪物与能量血瓶,通过打败怪物与 到达特点时间点可通关


本项目演示地址

⭐资源图片源代码私信博主⭐


           效果图以及关卡里面的演示

请添加图片描述


            界面类

package game;

import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

class Main extends JFrame implements ActionListener {  鼠标点击行为

	Image im1 = (new ImageIcon("src/images/游戏缩小图标.jpeg")).getImage();
	ImageIcon icon = new ImageIcon("src/images/bg.jpeg"); // 游戏背景

	JButton btn1 = new JButton("开始游戏"); // 开始界面的按钮
	JButton btn2 = new JButton("选择关卡");
	JButton btn3 = new JButton("关于游戏");
	JButton btn4 = new JButton("退出游戏");

	JPanel jpan = new JPanel();// 创建画板

	JLabel jlbBackImg = new JLabel();// 创建标签

	Main() {
		this.setLayout(null);// 取消窗口布局管理器
		this.setTitle("试炼之旅");
		this.setIconImage(im1);// 设置与游戏窗口图标
		this.setBounds(0, 0, 800, 800);

//		this.setSize(800, 800);
		this.setLocationRelativeTo(null); // 设置窗体居中显示

		jpan.setBounds(0, 0, 800, 800); // 定义控件的x,y,w,h的大小

//		jpan.setBounds(120, 120, 800, 800);
		jpan.setLayout(null); // 取消面板的布局管理器,防止闪烁

		btn1.setBounds(350, 350, 120, 40);

		btn2.setBounds(350, 410, 120, 40);
		btn3.setBounds(350, 470, 120, 40);

		btn4.setBounds(350, 530, 120, 40);

		btn1.addActionListener(this); // 窗口向按钮注册
		btn2.addActionListener(this);
		btn3.addActionListener(this);
		btn4.addActionListener(this);

		jlbBackImg.setBounds(0, 0, 800, 800); // 800 800
		jlbBackImg.setIcon(icon); // 设置图标

		jpan.add(btn1); // 添加按钮
		jpan.add(btn2);
		jpan.add(btn3);
		jpan.add(btn4);

		jpan.add(jlbBackImg); // 向面板添加标签
		this.add(jpan);

		this.setResizable(false);// 使游戏窗口不能改变大小
		this.setVisible(true);// 使窗口显示
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 单击窗口关闭按钮,结束程序
	}

	@Override // 按钮的动作事件
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == btn1) { // e.getSource 为获得事件源
			this.dispose();// 点击按钮“开始游戏”关闭当前窗口
			new Game();// 加载开始游戏窗口

		}
		if (e.getSource() == btn2) { // 这里记得写关于后面游戏关卡的操作
			this.dispose();
			new selectGame();
		}
		if (e.getSource() == btn3) {
			int value = JOptionPane.showOptionDialog(this,
					"关于游戏:第一关人物“WSAD”控制方向,“鼠标左键发射”,“按键Q消耗分数回血”" + "需要躲避周围射击出现的热旋。\n" + "                   "
							+ "第二关人物1“WSAD”控制方向,“鼠标左键发射”,“按键Q消耗分数回血”,“按键K消耗能量释放技能”;“人物2箭头控制方向”,“右键发射攻击特定怪物”。\n"
							+ "                   "
							+ "第三关人物“WASD”控制方向,“鼠标左键发射”,“按键Q消耗分数回血”,“按键K消耗能量释放技能”,“达到1500分数后解锁右键射击,R键特殊功能会在第二个Boss解锁”\n"
							+ "                   " + "“F1重新开始本关”" + "“F2”返回游戏主界面,“F3”退出游戏。游戏愉快!",
					"试炼之旅", JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null);
		}

		if (e.getSource() == btn4) {
			System.exit(0);// 退出程序
		}
	}

	public static void main(String[] args) {
		new Main();
	}
}

请添加图片描述
请添加图片描述
请添加图片描述


           关卡的绘制类

	@Override // 面板的各人物绘制
	public void paint(Graphics gh) {

		if (gamerun == 1) {
			if (bg1y >= 800) {
				bg1y = -800;
			}
			if (bg2y >= 800) {
				bg2y = -800;
			}
			bg1y += 10;
			bg2y += 10;
			gh.drawImage(ic1, bg1x, bg1y, 800, 800, null);// 画的游戏背景
			gh.drawImage(ic2, bg2x, bg2y, 800, 800, null);

			man.move(gh);// 画角色

			gametimeBoss1.paintSelf2(gh); // 画boss1

			for (int i = 0; i < shocks.size(); i++) { // 画雷电
				shocks.get(i).drowshock(gh);
			}

			for (int i = 0; i < timebossbullets.size(); i++) { // boss的射击
				timebossbullets.get(i).drowshock2(gh);
			}

			for (int i = 0; i < skills.size(); i++) { // 画K技能特效
				skills.get(i).drowshock2(gh);
			}

			for (int i = 0; i < gb.length; i++) {
				gb[i].drawShell(gh); // 画出炮弹
				gb[i].drawShells(gh);
				if (gb[i].getRect().intersects(man.getRect())) {
					Explode explode = new Explode(man.x, man.y);
					explode.draw(gh);
					explodes.add(explode);
					manlife1 -= 10;
					break;
				}
				if (gb[i].getRect1().intersects(man.getRect())) {
					Explode explode = new Explode(man.x, man.y);
					explode.draw(gh);
					explodes.add(explode);
					manlife1 -= 10;
					break;
				}

			}

相关的素材包
在这里插入图片描述


            随机Boss的子弹类

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;

import javax.swing.ImageIcon;

class gametimeboss { // 这里画的是随机关卡的东西

	Image ima = (new ImageIcon("src/timebossshock/随机事件.png")).getImage();
	protected int speed = 15;

	protected double degree = Math.random() * Math.PI * 5; // 炸弹随机角度
	protected int Shellx = 300, Shelly = 300;

	public Rectangle getRect() {

		return new Rectangle(Shellx, Shelly, 35, 35);
	}

	public void drawShell(Graphics gh) {
		Shellx += speed * Math.cos(degree);
		Shelly += speed * Math.sin(degree);
		if (Shellx < 0 || Shellx > 760) {
			degree = Math.PI - degree;
		}
		if (Shelly < 0 || Shelly > 760) {
			degree = -degree;
		}
		gh.drawImage(ima, Shellx, Shelly, 40, 40, null);// 画出炮弹

	}

/

	Image ima1 = (new ImageIcon("src/timebossshock/随机事件1.png")).getImage();
	protected int speed1 = 12;

	protected double degree1 = Math.random() * 10; // 炸弹随机角度
	protected int Shellx1 = 400, Shelly1 = 250;

	public Rectangle getRect1() { // 获得矩形

		return new Rectangle(Shellx, Shelly, 35, 35);
	}

	public void drawShells(Graphics gh) { // 画出炮弹使其碰撞窗口反弹
		Shellx1 += speed1 * Math.cos(degree1);
		Shelly1 += speed1 * Math.sin(degree1);
		if (Shellx1 < 0 || Shellx1 > 760) {
			degree1 = Math.PI - degree1;
		}
		if (Shelly1 < 0 || Shelly1 > 760) {
			degree1 = -degree1;
		}
		gh.drawImage(ima1, Shellx1, Shelly1, 50, 50, null);// 画出炮弹
	}

/

	// 画levl3的boss1的随机技能
	Image power2 = (new ImageIcon("src/bossimg/power2.png")).getImage();

	protected int powerspeed = 10;

	protected double powerdegree = Math.random() * 15; // 随机角度
	protected int powerx = 400, powery = 250;

	public Rectangle getRect2() { // 获得矩形

		return new Rectangle(powerx, powery, 30, 30);
	}

	public void drawpower(Graphics gh) { // 画出炮弹使其碰撞窗口反弹
		powerx += powerspeed * Math.cos(powerdegree);
		powery += powerspeed * Math.sin(powerdegree);
		if (powerx < 0 || powerx > 760) {
			powerdegree = Math.PI - powerdegree;
		}
		if (powery < 0 || powery > 760) {
			powerdegree = -powerdegree;
		}
		gh.drawImage(power2, powerx, powery, 50, 50, null);// 画出炮弹
	}

}


作者:KJ.JK
本文仅用于交流学习,未经作者允许,禁止转载,更勿做其他用途,违者必究。
文章对你有所帮助的话,欢迎给个赞或者 star 呀,你的支持是对作者最大的鼓励,不足之处可以在评论区多多指正,交流学习呀

package cn.feike.shoot; import java.awt.Graphics; import java.awt.image.BufferedImage; public abstract class FlyingObject { protected double x;//物体的x坐标 protected double y;//物体的y坐标 protected double width;//物体的宽 protected double heigth;//物体的高 protected BufferedImage image;//当前正在显示的图片 protected int index = 0;//图片数组下标序号,子类中使用 protected double step;//飞行物每次(1/24秒)移动的距离 protected int life;//命 protected int state;//飞行物的状态 public static final int ACTIVE=0;//活着状态 public static final int DEAD=1;//死亡状态 public static final int REMOVE=2;//回收状态 //默认构造器 public FlyingObject() { life = 1; state = ACTIVE; } //有参构造器 public FlyingObject(double width,double heigth){ this();//调用无参数的构造器,必须写在第一行. this.x = (int)(Math.random()*(480-width)); this.y = -heigth; this.width = width; this.heigth = heigth; step = Math.random()*3+0.8;//初始化step为[0.8,3.8)之间的数 } //重写toString方法 public String toString() { return x+","+y+","+width+","+heigth+","+image; } //重写paint,方便子类对象的使用 public void paint(Graphics g) { g.drawImage(image, (int)x, (int)y, null);//绘制图片 } //飞行物移动的move方法 /** * 重构了move,方法实现播放销毁动画功能 */ public void move(){ if(state == ACTIVE){ y += step; return ; } if(state == DEAD){ //从子类对象中获取下一张照片 BufferedImage img = nextImage(); if(img == null){ state = REMOVE;//没有照片则回收 }else{ image = img;//否则把子类的图片传给image } //越界则销毁 if(y>=825){ state = REMOVE; } } } /** * 子类中必须有的方法,返回下一个要播放的照片引用, * 如果返回null表示没有可播放的照片了. */ protected abstract BufferedImage nextImage(); /** * 飞行物被打了一下 */ public void hit(){ if(life>0){ life--; } if(life==0){ state = DEAD; } } /** * 碰撞检测的方法 * 检测物体的位置是否在碰撞的范围内. * (子弹是否在飞行物的碰撞范围内) */ public boolean duang(FlyingObject obj){ //this(x,y,w,h) //obj(x,y,w,h) double x1 = this.x - obj.width; double x2 = this.x + this.width; double y1 = this.y - obj.width; double y2 = this.y + this.heigth; return x1<obj.x&&obj;.x<x2&&y1;<obj.y&&obj;.y<y2; } /** 重构FlyingObject,添加了状态检查方法 */ /** 检查飞行物死了吗 */ public boolean isDead(){ return state == DEAD; } /** 检查飞行物是否活动的 */ public boolean isActive(){ return state == ACTIVE; } /** 检查飞行是否可以被删除*/ public boolean canRemove(){ return state == REMOVE; } /** 飞行物添加"去死"方法*/ public void goDead(){ if(isActive()){ state = DEAD; } } }
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KJ.JK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值