• 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!

Trying to Create a Script for Tile-Based Collisions

S

ShawnyTheFox

Guest
I am trying to create a script for top-down tile-based collisions that
  • can be used for any object
  • will work regardless of the object's speed
  • is tile-based
  • is independent of controls
  • only needs one script
  • has 45° slopes if possible.
How would i go about doing this? i don't really know where to start, i have only made one working collision system so far, and it was object-based.
 

Simon Gust

Member
I am trying to create a script for top-down tile-based collisions that
  • can be used for any object
  • will work regardless of the object's speed
  • is tile-based
  • is independent of controls
  • only needs one script
  • has 45° slopes if possible.
How would i go about doing this? i don't really know where to start, i have only made one working collision system so far, and it was object-based.
There is a tutorial with a download in this very forum.
https://forum.yoyogames.com/index.p...ment-and-collision-line-without-objects.4073/
 
S

ShawnyTheFox

Guest
Thanks for the recommendation. Is it GMS 2 Compatible?
 
S

ShawnyTheFox

Guest
It works pretty well on the example, but i don't know how i would implement it, and there are a few potential problems:
  • 1. I can't figure out how to edit where the tiles are, I placed some tile objects in the room and the player can pass through them, but the randomly generated ones are solid. I tried placing: obj_wall, obj_square, obj_slope1, obj_slope2, obj_slope3, and obj_slope4. None worked.
  • 2. Placing 2 player objects, it kind of worked but there were a few weird issues with the collisions. I don't know how this would translate to player and enemy collisions in my own game, but I don't quite think it would work.
  • 3. A lot of the stuff in this tutorial is really advanced, I don't think i am at that skill level yet. This might make it hard to implement other collision-based features later on.
  • 4. i don't know if it would work on larger objects, which could be a problem, as i will probably have large enemies later on in my game.
 

Simon Gust

Member
It works pretty well on the example, but i don't know how i would implement it, and there are a few potential problems:
  • 1. I can't figure out how to edit where the tiles are, I placed some tile objects in the room and the player can pass through them, but the randomly generated ones are solid. I tried placing: obj_wall, obj_square, obj_slope1, obj_slope2, obj_slope3, and obj_slope4. None worked.
  • 2. Placing 2 player objects, it kind of worked but there were a few weird issues with the collisions. I don't know how this would translate to player and enemy collisions in my own game, but I don't quite think it would work.
  • 3. A lot of the stuff in this tutorial is really advanced, I don't think i am at that skill level yet. This might make it hard to implement other collision-based features later on.
  • 4. i don't know if it would work on larger objects, which could be a problem, as i will probably have large enemies later on in my game.
I can't help you on this, You have to ask @Ariak, he made it.
 

Yal

🐧 *penguin noises*
GMC Elder
will work regardless of the object's speed
Nitpick: you should always clamp the speed to be within SOME reasonable range. Letting any value grow arbitrarily huge usually has the potential to break the game in some way, and speed is one of the most obvious ones to exploit.

If the max range is about the same size as the smallest objects you can collide with, that also solves the issues with things going through terrain... and even if it's much bigger, at least you have an upper bound for how many collision checks you need to do within a movement (approx. MoveSpeedMax/TerrainSizeMin checks)
 
S

ShawnyTheFox

Guest
the fastest you will probably be able to go is using a dash ability, but i will definitely have a clamped speed value.
On a side note, i found something that is almost exactly what i am looking for, sadly it uses objects, not tiles, which makes room-building a pain and causes a lot of lag. Also it is $3.99 for something that might not work properly.
https://marketplace.yoyogames.com/assets/1613/top-down-movement-collision
I might try to make my own, but i don't know if i am skilled enough to pull it off.
 
A

Ariak

Guest
Hello Shawny,

