# need help with colision

P

#### piksil_demon

##### Guest
so with my current code, the player will completely stop moving if encountering a wall, and cannot move away. the code im using dosnt use hspeed or vspeed so that all 8 directions are the same speed (google pythagorean theorem if you dont understand why).
so, without switching to hspeed and vspeed- how do i make a collision program for the code bellow?

//variables
var up, down, left, right, arrow;
up = keyboard_check (ord('W'));
down = keyboard_check (ord('S'));
left = keyboard_check (ord('A'));
right = keyboard_check (ord('D'));

//player movemnt
image_angle = point_direction(x, y, mouse_x, mouse_y);

if! up and !down and !left and !right {speed=0};
else {speed=spd;}

if right {
direction = 0;
}
if up {
direction = 90;
}
if left {
direction = 180;
}
if down {
direction = 270;
}
if up and right {
direction = 45;
}
if up and left {
direction = 135;
}
if down and left {
direction = 225;
}
if down and right {
direction = 315;
}

//collision
if instance_place (x,y, obj_wall)speed = 0;

p.s. i dont need to be told what the problem with the code is. i need to be told the solution

W

#### Wild_West

##### Guest
Well my first question is why are you setting the built in speed variable to another named spd which I assume does the same thing as actual speed?

Second would be , why use instance_place over place_meeting?

As the manual states :

With this function you can check a position for a collision with another instance or all instances of an object using the collision mask of the instance that runs the code for the check. When you use this you are effectively asking GameMaker: Studio to move the instance to the new position, check for a collision, move back and tell you if a collision was found or not. This will work for precise collisions, but only if both the instance and the object being checked for have precise collision masks selected otherwise only bounding box collisions are applied. this function will return the unique instance id of the object being collided, but if that is not needed it is slightly faster to use the function place_meeting. This function also accepts the special keywords all and other and will return the keyword noone if no collision occurs.

Note that the given x/y coordinates will be rounded to the nearest integer before the check is performed, so if this is not what you require (or you have been using a legacy GameMaker product), you should floor the coordinates in the check: instance_place(floor(x), floor(y), obj_Enemy).

Also adding a value to check a bit ahead of your object should help too so it won't check for the EXACT x and y position and then by that time the 2 instances are in fact colliding.

if(place_meeting( x + value, y, wall_object) ){ speed = 0;}

At least that's how I've been doing it.

P

#### piksil_demon

##### Guest
Well my first question is why are you setting the built in speed variable to another named spd which I assume does the same thing as actual speed?

Second would be , why use instance_place over place_meeting?

As the manual states :

With this function you can check a position for a collision with another instance or all instances of an object using the collision mask of the instance that runs the code for the check. When you use this you are effectively asking GameMaker: Studio to move the instance to the new position, check for a collision, move back and tell you if a collision was found or not. This will work for precise collisions, but only if both the instance and the object being checked for have precise collision masks selected otherwise only bounding box collisions are applied. this function will return the unique instance id of the object being collided, but if that is not needed it is slightly faster to use the function place_meeting. This function also accepts the special keywords all and other and will return the keyword noone if no collision occurs.

Note that the given x/y coordinates will be rounded to the nearest integer before the check is performed, so if this is not what you require (or you have been using a legacy GameMaker product), you should floor the coordinates in the check: instance_place(floor(x), floor(y), obj_Enemy).

Also adding a value to check a bit ahead of your object should help too so it won't check for the EXACT x and y position and then by that time the 2 instances are in fact colliding.

if(place_meeting( x + value, y, wall_object) ){ speed = 0;}

At least that's how I've been doing it.
im using spd as a variable because there is a level up system im planing on implementing, i dont want it to effect the speed of the mobs so i set a local variable.
as for your second question- im a noob, i dont know these things.
will my character be able to move faster than the width of the block and still allow this collision to happen?

also, what is "value"? it gave me an error

Last edited by a moderator:

#### jo-thijs

##### Member
@demonlight, you haven't given any actual collision code, so I'm guessing you're using solid objects, which is disrecommended.
When objects collide with solid objects and there is a collision event in one with other one, then the objects will reset their positions before the collision event happens,
making no difference between horizontal or vertical movement.

