栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > 其他

cocos2dx学习之路(七)——精灵、精灵旋转、淡入、水平翻转、自由移动、九宫格精灵

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

cocos2dx学习之路(七)——精灵、精灵旋转、淡入、水平翻转、自由移动、九宫格精灵

理解精灵的含义
学会创建一个精灵
掌握对精灵的控制
了解九宫格精灵及其应用

Sprite在2D游戏场景设计中指的就是像素图可以移动可以控制

1、通过图片路径创建精灵
Sprite* sprite = Sprite::create(“要加载的图片文件目录的相对路径”);
1、该方式创建的精灵以静态图的形式呈现
2、图片大小与原大小一致
3、如果图片显示大小超出屏幕范围,则只显示屏幕内的部分
4、如果精灵大小小于图片大小。则会按比例进行缩放图片,导致
图片变形。(长度和宽度的比例与原图长宽比不同,会导致图片变形)
SpriteDemo.h

#pragma once
#include"cocos2d.h"
USING_NS_CC;
class SpriteScene:public Scene
{
public:
	CREATE_FUNC(SpriteScene);
	virtual bool init();
};

SpriteDemo.cpp

bool SpriteScene::init()
{
	if(!Scene::init())return false;
	//创建一个精灵
	Sprite* sprite = Sprite::create("要加载的图片文件目录的相对路径");
	//图片太大会显示在屏幕外边,所以需要进行一个缩放,图片锚点默认在图片正中心
	//sprite ->setContentSize(Size(100*100));//这样处理图片大小会变形
	sprite ->setScale(0.3f);//需要进行整体缩放,缩放到原来的多少倍
	sprite ->setPosition(Vec2(Director::getInstance()->getVisibleSize() / 2));
	
	this->addChild(sprite);
	

	return true;
}

创建完成后要去AppDelegate.cpp 调用

2、使用图集创建一个精灵
如果读取图片过多,会导致内存奔溃,使用后,需要及时清理缓存
通常图片没有达到一定数量是不会清理的,不清理的话在创建精灵
的时候去读取图片就会非常快,如果每次读取都去加载一次因为是
大图,所以会非常卡顿。一般是做场景切换的时候会去清理缓存。

string path =  "plist文件的相对路径";
//通过plist文件路径将图片读取到精灵帧缓存
auto cache = SpriteFrameCache::getInstance()->addSpriteFrameWithFile(path);
//通过指定名称的精灵帧创建精灵
auto sprite = Sprite::createWithSpriteFrameName("1");

做序列帧动画的时候和做资源优化的时候会用到图集。
比如有很多张图片,有很多透明的边缘,我们想把边缘裁掉,
我们可以把很多张图片拼合在一起,拼合的时候裁剪,
最后做成一张大图,可以节省磁盘空间,也可以加快渲染的效率。

图集的产生会用到cocos2d官方提供的工具TexturePacker创建图集文件
TexturePacker集成了cocos2d生成图集的功能
会生成以下两个文件:
plist文件 、png大图;
plist文件就是xml文件,存放的每张图片的一个键值对,还包含了在大图中的偏移位置
以及精灵的大小,键是根据每张图片名称生成的可以有后缀。

SpriteDemo.h

#pragma once
#include"cocos2d.h"
USING_NS_CC;
class SpriteScene:public Scene
{
public:
	CREATE_FUNC(SpriteScene);
	virtual bool init();
};

SpriteDemo.cpp

