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 fulvio

I have a player who is capable of picking up different kinds of weapons (Laser Gun, Rocket Launcher, Grenade, etc).

I want to be able to position the weapon so it moves with the player rather than display a different set of sprites in the sprite sheet. My player has so many different kinds of animations that to add all these different weapon types would be incredibly time consuming. Is this something that's possible?

Any code that guides me would help.

1 decade ago by StuartTresadern

Have you looked at this plugin
http://impactjs.com/forums/code/modular-entity

It should give you some idea of how to do it.

1 decade ago by alexandre

EDIT: fixed bug per follow up post from @fulvio.


Unless I misunderstood your question, you could also start with something simple like this:

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

EntityWeapon = ig.Entity.extend({

	size: {x:8, y:8},
	offset: {x:0, y:0},
	animSheet: new ig.AnimationSheet('media/generic-weapon.png', 8, 8),
	bounciness: 0.1,	// a bit of bounce for when it drops
	gravityFactor: 1,
	owner: null,

	init: function(x, y, settings)
	{
		this.parent(x, y, settings);
		this.addAnim('idle', 1, [0], true);
	},
	
	update: function()
	{
		if (this.owner)
		{
			this.pos.x = this.owner.pos.x + this.offset.x;
			this.pos.y = this.owner.pos.y + this.offset.y;
			this.currentAnim.flip.x = this.owner.currentAnim.flip.x;
		}
		else
		{
			this.parent();	// drops on the floor automatically when owner null
		}
	},
});
});

1 decade ago by fulvio

@alexandre: Thanks for the code example. Much appreciated. Am I spawning this in the init() function of my player entity?

Like this:

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

    // Spawn weapon entity.
    ig.game.spawnEntity(EntityWeapon, this.pos.x, this.pos.y, { owner: this });
}

Because this doesn&039;t seem to be working as expected. It doesn't spawn if the #update() is left there. If I remove the entire update() code from the entity it appears, but obviously doesn't follow the player entity. Not quite sure what's going wrong here. Very strange.

EDIT: Found that there was a minor bug:

this.pos.x = this.owner.x + this.offset.x;
this.pos.y = this.owner.y + this.offset.y;

..when it should be:

this.pos.x = this.owner.pos.x + this.offset.x;
this.pos.y = this.owner.pos.y + this.offset.y;

Seems to be working as expected now. Thanks again.

1 decade ago by alexandre

EDIT: oops. you posted while I was. Oh well, here's some further advice. :)

...
zIndex perhaps, i.e., weapon spawned after player may be covered by it.

If I were doing this, I'd probably want the player to start out weapon-less. Eventually, through exploration or trade, he'd acquire a weapon. So, no weapons spawned at player init time. I'd relegate that to some pickup method.

main.js:
loadLevel: function(data)
{
	this.parent(data);
	
	// Add a weapon somewhere in world,
	// say between 100 and 1000 units southeast of player (offscreen, maybe)
	var x = Math.random().map(0,1,100,1000).round();
	var y = Math.random().map(0,1,100,1000).round();
	var p = this.getEntitiesByType('EntityPlayer')[0];
	this.spawnEntity('EntityWeapon', p.pos.x + x, p.pos.y+y);
},

update: function()
{
	this.updateFreeWeaponIf();
	this.parent();
},

updateFreeWeaponIf: function()
{
	// Until it's been picked up, adjust weapon's zIndex depending on
	// whether player is above it or not:
	// lower player y = weapon should have a higher z, i.e. drawn last
	// higher player y = weapon should have a lower z, i.e., drawn first
	var w = this.getEntitiesByType('EntityWeapon')[0];
	if (w && w.owner == null)
	{
		var oldZ = w.zIndex;
		
		var p = this.getEntitiesByType('EntityPlayer')[0];
		w.zIndex = (p.pos.y < w.pos.y ? p.zIndex + 1 : p.zIndex - 1);

		// Resort if index changed
		if (w.zIndex != oldZ)
			this.sortEntitiesDeferred();
	}
}

player.js:
weapon: null,

