Thorqq.com

2015年2月6日

欢迎!

在连续几周讨论了平台跳跃游戏的机制之后,我们也应该休息一下了。因此,本周的教程将基于论坛上经常谈论的特性:网格运动,或者可以说得更加明确一点:如何像Pacman(译者注:在红白机上叫做吃豆子,或者小精灵)那样在网格中移动。

我们本周讨论的代码可以让玩家优雅地在瓦片地图中移动,在很小的空间中转弯。我们还将构建Pacman游戏的核心代码。

获取源代码

在这里我只会着重高亮最重要的部分代码。所以请先浏览一下代码。如果你对一些代码有疑问,你可以去论坛询问。

运行/编辑汽车游戏代码可以到jsbin或者codepen(译者:国内用户可访问runjs)

克隆Phaser编程技巧代码可以到git repo。

基础设施的构建

我们需要一个玩家精灵和一张瓦片地图。瓦片地图包含来了关卡的布局。在这里,我们在Tiled(译者注:Tiled官网 )中画了一个简单的关卡:

这个软件导出了一个JSON文件,然后和tileset一起导入游戏中。在

this.map=this.add.tilemap(‘map’);this.map.addTilesetImage(’tiles’,’tiles’);this.layer=this.map.createLayer(‘TileLayer1′);this.map.setCollision(20,true,this.layer);this.car=this.add.sprite(48,48,’car’);this.car.anchor.set(0.5);this.physics.arcade.enable(this.car);this.cursors=this.input.keyboard.createCursorKeys();this.move(Phaser.DOWN);

我们创建了地图和图层。碰撞被设置到20号瓦片上(暗灰色的砖块)。汽车摆放在地图的左上角,并且一开始就向下移动。.

在update函数中,我们检测与瓦片地图的碰撞:

this.physics.arcade.collide(this.car,this.layer);当前的问题

玩家的地图中的移动是一件需要解决的游戏的挑战。 尽管表面上这个看起来很简单,但是实际上这需要玩家对象对周边的情况有一个基本的了解。

玩家通过上下左右方向键来控制,当按键按下的时候,玩家开始向着对应的方向不停的移动,直到撞到墙壁或者按下其他方向键转到其他方向。

在上面这个截图中,汽车即将接近一个交叉路口。如果用户不按任何键,它将继续向下移动。然而,如果正好在到达墙的右边的空隙时按下右键,汽车就会向右开。

你被包围了

所以,汽车如何知道他是否可以转弯,什么时候它应该转弯呢?为了弄清楚这个,我们在汽车四周创建了4块临时瓦片。

在update函数中,我们将使用Phaser Tilemap类中内建的特性,此特性可用于扫描特殊的瓦片:

this.marker.x=this.math.snapToFloor(Math.floor(this.car.x),32)/32;this.marker.y=this.math.snapToFloor(Math.floor(this.car.y),32)/32;vari=this.layer.index;varx=this.marker.x;vary=this.marker.y;this.directions[Phaser.LEFT]=this.map.getTileLeft(i,x,y);this.directions[Phaser.RIGHT]=this.map.getTileRight(i,x,y);this.directions[Phaser.UP]=this.map.getTileAbove(i,x,y);this.directions[Phaser.DOWN]=this.map.getTileBelow(i,x,y);

Tilemap.getTileLeft及其同类函数正是用于实现我们上面所说的功能:返回给定坐标左边的瓦片(如果没有找到,则范围null)。

因为这些函数是基于瓦片坐标而不是像素的,所以我们首先要找出我们的汽车的地图中的确切位置。我们对汽车的x和y值调用Math.floor函数,然后使用Phaser.Math.snapToFloor转换为网格坐标。这几步就会得到汽车所在的确切瓦片。我们把结果存放在marker变量中。

周围四块瓦片存放在directions数组中。启用渲染调试开关,我们能够看到汽车知道他四周的相关信息:

绿色的瓦片表示汽车可以安全的移动过去。红色的表示是障碍物,白色的表示当前的移动方向。

放置一个转弯标识

确认汽车是否可以转弯是第一个要解决的事情。第二个要解决的是要告诉它什么时候转弯,因为我们想要它在快达到地图合适的位置的时候转弯,否则,它就会撞到墙上停止向前。

可以利用checkDirection函数来实现这个。

这个函数需要传入一个参数:汽车将要转弯的方向。这是一个Phaser方向常量,例如Phaser.LEFT或Phaser.DOWN。

这个函数做的第一件事就判断是否满足以下任意一个条件:

汽车的运动方向就是要转向的那个方向

那个方向上没有瓦片

那个方向上的瓦片不是一个“安全瓦片”(例如是一堵墙)

如果不满足上面任意一个条件,接下来就会设置一个转向标志。这个标志保存在turnPoint中,这是个Phaser.Point对象,保存了我们要汽车改变方向时所在的点的坐标。

if(this.current===this.opposites[turnTo]){this.move(turnTo);}else{this.turning=turnTo;this.turnPoint.x=(this.marker.x*this.gridsize)+(this.gridsize/2);this.turnPoint.y=(this.marker.y*this.gridsize)+(this.gridsize/2);}

理想的转弯点就是汽车当前正驶入的那个方块的中心。在图中可以看到一个黄点:

Warm and Fuzzy Inside近朱者赤,近墨者黑

Thorqq.com

相关文章:

你感兴趣的文章:

标签云: