游戏邦在:
杂志专栏:
gamerboom.com订阅到鲜果订阅到抓虾google reader订阅到有道订阅到QQ邮箱订阅到帮看

论述迷宫游戏玩家精灵的网格移动模式

发布时间:2012-04-27 13:41:16 Tags:,,,

作者:Mark

我觉得有必要分享下自己处理方格运动的方式。这绝非终结模式,只是现在它能够带来令人满意的结果。

在我制作的所有游戏中,我通过基本方框方式进行触碰测试。在节奏合理的街机游戏中,精灵通常会填充方框,所以这不是个问题,因为玩家不会注意到有几个像素出现错误。除此之外,我总是在恰当时候突出有利于玩家的触碰路径。

在迷宫游戏中,我通过不同方式判定玩家精灵是否需要同迷宫墙触碰。

游戏呈现于32 x 32像素区块的10 x 15方格。区块其实就是精灵,因为我想要激活它们(游戏邦注:例如在动画框架中循环,移动至关卡加载位置,在游戏中调整尺寸及进行移动)。但和其他游戏精灵不同,我不会采用标准的触碰路径。在既定游戏时刻,玩家或a)处在能够转化成网格坐标的准确位置;b)或在两个网格坐标间移动。这是我墙面触碰模式的关键要素。

a & b

a & b

上述图像清楚说明这些观点。在插图中,b)玩家通过点击屏幕激活移动操作。游戏意识到这一情况:玩家精灵目前没有移动(m.player.moving = false),因此我们做出相应清除,试图激活移动操作。但首先我们通过将玩家精灵的x,y坐标转移到网格坐标中展开测试工作。

e.g. m.player.x = 128, m.player.y = 192 = the player sprite is sat at grid reference 4 , 6 (128/32, 192/32)

我们现在可以判定玩家期望精灵如何移动,然后测试对应网格坐标点,查看墙面是否挡在通道中。我们可以基于存储于墙面位置中的leveldata数组进行这一测试。所以就目前来说,这些都是基本操作。若墙面挡在通道中,那么移动请求就会遭到拒绝。

sprite move blocked c

sprite move blocked c

玩家精灵位于方格4, 1。他想要移动至5, 1。通过快速查看leveldata数组,我们发现,数组元素1的位置5有个“+”,如下:

var leveldata = [];
leveldata[0] = [
"+,+,+,+,+,+,+,+,+,+",
"+, , , , ,+,+, , ,+",
"+, , , , , , , , ,+",
"+, ,+,+,+,+,+,+, ,+",
"+, , , , , , , , ,+",
"+,+,+, ,+,+, ,+,+,+",
"+, , , , , , , , ,+",
"+, , , , , , , , ,+",
"+, , , , , , , , ,+",
"+,+,+,+, , ,+,+,+,+",
"+, , , , , , , , ,+",
"+, , , , , , , , ,+",
"+,+,+,+,+,+,+,+,+,+",
"+,+,+,+,+,+,+,+,+,+",
"+,+,+,+,+,+,+,+,+,+"
];

趣味点源自于在精灵运转后处理新的方向请求。

这里我们需要完成些许事项。首先我需要让玩家精灵持续运动,直到墙面被击中。

为完成这一目标,我规定精灵在穿过方格时,只有在其坐标轴顺利分解成成网格坐标的情况下才能够通过测试函数。

我的精灵以8个像素增量进行行走,这样从方格位置A移到方格位置B需要经过4个步骤。我们故意缩短网格点间的时段。在我看来,玩家能够基于预期的下个方向点击屏幕,进而实现经常登录非常重要。

sprite move intended d

sprite move intended d

预期的下个方向已存储起来,当玩家精灵出现在下个网格坐标时,我会测试这一新方向,而不是实际方向。若新方向进展不顺,精灵会继续遵照自己的预期路径,直到a)收到新方向请求,或b)击中墙面。

当然在任何移动位置里,玩家都能够自由“旋转他的精灵”。没有什么能够阻止这一操作(游戏邦注:因为游戏会探测准确地点,精灵会退回到先前的网格位置)。

