通过texturePacker做出的flash帧图怎么调用

通过texturePacker做出的flash帧图怎么调用,第1张

在flash中有时可能要使用位图动数橘画帧,如果每一改瞎帧都要一个图片来保存的话可能耗费多余的内存,如果能用上TexturePacker把小图合并成一个大图(下文用sprite sheet代替),不但可以减少内存的使用,而且减少读入到程序的图片数量,一定程度上还能加快程序的运行效率。本文章将介绍如何SpriteSheetAs3库来读入TexturePacker生成的sprite sheet来播放动画。

先介绍一下SpriteSheetAs3,这是一个开源的用SpriteSheet Animation in AS3修改和优化后的库,有以下新功能:

1.减少内存的使用;

2.可读入sprite sheet的plist格式配置文件

3.改为用图片名索引位图(小图)或动画帧;

4.支持旋转位图(小图)的sprite sheet;

5.可读入tiled地图。

以下来用TexturePacker为我们生成一个sprite sheet,在这里下载TexturePacker和小丑鱼动画帧,打开TexturePacker把所有小丑鱼图片加入到工程,如图所示:

注意Data Format一定要是cocos2d,Texture settings的其他选项最好和上图一致,texturefile和data file的路径由自己来定吧,然后点击public发布一个sprite sheet和有关sprite sheet所包含图片数据的plist文件。如果是免费版TexturePacker,点击public后,还要点continue,而且sprite sheet有两个图花了,这是免费版才会有的。

接下来是代码开发了,先下载SpriteSheetAs3,打开Flash Builder新建一个ActionScript项目,命名为testSpriteSheet,如下图核毕空:

点击"下一步",点"添加SWC",把SpriteSheetAs3里bin目录下的SpriteSheetAs3.swc文件添加到工程中,如下图:

点“完成”,把Clown_Normal.png和Clown_Normal.plist复制到testSpriteSheet/bin-debug/data/下(请手动创建目录),把以下内容复制到testSpriteSheet.as文件里:

//testSpriteSheet.as

package

{

import flash.display.Bitmap

import flash.display.DisplayObject

import flash.display.Sprite

import flash.display.StageAlign

import flash.display.StageScaleMode

import flash.events.Event

import flash.events.IOErrorEvent

import com.sprite_sheet.AnimSpriteSheet

import com.sprite_sheet.SpriteSheetFrame

import com.sprite_sheet.TextureCache

import com.sprite_sheet.SpriteFrameCache

import utils.Stats

import utils.loading.BigLoader

import utils.loading.BigLoadItem

[SWF (width="750", height="600")]

public class testSpriteSheet extends Sprite

{

private var mLoader:BigLoader//res loader

public function testSpriteSheet()

{

addEventListener(Event.ADDED_TO_STAGE, onAdded)

}

protected function onAdded(event:Event):void

{

stage.scaleMode = StageScaleMode.NO_SCALE

stage.frameRate= 60

//draw background

var appWidth:Number= 750

graphics.beginFill(0x434E8E)

graphics.drawRect(0,0, appWidth, 24)

graphics.endFill()

graphics.beginFill(0xf0f0f0)

graphics.drawRect(0,24, appWidth, 600)

graphics.endFill()

var st:DisplayObject= new Stats()

st.y= 20

addChild(st)

// load resources

mLoader= new BigLoader()

mLoader.add("data/Clown_Normal.png", "Clown_Normal.png")

mLoader.add("data/Clown_Normal.plist", "Clown_Normal.plist", 1, BigLoadItem.DATA)

mLoader.addEventListener(Event.COMPLETE, onAnimLoaded)

mLoader.addEventListener(IOErrorEvent.IO_ERROR, onLoadFailed)

mLoader.start()

}

private static const NUM_H:int = 6

protected function onAnimLoaded(event:Event):void

{

//add sprite sheet data file to SpriteFrameCache

SpriteFrameCache.Singleton().SetLoader(mLoader)

SpriteFrameCache.Singleton().AddSpriteFrames("Clown_Normal.plist")

//add sprite sheet file to TextureCache

TextureCache.Singleton().SetLoader(mLoader)

TextureCache.Singleton().addSpriteSheet("Clown_Normal.png")

for (var i:int = 0i <24i++)

{

//create clown fish anim

var anim: AnimSpriteSheet = createClownAnim()

addChild(anim)

//set fps

anim.mFps = 2 * (i + 1)

//set pos

var row: int = int(i/NUM_H)

anim.x= 20 + 100*(i%NUM_H) + row*36

anim.y= 150 + row*60

}

}

protected function createClownAnim(): AnimSpriteSheet

{

//00~09 frames

var bmps: Array = new Array()

var bmp: SpriteSheetFrame = null

for(var i:int = 0i <10i++)

{

bmp = SpriteFrameCache.Singleton().CreateSpriteSheetFrame("Clown_Normal0" + i + ".png")

bmps.push(bmp)

}

//10~ 23 frames

for(i = 10i <24i++)

{

bmp = SpriteFrameCache.Singleton().CreateSpriteSheetFrame("Clown_Normal" + i + ".png")

bmps.push(bmp)

}

var anim: AnimSpriteSheet = new AnimSpriteSheet(bmps)

anim.mFps = 30

anim.EnableShow(true)

anim.EnablePlay(true)

return anim

}

protected function onLoadFailed(event:IOErrorEvent):void

{

// if load file failed, will print the file name to console

trace("Cannot find file!")

trace(event.text)

}

}

}