I know you didn't want an explenation for what's going wrong, but a working solution,
but for us to be able to give you a working collision code, we would need a lot of information about how your project works.

Also, don't make duplicate topics, that's against the rules.

And also, Wild_West's second point is a very valid one.
Use place_meeting and use correct coordinates in it.

P

#### piksil_demon

##### Guest
@demonlight, you haven't given any actual collision code, so I'm guessing you're using solid objects, which is disrecommended.
When objects collide with solid objects and there is a collision event in one with other one, then the objects will reset their positions before the collision event happens,
making no difference between horizontal or vertical movement.

I know you didn't want an explenation for what's going wrong, but a working solution,
but for us to be able to give you a working collision code, we would need a lot of information about how your project works.

Also, don't make duplicate topics, that's against the rules.

And also, Wild_West's second point is a very valid one.
Use place_meeting and use correct coordinates in it.
im not using soild objects. this is my collision code-
//collision
if instance_place (x,y, obj_wall)speed = 0;

i had this as part of the code provided

as for wild_west's reply, i dont know HOW to use correct coordinates. i posted this in the hopes that people would assume i have 0 programming knowledge

W

#### Wild_West

##### Guest
im using spd as a variable because there is a level up system im planing on implementing, i dont want it to effect the speed of the mobs so i set a local variable.
as for your second question- im a noob, i dont know these things.
will my character be able to move faster than the width of the block and still allow this collision to happen?

also, what is "value"? it gave me an error
I put in "value" just as a stand-in for what the number of your speed would be. As in the value of the variable speed.
I'm not sure what you mean by "move faster than the width of the block" though.
But place_meeting will essentially check ahead of the player's current position( x+ a number to check in pixels, y) and if there's going to be a collision at the specified point, then it'll trigger the place_meeting function and apply your given code.
if speed is ever very high that can lead to the player or whatever object going to the point to check a bit prematurely and they still might get stuck , at least that's been my experience.
so just be careful with high speed.
Maybe set a limit in the step event or for your movement key presses.

if(spd > some number){ spd = the limiting number.}

#### Yal

##### đźŤ‹ *lemon noises*
GMC Elder
the code im using dosnt use hspeed or vspeed so that all 8 directions are the same speed (google pythagorean theorem if you dont understand why).
Feh, you could do with some more trigonometry.
This code
Code:
``````hspeed = lengthdir_x(2,45)
vspeed = lengthdir_y(2,45)``````
makes you move diagonally upwards with total speed 2.

P

#### piksil_demon

##### Guest
I put in "value" just as a stand-in for what the number of your speed would be. As in the value of the variable speed.
I'm not sure what you mean by "move faster than the width of the block" though.
But place_meeting will essentially check ahead of the player's current position( x+ a number to check in pixels, y) and if there's going to be a collision at the specified point, then it'll trigger the place_meeting function and apply your given code.
if speed is ever very high that can lead to the player or whatever object going to the point to check a bit prematurely and they still might get stuck , at least that's been my experience.
so just be careful with high speed.
Maybe set a limit in the step event or for your movement key presses.

if(spd > some number){ spd = the limiting number.}
what i mean with speed faster than the width of the block is if my character is going 33 pixels per step, how do i make sure he still collides with a block thats 32 pixels thick every time

also, i tested out if(place_meeting( x + spd, y, wall_object) ){ speed = 0;} in place of if instance_place (x,y, obj_wall)speed = 0; and the same problem happens- it gets glued to the walls

P

#### piksil_demon

##### Guest
Feh, you could do with some more trigonometry.
This code
Code:
``````hspeed = lengthdir_x(2,45)
vspeed = lengthdir_y(2,45)``````
makes you move diagonally upwards with total speed 2.
my speed isnt 2, its a changing variable due to a leveling system. can i put spd in place of 2 and it still work? also, how do i implement this into my code, and i need it to work on all 4 diagonals, not just diagonally upwards

#### Yal

##### đźŤ‹ *lemon noises*
GMC Elder
Yeah, you can use a variable instead of 2... as long as the variable contains a number at all times, it should work.

And all 360 directions work, too (you can even use a variable instead of the '45', too). 45 is upward-right, 135 is upward-left, -45 is downward-right and -135 is downward-left. (0 is right, 90 is upward, -90 or 270 is downward, 180 or -180 is left)

