1 游戏需求
分析射击游戏需求:
1)参与的角色:英雄机、子弹、大敌机、小敌机、小蜜蜂、天空
2)英雄机发射子弹
子弹可以射击小敌机、大敌机、小蜜蜂
小敌机、大敌机、小蜜蜂可以和英雄机撞
英雄机、子弹、小敌机、大敌机、小蜜蜂都在天空上飞
3)英雄机发射子弹分单倍和双倍,由火力值控制的
英雄机发射一次双倍火力,则火力值减2
4)子弹射击小敌机,子弹与小敌机消失,玩家得1分
子弹射击大敌机,子弹与大敌机消失,玩家得3分
子弹射击小蜜蜂,子弹与小蜜蜂消失,英雄机得奖励(1条命、40火力值)
5)小敌机、大敌机、小蜜蜂撞上英雄机,
小敌机、大敌机、小蜜蜂消失,
英雄机减1条命并清空火力值
1.1 找对象抽类
1)找对象:英雄机、小敌机、大敌机、小蜜蜂、子弹、天空
2)抽类:Hero、Airplane、BigAirplane、Bee、Bullet、Sky
3)设计类中的成员变量和方法:
4)创建对象并测试:
class Hero{ //英雄机
width,height,x,y,life,doubleFire
void moveTo(int x,int y){ //英雄机随着鼠标移动
}
void step(){ //英雄机切换图片
}
}
class Airplane{ //小敌机
width,height,x,y,speed
void step(){
y坐标改变
}
}
class BigAirplane{ //大敌机
}
class Bee{ //小蜜蜂
}
class Bullet{ //子弹
}
class Sky{ //天空
}
1.2 设计构造方法初始化
设计构造方法初始化各个类,并测试
1.3 抽出超类
1.设计小敌机数组、大敌机数组、小蜜蜂数组、子弹数组,并测试
2.设计FlyingObject超类,6个对象类继承
3.给FlyingObject类设计两个构造方法,6个对象类分别调用,step飞行方法为公共方法
1.将小敌机数组、大敌机数组、小蜜蜂数组合为FlyingObject数组,并测试(向上转型)
2.在6个对象类中重写超类的step()
3.画窗口
1.给类中成员添加访问控制修饰符
2.给6个对象类添加图片属性
1.4 画对象
设计抽象方法,设计抽象类
1. 在FlyingObject中设计抽象方法getImage()获取对象的图片
想画对象需要获取对象的图片,每个对象都得获取图片,
意味着获取图片为共有行为,所以设计在超类FlyingObject中,
每个对象获取图片的行为是不同的,所以设计为抽象方法
2. FlyingObject中设计LIFE、DEAD、REMOVE常量,state表示当前状态
获取图片时需要考虑对象的状态,因为不同状态下获取的图片是不同的,
每个对象都有状态,所以将状态设计在超类中,一般为常量
对象状态分三种:活着的、死了的、删除的
3. FlyingObject中设计isLife()、isDead()、isRemove()
获取图片时需在判断对象的状态,而每个对象都能判断状态,
所以判断状态行为为共有行为,设计在FlyingObject超类中,
每个对象判断状态的行为都一样,所以设计为普通方法
4. 在6个派生类中重写抽象方法getImage()获取图片
3.1)天空Sky,直接返回image
3.2)子弹Bullet:
3.2.1)若活着的,返回image
3.2.2)若死了的,改为删除状态
3.3)英雄机Hero:
3.3.1)若活着的,返回images[0]和images[1]来回切换
3.4)小敌机Airplane:
3.4.1)若活着的,返回images[0]
3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除
3.5)大敌机BigAirplane:
3.4.1)若活着的,返回images[0]
3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除
3.6)小蜜蜂Bee:
3.4.1)若活着的,返回images[0]
3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除
5. 在FlyingObject中设计普通方法paintObject()实现画对象
获取了图片,则可以开始画对象了,每个对象都能画,为共有行为
因为每个对象画图片的行为都是一样的,所以设计为普通方法
6. 在Sky中重写paintObject()画两张图片
天空需要画两张图片,所以在天空Sky中重写paintObject()
7. 在World中重写paint()
画对象行为写好后,在窗口上调用即可
1.5 设计对象入场
1.敌人入场:
1)敌人是由窗口产生的,所以在World类中设计nextOne()生成敌人
2)敌人入场是定时发生的,所以在run中调用enterAction()实现敌人入场
在enterAction()中:
每400毫秒获取敌人对象,enemies扩容,装到最后一个元素上
2.子弹入场:
1)子弹是由英雄机发射出来的,所以在Hero类中设计shoot()生成子弹对象
2)子弹入场是定时发生的,所以在run中调用shootAction()实现子弹入场
在shootAction()中:
每300毫秒获取子弹对象,bullets扩容,数组的追加
3.飞行物移动:
1)飞行物移动为共有行为,所以在FlyingObject中设计抽象方法step()
派生类中重写step()
2)飞行物移动是定时发生的,所以在run中调用stepAction()实现飞行物移动
在stepAction()中:
天空动,遍历敌人敌人动,遍历子弹子弹动
1.6 设计接口
1.英雄机随着鼠标移动:
1)英雄机随着鼠标动为英雄机的行为,在Hero中设计moveTo()实现英雄机移动
2)英雄机随着鼠标动为事件触发的,所以在侦听器重写mouseMoved()鼠标移动事件
在mouseMoved()中:
获取鼠标的x和y坐标,英雄机动
2.删除越界的敌人和子弹:
1)在FlyingObject中设计outOfBounds()检测敌人是否越界
在Bullet中重写outOfBounds()检测子弹是否越界
2)删除越界为定时发生的,所以在run()中调用outOfBoundsAction()实现删除越界敌人和子弹
在outOfBoundsAction中:
声明不越界敌人/子弹数组,遍历敌人/子弹数组,获取对象,
判断若对象不越界,则将对象添加到不越界敌人/子弹数组中
最后将不越界敌人/子弹数组,复制到enemies/bullets中
3.设计Enemy得分接口,Airplane和BigAirplane实现Enemy接口
设计Award奖励接口,Bee实现Award接口
1.7 设计得分和奖励
1.子弹与敌人的碰撞:
1)在FlyingObject中设计hit()实现检测碰撞
在FlyingObject中设计goDead()实现飞行物去死
在Hero中设计addLife()增命、addDoubleFire()增火力
2)碰撞为定时发生的,所以在run()中调bulletBangAction()实现子弹与敌人的碰撞
在bulletBangAction()中:
遍历子弹得子弹,遍历敌人得敌人,判断是否撞上了,
若撞上了:
子弹去死、敌人去死
判断被撞对象:
若能得分,得getScore()玩家增分
若是奖励,则getAwardType()英雄机奖励(命、火力值)
2.画分和画命:
1)在Hero中设计getLife()获取英雄机的命数
2)在paint()中: 画分和画命
1.8 检测状态
1.英雄机与敌人的碰撞:
1)借用FlyingObject中的hit()碰撞检测、goDead()飞行物去死
在Hero中设计subtractLife()减命、clearDoubleFire()清火力
2)碰撞为定时发生的,所以在run()中调用heroBangAction()实现英雄机与敌人的碰撞
在heroBangAction()中:
遍历敌人得敌人,判断是否撞上了,
若撞上了:
敌人去死、英雄机减命、英雄机清火力
2.检测游戏结束:
1)借用Hero的getLife()获取命数
2)检测游戏结束为定时发生的,所以在run()中调用checkGameOverAction()检测游戏结束
在checkGameOverAction()中:
判断若英雄机命数<=0,则...(将当前状态修改为游戏结束状态)
3.画状态:
1)在World中设计4个常量表示当前状态,1个state变量表示当前状态
在World中设计3个静态图片,在static块中初始化
2)在World的paint()方法中,设计在不同状态下画不同的图片
3)action()方法run()中的一堆action,设计为只在运行状态下执行
action()方法mouseMoved()中的英雄机动,设计为只在运行状态下执行
4)重写mouseClicked()鼠标点击:
启动变运行,游戏结束时先清理现场再变为启动状态
重写mouseExited()鼠标移出:
运行变暂停
重写mouseEntered()鼠标移入:
暂停变运行
代码见上传资源中。