【唠叨】

今天结束了本学期任务最为艰巨的项目实训课程,由于项目组里其他成员基本都已经找到实习了,然后他们都去实习了。只留下我和一个小伙伴在一起搞项目实训的小游戏。经过一个月与小伙伴的配合开发,做了一个勉强可以玩的一个小游戏demo,因为平时其他课程也比较繁重,所以游戏做得非常烂~(>_

我们本来打算做一款类似COC、海盗奇兵、口袋侏罗纪、城堡争霸的城战类的单机Demo。结果……哎说多了都是泪啊,经验不足,吸取教训了。

【经验教训】

由于时间比较紧张,加上自身也没有大项目开发的经验,所以一开始没有太重视去考虑游戏整体架构的问题,都是写一点算一点,从而在开发到一半,发现很多代码没有做到复用,而是一直复制张贴的。然后后期也没有时间去重构,结果导致代码写得比较凌乱不堪。

【收获】

虽然做的效果没有达到预期,但是还是从项目实训中有非常多的收获的。

1、再一次学习了一遍C++,对C++有了更深入的了解。

2、提前学习了各种文件读取解析的方式:JSON、XML、CSV、Sqlite。(最后我们采用了CSV来存储静态数据,用Sqlite来存储玩家数据)。

3、掌握了游戏开发的一些基本流程。

4、学习和掌握了cocos2d-x游戏引擎,cocos studio界面编辑器。

5、掌握了观察者模式、委托模式的运用。

6、学习了游戏的自动寻路的A*算法。

【项目Demo】

代码写的比较烂,但是我依然又放到了guthub上,只是为了想要存储我写的每一份代码。

因为放在本地硬盘,需要占存储空间的。~~~~(>_

【成果演示】

做得挺烂的,大家看了不要喷。。。

素材均来自《城堡争霸》,本游戏只做学习研究,切勿商用,以免侵权。。。

游戏概述:

1、玩家城池:可以移动设施、升级设施、新建设施、管理士兵、管理英雄。

2、关卡战斗:可以派出士兵自动寻路***,可以控制英雄移动,***指定建筑,释放技能。

3、战略地图通过迷雾遮罩,升级雷达,可以扩大地图的可视范围。

【开发环境】

Cocos2d-x 3.4

Cocos Studio 1.6.0 (UI编辑器、动画编辑器)

【一些重要的收获】

1、分辨率适配问题

由于地图比较大,可以通过拖动来显示地图的其他区域部分,所以分辨率的适配比较简单。只要宽度或高度适配即可。

2、地图的移动与缩放

根据手指触摸的数量,来判断是移动还是缩放。

> 一根手指:移动地图,实现比较简单。

> 两根或多根手指:看做两根手指,缩放地图。需要通过一定的公式来计算,缩放前和缩放后的坐标转换。(具体参见上述文章)。

对于手指滑动后,地图又具有惯性地减速移动:可以根据手指滑动的速度快慢,计算出一个加速度(其实可以通过触摸事件onTouchMoved中Touch的getDelta()函数获得),然后通过在update函数中进行减速计算。

缩放的前后坐标计算,如下图所示:

3、玩家城池中,建筑的坐标定位

由于城池中采用的是斜45°的2.5D视角,所以需要进行坐标的转换操作。

先将城池地图进行瓦片分割,分成一块一块区域。如下所示,其实可以看到地图是一个个小方块组成的。

4、关于建筑的触摸移动

当建筑需要移动它的位置的时候,需要屏蔽地图层的移动和缩放,不然你回发现你的建筑和地图都在移动!!!

做法是:触摸到建筑,进行移动时,其实cocos已经有了触摸吞噬的函数

listener->setSwallowTouches(true);即可。

当然还有一种比较好的做法是:定义一个专门处理触摸事件的触摸层,来管理场景中所有元素的触摸事件,并按照触摸的优先级进行排序,然后再按照优先级进行分发触摸响应事件(因为一般触摸只会有一个事件作出响应,也就是说每次的触摸只会有一个元素执行了触摸事件)。

5、关于设施升级、时间点触发某事件等一系列的响应事件

在设施进行升级、或者当到大某一时间点时,可能需要触发一些任务响应事件。可以通过委托模式来处理,即在做某一事件时,给该事件委托一个函数(可以通过函数指针来实现)。然后当某一事件完成后,调用该委托函数(可以不指定为某一特定的函数,而是通过函数指针的形式来调用)。

另一种做法是:通过观察者模式,即一个事件对某一消息进行订阅,然后另一个事件在执行完后,发布该消息,然后第一个事件就接受到了消息,执行相应的处理函数。

例如:士兵***建筑时,士兵执行完***动作,然后建筑需要作出“扣血”这一事件。就可以通过委托函数来完成,即实现不知道需要执行哪个建筑的“扣血”事件。而是通过函数指针来调用对应士兵所***的那个建筑的“扣血”事件处理函数。

6、对于游戏中时间控制的问题

因为是一个城战类的游戏,所以设施的升级是需要一定的时间的,比如升级需要10分钟。还有采矿场每分钟可以生产10个金币等等,都是需要用到“时间”。

做法是:拿设施的升级操作举例,在点击对设施进行升级时,可以记录一个升级时的“时间戳”,并存储到数据库的该设施的一个字段中,然后再游戏进行的过程中,只要不断获取当前时间的“时间戳”,然后减去之前记录的点击升级时的“时间戳”。差值即为从升级到目前过去了多少时间,然后就可以做一些列的操作了。

关于如何获取时间戳,参见:// 获取时间戳

int GlobalManager::getTimeStamp()

{

timeval tm;

gettimeofday(&tm, NULL);

return tm.tv_sec; // 返回当前时间对应的时间戳,单位:秒

}

7、战斗界面的AI(自动寻路、自动***)

我的做法比较简单,使用状态机:移动、***、闲置、已阵亡。然后每隔0.5秒执行一次状态转换的操作。

首先将地图分成一块一块,然后用二维bool矩阵来标记障碍物,然后控制士兵、英雄的移动。

> 对于士兵:设置定时器,每隔0.5秒执行一次动作。若士兵还未锁定***目标,则遍历设施,找到最近的设施作为目标。若士兵锁定了***目标,则可以通过A*算法检测上下左右、左上、右上、左下、右下八个方向的瓦片格子中,是空地,并且里目标建筑最近的,就将士兵往那个格子移动(至于距离:可以通过h函数来估计,我采用的是估计函数:曼哈顿距离,即x坐标之差的绝对值 + y坐标之差的绝对值),这样士兵可以自动绕过障碍物。若目标设施在士兵的可***范围内,则对设施进行***。

我为什么要尝试每隔一定时间,检测士兵的八个方向,离目标最近,然后移动过去呢?是因为如果士兵锁定了目标后,然后执行完整的A*算法,计算出完整的移动路径,这样的操作是非常耗时的。对于很多个士兵同时执行完整的A*算法进行寻路,可能就会出现卡顿的现象。而我的做法正好避免了这样的问题,将A*算法的每一步操作都均摊到每个0.5秒的时间。

> 对于英雄:通过触摸来控制移动,和***某一目标。触摸地图某一位置,英雄移动的操作与士兵的自动寻路和自动***思路类似。

> 对于可***型建筑:设施定时器,每个0.5秒执行一次。遍历我方士兵、英雄。若有士兵在建筑的可***范围内,则***我方。

8、头文件的管理

由于类和类之间不是独立存在的,必然会有头文件的相互引用问题,所以我就额外将所有的类的头文件都放到一个public.h文件中,那么其他类只要引用"public.h"头文件即可,而不需要考虑需要引用哪些哪些头文件。

然后在 public.h文件开头加上文件预编译指令:这样就可以保证头文件不会被多次编译。#ifndef __Public_H__

#define __Public_H__

#endif

9、全局变量的管理

也是当独放到一个头文件中进行管理的:包含了图片资源的路径、一些全局变量、数据文件的路径等。

10、CocosStudio的使用

本游戏用的时Cocos Studio 1.6.0版本。其实这个版本是已经非常强大了,不仅可以做界面UI,而已可以制作角色动画。

使用方法:到官网学习。

11、数据的管理

写了一个专门管理游戏数据的单例类DataManager。用于数据的加载、获取、更新等操作。

对于表现层和控制层有哪些数据修改的请求操作,都通过DataManager进行管理,然后再重新绘制游戏的UI。

12、一些全局的辅助函数的管理

也是用了一个GlobalManager单例类来进行管理。提供游戏中的相关的辅助函数。

如:获取最大最小值、地图坐标与瓦片坐标的转换、判断一个点是否落在多边形内、获取时间戳、×××数据和字符串数据的转换、场景的切换管理等功能。

【遇到的问题】

1、瓦片坐标与地图坐标的转换

计算相应的转换公式。

2、两头文件相互引用

需要在类之前,对另一个类做类的声明。

3、野指针问题

当两个建筑都锁定同一个士兵后,第一个建筑执行完***动画,然后让该士兵作出扣血事件,正好士兵血没了,就要从图层中移除。可是呢?第二个建筑也锁定了该目标啊,执行玩***动画后,调用该士兵的扣血事件,出现了异常。因为该士兵已被释放。。。

解决方案:

(1)一直保留士兵,阵亡后,不从图层中移除,而是将士兵隐藏。

(2)延迟士兵的移除操作。由于建筑是每个0.5秒寻找一次目标,然后对其进行***。那么我们只要在士兵阵亡后,用一个变量isDeath来标记士兵是否阵亡,然后建筑在遍历士兵时,跳过isDeath=true的士兵,那么建筑在下一个0.5秒就不会再指向该士兵。那么士兵只要在阵亡后,标记isDeath=true,然后延迟1秒钟后,调用remove()函数从图层中移除,就不会出现野指针异常的问题。

(3)同样也可以通过观察者模式,建筑对士兵的阵亡消息进行订阅,然后当士兵阵亡后,发布阵亡消息。建筑在接收到阵亡消息后,将锁定的目标target指针置为空NULL,即可。

4、中文乱码问题

使用UTF-8即可。

5、游戏AI问题

学习了A*算法。

6、还有其他一些小问题,已忘………………

cocos 时间函数需要什么引用_Cocos实战篇[3.4]——仿COC的一个小Demo总结相关推荐

  1. cocos 时间函数需要什么引用_Cocos Creator两个类相互引用(调用)

    如果两个类相互引用,脚本加载阶段就会出现循环引用,循环引用将导致脚本加载出错: ///Game.js var Item = require("Item"); var Game = ...

  2. cocos 时间函数需要什么引用_2021国家公务员考试时间是什么时候 国考备考时间需要多久...

    今日小编推荐 行测知识点那么多,有重点,不乱了! 申论考查面那么广,有范围,不愁了! 4月6日19点,中公院长帮你划重点&标范围 免费听课:http://19.offcn.com/class- ...

  3. cocos 时间函数需要什么引用_与时间赛跑:微盟的数据恢复为什么需要这么长时间...

    作者| 茹炳晟 责编 | Carol 出品| CSDN云计算(ID:CSDNcloud) 微盟"删库跑路"事件已经过去好几天了,据悉,微盟的服务已经全部恢复,对于新用户,已经能够正 ...

  4. cocos 时间函数需要什么引用_酱香型白酒,为什么需要长时间储存?

    优质酱香型白酒,需要长时间储存的主要原因有以下四个: 原因一:去除有害物质 优质酱香酒的制曲,堆积,发酵工艺都是在高温条件下进行(俗称三高工艺),产生的高沸点的生香型酸类物质较多,且不易挥发.但不可避 ...

  5. Vue实战篇二十九:模拟一个简易留言板

    系列文章目录 Vue基础篇一:编写第一个Vue程序 Vue基础篇二:Vue组件的核心概念 Vue基础篇三:Vue的计算属性与侦听器 Vue基础篇四:Vue的生命周期(秒杀案例实战) Vue基础篇五:V ...

  6. 仿百度html页面,HTML实战篇:html仿百度首页

    原标题:HTML实战篇:html仿百度首页 本篇文章主要给大家介绍一下如何使用html+css来制作百度首页页面. 1)制作页面所用的知识点 我们首先来分析一下百度首页的页面效果图 百度首页由头部的一 ...

  7. c语言生成16进制随机数,C语言实战篇——模拟ATM取款机,最强大脑小游戏,进制转换,产生不同的随机数...

    2019.11.24 模拟ATM取款机 如图为登录界面 银行.png #include int main(){ printf("----------------------------\n& ...

  8. Vue实战篇二十八:实现一个手机版的购物车

    系列文章目录 Vue基础篇一:编写第一个Vue程序 Vue基础篇二:Vue组件的核心概念 Vue基础篇三:Vue的计算属性与侦听器 Vue基础篇四:Vue的生命周期(秒杀案例实战) Vue基础篇五:V ...

  9. vue仿今日头条_Vue实战篇(Vue仿今日头条)

    前言 vue也弄了一段时间了, 前段时间一直想用vue写个移动端,加之年底也不是很忙,于是前几天便着手开始弄了,到今天为止也算是勉强能看了 因为也是纯粹的写写前端页面,所以数据方面用的是mock.js ...

最新文章

  1. 深入理解Python闭包概念
  2. AI部署前路坎坷,50%项目半路夭折
  3. BZOJ4810: [Ynoi2017]由乃的玉米田
  4. excel两个表格数据对比_Excel小技巧:实例教你快速对比多个表格的差异
  5. C语言字符串中最后一个单词的长度的算法(附完整源码)
  6. C# 查询一张表的数据用于补充另外一张表的数据 MySQL数据库
  7. myeclipse中如何在整个工程中搜索字符串
  8. linux命令之awk终极系列
  9. Linux kernel 内核升级与降级实战
  10. 微信云控开发SDK使用教程--手机回传朋友圈点赞数量通知服务端
  11. Windows 编程[6] - 学习窗体生成的过程六: 最终的代码!
  12. 关于空间计量模型中自回归系数大于1的解释
  13. novatel计算odom--GPS坐标与UTM坐标转换
  14. Jira开发实践、ScriptRunner插件开发总结
  15. [Win32]路径操作API函数
  16. 【Autosar】学习总结-MCAL
  17. 怎么抠图图片?抠图图片这样做就可以完成
  18. 动态分区最佳适应算法c语言,使用最佳适应算法对内存实现模拟动态分区管理...
  19. 100m光纤测速多少正常_终于知道为什么我的百兆宽带测速只有一半了
  20. 知识付费这么红,它会成为KFC吗?

热门文章

  1. Sqoop 各大命令解释
  2. icon font 网站推荐
  3. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【十】——使用CacheCow和ETag缓存资源...
  4. SPI W25Q128驱动
  5. linux怎么用启动u盘恢复系统,一种U盘引导下的linux系统备份还原方法与流程
  6. 小泼猴案例操作问题以及解决方法1
  7. 从中专生到腾讯程序员,深圳男孩实力演绎逆风翻盘
  8. 设置浏览器不显示图片
  9. Java 端口号的取值范围是怎样的?
  10. NO.A.0011——day05——数组的-索引/内存/遍历/最大值获取/反转/作为方法参数和返回值...