P

#### piksil_demon

##### Guest
Yeah, you can use a variable instead of 2... as long as the variable contains a number at all times, it should work.

And all 360 directions work, too (you can even use a variable instead of the '45', too). 45 is upward-right, 135 is upward-left, -45 is downward-right and -135 is downward-left. (0 is right, 90 is upward, -90 or 270 is downward, 180 or -180 is left)
so how would i implement it into the code i gave in the first comment? got to keep in mind that i have no experience prior to this in programing

#### Bingdom

The problem with your collision code is that whenever that 'if' statement is true, the speed = 0 will keep triggering.
What you need to do is set the player back to its original spot.

So with that 'if(place_meeting( x + spd, y, wall_object) ){ speed = 0;}'

You should have
Code:
``````if(place_meeting( x + spd, y, wall_object) ){
x -= spd;
}``````
Do this for all 4 directions and this should be fine (Up, Down, Left, Right).

EDIT:
Your movement code can be ultimately optimized

Step Event:
up = keyboard_check (ord('W'));
down = keyboard_check (ord('S'));
left = keyboard_check (ord('A'));
right = keyboard_check (ord('D'));

x+= (right - left)*spd;
y+= (down - up)*spd;

Movement Done

Last edited:
P

#### piksil_demon

##### Guest
@Bingdom how do i do that for the other 3 directions? plus it sucks me through the wall :/

also, with "x+= right - left;
y+= down - up;"
it will make the character move faster on the diagonal, which is something i specifically stated in the first post to be something i want to avoid

#### Bingdom

Then at the end of all that code do:
if speed > spd {
speed = spd;
}
That will set your speed limit diagonally

For the collision detection
Code:
``````if(place_meeting( x + spd, y, wall_object) ){
x -= spd;
}
if(place_meeting( x - spd, y, wall_object) ){
x += spd;
}
if(place_meeting( x, y + spd, wall_object) ){
y -= spd;
}
if(place_meeting( x , y - spd, wall_object) ){
y += spd;
}``````
Basically what all of this does is sets your player back to its original spot after hitting a wall.

P

#### piksil_demon

##### Guest
Then at the end of all that code do:
if speed > spd {
speed = spd;
}
That will set your speed limit diagonally

For the collision detection
Code:
``````if(place_meeting( x + spd, y, wall_object) ){
x -= spd;
}
if(place_meeting( x - spd, y, wall_object) ){
x += spd;
}
if(place_meeting( x, y + spd, wall_object) ){
y -= spd;
}
if(place_meeting( x , y - spd, wall_object) ){
y += spd;
}``````
Basically what all of this does is sets your player back to its original spot after hitting a wall.
so this is now my code-
//variables
var up, down, left, right, arrow;
up = keyboard_check (ord('W'));
down = keyboard_check (ord('S'));
left = keyboard_check (ord('A'));
right = keyboard_check (ord('D'));

//player movemnt
image_angle = point_direction(x, y, mouse_x, mouse_y);

if! up and !down and !left and !right {speed=0};
else {speed=spd;}

x+= (right - left)*spd;
y+= (down - up)*spd;

//collision
if instance_place (x,y,obj_enemy_parent) {hp -= global.enatk;}
if(place_meeting( x + spd, y, obj_wall) ){
x -= spd;
}
if(place_meeting( x - spd, y, obj_wall) ){
x += spd;
}
if(place_meeting( x, y + spd, obj_wall) ){
y -= spd;
}
if(place_meeting( x , y - spd, obj_wall) ){
y += spd;
}

now i cant move left, down makes me move down-right, and i STILL phase through walls :/

W

#### Wild_West

##### Guest
what i mean with speed faster than the width of the block is if my character is going 33 pixels per step, how do i make sure he still collides with a block thats 32 pixels thick every time

also, i tested out if(place_meeting( x + spd, y, wall_object) ){ speed = 0;} in place of if instance_place (x,y, obj_wall)speed = 0; and the same problem happens- it gets glued to the walls

But with your collision checks you need to say if NOT place meeting.
Your code now says "If I'm colliding with a wall, move me this way"

either change it to if not(place_meeting) or if( !place_meeting)
The exclamation mark means not too and will work with variables.

#### Bingdom

