TexturePacker是一个常用的制作sprite sheet的工具,它提供了很多实用的功能。

一般我们制作sprite sheet都是使用他的gui版本,纯手工操作,就像下面这张图示的一样。

刚开始我们的项目也是使用这种方式,但后来发现这种方式在开发中有很大的问题。随着图片的增多,sprite sheet会越来越多,为了生成这些sprite sheet需要做很多重复的手工劳动,再考虑到给Android平台打包的sprite sheet配置和iOS的不同,还有包括图片变更,配置优化等情况,算下来光打包sprite sheet就需要巨大的工作量,这还不考虑由于手工误操作造成的各种问题。

于是我就考虑,如何尽可能地减少打包sprite sheet的工作量,提高开发的效率。后来通过搜索,看到raywenderlich上一篇关于使用TexturePacker的文章,里面比较详细地介绍了TexturePacker的用法,特别还提到了它的命令行工具的使用以及这个工具和xcode的集成,这给了我想要的答案。

接下来讲一下我在项目中如何使用这个TexturePacker的命令行工具以及实用它的一些经验。

---------------------------------------正式开始的分割线-----------------------------------------

具体下载和安装TexturePacker以及它命令行工具的方法就不说了,上面提到的那篇文章里有较详细的说明。一些准备就绪后,我们可以在命令行里执行texturepacker命令,正常情况下你将会看到texturepacker的各种参数以及使用方法的说明,如下图:

接下来为了方便说明,我们新建一个测试工程foo,这里以quick-cocos2d-x-2.2.1-rc引擎创建的工程为例,创建好后目录结构如下图:

我们需要一个目录去保存所有原始的(未打到sprite sheet里的)图片,这里我们新建个目录叫originalImages,然后找些图片,丢进这个目录,并将他们分类到不同的文件夹,接着我们再创建一个目录,用来存放我们打包sprite sheet的脚本工具,我们起名叫tools,然后,我们再创建一个目录spriteSheets,用于存放打好的图片,最后,一般我们会将工程用到的图片存放到res/images目录里面,所以为了清楚,再创建一个这个文件夹,最终目录结构如下图所示:

接下来我说一下思路,我们的脚本工具存放在tools文件夹中,运行之后会去遍历originalImages这个目录下的所有文件夹,然后将每个文件夹中的图片打包为一个sprite sheet,这个sprite sheet名字与该文件夹的名字相同,接着将打包后的sprite sheet文件复制两份,一份存入spriteSheets目录中,另一份拷贝到我们程序使用图片的目录。

举例来说,当我运行脚本,会生成三份sprite sheet,分别是button.png,button.plist,checkBox.png,checkBox.plist,common.png,common.plist,他们分别会存放入spriteSheets目录和res目录下的images目录中(一般res目录下的images目录用来存放程序中用到的图片)。

---------------------------------------渐入佳境的分割线------------------------------------------

好的,一切准备就绪,我们开始说说这个脚本究竟要如何编写。

首先我们需要大概了解一下texturepacker的一些常用参数。

--format

指定sprite sheet的格式,默认是cocos2d,做cocos2d-x项目的话,就选cocos2d就行。可选的选项如下:

--texture-format

非常重要的一个属性,指定texture的格式。如果我们做iOS上的游戏,一般都会使用PVR,因为这个format的texture是专门为苹果iPhone和iPad的图形处理器优化的,而Android因为设备硬件多种多样,所以我们一般可能会选用png格式的,感兴趣的朋友可以自己搜索一下相关内容。这个参数如果不指定值的话texturepacker会尝试去根据sprite sheet的命名来自动选择一个合适的format。具体的选项如下:

--data

指定data文件的名字,也就是plist文件的名字

--sheet

sprite sheet文件的名字

--enable-rotation

是否开启旋转。一般我们会开启,为了更有效率的将散图打在一起。

--scale

在创建sprite sheet之前为所有散图做一个调整scale的操作,比如,如果是0.5,那么就把原始图都压缩一般大小,再存入sprite sheet中