bool SpriteScene::init()
{
	if(!Scene::init())return false;
	//创建一个精灵
	Sprite* sprite = Sprite::create("要加载的图片文件目录的相对路径");
	//图片太大会显示在屏幕外边,所以需要进行一个缩放,图片锚点默认在图片正中心
	//sprite ->setContentSize(Size(100*100));//这样处理图片大小会变形
	sprite ->setScale(0.3f);//需要进行整体缩放,缩放到原来的多少倍
	sprite ->setPosition(Vec2(Director::getInstance()->getVisibleSize() / 2));
	this->addChild(sprite);
	//隐藏此精灵
	sprite->setVisible(false);

	
	//通过图集创建精灵
	SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist文件相对路径");
	//这个 1 是对应plist文件中的文件名 键
	Sprite* vampireSprite = Sprite::createWithSpriteFrameName("1");
	this->addChild(vampireSprite);
	vampireSprite ->setPosition(sprite->getPosition());

	//吸血鬼动画实例
	auto cache = SpriteFrameCache::getInstance();
	//cococs2d的Vector与C++的不一样,是记录cocos2d对象的指针
	Vectorimages;
	//8张图片
	for(int i = 1;i<=8;i++)
	{
		//Value()是cocos2d专门提供基本类型转换的 这里文件名是字符串所以用asString()
		images.pushBack(cache->getSpriteFrameByName(Value(i).asString()));//每一帧都是一个精灵
	}
	Animation* _animation = Animation::createWithFrames(images,1.f/8);//每张图片间隔时间0.25m
	//播放一次,停下来的就是最后一张图片
	//vampireSprite ->runAction(Animate::create(_animation));
	//一直播放
	vampireSprite ->runAction(RepeatForever::create(Animate::create(_animation)));
	return true;
}

3、使用贴图创建一个精灵
贴图又称为纹理(读取到图片的数据存入内存)

//贴图缓存
auto textureCache = TextureCache::getInstance();
//读取贴图,在缓存中添加
auto cache = textureCache->addImage("图片文件相对路径");
//通过贴图创建一个精灵
Sprite*sprite = Sprite::createWithTexture(cache);
//裁切贴图
sprite ->setTextureRect(Rect(0,0,480,320));

SpriteDemo.cpp

bool SpriteScene::init()
{
	if(!Scene::init())return false;
	//创建一个精灵
	Sprite* sprite = Sprite::create("要加载的图片文件目录的相对路径");
	//图片太大会显示在屏幕外边,所以需要进行一个缩放,图片锚点默认在图片正中心
	//sprite ->setContentSize(Size(100*100));//这样处理图片大小会变形
	sprite ->setScale(0.3f);//需要进行整体缩放,缩放到原来的多少倍
	sprite ->setPosition(Vec2(Director::getInstance()->getVisibleSize() / 2));
	this->addChild(sprite);
	//隐藏此精灵
	sprite->setVisible(false);

	
	//通过图集创建精灵
	SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist文件相对路径");
	//这个 1 是对应plist文件中的文件名 键
	Sprite* vampireSprite = Sprite::createWithSpriteFrameName("1");
	this->addChild(vampireSprite);
	vampireSprite ->setPosition(sprite->getPosition());
	vampireSprite ->setVisible(false);//隐藏


	//通过纹理创建一个精灵
	//png支持透明,jpg不支持,如果一张图片转成jpg格式就会添加一个背景色
	//jpg比png占的磁盘空间更小,但是在读取到内存解析的时候png更快
	auto cache = TextureCache::getInstance()->addImage("图片相对路径");
	Sprite* textureSprite = Sprite::createWithTexture(cache);
	this->addChild(textureSprite);
	textureSprite ->setPosition(sprite->getPosition());
	//0,0,前边是图片坐标,480,320是图片长宽
	//如果裁切位置是240,160那么裁切出来的是图片右下角
	textureSprite ->setTextureRect(Rect(0,0,480,320));//裁切
	return true;
}

4、多边形精灵
对图片空白的地方进行裁切后构成多边形,算法越好裁切的就越多,
空白的地方就越少。裁切后需要着色的像素点就会变少。

读取图片生成多边形
注意:
1、图片格式只能为png图片,不支持其他格式的图片;
2、生成时会占用CPU,消耗系统性能
auto info = AutoPolygon::generatePolygon("图片相对路径",Rect(0,0,437,437));

根据多边形数据创建多边形精灵

auto sprite = Sprite::create(info);

