飞机大战游戏思路及问题总结

在做这个游戏刚开始时,不知如何着手,思路很乱,不能统观全局.如隔靴搔痒,抓不住其中要点,窥不透真义.几天下来,在老师的引导下,基本完成了简单的功能,现在回顾一下过程中的心得以及遇到的问题,希望有所助益.

一.思路

1.页面布局
- 有两个界面,开始界面和游戏界面,两个大div:开始界面div有开始背景图片,有一个开始按钮,建议按钮包裹在一个div里,方便定位;游戏界面有其背景图片,上面有个得分div,另外还有暂停div包含继续按钮和重新开始按钮以及结果分数.
- css div最好都是绝对定位,方便以后获取坐标,两个大div外可用一个div包裹,这个div无需设置宽高,只需绝对定位即可,当然也可以不用外包裹.
- 开始界面和游戏界面div宽高一致,游戏界面设置display为none,其中的暂停div也需要设置隐藏.

基本的布局就完成了,其他样式按自己喜好设置即可.

2.javascript实现

- 游戏界面有我方飞机,子弹还有敌机,这在开始按钮点击之前就应该准备好.这就需要构造函数,封装方法.创建飞机类,属性有图片路径,爆炸图片路径,图片宽高,坐标,分数还有血量,

- 敌机对象继承了飞机函数的属性,多加一个移动属性
- 子弹属性类似敌机,都是随机产生
- 构造完成
- 生成我方飞机对象
- 创建让鼠标位置始终处于我方飞机的中心点函数:

myPlane.imageNode.style.left = cx - MYPLANE_WIDTH/2 + "px";
myPlane.imageNode.style.top = cy - MYPLANE_HEIGTHT/2 + "px";

为避免飞机越界,需判断出现,cx,cy的位置
- 写定时器里的方法
 - 背景图片向下移动:改变它的Y坐标值,直到完全跑出div,设置Y为0,循环往复.` mainDiv.style.backgroundPosition = "0px " + bgPositionY + "px";`
 - 子弹生成:当我方飞机状态为真时,将生产的子弹对象放进数组里,方便遍历和销毁,子弹生成速度可自行设置
 - 子弹移动销毁:遍历数组,调用移动方法,当子弹top值超过一定值,移除子弹图片节点,并把对应的对象从数组移除,因为移除后,数组下标会改变,需要让下标-1
 - 敌机生成和移动:类子弹,不同的是敌机有3种,需要设置敌机的生成速度,另外敌机生成位置是随机,需要用到Maths.random();
 - 敌机销毁:两种情况:1.top值超出边界,2.敌机与子弹碰撞后,又延迟爆炸时间
 - 碰撞:敌机和我方本机碰撞,游戏结束,弹出重新开始框,遍历敌机数组判断top和left值是否相等,是则更换本方飞机图片为爆炸图片,更改本方飞机状态,清除定时器,弹出暂停div,但是继续按钮禁用
 - 碰撞:子弹和敌机碰撞后销毁敌机,并计算分数,遍历子弹和敌机数组,敌机血量减少为0,计分,更换敌方飞机图片为爆炸图片,更改敌机状态,移除子弹,中断遍历.

- 开始按钮点击显示游戏界面,开启定时器:隐藏开始界面,显示游戏界面,开启定时器
- 解决IE兼容性方法

   function add(obj,type,fn){
        if(document.attachEvent){
            obj.attachEvent( "on" + type ,fn);
        }else if(document.addEventListener){
            obj.addEventListener(type,fn,false);
        }
    }
      function remove(obj,type,fn){
        if(document.detachEvent){
            obj.detachEvent( "on" + type ,fn);
        }else if(document.removeEventListener){
            obj.removeEventListener(type,fn,false);
        }
      }

- 创建点击游戏界面暂停并弹出继续框函数
 - 创建点击继续按钮继续当前游戏函数:要阻止事件流ev.stopPropagation();
 - 添加事件 
    add(mainDiv,"mousemove",mouseMove);//添加鼠标移动事件
    add(mainDiv,"click",mainClick);//添加鼠标点击div后暂停事件
    add(continueBtn,"click",conClick);//添加继续按钮点击事件
- 重来按钮点击刷新界面,回到开始界面`window.location.reload();`

二.一些问题

