实习项目:雷霆战机
1、项目需求分析:
游戏状态state:
start准备状态
running运行状态
pause暂停状态
gameover游戏结束状态
英雄机:一个,走步行为(即两张图片的切换)
与鼠标一起移动的行为,鼠标位于英雄机的中心位置。
射击行为:子弹为单倍火力或双倍火力
碰撞行为:与敌机碰撞
减命行为:每次碰撞,生命值+1
敌机: 随时间产生很多架敌机。
走步行为:(向下移动)
碰撞行为:与子弹碰撞,敌机消失
小蜜蜂:随时间产生很多个
走步行为:(斜着向下移动)
是一种奖励:可能是+命奖励,+双倍火力奖励
子弹:随时间而数量在变化
走步行为:向上移动
需要注意的:
敌机越界,子弹越界的处理逻辑
2、类型设计
通过需求分析后,可以设计类型:
FlyingObject:飞行物---abstract
属性:
image;
x;开始绘制的横坐标
y; 开始绘制的纵坐标
width;//图片的宽度
height;//图片的高度
step();//走步行为
outOfBounds();越界行为
接口两个
Award:奖励接口
常量来模拟不同奖励
int DOUBLE_FIRE = 0 //默认为单倍火力
int LIFE = 1;// //默认奖励为一条命
int getType();//获取奖励的类型
Enemy:敌人接口
int getScore();//获取分数
Hero:英雄机类型
属性:
images--存储两张图片
life:----生命初始值
double_fire
step()--重写此方法:两张图片进行切换
moveTo(int x,int y);--跟着鼠标移动
shoot():产生单排或者是双排子弹
hit(FlyingObject objs):是否与其他飞行物进行碰撞
addLife():增加命
substractLife():减命
Airplane:敌机
speed:每次移动的像素点
step():----重写此方法
Bee:小蜜蜂
xSpeed:每次在x轴上行走的像素点
ySpeed:每次在y轴上行走的像素点
step():----重写此方法
Bullet:子弹
speed:每次在y轴上行走的像素点
step():----重写此方法
游戏面板类型:
ShootGame:
hero:一个英雄机对象
objects:很多个需要被击打的飞行物,(敌机,蜜蜂)
bullets:一堆子弹
加载静态资源:即所有的图片
hero0
hero1
background
airplane
bee
bullet
gameover
pause
start
3、程序编写
(1):写主类:ShootGame--->**JPanel**
提供main方法,创建窗口,面板等数据
加载所有的静态资源
重写绘制功能paint方法
绘制背景图片
(2):定义FlyingObject
添加了image,x,y,width,height属性
添加了step(),outOfBounds()方法
(3):定义接口
1)Award:奖励接口
添加DOUBLE_FIRE和LIFE两个常量
添加getType()方法
2)Enemy:敌人接口
添加getScore()方法
(4):定义Hero类型 ---extends FlyingObject
添加了images,double_fire,life三个独有属性
添加了构造器,给八个属性初始化
重写outOfBounds方法,设置成永不越界,返回false
重写step()方法,模拟英雄机飞行,即两张图片的交换
(5)在ShootGame中
添加定时器Timer,在action方法内
设置定时器任务,
10毫米开始执行任务,每隔10毫秒再次执行任务
(6)在Hero类型中:
添加了moveTo(int x,int y)
计算英雄机的位置与鼠标的关系
(7) 在ShootGame中:
action方法中添加了 鼠标监听事件
在监听事件中,重写了
mouseMoved()方法
(8) 定义类型Bullet
添加了独有的属性speed, 即移动像素
添加了构造器,给属性初始化
注意:构造器添加两个参数(因为子弹的位置与英雄机有关系)
step()--重写此方法,每次向上移动3像素
outOfBounds():重写此方法,考虑子弹越界情况
(9)在Hero类中,
添加shoot()方法,作用是英雄机产生单排子弹,或者是双排子弹。
(10)在ShootGame类中
添加了两个属性:
objects:所有飞行物的一个数组,用来存储敌机和蜜蜂
bullets:子弹数组,用来存储所有的子弹
在定时器中调用了方法
enterAction():表示所有飞行物进场。(此方法没有定义)
stepAction();
shootAction();
(11) 首先定义enterAction()方法,不写逻辑
定义stepAction()方法,
即objects(敌机和蜜蜂)
bullets
hero
都需要调用自己的step()
定义shootAction():
设计成每400毫米发射一次子弹,
将发射出来的子弹,存入bullets数组中
(12)在paint()中
调用paintBullets(g);方法
(13)定义paintBullets()方法,
绘制所有的子弹
(14)定义敌机类型Airplane
继承FlyingObject,实现Enemy接口
添加属性speed, 每次移动的像素
添加了构造器,给属性初始化
getScore()--重写,获取5分
step()--重写走步逻辑
outOfBounds()--重写越界逻辑
(15)定义蜜蜂类型Bee
继承FlyingObject,实现Award接口
添加了xSpeed,ySpeed,awardType等属性
添加了构造器,给属性初始化
getType():重写,获取奖励类型
step()--重写走步逻辑
outOfBounds()--重写越界逻辑
(16)在ShootGame类中
补全enterAction()功能
调用方法randomOne()随机生成一个敌人或者是蜜蜂
存储在objects数组中
(17)定义randomOne()方法
随机一个0~19的任意一个整数
0~18,生成一个敌机
19 生成蜜蜂
(18)为了看到游戏面板上的敌机或蜜蜂
我们在paint()方法调用
paintFlyingObject(g);
(19)定义完成
paintFlyingObject(Graphics g)
对飞行物进行绘制
(20)在定时器中添加
bangAction();//碰撞行为
(21)定义bangAction();
循环遍历子弹,是否击中飞行物
调用了bang(b)方法
(22)定义bang(b)方法
循环遍历飞行物是否被子弹击中
调用了shootBy(b);
记录被击中的飞行物的下标
备份,然后将飞行物从数组中删除。
然后查看备份的飞行物是哪种类型
敌机类型:
调用getScore方法进行加分
--此时需要定义属性score//总分数
life//总命数
蜜蜂类型:
获取奖励类型:
根据奖励类型,调用相应的方法
双倍火力奖励:调用addDoubleFire()
生命奖励:调用addLife();
(23)在FlyingObject中定义
boolean shootBy(Bullet b)
实现被击中的算法。
(24)在Hero类中定义
addDoubleFire()方法
addLife();
substractLife();
getLife();
setDoubleFire();重置火力值
(25)在绘制paint方法中
添加paintScore()方法
(26)定义paintScore()
对分数和命数进行绘制。
(27)在定时器中添加
outOfBoundsAction()//检查越界行为
(28)定义outOfBoundsAction()方法
将没有越界的对象存入一个新数组
然后将新数组赋值给相应的
bullets/objects;
(29)状态处理:
添加状态属性state
添加四个常量状态:
startgame
running
pausegame
over
(30)在paint()方法中调用
paintState(g)
(31)定义paintState()方法
绘制相应的图片
(32)
修改定时器内的逻辑
添加分支结构,running状态时,执行逻辑
(33)补全鼠标事件
1.点击事件,写出相应逻辑
2.离开事件,写出相应逻辑
3.进入事件,写出相应逻辑
(34)在定时器中添加
checkGameOver()行为。
(35)定义checkGameOver()方法
逻辑为
游戏结束时,修改游戏状态
调用了isGameOver()方法
(36)定义isGameOver()方法
逻辑为:
遍历所有的飞行物,查看是否与英雄机相撞
调用
hero.hit(obj)方法
撞击后,
英雄机减命
重置火力值
从数组中处理掉被撞击的飞行物
当生命值<=0时,游戏结束
(37)在Hero类型中定义
hit()方法
实现hit的逻辑。