为了账号安全,请及时绑定邮箱和手机立即绑定

绘制等距游戏世界

绘制等距游戏世界

智慧大石 2019-10-12 14:27:49
在2D游戏中绘制等距图块的正确方法是什么?我已经阅读了一些参考资料(例如this),这些参考资料建议以这种方式渲染图块,这些图块将使地图的2D数组表示形式中的每一列都呈锯齿形。我想应该以菱形的方式绘制它们,在屏幕上绘制的内容与2D阵列的外观更紧密相关,只是稍微旋转一下即可。两种方法都有优点还是缺点?
查看完整描述

3 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

更新:纠正了地图渲染算法,添加了更多插图,更改了格式。


也许可以说将瓦片映射到屏幕的“之字形”技术的优势在于,瓦片x和y坐标位于垂直轴和水平轴上。


“画钻石”的方法:


通过使用“在钻石中绘制”绘制等距图,我相信这是指for通过在二维数组上使用嵌套循环来绘制地图,例如以下示例:


tile_map[][] = [[...],...]


for (cellY = 0; cellY < tile_map.size; cellY++):

    for (cellX = 0; cellX < tile_map[cellY].size cellX++):

        draw(

            tile_map[cellX][cellY],

            screenX = (cellX * tile_width  / 2) + (cellY * tile_width  / 2)

            screenY = (cellY * tile_height / 2) - (cellX * tile_height / 2)

        )

优点:


该方法的优点是它是一个简单的嵌套for循环,具有相当简单的逻辑,可在所有图块中一致地工作。


坏处:


这种方法的一个缺点是,地图上图块的x和y坐标将以对角线增加,这可能使得将屏幕上的位置直观地映射到以数组表示的地图上更加困难:


瓷砖地图的图像


但是,实现上述示例代码将有一个陷阱–渲染顺序将导致应该位于某些图块后面的图块被绘制在前面的图块之上:


错误渲染顺序导致的图像


为了解决此问题,for必须反转内部循环的顺序-从最高值开始,再向较低值进行渲染:


tile_map[][] = [[...],...]


for (i = 0; i < tile_map.size; i++):

    for (j = tile_map[i].size; j >= 0; j--):  // Changed loop condition here.

        draw(

            tile_map[i][j],

            x = (j * tile_width / 2) + (i * tile_width / 2)

            y = (i * tile_height / 2) - (j * tile_height / 2)

        )

通过上述修复,应该更正地图的呈现方式:


正确渲染顺序生成的图像


“之字形”方法:


优点:


“之字形”方法的优点也许在于,呈现的地图可能看起来比“钻石”方法在垂直方向上更加紧凑:


锯齿形渲染方法看起来很紧凑


坏处:


从尝试实现之字形技术开始,缺点可能是编写渲染代码有点困难,因为它不能像for在数组中每个元素上的嵌套循环那样简单地编写:


tile_map[][] = [[...],...]


for (i = 0; i < tile_map.size; i++):

    if i is odd:

        offset_x = tile_width / 2

    else:

        offset_x = 0


    for (j = 0; j < tile_map[i].size; j++):

        draw(

            tile_map[i][j],

            x = (j * tile_width) + offset_x,

            y = i * tile_height / 2

        )

另外,由于渲染顺序的交错性质,尝试计算图块的坐标可能会有些困难:


之字形顺序渲染的坐标


注意:此答案中包含的插图是使用所呈现的图块渲染代码的Java实现创建的,其中以下int数组为地图:


tileMap = new int[][] {

    {0, 1, 2, 3},

    {3, 2, 1, 0},

    {0, 0, 1, 1},

    {2, 2, 3, 3}

};

磁贴图像为:


tileImage[0] -> 一个盒子里面有一个盒子。

tileImage[1] -> 黑匣子。

tileImage[2] -> 一个白盒子。

tileImage[3] -> 一个带有高灰色物体的盒子。

关于瓷砖宽度和高度的注意事项


上面的代码示例中使用的变量tile_width和tile_height是指表示地砖的图像中地砖的宽度和高度:


该图显示了瓷砖的宽度和高度


只要图像尺寸和图块尺寸匹配,就可以使用图像的尺寸。否则,可以使用图块之间的间隙来渲染图块地图。


查看完整回答
反对 回复 2019-10-12
  • 3 回答
  • 0 关注
  • 512 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信