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

8 years ago by SirPereira

Hey guys,

I am building an entity that moves up/down/left/right by having forces applied on it.

Currently, I've got that working. However I'm needing that suddenly when changing the direction, the forces that were being applied to the entity should be almost totally replaced by the new ones.

I'm looking for this kind of movement:

/><br />
<br />
You can see it in action by just creating a room in <a href=www.haxball.com (takes 3 seconds)

My code looks like it merges the newly applied forces with the already running forces and makes the movement not so smooth as the one in the GIF.

ig.module(
    'game.entities.player'
)
.requires(
    'plugins.joncom.box2d.entity',
    'plugins.joncom.box2d.entities.circle'
)
.defines(function(){

EntityPlayer = EntityCircle.extend({
    
    size: {x: 82, y: 82},

    radius: 41,
    density: 1,
    isFixedRotation: true,

    bounciness: 0.025,

    speed: 1300,
    maxVel: {x: 200, y: 200},

    animSheet: new ig.AnimationSheet( 'media/player.png', 82, 82 ),

    init: function( x, y, settings ) {
        this.parent( x, y, settings );

        this.addAnim( 'idle', 1, [0] );
        this.addAnim( 'shoot', 1, [1] );

        // Set a reference to the player on the game instance
        ig.game.player = this;
    },
    
    update: function(){

        if( ig.input.state('up') ) {

            var force = new Box2D.Common.Math.b2Vec2( 0, -this.speed );
            this.body.ApplyForce( force, this.body.GetPosition() );
            this.body.SetLinearDamping(0);

        } else if( ig.input.state('down') ) {

            var force = new Box2D.Common.Math.b2Vec2( 0, this.speed );
            this.body.ApplyForce( force, this.body.GetPosition() );
            this.body.SetLinearDamping(0);

        }

        // Left or right?
        if( ig.input.state('left') ) {

            var force = new Box2D.Common.Math.b2Vec2( -this.speed, 0 );
            this.body.ApplyForce( force, this.body.GetPosition() );
            this.body.SetLinearDamping(0);

        } else if( ig.input.state('right') ) {

            var force = new Box2D.Common.Math.b2Vec2( this.speed, 0 );
            this.body.ApplyForce( force, this.body.GetPosition() );
            this.body.SetLinearDamping(0);

        }

        if ( !ig.input.state('up') &&
             !ig.input.state('down') &&
             !ig.input.state('left') &&
             !ig.input.state('right')
        ){
            this.body.SetLinearDamping(3);
        }

        if ( ig.input.state('shoot') ) {
            this.currentAnim = this.anims.shoot;
        } else {
            this.currentAnim = this.anims.idle;            
        }


        this.parent();

    }

});


});

Any idea how can I improve it?

8 years ago by Joncom

I wonder if the solution at the bottom of this page might work? I think the basic idea is that you want to have high acceleration (so that direction can be changed quickly), and a relatively low max movement speed (so that the high acceleration doesn't turn your entity into a bullet).

var max = 300;
entity.maxVel.x = max;
entity.maxVel.y = max;

8 years ago by SirPereira

Hey @Joncom, thanks again for your support.

I'm not really sure that is what I'm looking for. Even with that snippet my entity seems to take so long to suddenly change direction when already having applied some other force.

I think I may have to use a counter force when changing to a direction different from the previous one that I was facing to, but I need to investigate it a bit.

I would like to explain this a little better. How can I upload a live code snippet to of ImpactJS to make a demo available?

8 years ago by Joncom

Even with that snippet my entity seems to take so long to suddenly change direction when already having applied some other force.
Can you apply an even greater force then? The force you apply should be great enough to quickly overcome the velocity regardless of direction. The velocity limiting should ensure that whatever force you apply will quickly be "dropped" so you don't have any significant forces you need to counter when you want to change direction. That's the theory anyway...
How can I upload a live code snippet to of ImpactJS to make a demo available?
Github? Dropbox?

8 years ago by SirPereira

You can find the player entity code here: https://github.com/IvoPereira/SocketBall/blob/master/lib/game/entities/player.js

But how in logic can I achieve that? Basically, if I'm moving, I should apply an higher force so the direction would change.

1) How can I know if I'm moving?
2) How can what is the current level of strength?
3) How should the new force be calculated?

8 years ago by Joncom

Oops.

Forget about my suggestion to limit the velocity separately via maxVel.x and y. That leads to some strange behavior.

What you'd probably want to do is limit the "total" max velocity:

EntityPlayer = EntityCircle.extend({
    ...

    speed: 10000, // bumping this up seems to help
    // maxVel: {...} // <-- Just delete this whole line
    ...

    update: function() {
        ...

        var maxVelocity = 600 * Box2D.SCALE; // 600 pixels per second

        var currentVelocity = this.body.GetLinearVelocity();
        if(currentVelocity.Length() > maxVelocity) {

            // Make a copy of the current velocity vector.
            var newVelocity = currentVelocity.Copy();

            // Set the total velocity equal to 1.
            newVelocity.Normalize();

            // Multiply vector so the total velocity is equal to maxVelocity.
            newVelocity.Multiply(maxVelocity);

            // Use new (capped) velocity.
            this.body.SetLinearVelocity(newVelocity);
        }

        this.parent();
    }
    ...
});

Basically we use a force value high enough to quickly overwhelm previous forces, which should provide more "responsive" direction changing...

Edited for grammar.
Edited to add comments.

8 years ago by SirPereira

Hey @Joncom,

Thanks a lot for replying and sorry for the late delay (big late!). I've been busy with some job stuff and was not able to get my hands into this again.

So, as far as I've tried it still takes too long to change direction into the opposite position. I guess the solution should pass on your logic, by applying an higher force, however it is not making me sense why it does make the "being dragged" effect that's being made on the object.

EDIT: I've been trying to replicate my current movement to a video like I did in the first post, but I guess it will not make clear what kind of movement I'm having. If possible, please clone my Git repo - https://github.com/IvoPereira/SocketBall/ - and check the movement for yourself.

The problem is basically the same. Basically when I'm changing direction, it takes too long to lose the previously gained force and gain the new one. Apart of that, moving in diagonal is strange, as it looks like you are being pushed by one of the sides.

Increasing speed seems to help, but however it will increase the speed movement and I am not really looking for it.

8 years ago by Joncom

Increasing speed seems to help
Looks like you're still using 1300. Use something higher, like 10000.
however it will increase the speed movement and I am not really looking for it.
That's why you limit the max speed.

Change this line:

var maxVelocity = 600 * Box2D.SCALE; // 600 pixels per second

to this:

var maxVelocity = 300 * Box2D.SCALE;

Limiting the max speed will prevent things from getting "too fast", so keep making maxVelocity smaller until you're happy with the top speed.
Page 1 of 1
« first « previous next › last »