All of that code i gave you, you put it in a step event in this order:
Keyboard Checks
Movement x+= y+=
If speed > spd
if place_meeting

Note: Codes are read like the same way how we read books. The lines of code at the top gets executed first while the ones at the bottom are executed last, it's important where each line of code gets placed.

EDIT:
Don't worry about setting speed = 0 anymore, as you are just changing the x and y coordinates per step.

P

#### piksil_demon

##### Guest
If it's not animated the only other place I would think to look is gravity.
Are you using that at all?
no animation, its just a square with a square mask

P

#### piksil_demon

##### Guest
All of that code i gave you, you put it in a step event in this order:
Keyboard Checks
Movement x+= y+=
If speed >0
if place_meeting

Note: Codes are read like the same way how we read books. The lines of code at the top gets executed first while the ones at the bottom are executed last, it's important where each line of code gets placed.

EDIT:
Don't worry about setting speed = 0 anymore.
ok, but now it wont go flush with the wall, and if i push towards the wall it phases through still

P

#### piksil_demon

##### Guest
ok, but now it wont go flush with the wall, and if i push towards the wall it phases through still
may bad, its when i rotate i phase through the wall

#### Bingdom

keyboard_check must run inside a step event, because it needs to update every time you press a key.
I've noticed a couple of mistakes that i made.
x+= and y+= has no use with speed. use vspeed and hspeed instead
So do this
hspeed= (right - left)*spd;
vspeed= (down - up)*spd;
After that, you will need to limit the speed if the player is going diagonal.
if speed > spd {
speed = spd;
}

The way how i checked for collisions was kinda wrong (and it kinda is still , but its really late for me.)
if(place_meeting( x +hspeed, y, obj_wall) ){
x -= hspeed;
}
if(place_meeting( x, y + spd, obj_wall) ){
y -= vspeed;
}

^^
Put all of this in your step event, in the same order i wrote it.

P

#### piksil_demon

##### Guest
keyboard_check must run inside a step event, because it needs to update every time you press a key.
I've noticed a couple of mistakes that i made.
x+= and y+= has no use with speed. use vspeed and hspeed instead
So do this
hspeed= (right - left)*spd;
vspeed= (down - up)*spd;
After that, you will need to limit the speed if the player is going diagonal.
if speed > spd {
speed = spd;
}

The way how i checked for collisions was kinda wrong (and it kinda is still , but its really late for me.)
if(place_meeting( x +hspeed, y, obj_wall) ){
x -= hspeed;
}
if(place_meeting( x, y + spd, obj_wall) ){
y -= vspeed;
}

^^
Put all of this in your step event, in the same order i wrote it.
now it wont go flush with the wall, and when i rotate near it the corner hits the wall it still phases through. how can i make it have pixel perfect collision, and not have the phasing glitch?

#### Bingdom

This was ripped from one of Hearbeast's pixel perfect platformer collision code
Code:
``````// Horizontal Collisions
if place_meeting(x+hspd,y,OBJ_Solid) {
while (!place_meeting(x+sign(hspd), y,OBJ_Solid)) {
x+= sign(hspd);
}
hspd = 0;
}

//Move Horizontally
x += hspd;

// Vertical Collisions
if place_meeting(x,y+vspd,OBJ_Solid) {
while (!place_meeting(x,y+sign(vspd),OBJ_Solid)) {
y+= sign(vspd);
}
vspd = 0;
}

//Move Vertically
y += vspd;``````
Work from there

EDIT:
Another method is to store the previous angle, rotate the image, if there is collision then set rotation to original angle, the code above just pushes the whole object away (i think)

Last edited:
P

#### piksil_demon

##### Guest
OTE="Bingdom, post: 40893, member: 1877"]This was ripped from one of Hearbeast's pixel perfect platformer collision code
Code:
``````// Horizontal Collisions
if place_meeting(x+hspd,y,OBJ_Solid) {
while (!place_meeting(x+sign(hspd), y,OBJ_Solid)) {
x+= sign(hspd);
}
hspd = 0;
}

//Move Horizontally
x += hspd;

// Vertical Collisions
if place_meeting(x,y+vspd,OBJ_Solid) {
while (!place_meeting(x,y+sign(vspd),OBJ_Solid)) {
y+= sign(vspd);
}
vspd = 0;
}

