vonhellblazer
Member
I'm using tile-based collisions for this game, but ordinarily, I'd be using object-based collisions and this wouldn't be a problem. I need to push or pull an object (in this case a box) when I get up next to it. Because my collisions are tile-based, my character just passes through any object, even when it's checked solid.
CREATE:
STEP:
COLLISION SCRIPT:
MOVEMENT SCRIPT:
CREATE:
GML:
/// @desc
//speeds
hsp = 0;
vsp = 0;
max_spd = 2;
walk_spd = 1.5;
hsp_decimal = 0;
vsp_decimal = 0;
jump_spd = -5;
jumps_initial = 2;
jumps = jumps_initial;
//friction
drag = .12;
//direction
facing = 1;
//movement
left = 0;
right = 0;
up = 0;
down = 0;
attack = 0;
jump = 0;
enum states {
IDLE,
WALK,
JUMP,
ATTACK
}
state = states.IDLE;
states_array[states.IDLE] = player_idle_state;
states_array[states.WALK] = player_walk_state;
states_array[states.JUMP] = player_jump_state;
states_array[states.ATTACK] = player_attack_state;
sprites_array[states.IDLE] = s_player_idle;
sprites_array[states.WALK] = s_player_walk;
sprites_array[states.JUMP] = s_player_jump;
sprites_array[states.ATTACK] = s_player_attack;
GML:
//execute state
script_execute(states_array[state]);
GML:
function collision() {
if hsp == 0 hsp_decimal = 0;
if vsp == 0 vsp_decimal = 0;
//apply carried over decimals
hsp += hsp_decimal;
vsp += vsp_decimal;
//floor decimals
//save and subtract decimals
hsp_decimal = frac(hsp);
hsp -= hsp_decimal;
vsp_decimal = frac(vsp);
vsp -= vsp_decimal;
//horizontal collision
var side;
//determine which side to test
if hsp > 0 side = bbox_right else side = bbox_left;
//check the top and bottom of the side
var t1 = tilemap_get_at_pixel(global.map, side + hsp, bbox_top);
var t2 = tilemap_get_at_pixel(global.map, side + hsp, bbox_bottom);
if ((t1 != VOID) and (t1 != PLATFORM)) or
((t2 != VOID) and (t2 != PLATFORM)) {
//collision found
if hsp > 0 x = x - (x mod global.tile_size) + global.tile_size - 1 - (side - x);
else x = x - (x mod global.tile_size) - (side - x);
hsp = 0;
}
x += hsp;
//vertical collision
var side;
//determine which side to test
if vsp > 0 side = bbox_bottom else side = bbox_top;
//check the left and right side
var t1 = tilemap_get_at_pixel(global.map, bbox_left, side + vsp);
var t2 = tilemap_get_at_pixel(global.map, bbox_right, side + vsp);
var t3 = tilemap_get_at_pixel(global.map, bbox_left, bbox_bottom);
var t4 = tilemap_get_at_pixel(global.map, bbox_right, bbox_bottom);
if (t1 != VOID and (((vsp > 0 or t1 != PLATFORM)) and t3 != PLATFORM) or (t1 == SOLID and t3 == PLATFORM)) or
(t2 != VOID and (((vsp > 0 or t2 != PLATFORM)) and t4 != PLATFORM) or (t2 == SOLID and t4 == PLATFORM)) {
//collision found
if vsp > 0 y = y - (y mod global.tile_size) + global.tile_size - 1 - (side - y);
else y = y - (y mod global.tile_size) - (side - y);
vsp = 0;
}
y += vsp;
}
GML:
function calc_movement(){
hsp += (right - left) * walk_spd;
vsp += global.grav;
//drag
hsp = lerp(hsp, 0, drag);
//stop
if abs(hsp) <= 0.1 hsp = 0;
//face correct way
if hsp != 0 facing = sign(hsp);
//limit speed
hsp = min(abs(hsp), max_spd) * facing;
}