如何通过 Cocos2d-html5 使用砖块地图编辑器

 

简介

砖块地图编辑器 (Tiled Map Editor) 是一个伟大的工具,用于创建游戏级别和砖块地图。 砖块应用程序在 Qt 应用程序框架的帮助下被写入 c + +,它是免费的。 它允许开发人员创建正交,以及等距的砖块地图。 地图保存为 TMX 文件,这只是基于 XML 的格式,所以它们很容易被读取且可与不同的游戏引擎配合使用。

砖块地图编辑器的官方网站:

http://www.mapeditor.org/ 

图 1:砖块地图编辑器

很多不同的游戏引擎已经支持 TMX 地图,如:

  • Cocos2d
  • Cocos2d-iPhone
  • Cocos2d-html5
  • AndEngine
  • melonJS
  • sprite.js
  • Unity 3D

完整的列表位于以下地址:

https://github.com/bjorn/tiled/wiki/Support-for-TMX-maps 

您可以通过访问其官方网站并遵循安装指南随时安装最新版本的砖块地图编辑器。 砖块应用程序应在最普及的操作系统上运行:

  1. Windows
  2. Mac OS
  3. Linux:Ubuntu、Fedora、openSUSE 和 CentOS

 

创建 TMX 地图

使用砖块应用程序创建新的地图和级别真的很容易。 下面的教程将向您展示如何创建地图和使用一些花哨的砖块功能。 由于我们在 RunSnailRun 示例应用程序中使用了砖块应用程序,我们将使用我们创建的应用程序作为一个示例。

首先,打开砖块应用程序,点击左上角的“新建”按钮。 此时会弹出一个窗口,显示您的新地图设置。 

图 2:新地图菜单

您可以设置地图应需要多少块砖块和那些砖块应该多大。 您应该考虑到并不是所有的地图大小都可以适用,且您应在开始编写游戏时设计您的地图。 

在 RunSnailRun 中,我们使用了一张地图,大小为 42 x 22 砖块。 即 1260 x 660 像素。 我们在设计时为填充物和显示在地图区域外的游戏徽标留有一定的空间。 单击“确定”后,您将看到一张新的砖块地图:

图 3:新的砖块地图

现在,您需要使用图块(图像)和对象填充地图。 正如在 Cocos2d-x 和大多数图形程序中,您使用图层在砖块应用程序中构建地图。 最好的办法是使用图层来收集所有相同的图块或共享相同属性的所有对象。 例如,我们在 RunSnailRun 中的地图有背景层,另一层用于放置碰撞元素(生菜)。 蜗牛和刺猬属于不同类型的对象。

在开始时第一层已经创建。 其名称通常是:砖块层 1。 您可以通过双击它来更改名称。 您将其更改为例如“背景”后,您可以开始填满它。 要执行此操作,您需要导入一些图块,即一些图像。

  1. 打开地图菜单,然后单击“新图块”。 
  2. 单击“浏览”,找到您想要添加的图像。
  3. 单击“确定”。

在“图块”面板的右侧,您将看到您的图像被导入。 您现在可以选择砖块,并放置在地图上。 

在顶部面板上,您会发现很多有用的选项,如:

  • 图章笔刷:此选项将导致只在地图上放置一个图块。
  • 颜料桶填充工具:设置此选项后,您将用指定的图块填充整个地图。
  • 橡皮擦:这将擦除所选的砖块。
  • 矩形选择:您可以使用此选项选择一个区域,以便所有修改只会在该区域内应用。

创建背景后,您还可以在地图上添加一些碰撞对象,这样玩家就不能在地图上四处走动。 您可以通过两种方式执行此操作。 第一种方法,您可以创建一个碰撞图层,用于放置所有可碰撞的图块,如岩石、河流、树木。 Cocos2d-x 可以从指定图层读取砖块的位置,您可以检查玩家是否想要移动到可碰撞的砖块上,并加以阻止。

