• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM Collisions without using the solid tickbox

B

bigbeno37

Guest
Over the last couple of days, I've been trying to get into Game Maker and see what I can do with it. It seems pretty cool so far, but I've read from numerous places online that using the solid tickbox for any object that does not move leads to more bad than good, and hence I stopped using it. But now, I have to program in collision handling, which is a pain.

One of my main issues is when dealing with collisions with the wall; I would like the player to be able to go right up to the wall, but when I do this, the player is able to go into the wall, but not escape from it. This is my current code:

Code:
///scr_move_state

// Define right_key and such vars
scr_get_input();

if (dash_key and (x_axis != 0 or y_axis != 0)) {
    state = scr_dash_state;
    alarm[0] = room_speed/6;
}

if (white_key) {
    sprite_index = spr_player_white;
}

if (black_key) {
    sprite_index = spr_player_black;
}

// Get direction
dir = point_direction(0, 0, x_axis, y_axis);

// Get the length
if (x_axis == 0 and y_axis == 0) {
    len = 0;
} else {
    len = obj_player_speed;
}

// Get the h_speed and v_speed
var h_speed = lengthdir_x(len, dir);
var v_speed = lengthdir_y(len, dir);

var collision_check_distance = 20;

if ((up_key and !place_meeting(x, y-collision_check_distance, obj_wall)) or (down_key and !place_meeting(x, y+collision_check_distance, obj_wall))){
    y += v_speed;
}

if ((right_key and !place_meeting(x+collision_check_distance, y, obj_wall)) or (left_key and !place_meeting(x-collision_check_distance, y, obj_wall))){
    x += h_speed;
}
To get around the issue of plays being able to go into the wall, I made a conditional checking to see if the player intersects with the wall within collision_check_distance units. If I make value low, then the players can move into the wall, but if I make this high, there is an invisible wall between the player and the wall.

Another issue I'm having is that when the player dashes (press SHIFT -> go 4 times the normal speed in one direction for a certain period of time), they can seemingly go past some of this barrier; even with an invisible wall between the player and the wall, if the player dashes into it, they can occasionally go further than 20 pixels (the value I'm using at the moment), which shouldn't happen. The code for the dash state can be found here:

Code:
///scr_dash_state
var len = obj_player_speed*4;

// Get the h_speed and v_speed
var h_speed = lengthdir_x(len, dir);
var v_speed = lengthdir_y(len, dir);

var dash_collision_check_distance = 20;

if (place_meeting(x+dash_collision_check_distance, y, obj_wall) or place_meeting(x-dash_collision_check_distance, y, obj_wall)){
    h_speed = 0;
}

if (place_meeting(x, y+dash_collision_check_distance, obj_wall) or place_meeting(x, y-dash_collision_check_distance, obj_wall)){
    v_speed = 0;
}

x += h_speed;
y += v_speed;

// Create the dash effect
var dash = instance_create(x, y, obj_dash_effect);
dash.sprite_index = sprite_index;
dash.image_index = image_index;
And for my final issue, I have two enemies that constantly follow the player around. With solid collision checking, this was fine; they would collide, and continue heading in the direction of the player, without intersecting. Now, however, when the two enemies collide, they simply freeze, and do not move any further. Here is the code for the enemies:

Code:
///scr_enemy_move_state

// Get direction
var dir = point_direction(x, y, obj_player.x, obj_player.y);
var len = obj_enemy_speed;

// Get the h_speed and v_speed
var h_speed = lengthdir_x(len, dir);
var v_speed = lengthdir_y(len, dir);

var collision_check_distance = 5;

if (!place_meeting(x, y-collision_check_distance, obj_collide) or !place_meeting(x, y+collision_check_distance, obj_collide)){
    y += v_speed;
}

if (!place_meeting(x+collision_check_distance, y, obj_collide) or !place_meeting(x-collision_check_distance, y, obj_collide)){
    x += h_speed;
}
If you want to take a look at the source code in it's entirety, it's all on github: https://github.com/bigbeno37/ROYGBIV/tree/remove-physics

And here's a link to the .exe file if you want clarification on what I'm talking about: https://drive.google.com/open?id=0BySjsjvInP0-NGtLWi1vZ0VQTVU

I apologise if all of this has been answered before. I tried taking a look, but nothing satisfactorily answered my questions.

Thank you to anybody who replies!
 

HayManMarc

Member
This is a pretty common issue for newbies, I'm surprised you couldn't find a solution during your search.

I'm not sure why you are using the value 20 for your collision detection distance. Try changing that value to match your speed. That will start you in the right direction.

The object moves "speed value" pixels per step, so you want to check within that amount of space per step. This won't get you pixel perfect collisions, but it will get you closer to your goal.

I'd explain further, but I'm winding down. Perhaps tomorrow if nobody takes over.
 

Roderick

Member
One problem that I had early on with manual collision detection was that I'd suddenly find my character getting stuck to a wall, just like you're describing.

In my case, the problem was precise collision masking. The character would stop one pixel before overlapping the wall, as intended, then drop into the idle animation, which was wider, and suddenly be overlapping the wall.

It's best, in my experience, to use rectangle or oval collision detection for your character, and make sure that the origin and collision masks are the same for every sprite the object uses.

And if you want to hand code collision, check out @ShaunJS's pixel-perfect platformer tutorial:
 
Top