网页功能: 加入收藏 设为首页 网站搜索  
游戏中的地图
发表日期:2007-01-17作者:[转贴] 出处:  


关于地图:

《仙剑奇侠传》地图图块(Tile)的大小为32X16(以象素为单位)。
实际每个图块的大小为32x15(以像素为单位),通过拼接刚好天衣无缝。
地图大小为128x128(以图块为单位)。

排列方式如下:
0 2 4 6 8…… // 第0行
 1 3 5 7 9……
0 2 4 6 8…… // 第1行
 1 3 5 7 9……

采用这种方式的好处是很容易确定那些图块在屏幕可见范围内,每次只画可见部分。

地图分为底层和表层共两层。每个图块属性占4个字节(底层和表层各2字节)。
所以整个地图的大小为:128x128x4=64K字节。(太巧了,不是吗?DOS下内存一个段就这么大)

每个图块的属性格式如下:

typedef struct
{
unsigned No:8; // 图块序号
unsigned Height:4; // 图块高度
unsigned Add:1; // 图块序号高位
unsigned Block:1; // 障碍标志(这儿不能走,比如说墙根)
unsigned Actor:1; // 人物标志(有人站在这儿NPC)
unsigned Switch:1; // 地图切换标志(人物走到这里要切换到另一个场景)
} TCell;


注释:
1、设GroundNo = 4,如果GroundAdd = 1,那么实际的GroundNo += 256,即GroundNo = 300。
2、每个地图最多由2的(8+1)次方即512种不同的图块拚成。实际应用中大约每个地图用到300种图块。
3、人物大约是3个图块高,所以4位Height足够处理人物与场景的遮挡效果。

关于人物:
  
人物处在底层和表层之间,通过图块的高度处理人物与场景之间的遮掩关系。

但是人物之间也有前后关系,怎么处理呢?
我的方法是建立一个人物链表,利用画家算法。
人物的先后关系很容易计算:先比较Y,再比较X,小的先画。

可是,可能出现这样的情况(实际游戏中可能更复杂,这里只是一个简要的举例):
魔法师站在骷髅的尸体上,正在释放圆形闪电魔法,又被敌人释放的四处乱跑的火人击中。
所以,在同一个图块上,同时存在几个精灵:骷髅、闪电上部、魔法师、闪电下部,火人。

解决的方法是每个精灵有一个属性字段:BYTE Level;表明它所处的层。
层可以如下定义:(仅仅是个例子,不是真的这样做的)

const // Sprite Level
slDeadBody = 1, // 尸体层
slSpellUnder = 2, // 下层释放魔法层
slSprite = 3, // 精灵层
slSpellAbove = 4, // 上层释放魔法层
slSpellHit = 5, // 攻击魔法层
slFree = 6, // 自由层(天空中飞鸟、蝴蝶等)
……


综合起来,精灵的先后顺序通过3个数即可确定:Y, X, Level。

动态场景:

多数游戏的场景都比较死,缺乏生气。即使象Diablo这样的游戏,村中的小河和喷泉水池也不会流动,树也不会随风摇摆。因为动态确实有难度。

在256色游戏中最常见的做法是调色板动画。即通过动态改变256色调色板中某些色彩的值(通常是轮流替换),来实现水波荡漾的效果。

还有一种方式是通过标准的(通常是正方形)多帧动画(如水波)结合地图掩码做剪裁,游戏运行时以固定的频率顺次贴动态地表的各帧,从而实现动态地表的效果。最成功的例子我认为是Commandos。
详细内容参阅: 云风工作室——斜视角图形引擎的设计——动态地表的实现http://www.netease.com/~cloudwu/

在16位色彩模式中第一种方法失效,需要加以变通。比如使用多调色板,每个图像依然以256色模式保存,运行时实时查表。第二种方法依然有效。

在吸收这几种方法的优点的基础上,我设想了另一种方法。
地图数据实际上有两部分:一个二维矩阵,描述每个图块的属性;一个一维数组,保存各种不同图块的图像数据。如果我们把一维图像数组比作256色模式下的调色板,就可以发现,使用与调色板的动态技术同样可以用于地图地表的动态效果。详细方法就不罗嗦了。

在实际应用中,我们通常都会对标准的方法加以变通,根据自己的需要有取有舍。
在程序设计里没有必须这样或必须那样的铁律。即使是同一个算法,同一个数据结构,每个
程序员的具体实现都可能不尽相同。

我的游戏引擎(不好意思,很久没更新了)就不是按上面提到的格式做的。不过原理大同小异。


我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 游戏中的地图
本类热点文章
  脚本系统的实现
  C++基本功和 Design Pattern系列(2) Ty..
  C++基本功和 Design Pattern系列(1) - ..
  斜45度游戏开发(提高篇)
  睱酵笴栏祘Α砞璸?? - [秈顶絞]
  斜45度游戏开发(二)
  第一次写技术文献。Collision AI
  斜视角游戏中遮挡的判断
  C语言基本功教程系列(5) - 文件, Socke..
  用rand()和srand()产生伪随机数的方法总..
  C语言基本功教程系列(1)
  C++基本功和 Design Pattern系列(3) co..
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00457