所以,我们可以简单概括游戏其他物件发生什么情况。怪兽会遵循玩家精灵的代码路径。当它们击中墙面时,它们会基于自己的定义做决定。在多数情况下,怪兽会“搜寻”玩家,因为这就是挑战的所在。但在某些情况下,我会将此随机分配,这样怪兽就会高兴地重新迈出自己的步伐。游戏应该融入足够的混合元素,方能让玩家发挥想象。

宝石、升级道具、奖金及魔法武器等实体物件的放置位置将由leveldata[]定义决定,但我们会通过标准触碰程序测试它们同玩家的触碰情况。这样我就能够在迷宫中随意移动精灵。

游戏邦注:原文发表于2012年2月8日,所涉事件及数据以当时为准。(本文为游戏邦/gamerboom.com编译,拒绝任何不保留版权的转载,如需转载请联系:游戏邦

Handling grid movement

by Mark

I thought it might be worth briefly sharing my approach to handling grid movement. It’s by no means finalised but just now is giving some very satisfactory results.

In every game that I make I employ a fairly basic box based method for collision detection. In reasonably fast paced arcade games where the sprites are deliberately designed to fill the box this really isn’t a problem since gamers won’t notice a couple of pixels in error. Besides I always weight the collision routine in favour of the player where relevant.

With the maze game I’ve adopted a slightly different approach to handling whether or not the player sprite is about to collide with the maze walls. ( Visit this link to read an earlier blog post on the construction of the maze walls )

The game is laid out on a 10 x 15 grid of 32 x 32 pixel blocks. The blocks are actually sprites since I want to animate them (i.e. cycle through animation frames, move in to position on level load, resize and move during the game). But unlike all other sprites in the game I won’t be using the standard collision routines. At any given moment in the game the player will be either a) sat at a precise location that can be converted in to a grid reference or b) in transit between two grid references. This is the key to my handling of wall collision.

The graphics above should illustrate these points.In illustration b) the player has swiped the screen to initiate movement. The game recognises the fact that the player sprite is currently not moving ( m.player.moving = false ) and is therefore cleared to attempt movement. But first we perform a test by translating the player sprite’s x,y co-ordinates in to a grid reference.

We can now determine which way the player wishes the sprite to travel and test the corresponding grid location to see whether a wall is sat in the way. We can perform this test against the leveldata array that stores our wall locations. You can see more on this in the blog post I linked to above. So fairly basic so far. If a wall is in the way the move request is rejected – see below.

Player sprite is sat at grid 4, 1. He wants to move to 5, 1. A quick lookup on the leveldata array shows us that for element 1 of the leveldata array there is an “+” sat in position 5. See below.

Where the fun begins is in the handling of new direction requests once the sprite is in motion.

A couple of things need to happen here. First I need the player’s sprite to just keep going until a wall is hit.

In order to do this I let the sprite walk the grid only passing through the test function once its co-ordinates perfectly resolve to a grid reference. ( This my sound a bit hit and miss but I can, by initially setting the player sprite to an x and y that is divisible by 32, guarantee that this will always happen. )

My sprite walks at 8 pixel increments so moving from grid location A to grid location B takes 4 steps. This is a deliberately short timeframe between grid points. It is important for me that the player is able to register quite frequently by way of a swipe on the screen an intended next direction.

This intended next direction is stored and when the player’s sprite falls perfectly in to position at the next grid reference I test this new direction instead of the actual direction. If the new direction fails the sprite just carries on on its prefered course until a) a new direction request is received or b) it hits a wall.

Of course at any point in transit the player has the freedom to “turn his sprite around”. There is nothing to stop this since the game is testing for precise locations the sprite will just fall back in to a previous grid location.

So finally a word on what happens with the other objects in the game. Monsters will follow the same code path as the player sprite. When they hit a wall they will make a decision based on their definitions. In most cases I expect that the monsters will “hunt” for the player since this is where the challenge should be. But in some cases I will completely randomise things such that the monster will quite happily retread his footsteps. This should add enough of a mix to the game to keep the player guessing.

Other entities such as gems, powerups, bonuses, magic weapons etc will be initially placed by the leveldata[] definitions but will actually be tested for collision against the player using my standard collision routine. That way I am free to move the sprites around the maze if I wish.

So that’s it ! Nothing overly complicated at all. Of course this is all just theory written here. I’ve not posted code since the code isn’t finished. Once it is I’ll revisit some of this.

Thanks for reading.(Source:spacemonsters


上一篇:

下一篇: