Tilemap collisions?

  • A while back I had help in figuring this out. I want particular tiles to block movement, but after my computer was restored and my backup drive failed to power on after backing up my data, I lost all information about this.

    Basically, I have to determine which tile it is at an overlap, but I'm not sure exactly the structure of doing so.

    I'm just now getting around to re-writing everything and figured I'd get this done sooner than later, as it can take some time to get a response.

    Thank you in advance. I have included a link to my Google Drive where anyone who wants to may look at it.

    ~Rory

    PS: THIS IS NOT TILEMAP COLLISION POLYGONS, IT IS OFFSET OVERLAPS COMPARING TO TILES THEMSELVES!

    Attachment: https://drive.google.com/file/d/1TzMNcgQ4H0wON4eXHmDa0CbtZdMuRdNH/view?usp=sharing

  • Hey roracle

    would't it be much easier to duplicate your tilemap and give it the solid behavior? Then you can take all tiles that are not passable from this second tilemap.

  • No, not at all. It would also make a larger file than necessary. The original files I was using were corrupted and the only thing I have remaining are compiled versions of it, which are corrupted and won't load as well, and they aren't easy to read at all.

    I would rather see if someone could help me get this working correctly, as tiles are going to all be used differently depending on certain situations. I don't want the player colliding with mountain tiles or water tiles, but if the player is in "boat" mode, I only want him to travel on water and collide with every other tile.

    Your suggestion is noted, but I've already tried it before, and the situation is a little easier if I can find the thread where it was discussed before, but until the search function is available, I'd rather just ask here to get help on it.

    Also, in regards to another issue, which again I won't be able to find the thread: the toroidal scrolling seems to have a problem. If you take the player to run around the 0,0 point you will see that depending on his location, there is part of the map missing. That is, the duplicated layers are only above and below, but not to the diagonal.

  • There is a number of expressions you can use to convert from layout coordinates to tilemap x,y:

    PositionToTileX(x)

    PositionToTileY(y)

    Convert an X or Y layout co-ordinate in to the corresponding tile number in the tilemap. For example, this can be used to get the tile position under the mouse.

    SnapX(x)

    SnapY(y)

    Snap an X or Y layout co-ordinate to the nearest tile. This also returns a layout co-ordinate, but aligned to the nearest tile in the tilemap.

    TileAt(x, y)

    Return the tile ID at a position in the tilemap. Note the position is given in tiles, not layout co-ordinates. If the tile at the given position is empty (has been erased), the expression returns -1.

    TileToPositionX(x)

    TileToPositionY(y)

    Convert a tile position to layout co-ordinates. For example, this can be used to position a Sprite object on top of a given tile.

    .

    So you can get tile number that player is on using this formula:

    tilesMap.TileAt(tilesMap.PositionToTileX(player.X), tilesMap.PositionToTileY(player.Y))

    You can check 4 points at some offset from the player to prevent it from stepping into water etc.

    .

    Creating a separate invisible solid tilemap for collision detection is actually a very good and popular solution. It will not make your project file any larger, because you only need one tile (just a black square).

    You can auto-generate this collision tilemap based on tiles on your main tilemap. Just loop through all x,y tiles on your main tilemap and set or erase corresponding tiles on the collision tilemap.

    When your player is in "walking" mode, erase entire collision tilemap and then set tiles with water, trees, mountains etc. When your player is in "boat" mode, set tiles for the entire collision tilemap, and then erase water tiles.

  • The top method is perfect for what I'm doing. After testing it, it's working perfectly well. I was doing it ALMOST correctly but didn't realize I had to do the "tilesmap.PositionToTile.X(player.X)" part. I thought it was a bit more simple than that lol.

    However, one last question about this, if I need to check multiple tiles, (for example, all "mountain" tiles of different colors), and they start at 60, I know the OR expression is a pipe (|).

    So I have this

    tilesMap.TileAt(tilesMap.PositionToTileX(player.X), tilesMap.PositionToTileY(player.Y)) = 60|61|62|63|64

    HOWEVER it now only does it with tile 1 (my water tile) which isn't even in the equation. Is there another way of doing this without it having to be copied and pasted multiple times?

    HINT: I have put spaces between the numbers and pipes, putting the numbers in quotes, and using parentheses as well. Example: 60 | 61 | 62 etc.; "60"|"61"|"62" etc., (60)|(61)|(62) etc. Is there something wrong with this particular plugin or am I just doing something wrong?

    EDIT: The reason I need "OR" to be involved instead of just doing a "greater or equal" with a "less or equal" duplicate is because not all of my solid objects are in a row, so it would take even more code. I'm all about efficiency (which is why I need that way you first described to handle everything).

  • As far as I know, you can not use expressions like | and & in conditions because the condition block itself is always an AND block or can be converted into an OR block. So you have to make an OR block and add a condition for each tile.

  • Then why would they have the operators like that in the manual if we weren't able to use them in conditions?

    https://www.scirra.com/manual/78/expressions

  • To use or in an expression you have to do it like this:

    Sprite.x=22 | sprite.x=33 | sprite.x=66

    So you’ll probably want to store the the long position expression in a variable first to simplify.

    If you do stuff like that a lot you could make a helper function to simplify things further.

  • Thanks, R0J0hound

    Is there a way you could give me an example in the file I provided up top? That is, the "Sprite.x=22 | sprite.x=33 | sprite.x=66" part.

    Also, I'm not exactly sure how to pull off a function like this.

  • I don’t have time for a while to open construct.

    You can just throw that in a system compare condition. That expression for the first part and 1 in the second.

  • You can use "Between values" condition:

    tilesMap.TileAt(tilesMap.PositionToTileX(player.X), tilesMap.PositionToTileY(player.Y)) Between 60 and 64

    .

    You can use the "|" operator like this:

    Set variable tempTile=tilesMap.TileAt(tilesMap.PositionToTileX(player.X), tilesMap.PositionToTileY(player.Y))
    System compare two values: (tempTile=60 | tempTile=61 | tempTile=62 | tempTile=63 | tempTile=64) EQUALS 1
    
  • I think I'm just going to do the copy/paste method for now. Seems to work fine anyway.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • You could use helper functions that makes it explicit what each condition does.

    IsTileWater(x,y)

    IsTileMountain(x,y)

    etc

    You could then also create another function that re-use those.

    IsTileObstacle(x,y)

    This function could then allow you to alter the way your sprite can move. Like this. Please forgive my awesome artistic talent. :)

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)