SpriteDemo.cpp

bool SpriteScene::init()
{
	if(!Scene::init())return false;
	//创建一个精灵
	Sprite* sprite = Sprite::create("要加载的图片文件目录的相对路径");
	//图片太大会显示在屏幕外边,所以需要进行一个缩放,图片锚点默认在图片正中心
	//sprite ->setContentSize(Size(100*100));//这样处理图片大小会变形
	sprite ->setScale(0.3f);//需要进行整体缩放,缩放到原来的多少倍
	sprite ->setPosition(Vec2(Director::getInstance()->getVisibleSize() / 2));
	this->addChild(sprite);
	//隐藏此精灵
	sprite->setVisible(false);

	
	//通过图集创建精灵
	SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist文件相对路径");
	//这个 1 是对应plist文件中的文件名 键
	Sprite* vampireSprite = Sprite::createWithSpriteFrameName("1");
	this->addChild(vampireSprite);
	vampireSprite ->setPosition(sprite->getPosition());
	vampireSprite ->setVisible(false);//隐藏


	//通过纹理创建一个精灵
	//png支持透明,jpg不支持,如果一张图片转成jpg格式就会添加一个背景色
	//jpg比png占的磁盘空间更小,但是在读取到内存解析的时候png更快
	auto cache = TextureCache::getInstance()->addImage("图片相对路径");
	Sprite* textureSprite = Sprite::createWithTexture(cache);
	this->addChild(textureSprite);
	textureSprite ->setPosition(sprite->getPosition());
	//0,0,前边是图片坐标,480,320是图片长宽
	//如果裁切位置是240,160那么裁切出来的是图片右下角
	textureSprite ->setTextureRect(Rect(0,0,480,320));//裁切

	//创建一个多边形精灵3.x的版本才有的
	//RGBA8888这个格式就是png
	auto polygonInfo = AutoPolygon::generatePolygon("图片相对路径",Rect(0,0,437,437));
	Sprite* _sprite = Sprite::create(polygonInfo);
	_sprite ->setPosition(sprite->getPosition());
	this->addChild(_sprite);
	return true;
}
创建精灵的方式优点缺点
通过图片路径创建不需要清理缓存图片过大,直接读取会卡顿
通过图集创建图片加载速度快内存占用较大,切换场景时需要清理缓存
通过贴图创建图片加载速度快内存占用较大,切换场景时需要清理缓存
通过多边形数据创建渲染速度快读取图片生成多边形信息会消耗更多CPU性能

游戏中常见的几种对精灵的控制

对精灵控制的演示:
1、实现精灵旋转效果
2、实现精灵淡入效果
3、实现精灵水平翻转
4、实现精灵在屏幕中自动移动

SpriteDemo.h

#pragma once
#include"cocos2d.h"
USING_NS_CC;
class SpriteScene:public Scene
{
public:
	CREATE_FUNC(SpriteScene);
	virtual bool init();
private:
	Sprite* _sprite;
	float _angel;
	int _opacity;//淡入,对应到阿尔法通道,对透明度操作的
	float _scaleX;
	float _minScaleX;
};

SpriteDemo.cpp

