实际上, 这个问题早在文本模式的程序就已经出现过. 那就是表格线的处理. 文本模式下, 不能绘制直线, 我们需要绘制表格时, 就需要利用 ASCII 字符来拼接出需要的图形. 成功的文本编辑器, 都具有绘制制表线的功能. 其中最需要解决的问题就是表格线交叉时, 如何正确的选择合适的 ASCII 码.
如果采用多层条件判断是很愚蠢的方法. 最简洁的程序是将拼接用的图素按一定的次序 (序号的 2 进制形式可以反映周围的连接状态) 排列. 然后通过简单的公式计算出正确的元素. 具体就是说, 将上下左右的连接用 4 位 2 进制数表示出来. 通过读取当前图素的上下左右的图素是否有连接来生成一个数字, 查表得到正确的图素. :-)
下面附有一个小程序, 可以完成上述的功能, 感兴趣的朋友可以读读 :-) /*
墙壁交叉 Tile 的处理. 类似于文本方式的制表符处理, 我们需要针对制表线的交叉输出正确的 ASCII 码.如果 采用多层条件判断是很愚蠢的方法. 最简洁的程序是将 拼接用的图素按一定的次序 (序号的 2 进制形式可以 反映周围的连接状态) 排列. 然后通过简单的公式计算 出正确的元素.
如下程序演示了这一算法, 其输出结果如下
┏━━┳━━━┳━┓ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┫ ┃ ┃ ┃ ┃ ┏┻━┓ ┃ ┃ ┃ ┃ ┃ ┃ ┗━━╋━━━┫ ┃ ┃ ┃ ┃ ┃ ┃ ┗━━━━┻━━━┛
程序没有注释, 但应当很容易理解. 如有问题, 可以联系 作者 cloudwu@263.net
Homepage: http://member.netease.com/~cloudwu
云风作于 1999 年 9 月 20 日 */
#include
char wall[32]=\
char map[MAX][MAX]={ \ \ \ \ \ \ \ \ \ \ \ \};
int main() {
int i,j,id;
for (i=1;i if (map[i][j]=='.') printf(\ else { id=(map[i][j-1]=='o')<<3|(map[i+1][j]=='o')<<2|(map[i][j+1]=='o')<<1|(map[i-1][j]=='o'); printf(\ } printf(\ } return 0; } Tile Based Engine的设计 - 遮挡处理 所谓 Isometric, 应该是指等距视角, 和透视相对, 指视野内的物体, 无论远近都用同一大小来表现. 而Tile 就是指的砖块, 我们平常所见的许多 2D 游戏, 都是 Tile 的. 比如新出的决战朝鲜, 还有去年的皇朝霸业;-), 这两个游戏都是典型的 Tile 游戏, 游戏中的元素被分割为一个个的砖块拼装起来. 不同的是, 前者是矩形的 Tile, 而后者是 Isometric 的. 它的Tile 有高度, 底面为一个菱形. Isometric 的外观更接近真实物体, 我个人比较喜欢这样的图形表现形式. 由于 Isometric 的 Tile 相互覆盖, 所以就有了遮挡问题, (传统的矩形Tile是没有遮挡问题的, 但其扩展也需要处理这个,不过比Isometric的简单), 这也许是Isometric Tile 引擎设计的一个难点, 本文 的重点就在于介绍云风的处理方法. 先来看看 Isometric 下的地图, 这里由一个个菱形拼起来,每个菱形就是一个 Tile 的底面, 我将每个 Tile 编了号, 是按游戏世界的坐标编的, 组织数据的时候完全可以按照这个形式在内存开一个2D 数组描述地图. 实际上你也可以按照屏幕的横竖方向编坐标, 处理时注意这时奇数行和偶数行Tile的屏幕坐标相差半个 Tile 宽就可以了, 这样处理也很方便, 实际上两种坐标可以用一个很简单的公式换算, 本文不使用这种坐标,在此不提. 如果你不想为遮挡的问题而烦恼, 最简单的处理方法是每次产生一症图象的时候, 按从左上到右下,从右上到左下(就是游戏世界中的从左到右,从后到前)的顺序把每个Tile画一遍就够了. 但是这对于 Isometric 来说是很大的浪费, 因为 Isometric 中每个Tile 都是等大的,遮挡关系一目了然. 一般我们将Tile 的高度单位设置成 Tile 底面矩形的高,方便处理(如下图). 当游戏世界是单层时,这样一个最小单位的Tile, 它可能被比它的 (x,y) 坐标大 1 的 Tile 共 3 块遮挡. 同样, 如果一个精灵占了 4 个 Tile,可能遮挡它的 Tile 为 5 个. 如果物体有两层, 可能遮挡这个 2x2 物体的 Tile 就是10个, 依此类推. 现在来看一个例子, 上图中, 有两个(固定)物体, 树是 2x2 的, 它占据了 (2,2) (2,3) (3,2) (3,3) 四个Tile, 石块是 1x1 的, 占据了 (1,3) 这个 Tile. 大象(精灵) 也是 2x2 的,目前它在 (0,1) (0,2) (1,1) (1,2) 这4个 Tile 上. OK, 看看另一张图: 更清楚一些. 一般来说, 绘制 Isometric 的场景分 2 步, 先产生固定的场景,再绘制精灵.精灵由于是运动的, 所以通常每帧图都要重画一次(当然也可以不用全部重画, 让每个精灵的运动频率不同, 动画交错, 提高速度, 这个技术比较复杂, 在我的超越 Isometric Tile Engine 中使用的效果不错:-) 这个例子就是要说明图中的大象是怎么画的: 大象占据的是 (0,1) (0,2) (1,1) (1,2) 4 个Tile, 单层地图中可以遮挡它的 5 个 Tile 分别是 (2,1) (2,2) (2,3) (0,3) (1,3), 这 5 个坐标很容易求得, 最简单的方法是将 大象占据的 4 个 Tile 的坐标都加 1,(从 (x,y) 推出 (x+1,y) (x+1,y+1) (x,y+1) ), 把推出的 12 组坐标中重复的删掉. 当然这不是最好的算法, 这儿只是举个例子. 从地图上可以得到, (2,2) (2,3) (1,3) 上放有物体, 其中 (2,2) (2,3) 是 同一棵树的两部分, 所以只算一个. (1,3) 上是一个石块. 下一步, 我们设置一个剪裁矩形将画大象的区域框起来, 再向上面绘制遮挡它的树和石块. 注意,这里剪裁矩形的设置是不能少的, 否则这个遮挡问题处理完了, 又会引出新的遮挡问题 ;-) 具体步骤如下: --> --> --> 可以看到, 传统的 Isometric Tile 引擎的优点正在于遮挡处理简洁, 速度快. 所以我个人观点就是, 如果要2D 游戏图形引擎要革新, 就全部采用新的复杂的手段, 使其完全摆脱 Tile, 所有的物体都是任意凸多边形, 精灵行走方向任意, 物体高度任意. 否则就采用传统的 Isometric Tile 型, (到目前的经典 2D 游戏几乎都是很正统的Tile Base 的, 比如 Diablo, Starcraft...) 以获得高的处理速度. 从速度和效果两方面看, 界于中间的处理方法,就不是很可取了。 Tile Based Engine的设计 - 坐标变换 Isometric Tile的处理比矩形的稍微复杂一点的地方在于屏幕是矩形的, 而反映出来的游戏世界的坐标轴有些不同. 无论是精灵的移动, 还是处理 Tile 都需要经过坐标变换. 而一个屏幕的区域在游戏世界的地图上却成了一个菱形. 我想,所有第一次设计 Isometric Tile 引擎的程序员都为这个烦躁过 (自己的感受啦;-) 不排除因为这个原因修改自己的原始设计的可能性 ^_^. 实际它一点也不复杂,但需要你静下心来用直尺在白纸上画一张示意图. (注意:如果你贪图一时的便宜,而随手用铅笔比画,只会使你的心情更烦躁) 或者按云风的习惯用C程序来作图(推荐使用风魂 等方便的图形库;-) 当然你 AutoCAD 玩的好的话, 用 ADS 也非常方便. 这些方法不只针对这个特定问题, 我想每个程序员都应该养成这些良好的习惯 ;-) 这里云风为你做了这步. 看下图: 百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库游戏编程文章搜集资料(5)在线全文阅读。
相关推荐: