到本系列文章的前四篇为止,我们已经完成了一个简单的游戏,Ray Wenderlic的那篇文章也翻译完了。但实际上工作还没有结束。游戏开发者应该没人愿意像前文那样,把图片和音乐资源存储在公开的文件目录下,被人拷走就能轻易被山寨了。所以这篇里我们先来讲下怎么对资源进行打包,最后和程序混在一起,编译成一个二进制文件发布。这个资源打包工作是uPhone机制提供的。

一、图片和音乐资源打包

前面的Cocos2dSimpleGame中,如上图,我们一共使用了5张图片资源:

图片名称

图片用途

CloseNormal.png

关闭按钮的正常状态图片

CloseSelected.png

关闭按钮被点击时的图片

Player.png

带头大哥

Projectile.png

带头大哥的暗器

Target.png

不知死活的小喽啰

下面,我们使用Uphone开发平台自带的资源编辑器TOPS Builder将资源进行打包。步骤如下:

1. 使用 TOPS Builder 打开游戏的资源工程:

双击 D:\Work7\cocos2d\Cocos2dSimpleGame\Res\Cocos2dSimpleGame_Res.TRG 文件,这就打开了游戏的资源工程,运行的界面如下图:

2. 将需要使用的图片和音乐添加到资源编辑器中

在资源编辑器中添加图片的示意图如下:

  • 首先,单击图中 1 所示的"Bitmaps"标签,进入图片资源编辑分页;
  • 然后,右击图中 2 所示的空白区域,弹出如图中 3 所示的菜单,选择“添加图片”,即可选择图片加到资源比编辑器中。
  • 添加成功后,图中 2 所示的空白区域会把已添加的图片名字列出。
  • 使用同样的方法添加音乐资源(mp3,wav等),但注意第一步选资源类型时,应点到"Raw data"标签内

3. 对添加的资源进行编译

在资源编辑器中,点击界面左上角的闪电符号按钮,对资源进行编译。

注意:在进行编译之前,需要讲使用的图片、音月资源文件添加到代码的Visual Studio工程中,添加后Visual Studio工程的文件视图如下:

注意:此编译过程是将图片文件的数据以 Uphone 内部的结构形式保存到 .h 文件中,并为每个图片资源分配一个资源 ID,在应用中通过该 ID 使用该图片资源。编译后,你可以看到这个巨大的.h文件D:\Work7\cocos2d\Cocos2dSimpleGame\Res\cocos2dsimplegame_res_def.h 。

通过上面的几个简单步骤,我们就完成了资源打包。这样我们的游戏在编译完成后,资源和代码就在同一个二进制包里了

二、在cocos2d游戏中使用打包的资源

资源打包的工作完成了。接下来我们就可以在cocos2d游戏中使用这些资源了。使用前,我们先了解一下普通的Uphone应用是如何使用打包资源的

1. 普通Uphone应用使用打包资源的方法

在Uphone SDK中,有一个TResource类,这个类提供了静态接口函数用于获取当前上下文的bitmap和rawdata资源数据,接口及注释是这样的:

/**
@brief  获取当前上下文资源里的图片类实例。

此函数返回的TBitmap实例,无须释放。
@param nResId 资源ID。
@return TBitmap指针。
*/
static const TBitmap * LoadConstBitmap(Int32 nResId);

/**
@brief  获取当前上下文资源里的原始数据。

此函数直接返回资源中的原始数据的地址(即原始数据内容不可更改)。
@param nResId 资源ID。
@param puLength 原始数据长度。
@return 原始数据指针。
*/
static const void * LoadConstRawData(Int32 nResId, UInt32 * puLength = NULL);

所以,在Uphone应用中只要使用如下代码就可以加载图片资源了:

const TBitmap* pBmp = TResource::LoadConstBitmap(COCOS2_ID_BITMAP_CloseNormal);

2.  cocos2d-x游戏中使用打包资源的方法

上面的资源调用方法对cocos2d-x开发者来说功能不够强、不够跨平台,也不能很好地解决不同分辨率匹配不同资源的问题。同时,用资源ID调用的方法比较类似于windows mobile,而对于习惯了cocos2d-iphone的开发者来说,文件名会更符合一些。所以我们做了一个哈希表来实现 文件名(key)-> 资源ID(value) 的映射,cocos2d-x开发者只要实现填写好这份映射,然后游戏里就可以用文件名来调用资源,甚至不用理会这个资源是暴露在文件目录里还是打包编译在资源包里。

(1) 首先,建立一个资源名称字符串与资源ID的映射

我们添加一个Resource.h头文件来保存这个映射,头文件中代码如下:

