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 rootbeerking

Hello everyone. I have a couple new questions.

Question 1: I'm working on my player movement, for a 2D platformer, and I've gotten it just about perfect, only trouble is I can't seem to find a way to stop my character from sliding when turning quickly. I think it has something to do with friction(which I've set to friction: {x: 10000, y:0} ) , however it says in the documentation that the set friction only comes into play when accel is at 0, so I'm not too sure... Long story short: I basically want the character to keep it's accel, but not slide like it's on ice when changing directions quickly.

Player Movement Code:
if( ig.input.state('left') ) {
			(ig.input.state('right') == true) ? this.accel.x = 0 : this.accel.x = -400;    
		}
		else if( ig.input.state('right') ) {
			(ig.input.state('left') == true) ? this.accel.x = 0 : this.accel.x = 400;
		}
		else {
			this.accel.x = 0;
		}

Question 2: I'm having some issues getting shadows working correctly. First o' all, I've gotten it to follow the player, however it lags behind the character a little bit like it isn't connected to the character at all, the character will move and then the shadow will move like half a second later.

Also, I'd like to make it so the shadow stays on the ground when the player is jumping, but I'm not sure how to go about that.

Lastly, I can't seem to make the shadow disappear when the player dies. Here is what I'm using for the shadow code(in main.js update before this.parent();):
if( this.player ) {
        this.shadow.pos.x = this.player.pos.x;
        this.shadow.pos.y = this.player.pos.y;
    }
    else {
	this.shadow.kill();
    }

Sorry for asking so many questions at once, but I thought it'd be better than making a separate topic for each question. Any help would be much appreciated.

Oh and if it helps here is my game so far: http://www.dashproject.com/RBKtestgame/index.html

Thank you for taking the time to read this.

1 decade ago by Ash_Blue

Q1. When somebody changes to a left or right input you could set the x velocity to 0 for a split frame. This would stop the character from going in the previous direction. Also, not too sure if setting the friction at such a high amount is a good idea.

Q2. What about making the shadow part of the character itself instead of a separate entity? That way you could shut it off during jumps or specific situations with a different animation.

If that doesn't work are you constantly drawing the shadow? If so that will make it lag. Try using update instead of draw if that's the case.

1 decade ago by rootbeerking

Quote from Ash_Blue
Q1. When somebody changes to a left or right input you could set the x velocity to 0 for a split frame.


Thanks! That worked just fine, well actually setting it to about half the normal velocity was better.

Quote from Ash_Blue
What about making the shadow part of the character itself instead of a separate entity?

Yeah I thought about this, but I wasn't sure how to pull it off exactly, and the documentation on entities didn't really answer my questions either.

As for the drawing of the shadow, it's a separate entity that I spawn at the beginning of the level load. I am using update to link the shadow.pos to player.pos, yet this still causes the lag.

Basically I want the shadow to follow the character on the x-plane but then be projected onto whatever's below them on the y plane, but I'm not sure how to get that done correctly.

1 decade ago by Ash_Blue

For Q2. I think you'll need to update the shadow's y coordinate whenever the character is .standing in the shadow's update function. Store that in a variable and fire it. I haven't tried this code, but it should work.

var player = ig.game.getEntitiesByType( EntityPlayer )[0];

if ( player.standing ) {
    standingY = player.pos.y;
}
this.pos.x = player.pos.x;
this.pos.y = standingY;

For the lag issue on the shadow I'm not seeing it. At least in Firefox 4 PC. What browser are you having this issue in?

1 decade ago by rootbeerking

Thanks Ash_Blue! That slightly works. Only issue is that it will hover if jumping over a gap, or if falling from one platform down to another. How would I go about having it so the shadow entity falls down to the nearest solid block if it's not touching the ground? I have a max Y velocity set for it but that doesn't really drop the shadow down more than it does slowly move it down a couple pixels when it's no longer "standing".

Also, the shadow is spawning on top of the player sprite, how do I make it so it's placed below the player sprite? I tried setting it's zIndex to -10 but that didn't seem to do anything.

1 decade ago by Ash_Blue

I'm stumped for that question. To be honest the only solution I can think of would be to give the shadow gravity and make it respawn if it gets too far away (falling into gaps and what nots). Hopefully someone else can jump in here with a great idea.