//Move Vertically
y += vspd;``````
Work from there

EDIT:
Another method is to store the previous angle, rotate the image, if there is collision then set rotation to original angle, the code above just pushes the whole object away (i think)[/QUOTE]
??? that just confuses me more. i need to repeat- ive never done coding before. by saying "work from there" thats like giving a toddler a gun, and putting him in a room with a t-rex and saying "goodluck son"
how do i work from there? where do i put it? why is my character phasing through the blocks? why isnt the code you gave me not pixel perfect? what can i do to fix that?
these are the questions im wondering right now, i dont understand this stuff

P

#### piksil_demon

##### Guest
This was ripped from one of Hearbeast's pixel perfect platformer collision code
Code:
``````// Horizontal Collisions
if place_meeting(x+hspd,y,OBJ_Solid) {
while (!place_meeting(x+sign(hspd), y,OBJ_Solid)) {
x+= sign(hspd);
}
hspd = 0;
}

//Move Horizontally
x += hspd;

// Vertical Collisions
if place_meeting(x,y+vspd,OBJ_Solid) {
while (!place_meeting(x,y+sign(vspd),OBJ_Solid)) {
y+= sign(vspd);
}
vspd = 0;
}

//Move Vertically
y += vspd;``````
Work from there

EDIT:
Another method is to store the previous angle, rotate the image, if there is collision then set rotation to original angle, the code above just pushes the whole object away (i think)
??? that just confuses me more. i need to repeat- ive never done coding before. by saying "work from there" thats like giving a toddler a gun, and putting him in a room with a t-rex and saying "goodluck son"
how do i work from there? where do i put it? why is my character phasing through the blocks? why isnt the code you gave me not pixel perfect? what can i do to fix that?
these are the questions im wondering right now, i dont understand this stuff.

#### Bingdom

Sorry, im really tired right now. Im at the point of giving people random code. LOL

According to your first post im guessing you are still rotating the object using image_angle = point_direction();

So you do something like this in the step event.

old_angle = image_angle;
image_angle = point_direction(x,y,mouse_x,mouse_y);
if place_meeting(x,y,OBJ_Wall) {
image_angle = old_angle;
}

The only problem with this is that the player can 'skip' angles.

P

#### piksil_demon

##### Guest
Sorry, im really tired right now. Im at the point of giving people random code. LOL

According to your first post im guessing you are still rotating the object using image_angle = point_direction();

So you do something like this in the step event.

old_angle = image_angle;
image_angle = point_direction(x,y,mouse_x,mouse_y);
if place_meeting(x,y,OBJ_Wall) {
image_angle = old_angle;
}

The only problem with this is that the player can 'skip' angles.
it says it dosnt know what old_angle is :/

#### Bingdom

It should work just fine, make sure you dont have any typos

EDIT:
Make sure you have enabled Perfect Collisions on the sprite

P

#### piksil_demon

##### Guest
It should work just fine, make sure you dont have any typos

EDIT:
Make sure you have enabled Perfect Collisions on the sprite
it still isnt pixel perfect, and it still phases through the wall when i rotate

#### Bingdom

Make sure that is enabled

W

#### Wild_West

##### Guest
what i mean with speed faster than the width of the block is if my character is going 33 pixels per step, how do i make sure he still collides with a block thats 32 pixels thick every time

also, i tested out if(place_meeting( x + spd, y, wall_object) ){ speed = 0;} in place of if instance_place (x,y, obj_wall)speed = 0; and the same problem happens- it gets glued to the walls
If it's not animated the only other place I would think to look is gravity.
Are you using that at all?
now it wont go flush with the wall, and when i rotate near it the corner hits the wall it still phases through. how can i make it have pixel perfect collision, and not have the phasing glitch?

You said when you rotate, so your square is using image_angle yeah?
If the image_angle changes it changes the object's mask too. Like I was getting at before, masks colliding is what stops objects if they're coded to interact at all with each other.

Use this code in your player object's draw event and you'll see it's bounding box (collision mask)
change.

draw_rectangle(bbox_left,bbox_top,bbox_right,bbox_bottom,true);

P

#### piksil_demon

##### Guest
Use this code in your player object's draw event and you'll see it's bounding box (collision mask)
change.

