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 Hareesun

I thought I'd seen it on the forums before, but I looked and couldn't see it.

I'm trying to make that age old Mario effect where certain things can be jumped through from underneath but can still be stood on. Don't suppose anyone else has done anything similar? :) Thanks!

1 decade ago by matthew

Why not just erase the collision layer for all but the very top pixels?

1 decade ago by Hareesun

Because that doesn't work :P I guess the key word is through. From underneath, jumping through the entity then landing on top of it and not falling back down through it.

1 decade ago by dominic

Have a look at the Entity's handleMovementTrace() method. Something like this should work:

handleMovementTrace: function( res ) {
	if( res.tile.x == PLATFORM_TILE ) {
		// Always ignore collisions with the PLATFORM_TILE
		// on the x axis
		res.collision.x = false;
		res.pos.x = this.pos.x + this.vel.x * ig.system.tick;
	}
		
	if( res.tile.y == PLATFORM_TILE && this.vel.y < 0 ) {
		// Ignore collisions with the PLATFORM_TILE
		// on the y axis, if we're moving upwards
		res.collision.y = false;
		res.pos.y = this.pos.y + this.vel.y * ig.system.tick;
	}
	
	// Call the original handleMovementTrace() with our modified
	// trace result (res)
	this.parent( res );
},

Where PLATFORM_TILE is the tile number on your collision map for that special "jumpthrough" tile.

Edit: Hold on, this doesn't work, because this.pos is still set to the collision pos from the trace result, regardless of res.collision is set or not. Let me think about it one sec :F

Edit2: Ok, I updated the code to also modify res.pos if a collision is ignored. Still haven't tested it. Good luck :)

1 decade ago by Hareesun

Dom, once again, you're a genius. :D

EDIT: It may be worth noting for anyone else that uses this that tile numbers start at 1 not 0 like sprite numbers.

1 decade ago by paulstraw

Dominic, this works great. The only problem I'm seeing is that there doesnt appear to be any way to get the position of the tile you're colliding with. Because of this, if the collision is still happening when the player starts descending, they magically jump to the top of the tile. Am I just missing something, or is there no way to get the x/y coords of any given tile?

1 decade ago by fugufish

mmm weird doesn't work ( i'm sure i did something wrong here)

anyone have any luck?

1 decade ago by dominic

Good point paulstraw! I didn't think of that.

If you also ignore the collision when the resulting entity position is above the current entity position you will avoid the entity being magically pushed up. Try this:
handleMovementTrace: function( res ) {
	if( res.tile.x == PLATFORM_TILE ) {
		// Always ignore collisions with the PLATFORM_TILE
		// on the x axis
		res.collision.x = false;
		res.pos.x = this.pos.x + this.vel.x * ig.system.tick;
	}
		
	if( res.tile.y == PLATFORM_TILE && (
		this.vel.y < 0 || this.pos.y > res.pos.y
	)) {
		// Ignore collisions with the PLATFORM_TILE
		// on the y axis, if we're moving upwards
		res.collision.y = false;
		res.pos.y = this.pos.y + this.vel.y * ig.system.tick;
	}		
	
	// Call the original handleMovementTrace() with our modified
	// trace result (res)
	this.parent( res );
},

fugufish: Can you be a bit more specific? Are you sure you are checking for the right tile number? As Hareesun pointed out, tile numbering starts at 1, not 0.

1 decade ago by fugufish

hmm trying to wrap my head around this...

so i'm tweaking the jump and run demo. I want to set a certain row of tiles, so that the player can jump through them from below.

using the code above is only for that one specific tile

 if( res.tile.x == PLATFORM_TILE ) {  //only for 1 tile

plus I have to manually search for that tile in the javascript file

  // what a level file looks like in a 2d platformer
   "data":[[1,1,1,1,1,1,PLATFORM_TILE,1,1,1,0,0,0,0

is there a better way to do this?

what if we create a special entity called "special_tile"? Once that is done, we can just paint that entity on the map, saves all the work trying to locate the PLATFORM_TILE.

PS: I tried doing that but had no progress :(

1 decade ago by fugufish

if we were to make this "special_tile" entity, it would have the following:

- no gravity ( the entity must not 'fall' upon being spawned )
- non-active collision
- its handleMovementTrace should be similar to what Dom has

my heads super full atm, can't code. Anyone daring enough to attempt?

1 decade ago by dominic

fugufish, PLATFORM_TILE is only a "placeholder" for the tile number. So either you replace PLATFORM_TILE with 2 in the code (1 is still for normal collisions), or you set the variable somewhere:
PLATFORM_TILE = 2;

You can then use Weltmeister to paint tile number 2 on the collision layer, instead of 1 where you want your platforms. Sorry for not making this clear earlier.

1 decade ago by paulstraw

Ah, brilliant. Thanks, Dominic!

1 decade ago by Ash_Blue

I understand how this code works with tiles. But let's say I want to make an entity like falling debris that players can jump up through. How would you alter this code to make it compatible with entities?

1 decade ago by BlackDolphinMedia

basicly the same way ..
entitie debris .. with a different collision tile + set the handlemovment function to listen just there on that event of "the act you wana do " .. so for argument sake

handleMovementTrace: function( res ) {
    if( res.tile.x ==  "2") {
        this.vel.x = -300;
	this.currentAnim = this.anims.walkup;
        res.collision.x = false;
        res.pos.x = this.pos.x + this.vel.x * ig.system.tick;
    }

.. somehow like that


if you wana set it on a special key

you have to get if( ig.input.state('swimup') ){
  .. do what you have todo
}

1 decade ago by dominic

Entity vs. Entity collisions are resolved differently than those against the collision map. handleMovementTrace() won't help you here.

One thing you could do, is using the entities check() method to temporarily disable collisions for the entity. check() is called before the collisions are handled, so if you set .collidies to ig.Entity.COLLIDES.NEVER, when this.vel.y < other.vel.y, you can move up through it. Don't forget to reset .collides in your player's update() method though.

I hope this makes sense.
Page 1 of 1
« first « previous next › last »