#ifndef _RESOURCE_H_
#define _RESOURCE_H_

#include "SimpleAudioEngine.h"
#include "cocos2dsimplegame_res_def.h"
#include "cocos2d.h"

const T_ResourceInfo ResInfo[] =
{
    { "CloseNormal",    COCOS2_ID_BITMAP_CloseNormal },
    { "CloseSelected",  COCOS2_ID_BITMAP_CloseSelected },
    { "Player",         COCOS2_ID_BITMAP_Player },
    { "Projectile",     COCOS2_ID_BITMAP_Projectile },
    { "Target",         COCOS2_ID_BITMAP_Target },
    { "CloseNormal@WVGA",    COCOS2_ID_BITMAP_CloseNormal_WVGA },
    { "CloseSelected@WVGA",  COCOS2_ID_BITMAP_CloseSelected_WVGA },
    { "Player@WVGA",         COCOS2_ID_BITMAP_Player_WVGA },
    { "Projectile@WVGA",     COCOS2_ID_BITMAP_Projectile_WVGA },
    { "Target@WVGA",         COCOS2_ID_BITMAP_Target_WVGA },
};

/**
@warning 在声音数据信息的结构体中,FileName必须包含文件的扩展名,并且需要与原始文件的扩展名一致
         否则无法播放
*/
const T_SoundResInfo SoundResInfo[] =
{
    { "background-music-aac.mp3",     COCOS2_ID_RAWDATA_background_music_aac },
    { "pew-pew-lei.wav",              COCOS2_ID_RAWDATA_pew_pew_lei },
};

#endif

这里面@WVGA的资源,将在下一篇文章中解释

(2) 其次,需要让游戏引擎“知道”这个映射关系的存在:

  在Cocos2dSimpleGameAppDelegate.cpp文件的initCocos2d() 函数中添加代码如下(当然,别忘记添加Resource.h这个头文件)

// set the ResourceEntry and Images ResInfo (name and ResID)
CCFileUtils::setResourceInfo(ResInfo, 
                             sizeof(ResInfo) / sizeof(T_ResourceInfo));

// set the ResourceEntry and sound ResInfo (filename and ResID)
SimpleAudioEngine::getSharedEngine()->setSoundResInfo(SoundResInfo, 
                                                      sizeof(SoundResInfo) / sizeof(T_SoundResInfo));

(3)  第三,需要让游戏引擎“知道”当前的上下文

在上面我们了解了普通Uphone应用通过TResource类来获取上下文资源。现在游戏引擎已经“知道”了打包资源的ID,但是还需要让游戏引擎“知道”当前的上下文信息,它才能根据资源ID获取数据。具体做法如下

extern const AppResourceEntry Cocos2dSimpleGameResourceEntry;

(a) 在D:\Work7\cocos2d\Cocos2dSimpleGame\main.cpp文件中,使用extern声明变量Cocos2dSimpleGameResourceEntry

#include  "cocos2dsimplegame_res_c.h"

const ResourceRegisterEntry ResRegList_Cocos2dSimpleGame[]  =
{
    TG_RESOURCE_DEFINE
};

extern const AppResourceEntry Cocos2dSimpleGameResourceEntry  =
{
    (ResourceRegisterEntry*)ResRegList_Cocos2dSimpleGame,                     // res list in this app
    sizeof(ResRegList_Cocos2dSimpleGame) /  sizeof(ResourceRegisterEntry),    // number of item in res
};

(b) 在Cocos2dSimpleGameAppDelegate.cpp文件头部添加代码

extern const AppResourceEntry Cocos2dSimpleGameResourceEntry; 

并在initCocos2d() 函数中,在上面步骤(2)的基础上,把代码改成

// for cocos2d-x, set the ResourceEntry and Images ResInfo (name and ResID)
CCFileUtils::setResourceEntry(&Cocos2dSimpleGameResourceEntry);
CCFileUtils::setResourceInfo(ResInfo, sizeof(ResInfo) / sizeof(T_ResourceInfo));

// for cocosDenshion, set the ResourceEntry and sound ResInfo (filename and ResID)
SimpleAudioEngine::getSharedEngine()->setResourceEntry(&Cocos2dSimpleGameResourceEntry);
SimpleAudioEngine::getSharedEngine()->setSoundResInfo(SoundResInfo, sizeof(SoundResInfo) / sizeof(T_SoundResInfo));

之所以需要两步,是因为cocos2d处理图像,cocosDenshion处理音频,是两个不同的库。

(4) 最后,就可以使用打包的资源了

CCSprite *player = CCSprite::spriteWithFile("player.png");

或者

