雷电飞机大战游戏|基于Java开发实现雷电飞机大战游戏

news2024/11/25 10:39:11

作者主页:编程指南针

作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师

主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助

收藏点赞不迷路  关注作者有好处

文末获取源码 

项目编号:KS-034

前言:

 电脑游戏,是指在计算机上能够运转的游戏软件。这种软件具有较强的娱乐性。电脑游戏的创新和发展与硬件、软件的发展紧密相关。它能够给玩家提供一个虚拟的环境,使游戏带给了人们很多的享受和欢乐。雷电游戏因为操作简单,节奏明快,一直是纵轴射击游戏的经典之作。经常能够在手机或者计算机中见到这款游戏,深得广大玩家的喜爱,可以说是妇孺皆知的一款益智类游戏。

   本游戏基于Eclipse开发工具,以java作为编程语言,整个项目开发旨在模拟雷电游戏的飞机射击游戏。游戏界面的下部是玩家的飞机,可以根据按键控制子弹的发射,上部为敌方飞机,在界面中随机出现。在游戏过程当中,用户飞机的移动是被电脑键盘的方向键所控制的,在整个游戏过程当中,如果用户飞机的子弹与敌方飞机发生相撞时,敌方飞机就会有爆炸的效果产生。游戏中使用到的飞机、子弹均采用对应的类实现。

一,项目简介

我们在小时候都拥有属于自己的一台游戏机,里面形形色色大概有十来款游戏。像 “扫雷”、“推箱子”、“俄罗斯方块”等等,我们的童年有这些游戏陪伴我们是幸福的,令许多小伙伴都为之痴迷,即使现在,这些都是随处可见的休闲游戏。我之选择“雷电”游戏作为我的毕业设计,因为它可以代表一代人青春的回忆。

Java语言,实际上就是面向对象的编程语言。对于计算机编程者来说,使用Java最大的好处有两方面,一是就编写程序而言,非常的简单也容易使用,二是它的功能很强大。与此同时,面向对象理论得以很好的实现。“雷电”游戏的毕业设计使我对本科期间所学知识进行了巩固。

    目前常见的电脑游戏的类型有动作游戏、传统益智游戏、体育游戏、策略游戏、休闲游戏和角色扮演类游戏等。不同的类型的游戏有着自身的特点,每一种类型的游戏都有一定的支持人群。开发出一款良好的游戏,了解各种类型的基本特点是很有必要的。而“雷电”游戏就属于上述类型中的STG(射击类)游戏,STG(Shooting Game)类型游戏主要凭借远程武器与敌方开展模拟对抗,拥有绚丽的射击画面。

这个项目使我第一次全流程地独立完成整条链路的开发,对于我自己而言,是0-1的突破。万事开头难,有了这次完整项目开发的经历,以后再做游戏或者其它项目时就对全局有所把控,能够做到游刃有余。假如自己没有亲自动手设计这些,哪怕一次,就不能够真正的领会一个完整项目体系中的每个元素。在以后做一些大的项目时,就更不能对整体进行宏观思考,也就不能对具体项目中每一个细分的小模块进行合适的时间估计,导致项目开发超过预期时间,更有甚,不能完成。

大部分的射击类游戏都存在一定的相似性,雷电游戏也不存在特殊。其实就是一个周而复始的情形,一直到游戏结束才能够停止。游戏开始阶段接受玩家的输入并对这个输入办理,如果没有结束就会不断产生飞机,通过检查我方飞机的血条判断游戏是不是最终结束。

该雷电主要就是我方飞机与敌方飞机的射击比拼,首先需要有界面来装载整个项目,通过键盘的上、下、左、右键遥控自己的飞机,z、x键进行子弹发射的选择,然后是敌方飞机的出现方式,敌机子弹的生成,通过各个关卡,最后得出比赛的结果。