最后运行一下程序,成功的话会看见有很多小丑鱼在游动,不过有些花图(我用的是免费版TexturePacker)

在cocos2d-x中可以用.plist格式的文件来保存数据,它是XML文件格式的一种,在cocos2d-x解析.plist方面相关的资料比较少,但本身也很简单,要解析.plist文件可以参考cocos2d-x类库中的CCSpriteFrameCache类和CCParticleSystem类,它主要是使用CCDictionary类来对.plist文件进行 *** 作。

下面有一个.plist文件:

[html] view plaincopy

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"瞎宴闭>

<plist version="1.0">

<dict>

<key>level1</key>

<dict>

<key>bg_far_scene</key>

<dict>

<key>path</key>

<string>images/far_scene.png</string>

<key>pos</key>

<string>{358, 309}</string>

</dict>

<key>bg_near_scene</key>

<dict>

<key>path</key>

<string>images/near_scene.png</string>

<key>pos</key>

<string>{360, 100}</string>

</dict>

</dict>

</dict>

</plist>

读取.plist文件的代码如下:

[cpp] view plaincopy

const char* testPlistPath = "BSPlistDatas\\test.plist"

const char* fullPath = CCFileUtils::sharedFileUtils()->fullPathFromRelativeFile("test.plist", testPlistPath)

CCDictionary* plistDic = CCDictionary::createWithContentsOfFile(testPlistPath)

CCDictionary* levelDic = dynamic_cast<CCDictionary*>(plistDic->objectForKey("level1"))

CCDictionary* farScene = dynamic_cast<CCDictionary*>(levelDic->objectForKey("bg_far_scene"))

CCString* farScenePath = dynamic_cast<CCString*>(farScene->objectForKey("path"))

CCPoint point = CCPointFromString(farScene->valueForKey("pos")->getCString())

CCLog("path = %s", farScenePath->getCString())

CCLog("pos = %f, %f", point.x, point.y)

第一行是.plist文件的相对路径,通过CCFileUtils类获得文件中绝对路径后,使用CCDictionary::createWithContensOfFile(filePath)将文件中内容加载到CCDictionary数据结构的内存中,然后通过xxxForKey获得相应的key下的value。

这里需要注意的是,当在读取'pos'的时候,它的值一个{x, y}的字磨裂符串,这是.plist文件中祥州的数组存储规则,我们可以通过cocos2d-x提供函数api将这样的字符串转化为CCpoint对象。

[cpp] view plaincopy

CCPoint point = CCPointFromString(farScene->valueForKey("pos")->getCString())

上面这句话就是做了这样的一个转化的过程,同样的cocos2d-x还支持CCSize、CCRect的字符串的转化。他们转化的方法以及在.plist中对应的字符串格式如下:

CCPoint: CCPointFromString(){x, y}

CCSize:CCSizeFromString(){w, h}

CCRect: CCSizeFromString(){x, y, w, h}