1.敌机,特别是大飞机在产生后会闪动,而且一晃就消失了?
原因:帧数.
- 帧数就是在1秒钟时间里传输的图片的量,也可以理解为图形处理器每秒钟能够刷新几次,通常用fps(Frames Per Second)表示。每一帧都是静止的图象,快速连续地显示帧便形成了运动的假象。高的帧率可以得到更流畅、更逼真的动画。帧数 (fps) 越高,所显示的动作就会越流畅。 但是文件大小会变大。
- 游戏帧数:游戏运行时每秒所运行的帧数(简称FPS,Frames Per Second) 和视频一样,FPS越大,在屏幕上的视频就越来越平滑,直到一个临界点(大约是100FPS),超过这个临界点,再高的FPS都只是一个令人惊奇的数值,400FPS和100FPS在人的视觉中几乎没有差别。一般游戏都是40左右fps就可以称之为流畅了。
- 30帧的情况下,每帧显示33ms,响应极限大概是100ms。60帧的情况下,每帧显示16ms,响应极限大概是50ms。
- 我当时设置的定时器的时间是100ms,大飞机生成速度我又设置的比其它飞机慢,就明显看到闪动
- 大部分电影帧数只有 24 帧每秒,就可以流畅

2.事件流影响

         function conClick(e){
        var ev = e || window.event;
        pauseDiv.style.display = "none";
        myPlane.imageNode.style.display = "block";
        ev.stopPropagation();
        add(mainDiv,"mousemove",mouseMove);
        endTimer =  window.setInterval(main_loop, 16);
       }

 在创建继续按钮点击事件时,我没有阻止事件流, ` pauseDiv.style.display = "none";`这句话的效果一直没有实现,但是定时器却成功启动了,一直不知为何,后来想原来是,我用的是冒泡法,继续按钮是在pauseDiv里,pauseDiv又处在mainDiv里,而mainDiv正好也有个点击事件,不阻止事件流,就会向外传播,触发mainDiv的点击事件,导致无法隐藏pauseDiv.  

         function conClick(e){
        var ev = e || window.event;
        pauseDiv.style.display = "none";
        myPlane.imageNode.style.display = "block";
        ev.stopPropagation();
        add(mainDiv,"mousemove",mouseMove);
        endTimer =  window.setInterval(main_loop, 16);
       }

  在创建继续按钮点击事件时,我没有阻止事件流, ` pauseDiv.style.display = "none";`这句话的效果一直没有实现,但是定时器却成功启动了,一直不知为何,后来想原来是,我用的是冒泡法,继续按钮是在pauseDiv里,pauseDiv又处在mainDiv里,而mainDiv正好也有个点击事件,不阻止事件流,就会向外传播,触发mainDiv的点击事件,导致无法隐藏pauseDiv.

  function mainClick(){
        clearInterval(endTimer);
        myPlane.imageNode.style.display = "none";
        pauseDiv.style.display = "block";
        remove(mainDiv,"mousemove",mouseMove);
    }

3.经过这个项目,才发现构造对象,封装方法很重要,而且也很方便.