雷电游戏主要包括以下功能:

  1. 雷电游戏状态调整功能 :在游戏启动时,游戏会自动进行初始化的验证,若初始化成功后,界面会自动进行跳转,跳转到游戏开始界面,有开始、暂停、恢复游戏等选项。

    (2)雷电游戏难度的升级:当进入游戏后,随着时间越来越长,游戏难度会越来越大,界面中敌机增多,对飞机造成伤害的子弹增多,游戏难度增加,最后会遇到一个血条较长的怪兽,攻击其至血条为0时,自动过关跳转到下一关卡。

    (3)玩家对飞机的控制功能:玩家可以对飞机进行操控,通过前后左右键来控制飞机的飞行路线。

    (4)游戏界面绘画功能。

 关键技术

  1. 游戏美工。游戏中需要使用的游戏素材有自己控制的飞机、敌方飞机、游戏过程当中飞机所产生的子弹、飞机被命中的爆炸图片等。这些素材的选择尤为重要,游戏中清新亮丽的画面可以给玩家带来充足的美感和游戏体验。所以,在这个“雷电”游戏的素材选择中,应挑选一些立体感强的图片,给玩家更大的视觉冲击。
  2. 多线程技术的实现。多线程编程能够提供程序两个或两个以上并发执行任务的能力,极大改善程序的响应性能,有效提高资源的利用效率。采取Runnable接口的方法达到定义用户线程的功能,这样既不会对继承其他类有所变化,也不会改变实现其它接口。
  3. 用户飞机子弹与敌方飞机的相撞测试。包括自己控制的飞机与敌方飞机或子弹的相撞等。在这一过程中,将所有子弹对象的矩形区域与敌机对象的矩形区域逐个以此进行检测,如果出现重叠则说明子弹与敌机发生了碰撞。

(4)游戏地图滚动原理的实现。我们在坐火车时都产生过一种错觉:自己乘坐的火车没有发生移动,但如果旁边有其他火车发生移动,我们就会感到是自己的火车在移动。这种现象与飞机射击类游戏的地图原理类似,即通过背景图片的来回滚动,给游戏玩家一种是自己操纵的飞机向前飞行的感觉。

二,环境介绍

语言环境:Java:  jdk1.8

数据库:Mysql: mysql5.7

应用服务器:Tomcat:  tomcat8.5.31

开发工具:IDEA或eclipse

开发技术:JavaSwing 及多线程

三,系统展示

 

四,核心代码展示

package com.ideabobo.game.leidian;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;

import com.ideabobo.game.leidian.Boss;

public class Battle extends Role {
	private static Battle battle = new Battle();

	private int tamaIntCount;

	private float speed;

	private float oldx;

	private float oldy;

	public static float vx;

	public static float vy;
	
	public static boolean keygo = false;

	private float tv[] = { -1F, -7F, 0.0F, -8F, 1.0F, -7F };

	public int power;

	public int powerMax;
	


	public Battle() {
		super(GamePanel.heroImage);
		speed = 3F;
		tamaIntCount = 0;
		x = ((float) app.getWidth() - WIDTH) / 2.0F;
		y = (float) app.getHeight() - HEIGHT * 2.0F;
		power = 600;
		powerMax = power;
	}

	public static Battle getInstance() {
		return battle;
	}

	public void move() {
		oldx = x;
		oldy = y;
		if (Key.left) {
			if (Key.xkey)
				x -= (double) speed / 4D;
			else
				x -= speed;
			if (x <= 0.0F)
				x = 0.0F;
		}
		if (Key.right) {
			if (Key.xkey)
				x += (double) speed / 4D;
			else
				x += speed;
			if (x + WIDTH >= (float) app.getWidth())
				x = (float) app.getWidth() - WIDTH;
		}
		if (Key.down) {
			if (Key.xkey)
				y += (double) speed / 4D;
			else
				y += speed;
			if (y + HEIGHT >= (float) app.getHeight())
				y = (float) app.getHeight() - HEIGHT;
		}
		if (Key.up) {
			if (Key.xkey)
				y -= (double) speed / 4D;
			else
				y -= speed;
			if (y <= 0.0F)
				y = 0.0F;
		}
		//**//--///loonframewrk提供
		vx = x - oldx;
		vy = y - oldy;
		if (tamaIntCount > 0)
			tamaIntCount--;
		if (Key.zkey && tamaIntCount <= 0) {
			for (int i = 0; i < tv.length; i += 2) {
				GamePanel.addList(new BattleBasic(x + WIDTH / 2.0F, y, tv[i],
						tv[i + 1]));
				tamaIntCount = 8;
			}
		}
		if (Key.xkey && !Key.zkey && tamaIntCount <= 0) {
			GamePanel.addList(new BattleBeam(x + WIDTH / 2.0F, y, 0.0F, -8F));
			tamaIntCount = 2;
		}
		if(Key.space){
			if(!keygo){
				GamePanel.skillCount--;
			}
			app.skillAnime();
			
			if(GamePanel.skillCount < 0){
				GamePanel.skillCount = 0;
			}
			if(GamePanel.skillCount>0){
				for (int i = 0; i < GamePanel.list.size(); i++) {
					Role chara1 = (Role) GamePanel.list.get(i);
					if(!(chara1 instanceof Battle) && chara1.x>0 && chara1.y>0 && !(chara1 instanceof BossA)  && !(chara1 instanceof BossB)  && !(chara1 instanceof BossC)){
						GamePanel.list.remove(i);
					}else if((chara1 instanceof BossA)  || (chara1 instanceof BossB)  || (chara1 instanceof BossC)){
						Boss cb = (Boss)chara1;
						cb.power-=50;
					}
				}
			}
			keygo = true;
		}
		
		if(!Key.space){
			keygo = false;
		}
	}

