Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by Cadence96

Hi,

I pretend to do the dead animation from NES Super Mario Bros 1 ( link)

Those are the steps I'm trying to do:
1 If life of the player reachs 0, execute deadAnimation().
2 deadAnimation() triggers after 2 seconds.
3 EntityPlayer is moved up with (this.vel.y -= this.pos.y - 200) (like jumping)
4 After that, the EntityPlayer falls to the bottom of the window (this.vel.y -= this.pos.y + 500;).

In my EntityPlayer I've added this code
// gravity from main.js is 3000

friction: {x: 800, y: 0},
maxVel: {x: 800, y: 800},
jump: 300,
deadTimer: null,

update: function() {
      if (this.health <= 0) {
        this.deadAnimation();
      }
},
deadAnimation: function() {
        if ( this.deadTimer.delta() > 2) {
              this.vel.y -= this.pos.y - 200;   

              if (this.pos.y == -200) {
                   this.vel.y -= this.pos.y + 500;
              } 
        }     
}

My problem is that the Entity starts a jump loop moving up and down.
Can I have a hint how to do this?

1 decade ago by drhayes

In my own game, when the player is dying/dead I use a completely different entity with its own animations. It doesn't respond to input and it uses an EventChain to time the death animations/movements. It also has its own friction, maxVelocity, etc. Makes it really easy to be very precise without screwing up the "real" player.

Whether or not you switch entities it sounds like you want these three steps:

1. Show "oh noes" animation.
2. Set accel.y to some negative value.
3. Restart level when entity pos.y is greater than some value.

That could look like this:

init: function(x, y, settings) {
   // ... other stuff ...
   this.deathChain = new EventChain(this)
      .then(function() {
         this.currentAnim = this.anims.ohNoes;
      })
      .wait(3)
      .then(function() {
         this.accel.y = -150; // You'll have to experiment here.
      })
      .wait(1) // And here.
      .then(function() {
         this.accel.y = 0;
      })
      .wait(90)
      .orUntil(function() {
         return this.pos.y > 200; // And here.
      })
      .then(function() {
         ig.game.restartLevel(); // Or whatever you call it.
      });
},

update: function() {
   // ... other stuff ...

   if (this.health <= 0) {
      this.deathChain();
   }
}

That should do it.

1 decade ago by Apiheld

A few things:

1. An exact match for a position is always a bad idea. Imagine your entity starts at pos.y = 80 and then you add 50 every frame. It goes to: 130, 180, 230. It never is exactly equal to "200" or "-200" or whatever. You should use <= or =>

2. If you velocity depends on the position of your entity, it will have a higher velocity if it is in a lower part of the screen. Example: Your entity walks on the bottom of the screen, say, at pos.y = 800, vel.y starts at 0.

Tick 1: vel.y = 0 - 800 - 200 = -1000
Tick 2: vel.y = -1000 - 200 (current pos) - 200 = -1400
...

If your entity is at the top, say pos = 100:
Tick 1: vel.y = 0 - 100 - 200 = -300
Tick 2: vel.y = -300 - -200 (current pos) - 200 = -300

So, as you can see, the movement is probably extremely weird. vel.y should be increased and decreased independent from the position, as this can have weird side effects.

3. Your velocity in the current code is even set twice. You use "-=" in both lines, which decreases velocity twice whenever the entity is exactly on -200


4. Major problem that causes the up-and-down loop: The logic right now is: If your entity is at exactly the position -200, go up. It doesn't matter if it was up before and goes down or if it was down before and goes up. Once it's at -200, it goes up, no matter what.

To solve this, you need to store some state. You could set a flag once you passed the "high point".

Or you could set a direction that modifies the velocity. In a naive way, it looks like this:

deadAnimation: function() {
        if ( this.deadTimer.delta() > 2) {
		if (this.pos.y <= -200) {
			this.reachedHighPoint = true;
			this.vel.y = 0;
		}
		if (!this.reachedHighPoint)
	              this.vel.y -= 200;   
		else
		      this.vel.y += 200;
        }  
}

1 decade ago by Cadence96

Thanks for your help. Both answers give me the solution.

PD: drhayes your libraries are awesome.

1 decade ago by drhayes

Thanks! My theory is more great libraries === more great games.
Page 1 of 1
« first « previous next › last »