--shape-padding

设置每个图片在sprite sheet中的间隔,默认是2

--max-size

sprite sheet的最大尺寸,你不可能将所有图片都打入到一张sprite sheet里,因为没有设备能支持这样的sprite sheet,于是需要限定大小:)。

--opt

这个是很重要的一个属性,决定了sprite sheet的像素格式,这个属性可以很大程序改变sprite sheet所占的内存。常用的选项如下:

--trim

为了能在一张sprite sheet加入更多的图片,裁减掉原始图片的空白像素,但是使用的时候还是按照图片的原始尺寸来使用。

--smart-update

智能更新,为了避免重复生成相同内容的sprite sheet,texturepacker会检查现存的sprite sheet和将要生成的sprite sheet内容是否相同,如果不同再生成新的,如果相同则不生成。

---------------------------------------激动人心的分割线------------------------------------------

好了,最后激动人心的时刻到了,我们上脚本!(脚本写的一般,多包涵)

 #! /bin/bash

 CURRENT_DIR=`dirname $`

 # input paths
IMAGE_DIR=$CURRENT_DIR/../originalImages # path that game proj use
GAME_IMAGE_PATH=$CURRENT_DIR/../res/images # temporary path to place the sprite sheets
OUTPUT_PATH=$CURRENT_DIR/../spriteSheets
OUTPUT_PATH_PVR=$OUTPUT_PATH/packagedPVR
OUTPUT_PATH_PNG=$OUTPUT_PATH/packagedPNG # path of the texture packer command line tool
TP=/usr/local/bin/TexturePacker # $: Source Directory where the assets are located
# $: Output File Name without extension
# $: RGB Quality factor
# $: Scale factor
# $: Max-Size factor
# $: Texture Type (PNG, PVR.CCZ)
# $: Texture format
pack_textures() { ${TP} --smart-update \
--texture-format $ \
--format cocos2d \
--data "$2".plist \
--sheet "$2".$ \
--maxrects-heuristics best \
--enable-rotation \
--scale $ \
--shape-padding \
--max-size $ \
--opt "$3" \
--trim \
$/*.png } # check the output path if [ -d $OUTPUT_PATH ];then
:
else
mkdir $OUTPUT_PATH
fi if [ -d $OUTPUT_PATH_PVR ]
then
:
else
mkdir $OUTPUT_PATH_PVR
fi if [ -d $OUTPUT_PATH_PNG ]
then
:
else
mkdir $OUTPUT_PATH_PNG
fi # do the job
for i in $IMAGE_DIR/*
do
if [ -d $i ]
then
spriteSheetName=`basename $i`
pack_textures $i $OUTPUT_PATH_PNG/$spriteSheetName 'RGBA8888' 1 2048 'png' "png"
pack_textures $i $OUTPUT_PATH_PVR/$spriteSheetName 'RGBA8888' 1 2048 'pvr.ccz' "pvr2ccz"
fi
done # cp them to the game proj image path cp -f $OUTPUT_PATH_PVR/* $GAME_IMAGE_PATH

将脚本的内容保存到一个文件中,命名后把后缀改为command,比如我是这个样子的:

然后记得在命令行里改一下脚本的权限,最后双击一下脚本,新鲜的sprite sheets就打包出来了,如果有什么图片的改动,只需要修改originalImages这个目录下的图片,然后双击一下脚本,新的sprite sheet就生成好了,再也没有了无聊烦人的手工劳动,向TP的GUI说再见吧!是不是很爽?:)

----------------------------------------最后的分割线-----------------------------------------

最后简单说一下在脚本里我们做的事情:

在脚本中我们针对originalImages里面每一个文件夹中的图,生成了两份sprite sheet,这两份唯一的区别是一份是pvr2ccz格式的,一份是png格式的,其他的属性都相同:像素格式RGBA8888,scale为1,最大尺寸为2048*2048。在生成完成后,将所有的sprite sheet拷贝到了spriteSheets这个文件夹,并把其中pvr格式的sprite sheet拷贝到了我们工程使用的图片目录里。

OK,大概就是这样子,那个脚本可以根据项目具体需求去改,我写的很简单,也没加什么log,这个其实完全可以写得更智能话写,这就留给各位去发挥了。

----------------------------------一些更新和补充----------------------------------------

最近有园子里的朋友和我交流了几个问题,我觉得其中有2个挺不错的,具体交流的内容在本文的留言里面有,不过为了方便大家查阅,我把它们整理(其实主要是截图,我是有多懒=。=)了一下,整合到这个篇文章中:

问题1:来自园友 tanyongdahaoren

答案:

这个问题回答的比较明确,我就不过多解释了:)

(这里忍不住吐槽一下博客园的插入代码功能,在回复里面没有bash的选项不说,在文章中bash的代码明显没有按照bash的脚本着色,“/*”竟然按照注释理解了,真心汗一个)

问题2:来自园友sousou123

这个园友主要的想法是考虑如何用TexturePacker把单张的png图片转换成pvr格式的图片。我一开始建议它用苹果官方的工具texturetool,但后来我意识到,这个texturetool相对TexturePacker有很多不方便的地方,比如它对原始图片的格式有硬性要求,必须至少满足:

  • Height and width must be at least 8.
  • Height and width must be a power of 2.
  • Must be square (height==width)

而TexturePacker虽然可以做png到pvr转换的事情,但是毕竟设计目的是打包sprite sheet用的。

不过经过和他的讨论,最终我给出了TexturePacker的解决方案:

这段脚本所做的事情是遍历images这个文件夹下的所有png图片,然后对每一张小图片都做一次打包操作,打包后的图片格式为pvr,这就相当于对每一张图片做了一次格式的转换:从png到pvr。这个做法虽然不同于TexturePacker的设计初衷,但毕竟是可行的,而且很方便。

这里要注意一点,我们相对于之前打包的脚本多增加了一个参数:--size-constraints

这个参数非常关键,它决定了最终生成的sprite sheet的尺寸是否会受POT(Power Of Two)格式的限制。一般情况下我们生成sprite sheet的尺寸都是宽高相等,并且都是2的N次方。而对我们现在这个转换图片格式的需求,这个限制就多余了,因为我们肯定希望原始图片多大尺寸,最终转换得到的图片就是多大尺寸,所以这里我们设置这个参数的值为AnySize。

--size-constraints AnySize

不得不说TexturePacker这个工具的功能真的很强大,作者考虑问题非常得全面~

这个参数在GUI里面在这里:

还有一点小问题是,对于每一个sprite sheet,都会需要生成一个data文件,这里我们不需要这个data文件,所以在参数里面我们就随便叫了一个dummy.plist:)其他的参数你们可以按需修改。

好了,更新部分就是这么多,最后感谢一下园友sousou123和tanyongdahaoren,通过解决他们的问题也让我学到了新的东西:)

感谢大家的收看~ 如果有问题可以留言或者私信我,我会尽量回覆大家。

最近刚开始专门写博客,如果表达的不好,或者有其他方面问题,也请大家多提宝贵意见:)

最最后,原创文章,转载请注明出处,谢谢:)

[原创]使用命令行工具提升cocos2d-x开发效率(一)之TexturePacker篇的更多相关文章

  1. [原创]使用命令行工具提升cocos2d-x开发效率(二)之CocosBuilder篇

    如果你正在使用CocosBuilder或者是其他基于CocosBuilder源码改装而成的工具为你的游戏搭建场景或者UI,那你一定要看看这篇文章:)   你是否已经厌倦了无聊的手工publish操作? ...

  2. 使用命令行工具提升cocos2d-x开发效率 之CocosBuilder篇

    http://www.cnblogs.com/flyFreeZn/p/3617983.html 假设你正在使用CocosBuilder或者是其它基于CocosBuilder源代码改装而成的工具为你的游 ...

  3. [原创]用命令行工具删除TFS2010服务器上的工作区信息

    下面的示例显示有关所有计算机上的所有用户已在地址 http://myserver:8080/tfs/DefaultCollection 上的以下团队项目集合中创建的所有工作区的列表. c:\proje ...

  4. Wireshark命令行工具tshark

    Wireshark命令行工具tshark 1.目的 写这篇博客的目的主要是为了方便查阅,使用wireshark可以分析数据包,可以通过编辑过滤表达式来达到对数据的分析:但我的需求是,怎么样把Data部 ...

  5. 如何用node编写命令行工具,附上一个ginit示例,并推荐好用的命令行工具

    原文 手把手教你写一个 Node.js CLI 强大的 Node.js 除了能写传统的 Web 应用,其实还有更广泛的用途.微服务.REST API.各种工具……甚至还能开发物联网和桌面应用.Java ...

  6. [易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)]

    [易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)] 项目实战 实战2:命令行工具minigrep 我们继续开发我们的minigrep. 我们现 ...

  7. JDK的命令行工具

    Jcmd:综合工具 jcmd -l  列出当前运行的所有虚拟机 参数-l表示列出所有java虚拟机,针对每一个虚拟机,可以使用help命令列出该虚拟机支持的所有命令 jcmd [pid] help j ...

  8. 显示器 Linux 性能 18 (一个命令行工具传递)

    对于系统和网络管理员来说每天监控和调试Linux系统的性能问题是一项繁重的工作.在IT领域作为一名Linux系统的管理员工作5年后,我逐渐认识到监控和保持系统启动并执行是多么的不easy.基于此原因. ...

  9. MSSQL-Scripter,一个新的生成T-SQL脚本的SQL Server命令行工具

    这里向大家介绍一个新的生成T-SQL脚本的SQL Server命令行工具:mssql-scripter.它支持在SQL Server.Azure SQL DB以及Azure SQL DW中为数据库生成 ...

随机推荐

  1. 1099. Build A Binary Search Tree (30)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  2. Java从入门到精通——数据库篇Oracle 11g服务详解

    装上Oracle之后大家都会感觉到我们的电脑慢了下来,如何提高计算机的速度呢?我们应该打开必要的服务,关闭没有用的服务.下面是Oracle服务的详解: Oracle ORCL VSS Writer S ...

  3. 常见前端面试题之HTML/CSS部分

    转自http://www.cnblogs.com/jscode/archive/2012/07/10/2583856.html Doctype是什么?如何触发严格模式与混杂模式模式?区分它们有何意义? ...

  4. Apache网站根目录

    Apache环境配置好了,把项目放到网站根目录下的htdocs文件夹下,运行网站的时候不需要加上该文件夹的名称,Apache直接在上面找对应的项目

  5. 结构体,公用体,枚举类型的sizeof

    1)枚举类enum型空间计算 enum只是定义了一个常量集合,里面没有“元素”,而枚举类型是当做int来存储的,所以枚举类型的sizeof值都为4 enum color(red,pink,white, ...

  6. UIScrollView显示超出屏幕大小的内容

    1:UIScrollView在初始化的时候可以指定frame,它的frame和其他控件不太一样的地方是: 它的frame指的的“可视大小”,也就是我们指定多大的frame来看一张图片,当然最大就是屏幕 ...

  7. 2014 Multi-University Training Contest 2

    官方解题报告:http://blog.sina.com.cn/s/blog_a19ad7a10102uyet.html ZCC Loves Intersection ZCC Loves COT 首先考 ...

  8. Introduction To Monte Carlo Methods

    Introduction To Monte Carlo Methods I’m going to keep this tutorial light on math, because the goal ...

  9. oracle Execute Immediate 用法

      包含using into用法. Declare        v_sid Integer:=20020101;        v_sql Varchar2(100);        v_resul ...

  10. Caffe训练好的网络对图像分类

    对于训练好的Caffe 网络 输入:彩色or灰度图片 做minist 下手写识别分类,不能直接使用,需去除均值图像,同时将输入图像像素归一化到0-1直接即可. #include <caffe/c ...