	public boolean checkHit(Role chara) {
		if ((chara instanceof EnemyA) || (chara instanceof EnemyB)|| (chara instanceof EnemyC) || (chara instanceof EnemyShot)) {
			
			if ((x + WIDTH) - 14F > chara.x && x + 14F < chara.x + chara.WIDTH
					&& (y + HEIGHT) - 12F > chara.y
					&& y + 12F < chara.y + chara.HEIGHT) {
				//如果碰到敌人,敌人死亡
				chara.dead();
				//如果碰到子弹血量减少
				if (chara instanceof EnemyBeam){
					power--;
				}
					
				power -= 50;
				if (power <= 0) {
					dead();
					//绘制爆炸图片
					GamePanel.burst = new Burst(x, y);
				}
				return true;
			}
		} else if ((chara instanceof Boss) && (x + WIDTH) - 14F > chara.x + 50F
				&& x + 14F < (chara.x + chara.WIDTH) - 50F
				&& (y + HEIGHT) - 12F > chara.y + 50F
				&& y + 12F < (chara.y + chara.HEIGHT) - 80F) {
			power--;
			if (power <= 0) {
				dead();
				GamePanel.burst = new Burst(x, y);
			}
			return true;
		}
		return false;
	}

	public void setX(float x) {
		this.x = x;
	}

	public void setY(float y) {
		this.y = y;
	}

	public float getWidth() {
		return WIDTH;
	}

	public float getHeight() {
		return HEIGHT;
	}

	public float getX() {
		return x;
	}

	public float getY() {
		return y;
	}

	public Image getImage() {
		return img;
	}

	public int getPower() {
		return power;
	}

	public int getPowerMax() {
		return powerMax;
	}

	public void setPower(int power) {
		this.power = power;
	}

	public void drawPower(Graphics g) {
		g.setColor(Color.white);
		g.drawRect(380, 450, 50, 15);
		g.setColor(Color.red);
		g.fillRect(381, 451,
				(int) ((50D / (double) (float) powerMax) * (double) power) - 1,
				14);
	}
	
	public void drawSkillCount(Graphics g){
		g.setColor(Color.white);
		Font font = new Font("宋体", 1, 20);
		g.setFont(font);
		g.drawString("全屏爆破:" + GamePanel.skillCount, 0, 450);
	}

}

package com.ideabobo.game.leidian;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;

abstract class Boss extends Enemy {

	protected int powerMax;

	public Boss(Battle battle, Image enemyImage) {
		super(battle, enemyImage);
	}

	public abstract void move();

	public float getX() {
		return x;
	}

	public float getY() {
		return y;
	}

	public float getWidth() {
		return WIDTH;
	}

	public float getHeight() {
		return HEIGHT;
	}

	public int getPower() {
		return power;
	}

	public Image getImage() {
		return img;
	}

	public void drawPower(Graphics g) {
		g.setColor(Color.white);
		g.drawRect(200, 20, 150, 15);
		g.setColor(Color.green);
		g
				.fillRect(
						201,
						21,
						(int) ((150D / (double) (float) powerMax) * (double) power) - 1,
						14);
	}

	public int getPowerMax() {
		return powerMax;
	}

}

五,项目总结

本次项目开发是基于JAVA的雷电游戏。

此雷电游戏通俗来说就是我方飞机和敌方之间的对决,先要做的应该是通过一个界面来达到装载整个游戏,然后就是我方飞机的移动方式(也就是通过键盘来移动),接着就是生成我方飞机的子弹(依据子弹类型的不同有不同的实现形式),准备就绪后会有敌方飞机的出现,每一个飞机会对应发射不同种类的子弹,最后是我方飞机通过键盘进行移动、射击,显示出游戏结果,然后结束游戏。

该雷电应该满足以下一些要求:

(1)游戏状态控制功能

