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 gothikon

Hi

After purchasing Impact the first thing I did was modify a few of the example games and add support for local multiplayer. Initially I duplicated the entire EntityPlayer file for the jumpnrun example, rename EntityPlayer to EntityPlayer2 and change the keyboard bindings, everything worked fine but the amount of code duplication quickly became a maintenance problem so I decided to give inheritance a shot.

This is roughly how the code looks now:

player.js


ig.module(
    'game.entities.player'
).requires(
    'impact.entity'
).defines(function () {

    EntityPlayer = ig.Entity.extend({

        // generic properties for physics, collision, maxVel etc.

        init: function (x, y, settings) {
            // ...
        }

        update: function () {
            // input handling code
            if (ig.input.state('left')) {
                // ...
            }
            if (ig.input.state('right')) {
                // ...
            }
            // etc
        }

    });

});


player-2.js


ig.module(
    'game.entities.player-2'
).requires(
    'impact.entity',
    'game.entities.player'
).defines(function () {

    EntityPlayer = EntityPlayer.extend({

        update: function () {
            // input handling code
            if (ig.input.state('left2')) {
                // ...
            }
            if (ig.input.state('right2')) {
                // ...
            }
            // etc
        }

    });

});


I fired up the game and everything looked okay until I tried to control the players, all the inputs for EntityPlayer would move EntityPlayer AND EntityPlayer2. When I tried to move EntityPlayer2 only EntityPlayer2 would respond but x-axis movement didn't work properly, movement in the y-axis was fine.

It's almost as if EntityPlayer2 is running the code in both update methods, my assumption was that any methods with the same name would overwrite the inherited methods.

I'd really appreciate any help!

1 decade ago by fugufish

hi, what keys did you bind left, right, left2 and right2 to?

1 decade ago by MikeL

Try this:
1. First rename your file to player2.js. (I think it's best to reserve the hyphens for compound words e.g. blue-ship.js).

2. Next alter your code as below:
ig.module(
    'game.entities.player2'
).requires(
    'impact.entity',
    'game.entities.player'
).defines(function () {

    EntityPlayer2 = EntityPlayer.extend({

As you can see EntityPlayer2 matches the end of the module name. You were using EntityPlayer which was overwriting your initial player entity.

Let me know if you have any problems and welcome to Impact! You may also want to check out an existing beginning of multiplayer with ape's Impsock.

1 decade ago by dominic

I guess you&039;re calling #this.parent() in your update() methods? If so, the call to this.parent() in EntityPlayer will call the update() method of ig.Entity as intended, but the this.parent() in EntityPlayer2 will call the update() method of EntityPlayer (which in turn will call the update() method of ig.Entity again).

I.e. EntityPlayer2.update() -> EntityPlayer.update() -> ig.Entity.update().

So your class hirachy looks like this:
ig.Entity
	EntityPlayer
		EntityPlayer2

When instead you'd probably want something like this:
ig.Entity
	EntityPlayer
		EntityPlayer1
		EntityPlayer2

So EntityPlayer has all the code shared by both player entities, while EntityPlayer1 and EntityPlayer2 handles all different input keys.

1 decade ago by gothikon

Quote from MikeL
Let me know if you have any problems and welcome to Impact! You may also want to check out an existing beginning of multiplayer with ape's Impsock.


That's definitely on my to do list!

1 decade ago by gothikon

Quote from dominic

When instead you'd probably want something like this:
ig.Entity
	EntityPlayer
		EntityPlayer1
		EntityPlayer2

So EntityPlayer has all the code shared by both player entities, while EntityPlayer1 and EntityPlayer2 handles all different input keys.


Thanks, you nailed it.

Initially I defined a complete update method in EntityPlayer1 and EntityPlayer2 and left it out of EntityPlayer. My update method was quite large though so to reduce the duplication even further I've put it back in EntityPlayer and added some unique properties to map the input bindings / actions, like so:

    EntityPlayer = ig.Entity.extend({

        controls: {
            jump        : '',
            down        : '',
            left        : '',
            right       : '',
            primary     : '',
            secondary   : ''
        },

        init: function () {
            // ...
        },

        update: function () {
            
            if (ig.input.pressed(this.controls.left)) {
                // ...
            }
        },

        // ...

    }

    EntityPlayer1 = EntityPlayer.extend({

        controls: {
            jump        : 'jump',
            down        : 'down',
            left        : 'left',
            right       : 'right',
            primary     : 'primary',
            secondary   : 'secondary'
        }

    }

    // Likewise for EntityPlayer2

1 decade ago by gothikon

I was just re-reading the docs or and saw this

new ig.Entity( x, y, settings )

Is it possible to define this settings object via weltmeister? This would make it possible for me to have a single EntityPlayer and pass the keyboard input, or other config through.

1 decade ago by MikeL

@gothinkon - have a look at the Weltmeister docs under manipulating entities for customizing via Weltmeister. Also see this caveat about where to place the call to this.parent.

Personally, I would not define keyboard input through Weltmeister. What is possible though, is to define a 'name' property for the player through weltmeister - 'player1' or 'player2', etc. Then in your update function it could call a custom function like player1Update or player2Update based on the name. I use this method for giving similar appearing entities customized behavior without having to use inheritance.

1 decade ago by MikeL

Or, as I think about it, you could just use a property called 'player' and the value could be an integer 1, 2, etc. This way you would save having to look up a string value at every update.

The resulting update function would look something like this:
update: function(){
    switch(this.player){
      case 1:
        this.player1Update();
        break;
      case 2:
        this.player2Update();
        break;
    }

    //Put code that is in common for any player here.

    this.parent();
},

Obviously you don't have to use switch, but any sort of if then statement.
Page 1 of 1
« first « previous next › last »