draw_rectangle(bbox_left,bbox_top,bbox_right,bbox_bottom,true);
that did nothing :/

W

#### Wild_West

##### Guest
??? that just confuses me more. i need to repeat- ive never done coding before. by saying "work from there" thats like giving a toddler a gun, and putting him in a room with a t-rex and saying "goodluck son"
how do i work from there? where do i put it? why is my character phasing through the blocks? why isnt the code you gave me not pixel perfect? what can i do to fix that?
these are the questions im wondering right now, i dont understand this stuff.
You watch any tutorials? There's a lot of good ones on youtube that got me started better than I'd done by reading about it.
I'd suggest to start :

and then when your a little more familiar try these videos :

W

#### Wild_West

##### Guest
that did nothing :/
But did you see the player bounding box change angles when it hit the wall?
That was what it was intended to show you

P

#### piksil_demon

##### Guest
But did you see the player bounding box change angles when it hit the wall?
That was what it was intended to show you
no, it did nothing and even if it did- that wouldnt tell me how to fix it

W

#### Wild_West

##### Guest
no, it did nothing and even if it did- that wouldnt tell me how to fix it
well without seeing it in action I'm afraid I can't tell you much else, sorry.
but give the tutorial videos on those channels I linked a look, they should really help.
Biggest part of learning to code isn't mastering a bunch of commands and all that, it's developing the mindset to problem solve with the tools you have.
getting the hang of seeing the logic behind the code is when you'll really start improving.
Try drawing out all the actions that should happen and compare those to your code lines, see if anything isn't matching up. It helps me sometimes when my thinking starts getting muddled.

W

#### Wild_West

##### Guest
no, it did nothing and even if it did- that wouldnt tell me how to fix it
If collision is the only issue here though, then if nothing else I can offer what I do for collisions

1. Make the wall flagged as solid.
2. use move_contact_solid(direction,-1); speed = 0; in the collision event with the wall.
3. control movement with speed so direction will take care of where it moves, since x += or -= moves in only pixels. (I'm not sure EXACTLY how that's different than speed but that's what it means seemingly)
and that usually does the trick for my objects.

P

#### piksil_demon

##### Guest
well without seeing it in action I'm afraid I can't tell you much else, sorry.
but give the tutorial videos on those channels I linked a look, they should really help.
Biggest part of learning to code isn't mastering a bunch of commands and all that, it's developing the mindset to problem solve with the tools you have.
getting the hang of seeing the logic behind the code is when you'll really start improving.
Try drawing out all the actions that should happen and compare those to your code lines, see if anything isn't matching up. It helps me sometimes when my thinking starts getting muddled.
those videos dont help this problem. also, i know what the problem is- the mask clips into the wall when i rotate. i just dont know how to fix it. until i learn more about programming its gonna be more of a q&a. when i get enough answers ill be able to form my own. you know, like how actual learning is :/

W

#### Wild_West

##### Guest
those videos dont help this problem. also, i know what the problem is- the mask clips into the wall when i rotate. i just dont know how to fix it. until i learn more about programming its gonna be more of a q&a. when i get enough answers ill be able to form my own. you know, like how actual learning is :/
You said you were a beginner with no experience, right?
I don't know how far that goes but learning some tricks even if they aren't directly related to your exact issue might give you some ideas, which is what actual learning can stem from

P

#### piksil_demon

##### Guest
You said you were a beginner with no experience, right?
I don't know how far that goes but learning some tricks even if they aren't directly related to your exact issue might give you some ideas, which is what actual learning can stem from
yes, but i cant learn if it has nothing to do with my problem. my problem is a clipping glitch, not a collision error. the point of asking questions is to learn things that you cant on your own. if your not going to provide the help i need then your input is not necessary

W

#### Wild_West

##### Guest
yes, but i cant learn if it has nothing to do with my problem. my problem is a clipping glitch, not a collision error. the point of asking questions is to learn things that you cant on your own. if your not going to provide the help i need then your input is not necessary
Just trying to offer some advice on another way to go since no one else seems to have the answer, no need to jump down my throat.
Not like I don't know how frustrating not getting this stuff can be, that's why I offered the videos.
If they can help a hopeless idiot like me they can help anybody.