For the sprite overlap make sure that you set a zindex for both the player and shadow. - zindex may not work, not too sure.

1 decade ago by MikeH

For positioning the shadow beneath the player, even if the player isn't standing on a platform, in the player update function, do this :

Get the x,y position of the player into variables
get the collisionmap tile at x,y
if there's no tile (0) increment y
keep doing that until you find a collisionmap tile ( > 0)
Now you have the x,y coords for the shadow! Get the shadow entity and set them.

1 decade ago by rootbeerking

What is the code to check for a tile at x & y?

EDIT: Also it seems the following lag comes back if the player is above the shadow... Not sure why that is...Like if I spawn the shadow entity the shadow doesn't lag but if I spawn the entity and then sortEntities to get the shadow below the player it will then lag.

Also, I still can't figure out how to destroy the shadow when the player dies... I've tried "ig.game.removeEntity( EntityShadow )" before the player "this.kill()" and that did nothing...

1 decade ago by rootbeerking

Yeah... I tried looking for the answer in the documentations but couldn't find anything that looked like it had to do with checking for tiles at x & y... So I'm still wondering how to do that... Also I'm still wondering about the other things mentioned in the post above this one, so any help would be appreciated, and thanks for the help thus far.

1 decade ago by Ash_Blue

You'll probably need to email or get a hold of MikeH directly. I haven't done some of the things he mentioned so I'm not too sure how to help. Really wish profiles on here allowed us to drop some basic contact info in case of times like this (optional to give out those details of course).

1 decade ago by dominic

To check for a tile at x,y, you can use the .getTile() method.

For your problem, projecting a shadow, there is however a shortcut: You don't have to check all tiles yourself, as MikeH suggested, but can use the ig.CollisionMap's .trace() method directly.

The trace method basically starts at the specified coordinates in the CollisionMap and travels along a straight line to the target coordinates. As soon as the trace finds a solid tile, it stops and returns the coordinates of that tile.

You can use this to start a trace from your characters position straight down, to find the ground onto which the shadow can be "projected".
var tr = ig.game.collisionMap.trace( 
	// x, y position of the starting point - i.e. the position of the 
	// player character
	this.pos.x, this.pos.y, 
	
	// x, y direction of the trace. We want to trace straight down 
	// (positive y), but no further than the screen height. If 
	// there is no solid tile found, (i.e. the next solid tile is 
	// outside of the screen), we don't need to display the 
	// shadow anyway.
	0, ig.system.height, 
	
	// width and height of shadow object
	32, 16
);

// tr now hold the result of this trace, and we can check if it 
// hit a solid tile:
if( tr.collision.y ) {
	this.shadow.pos.x = tr.pos.x;
	this.shadow.pos.y = tr.pos.y;
}
else {
	// no collision? hide your shadow entity somehow
}

I hope that makes sense.


To remove the shadow, call ig.game.removeEntity() with the actual shadow entity, not with the entity class:
// Get the first entity of the class EntityShadow:
var shadowEntity = ig.game.getEntitiesByType( EntityShadow )[0];

// remove it:
ig.game.removeEntity( shadowEntity );

Note that getEntitiesByType() can be slow when you have a lot of entities in your level. It's best to save a reference to that entity somewhere, so you don't have to search for it when you need it. Since your shadow entity directly belongs to your player entity, you could create the shadow when creating the player entity, and remove it from the game world when removing the player entity:
EntityPlayer = ig.Entity.extend({
	init: function( x, y, settings ) {
		this.parent( x, y, settings );
		
		this.shadow = ig.game.spawnEntity( EntityShadow, x, y );
	},
	
	kill: function() {
		this.parent();
		this.shadow.kill();
	}
});

1 decade ago by rootbeerking

Thank you once again Dominic for your help. Only problem is I'm getting an ig.game is null error when I put "this.shadow = ig.game.spawnEntity( EntityShadow, x, y );" in my character's init function like you said. I read the documentation and found out that the error happened because the game wasn't running yet, but I'm not sure what to do to fix that problem...

