So, the FlxG collide method knows how to tell which tiles in a tilemap are walls or not walls, but the overlap method does not. If you write a simple custom collision with the overlap method and tell it to .separate(), your sprite will collide with every tile in the map, not just the walls.

This is expected behavior, as there’s a note in the FlxG documentation that says:

this takes the entire area of FlxTilemaps into account (including “empty” tiles). Use FlxTilemap#overlaps() if you don’t want that.

On the other hand, the documentation for FlxTilemaps.overlaps() says:

Checks to see if some FlxObject overlaps this FlxObject object in world space. If the group has a LOT of things in it, it might be faster to use FlxG.overlaps().

In my scenario I have a lot of tilemaps and just one object to collide with them, the player. The way this is written, I’m thinking I have to call this method for EACH MAP, i.e. map1.overlaps(player), map2.overlaps(player), etc. Whereas with the FlxG method I can pass it the entire FlxGroup of maps as one parameter and the player as another parameter, which seems way better. I guess I could write a function with a loop that iterates through each map doing this one by one, and then call that in update(), but I’m getting the impression that it might be really inefficient.

What’s the best approach here? Am I missing something obvious?

  • @sturlabragason@lemmy.world
    link
    fedilink
    210 months ago

    Hi Remy Rose, here is what GPT4 told me after posting your post and comment, hopefully it solves something, but I have personally had great success in using it as an development assistant.

    You’ve raised some excellent points, and I can understand why you’re concerned about efficiency. Let’s tackle your questions one by one.

    Collision with Multiple Tilemaps It does seem like using FlxG.collide() would be easier if you could pass an entire FlxGroup of maps, but you’re correct that FlxTilemap#overlaps() would have to be called for each individual map. If you’re concerned about performance, you might want to consider some optimizations:

    Spatial Partitioning: Divide your game world into sections and only check for overlaps within the section where the player currently is. Caching: If a tilemap has not changed, you could cache the result of the overlap check until the player moves to a different region or the tilemap is modified. Redundant Position Checks You mentioned that you’re checking the player’s position twice per update: once for collision detection and once for random encounters. One solution could be to combine these checks into a single function that both handles collisions and determines random encounters. This way, you only need to check the player’s position once per update.

    Here’s a pseudo-code example:

    function update() {
      // Collision checks and random encounter checks
      for (map in allTileMaps) {
        if (map.overlaps(player)) {
          // Handle collision logic here
        }
      }
    
      // Use the latest player position for random encounters
      var currentPlayerPosition = player.getPosition();
      randomEncounterCheck(currentPlayerPosition);
    }
    

    Final Thoughts These are just suggestions, and the best solution may depend on the specifics of your game. However, I hope these points guide you in a direction that helps you streamline your code and enhance performance.

    Best of luck with your game development!

  • Remy RoseOPM
    link
    English
    110 months ago

    Update: Got it working for now, but I suspect it’s very inefficient!

    So, for some context, I have a bunch of tilemaps right up against each other forming one large continuous world map made up of many small regions. I wanted the player to have random encounters that were specific to the region they’re crossing. In examples online, I saw that people will write custom collision behavior with FlxG.overlap() instead of the default FlxG.collide() because they want different kinds of collisions to behave differently. I thought I could use that to fold my region-specific-encounters stuff into the collision-detection stuff. My thought was, It’s got to be more efficient to only check the player’s location once per update, rather than multiple times, right? Only, I never figured out how to do it…

    So instead, every update I’m using the default collide method, and also writing the player’s location to a singleton. When an encounter procs, another function uses that location to pick an appropriate encounter. And it works! But I’m checking the same thing twice per update… Surely that’s unnecessary right?