Skip to main content

数组在游戏开发中的应用

Feishiko
Author
Feishiko
Programming Avali
Table of Contents

很多游戏,像Tetris(俄罗斯方块)、Sokoban(推箱子)的逻辑实现都是依靠对数据的操纵,把离散的数据用数据结构储存起来,就能对其做很多事情。

比如在Tetris中,我们可以把每一块离散的空间都放到一个二维数组里面,然后给数组里面的每一个元素一个ASCII,比如#表示方块,.表示空位置。方块旋转的时候可以乘以一个2d旋转矩阵,然后让方块转动到对应的位置;当有一行全部被#挤满的时候,那一行将被删除,并且在上面的所有方块往下移动一格。然后我们可以把这个二维数组用绘图API画出来。

再比如Sokoban,我们可以用@表示玩家,#表示墙壁,O表示箱子,^表示坑。然后基于二维数组进行各种逻辑上的处理,比如要让玩家移动,要保证玩家前面不能有墙壁,举一个简单的例子,这里用lua

local map = []
for width = 1; i = maxWidth do -- lua的table自增从1开始!
    map[width] = []
end
-- 省略一些初始化过程~
-- ...
-- 如果玩家的左侧没有墙壁,那么玩家就向左移动一格
if map[player.x - 1][player.y] ~= "#" then
    player.x = player.x - 1
end

只要你掌握了怎么操纵数组,那么对于很多功能的实现就会变得非常简单!像关卡生成或者寻路算法等等,都需要对数据进行各种操纵。

甚至关卡编辑器我们也可以使用各种格子。

在SHENZHEN I/O中,玩家如果要制作自己的关卡,就要自己写lua,其中关卡编辑器就是一个asciiMap!玩家把地图用ascii的方式打成字符串,然后后台就会把这个table拿去解析成一个二维数组。

我自己用一些比较原始的游戏引擎做游戏的时候,也喜欢写asciiMap,然后解析成二维数组,进而写一些逻辑。

再比如寻路算法,如果你的游戏地图是用二维数组表示的,那么就能通过操纵各种数据来实现寻路。这里我们用一个叫做BFS的算法。

使用BFS需要一个Quene,我们简略画一个地图。其中下面的@是玩家,E是敌人,#是墙壁,.是空地

#########
#E..#..@#
#..#.#..#
#.......#
#########

首先我们要创建另一个二维数组,#标记为-9999,空地标记为0,@标记为0,E自身是9999。在@的位置对四周非-9999的进行标记,此轮标记为1,然后把标记为1的位置记录到Quene,Quene的原则是先进先出。

#########
#E..#.1@#
#..#.#.1#
#.......#
#########

接下来就可以对1的这个位置做刚才一样的事情,但是我们是从Quene里面提取的位置,直到Quene没有东西为止。之后的asciiMap应该大致如此:(x表示10,因为这里放不下了)

#########
#E9x#21@#
#98#6#21#
#8765432#
#########

然后E(敌人)就可以找周围更小一点的数,如果更小就走这一格,最后就能走到玩家的位置。

再比如Solitaire(单人纸牌),像蜘蛛纸牌/空当接龙之类的,也很需要对数组进行操纵

Solitaire有很多行,很多列,然后每一个元素里面存一个数字,数字表示对应的牌,举个简单的例子:

1 8 15
2 9 16
3 10 17
4 11 18
5 12 19
6 13 20
7 14 21

随便打了一点,当然正常Solitaire是随机的,乱序的,不像我这么整齐。

我们都知道,扑克牌一共四种花色,每种花色13张牌,我们就可以1-13一个花色;14-26一个花色以此类推。

再然后我们可能要堆叠牌,比如我们要把红桃7放到红桃8上面,这里红桃是1-13,那么我们要判断当前牌的id+1是否等于要放到的牌上面(是否等于8)

总结
#

所以对于很多游戏来说,数组是一个很强大的工具!如果你能很好的用在你的游戏上,这会很有帮助!