另一种方法是为每一种地形类型创建一个图层,因此会有树木图层、岩石图层等等。 然后,您将使用透明图块创建另一个单独的图层。 您可以通过在这些砖块上放置透明的图块来指定哪些砖块是玩家不得逾越的。

在 RunSnailRun 中,只有一种碰撞对象类型,即生菜。 这就是为什么我们决定不设置额外的图层。 我们创建一个名为“collidable”的级别,并在此级别内放入生菜。 

正如前面所提到的,蜗牛和刺猬都属于对象。 这意味着它们不显示为图像,但它们存储位置和元素的一些属性。 在我们的应用程序中,我们在地图上放置蜗牛对象和刺猬对象,然后使用 Cocos2d-x 读取它们的位置,并创建 sprite。

为了在砖块应用程序中创建一个对象图层,您需要打开图层菜单,然后点击“添加对象图层”。 您现在设置对象图层的名称。 在我们的例子中,我们创建了两个对象图层,一个用于蜗牛,另一个用于刺猬。 创建对象图层后,您可以创建对象。 现在它应该看起来像这样:

图 4:用砖块应用程序创建的地图由两个砖块图层和一个对象图层组成

您现在只需保存地图并将其放置在游戏文件夹内。

 

在 Cocos2d-x 使用 TMX 地图

在 Cocos2d-x 中有一个特殊的类,使您可以加载 TMX 文件作为一张地图。 此外,此类有一些额外的函数,帮助处理 TMX 地图属性。 它可以访问图层、单个网格和读取它们的属性。 下面是一个从 RunSnailRun 应用程序中截取的代码片段,关于如何加载由砖块应用程序生成的地图:

classes.maps.TiledMeadow = cc.TMXTiledMap.extend({
    ctor : function() {
        this._super();
        this.initWithTMXFile("images/tiledMeadow.tmx");
    }
});
var tiledMap = new classes.maps.TiledMeadow();

 

正如您所见,TiledMeadow 类扩展了 TMXTiledMap,并在 tiledMeadow.tmx 文件被创建后加载该文件。

将一个 tiledMap 对象添加到您所创建的地图图层时,仅显示砖块图层。 对象图层(如蜗牛)不会出现,也不会有任何机制检查对生菜的碰撞。 您必须自己做。 下面显示了我们如何在我们的示例应用程序中完成这项操作。

加载 TMX 文件后,我们可以使用一些现有函数来读取地图属性。 例如,我们可以读取所有的可碰撞砖块和创建反映它们的矩形。

initObstacles : function() {
    this.obstacles = [];
    var mapWidth = this.getMapSize().width;
    var mapHeight = this.getMapSize().height;
    var tileWidth = this.getTileSize().width;
    var tileHeight = this.getTileSize().height;
    var collidableLayer = this.getLayer("collidable");
    var i, j;
    for (i = 0; i < mapWidth; i++){
        for (j = 0; j < mapHeight; j++){
            var tileCoord = new cc.Point(i, j);
            var gid = collidableLayer.getTileGIDAt(tileCoord);
            if(gid) {
                var tileXPositon = i * tileWidth;
                var tileYPosition = (mapHeight * tileHeight) - ((j+1) * tileHeight);
                var react = cc.rect(tileXPositon, tileYPosition, tileWidth, tileHeight);
                this.obstacles.push(react);
            }
        }
    }
}

 

Cocos2d-x 允许您只需使用您想要检查的图层名称调用 getLayer() 函数即可访问任何地图图层。 您还可以使用 getTileGIDAt() 函数访问图层内部的网格,但您必须将网格的位置传递至该函数。

我们遍历整个地图,并使用前述函数检查“可碰撞”砖块的位置。 找到每个可碰撞的砖块后,我们创建了稍后将用于碰撞检测的矩形。

我们使用类似方法读取蜗牛的所有位置。 下面是代码片段:

initSnails : function() {
    if (this.tiledMap) {
        var objectGroupSnails = this.tiledMap.getObjectGroup("snails");
        var objectSnails = objectGroupSnails.getObjects();
        this.numberOfSnails = objectSnails.length;
        var that = this;
        objectSnails.forEach(function(objectSnail) {
            var snail = new classes.sprites.Snail();
            snail.setPosition(new cc.Point(objectSnail.x, objectSnail.y));
            that.snails.push(snail);
            that.addChild(snail, 1);
        });
    }
}

 

