Jump to content

Triggering me.LevelEntity transitions when contained instead of on collide


alcor
 Share

Recommended Posts

Greetings! I've very much enjoyed getting to know MelonJS, and had an initial question:

for LevelEntity objects in TMX maps, I wanted to adjust the behavior — 

  • The default is to trigger the level transition as soon as the play object even touches the Level object.
  • I'd like (and might even suggest as default behavior) to have the level transition as soon as the Player object is mostly CONTAINED by the level object. This would make many of the transitions more natural. You'd be able to walk on to stairwells, doorways, or into other level switch regions.

What is the best way to override the default? I tried a few things, including setting a custom LevelEntity to "me.collision.types.NO_OBJECT", but that disables the triggering. 

Thanks in advance for any help!

Link to comment
Share on other sites

I've created a subclass of me.LevelEntity, but it doesn't seem possible to set the collision system to allow objects fully overlap (it always pushes the colliding items out).

Is the correct path to do something like this in the level entity? Or will this be highly inefficient? It seems a similar check is done every frame anyway.

 

 update : function (dt) {
        this._super(me.LevelEntity, 'update', [dt]);
        var player = me.game.world.getChildByType(game.PlayerEntity)[0];
        var collide = player.getBounds().overlaps(this.getBounds());
        if (collide) {
            // check percentage overlap, and trigger level transition
        }
    },

Thanks for the advice!

Link to comment
Share on other sites

what I would do personally is to actually use the response object you get through the collision handle, it prevent checking for overlap every single frame in your code and since you get directly access to both colliding object you can also filter and only check if/when response.b is the player. Then finally I would actually just calculate the distance between both position to see how close they are which should give the level of overlap somehow.

so something like that :

onCollision : function (response) {
   if (response.b instanceof MyPlayerClass) {
       //probably better to use both bounding boxes, just simplifying here
       distance = response.b.pos.distance(response.a.pos);
       if (distance < response.b.width / 4) {
          // if the distance between b and a is smaller than a quarter 
          // of the b box size, we can assume that 3/4 of b is overalping with a
          doSomething();
       }
   }
}

I haven't tried this code, so maybe I'm missing something, but definitely how I would start.

let me know if it helped !

Edited by obiot
Link to comment
Share on other sites

Thank you for the help! I was able to get it working by having the player ignore the level entity:

game.playerEntity:

    onCollision : function (response, other) {
        if (other instanceof game.PortalEntity) { return false;}
        return true;
    }

game.portalEntity: (My level entity subclass)

    onCollision: function onCollision(response, other) {
        if (!this.supressed) {
            if (response.overlap >= other.body.width / 4) {
                this.goTo.apply(this);
            }          
        }
        return false;
    },

This prevents the goTo from applying when you just lightly brush the levelEntity (which would sometimes happen as you walked by one, but didn't actually intend to go through)

If you want to give it a try,
I put a quick test up at https://itty.bitty.land (note it is just basic map navigation. you can't do anything yet ;)
Now I'll work at carrying velocity through as you exit. Thanks again!

Link to comment
Share on other sites

awesome, and indeed i's a way better "experience".

else, since I noticed you are using the master branch, would you mind testing the WebGL2 renderer ? it has been added in the last 8.0 (be sure you also have the latest 8.0), it seems to be working for most things (the platformer example uses it as well now), but it's still disabled by default, you can just add "preferWebGL1 : false" to the video init parameters (don't worry it will fallback to WebGL1 if the device does not support WebGL2).

Edited by obiot
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

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