• 浅谈cocos2d游戏中天气系统的简单实现


    一、前言

       此博客由一个新手游戏程序编写,没有高深的技术,基本是天气效果表现和代码设计的浅谈,如果有更好的实现方法,欢迎指正。

    二、背景

       该系统设计背景:2D游戏、正交45度表现地图、以及同一张地图上存在不同气候的区域/地形,需要体现不同天气效果以及不同天气的切换

       类似游戏:三国群英传(地图相似)、塞尔达传说-众神的三角力量(天气表现相似)、口袋妖怪绿宝石(天气表现相似)

    三、全局计算和局部表现

       额外系统:区域划分系统

       根据地图的设计,各个理论上会出现不同气候的地形均放在一张地图里面,因此在游戏中就需要有一个类似“气象台”的系统来控制不同区域的天气,然后根据玩家所在区域去“表现”当前区域的天气,该设计的目的就是为了节省cpu和内存。

       众所周知,天气的表现是会有不小的消耗的(2d游戏中,大量的雨滴粒子以及地面滴水表现;3d游戏中则是画面的渲染),直接全场景添加天气的效果明显不现实,所以采用全局计算天气的状态,再根据位置表现天气的方式去实现该系统

      1、全局计算

       “气象台”的实现需要引入另外一个系统:区域划分系统。该系统系统主要的作用有两点:1)根据玩家的位置得出当前所在区域。2)根据时间变化实施计算各个天气的状态

       第一点的实现,在此不展开讲,区域划分的方式因人而异,博主采用的方式就是把区域看成一个多边形去做,如果使用这种方法的话,区域判定提供两种方式:

        1)一定时间判断点与多边形的包含关系。

         这个可以去搜索“判断点是否在多边形内部”,然后定时去计算。

         参考:https://www.jianshu.com/p/ba03c600a557

         优点:空间上的精准;实现方式清晰,复杂度可以自己控制。缺点:频繁调用,时间上不够精准。

        2)物理框碰撞。

         这个方法是博主朋友提议的,并未实现。也是把区域看成一个多边形,不过这个多边形是一个物理框,玩家(也需要有物理框)进入和离开区域的时候去调用其碰撞函数,再去判定位置

         优点:时间上的精准;方法不用自己实现。缺点:空间上的准确度有待商榷;需要进一步优化需要学习底层代码。

       天气状态也是因人而异,不过最重要的就是“天气”和“天数”了。

      2、局部表现

       不管用什么方式得到当前区域的天气之后,就需要去表现天气。表现的方式就是在摄像机上,把粒子和效果添加到相机节点上(或者根据相机位置添加到地图上),具体的表现和实现在下一节讲述。

    四、天气表现效果

       天气系统的运作方式决定了之后,就是去设计天气的表现效果了。

       博主设计的天气目前有四种:小雨、烈日、沙暴和暴雨

      1、小雨和暴雨

       效果参考:

       

       该天气推荐使用cocos2d的粒子编辑器(Particle Builder)做。粒子编辑器可以用一张图片表现各种效果,如下面两张图,只需要调节参数就可以做出下雨特效

         

          

       下雨的时候可以在相机上再添加一个图片精灵(或者着色精灵)去实现变暗效果,通过修改颜色和透明度起到天变暗的效果,在暴雨天下,设置可以在几帧内瞬间改变亮度和颜色,起到打雷的表现效果

       根据我的理解,粒子编辑器只能针对一张图片做特效,而地面滴水需要一个动画表示,所以需要创建精灵节点去播放动画,实现方式下文再讲。下图是植物大战僵尸滴水特效:

       

       滴水精灵节点需要添加在地图节点上,如果添加在相机节点上的话,那么如果相机跟随人物移动的话,滴水还没消失就会移动会看上去很别扭。

       滴水效果添加是很有必要的,博主表达能力不强,所以只能用“感觉上没滴水的雨很别扭”这句话去形容。

         最终效果:

               

      2、沙暴

        

        看到图应该就能理解了,目前实现方式为一张图片循环移动。

      3、烈日

        烈日实现的效果目前参考口袋妖怪绿宝石的烈日的效果,在之前下雨的着色精灵把透明度调高,改变颜色实现(和雨天的闪电闪屏效果类似),不过效果并不是很好……

        

    五、技术点(代码和数值设计的原因)

      1、所有天气精灵独立

        各个表现天气的精灵都需要独立,目的是防止在“切换”表现天气时出现冲突。人物从一个区域走到另外一个区域的时候,天气系统需要做的事是:原区域天气逐渐消失,现区域天气逐渐出现,如果所有精灵(或者个别精灵)共用一个节点的话,那么“新”的天气精灵会覆盖之前的天气精灵,导致原区域天气瞬间消失。

        
            def __init__(self):
                # 雨天精灵
                self.RainSprite = None
                # 沙暴精灵
                self.SandStormSprite = None
                # 暴雨精灵
                self.RainStormSprite = None    
    View Code

      2、区域划分的时候需要有过渡区

        说简单一点就是划分区域的时候,把边缘部分再划分一个区域。其目的是防止不同区域刷出完全对立的天气导致的不合理,比如说沙漠目前处于烈日状态,而沙漠外的草原在下暴雨,如果没有做过渡区,会出现“烈日渐渐消失,暴雨渐渐出现”的天气切换效果,虽然是渐变效果,但还是出现了烈日和暴雨同时出现的画面,非常不合理。

      3、滴水效果实现方法

        前文讲了,滴水效果是动画效果,不能用粒子编辑器来做。所以博主的实现方式是:在初始化天气的时候,直接创建一堆精灵(比如暴雨天,地面上需要有300个滴水效果),每帧(时间间隔可以改)去播放动画,在播放动画之前把精灵移动到摄像机视野范围内。当前区域天气的表现结束的时候,也不要销毁精灵, 而是继续保留,其目的是防止频繁的创建精灵导致的消耗,水滴精灵的内存占用和地图相比,通常只占了很小一部分,权衡之下,可以用空间去换时间。

    六、后记

        因为博主个人原因,代码不愿意公开,所以本篇博文不过是个技术总结罢了。

        总而言之,天气系统在游戏中不是一个很难实现的系统,不过在实际编写代码的过程中还是会遇到很多问题。

        天气系统的主要难点只有两个,一是各种渐变效果,二是天气的表现效果,没有很硬核的技术。

        最后感谢您看到这里,如果有好的想法和建议,欢迎留言~

        

  • 相关阅读:
    20180925-3 效能分析
    20180925-7 规格说明书-吉林市2日游
    20180918博客作业
    第二周例行报告
    2018091-2博客作业
    容器(list集合)
    给应届生们的建议(一定要看哦)!
    MySQL 和 JDBC(Java数据库连接)
    Oracle常用数据库对象(片段)
    7353. 【2021.11.06NOIP提高A组模拟】qaq (qaq)
  • 原文地址:https://www.cnblogs.com/end-emptiness/p/11412681.html
Copyright © 2020-2023  润新知