Java基础练习项目【飞机大战】
飞机大战
游戏需求
- 用户通过鼠标操作一架英雄机,英雄机自动发射子弹,攻击自上而下飞行的敌机,击落敌机获得奖励,不同敌机奖励不同,英雄机生命归零则死亡,游戏结束。
- 界面信息:
- 得分信息、英雄机剩余生命信息、英雄机、敌机、子弹、天空图
- 初始界面,用户点击界面,游戏开始,鼠标移至窗口外面,游戏暂停,英雄机死亡后,显示Game Over界面,再次点击鼠标,恢复初始界面
- 敌机及奖励类型:
- 小敌机:击落得1分
- 大敌机:击落得3分
- 小蜜蜂:击落奖励(英雄机获得40火力值或者1条生命)
- 敌机被击落后,显示爆炸效果后消失
- 英雄机:
- 初始生命值:3
- 初始火力值:1
- 攻击模式:单发/双发,默认单发,击落小蜜蜂后,切换为双发攻击模式
- 其它:
开发文档
需求分析
fields/method | World | Sky | Hero | Bullet | BigAirplane | Airplane | Bee |
---|---|---|---|---|---|---|---|
WIDTH | √ | ||||||
HEIGTH | √ | ||||||
START | √ | ||||||
RUNNNING | √ | ||||||
PAUSE | √ | ||||||
GAME_OVER | √ | ||||||
score | √ | ||||||
maxScore | √ | ||||||
LIFE | √ | √ | √ | √ | √ | ||
DEAD | √ | √ | √ | ||||
REMOVE | √ | √ | √ | √ | √ | ||
width | √ | √ | √ | √ | √ | √ | |
heigth | √ | √ | √ | √ | √ | √ | |
x | √ | √ | √ | √ | √ | √ | |
y | √ | √ | √ | √ | √ | √ | |
speed | √ | √ | √ | √ | √ | ||
√ | √ | √ | |||||
y1 | √ | ||||||
life | √ | ||||||
fire | √ | ||||||
xspeed | √ | ||||||
awardType | √ | ||||||
getImage() | √ | √ | √ | √ | √ | √ | |
生成对象 | √ | √ | √ | √ | √ | ||
移动 | √ | √ | √ | √ | √ | ||
得分 | √ | √ | |||||
奖励 | √ | ||||||
碰撞 | √ | √ |
超纲代码
主窗口
/*** 飞机大战,世界窗口*/private static final long serialVersionUID = 1L;public static final int WIDTH = 400;public static final int HEIDHT = 800;public static void main(String[] args) {JFrame frame = new JFrame();World world = new World();frame.add(world);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(WIDTH, HEIDHT);frame.setLocationRelativeTo(null);frame.setVisible(true);world.action();// 运行游戏入口}private void action() {// TODO Auto-generated method stub}
画界面
@Overridepublic void paint(Graphics g) {g.drawImage(sky.getImages(), sky.x, sky.y, null);// 将天空图片画到界面上}}
获取图片文件
public static BufferedImage readImage(String fileName) {try {BufferedImage img = ImageIO.read(FlyingObject.class.getResource(fileName));return img;} catch (Exception e) {e.printStackTrace();throw new RuntimeException();}}
游戏入口(监听器、定时器)
/*** 游戏入口*/public void action() {// 监听器MouseAdapter msAdapter = new MouseAdapter() {};this.addMouseListener(msAdapter);this.addMouseMotionListener(msAdapter);// 定时器Timer timer = new Timer();int intervel = 10;// 定时周期,单位毫秒timer.schedule(new TimerTask() {@Overridepublic void run() {// 要运行的程序}}, intervel, intervel);}
开发步骤
创建对象类
- 创建World类,画窗口(复制超纲代码)
- import JFrame+JPanel
- 设计World类继承JPanel
- 复制粘贴main()方法中的所有代码
- 修改frame.setSize()中的参数为常量WIDTH,HEIGHT
- 创建了6个对象类,设计FlyingObject超类,6个对象类继承超类
- FlyingObject定义共用属性,6个对象定义特定属性
基础数据初始化
- 给FlyingObject设计两个构造方法,6个派生类分别调用
对象 | 宽 | 高 | x | y | speed |
---|---|---|---|---|---|
Sky | 400 | 800 | 0 | 0 | 1 |
Hero | 97 | 139 | 140 | 400 | |
Bullet | 8 | 20 | x | y | 3 |
BigAirplane | 66 | 89 | 随机 | -高 | 2 |
Bee | 60 | 51 | 随机 | -高 | 2 |
Airplane | 48 | 50 | 随机 | -高 | 2 |
设计Images图片工具类
- 静态块
画对象:
- 想画对象需要去获取对象的图片,每个对象都得获取图片, 意味着获取图片行为为共有行为,所以设计在超类FlyingObject中, 每个对象获取图片的行为都是不一样的,所以设计为抽象方法 ----在FlyingObject中设计抽象方法getImage()用于获取对象的图片
- 获取图片时需要考虑对象的状态,因为在不同状态下获取的图片是不同的, 每个对象都有状态,意味着状态为共有属性,所以设计在FlyingObject超类中, 状态一般都设计为常量,同时设计变量state来表示当前状态 ----在FlyingObject中设计LIFE、DEAD、REMOVE常量,state变量表示当前状态 有了状态常量还不够,还需要去判断对象的状态,每个对象都得判断, 意味着判断状态为共有行为,所以设计在超类FlyingObject中, 每个对象判断状态的行为都是一样的,所以设计为普通方法 ----在FlyingObject中设计isLife()、isDead()、isRemove()来判断对象的状态
- 重写getImage()获取对象图片:
- 天空Sky: 返回sky图片即可
- 子弹Bullet:
- 若活着的,直接返回bullet图片即可
- 若死了的,直接删除(不返回图片)
- 英雄机Hero:
- 若活着的,返回heros[0]和heros[1]来回切换
- 小敌机Airplane:
- 若活着的,返回airs[0]即可
- 若死了的,依次返回airs[1]到airs[4],4后删除
- 大敌机BigAirplane:
- 若活着的,返回bairs[0]即可
- 若死了的,依次返回bairs[1]到bairs[4],4后删除
- 小蜜蜂Bee:
- 若活着的,返回bees[0]即可
- 若死了的,依次返回bees[1]到bees[4],4后删除
- 图片有了,就可以开画了,在World类中重写paint()画方法
英雄机随鼠标移动
- 英雄机随着鼠标移动为英雄机的行为,所以在Hero中设计moveTo()来实现英雄机随着鼠标移动
- 英雄机随着鼠标动为事件触发的,所以在侦听器中重写mouseMoved()鼠标移动事件 在mouseMoved()中: 获取鼠标的x和y坐标,调用Hero的moveTo()实现英雄机随着鼠标移动
敌机/子弹入场:enterAction()
- 随机生成一个敌机,构建getEnemy()方法,用于生成敌机,进行延时生成处理,0.4秒生成一个
- 对敌人数组进行扩容,并将生成的敌机插入数组中
- 构建getBullet()方法,用于生成子弹,根据英雄机的火力值,确认单双发,火力值>0,说明击落过小蜜蜂,获得双发火力,延时处理,0.3秒生成一个
- 对子弹数组进行扩容,并将子弹插入数组中
敌机和子弹移动:stepAction()
- 飞行物移动为派生类所共有的行为,所以在FlyingObject类中设计step()实现飞行物移动,默认自上而下移动,派生类不同的自行重写
- 飞行物移动为定时发生的,所以在run()中调用stepAction()实现飞行物移动 在stepAction()中:天空动,遍历敌人敌人动,遍历子弹子弹动
画分和画命:
- 在Hero中设计getLife()获取英雄机的命数
- 在World类的paint()中: 画分和画命
碰撞检测:checkHitAction()
- 设计EnemyScore得分接口,Airplane和BigAirplane实现接口 设计EnemyAward奖励接口,Bee实现接口
- 在FlyingObject中设计isHit()检测碰撞、goDead()飞行物去死,在Hero中设计addLife()增命、addFire()增火力,在Hero中设计subtractLife()英雄机减命、clearFire()清空火力值
- 子弹与敌人的碰撞:
- 遍历子弹得子弹,遍历敌人得敌人,判断若都活着并且撞上了:敌人去死、子弹去死 判断若敌人能得分,则强转为得分接口, 则玩家得分 判断若敌人为奖励,则强转为奖励接口, 则获取奖励类型,最后根据不同的奖励类型来获取不同的奖励
- 英雄机与敌人的碰撞
- 遍历敌人得敌人,判断若都活着并且撞上了:敌人去死、英雄机减命、英雄机清空火力值
删除越界和remove对象:deleteAction()
- 在FlyingObject中设计isOutside()检测敌机是否越界 在Bullet中重写isOutside()检测子弹是否越界
- 遍历所有敌人/子弹,判断若敌人/子弹越界了或者处于remove状态,则将最后一个元素赋值到越界位置,缩容
检测游戏结束:checkGameOverAction()
- 判断若英雄机的命数<=0,则表示游戏结束,…
画游戏状态控制
- 在World中设计START、RUNNING、PAUSE、GAME_OVER状态常量,usestatus变量表示当前状态 在Images中设计start、pause、gameover状态图片,静态块中初始化 在World的paint()中,设置在不同的状态下画不同的状态图
- 设置那一堆action为仅在运行状态下执行 设置英雄机随着鼠标移动为仅在运行状态下执行
- 重写mouseClicked()鼠标点击事件: 启动时变运行,游戏结束时先清理现场再变启动 重写mouseExited()鼠标移出事件: 运行变暂停 重写mouseEntered()鼠标移入事件: 暂停变运行
扩展需求列表
更多需求改动,详见https://gitee.com/qiaobilong/shoot(内附源码哦)
Java基础练习项目【飞机大战】相关推荐
- java基础小项目_java基础小项目练习之1----3天做出飞机大战
Shoot射击游戏第一天 一.关键问题(理论): 1.简述FlyingObject.Enemy.Award.Airplane.Bee.Bullet.Hero之间的继承与实现关系 2.简述Hero类构造 ...
- JAVA实战项目飞机大战——手把手教你轻松学会
飞机大战是90后童年经典回忆游戏,紧张刺激的画面和操作感,令人回味无穷.只是大家可能不知道的是,这个经典游戏只是Java的入门项目而已.只要稍微有点基础,便可以轻松的制作出来.今天小编就来带大家用ja ...
- 用JAVA制作小游戏——飞机大战(三)
本篇博客是对飞机大战游戏项目完整代码的展示 详细代码讲解: 用JAVA制作小游戏--飞机大战(一) 用JAVA制作小游戏--飞机大战(二) 最下方附整个程序的文件下载链接 代码展示 主界面 impor ...
- 用JAVA制作小游戏——飞机大战(二)
本篇博客是对飞机大战游戏使用代码的展示 重难点: 首先需要鼠标能够控制战机,使鼠标在窗口内时始终能够使战机的位置与鼠标相同,实现鼠标控制战斗机移动. 其次需要能够以一定的速度产生子弹和敌机,并且以一定 ...
- java飞机场模拟程序_java 飞机大战 小游戏源码
[实例简介] 本项目是一个使用java做的一个飞机大战的小游戏,一个英雄机,初始有三次生命,当打中蜜蜂会有一次生命奖励,当打中敌机会有相应分数奖励,但如果被敌机打中会失去一次生命机会.如果生命都失去, ...
- Java多线程编写简易飞机大战(一)
** Java多线程编写简易飞机大战(一) ** 利用多线程编写飞机大战,主要有3个关键: ①继承Thread类,重写run方法: ②线程工作代码在run方法中写: ③启动时,调用线程对象的start ...
- VS/Qt C++ 入门项目飞机大战(内含全部源代码,素材,项目工程,项目祥解)可直接运行
零.说在前面 最近做了个qt/c++的小项目飞机大战,主要是边玩边做,主要讲解一下设计思路,各个模块的实现原理,非常适合初学者拿来练手.需要源码.素材.项目详解.打包软件等整个项目用到的全部内容,可以 ...
- java 雷霆战机游戏 飞机大战 全过程教学+免费素材(附全部源代码)
这个游戏已是我第二次编写了,之前写过一个简易版的飞机大战类似demo.这次在上一次基础上添加了许多元素,增添了可玩性. 游戏效果图如下: ps :完整源码+视频教程+论文文档 :java雷霆战机完整资 ...
- 用Java实现简易的飞机大战---附源码和图片
先看演示 Java简易飞机大战 源码链接:(内置图片) 此项目源码链接[百度网盘]提取码:1234https://pan.baidu.com/s/1EoBdg_47nYgLWgB6Zee9gg 一.基 ...
最新文章
- lintcode---线段树查询||(区间元素个数)
- Linux挂载新磁盘
- 爨底下-双龙峡,凑合的一日游
- 爬虫项目(二)---采集从03月02号以来的世界各国疫情数据
- 暮色森林模组_《我的世界》暮色森林VS天启之境 到底谁才是冒险模组一哥
- STEP 7新建梯形图程序,S7-plcsim使用
- jdk和jre安装配置
- 【深度好文】simhash文本去重流程
- windows截图保存自动化脚本以及设置快捷键一键运行
- 如何优雅的创建一个Java不可变对象类,JDK源码中也是这么干的!
- 猫咪藏在哪个房间python_盘点:猫咪玩“躲猫猫”喜欢藏的几个地方,这下再也不愁找不到了...
- 2.10 窗口的拆分与隐藏 [原创Excel教程]
- html 不自动缩放,html 禁止缩放
- 设计师必读的 10 本书
- JAVA黑马程序员day7(面向对象)
- OVAL学习之第二篇
- 可删除的BloomFilter
- android 开放聊天室
- python爬虫---爬取优信二手车
- 外汇天眼:外汇中的做空和做多是什么意思?有什么区别?
热门文章
- 2019最新《Android开发全套学习教程》
- Qt的QImage类
- 驱动程序开发:基于ICM20608六轴传感器 --- 使用Regmap API 的 SPI 读取数据 之 IIO驱动
- mysql 日期group_MySql 使用GROUP BY 按照日期分组统计
- golang获取时间所在周的起止时间
- JVM中的monitorenter和monitorexit
- Android 快速集成谷歌账户登录
- Efficient multi-keyword ranked query over encrypted data in cloud computing (6)
- so-vits-svc4.0 中文详细安装、训练、推理使用教程
- 简述同步和异步的区别