Jump to content

tilemap, how to store player&enemies start position


BdR
 Share

Recommended Posts

I want to make a puzzle game like Pitman and I'm thinking about how to do this with tilemaps, but I can't figure it out.

Pitman is a puzzle game with 50 single screen levels, each level are tiles on a 11 x 8 grid (relatively small) and the player start position is different in each level. In the original Pitman game, the player start position is also stored as a "tile" in the grid. How would you store the player position in a tilemap file?

pitman.png

I guess something similar applies to a game like Puzzle Bobble; it also many levels (100 levels) with enemy positions stored in level layouts as tiles. What would be a good way to handle so many levels in Phaser.js? And how to create enemies based on tile index/positions?

Bubblebobble.png

So my questions are:
- is it possible to store a player position based on a special tile index? (how would you decode it? I mean how do you make it a movable&controllable sprite?)
- is it possible to store many levels in one JSON tilemap file?
- is it possible/advisable to create such a game without tilemaps?
- are there advantages/disadvantages to creating a such a platform game without tilemaps?

Any advice greatly appreciated.:)

Link to comment
Share on other sites

On 13-5-2016 at 4:48 PM, drhayes said:

If you're using Tiled, you can make an object layer. The object layer data is available to you after you load the map. You can read the positions and spawn characters there yourself.

Yes, I'm using the Tiled Map Editor and I know you can add an object layer to store the objects and enemy classes. I saw a very good example here. However, the downside is that you need to define the enemy properties (score, texture etc.) for each single enemy in all of the level files. Even when the enemies look and behave the same in all levels.

In my game there are only a few enemy types, so to me that seems a little redundant. I mean it doesn't make sense to store enemy properties for each indiviual enemy and in each level file. Only their initial position changes and that's it. So instead, I'm using the Tilemap.createFromObjects() function as shown in this example which works fine for what I want to do in my game. :)

I would still like to hear any suggestions as to if it is possible to store many levels in one sinlge tilemap JSON file.

Link to comment
Share on other sites

Nah, you don't have to do that. In my game I have multiple object layers, but the one that contains the enemies and breakable walls and things is always called "entities". In the code that loads my tilemap I have a function that iterates through all the objects in "entities" and looks up the class name to instantiate based on the name of the object.

Something like this:

export function entityFactory(game, entities) {
  const { groups } = game;
  entities.forEach(mapEntity => {
    let currentEntity = null;
    if (FACTORY_MAP.has(mapEntity.name)) {
      const { factory, groupName } = FACTORY_MAP.get(mapEntity.name);
      currentEntity = factory(game, mapEntity);
      currentEntity.name = name;
      groups[groupName].add(currentEntity);
    } else {
      console.error(`No FACTORY_MAP entry for ${mapEntity.name}`);
    }
  });
}

The "entities" array is the object layer from Tiled named "entities". Each object in that array has a set of standard properties, including its name, x, y, width, height, etc. Based on the "name", I pull out the class name from the FACTORY_MAP (which I dynamically generate earlier in the file). Most things build exactly the same way:

const DEFAULT_FACTORY = function (EntityType) {
  return (game, mapEntity) => {
    const { x, y, width, height, properties: { id, name }} = mapEntity;
    const middleX = x + width / 2;
    const bottomY = y + height;
    return new EntityType(game, id, middleX, bottomY);
  }
}

I have an enemy with a class name of Beetle. Beetle extends Phaser.Sprite. Its constructor takes "game, id, x, y". The rest is specified by my custom class, so I don't have to repeat properties across all my map files. Piece of cake. ( =

Any data I need to customize my sprites' behavior can be pulled out of the "properties" field of the map entity. For example, I have a custom class called Gargoyle that spits fireballs at the player. It has properties for numFireballs, fireTiming, and faceRight (by default it faces left).

One of the downsides to this approach is my maps are full of blank rectangles in Tiled that correspond to all my dynamic stuff. Later versions of Tiled at least show the names next to the rectangles, but it would've been nice to define a "palette" or something in Tiled that showed the graphics and maybe specified some properties by default. I know I can use the tile images from my atlas or something... but my atlas is still in flux and a lot of these things are variable in size.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...