4.多定义常量,尽量少用数字,即magic number
- 在源代码编写中,有这么一种情况:编码者在写源代码的时候,使用了一个数字,比如0x2123,0.021f等,他当时是明白这个数字的意思的,但是别的程序员看他的代码,可能很难理解,甚至,过了一段时间,代码的作者自己再看代码的时候也忘记了这个数字代表的含义。
- 在编程中使用幻数是不好的习惯,开发中应当尽量避免
- 代码可读性差,修改不方便
- 解决魔术数字的方法主要是将这些数字定义为常量,或者枚举类型,或者使用编译器的宏定义(如C/C++的#define) 

时间: 2024-11-09 09:17:54

飞机大战游戏思路及问题总结的相关文章

基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(下)

在飞机大战游戏开发中遇到的问题和解决方法: 1.在添加菜单时,我要添加一个有背景的菜单,需要在菜单pMenu中添加一个图片精灵,结果编译过了但是运行出错,如下图: 查了很多资料,调试了很长时间,整个人都要崩溃了. 最后发现引擎中CCMenu::itemForTouch函数中有遍历子节点的行为,但是循环中没有判断子节点类型是否为CCMenuItem.如图:码,这样一来,加入到pMenu中的图片精灵被当作菜单项取了出来使用,导致报错.老版本的果然又不完善的地方,整个人都不好了...果断修改引擎里的源

基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(中)

接<基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)> 三.代码分析 1.界面初始化 1 bool PlaneWarGame::init() 2 { 3 bool bRet = false; 4 do 5 { 6 CC_BREAK_IF(! CCLayer::init()); 7 8 _size = CCDirector::sharedDirector()->getWinSize(); 9 10 // 设置触摸可用 11 this->setIsTouchEnabled

基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)

最近接触过几个版本的cocos2dx,决定每个大变动的版本都尝试一下.本实例模仿微信5.0版本中的飞机大战游戏,如图: 一.工具 1.素材:飞机大战的素材(图片.声音等)来自于网络 2.引擎:cocos2d-1.0.1-x-0.9.2 3.环境:vs2010 二.使用的类 1.游戏菜单界面类:PlaneWarMenu——派生自CCLayer类. 1 // 游戏菜单界面类 2 class PlaneWarMenu: public CCLayer 3 { 4 public: 5 virtual bo

用Swift语言和Sprite Kit复制微信飞机大战游戏

先上GitHub链接: https://github.com/songrotek/PlaneWar.git 接下来稍微讲解一下! 这个程序还有点Bug,见谅! 1 说明 游戏采用了Sprite kit最新的Per pixel for physic 技术,就是直接使用texture纹理作为sprite的physics body . 游戏的texture.atlas从别的打飞机项目中拷之并辛苦地分解了. 游戏编写借鉴了网上的objc代码! 2 游戏编写过程 添加背景-> 添加控制的飞机-> 添加发

微信飞机大战游戏开发

原文出自:方杰|http://fangjie.sinaapp.com/?p=366转载请注明出处 这学期上了一学期的Windows游戏开发课程,学期末的时候所以决定做一个微信飞机大战的小游戏. 不同于微信手机上的飞机大战,这是一个Win32平台下游戏.Win32项目,VS2008开发平台,利用我的老师写的TinyEngine微型游戏引擎开发. TinyEngine引擎的相关源码及介绍参见:https://github.com/JayFang1993/TinyEngine 飞机大战游戏的相关源码参

web版canvas做飞机大战游戏 总结

唠唠:两天的时间跟着做了个飞机大战的游戏,感觉做游戏挺好的.说是用html5做,发现全都是js.说js里一切皆为对象,写的最多的还是函数,都是函数调用.对这两天的代码做个总结,希望路过的大神指点一下,我对这个游戏的思路,可改进优化的代码. 先说一下游戏的基本内容: 打飞机(不要想歪了),有鼠标控制移动英雄机,子弹自动射击:敌机从上而下,有三种敌机: 先说下HTML代码(主要就是这一行): <canvas id="canFly" width="480" heig

H5 canvas 实现飞机大战游戏

首先看几张效果图: 上面三张图分别对应游戏的三种状态 ready,play,pause.体验一下 先介绍一下canvas 画图的原理,在这个游戏中的背景,飞机,子弹以及飞机被击中爆炸的效果都是一张张的图片,通过canvas的 drawImage() 函数把这一帧需要的所有图片按其所在的位置(坐标)画到画布上,当然有时候也需要画些文本,比如左上角的得分:然后接着画下一帧,同时改变飞机和子弹的位置:画下一帧之前一定要清除画布(通过这个函数 clearRect(x,  y, width, height

cocos2d中分步实现飞机大战----游戏场景中背景的滚动

上一节说了场景的跳转,现在开始布置游戏游戏界面.在游戏的主界面,首先要有游戏背景,为了使GameScene的代码不至于太多,可以吧自己的背景进行封装,在GameScene中调用就好,飞机的正常飞行移动可以用北京的移动来实现.创建BackGround: background.h: #include "cocos2d.h" USING_NS_CC; class background:public Node{ public: CREATE_FUNC(background); bool ini

16 飞机大战:思路整理、重要代码

思路整理 重要代码 0.重写方法万万检查记得要不要继承父类方法 def __init__(self): super().__init__() 1.创建游戏时钟:用来设置游戏刷新率 # 新建游戏时钟对象 self.clock = pygame.time.Clock() ... ... # 设置游戏刷新率 self.clock.tick(60) #60帧/s 2.精灵组 # 创建xx精灵 self.xx = Xx() #其中Xx是Xx类 # 创建xx精灵组 self.xx_group = pygam