CCSprite *player = CCSprite::spriteWithFile(ResInfo[2].ResName);

实际上,对于按照前面教程开发的代码,在这里就不用修改一字了。

在 Uphone 平台下,游戏引擎根据图片名称创建 Texture 的逻辑为:根据传入的字符串先在设置的ResInfo映射表中查找是否有相应的资源ID,如果存在则加载并成功返回;如果不存在,则到文件目录下查找同名文件,若还是找不到则加载失败。

特别注意

1. 如果打包的资源都是直接进行使用的话,在ResInfo这个映射里的资源名称可以随意设定。但是,当打包的图片资源是被 .plist / .tmx / .fnt 等配置文件指定要使用的图片时,资源名称就不能随意设定了。示例如下:

// 代码要用.plist 文件创建SpriteFrames,其中grossini.plist 文件指定要使用 XXX.png
CCSpriteFrameCache::addSpriteFramesWithFile("animations/grossini.plist");

那么在Resinfo中图片XXX.png的资源名称就必须为 "animations/XXX.png" ,这样才能让游戏引擎找到

2. 建议在给cocos2d-x用的ResInfo中资源名称包含原始文件的扩展名。而给cocosDenshion用的T_SoundResInfo中,资源名则必须明确是.mp3还是.wav,否则SimpleAudioEngine无法识别该资源的解码类型

 三、交叉编译

交叉编译的方法,在Uphone开发文档里有详细描述,这里就不重复了。对于cocos2d-x游戏来说,首先得把cocos2dx, CocosDenshion, chipmunk, Box2D这几个库编译好。我们已经做好了makefile文件,现在只要把四个目录挨个进去,敲一行

make -f Makefile.ARM all

就可以了。生成的.so文件都在 D:\Work7\PRJ_TG3\LIB\ARMLib 目录下。

而我们新开发的Cocos2dSimpleGame, 得在Makefile.ARM文件里增加一些DEFINE, PATH和链接的LIB,如下

DEFINES += -DCCX_UNDER_UPHONE
INCLUDE_PATH += -I. \   
                -I./Res \
                -I../cocos2dx \
                -I../cocos2dx/include \
                -I../cocosDenshion/include
LIBS +=-lcocos2d -lCocosDenshion -lTG3_EGL -lTG3_GLESv1_CM

LIBS里面,第一个是cocos2d图形库,第二个是CocosDenshion音效库,然后是EGL库和GLES 1.1的库。虽然Uphone上有GLES 2.0,但cocos2d仍然使用1.1

同上面那条指令一样make之,我们就可以看到libCocos2dSimpleGame.so这个文件生成在 D:\Work7\PRJ_TG3\LIB\ARMLib 目录下了

四、安装包制作

和uphone普通应用的打包过程一样,详细步骤的文档在uphone开发指南和开发者社区里都有。在 D:\Work7\PRJ_TG3\Tools\ 目录下有个 TG3_Publish_Maker_V1.04.exe ,启动之。然后填入安装目录、装入libCocos2dSimpleGame.so, 选择好桌面快捷图标就行了。

实际上,我们已经把Cocos2dSimpleGame的安装包配置文件保存为Cocos2dSimpleGame\pak\Cocos2dSimpleGame.TG3_IProc了,您可以从安装包制作工具里点“从文件加载”,并选择上述的TG3_IProc文件,就可以看到所有参数应如何填写。然后,点图中左下角的“生成安装包”,就会生成一个Cocos2dSimpleGame.TGI安装文件。这就是最后结果了。可以直接拷到手机里安装,或者发布到应用商城里。

《如何用cocos2d-x来开发简单的Uphone游戏 》这系列教程到这篇就结束了。后面我会从cocos2d-iphone上翻译更多的cocos2d-x文章过来。最后,祝所有用cocos2d引擎的开发者:游戏卖座、大把赚钱!

本文转自Walzer博客园博客,原文链接:http://www.cnblogs.com/walzer/archive/2010/10/22/1858155.html,如需转载请自行联系原作者