bool SpriteScene::init()
{
	if(!Scene::init())return false;
	//创建一个精灵
	Sprite* sprite = Sprite::create("要加载的图片文件目录的相对路径");
	//图片太大会显示在屏幕外边,所以需要进行一个缩放,图片锚点默认在图片正中心
	//sprite ->setContentSize(Size(100*100));//这样处理图片大小会变形
	sprite ->setScale(0.3f);//需要进行整体缩放,缩放到原来的多少倍
	sprite ->setPosition(Vec2(Director::getInstance()->getVisibleSize() / 2));
	this->addChild(sprite);
	//隐藏此精灵
	sprite->setVisible(false);

	
	//通过图集创建精灵
	SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist文件相对路径");
	//这个 1 是对应plist文件中的文件名 键
	Sprite* vampireSprite = Sprite::createWithSpriteFrameName("1");
	this->addChild(vampireSprite);
	vampireSprite ->setPosition(sprite->getPosition());
	vampireSprite ->setVisible(false);//隐藏


	//通过纹理创建一个精灵
	//png支持透明,jpg不支持,如果一张图片转成jpg格式就会添加一个背景色
	//jpg比png占的磁盘空间更小,但是在读取到内存解析的时候png更快
	auto cache = TextureCache::getInstance()->addImage("图片相对路径");
	Sprite* textureSprite = Sprite::createWithTexture(cache);
	this->addChild(textureSprite);
	textureSprite ->setPosition(sprite->getPosition());
	//0,0,前边是图片坐标,480,320是图片长宽
	//如果裁切位置是240,160那么裁切出来的是图片右下角
	textureSprite ->setTextureRect(Rect(0,0,480,320));//裁切

	//创建一个多边形精灵3.x的版本才有的
	//RGBA8888这个格式就是png
	auto polygonInfo = AutoPolygon::generatePolygon("图片相对路径",Rect(0,0,437,437));
	_sprite = Sprite::create(polygonInfo);
	_sprite ->setPosition(sprite->getPosition());
	this->addChild(_sprite);

	//实现精灵旋转效果
	//将图片先缩小
	_sprite ->setScale(0.3f);
	//_angel = 0;
	//_sprite ->setRotation(_angel );
	//开启一个调度器
	//this->schedule([&](float dlt)
	//{
		//_angel +=1.f;
		//if(_angel > 360)
		//{
			//_angel = _angel - 360;
		//}
		//_sprite ->setRotation(_angel );
	//},0.02f,"schedule");
	
	//实现精灵淡入效果
	//_opacity = 0;
	//精灵默认透明度是255,所以需要先初始化
	//_sprite ->setOpacity(_opacity);
	
	//this->schedule([&](float dlt)
	//{
		//if(_opacity>= 255)
		//{
			//调度器用完需要注销,不然就会像线程的死循环
			//this->unschedule("schedule");
			//return;
		//}
		//_opacity+=5;
		//_sprite ->setOpacity(_opacity);
	//},0.02f,"schedule");

	//实现精灵水平翻转(X轴)
	//_scaleX = _sprite->getScaleX();
	//_minScaleX = -_sprite->getScaleX();

	//this->schedule([&](float dlt)
	//{
		//if(_minScaleX > _scaleX)
		//{
			//this->unschedule("schedule");
			//return;
		//}
		//_scaleX -= 0.01f;
		//_sprite ->setScaleX(_scaleX);
	//},0.02f,"schedule");

	//控制精灵移动
	this->schedule([&](float dlt)
	{
		//游戏角色锚点一般在底部中心
		//宽度需要乘以一个系数_sprite ->getScale(),不然缩小后的图片在原始图片的范围情况下不会到边
		if(_sprite ->getPositionX() + _sprite ->getContentSize().width /2 * _sprite ->getScale() > 				Director::getInstance()->getVisibleSize().width 
		|| _sprite ->getPositionX() - _sprite ->getContentSize().width /2 * _sprite ->getScale()< 0)
		{
			this->unschedule("schedule");
			return;
		}
	_sprite ->setPositionX(_sprite ->getPositionX() + 1.f);
	},0.02f,"schedule");
	return true;
}

九宫格古代称为"洛书"
Scale9Sprite类继承自Sprite所以也是精灵
对图片的拉伸,长宽比例会改变,但是不会
发生拉伸的形变。特点就是四个角不会变,
四条边会被拉伸。需要确定中心区域,
中心区域确定后就可以确定四个角,只改变中心区域

创建九宫格精灵

auto sprite = Scale9Sprite::create("图片相对路径");

设置九宫格中心区域

//22,22是相对整个图形的坐标位置,56,56是传入的整个中心区域的大小,长和宽
sprite ->setCapInsets(Rect(22,22,56,56));

