SOLVED Character collision seems one pixel off

FunkyPoop

Member
Hello,

I'm trying to build a simple platformer and am working on the movement and collision.
I copied it out of this book that I'm following called Game Development with GameMaker Studio 2 by Sebastiano M. Cossu.

In the original bookcode the player sprite is 50x64 px.
I'm trying to make a game where the player sprite is 8x8 px.
Are there any restrictions as to how small a sprite can be in GameMaker?

Because when I try to run the game, the player sprite falls one pixel in the ground object and can't move.
When I jump, I can get out of the ground object and move during airtime, but as soon as I land I get stuck again.
Weirdly enough, when keep moving to the right, I am able to move until I stop and the characters 'sinks' by one pixel. Moving to the left after a jump isn't possible.

I tried some stuff, also making the sprite bigger to see if that was the problem, but that didn't help.

Could someone help me?
Thanks in advance!

I'll paste the code under here.

Apart from obj_player, there are no other objects with code in them.


Create event to assign variables
GML:
spd = 2;
grv = 0.4;

vsp = 0;
hsp = 0;
jspd = 4;

grounded = false;
climbing = false;
Step event
GML:
var keyLeft = keyboard_check(vk_left);
var keyRight = keyboard_check(vk_right);
var keyUp = keyboard_check(vk_up);
var keyDown = keyboard_check(vk_down);
var jump = keyboard_check(vk_space);

var move = keyRight - keyLeft;
var vmove = keyDown - keyUp;
hsp = spd * move;
vsp = vsp + grv;

// Walking
if (move != 0){
    image_xscale = move;
    if(grounded){
        sprite_index = spr_player_run;
    }
} else {
    if(not climbing){
        sprite_index = spr_player_idle;
    }
}


// Jumping
if(grounded and jump){
    vsp = -jspd;
    grounded = false;
    sprite_index = spr_player_idle;
}


// Climbing
if(place_meeting(x,y+1, obj_climable)){
    if(vmove < 0) or
    (vmove == 0 and climbing) or
    (vmove > 0 and place_meeting(x, y+sprite_height, obj_climable)){
        climbing = true;
    } else {
        climbing = false;
    }
} else {
    climbing = false;
}

if(climbing){
    vsp = vmove * spd;
    sprite_index = spr_player_idle;
}


// Collision with blocks
if(place_meeting(x+hsp, y, obj_block)){
    while(not place_meeting(x+sign(hsp), y, obj_block)){
        x += sign(hsp);
    }
    hsp = 0;
}

x += hsp;


// Gravity
if(place_meeting(x, y+vsp, obj_block)){
    if(not climbing){
        while(not place_meeting(x, y+sign(hsp), obj_block)){
            y += sign(vsp);
        }
        vsp = 0;
        grounded = true;
    }
} else {
    grounded = false;
}

y += vsp;
 

Attachments

FunkyPoop

Member
woods helped me out in a conversation.

He saw that I forgot to change a little thing:
// Gravity
if(place_meeting(x, y+vsp, obj_block)){
if(not climbing){
while(not place_meeting(x, y+sign(hsp), obj_block)){
y += sign(vsp);
}

hsp should've been vsp.

Thanks again woods!
 
x is not an int. so since it's pixel art, you may want to draw yourself (or actually put yourself) on rounded coordinates.
At 8x8, it will look weird if you have some interpolation because its "trying to draw subpixels"
 
Top