i'll address your issues in order:
  1. Collisions are not working with objects you place in the room as the create event setting up the random tiles overwrites them. There is a "safezone" on the top left corner of the screen. This is simpyl for demo purposes - it would take me a while to manually place down 32000x32000 tiles, so instead i made a simple loop! If it werent for the randomize loop objects you placed manually would work.
  2. As it stated in the introduction to the tutorial the player sets up the collision grid - in a real game this is naturally a terrible design choice. How many players exists has no impact on the logic behind my collisions -the same way the number of enemies will not cause object based wall collisions to glitch - however, running the setup twice by having two of my demo player objects active can certainly lead to unexpected behaviour.
  3. +4. I agree my tutorial is not beginner friendly, especially if you have not previously had an indepth look at collisions. Most of the collision code and needed scripts can be immensly simplified when using object collisions. I used grid collisions to demonstrate the immense performance boost they may offer. Heres what is simplified with objects:
  • sections 1+2 are relevant for grid collisions only. GM has built in collision line functions, if you switch on "precise collision" on the neccesary objects, this will work.
  • section 3 is interesting - this is where it all comes together to enable 45° movement. Replace my gridcol_place_meeting with the GM native place_meeting. The rest of the logic of gridcol_move_speeds still holds
  • using object collisions lets you use any sized objects - the size restrictions where neccessary at the time to facilitate grid collisions, nothing more.
As you get more familiar with collisions my work might be helpful as a reference - a direct copy paste is not adviseable as you cant really adapt them to your needs.
Its merely one approach to slopes in gamemaker. If you are not going for top-down but rather building a platformer then the tutorials by Zack Bell are a good starting point (parts 1+2).

GMS2 tile collisions and gms1 grid collisions are 100% transferable - and there are ways to make it work with any sized "objects". I would advise to adapt what I started with tiles in gms2 first, and then tinker with object sizes.

https://zackbellgames.com/2014/10/28/understanding-collision-basics/

Best of luck with your game!
 
Last edited by a moderator:
S

ShawnyTheFox

Guest
I followed Shaun Spalding's tutorial for tile-based collisions, and it was very helpful. I actually got collisions working (not completely, but i can walk against walls without going through them or being flung off-screen, so that's good :D)
I have a few problems, however.
1. it is currently horizontal-only collisions, i have the vertical collisions code ready to go but when i ran the game with horizontal and vertical checking it went haywire and pretty much sent my player off to some off-screen location when i hit the collision tiles.
2. The actual collision for each tile is... strange. The horizontal collision on the right side of the tile works fine, but on the left side you can walk only halfway into the tile before the collision happens. On the top and bottom right sides you get teleported to the non-solid side of the tile, probably because of the fact that i had to comment out the vertical collision code.

The code is as follows:
Code:
var bbox_side;
key_right = keyboard_check(vk_right);
key_left = keyboard_check(vk_left);
key_up = keyboard_check(vk_up);
key_down = keyboard_check(vk_down);
//Manage Player Movement
if (key_right)
{
x += spd;
directionfacing = 1;
}

if (key_left)
{
x += -spd;
directionfacing = 3;
}

if (key_up)
{
y += -spd;
directionfacing = 2;
}

if (key_down)
{
y += spd;
directionfacing = 4;
}

//Horizontal Collisions
if (hsp > 0)
{
bbox_side = bbox_right
}
else
{
bbox_side = bbox_left
}

//Check Tilemap
//checks a given pixel at the bbox top and bottom, and if it does not find a zero it assumes it found a collision tile.
if (tilemap_get_at_pixel(tilemap,bbox_side+hsp,bbox_top) != 0) or (tilemap_get_at_pixel(tilemap,bbox_side+hsp,bbox_bottom) != 0)
{
    if (hsp > 0) x = x - (x mod 64) + 63 - (bbox_right - x); //collide with tiles on the right
    else x = x - (x mod 64) - (bbox_left - x); //collide with tiles on the left
    hsp = 0

}
/*
//Vertical Collision
if (hsp > 0)
{
bbox_side = bbox_bottom
}
else
{
bbox_side = bbox_top
}

//Check Tilemap
if (tilemap_get_at_pixel(tilemap,bbox_left,bbox_side+vsp) != 0) or (tilemap_get_at_pixel(tilemap,bbox_right,bbox_side+vsp) != 0)
{
    if (vsp > 0) y = y - (y mod 64) + 63 - (bbox_bottom - y); //collide with tiles on the right
    else y = y - (y mod 64) - (bbox_top - y); //collide with tiles on the left
    vsp = 0

}

Code:
tilemap = layer_tilemap_get_id("Tiles_Collisions")


EDIT: I played around with it some more and got perfect horizontal collisions working, but only if i use the same movement system from the tutorial, and adding vertical movement still does not work properly. I am very confused, please help!
 
Last edited by a moderator:
S

ShawnyTheFox

Guest
YAY! I got the collisions working :D
Hopefully I can eventually add thin lines, slopes, and etc.
 
Top