在进行游戏的设计时,我们应该考虑到,如何进行游戏状态的划分。简单来说,我们需要设置开始,并且要考虑到游戏中断,以及中断后回到游戏中。玩家点击开始之后,程序会调用启动页面的代码,然后进入游戏,在游戏的过程中,玩家如果由于其它工作需要离开时,可以将其中断,比如单击空格键,当需要恢复游戏现场时,再单击空格键,就可以继续游戏,当自己控制的飞机被击毁时,会有游戏结束的显现。

(2)游戏难度的调整

    随着游戏的进行、关卡的提高,敌机的速度会越来越快、敌方飞机的数目会越来越多、子弹数量也会越快且越多。此时,带给游戏玩家的视觉冲击变得更强,需要玩家更加冷静地去躲闪以及攻击敌机。

(3)游戏界面绘画功能

游戏主屏主要用来输出用户对我方的控制与敌方的动作显示。在游戏屏幕的左下角有全屏爆破次数的显示,这相当于游戏玩家的特殊技能,可以瞬间清除当前屏幕上的所有敌机以及子弹,在游戏屏幕的右下角会呈现玩家飞机血条,代表着当前我方飞机的状态。当血条格为空时,表示我方飞机已经被击毁,整个雷电游戏也将结束。

  1. 玩家游戏控制功能

对于我方飞机的移动和子弹的发射,游戏用户可以通过控制键盘来控制。飞机的左右移动通过键盘的上、下、左、右键来实现,而我方飞机子弹的释放方式有两种,z键会释放出点状子弹,而x键会释放出线状子弹,可供游戏玩家依据需要自行选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/143941.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前端】Vue项目:旅游App-(8)city:标签页Tabs动态数据:网络请求axios与request、数据管理store与pinia、各种封装

文章目录目标过程与代码安装相关库封装网络请求相关代码网络请求数据网络请求数据操作封装pinia管理数据并封装tab栏改为动态数据效果本篇总结总代码修改或新建的文件serviceindexmodules的cityrequest的configrequest的indexstoremodules的citymodules的loadingcity.vue参考目…

录屏没有声音怎么办?录屏怎么录声音

相信部分朋友在录制视频时&#xff0c;有出现录制视频没有声音&#xff0c;导致该段视频没有声音而无法播放。录屏怎么录声音&#xff1f;可以使用支持录制声音的专业的电脑录屏软件。今天小编就在这给大家分享在录制视频同时&#xff0c;将声音也录制进去的操作步骤。一、录屏…

【Linux】主函数的三个形参

主函数的形参有三个&#xff1a;argc参数个数&#xff0c;argv参数内容&#xff0c;envp环境变量。其中argc是整型&#xff0c;argv和envp是指针数组&#xff08;存的字符串&#xff09; argv源于我们自己在使用执行命令时传的内容&#xff0c;envp源于程序的父进程&#xff08…

力扣sql入门篇(十)

力扣sql入门篇(十) 1 查找重复的电子邮箱 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 SELECT Email FROM Person GROUP BY Email HAVING count(id)>21.3 运行截图 2 合作过至少三次的演员和导演 2.1 题目内容 2.1.1 基本题目信息 2.1.2 示例…

Java并发编程(六)ExecutorService

ExecutorService invokeAny() he invokeAll() 具有阻塞特性 invokeAny invokeAny 的作用是取得第一个完成任务的结果的值。 如果线程中增加 if (!Thread.currentThread().isInterrupted()) 判断&#xff0c;则会中断这些线程。 其他线程如果抛出 InterruptedException() 异常&a…

从徘徊迷茫到行业精英,社科院与杜兰大学金融管理硕士改变你的人生轨迹

在以“内卷”为主基调的职场环境里&#xff0c;似乎不停地进阶已经成为了职场人的唯一出路。但是&#xff0c;如何在进阶路上冲破职业瓶颈&#xff0c;到达心之所往的理想位置&#xff0c;则没有一个标准的答案。有的职场人士通过考取不同的技能证书来增加自身优势&#xff0c;…

Java Agent 踩坑之 appendToSystemClassLoaderSearch 问题

作者&#xff1a;卜比 本文是《容器中的 Java》系列文章之 2/n&#xff0c;欢迎关注后续连载 &#x1f603; 。 从 Java Agent 报错开始&#xff0c;到 JVM 原理&#xff0c;到 glibc 线程安全&#xff0c;再到 pthread tls&#xff0c;逐步探究 Java Agent 诡异报错。 背景 …

数据分析,你还在单纯地看数据?

