Staying in place on object collision



  • Hi,
    I'm making a Mario-style enemy interaction, colliding enemy from top should hurt him (but it takes two hits to kill), colliding from other sides - hurt main hero.
    I make the distinction between who hurts whom with touching flags, that are set when calling FlxG.collide.
    After being hurt, main hero has an invincibility period.
    But, while invincible, he can push enemies, and I want them to just stay at their positions, no pushing, no passing through, still preserving the possibility for main hero to hurt enemy in the period.
    If I mark enemy as immovable, the main hero is flying far through the walls on collision.

    Are there any best practices how to approach this? Some snippet?



  • FlxG.collide will calculate and apply physics to the objects colliding
    try using FlxG.overlap to check for sprite collisions which doesn't apply any physics, it just checks for collisions.

    And thenin the collision callback you can manually call FlxObject.updateTouchingFlags(player,enemy);
    to update the touching flags so you can check them

    Something like this, perhaps:

    override public function update(elapsed:Float):Void 
    {
       // ... 
       FlxG.overlap(player, enemies, onCollide_player_enemy);
       // ...
    }
    
    function onCollide_player_enemy(p:Player, e:Enemy)
    {
       FlxObject.updateTouchingFlags(p, e);  
    	
       if (e.justTouched(FlxObject.WALL)) { // left or right
          if (FlxFlicker.isFlickering(player)) return; // or check in hurt() perhaps?
          p.hurt(1);
       }
       else if (e.justTouched(FlxObject.UP)) { 
          e.hurt(1);
          // .. custom logic
       }
    }
    


  • @johndimi Thanks, I tried this, and still trying it again, but there is a problem: I get at least 2 overlap notifications (one at a frame), when I hit enemy (which stands on the ground):

    1. Enemy touches down+up, hero touches down. Hero auto-jumps
    2. Enemy touches down+right, hero touches up+left

    With the second fake notification, both enemy and hero get hurt.



  • @starry-abyss

    Yeah, the overlapping check occurs at every frame, you'll need to counter it by more custom checks.

    Maybe check when the player is falling, and only then have him hurt the enemy?
    Or if an enemy is hurt, have a timer count to X seconds and in that period the enemy is invincible?

    I made a quick thing where the player jumps like mario.

    Git folder here:
    https://github.com/johndimi/djFlixel/tree/dev/examples/Platform.Game.01

    Flash build here:
    http://johndimi.github.io/djFlixel/examples/PlatformGame01.swf

    I used some flags on the player to check for falling and jumping states to keep the enemy from continuously triggering an enemy. Perhaps something like that?



  • @johndimi Your algorithm didn't work for me, as I need to filter hurting of hero, not of enemy. Somehow hero is treated like under enemy for a frame. Could be something in my other code though...

    I have the issue when enemy's health > 1. And your example works OK in this situation :-) So I need to investigate more.



  • Good luck sorting this out :smile:



  • @johndimi I was mistaken!
    In your example (with raised enemy starting HP), the player hurts itself too, if two conditions are met at the moment of collision:

    1. enemy.health > 1
    2. Math.abs(player.velocity.x) > 0

    Same goes for my project. I wonder why velocity.x matters at the next frame when enemy and player are not overlapping (they have 2-3 pixels gap), and why do I get that second notification at all?



  • This hacky solution seems to work:

    if (!player.overlaps(enemy))
    {
    	trace("fake overlap");
    	return;
    }
    
    // may be helpful too
    //enemy.touching &= ~FlxObject.UP;
    
    FlxObject.updateTouchingFlagsX(enemy, player);
    FlxObject.separateY(enemy, player);
    
    var enemyHurt: Bool = enemy.isTouching(FlxObject.UP);
    if (enemyHurt)
    	// enemy is hurt, player jumps
    else
    	// player goes to 'hurt' state
    

Log in to reply