Cocos2d-x之Sprite
| 版权声明:本文为博主原创文章,未经博主允许不得转载。
Sprite是Cocos2d-x游戏开发者最常用的类,用图片把精灵(Sprite)显示在屏幕上。
在游戏开发中,经常会遇到精灵(Sprite)这个术语。精灵是一个图像,可以在屏幕上独立的移动,一个精灵可能是玩家角色,子弹,敌人或者是大的背景图片。一般情况下,精灵来自开发者所准备的PNG或PVRTC或JPG图像。一旦图像载入内存,就会将精灵转换成纹理图CCTexture,从而被CPU用于在屏幕上渲染;Cocos2d中的精灵和其他游戏引擎中的精灵相似,它可以移动,旋转,缩放,执行动画,并接受其他转换Cocos2dx的Sprite由Texure,frame和animation组成,由openes负责渲染。
主要的类关系如下: 简单过程可描述为:用Texture2D加载图片,可以用Texture2D生成对应的SpriteFrame(精灵帧),将SpriteFrame添加到Animation生成动画数据,用Animation生成Animate(就是最终的动画动作),最后用Sprite执行这个动作。创建精灵的几种方式:直接创建,纹理来创建精灵,精灵帧来创建精灵;
精灵类的主要公共函数:
精灵类的六种创建方法:
static Sprite* create(const char *pszFileName);
使用一个图片名称创建一个精灵,这种适用于静态的精灵创建,如添加背景 static Sprite* create(const char *pszFileName, const Rect& rect);
使用一个文件名称和一个矩形框创建一个精灵 static Sprite* createWithTexture(Texture2D *pTexture);
使用texture创建一个sprite,纹理创建 static Sprite* createWithTexture(Texture2D *pTexture, const Rect&& rect);
使用texture和一个矩形框来创建一个sprite static Sprite* createWithSpriteFrame(SpriteFrame *pSpriteFrame);
使用一个精灵帧来创建一个精灵 static Sprite* createWithSpriteFrameName(const char *pszSpriteFrameName);
使用精灵帧名称来创建一个精灵
实例:
第一种创建:图片名称创建
void SpriteTest::Test1()
{
Sprite* sprite = Sprite::create("GameMainMenu.png");
sprite->setPosition(Vec2(origin.x + visible.width / 2,
origin.y + visible.height / 2));
float xs = visible.width / sprite->getContentSize().width;
float ys = visible.height / sprite->getContentSize().height;
sprite->setScale(xs, ys);
this->addChild(sprite);
}
第二种创建:文件名称和一个矩形框创建
void SpriteTest::Test2()
{
Rect r = Rect(1, 91, 110, 83); //矩形框的位置坐标
sprite = Sprite::create("Mouse_1.png", r);
sprite->setPosition(Vec2(origin.x + visible.width / 4,
origin.y + visible.height / 4));
this->addChild(sprite);
}
第三种创建:纹理创建
void SpriteTest::Test3()
{
//取得一个.png图片的纹理
texture = Director::getInstance()->getTextureCache()->addImage("ThorHammer.png");
sprite = Sprite::createWithTexture(texture);
sprite->setPosition(Vec2(origin.x + visible.width / 4,
origin.y + visible.height / 2.5));
this->addChild(sprite);
}
第四种创建:texture和一个矩形框来创建
void SpriteTest::Test4()
{
//加载一张包含多张小图片的大图片
texture = Director::getInstance()->getTextureCache()->addImage("MainBottom.png");
//框出大图片中的一张小图片
Rect r = Rect(1, 305, 558, 150);
sprite = Sprite::createWithTexture(texture);
//设置位置
sprite->setPosition(Vec2(origin.x + visible.width / 2,
origin.y + visible.height - 1.5*(visible.height / 3)));
sprite->setScale(0.3, 0.3);
this->addChild(sprite);
}
第五种创建:一个精灵帧来创建
void SpriteTest::Test5()
{
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("Hammer.plist");
SpriteFrame* frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("GoldenHammer.png");
sprite = Sprite::createWithSpriteFrame(frame);
sprite->setPosition(Vec2(origin.x + visible.width / 2,
origin.y + visible.height / 2));
this->addChild(sprite);
}
第六种创建:精灵帧名称来创建
void SpriteTest::Test6()
{
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("Hammer.plist");
sprite = Sprite::createWithSpriteFrameName("StarHammer .png");
sprite->setPosition(Vec2(origin.x + visible.width / 2,
origin.y + visible.height / 3));
this->addChild(sprite);
}
完整代码:
.h file #ifndef _SPRITETEST_SCENE_H_
#define _SPRITETEST_SCENE_H_
#include "cocos2d.h"
class SpriteTest : public cocos2d::Layer
{
private:
cocos2d::Size visible;
cocos2d::Vec2 origin;
cocos2d::Sprite* sprite;
cocos2d::Texture2D* texture;
public:
static cocos2d::Scene* createScene();
virtual bool init();
void Test1();
void Test2();
void Test3();
void Test4();
void Test5();
void Test6();
CREATE_FUNC(SpriteTest);
};
#endif // _SPRITETEST_SCENE_H_ .cpp file #include "SpriteTest.h"
USING_NS_CC;
Scene* SpriteTest::createScene()
{
auto scene = Scene::create();
auto layer = SpriteTest::create();
scene->addChild(layer);
return scene;
}
bool SpriteTest::init()
{
if (!Layer::init())
{
return false;
}
visible = Director::getInstance()->getVisibleSize();
origin = Director::getInstance()->getVisibleOrigin(); Test1();
this->Test2();
Test3();
this->Test4();
Test5();
Test6(); return true;
}
//第一种创建: 通过.png图片来创建精灵
void SpriteTest::Test1()
{
Sprite* sprite = Sprite::create("GameMainMenu.png");
sprite->setPosition(Vec2(origin.x + visible.width / 2,
origin.y + visible.height / 2));
float xs = visible.width / sprite->getContentSize().width;
float ys = visible.height / sprite->getContentSize().height;
sprite->setScale(xs, ys);
this->addChild(sprite);
} //第二种创建: 通过在一张大图片中框出一个矩形图片来创建精灵
void SpriteTest::Test2()
{
Rect r = Rect(1, 91, 110, 83); //矩形框的位置坐标
sprite = Sprite::create("Mouse_1.png", r);
sprite->setPosition(Vec2(origin.x + visible.width / 4,
origin.y + visible.height / 4));
this->addChild(sprite);
} //第三种创建: 通过纹理来创建精灵
void SpriteTest::Test3()
{
//取得一个.png图片的纹理
texture = Director::getInstance()->getTextureCache()->addImage("ThorHammer.png");
sprite = Sprite::createWithTexture(texture);
sprite->setPosition(Vec2(origin.x + visible.width / 4,
origin.y + visible.height / 2.5));
this->addChild(sprite);
} //使用一个纹理和一个矩形框创建一个精灵
void SpriteTest::Test4()
{
//加载一张包含多张小图片的大图片
texture = Director::getInstance()->getTextureCache()->addImage("MainBottom.png");
//框出大图片中的一张小图片
Rect r = Rect(1, 305, 558, 150);
sprite = Sprite::createWithTexture(texture);
//设置位置
sprite->setPosition(Vec2(origin.x + visible.width / 2,
origin.y + visible.height - 1.5*(visible.height / 3)));
sprite->setScale(0.3, 0.3);
this->addChild(sprite);
} //使用一个精灵帧创建一个精灵
void SpriteTest::Test5()
{
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("Hammer.plist");
SpriteFrame* frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("GoldenHammer.png");
sprite = Sprite::createWithSpriteFrame(frame);
sprite->setPosition(Vec2(origin.x + visible.width / 2,
origin.y + visible.height / 2));
this->addChild(sprite);
} //使用精灵帧名称创建一个精灵
void SpriteTest::Test6()
{
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("Hammer.plist");
sprite = Sprite::createWithSpriteFrameName("StarHammer .png");
sprite->setPosition(Vec2(origin.x + visible.width / 2,
origin.y + visible.height / 3));
this->addChild(sprite);
}
SpriteBatchNode简介:
在游戏开发中当屏幕上的精灵太多时,程序性能将急剧下降,这是因为每当添加一个精灵时,GPU都会重新渲染一次,这样性能很低.当有多个精灵出现时,例如:游戏中的子弹,可以使用SpriteBatchNode批量加载一次,从而提高了程序的性能。
通过源码分析,我们看到SpriteBatchNode还是通过TestureCache来加载图片的
bool SpriteBatchNode::initWithFile(const char*fileImage,
unsigned int capacity)
{
Texture2D* ptexture2d =
TextureCache::sharedTextureCache()->addImage(fileImage);
return initWithTexture(ptexture2d, capacity);
}
和SpriteFrameCache不同的是,SpriteFrameCache通常用来实现动画,但是在3.0的版本中不建议使用,只要sprite来自一张大图就行
实例源码:
.h files #ifndef _SPRITEBATCHNODETEST_SCENE_H_
#define _SPRITEBATCHNODETEST_SCENE_H_
#include "cocos2d.h"
class SpriteBatch : public cocos2d::Layer
{
private:
cocos2d::Size visible;
cocos2d::Vec2 origin;
cocos2d::SpriteBatchNode* batch;
cocos2d::Sprite* mole;
public:
static cocos2d::Scene* createScene();
virtual bool init();
//初始化Batch,通过这个函数来添加多个地鼠
void initBatch();
//添加地鼠,从batch取得,然后在当前的这个点出添加一个地鼠(点事通过触屏事件得到)
void addMole(cocos2d::Vec2 point);
//添加一个触屏事件,当我们点击屏幕时,在我们点击的位置添加一个地鼠
virtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event); CREATE_FUNC(SpriteBatch);
};
#endif // _SPRITEBATCHNODETEST_SCENE_H_ .cpp files #include "SpriteBatchNodeTest.h"
USING_NS_CC;
Scene* SpriteBatch::createScene()
{
auto scene = Scene::create();
auto layer = SpriteBatch::create();
scene->addChild(layer);
return scene;
}
bool SpriteBatch::init()
{
if (!Layer::init())
{
return false;
}
visible = Director::getInstance()->getVisibleSize();
origin = Director::getInstance()->getVisibleOrigin();
initBatch();
//注册监听器
auto l = EventListenerTouchOneByOne::create();
l->onTouchBegan = CC_CALLBACK_2(SpriteBatch::onTouchBegan, this);
//注册事件
_eventDispatcher->addEventListenerWithSceneGraphPriority(l, this);
return true;
}
void SpriteBatch::initBatch()
{
//首先初始化,创建地鼠对象,添加50个地鼠到layer中
batch = SpriteBatchNode::create("Rat4.png", 50);
//将batch添加到当前的Layer中
this->addChild(batch);
}
void SpriteBatch::addMole(cocos2d::Vec2 point)
{
//创建一个地鼠的精灵,此精灵为纹理,且取自batch中的地鼠纹理
mole = Sprite::createWithTexture(batch->getTexture());
//将地鼠显示在单击屏幕的地方
mole->setPosition(point);
//最后将此精灵添加到Layer中
this->addChild(mole);
}
bool SpriteBatch::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event)
{
//首先,取得鼠标点击屏幕的那个点
cocos2d::Vec2 point = touch->getLocationInView();
//将获取的point这个点,转换成坐标
point = Director::getInstance()->convertToGL(point);
//每点击一次屏幕,就调用addMole()一次
addMole(point);
return false;
}
SpriteFrameCache
SpriteFrameCache是精灵帧的缓存类,提供了一些管理精灵帧Sprite的方法,SpriteFrameCache是单例类,实例化方法如下:
static SpriteFrameCache* getInstance(void);
其他重要的方法:
static void purgeShareSpriteFrameCache(void);
清除缓存
void addSpriteFramesWithFile(const char* plist);
从plist配置文件中添加多个精灵帧SpriteFrame
void addSpriteFramesWithFile(const char* plist, const char* fileName);
使用plist和纹理文件创建多个精灵帧(新增纹理时使用,该纹理和plist关联在一起)
void addSpriteFramesWithFile(const char* pszPlist, cocos2d::Texture2D* texture);
使用plist和纹理文件创建多个精灵帧(新增纹理时使用,该纹理和plist关联在一起)
void addSpriteFrame(cocos2d::SpriteFrame* frame,const char* frameName)
添加单帧精灵帧,并为精灵帧指定名称
void removeSpriteFrame(void);
删除精灵帧
void removeUnusedSpriteFrames(void)
删除未使用的精灵帧
void removeSpriteFramesFromFile(const char* plist);
根据plist删除精灵帧
SpriteFrame
在游戏的开发过程中,通常使用工具将多张图片放在同一张大的图片中来加载,这样可以提高性能,可以根据某个单个小图片放在大图片的矩形框中来显示这张小图片,精灵帧SpriteFrame就是用来封装这张小图片。
SpriteFrame的重要创建函数:
static SpriteFrame* create(const char* filename, const Rect& rect);
使用Texture(纹理)和矩形框创建精灵帧
static SpriteFrame* createWithTexture(Texture2D* pobTexture, const Rect& rect);
使用图片文件和矩形框来创建精灵帧
实例:
.h files #ifndef _SPRITEFRAMETEST_SCENE_H_
#define _SPRITEFRAMETEST_SCENE_H_
#include "cocos2d.h"
class spriteFrame : public cocos2d::Layer
{
private:
cocos2d::Vec2 origin;
cocos2d::Size visible;
cocos2d::Sprite* sprite;
public:
static cocos2d::Scene* createScene();
virtual bool init();
void Test_1();
void Test_2();
CREATE_FUNC(spriteFrame);
};
#endif // _SPRITEFRAMETEST_SCENE_H_ .cpp files #include "SpriteFrameTest.h"
USING_NS_CC;
Scene* spriteFrame::createScene()
{
Scene* scene = Scene::create();
auto layer = spriteFrame::create();
scene->addChild(layer);
return scene;
}
bool spriteFrame::init()
{
if (!Layer::init())
{
return false;
}
visible = Director::getInstance()->getVisibleSize();
origin = Director::getInstance()->getVisibleOrigin();
Test_1();
this->Test_2();
return true;
}
void spriteFrame::Test_1()
{
Rect r = Rect(2, 2, 63, 72);
auto frame = SpriteFrame::create("Hammer.bng", r);
sprite = Sprite::createWithSpriteFrame(frame);
sprite->setPosition(Vec2(origin.x + visible.width / 2,
origin.y + visible.height / 2));
this->addChild(sprite);
}
void spriteFrame::Test_2()
{
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("Mouse_3.plist");
SpriteFrame* frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("Rat_1_2.png");
sprite = Sprite::createWithSpriteFrame(frame);
sprite->setPosition(Vec2(origin.x + visible.width / 3,
origin.y + visible.height / 3));
this->addChild(sprite);
}
重要函数:
Cocos2d-x之Sprite的更多相关文章
- Cocos2d 中的Sprite大小调整问题
以前用UIImageView,比如 UIImageView *view = [[UIImageViewalloc] initWithImage:[UIImageimageNamed:@"b ...
- Sprite Kit 入门教程
Sprite Kit 入门教程 Ray Wenderlich on September 30, 2013 Tweet 这篇文章还可以在这里找到 英语, 日语 If you're new here, ...
- ios游戏开发 Sprite Kit教程:初学者 1
注:本文译自Sprite Kit Tutorial for Beginners 目录 Sprite Kit的优点和缺点 Sprite Kit vs Cocos2D-iPhone vs Cocos2D- ...
- Sprite Kit教程:初学者
作者:Ray Wenderlich 原文出处:点击打开链接 http://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners 转自 ...
- Unity3D游戏开发从零单排(四) - 制作一个iOS游戏
提要 此篇是一个国外教程的翻译,尽管有点老,可是适合新手入门. 自己去写代码.debug,布置场景,能够收获到非常多.游戏邦上已经有前面两部分的译文,这里翻译的是游戏的最后一个部分. 欢迎回来 在第一 ...
- 【Cocos游戏实战】功夫小子第七课之游戏主功能场景逻辑功能和暂停功能场景的分析和实现
CSDN的markdown编辑器是吃屎了么! !.什么玩意.!写了一半写不了东西还全没了,搞个毛线! 本节课的视频教程地址是:第七课在此 假设本教程有帮助到您,希望您能点击进去观看一下,并且如今注冊成 ...
- cocos2dx 3.x 拼图小游戏
.h #define IMAGE_MAX 2 //图片的个数.. //图片结构体 属性 struct IMAGE_DATA { cocos2d::Sprite *m_pImage; bool m_bO ...
- cocos2dx 3.x 精灵重叠时点击最上层的精灵
ps. 这个方法只适用设置精灵的触摸.. //注册触摸事件..3.X后可以在这样写..不需要重新声明 EventListenerTouchOneByOne *listener = EventListe ...
- Cocos2d-x 学习笔记(20) ControlButton
[Cocos2d-x 学习笔记 目录链接] 1. 简介 ControlButton实现了按钮功能,根据触摸的位置和移动的过程可识别9中EventType类型,执行对应的回调函数. 直接继承了Contr ...
- Cocos2d-x之Action
| 版权声明:本文为博主原创文章,未经博主允许不得转载. 在Cocos2d-x中的Node对象可以有动作,特效和动画等动态特性.因此在Node类中定义了这些动态特性,因此精灵,标签,菜单,地图和粒 ...
随机推荐
- lucene版本升级到4.6.0以上之后使用ik分词器遇到的问题
在将lucene core版本从4.5.1升级到4.7.0后,如下代码使用ik分词器报错 IKAnalyzer analyzer = new IKAnalyzer(true); StringReade ...
- Xcode 及 iOS 常用宏和常量
Xcode Xcode 工程设置支持 bash 脚本及其语法,如 $(PROJECT_DIR)$(PROJECT_DIR) PROJECT_DIR 代表当前工程的绝对路径,所以 $(PROJECT_D ...
- Linux知识-不断更新
找到使用cpu最高的进程之使用cpu最高的线程的16进制号 shell命令行: ps -eo %cpu,pid | sort -n -k1 -r |head -n 1|awk '{print$2}'| ...
- 用vbs脚本简易实现 番茄工作法
番茄工作法: 专注于某一段时间,减少打断,提高时间的感知和掌控. 25min工作+5min休息 周期:4x(25+5)+20 VBS代码实现如下: Dim fso,f,count,time,shell ...
- (ACM模板)队列queue
#include<iostream> #include<cstdio> #include<queue> using namespace std; struct po ...
- SQL回顾1
1.学生表Student(SID,Sname,Sage,Ssex) --SID 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 2.课程表 Course(CID,Cname,T ...
- Winfrom 弹出窗体位置设定
Winfrom 窗体弹出位置设定,其实就是两种模式,第一种模式是通过Winform提供的属性来设定:第二种模式是自定义,可以相对于软件本身,也可以是相对于屏幕. 一.第一种模式 使用Winform提供 ...
- mysql数据库进阶
一.索引 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可. 分类: 普通索引 唯一索引 全文索引 组合 ...
- Flutter-RaisedButton
RaisedButton({ Key key, //点击按钮的回调出发事件 @required VoidCallback onPressed, //水波纹高亮变化回调 ValueChanged< ...
- bzoj1495 [NOI2006]网络收费 复杂度分析+树上背包
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1495 题解 通过观察可以发现,对于一个 \(lca\),如果 \(nA \leq nB\),那 ...