企业的数字化意识越来越强&#xff0c;工作中也开始使用各种业务系统来管理业务&#xff0c;管理数据。很多人以为上了业务系统&#xff0c;对数据进行统计了&#xff0c;就是数据分析&#xff0c;这是大错特错的观点&#xff0c;数据分析是通过数据来剖析企业经营管理和业务发…

Using chatbots to scaffold EFL students argumentative writing (论文翻译)

使用聊天机器人来指导学生的议论文写作摘要研究表明&#xff0c;英语作为外语的学生的议论文写作受益于与同龄人的互动。然而&#xff0c;在实践中找到一个理想的对象很困难&#xff0c;聊天机器人被认为是这个问题的潜在解决方案。聊天机器人是人工智能的一种形式&#xff0c;…

Studio One6最新更新教程及安装包下载

Studio One6拥有多达50款原生效果插件&#xff0c;例如Analog Delay延迟插件&#xff0c;除能制作延迟效果外&#xff0c;还提供了制作复古的镶边与和声效果。Rotor插件制作的经典旋转扬声器效果也是非常不错的。这些插件&#xff0c;无论是在用户界面&#xff0c;还是使用体验…

http-serve开启一个服务器

前言在写前端页面中&#xff0c;经常会在浏览器运行HTML页面&#xff0c;从本地文件夹中直接打开的一般都是file协议&#xff0c;当代码中存在http或https的链接时&#xff0c;HTML页面就无法正常打开&#xff0c;为了解决这种情况&#xff0c;需要在在本地开启一个本地的服务器…

70. 爬楼梯

70. 爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1 阶 1 阶2 阶 示例 2&am…

如何将python脚本打包成可执行exe文件

如何将python脚本打包成可执行exe文件 前提条件 1. 新建一个python项目&#xff0c;并且配置虚拟环境 2. 安装pyinstaller 打包EXE文件 写一个支持入参的python脚本&#xff0c;打包成exe文件 找一张图片作为exe文件的图标 百度搜索” 在线jpg转cio”,将图片转换成cio格式 …

MySQL基础篇第11章(数据处理之增删改)

1.插入数据 1.1 实际问题 1.2 方式1&#xff1a;VALUES的方式添加 使用这种语法一次只能向表中插入一条数据。 情况1&#xff1a;为表的所有字段按默认顺序插入数据 INSERT INTO 表名 VALUES (value1,value2,....);值列表中需要为表的每一个字段指定值&#xff0c;并且值的…

MTIC工业大脑,海量接入网关!

MTIC3.0工业大脑是高性能&#xff0c;高可靠性的低代码开发数据核心平台&#xff0c;支持上万级别的网关设备同时在线&#xff0c;提供标准版本业务系统&#xff0c;可实现多业主工程项目并行管理&#xff0c;吸取大型物联网数据监测工程专家建议&#xff0c;实现项目精细化管理…

什么是DPU

什么是DPU 什么是 DPU&#xff1f; 在数据中心、DPU 或数据处理单元中移动数据的专家是一种新型的可编程处理器&#xff0c;将与 CPU 和 GPU 一起成为计算的三大支柱之一。 当然&#xff0c;您可能已经熟悉中央处理器。 多年来&#xff0c;CPU 是大多数计算机中唯一的可编程元…

如何避免成为背锅侠?

你被同事甩过锅吗&#xff1f; 打工人在职场中犯错都是不可避免的。 但明明不是自己的问题&#xff0c;还要背个黑锅&#xff0c;就非常闹心了&#xff01; 大家好&#xff0c;我是大D。 前几天&#xff0c;大D开发完了一个项目&#xff0c;在交付验收中发现业务逻辑存在漏洞&a…

java swing人机对战五子棋(含背景音乐)

一、项目简介 本项目是一套基于java swing的人机对战五子棋系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xf…

java BigDecimal保留两位小数

对于一些精准的数字&#xff0c;如涉及到金额时我们一般会使用BigDecimal类型来保存和处理。在处理保留小数位数时&#xff0c;如果通过DecimalFormat表达式需要注意下。 1、通过DecimalFormat保留两位小数 通过上图可以看到&#xff0c;#在补位时&#xff0c;如果该位没有数…

C/C++入门005-C语言数组

文章目录C语言数组数组的基本概念及定义数组定义数组中的几个名词数组长度计算方法二维数组的含义二维数组的定义字符数组字符函数1. strlen 计算字符串长度2. strcpy 字符串拷贝3. strcat 字符串追加4. strcmp 字符串比较1. strncpy 字符串拷贝3. strncmp 字符串比较4. strstr…