zoukankan      html  css  js  c++  java
  • 飞机大战游戏思路及问题总结


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

    一.思路


    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) 



  • 相关阅读:
    【ShardingSphere】ShardingSphere-JDBC 快速入门
    【Java】Java8新特性之重复注解与类型注解
    【Java】Java8新特性之时间和日期API
    【Java】Java8新特性之接口默认方法与静态方法
    【数据结构】堆
    【数据结构】二叉树
    JavaFx 创建快捷方式及设置开机启动
    【开源库推荐】#2 AndroidUtilCode Android常用工具类大全(附API使用说明)
    谈谈Android中的消息提示那些坑
    Android CheckBox控件去除图标 样式改造
  • 原文地址:https://www.cnblogs.com/sapho/p/4840510.html
Copyright © 2011-2022 走看看