基于TILED的2D游戏绘制方法详解
2010-02-06 01:29
465 查看
1 Introduction
1.1 Purpose and Scope
游戏引擎作为游戏制作的基础是保证游戏质量的最重要部分,目前主要包括两方面:背景绘制和动画播放。为了使新员工对目前开发的手机游戏能够有深入的了解,此文档详细描述了目前使用的背景绘制的原理和具体实现方法。
1.2 Abbreviation
GD Game DesignBG Background
1.3 Reference
[1] Cao Heng, Gameloft, “Training Minutes For Game Tools”, V0.002.2 Tiled Background
2.1 什么是Tiled Background
游戏场景中的背景要展现出一副巨大的图像,它是游戏设计者表现游戏环境和氛围的重要手段。无论对于PC游戏还是其他平台的游戏,巨大的背景都会带来容量问题,而容量对于手机游戏更是十分宝贵的。为了使用尽量少的图绘制出尽量多的背景,背景图像由无数的等大小的图形组成,这些图形通常使用正方形。而这些图形的种类是有限的,只是每一个都可能被使用了很多次。就好像墙上的瓷砖一样,可以通过有限的种类拼出无限的组合。那么组成背景的图形就被称为Tile,而使用Tile 拼成的背景就被称为 Tiled Background。
最后,我们把拼接一副背景所用的所有 Tile 保存在一张图像中,就构成了我们在游戏中使用的图像资源,我们通常称之为 Tileset。并且,我们会把 Tileset 中的每一个 Tile 进行编号,顺序是从左到右,从上到下,如下所示。
0 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 |
4 | 5 | 7 | 18 | 8 | 4 | 5 | 7 | 18 | 8 | 4 | 5 | 7 | 18 | 8 |
9 | 0 | 1 | 11 | 13 | 9 | 0 | 1 | 11 | 13 | 9 | 0 | 1 | 11 | 13 |
10 | 6 | 17 | 2 | 12 | 10 | 6 | 17 | 2 | 12 | 10 | 6 | 17 | 2 | 12 |
3 | 16 | 15 | 19 | 14 | 3 | 16 | 15 | 19 | 14 | 3 | 16 | 15 | 19 | 14 |
4 | 5 | 7 | 18 | 8 | 4 | 5 | 7 | 18 | 8 | 4 | 5 | 7 | 18 | 8 |
9 | 0 | 1 | 11 | 13 | 9 | 0 | 1 | 11 | 13 | 9 | 0 | 1 | 11 | 13 |
10 | 6 | 17 | 2 | 12 | 10 | 6 | 17 | 2 | 12 | 10 | 6 | 17 | 2 | 12 |
3 | 16 | 15 | 19 | 14 | 3 | 16 | 15 | 19 | 14 | 3 | 16 | 15 | 19 | 14 |
4 | 5 | 7 | 18 | 8 | 4 | 5 | 7 | 18 | 8 | 4 | 5 | 7 | 18 | 8 |
9 | 0 | 1 | 11 | 13 | 9 | 0 | 1 | 11 | 13 | 9 | 0 | 1 | 11 | 13 |
2.2 Tiled Background的数据结构
通过上一节的介绍,我们可以知道,巨大的背景可通过一张很小的 Tileset 图和索引数组来绘制出来。在手机功能允许的范围内,程序还可以对 Tile 进行水平翻转(X Flip)和垂直翻转(Y Flip),这样就可以在背景中使用经过翻转的 Tile ,用于丰富背景图的内容。
2.2.1 XML 数据格式
为了通用性和可读性,在编辑阶段我们将 Background 的索引数组和相关数据保存为 XML 格式,这样不仅可以在 IE 等软件中浏览,更可以在 Notepad, UltraEditor, HexEditor 等工具中进行编辑。下面是一个 XML 文件的例子,该格式为公司内部定义。
<?xml version="1.0" encoding="UTF-8"?>
<Map width="160" height="176">
<Layer file="X:/mac.png" tilew="16" tileh="16" tilew_t="10" tileh_t="11">
<Data>16,16,16,16,-1,16,16,16,16,16,6,16,16,16,16,16,16,16,16,16,6,16,16,16,16,16,
16,16,16,16,6,16,16,16,17,1073741841,16,16,16,16,6,16,2,2,0,1073741824,2,2,2,2,6,16,7,7,5,1073741829,7,7,7,7,6,16,19,11,8,1,11,11,11,19,6,10,19,19,12,1073741836,15,15,19,19,13,14,536870930,536870930,536870930,536870930,536870930,536870930,536870930,536870930,9,18,18,18,18,18,18,18,18,18,4,4,1073741828,1073741828,4,4,1073741828,1073741828,4,4</Data>
</Layer>
<Layer file="X:/phb.png" tilew="16" tileh="16" tilew_t="10" tileh_t="11">
<Data>0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,3,3, 0,0,1,1,0,0,0,0,3,3,0,0,1,1,0,0,0,0,3,3,4,0,1,1,0,0,0,4,3,3,4,4,1,1,0,0,4,4,3,3,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3</Data>
</Layer>
</Map>
在例子中,我们可以看到紫色的为背景图的大小(单位为象素),绿色依次为 Tileset 图像文件的路径,Tile 的宽度,Tile 的高度,背景上每行的 Tile 数量,背景上每列的 Tile 数量,棕色即为索引数组。在索引数组中,每一个 Tile 的索引用一个4 Bytes的整数表示,如果索引值小于0(即二进制中的最高位为1),表示该 Tile 为空(即没有 Tile),为了便于记录,我们将二进制中的次高位和次次高位是否为1,分别用于表示每个 Tile 是否需要进行 X Flip 或 Y Flip。如例子中的-1就表示该位置没有 Tile,1073741828 (0x40000004)表示该 Tile 进行了 X Flip。
2.2.2 物理层的用途
在上面的XML文件中,有两层背景,第一层用于游戏中绘制背景,可称为显示层(Visual Layer),第二层不用于绘制背景,只以同样的形式记录每个 Tile 的物理属性,可称为物理层(Physical Layer)。为了给背景上不同的区域划分物理属性,比如有些区域人物可以通过,有些区域不能通过。我们使用另外一套 Tileset 拼出与显示层同样大小的物理层,我们的目的只是得到物理层的索引数组,用这套索引数组表示每一个 Tile 对应位置的物理属性,而不是将物理层画到屏幕中。
2.2.3 背景编辑工具
目前我们所使用的背景编辑工具为 ezPlayfieldEditor.exe ,它是Gameloft-Beijing内部使用的开发工具,由Java语言编写,使用 J2SDK1.4.2编译完成,因此在J2SDK 1.4.2的环境下才可以正常运行。它可以创建、读取、保存XML格式的背景数据,由于项目的不断创新,该工具还在不断的修改和完善中。
2.2.4 数据格式转换
XML文件并非游戏使用的最终资源,我们必须将XML文件转换为二进制文件,以便于程序使用和减少容量。所使用的工具为 Convert.exe ,与 ezPlayfieldEditor 一样,在公司内部开发和使用。二进制文件的数据结构与XML文件基本相同,同样包括每张背景的宽、高和Tile 的宽、高等信息。而对使用的 Tileset 图像文件进行了统一的编号,在二进制文件中只记录背景所用 Tileset 的编号。
由于各个项目都会对所用的二进制资源进行容量上的优化,所以具体格式不尽相同,这里就不举例介绍了。大家可以集思广益,不断创新,以达到容量最小,使用最便利的目的。
2.3 Tiled Background显示算法
显示算法就是通过二进制文件和Tileset图在屏幕上的绘制背景的算法。对于手机游戏来说,显示算法的速度是最重要得。2.3.1 逐块绘制法
当屏幕(红色框)要绘制背景上某一区域时,我们将涉及到的Tile(黄色区域)逐块绘制到对应的位置,就是逐块绘制法。逐块绘制法是显示背景的最基本的方法。0,0 X Y |
但是这种方法有一个致命的缺点,就是每帧都需要将所有涉及的 Tile 重新绘制到屏幕上,极大的影响了游戏的流畅度。为了提高速度,于是有了下面的缓冲绘制法。
2.3.2 缓冲绘制法
当屏幕在背景中移动时,实际上所涉及的 Tile 根本没有变化,或者只有一小部分发生了改变。所以我们可以创建一个背景图像缓冲(buffer),保存当前屏幕的背景图像,减少每帧得画图次数,可以大大提高速度。当我们创建的图像缓冲和黄色区域大小相同时,如果背景涉及的Tile没有变化,我们只需将缓冲图像画到屏幕的适当位置上。如果背景涉及的 Tile 发生了变化,如变为绿色区域,我们只需更新变化的部分Tile到背景缓冲,再将缓冲画到屏幕上即可。
0,0 X Y |
当然,按照屏幕在背景中的位置,我们的缓冲分区会出现四种情况。
l 分1个区,刚好背景没有被缓冲切开
l 分2个区,背景只在X轴方向被缓冲切开
l 分2个区,背景只在Y轴方向被缓冲切开
l 分4个区,背景在X、Y轴方向都被缓冲切开(如例子)
I II III IV |
IV III II I |
背景缓冲 |
实际背景 |
2.3.3 多层背景
背景和动画的图像是相同的,可以有透明效果。为了得到更加丰富的游戏背景,我们可以将两层甚至多层背景重叠,使背景的组合更多,更加复杂。多层背景与单层背景的原理完全相同,也使用一个背景图像缓冲,区别在于更新缓冲时,需要更新多次缓冲,每一个Tile的位置会被多个Tile按顺序更新。
2.3.4 游戏背景知识扩展
l 背景缓冲的大小背景缓冲图像的大小要大于屏幕最多可涉及的Tile的区域。
例如:
屏幕大小是128 X 128,Tile是 8 X 8,缓冲图像至少是
136 X 136 = (128 + 8) X (128 + 8)
屏幕大小是120 X 130,Tile是 8 X 8,缓冲图像至少是
128 X 144 = (120 + 8) X ((130+7)/8*8 + 8)
屏幕大小是 screenW X screenH,Tile是 tileW X tileH,缓冲图像至少是
(screenW+(tileW-1))/tileW*tileW+tileW X (screenH+(tileH-1))/tileH*tileH+tileH
l 背景缓冲的内存消耗
背景缓冲虽然可以提高游戏的速度,但是它所占用的内存也是十分巨大的。
在一般手机中,一张图片的大小为 长X宽X 2。
如背景缓冲的大小为 136 X 136,那么它所占用的内存为 36992 Bytes。
因为,我们可以认为使用背景缓冲是用内存换取速度的一种手段。
在游戏开发过程中,经常会利用内存换取速度,或者速度换取内存。
l 背景缓冲的滚动
当游戏的背景只用到了X轴滚动或者Y轴滚动时,我们的代码就可以进行优化,去掉不需要的滚动代码,可以减少一些容量的负担。
l 多层背景的限制
由于多层背景在更新缓冲时比单层背景要更多的绘图操作,因此更新缓冲的速度相对较慢。对于性能较差和背景滚动频繁的项目不宜使用这种方法。
另外,多层背景必然使用多个Tileset,而Tileset也会消耗大量内存,因此对于内存紧张的项目也不宜使用该方法。
相关文章推荐
- 一种在嵌入式环境下的2D游戏栅格地图绘制方法
- 基于生长的棋盘格角点检测方法--(3)代码详解(下)
- Unity3D 游戏引擎之游戏对象的访问绘制线与绘制面详解
- 基于一个简单定长内存池的实现方法详解
- 在unity3d开发2d游戏控制摄像机移动以及主角移动的方法
- bada 2D游戏编程之五——一个基于定时器的游戏循环
- Android游戏开发27:详解Android项目下的hdpi、mdpi和ldpi文件夹及设置游戏高清版本的方法
- 基于Stage3D的2D游戏加速框架:Starling介绍
- Cocos 2d-X Lua 游戏添加苹果内购(一) 图文详解准备流程
- 基于生长的棋盘格角点检测方法--(2)代码详解(上)
- 基于Android RxCache使用方法详解
- 基于js对象,操作属性、方法详解
- Android基于OpenGL在GLSurfaceView上绘制三角形及使用投影和相机视图方法示例
- 基于jquery ajax 用户无刷新登录方法详解
- 《Cocos2d-x for iPhone游戏开发实例详解---1.5 绘制OpenGL图元》
- Django基于ORM操作数据库的方法详解
- 基于js 各种排序方法和sort方法的区别(详解)
- 关于在MFC中实用在基于对话框窗口上面绘制折线的实现方法
- Android 3D 游戏学习笔记(2)-绘制方法
- 基于Bootstrap下拉框插件bootstrap-select使用方法详解