这一次,我们使用 getObjectGroup() 函数来访问包含所有蜗牛的组。 我们遍历了此清单中的每只蜗牛。 对于每一只蜗牛,我们通过参考砖块地图上的 x 和 y 参数读取其位置,并创建一个 sprite,将其放置在 Cocos2d-x 图层上的同一位置。 我们以同样的方式也把刺猬放置在 Cocos2d-x 图层。

碰撞检测

现在根据其在由砖块应用程序创建的 TMX 地图上定义的位置显示了所有的蜗牛和刺猬。 下一个问题是,当所有的动物都将开始移动时,它们将走到它们想去的地方。 它们将走进彼此,但不会发生任何事情。 我们需要某种形式的碰撞检测机制。 此问题已经在上一篇文章中进行了描述(Tizen 应用程序中的 Cocos2x-html5 游戏框架: 后续),但我会重复一遍,以保持文章的一致性。 我还将对新案例进行碰撞检测。

由于我们已经有了反映碰撞对象(生菜)的矩形,且可以轻松地创建蜗牛和刺猬的矩形,我们可以使用所有这些矩形来检查当对象在地图上移动时,这些矩形是否彼此相交。 在对象移动时的主游戏循环中,我们可以检查任何这些矩形是否发生碰撞并触发一些操作,例如,如果蜗牛矩形想要移动到生菜矩形,我们可以加以阻止。 这是更新函数在 RunSnailRun 应用程序中的样子:

update : function(dt) {
    var that = this;
    this.moveAndCheckForObstacles(this.hedgehog, dt);
    this.snails.forEach(function(snail) {
        that.moveAndCheckForObstacles(snail, dt);
    });
    this.collisionDetection();
}

 

正如您所见,我们尝试移动刺猬和蜗牛,并检查它们是否碰到任何障碍物,在本例中是棵生菜。 为了检查一个对象是否撞到一个障碍物,我们使用 moveAndCheckForObstacles 函数:

moveAndCheckForObstacles : function(object, dt) {
    var newPosition = object.move(dt, this.keyboardArrows);
    var newReactangle = cc.rect(newPosition.x+2 - object.width / 2, newPosition.y+2 - object.height / 2, object.width-4, object.height-4);
    if (!this.isCollisionInArray(newReactangle, this.tiledMap.obstacles)) {
        object.setPosition(newPosition);
    }
}

 

此函数非常简单,其工作方式如下:

  • 它让对象计算其新的位置。
  • 它创建一个新的矩形,使用所获取的位置,确定这个对象在移动后所在的位置。
  • 它调用 isCollisionInArray 函数来检查这个新的矩形是否将碰撞到数组 (在本例中,这是在 TMX 地图被加载时创建的一组生菜) 中定义的任何矩形。
  • 如果没有发生碰撞,该函数将在新位置上设置对象。

IsCollisionInArray 函数采用两个参数:对象和数组。 该函数遍历数组,并通过调用 Cocos2d-x 的函数 cc.rectIntersectsRect 检查数组中的任何项目是否碰撞到传递的对象。 它看起来像这样:

isCollisionInArray : function(item, array) {
    for (var i = 0; i < array.length; i++) {
        if (cc.rectIntersectsRect(item, array[i])) {
            return true;
        }
    }
    return false;
}

 

使用砖块应用程序在对象图层中添加的所有对象将与生菜碰撞。 您可以更改生菜的位置,所有这些机制应仍然工作。

总结

砖块地图编辑器是一个非常有用和简单的工具,使您可以创建 TMX 地图。 您可以创建对象并定义对象和图层的属性,并在游戏引擎(如 Cocos2x-HTML5)中使用这些属性。 如果您正在创建一个游戏应用程序,您真的应该考虑使用砖块应用程序。

文件附件: