关于在cocos2dx中继承Sprite的分析与技巧
(转载请注明原文:http://blog.csdn.net/while0/article/details/25615685)
本文章特指使用C++作为编程语言。基于cocos2dx游戏引擎开发游戏。
在cocos2dx中,sprite作为精灵类是使用最为频繁的类,与其他类相比。如:Node, Layer或Scene。Sprite最大的不同是它包括一个纹理。通过OpenGL的渲染。在游戏中呈现出来。
游戏中的主角。怪物,背景,或是精灵的血条等都是通过Sprite来实现的。
在cocos2dx中,关于创建Sprite的类,依据输入參数的不同有下面几个工厂函数。
static Sprite* create()
static Sprite* create(const std::string& filename)
static Sprite* create(const std::string& filename, const Rect& rect)
static Sprite* createWithTexture(Texture2D *texture)
static Sprite* createWithTexture(Texture2D *texture, const Rect& rect, bool rotated=false)
static Sprite* createWithSpriteFrame(SpriteFrame *spriteFrame)
static Sprite* createWithSpriteFrameName(const std::string& spriteFrameName)
顺便提醒,工厂函数中Sprite的实例都调用了autorelease(),所以由工厂函数返回的实例一般马上通过addChild到增加到父节点中,这样它的引用计数加一,表示有人在使用这个实例,这个实例不能被释放。
当然。假设你不想马上增加到父节点中,也能够调用retain()函数直接对其引用计数加1,不然在主循环的下一次,就会将其回收,这是cocos2dx内存自己主动回收的机制决定的。
在游戏的开发过程中,使用Sprite最频繁的编码就是三部曲 (1)创建Sprite (2)增加layer中 (3)设置精灵位置:
Sprite *sprite = Sprite::create("hero.png");
this->addChild(sprite);
sprite->setPosition(Point(100, 200));
第一行创建Sprite的实例,也就是创建了一个类Sprite的对象,这个是在工厂函数中实现的。
Sprite *sprite = new Sprite();
if (sprite && sprite->initWithFile(filename))
{
sprite->autorelease();
return sprite;
}
CC_SAFE_DELETE(sprite);
return nullptr;
我们重点关注第一句:
Sprite *sprite = new Sprite();
它决定了工厂函数创建的实例是Sprite类型,所以当在编码中调用Sprite的虚函数时,调用的就是Sprite类中的对应函数。
可能你会有这样一个问题:假设我想重载一个虚函数,在这个函数中实现自己须要的一些特殊行为,该怎么做?
答案是:必须继承Sprite创建一个你自己精灵类,在类中重载这个虚函数,这样还不够,必须定义这个新的继承类的工厂函数,在这个工厂函数中创建这个类的对象,
class MySprite : public Sprite
{
static MySprite * create(const char *pszFileName);
} MySprite * MySprite ::create(const char *filename)
{
MySprite *sprite = new MySprite();
if (sprite && sprite->initWithFile(filename))
{
sprite->autorelease(); return sprite;
}
CC_SAFE_DELETE(sprite);
return nullptr;
}
在程序中使用MySprite的代码与Sprite类似。
MySprite *sprite = MySprite::create("hero.png");
this->addChild(sprite);
sprite->setPosition(Point(100, 200));
假设输入參数不同。能够參考Sprite类的实现。创建不同输入參数的工厂函数。
所以,依照眼下cocos2dx的设计,在Sprite的继承类中,必须又一次实现新类的工厂函数,在工厂函数中创建新类的实例。这样新类中重载的虚函数就会被调用到。
使用C++编程,常常须要继承Sprite来定制和封装游戏特定的精灵。
有时候可能须要在Sprite的基础上进行多次继承,来达到类重用的目的。
本文以下提供两种方法,提供给读者參考。
在这两种方法中,不须要在继承类中又一次实现工厂函数。
- 在工厂函数中,实例作为输入參数传入
MySprite * MySprite ::create(Sprite* sprite, const char *filename)
{
if (sprite && sprite->initWithFile(filename))
{
sprite->autorelease();
return sprite;
}
CC_SAFE_DELETE(sprite);
return nullptr;
}
调用MySprite的代码:
MySprite *sprite = new MySprite();
MySprite::create(sprite, "hero.png");
this->addChild(sprite);
sprite->setPosition(Point(100, 200));
在MySprite的基础上再做继承时,就不须要实现工厂函数了。
比如:从MySprite继承新类MySprite2:
class MySprite2 : public MySprite
{
...
}
调用MySprite2的代码:
MySprite2 *sprite = new MySprite2();
MySprite::create(sprite, "hero.png");
this->addChild(sprite);
sprite->setPosition(Point(100, 200));
2. 创建newInstance的虚函数
另外一种方法,我们能够通过虚函数newInstance()来避免反复创建工厂函数。
在newInstance中创建新类的对象。
class MySprite : public Sprite
{
static MySprite * create(const char *filename);
virtual Sprite* newInstance();
}
Sprite* MySprite::newInstance()
{
return new MySprite();
} MySprite * MySprite ::create(const char *filename)
{
MySprite *sprite = newInstance();
if (sprite && sprite->initWithFile(filename))
{
sprite->autorelease(); return sprite;
}
CC_SAFE_DELETE(sprite);
return nullptr;
}
调用MySprite的代码:
MySprite::create("hero.png");
this->addChild(sprite);
sprite->setPosition(Point(100, 200));
另外一种方法的优点是在使用MySprite时与Sprite的全然同样,但须要在继承类中实现虚函数newInstance()。
本文抛砖引玉,在您的实现过程中或许会有更好的方法,欢迎讨论,共同进步。
关于在cocos2dx中继承Sprite的分析与技巧的更多相关文章
- Cocos2d-x中由sprite来驱动Box2D的body运动(用来制作平台游戏中多变的机关)
好久都没写文章了,就来一篇吧.这种方法是在制作<胖鸟大冒险>时用到的.<胖鸟大冒险>中使用Box2D来进行物理模拟和碰撞检測,因此对每一个机关须要创建一个b2body.然后&l ...
- cocos2dx lua中继承与覆盖C++方法
cocos2dx的extern.lua中的class方法为lua扩展了面向对象的功能,这使我们在开发中可以方便的继承原生类 但是用function返回对象的方法来继承C++类是没有super字段的,这 ...
- 2018.3.3 多线程中继承Thread 和实现Runnable接口 的比较(通过售票案例来分析)
多线程中继承Thread 和实现Runnable接口 的比较(通过售票案例来分析) 通过Thread来实现 Test.java package com.lanqiao.demo4; public cl ...
- cocos2d-x中绘制3D图形--3D ToolKit for cocos2dx实现原理
首先:了解具体情况请看这里:https://github.com/wantnon2/3DToolKit-for-cocos2dx 在看代码之前,最好还是先把项目git下来执行一下demoproject ...
- cocos2d-x 中的基本概念
在 cocos2d-x 开头配置(Windows 平台)中,介绍了新建工程,这篇就介绍下 cocos2d-x 的一些概念.(前提是需要有C++的面向对象的基本知识和C++11的常用知识) 层,场景,导 ...
- cocos2d-x中的Box2D物理引擎
在Cocos2d-x中集成了2个物理引擎,一个是Chipmunk,一个是Box2D.前者是用C语言编写的,文档和例子相对较少:Box2D是用C++写的,并且有比较完善的文档和资料.所以在需要使用物理引 ...
- cocos2dx Scene,Layer,Sprite的理解
layer,scene,sprite的默认锚点都是0.5,0.5 三者都继承自Node节点,暂时没看出有什么区别,或者下面的话是对的吧. 在cocos2d-x中,一个应用可以有多个scene,但任何时 ...
- 3 cocos2dx 3.0 源码分析-mainLoop详细
简述: 我靠上面图是不是太大了, 有点看不清了. 总结一下过程: 之前说过的appController 之后经过了若干初始化, 最后调用了displayLinker 的定时调用, 这里调用了函数 ...
- cocos2dx中的内存管理方式
转载:http://www.cocoachina.com/bbs/read.php?tid=195219 今天看了一下cocos2dx的内存管理机制,有些地方不太好理解搞了挺长的时间,现在感觉自己理解 ...
随机推荐
- JS学习之事件冒泡
(1)什么是事件起泡 首先你要明白一点,当一个事件发生的时候,该事件总是有一个事件源,即引发这个事件的对象,一个事件不能凭空产生,这就是事件的发生. 当事件发生后,这个事件就要开始传播.为什 ...
- dubbo架构演变之路
背景 (#) 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 单一应用架构 当网站流量很小时, ...
- input file 模拟
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- codeforcese 498C. Array and Operations 网络流
题目链接 给n个数, m个数对, 每个数对是两个下标加起来为奇数的两个数.每次操作可以使一个数对中的两个数同时除某个数, 除的这个数是这两个数的任意约数, 问这种操作最多可以做几次.n<100, ...
- poj 3304 计算几何
大意: 是否存在一条直线,使所有线段在直线上的投影至少交与一点 思路: 转换为是否存在一条直线与所有的线段相交,做这条直线的垂线,那么垂线即为所求 **/ #include <iostream& ...
- web 性能优化指南阅读笔记
1.关于拥塞预防算法 PRR-比例降速,RFC6937 规定的一个新算法,其目标是改进丢包后的恢复速度,谷歌测量结果:该算法改进丢包造成的平均连接延迟减少了3%-10%.PRR是linux 3.2+内 ...
- NuGet安装软件包故障解决
今晚在家工作,使用NuGet安装 Install-Package Microsoft.AspNet.Web.Optimization 时,一直提示无法连接到nuget.org. 搜索后,可使用如下方法 ...
- ArcSde for Oracle服务注册
1.首先安装ArcSde,安装完成之后在dos命令窗口运行如下命令: sdeservice -o create -d oracle,instance -p sde -i port; 参数说明: ins ...
- CI 模板解析器类
模板解析器类可以解析你的视图文件中的伪变量.它可以解析简单的变量或者以变量作为标签的结构.如果你以前没有用过模板引擎,那么伪变量如下所示: <html><head><ti ...
- Java算法——O(n)查询数列中出现超过半数的元素
主要思想: 相邻元素两两比较,如果相同存入新数组,不同二者都删除.如果 某数出现次数超高n/2,则最后剩下的1元素为所求. public static int findMostElem(final A ...