代码小记 刺骨的言语ヽ痛彻心扉 2021-11-09 01:42 439阅读 0赞 0. 引子 前一阵子一直在制作一款小[游戏][Link 1],虽说最终的成果并不完美,但也算是花了不少精力,网上批评的声音不少,但更多的则是鼓励,这也让我们颇感欣慰,自省之余,也算拾得一些信心,总之一句话,继续奋力前行~ :) 游戏大概是个有些“另类”的音乐游戏,基本玩法仍属传统,画面则偏中国风,相对另类一些,不过其中最另类的,当算是每个场景中都会出现的池塘,以及池塘中那群“活蹦乱跳”的小鱼儿~ 就池塘这个意像来讲,在很多的仿池塘游戏(应用)中都有,可以说是稀松平常,但是将其运用在音乐游戏中,恐怕就很少很少了(我怀疑是没有的:)),我想曾经尝试过这个游戏的朋友想必都会对其中的池塘有所注意,犹有甚者,不少朋友还对池塘中小鱼的程序实现方式颇有兴趣~ 想来自己也确实应该花些时间总结整理一下之前项目中的代码,而其中关于小鱼的实现也算是待整理代码中比较重要的一个部分,既然有童鞋对此好奇,那么索性在此将其开源,总结复习之余,也给有兴趣的朋友一些参考 :) 1. 原理 就基本原理而言,小鱼的实现其实非常简单,就是将原本“整片”的精灵(Sprite)“分块”,然后通过一定的规律控制这些分块节点的运动,继而影响精灵的整体显示,产生诸如游动之类的运动方式,就这么简单 :)某种角度上来讲,确实有点像骨骼动画,只是比较特殊简陋罢了。之前制作时也曾尝试过逐帧动画之类的方法,但是结果都不尽人意,几番尝试下来还是采用了目前的方法,虽说稍稍复杂了些,但就结果来看还是值得的(如下图所示,黄点像素便是分割所得的节点) :) ![20130809234441531][] 3. 代码 好了,不多扯了,让我们马上来看看代码: 首先是最重要的FlagellumSprite: /\*! \\file FlagellumSprite.h \\brief flagellum like sprite, comprise of several nodes \*/ \#ifndef \_\_FLAGELLUM\_SPRITE\_H\_\_ \#define \_\_FLAGELLUM\_SPRITE\_H\_\_ \#include <vector> \#include <map> \#include "cocos2d.h" USING\_NS\_CC; class FlagellumSpriteModifier; class FlagellumSprite: public Node \{ public: /\*! create with texture file \\param filename texture filename \\param nodeCount sprite node count (default is 8) \\return FlagellumSprite pointer (autoreleased) \*/ static FlagellumSprite\* create(const char\* filename, size\_t nodeCount = 8); /\*! create with texture object \\param texture texture object \\param nodeCount sprite node count (default is 8) \\return FlagellumSprite pointer (autoreleased) \*/ static FlagellumSprite\* create(Texture2D\* texture, size\_t nodeCount = 8); //! constructor for initialize FlagellumSprite():m\_texture(NULL),m\_vertices(NULL),m\_texCoords(NULL),m\_debug(false) \{\} //! destructor for releasing virtual ~FlagellumSprite(); /\*! init with texture method \\param texture texture object \\param nodeCount sprite node count (default is 8) \\return true if success, otherwise false \*/ bool initWithTexture(Texture2D\* texture, size\_t nodesCount = 8); //! reset method //void reset(); //! update method //virtual void update(float frameTime); //! draw method virtual void draw() override; /\*! set node count \\param nodeCount sprite node count \*/ void setNodeCount(size\_t nodeCount); /\*! get node count \\return sprite node count \*/ size\_t getNodeCount() const \{ return m\_nodes.size(); \} /\*! set texture \\param texture texture ref \*/ void setTexture(Texture2D\* texture); /\*! get texture \\return texture ref \*/ Texture2D\* getTexture() const \{ return m\_texture; \} /\*! set debug flag \\param debug debug boolean \*/ void setDebug(bool debug) \{ m\_debug = debug; \} /\*! get debug flag \\return debug boolean \*/ bool getDebug() const \{ return m\_debug; \} /\*! add sprite modifier \\param modifier sprite modifier to add \\param priority modifier priority (default is 0) \*/ bool addModifier(FlagellumSpriteModifier\* modifier, int priority = 0); /\*! remove sprite modifier \\param modifier sprite modifier to remove \*/ bool removeModifier(FlagellumSpriteModifier\* modifier); /\*! clear all modifiers \*/ void clearModifiers(); /\*! update modifier \\note you have to call this every update \*/ void updateModifiers(); private: // implement details here \}; \#endif // \_\_FLAGELLUM\_SPRITE\_H\_\_ FlagellumSprite的作用便是将原本整体的精灵分割为指定的区块并负责正确显示他们,以上代码罗列了FlagellumSprite的头文件,其中的create、setTexture、setNodeCount等方法都是比较传统的函数,作用也比较明确,需要细讲一下的可能还是关于FlagellumSpriteModifier的那几个接口方法。 讲述之前,让我们先来看看FlagellumSpriteModifier: /\*! \\file FlagellumSpriteModifier.h \\brief base class of flagellum sprite modifier \*/ \#ifndef \_\_FLAGELLUM\_SPRITE\_MODIFIER\_H\_\_ \#define \_\_FLAGELLUM\_SPRITE\_MODIFIER\_H\_\_ \#include <vector> \#include "cocos2d.h" USING\_NS\_CC; class FlagellumSpriteModifier: public Object \{ public: /\*! pre modify callback interface \\param points points vector as in and out param \*/ virtual void preModify(std::vector<Point>& points) = 0; /\*! modify callback interface \\param points points vector as in and out param \*/ virtual void onModify(std::vector<Point>& points) = 0; /\*! post modify callback interface \\param points points vector as in and out param \*/ virtual void postModify(std::vector<Point>& points) = 0; \}; \#endif // \_\_FLAGELLUM\_SPRITE\_MODIFIER\_H\_\_ 可以看到,FlagellumSpriteModifier仅是一个简单的基类型,约束的几个方法分别是preModify、onModify和postModify。如前所述,FlagellumSprite用以分割精灵并加以显示,但是其并不负责分割后所得节点的运动逻辑,也就是说,如果我们仅仅创建一个FlagellumSprite,所得结果和创建一个Sprite并无二致,所有进一步的FlagellumSprite“运动”都需要FlagellumSpriteModifier来帮忙,而FlagellumSpriteModifier的preModify、onModify和postModify便是用来完成这些“运动”;而FlagellumSprite为了配合FlagellumSpriteModifier,自然需要提供必要的支持接口,而这些接口也便是上面我们所见但仍未有讨论的接口,他们分别是: addModifier : 向FlagellumSprite添加一个FlagellumSpriteModifier removeModifier : 从FlagellumSprite移除一个FlagellumSpriteModifier clearModifiers : 删除FlagellumSprite中所有FlagellumSpriteModifier updateModifiers : 更新FlagellumSprite中所有FlagellumSpriteModifier 使用上,FlagellumSprite同普通的Node并无二致,大抵上便是这个样子: // create flagellum sprite FlagellumSprite\* fish = FlagellumSprite::create("fish.png"); if (fish) \{ fish->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); fish->setRotation(-90); fish->setAnchorPoint(Point(0.5f, 0.5f)); fish->setScale(1.5f); fish->setDebug(true); /\* \{ FlagellumSpriteModifier\* modifier = new FlagellumSpriteModifierShrink(); modifier->autorelease(); arraw->addModifier(modifier); \} \*/ \{ FlagellumSpriteModifier\* modifier = new FlagellumSpriteModifierSine(); modifier->autorelease(); fish->addModifier(modifier); \} fish->setTag(1); addChild(fish, 1); \} 要讲的就是这么多了,有兴趣的朋友可以[在此][Link 2]取一份代码来看看(代码根据cocos2d-x-3.0版本进行了改写,并且运用了一点C++11的特性,在较老的版本中编译应该会有问题,注意一下),其中实现了两个简单的FlagellumSpriteModifier,感觉还有那么一点意思 :)当然,FlagellumSprite的想法并非我的独创,网上早已有了很多优秀的资源,[这里][Link 3]就有一个非常好的参考,有兴趣的朋友可以仔细看看 :) 最后放一张示例gif :) ![20130809234446515][] OK,that's it :) [Link 1]: https://itunes.apple.com/cn/app/sui-le-ji/id599936784?mt=8 [20130809234441531]: /images/20211108/4f809248af4047dab961e4b535d4b579.png [Link 2]: https://github.com/tkokof/GitTest/tree/master/Examples/FlagellumSprite [Link 3]: http://www.levitated.net/daily/levFlagellum.html [20130809234446515]: /images/20211108/be925e979c254524bf08039fcabde9f3.png
相关 Java小记 1. instanceof 关键字 instanceof是Java的一个二元操作符,和==,>,<是同一类东东。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是 缺乏、安全感/ 2022年09月18日 03:55/ 0 赞/ 142 阅读
相关 小记 大四开学,这段时间没有来记录自己的学习进度,真是遗憾,今天写代码,发现以前的基础知识都不会,这今天开始,遇到的问题要开始总结了. 前两天收到招聘邮件,待遇不错, 桃扇骨/ 2022年08月12日 01:14/ 0 赞/ 144 阅读
相关 小记 python中用numpy包读取文本时可以用np.loadtxt()函数 entity = np.loadtxt(open('C:\\Users\\chemprot_ Bertha 。/ 2022年06月05日 10:29/ 0 赞/ 211 阅读
相关 数学小记 近来看到的一个小小的数学问题,简单一记~ 问题 给定任一奇数a,求平方数b,使其与a的和等于另一平方数c 初一看该问题没想到直接的构造方法,首先使用穷举法来看下小范围 桃扇骨/ 2022年06月03日 04:57/ 0 赞/ 180 阅读
相关 元宵节小记 三坊七巷的灯会,面具和牛角,各式的灯笼,汹涌的人流,健硕挺拔的警卫。 ![3926053_1267454200sNrX.jpg][] ![3926053_126745419 灰太狼/ 2022年05月16日 09:22/ 0 赞/ 103 阅读
相关 返乡小记 <!-- \[if !mso\]> <mce:style><!-- v/:\ \{behavior:url(\default\VML);\} o/:\ \{behavior:u 小咪咪/ 2022年05月16日 09:20/ 0 赞/ 205 阅读
相关 实习小记 八月八号,一个多么吉利的日子,我开始了我的实习生活。实习公司和学校宿舍也就一个小时车程,不过,个人暂时还没有早起的习惯,所以,选择了住在公司,这样其实也挺好的,因为早上万一堵 本是古典 何须时尚/ 2022年04月23日 02:02/ 0 赞/ 192 阅读
相关 工作小记 在工作中遇到listview item 鼠标放上去后显示阴影的问题,使用mousemove 和mouseleave消息实现,经测试,发现:当连续响应mousemove消息时,m 拼搏现实的明天。/ 2022年04月10日 08:52/ 0 赞/ 272 阅读
相关 模拟小记 [【p1098】字符串展开][p1098] [【p1042】乒乓球][p1042] 做模拟的lz日渐崩溃; 请放一首“我要一步一步往上爬” ![1605606-2019 朱雀/ 2021年11月14日 11:10/ 0 赞/ 332 阅读
相关 代码小记 0. 引子 前一阵子一直在制作一款小[游戏][Link 1],虽说最终的成果并不完美,但也算是花了不少精力,网上批评的声音不少,但更多的则是鼓励,这也让我们颇感欣慰,自省 刺骨的言语ヽ痛彻心扉/ 2021年11月09日 01:42/ 0 赞/ 440 阅读
还没有评论,来说两句吧...