How do I get the game to run before actually loading the level? I tried to remedy the error by spawning the player after the level loaded(instead of having the player entity placed in the level editor, but the only way I found I could do this is by having the character spawned in the update function, which of course then spawned a million players(which was hilarious, but not what I wanted haha.) So I then looked at the game documentation to see if there was a function that was like update but only ran once after the level was loaded, but it seems no such function exists... So I'm at a loss... Please help!

1 decade ago by dominic

Simple workaround: in your Game's init method, before you call loadLevel, do this:
ig.game = this;

Sorry for that. Didn't think about it.

1 decade ago by MikeL

@rootbeerking: I've run into the same situation. What I've done as a workaround, which has a negligible impact on performance is to set a variable for my entity called firstUpdate, as in:
EntityCannon = ig.Entity.extend({
	
        size: {x:9, y:47},
        halfWidth: 4,
        collides: ig.Entity.COLLIDES.LITE,    
        firstUpdate: true,
        .......

then in update:

update: function() {
      if (this.firstUpdate){
          //Do stuff for the first update here like spawning a shadow entity.
          this.firstUpdate = false;
      }
      //Usual update stuff.
      this.parent();
  }

Again, I haven't seen any negative impact on performance even though there is a check for firstUpdate on every update call. I'm guessing that this boolean check is super fast.

1 decade ago by MikeL

Oh, Dominic beat me to it. Much simpler. Haven't tried that.

1 decade ago by rootbeerking

@Dominic Yikes... You said simple, yet that seemingly broke everything, haha. The camera code did not like when I added ig.game = this; before loadLevel, and the ig.game null error from the "this.shadow = ig.game.spawnEntity( EntityShadow, x, y );" still happens when I load the level editor.

1 decade ago by MikeL

Well in that case, try the code that I have above. I've used it in my games and it definitely works. Let me know if you run into any issues using the firstUpdate method above.

1 decade ago by rootbeerking

Yeah, I'll give that a try MikeL, thanks!

EDIT: Alright ig.game = this; works, I'm just in idiot and misplaced some code after pasting it in... However the problem still remains with ig.game being null in the level editor, is there a work around for that as well? Cause I can no longer load the level with the player in it because of the ig.game is null error.

Also, any guesses as to why the shadow lags behind the player when moving?

1 decade ago by MikeL

@rootbeerking

Quote from rootbeerking
However the problem still remains with ig.game being null in the level editor, is there a work around for that as well?


Well, that is another reason why I go with the firstUpdate. But there is a way to check to see if Welmeister is running and then not spawn the shadow in your init function. The following is a quote from Dominic from another post:

Quote from dominic
Weltmeister only calls the init() and draw() methods of entities.
...
You can also check if ig.global.wm is defined, to see if you're running in the editor:
if( !ig.global.wm ) {
	// Not in Editor - Do some fancy stuff here.
}

1 decade ago by rootbeerking

Thank you very much MikeL! As they say: you are a gentleman and a scholar!

Now, if only the shadow didn't lag behind the character... then everything would be perfect!

1 decade ago by MikeL

Sure thing. Glad it helped! If you want, post the code for your shadow entity, or at least your init and update functions and anything that has to do with shadow movement and I'll see if I can help with the lag problem. Haven't had that situation, so no promises :)

1 decade ago by rootbeerking

Yeah, it's an odd little bug... As far as the shadow code goes I just used what Dominic said about the tracing. The complete shadow entity is just this:

EntityShadow = EntityDynamicActor.extend({
	
	size: {x:16, y:70},
        checkAgainst: ig.Entity.TYPE.B,
        
        zIndex: 1,
	
	animSheet: new ig.AnimationSheet( 'media/playershadow.png', 50, 85 ),
	
	init: function( x, y, settings ) {
		
                this.addAnim( 'idle', 1, [0] );
                this.offset.y = 18;
		this.offset.x = 16;
                this.parent( x, y, settings );
                
	},
        
        update: function() {        
    this.parent();
}
	
 
});

the init for the player is this:
EntityPlayer = EntityDynamicActor.extend({
	
  size: {x:16, y:70},
  friction: {x: 900, y:0},
  checkAgainst: ig.Entity.TYPE.B,
  animSheet: new ig.AnimationSheet( 'media/player.png', 50, 85 ),
  zIndex: 2,
	
  init: function( x, y, settings ) {
		this.parent( x, y, settings );
		this.addAnim( 'idle', 1, [0] );
    this.addAnim( 'walk', 0.2, [0] );
    this.addAnim( 'run', 0.2, [0,1] );
    this.addAnim( 'jump', 0.2, [1] );
    this.addAnim( 'crouch', 1, [3] );
    this.addAnim( 'lookup', 1, [2] );
    this.addAnim( 'fall', 0.2, [0] );
		this.offset.y = 18;
		this.offset.x = 16;
    this.maxVel.y = 400;
    this.maxVel.x = 100;
    this.jumpTimer = new ig.Timer();
		this.jumpAttackVel = -80;
		this.jumpSustainVel = -300;
		this.flipx = false;
		
		if( !ig.global.wm ) {
    // Not in Editor - Do some fancy stuff here.
    this.shadow = ig.game.spawnEntity( EntityShadow, x, y );
}

and if it helps my update function in main.js looks like this:
update: function() {
	this.parent();
    this.camera.follow( this.player ); 
     for( var i = 0; i < this.backgroundMaps.length; i++ ) {
        this.backgroundMaps[i].setScreenPos( this.screen.x, this.screen.y);
    }
    
},

My shadow entity, before Dominic kindly stepped up to the plate, looked like this:
EntityShadow = EntityDynamicActor.extend({
	
	size: {x:16, y:70},
        checkAgainst: ig.Entity.TYPE.B,
        
        zIndex: 1,
	
	animSheet: new ig.AnimationSheet( 'media/playershadow.png', 50, 85 ),
	
	init: function( x, y, settings ) {
		
                this.addAnim( 'idle', 1, [0] );
                this.offset.y = 18;
		this.offset.x = 16;
                this.maxVel.y = 1000;
                standingY = 0;
                this.parent( x, y, settings );
                
	},
        
        update: function() {        
    var player = ig.game.getEntitiesByType( EntityPlayer )[0];

    if ( player.standing ) {
        standingY = player.pos.y;
    }
    this.pos.x = player.pos.x;
    this.pos.y = standingY;
    
    this.parent();
}

});

and I spawned it in the loadLevel function after "this.parent( level );" and that didn't lag behind the player, however if I reordered the entities(to get it to appear under the player sprite) it would then cause it to lag behind the character like it does now.

That's all I can give you for clues really; hopefully you can figure it out, cause I got nothing.

1 decade ago by MikeL

Well unfortunately I haven't worked with your sort of camera movements etc, so I don't want to send you down the wrong path.

However I did come up with a fancy-shmancy way (well not really that fancy) to swap the zIndex of 2 different entities. This doesn't affect any other entities.

What you could do is call it immediately after creating the shadow and use it to swap the shadow and the player. It might be a quick thing to try and see if it works. If not, maybe someone else knows.

1 decade ago by rootbeerking

Thanks MikeL, but it doesn't actually seem to be the zindex as I had once thought, cause now with the new shadow code the shadow obeys it's zindex without needing to resort the entities. I've tried changing the zindex so that it's above the character and it still lagged. Maybe Dominic will have the answer, seeing as it's also his camera code that I'm using...

1 decade ago by dominic

The problem is quite simply that the update() method of your EntityShadow is called before the update() method of your EntityPlayer. This means, that the shadow position is set to where the player is before he moves for this frame. Then, when the update() method for the player is called, the player position is updated - the shadow "lags" one frame behind.

Here&039;s what I would do: set the position of the players shadow from within the #EntityPlayer&039;s #update() method, after calling this.parent(). This way the player position is already updated for this frame and you can set the shadow position accordingly. E.g.:

EntityPlayer = ig.Entity.extend({
	...
	update: function() {
		// move the player before updating the shadow
		this.parent()
		
		
		// do the trace on the collision map and
		// update the shadow pos from trace result
		
		...
		
		this.shadow.pos.x = tr.pos.x;
		this.shadow.pos.y = tr.pos.y;
	}
});

1 decade ago by rootbeerking

It worked! You are a genius Dominic! Thank you very much, once again, for all the help. Now I can finally move on to other things! And inevitably ask more questions.
Page 1 of 1
« first « previous next › last »