这样我们2D游戏所初始化所需要的数据都基本上够用了,可以尝试将游戏的初始数据放在.plist中,然后修改调整数值就可以直接修改plist文件,而无需重新编译程序了,从而实现游戏数据和游戏逻辑的分离。

Cocos Creator 有一套统一的资源管理机制 ,在本篇教程,我们将介绍

资源的分类

如何在 属性检查器 里设置资源

动态加载 Asset

动态加载 Raw Asset

资源的分类

目前的资源分成两种,一种叫做 Asset,一种叫做 Raw Asset。

Asset

Creator 提供了名为 "Asset" 的资源类型,cc.SpriteFrame, cc.AnimationClip, cc.Prefab 等资源都属于 Asset。Asset 的加载是统一并且自动化的,相互依赖的 Asset 能够被自动预加载。

例如,当引擎在加载场景时,会先自动加载场景关联到的资源,这些资源如果再关联其它资源,其它也会被先被加载,等加载全部完成后,场景加载才会结束。

因此只要你拿到了一个 Asset 对象,这个对象一定是已经加载结束的,可以直接通过对象上的属性访问到资源的所有数据。当你要在引擎中使用这些资源,引擎的 API 接收的都必须是一个加载好的 Asset 对象。

脚本中可以这样定义一个 Asset 属性:

// NewScript.js

cc.Class({

extends: cc.Component,

properties: {

spriteFrame: {

default: null,

type: cc.SpriteFrame

},

}

})

Raw Asset

为了兼容 Cocos2d 的一些既有 API,我们把保留原始资源文件扩展名资源叫做 "Raw Asset"。图片(cc.Texture2D),声音(cc.AudioClip),粒子(cc.ParticleAsset)等资源都是 Raw Asset。Raw Asset 在脚本里由一个 url 字符串来表示,当你要在引擎中使用 Raw Asset,只要把 url 传给引擎的 API,引擎内部会自动加载这个 url 对应的资源。

当你在脚本里声明一个类型是陵胡蚂 cc.Texture2D 的 Raw Asset,一开始可能会想这样定义:

cc.Class({

extends: cc.Component,

properties: {

textureURL: {

default: null,

type: cc.Texture2D

}

}

})

这样写的问题在于,在代码中 textureURL 实际上是一个字符串,而不是 cc.Texture2D 的实例。为了不混淆 type 的语义,在 CCClass 中声明 Raw Asset 的属性时,要用 url: cc.Texture2D 而不是 type: cc.Texture2D。

cc.Class({

extends: cc.Component,

properties: {

textureURL: {

default: "",

url: cc.Texture2D

}

}

})

如何在属性检查器里设置资源

不论是 Asset 还是 Raw Asset,只要在脚本中定义好类型,就能直接在 属性检查器 很方便地设尺埋置资源。假设我们有这样一个组件:

// NewScript.js

cc.Class({

extends: cc.Component,

properties: {

textureURL: {

default: "",

url: cc.Texture2D

},

spriteFrame: {

default: null,

type: cc.SpriteFrame

},

}

})

将它添加到场景后,属性检查器 里是这样的:

asset-in-properties-null

接下来我们从 资源做饥管理器 里面分别将一张贴图和一个 SpriteFrame 拖到 属性检查器 的对应属性中:

asset-in-properties-dnd

结果如下:

asset-in-properties-dnd

这样就能在脚本里直接拿到设置好的资源:

onLoad: function () {

var spriteFrame = this.spriteFrame

var textureURL = this.textureURL

spriteFrame.setTexture(textureURL)

}

在 属性检查器 里设置资源虽然很直观,但资源只能在场景里预先设好,没办法动态切换。如果需要动态切换,你需要看看下面的内容。

动态加载

所有需要通过脚本动态加载的资源,都必须放置在 resources 文件夹或它的子文件夹下。resources 需要在 assets 文件夹中手工创建,并且必须位于 assets 的根目录,就像这样:

asset-in-properties-null

这里的 image/image, prefab, anim, font 都是常见的 Asset,而 image, audio 则是常见的 Raw Asset。

