Collision with solid in scripting (platformer behavior)

0 favourites
  • 4 posts
From the Asset Store
10 Retro songs ideal for platformers or farming games
  • Ashley wrote somewhere that collisions are something we have to handle ourselves in javascript. He also wrote that internally a collision is "is overlapping & wasn't overlapping previous frame" but that doesn't appear to be the entire story.

    Example: The platform behavior lands on solid ground. With events this correctly triggers a collision, makes sense. But in javascript with just a testOverlapSolid() it never triggers. So without tearing open the platform behavior again, I have to assume that there is a piece of code that roughly does:

    1. Execute the movement

    2. testOverlapSolid() -> if true trigger collision

    3. Push out solid

    So when my scripts are executed, the platformer object will just never be overlapping the solid. So I came up with this, which sort of works

    const sprites = runtime.objects.Sprite;
    
    for(const i of sprites.instances()) {
    	const vec = {
    		"x": i.behaviors.Platform.vectorX,
    		"y": i.behaviors.Platform.vectorY
    	}
    	const prev = {
    		"x": i.x,
    		"y": i.y
    	}
    	
    	i.offsetPosition(vec.x*runtime.dt, vec.y*runtime.dt);
    	if(i.testOverlapSolid()) i.setAnimation("Animation 2");
    	i.setPosition(prev.x, prev.y);
    }

    At least I think it does what I want it to. I have to be cautious to only execute this code after any potential changes to the vectors (e.g. jumping, knockback) which is fine.

    The main issue I'm having is that this technically triggers the collision a frame to early. So I kinda need to only register the collision first, and then handle what it should do the next frame. Is this the right approach? My gut feeling tells me this might be prone to a bunch of edgecases but maybe I'm mistaken...

    Of course I could possibly also just handle this in events, but that's not the point :V

  • You could delay it a frame with something like this pseudocode. Beyond that I guess you'd have to implement the platform behavior from scratch so you can actually know when a collision occurs.

    bool overlap = false;
    bool futureOverlap = false
    
    onTick(){
     if futureOverlap==true && overlap==false
     then doStuff()
     
     overlap = futureOverlap
     futureOverlap = obj.isOverlappingSolidAtOffset(obj.vx*dt, obj.vy*dt)
    }
  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Yeah I suppose that's what I gotta do. I just think it's kinda weird to implement it this way. I wish I could hack into the platform behavior and emit some event or something :I

  • Thanks for posting about this. I had a similar issue with the bullet behavior. I wanted to destroy instances after they bounced off of a solid a couple times, but testOverlapSolid() always returns false for instances where the bounceOffSolids property is true.

    I used a similar solution to what’s been discussed here (tailored to the bullet behavior), and am planning to handle instances with the platform behavior as above. I agree this isn't the smoothest implementation, especially if it needs tweaks for different behaviors. That said, it gets the job done for now.

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