S
Sammenator
Guest
Hi there!
recently I picked up an old project (a remake of the old platformer game called Crystal Caves) and started changing over all object based collision to a tile based collision system.
my starting point was Shaun Spaldings tutorial and the YoYo games platformer tutorial.
the problem:
all collision is working fine! except one little thing when I started adding one-way platforms
suddenly whenever I walk and press the jump button the character gets snapped to the nearest 'grid' of 32 on the X axis before jumping up.
this did not happen before implementing
and to my knowledge nothing has changed in the code except improving when the code is executed plus making it work for one way platforms.
so my guess is that when I jump it somehow triggers a horizontal collision due to some behind the hood bounding box magic
so in short: perfectly working jump > adding one-way platform (which works) > jump snaps to nearest X of 32 and then jumps.
the code I run now:
the code I ran BEFORE adding the one-way platform system
additional info: the tileset that is being checked consists of the 4 tiles. the mandatory transparant at 0,0
a red square at 1,0 (used for solid walls)
a yellow square at 0,1 (used for one-way platforms)
a blue square at 1,1 (not in use at the moment, so will collide when a specific tile is not specified. will be used for enemy AI tile to guide movement)
things I have tried already:
relocating x+= hsp and y+= vsp to different locations (before inbetween or after the collision check)
relocating the horizontal collision before the vertical collision
reset the c1 and c2 variables inbetween horizontal and vertical collision to a value of -1
am I just missing something tiny here or is there something weird going on?
thanks in advance,
Sam
recently I picked up an old project (a remake of the old platformer game called Crystal Caves) and started changing over all object based collision to a tile based collision system.
my starting point was Shaun Spaldings tutorial and the YoYo games platformer tutorial.
the problem:
all collision is working fine! except one little thing when I started adding one-way platforms
suddenly whenever I walk and press the jump button the character gets snapped to the nearest 'grid' of 32 on the X axis before jumping up.
this did not happen before implementing
and to my knowledge nothing has changed in the code except improving when the code is executed plus making it work for one way platforms.
so my guess is that when I jump it somehow triggers a horizontal collision due to some behind the hood bounding box magic
so in short: perfectly working jump > adding one-way platform (which works) > jump snaps to nearest X of 32 and then jumps.
the code I run now:
Code:
/// @description Processing player
var c1, c2; //collision variables
var map = objGame.map; //tilemap for tile collision
//sort out input
key_right = keyboard_check(vk_right);
key_left = keyboard_check(vk_left);
key_jump = keyboard_check_pressed(vk_space);
//set speed and gravity
hsp = (key_right - key_left) * spd; //horzontal speed
vsp = grav; // vertical speed
grav += gravdelta; //change in gravity (acceleration towards ground)
if( grav>=gravmax ) {grav=gravmax;} //cap falling speed
var rvsp = vsp; //temporary variable
if rvsp < 0 {rvsp = rvsp + (rvsp < 0 ? -1 : 0) >> 0;} else {rvsp = rvsp + (rvsp < 0 ? 0 : 1) >> 0;} //floor and ceil vsp values bitwise to prevent bouncing effects due to rounding as bbox are rounded?
//jumping
if key_jump && jump==false { //on jump gravity is set to -6 (which effectively moves the player up instead of down)
if can_jump == true {
grav=grav_jump; // make the player jump
jump=true; // flag that we are jumping
can_jump = false;
}
}
// vertical collision
if (grav < 0) {// if we are moving up check above the player
c1 = tilemap_get_at_pixel(map,bbox_right,bbox_top+rvsp); //bounding box check top right returns index of tile it finds at the position 0 for nothing 1 2 or 3 for one of the tiles
c2 = tilemap_get_at_pixel(map,bbox_left,bbox_top+rvsp); //bounding box check top left
if ((c1 == 1) || (c2 ==1)) { //only collide when a wall tile (red) is above otherwise do nothing (jump through platform)
y = y - (bbox_top&31); //move out of the wall tile
grav = 0; //set gravity to 0 (stop moving up)
vsp = 0; //stop moving vertically for the rest of the frame
}
}
else { //check below the player
c1 = tilemap_get_at_pixel(map,bbox_right,bbox_bottom+rvsp); //bounding box check bottom right
c2 = tilemap_get_at_pixel(map,bbox_left,bbox_bottom+rvsp); //bounding box check bottom left
if ((c1 != 0) || (c2 != 0)) {
y = y - (bbox_bottom&31) + 31; // move out of the collision
jump = false; //player is on the ground again
can_jump = true; //so the player is allowed to jump again
vsp = 0;
}
}
y += vsp; // move player vertically if no collision was detected in this frame
c1 = -1; //reset collision positions for next collision check
c2 = -1;
//horizontal collision
if (hsp > 0) { //move right
dir = 1; //directon facing
sprite_index = sprCharWalk;
c1 = tilemap_get_at_pixel(map, bbox_right + hsp, bbox_top); //boudning box check top right
c2 = tilemap_get_at_pixel(map, bbox_right + hsp, bbox_bottom); //bounding box check bottom right
if ((c1 == 1) || (c2 == 1)) { //only when colliding with a wall tile (red) we stop (other are walk-through from the sides and bottom)
x = x- (bbox_right&31) + 31; // move out of the collision
hsp = 0;
}
} else if (hsp < 0) { //move left
dir = -1;
sprite_index = sprCharWalk;
c1 = tilemap_get_at_pixel(map, bbox_left + hsp, bbox_top);
c2 = tilemap_get_at_pixel(map, bbox_left + hsp, bbox_bottom);
if ((c1 == 1) || (c2 == 1)) {
x = x- (bbox_left&31); // move out of the collision
hsp = 0;
}
} else {
sprite_index = sprCharIdle;
}
x += hsp; // move player horizontally
//set jump animation and direction of looking
image_xscale = dir;
if (vsp != 0 || jump == true) {sprite_index = sprCharJump; can_jump = false;}
image_speed = 1;
Code:
/// @description Processing player
//scrProcessPlayer()
var bbox_side;
var map = objGame.map
//sort out input
key_right = keyboard_check(vk_right);
key_left = keyboard_check(vk_left);
key_jump = keyboard_check(vk_space);
//set speed and gravity
hsp = (key_right - key_left) * spd;
vsp = grav;
grav += gravdelta;
if( grav>=gravmax ) grav=gravmax;
if key_jump && jump==false {
if can_jump == true {
grav=grav_jump; // make the player jump
jump=true; // flag that we are jumping
}
}
//horizontal collision
if (hsp > 0) {bbox_side = bbox_right;} else {bbox_side = bbox_left;}
if (tilemap_get_at_pixel(map, bbox_side + hsp, bbox_top) == 1) || (tilemap_get_at_pixel(map, bbox_side + hsp, bbox_bottom) == 1) //only collide horizontally with wall collision tile (red)
{
if (hsp > 0) {x = x- (bbox_right&31) + 31; }
else {x = x- (bbox_left&31); }
hsp = 0;
}
x += hsp; // move player horizontally
//vertical collision
if (vsp > 0) {bbox_side = bbox_bottom;} else {bbox_side = bbox_top;}
var rvsp = vsp;
if rvsp < 0 {rvsp = rvsp + (rvsp < 0 ? -1 : 0) >> 0;} else {rvsp = rvsp + (rvsp < 0 ? 0 : 1) >> 0;} //floor and ceil vsp values bitwise to prevent bouncing effects due to rounding
if (tilemap_get_at_pixel(map, bbox_right, bbox_side + rvsp) != 0) || (tilemap_get_at_pixel(map, bbox_left, bbox_side + rvsp) != 0)
{
if (vsp > 0) {y = y - (bbox_bottom&31) + 31 ; jump = false; can_jump = true;}
else {y = y - (bbox_top&31); grav = 0;}
vsp = 0;
}
y += vsp; // move player vertically
//set correct animation
if (hsp > 0) {dir = 1;} else if (hsp < 0) {dir = -1;}
if (hsp == 0) {sprite_index = sprCharIdle;} else {sprite_index = sprCharWalk;}
image_xscale = dir;
if (vsp != 0 || jump == true) {sprite_index = sprCharJump; can_jump = false;}
image_speed = 1;
a red square at 1,0 (used for solid walls)
a yellow square at 0,1 (used for one-way platforms)
a blue square at 1,1 (not in use at the moment, so will collide when a specific tile is not specified. will be used for enemy AI tile to guide movement)
things I have tried already:
relocating x+= hsp and y+= vsp to different locations (before inbetween or after the collision check)
relocating the horizontal collision before the vertical collision
reset the c1 and c2 variables inbetween horizontal and vertical collision to a value of -1
am I just missing something tiny here or is there something weird going on?
thanks in advance,
Sam