resources 文件夹里面的资源,可以关联依赖到文件夹外部的其它资源,同样也可以被外部场景或资源引用到。项目构建时,除了已在 构建发布 面板勾选的场景外,resources 文件夹里面的所有资源,连同它们关联依赖的 resources 文件夹外部的资源,都会被导出。所以如果一份资源不需要由脚本直接动态加载,那么不用放在 resources 文件夹里。

动态加载 Asset

Creator 提供了 cc.loader.loadRes 这个 API 来专门加载那些位于 resources 目录下的 Asset。和 cc.loader.load 不同的是,loadRes 一次只能加载单个 Asset。调用时,你只要传入相对 resources 的路径即可,并且路径的结尾处不能包含文件扩展名。

// 加载 Prefab

cc.loader.loadRes("test assets/prefab", function (err, prefab) {

var newNode = cc.instantiate(prefab)

cc.director.getScene().addChild(newNode)

})

// 加载 AnimationClip

cc.loader.loadRes("test assets/anim", function (err, clip) {

myNode.getComponent(cc.Animation).addClip(clip, "anim")

})

// 加载 SpriteAtlas(图集),并且获取其中的一个 SpriteFrame

// 注意 atlas 资源文件(plist)通常会和一个同名的图片文件(png)放在一个目录下, 所以需要在第二个参数指定资源类型

cc.loader.loadRes("test assets/sheep", cc.SpriteAtlas, function (err, atlas) {

var frame = atlas.getSpriteFrame('sheep_down_0')

sprite.spriteFrame = frame

})

加载独立的 SpriteFrame

图片设置为 Sprite 后,将会在资源管理器中生成一个对应的 SpriteFrame。但如果直接加载 test assets/image,得到的类型将会是 cc.Texture2D。你必须指定第二个参数为资源的类型,才能加载到图片生成的 cc.SpriteFrame:

// 加载 SpriteFrame

cc.loader.loadRes("test assets/image", cc.SpriteFrame, function (err, spriteFrame) {

myNode.getComponent(cc.Sprite).spriteFrame = spriteFrame

})

如果指定了类型参数,就会在路径下查找指定类型的资源。当你在同一个路径下同时包含了多个重名资源(例如同时包含 player.clip 和 player.psd),或者需要获取“子资源”(例如获取 Texture2D 生成的 SpriteFrame),就需要声明类型。

资源释放

loadRes 加载进来的单个资源如果需要释放,可以调用 cc.loader.releaseRes,releaseRes 只能传入一个和 loadRes 相同的路径,不支持类型参数。

cc.loader.releaseRes("test assets/anim")

此外,你也可以使用 cc.loader.releaseAsset 来释放一个具体的 Asset 实例。

cc.loader.releaseAsset(spriteFrame)

动态加载 Raw Asset

Raw Asset 可以直接使用 url 从远程服务器上加载,也可以从项目中动态加载。对远程加载而言,原先 Cocos2d 的加载方式不变,使用 cc.loader.load 即可。对项目里的 Raw Asset,加载方式和 Asset 一样:

// 加载 Texture,不需要后缀名

cc.loader.loadRes("test assets/image", function (err, texture) {

...

})

cc.url.raw

Raw Asset 加载成功后,如果需要传给一些 url 形式的 API,还是需要给出完整路径才行。你需要用 cc.url.raw 进行一次 url 的转换:

// 原 url 会报错!文件找不到

var texture = cc.textureCache.addImage("resources/test assets/image.png")

// 用 cc.url.raw,此时需要声明 resources 目录和文件后缀名

var realUrl = cc.url.raw("resources/test assets/image.png")

var texture = cc.textureCache.addImage(realUrl)

资源批量加载

cc.loader.loadResAll 可以加载相同路径下的多个资源:

// 加载 test assets 目录下所有资源

cc.loader.loadResAll("test assets", function (err, assets) {

// ...

})

// 加载 sheep.plist 图集中的所有 SpriteFrame

cc.loader.loadResAll("test assets/sheep", cc.SpriteFrame, function (err, assets) {

// assets 是一个 SpriteFrame 数组,已经包含了图集中的所有 SpriteFrame。

// 而 loadRes('test assets/sheep', cc.SpriteAtlas, function (err, atlas) {...}) 获得的则是整个 SpriteAtlas 对象。

})


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12226394.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-22
下一篇 2023-05-22

发表评论

登录后才能评论

评论列表(0条)

保存