Scale9Demo.h

#pragma once
#include"cocos2d.h"
USING_NS_CC;

#include"ui/UIScale9Sprite.h"
using namespace ui;
class Scale9SpriteScene:public Scene
{
public:
	CREATE_FUNC(Scale9SpriteScene);
	virtual bool init();
};
bool SpriteScene::init()
{
	if(!Scene::init())return false;
	//如果图片背景和颜色都是黑色,那么我们需要添加白色背景,方便观察
	auto layer = LayerColor::create(Color4B::WHITE);
	this->addChild(layer);
	//创建九宫格精灵的演示实例
	Scale9Sprite* sprite = Scale9Sprite::create("图片相对路径");
	this->addChild(sprite);
	//设置精灵坐标位置在屏幕正中心
	sprite->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
	sprite->setPosition(Vec2(Director::getInstance()->getVisibleSize() / 2));
	
	//设置九宫格精灵的中心区域
	sprite->setCapInsets(Rect(20,20,1,1));
	//改变图形大小
	sprite->setContentSize(Size(200,200));
	//改变图形形状为矩形
	sprite->setContentSize(Size(300,200));
	//后边创建的精灵会盖在前边的九宫格精灵下面,所以这里隐藏九宫格的
	//sprite->setVisible(false);
	//创建一个用于对比的精灵
	//Sprite*_sprite = Sprite::create("图片相对路径");
	//this->addChild(_sprite );
	//_sprite ->setColor(Color3B::RED);
	//设置精灵坐标位置在屏幕正中心
	//_sprite ->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
	//_sprite ->setPosition(Vec2(Director::getInstance()->getVisibleSize() / 2));
	//_sprite ->setContentSize(Size(200,200));
	
	return true;
}

九宫格精灵VS精灵
性能参数对比

对比参数九宫格精灵精灵
图片资源占用磁盘大小
消耗CPU性能
占用内存一般
渲染速度一般一般

九宫格精灵应用范围
常用于发布包(apk release)大小要求的情况,用于压缩图片大小。

演示示例:对话框自适应文字内容
要求:
文字显示内容不确定,对话框需要根据文字内容大小进行自适应匹配

bool SpriteScene::init()
{
	if(!Scene::init())return false;
	//如果图片背景和颜色都是黑色,那么我们需要添加白色背景,方便观察
	auto layer = LayerColor::create(Color4B::WHITE);
	this->addChild(layer);
	//创建九宫格精灵的演示实例
	Scale9Sprite* sprite = Scale9Sprite::create("图片相对路径");
	this->addChild(sprite);
	//设置精灵坐标位置在屏幕正中心
	sprite->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
	sprite->setPosition(Vec2(Director::getInstance()->getVisibleSize() / 2));
	
	//设置九宫格精灵的中心区域
	sprite->setCapInsets(Rect(20,20,1,1));
	//改变图形大小
	sprite->setContentSize(Size(200,200));
	//改变图形形状为矩形
	sprite->setContentSize(Size(300,200));
	

	//读取文字内容
	auto data = FileUtils::getInstance()->getValueMapFromFile("plist文件相对路径");
	if(!data.empty())
	{
		std::string content = data.at("1000").asString();
		Label* _label = Label::create(content,"方正姚体",24);
		
		_label ->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
		//九宫格包裹了内容,内部标签距离上下左右都有20的距离
		//Vec2(20,20)这个外边距的长度正好是中心区域sprite->setCapInsets(Rect(20,20,1,1));20,20的长宽
		_label ->setPosition(Vec2(20,20));
		//把标签直接添加到九宫格上,因为二者都是精灵
		sprite->addChild(_label);
		//控制宽度
		if(_label->getContentSize().width>300)
		{
			_label->setDimensions(300,0);//宽度300像素换行
		}
		//Size(40,40)设置个外边距
		sprite->setContentSize(_label->getContentSize() + Size(40,40));
	}
	return true;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/901544.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号