pickup: function(other)
{
	if (other instanceof EntityWeapon)
	{
		this.weapon = other;
		other.owner = this;
		other.zIndex = this.zIndex+1;
	}
},

drop: function(weapon)
{
	this.weapon = null;
	weapon.owner = null;
}

1 decade ago by fulvio

The updated code doesn&039;t seem to be working properly just yet. I think it might be a problem that the #update() method of the EntityWeapon is checking for whether there&039;s an #owner or not. So if we're spawning, there won't be one until collection, right? Bit confused on that one.

I&039;m guessing there should there be a #check() method in EntityWeapon that executes pickup() at some point when the player collides with it?

Also when would drop() execute? When a different weapon is picked up I guess?

I will have a bit more of a play around, I've been trying to get it working while on the train to work and it's not the best environment to code in. ;-)

So far this is the entire EntityWeapon class:

ig.module('game.entities.weapon').requires('impact.entity').defines(function() {
    EntityWeapon = ig.Entity.extend({
        size: { x: 7, y: 6 },
        offset: { x: 10, y: 80 },
        type: ig.Entity.TYPE.A,
        checkAgainst: ig.Entity.TYPE.NONE,
        collides: ig.Entity.COLLIDES.ACTIVE,
        bounciness: 0.1,
        //gravityFactor: 1,
        owner: null,
        weapon: null,
        //zIndex: 2,
        animSheet: new ig.AnimationSheet('media/sprites/laser-gun.png', 7, 6),
        init: function(x, y, settings) {
            this.parent(x, y, settings);
            this.addAnim('idle', 1, [0], true);

            console.log('spawned.x=' + this.pos.x);
            console.log('spawned.y=' + this.pos.y);
        },
        pickup: function(other) {
            if (other instanceof EntityWeapon) {
                this.weapon = other;
                other.owner = this;
                other.zIndex = this.zIndex + 1;
            }
        },
        drop: function(weapon) {
            this.weapon = null;
            weapon.owner = null;
        },
        update: function() {
            if (this.owner) {
                if (this.owner.flip) {
                    this.pos.x = this.owner.pos.x + 4;
                } else {
                    this.pos.x = this.owner.pos.x + 23;
                }
                this.pos.y = this.owner.pos.y + 90;
                this.currentAnim.flip.x = this.owner.currentAnim.flip.x;
            } else {
                this.parent();
            }
        }
    });
});

EDIT: The weapon itself does spawn, however it's floating above the player and also moves on the Y-axis when the player is near it. Very strange.

1 decade ago by alexandre

You should disable collisions for your weapon. Give it a collides of NEVER. It should not be affected when the player's bounds are over it:

weapon.js:
type: ig.Entity.TYPE.A,
checkAgainst: ig.Entity.TYPE.NONE,
collides: ig.Entity.COLLIDES.NEVER,

Also, in my example, pickup and drop were player methods, not weapon methods.


As for the how of pickups and drops, I'd bind a couple of keys for those, then:

player.js:
update: function()
{
  if (ig.input.state('drop') && this.weapon)
  {
    this.drop(this.weapon);
  }

  this.parent();
},

check: function(other)
{
  if (other instanceof EntityWeapon && this.weapon == null && ig.input.state('pickup'))
  {
    this.pickup(other);
  }
  this.parent(other);
}

1 decade ago by alexandre

I forgot to ask, for clarity's sake: is your game a platformer or top-down? zIndex updates won't be needed for platformers. Just make sure that weapons and other game accessories have a higher default zIndex than the player does.

1 decade ago by fulvio

@alexandre: My game&039;s a platformer. Thanks for the info regarding the zIndex value. Will give the code a go. I didn't notice that the #drop() and pickup() functions were meant to go in the player entity. D'oh.

1 decade ago by xOpti

I have a system like this working pretty well. The only issue that I notice is that the spawned modules do not always keep up with the 'owner'. Especially when moving diagonally, the modules separate several pixels behind the owner. Once stopped, they sync back up again.

Anyone notice this issue or how to resolve it?
Page 1 of 1
« first « previous next › last »