W
WimpyLlama
Guest
For collision with walls and such, I use this method.
I forget who showed me this method, but I've used it ever since. It's much smoother and more reliable than Saun Spaulding's method (which for some reason doesn't even work in my current project. The player often clips into the wall on the y-axis). I showed you my collision code so you can know what type of collision checking I'm doing. Time for the actual problem.
So, I have the object oBuilding. Each of these buildings has different things in them like sprites and stats. Some don't have collision and some do. In order to test if a building the player is colliding with has collision, I created a function call "can_collide(building)". This simply takes the inputted building and looks through things in it to determine if it has collision or not, then returns a boolean. To use this function, I change a little of the collision code.
In the horizontal and vertical collision checks, I changed "if (building != noone)" to " if (can_collide(building))". This works great! I can collide with buildings that have collision and not collide with ones that don't. But there's a problem. If I have an instance with collision next to one without it, and I go through the one without it, I can easily clip into the one with collision. This is because the collision code has no way to test if the player is colliding with multiple instances, and even if it did know, it wouldn't know what to do about it. I had this same issue in a past project and ended up scraping the whole project BECAUSE of this one issue. I tried to solve it for so long, but I couldn't find a solution. Now I'm having the same issue on my current project, and I'm not turning down this time. I'm gonna figure out how to do this... with your help, lol. I can't seem to figure this out myself, so thanks for any help y'all give me!
GML:
//Movement
moveX = (keyD-keyA)*walkSpeed;
moveY = (keyS-keyW)*walkSpeed;
//Collision
//Set sprite bbox variables
var sprite_bbox_top = sprite_get_bbox_top(sprite_index)-sprite_get_yoffset(sprite_index);
var sprite_bbox_bottom = sprite_get_bbox_bottom(sprite_index)-sprite_get_yoffset(sprite_index);
var sprite_bbox_left = sprite_get_bbox_left(sprite_index)-sprite_get_xoffset(sprite_index);
var sprite_bbox_right = sprite_get_bbox_right(sprite_index)-sprite_get_xoffset(sprite_index);
//Move x
x += moveX;
//Horizontal
if (place_meeting(x+sign(moveX),y,oBuilding)) {
//Get building
var building = instance_place(x+sign(moveX),y,oBuilding);
//If we can collide with it then do collision
if (building != noone) {
if (moveX > 0) x = (building.bbox_left-1)-sprite_bbox_right;
else if (moveX < 0) x = (building.bbox_right+1)-sprite_bbox_left;
moveX = 0;
}
}
//Move y
y += moveY;
//Vertical
if (place_meeting(x,y+sign(moveY),oBuilding)) {
//Get building
var building = instance_place(x,y+sign(moveY),oBuilding);
//If we can collide with it then do collision
if (building != noone) {
if (moveY > 0) y = (building.bbox_top-1)-sprite_bbox_bottom;
else if (moveY < 0) y = (building.bbox_bottom+1)-sprite_bbox_top;
moveY = 0;
}
}
So, I have the object oBuilding. Each of these buildings has different things in them like sprites and stats. Some don't have collision and some do. In order to test if a building the player is colliding with has collision, I created a function call "can_collide(building)". This simply takes the inputted building and looks through things in it to determine if it has collision or not, then returns a boolean. To use this function, I change a little of the collision code.
GML:
if (place_meeting(x+sign(moveX),y,oBuilding)) {
//Get building
var building = instance_place(x+sign(moveX),y,oBuilding);
//If we can collide with it then do collision
if (can_collide(building)) {
if (moveX > 0) x = (building.bbox_left-1)-sprite_bbox_right;
else if (moveX < 0) x = (building.bbox_right+1)-sprite_bbox_left;
moveX = 0;
}
}