如何用cocos2d-x来开发简单的Uphone游戏:(五) 打包和发布相关推荐

  1. 如何用cocos2d-x来开发简单的Uphone游戏:(二) 移动的精灵

    三.添加一个精灵 我们先用个简单的方式,把player, projectile, target三个PNG文件拷贝到 D:\Work7\NEWPLUS\TDA_DATA\UserData 目录下,这使其 ...

  2. [20110209]Cocos2dSimpleGame入门系列《如何用cocos2d-x来开发简单的Uphone游戏》学习小记

    原文: http://www.cnblogs.com/walzer/archive/2010/10/10/1847089.html 拜读王哲王总的cocos2d-x入门教程,将学习过程中对C++或co ...

  3. 翻译:如何用Cocos2d来开发简单的IPhone游戏教程

    这一周接触到Cocos2D开发,在它的官网上看到Ray Wenderlic写的关于cocos2d开发的文章,感觉写的挺好,翻译了一下.  原文链接地址大家可以在上面看到作者的更多内容 初次翻译文章,望 ...

  4. Cocos2D教程:使用SpriteBuilder和Cocos2D 3.x开发横版动作游戏——Part 2

    本文是"使用Cocos2D 3.x开发横版动作游戏"系列教程的第二篇,同时也是最后一篇.是对How To Make A Side-Scrolling Beat Em Up Game ...

  5. 开发html5 2d 赛车游戏以及打包发布为手机APP 第一话 工欲善其事

    按照昔日做给上头拿去找汽车商卖钱的一个赛车游戏APP的经验来说明这个例子(不过当然只说有关游戏的部分) 思路:一幅赛道画面,赛道上面有一辆主角车,可以由玩家用手指拖拽去控制赛车的移动 设置计时器,画面 ...

  6. Cocos2D教程:使用SpriteBuilder和Cocos2D 3.x开发横版动作游戏——Part 1

    本文是对教程How To Make A Side-Scrolling Beat Em Up Game Like Scott Pilgrim with Cocos2D – Part 1的部分翻译,加上个 ...

  7. 如何使用cocos2d-x 3.0来做一个简单的iphone游戏教程(第一部分)

    游戏截图: cocos2d-x 是一个支持多平台的开源框架,用于构建游戏.应用程序和其他图形界面交互应用.Cocos2d-x项目可以很容易地建立和运行在iOS,Android的三星Bada,黑莓Bla ...

  8. HiLink LiteOS IoT芯片 让IoT开发简单高效

    HiLink & LiteOS & IoT芯片 让IoT开发简单高效 华为HiLink & LiteOS & IoT芯片使能三件套,让IoT开发更简单高效.下一代智能手 ...

  9. Unity 2D游戏开发快速入门第1章创建一个简单的2D游戏

    Unity 2D游戏开发快速入门第1章创建一个简单的2D游戏 即使是现在,很多初学游戏开发的同学,在谈到Unity的时候,依然会认为Unity只能用于制作3D游戏的.实际上,Unity在2013年发布 ...

  10. 使用 Node.js 开发简单的脚手架工具

    前言 像我们熟悉的 vue-cli,react-native-cli 等脚手架,只需要输入简单的命令 vue init webpack project,即可快速帮我们生成一个初始项目.在实际工作中,我 ...

最新文章

  1. mysql mha官网下载_mysql MHA 及多主复制
  2. h5怎么加入php代码,HTML5主要新增标签的使用代码分享
  3. 使用Docker-容器命令案例2
  4. 【Python】简单的apscheduler定时任务
  5. [蓝桥杯][算法训练VIP]接水问题(思维)
  6. E1 PCM复用设备作用
  7. python 进程池不足_python 进程池pool简单使用
  8. SpringBoot自定义Filter
  9. (13)System Verilog typedef创建新数据类型
  10. int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
  11. oracle磁盘组实例启动,12c rac 实例无法启动之磁盘组空间耗尽
  12. react 返回一个页面_react-router-dom 怎么让第二个页面返回到第一个页面使得第一个页面不重新加载...
  13. 徐明星解读区块链与物联网的重要联系
  14. linux拆分文件会影响源文件吗,linux split拆分文件
  15. 软件测试基础 ——— 测试分析
  16. 分享免费下载论文的网站
  17. MySql查询之单表查询 --附练习素材
  18. python暴力破解WiFi
  19. 全志A31编译脚本 .
  20. 数据库分页数据丢失问题

热门文章

  1. CATIA二次开发过程中几个问题
  2. stony大学计算机科学找工作,福布斯排名:这些大学的STEM专业毕业生薪资最高!...
  3. 使用java进行远程控制,java实现远程控制
  4. 单片机 TDA8023 读 ic 卡 smrat card sync_card
  5. vs2019豆沙绿背景色及consolas字体设置
  6. CEC2018:动态多目标测试函数DF6~DF9的PS及PF(提供Matlab代码)
  7. 我用计算机的故事,计算机老师的我的教育故事随笔
  8. 10个互联网兼职平台,让你的一技之长变现,副业薪资比日常搬砖高也太爽了
  9. 计算机无法识别建行网银盾,为你修复建行网银盾无法识别 【应对方案】 的详细方案_...
  10. 解决微软应用商店打不开 代码: 0x80131500