实验五数据结构综合应用 20162310
分析系统架构
Sprite精灵类
- ISprite精灵类是所有类的父类
CombatAircraft战斗机类
- 首先确保战斗机完全位于Canvas范围内,每隔7帧发射单发黄色子弹。
protected void beforeDraw(Canvas canvas, Paint paint, GameView gameView) {
if(!isDestroyed()){
//确保战斗机完全位于Canvas范围内
validatePosition(canvas);
//每隔7帧发射子弹
if(getFrame() % 7 == 0){
fight(gameView);
}
}
战斗机如果被击中,执行爆炸效果,具体来说,首先隐藏战斗机,然后创建爆炸效果,爆炸用28帧渲染完成,爆炸效果完全渲染完成后,爆炸效果消失。然后战斗机会进入闪烁模式,战斗机闪烁一定次数后销毁。
//在飞机当前还没有被击中时,要判断是否将要被敌机击中
if(!collide){
List<EnemyPlane> enemies = gameView.getAliveEnemyPlanes();
for(EnemyPlane enemyPlane : enemies){
Point p = getCollidePointWithOther(enemyPlane);
if(p != null){
//p为战斗机与敌机的碰撞点,如果p不为null,则表明战斗机被敌机击中
explode(gameView);
break;
}
}
}
//beginFlushFrame初始值为0,表示没有进入闪烁模式
//如果beginFlushFrame大于0,表示要在第如果beginFlushFrame帧进入闪烁模式
if(beginFlushFrame > 0){
long frame = getFrame();
//如果当前帧数大于等于beginFlushFrame,才表示战斗机进入销毁前的闪烁状态
if(frame >= beginFlushFrame){
if((frame - beginFlushFrame) % flushFrequency == 0){
boolean visible = getVisibility();
setVisibility(!visible);
flushTime++;
if(flushTime >= maxFlushTime){
//如果战斗机闪烁的次数超过了最大的闪烁次数,那么销毁战斗机
destroy();
//Game.gameOver();
}
}
}
AutolSprite
- AutoISprite是一个走直线的精灵,其位置只能直上直下,且向下为正。在y轴方向移动speed像素,检查Sprite是否超出了Canvas的范围,如果超出,则销毁Sprite。其中RectF为坐标类,判断位置。
//检查Sprite是否超出了Canvas的范围,如果超出,则销毁Sprite
RectF canvasRecF = new RectF(0, 0, canvas.getWidth(), canvas.getHeight());
RectF spriteRecF = getRectF();
if(!RectF.intersects(canvasRecF, spriteRecF)){
destroy();
敌机类EnemyPlane
- 敌机类,从上向下沿直线运动。设置一个敌机的抗打击能力(通俗说是血量)和打一个敌机的得分。敌机在绘制完成后要判断是否被子弹打中,判断方法为判断敌机在坐标轴上是否与子弹相交。若敌机已经没有能量了,执行爆炸效果。
//创建爆炸效果,爆炸由敌机中心点开始爆炸
float centerX = getX() + getWidth() / 2; // 得到敌机中心坐标
float centerY = getY() + getHeight() / 2;
Bitmap bitmap = gameView.getExplosionBitmap();
Explosion explosion = new Explosion(bitmap);
explosion.centerTo(centerX, centerY);
gameView.addSprite(explosion);
//创建爆炸效果完成后,向GameView中添加得分并销毁敌机
gameView.addScore(value);
destroy();
爆炸类Explosion
- 爆炸效果类Explosion,可以显示动态的爆炸效果。爆炸效果由14个片段组成,每个爆炸片段绘制2帧。当绘制完所有的爆炸片段后,销毁爆炸效果。得到绘制完整爆炸效果需要的帧数,即28帧。
protected void afterDraw(Canvas canvas, Paint paint, GameView gameView) {
if(!isDestroyed()){
if(getFrame() % explodeFrequency == 0){
//level自加1,用于绘制下个爆炸片段
level++;
if(level >= segment){
//当绘制完所有的爆炸片段后,销毁爆炸效果
destroy();
}
}
}
编译、运行、测试系统
第一步,将码云上的代码克隆下来
第二步,编译,运行
修改系统
分析数据结构,排序,查找算法的应用
List线性表
- 主要使用了线性表来获取处于活动状态的敌机、存储所有的精灵等。
public List<EnemyPlane> getAliveEnemyPlanes(){
List<EnemyPlane> enemyPlanes = new ArrayList<EnemyPlane>();
for(ISprite s : sprites){
if(!s.isDestroyed() && s instanceof EnemyPlane){
EnemyPlane sprite = (EnemyPlane)s;
enemyPlanes.add(sprite);
}
}
return enemyPlanes;
}
- 将所有敌机存储在list中,并进行for循环查找是否与战斗机有交点。若有交点则战斗机摧毁。
List<EnemyPlane> enemies = gameView.getAliveEnemyPlanes();
for(EnemyPlane enemyPlane : enemies){
Point p = getCollidePointWithOther(enemyPlane);
if(p != null){
//p为战斗机与敌机的碰撞点,如果p不为null,则表明战斗机被敌机击中
explode(gameView);
break;
}
}