tileset collision

So I'm trying to do tileset collision and I got it partly working. it works from the left and bottom of the tileset and from the right and top I go through the tileset and stop while standing on it. I'm using a virtual joystick and not getting my head wrapped around it. here is the code for the joystick. It works all the way with the keyboard arrow keys but I really need it working with the joystick as it's going to be a mobile game.
Code:
if(device_mouse_x_to_gui(0) < get_stop_view/2) {

guiposX = event_data[? "guiposX"];
guiposY = event_data[? "guiposY"];
// jDis = joystick distance
// jDir = joystick direction
var jDis = min(30, point_distance(guistartposX, guistartposY, guiposX, guiposY));
var jDir = point_direction(guistartposX, guistartposY, guiposX, guiposY);

guiposX = guistartposX + lengthdir_x(jDis, jDir);
guiposY = guistartposY + lengthdir_y(jDis, jDir);


for(var i=0; i<2; i++) {
    if (jDis >=2) && (device_mouse_check_button(i, mb_left)) {
        obj_blob.direction = jDir;
        obj_blob.speed = jDis/10;
        show_debug_message(obj_blob.direction);
      
    }
    if (jDis = 0) { obj_blob.speed = 0 }
}
jVisible = true;
}
and here is the code for the collision detection

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);

hsp = (key_right - key_left) * 2;
vsp = (key_down - key_up) * 2;


//Keep player inside the map
if (x <= 64) x = 64;
if (x >= room_width - 64) x = room_width - 64;
if (y <= 64) y = 64;
if (y >= room_height - 64) y = room_height - 64;

for(var i=0; i<2; i++) {
      
}
x += hsp;

if(speed = 0) {
    image_speed = 0;
} else {
    image_speed = .2;
}

// Horizontal collison
if (hsp > 0) bbox_side = bbox_right; else bbox_side = bbox_left;
if (tilemap_get_at_pixel(tilemap,bbox_side+hsp,bbox_top) != 0) || (tilemap_get_at_pixel(tilemap,bbox_side+hsp,bbox_bottom) != 0)
{
    if (hsp > 0) x = x - (x mod 32) + 31 - (bbox_right - x);
    else x = x - (x mod 32) - (bbox_left - x);
    hsp = 0;
}

x += hsp;

// Vertical collison
if (vsp > 0) bbox_side = bbox_bottom; else bbox_side = bbox_top;
if (tilemap_get_at_pixel(tilemap,bbox_left,bbox_side+vsp) != 0) || (tilemap_get_at_pixel(tilemap,bbox_right,bbox_side+vsp) != 0)
{
    if (vsp > 0) y = y - (y mod 32) + 31 - (bbox_bottom - y);
    else y = y - (y mod 32) - (bbox_top - y);
    vsp = 0;
}
y += vsp;
How would I go about doing this?
 
Last edited:

TheouAegis

Member
You are checking collisions based on hsp and vsp, but your gamepad code is using hspeed and vspeed (direction & speed). You need to make your gamepad code use hsp and vsp.
 
You are checking collisions based on hsp and vsp, but your gamepad code is using hspeed and vspeed (direction & speed). You need to make your gamepad code use hsp and vsp.
So how would I implement that? I understand it with the vsp and hsp but not with the directions using the joystick.
 
Edited your code a bit. Some parts were weird, like a for loop that doesn't do anything and a "x += hsp;" that was written twice.
Arranged things a bit to my liking, for easier readability.

I don't know why you were using "mod" to try to set the position of the player. I changed it so simply rounding down to the tile. You may have to adjust it depending on how you manage your origin points. I assumed your tilemap uses 32px X 32px tiles.


GML:
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);

hsp = (key_right - key_left) * 2;
vsp = (key_down - key_up) * 2;


//Keep player inside the map
if (x <= 64)                x = 64;
if (x >= room_width - 64)    x = room_width - 64;
if (y <= 64)                y = 64;
if (y >= room_height - 64)    y = room_height - 64;

if(speed = 0)    image_speed = 0;
else            image_speed = .2;

// Horizontal collison
if (hsp > 0)    bbox_side = bbox_right;
else            bbox_side = bbox_left;

if (tilemap_get_at_pixel(tilemap,bbox_side+hsp,bbox_top) != 0)
|| (tilemap_get_at_pixel(tilemap,bbox_side+hsp,bbox_bottom) != 0)
{
    // Assuming the x is in the middle of object or at least not too close to its bounding box.
    // Only need to lock into the position of the tile he's into. Either side is the same.
    x = floor(x/32)*32;
    hsp = 0;
}

// Vertical collison
if (vsp > 0)    bbox_side = bbox_bottom;
else            bbox_side = bbox_top;

if (tilemap_get_at_pixel(tilemap,bbox_left,bbox_side+vsp) != 0)
|| (tilemap_get_at_pixel(tilemap,bbox_right,bbox_side+vsp) != 0)
{
    y = floor(y/32)*32;
    vsp = 0;
}

// "x += hsp" was duplicated. Moved it here for easier readability.
x += hsp;
y += vsp;
 
Edited your code a bit. Some parts were weird, like a for loop that doesn't do anything and a "x += hsp;" that was written twice.
Arranged things a bit to my liking, for easier readability.

I don't know why you were using "mod" to try to set the position of the player. I changed it so simply rounding down to the tile. You may have to adjust it depending on how you manage your origin points. I assumed your tilemap uses 32px X 32px tiles.


GML:
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);

hsp = (key_right - key_left) * 2;
vsp = (key_down - key_up) * 2;


//Keep player inside the map
if (x <= 64)                x = 64;
if (x >= room_width - 64)    x = room_width - 64;
if (y <= 64)                y = 64;
if (y >= room_height - 64)    y = room_height - 64;

if(speed = 0)    image_speed = 0;
else            image_speed = .2;

// Horizontal collison
if (hsp > 0)    bbox_side = bbox_right;
else            bbox_side = bbox_left;

if (tilemap_get_at_pixel(tilemap,bbox_side+hsp,bbox_top) != 0)
|| (tilemap_get_at_pixel(tilemap,bbox_side+hsp,bbox_bottom) != 0)
{
    // Assuming the x is in the middle of object or at least not too close to its bounding box.
    // Only need to lock into the position of the tile he's into. Either side is the same.
    x = floor(x/32)*32;
    hsp = 0;
}

// Vertical collison
if (vsp > 0)    bbox_side = bbox_bottom;
else            bbox_side = bbox_top;

if (tilemap_get_at_pixel(tilemap,bbox_left,bbox_side+vsp) != 0)
|| (tilemap_get_at_pixel(tilemap,bbox_right,bbox_side+vsp) != 0)
{
    y = floor(y/32)*32;
    vsp = 0;
}

// "x += hsp" was duplicated. Moved it here for easier readability.
x += hsp;
y += vsp;
Thanks, I'll try it out here in a bit.
 
Edited your code a bit. Some parts were weird, like a for loop that doesn't do anything and a "x += hsp;" that was written twice.
Arranged things a bit to my liking, for easier readability.

I don't know why you were using "mod" to try to set the position of the player. I changed it so simply rounding down to the tile. You may have to adjust it depending on how you manage your origin points. I assumed your tilemap uses 32px X 32px tiles.


GML:
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);

hsp = (key_right - key_left) * 2;
vsp = (key_down - key_up) * 2;


//Keep player inside the map
if (x <= 64)                x = 64;
if (x >= room_width - 64)    x = room_width - 64;
if (y <= 64)                y = 64;
if (y >= room_height - 64)    y = room_height - 64;

if(speed = 0)    image_speed = 0;
else            image_speed = .2;

// Horizontal collison
if (hsp > 0)    bbox_side = bbox_right;
else            bbox_side = bbox_left;

if (tilemap_get_at_pixel(tilemap,bbox_side+hsp,bbox_top) != 0)
|| (tilemap_get_at_pixel(tilemap,bbox_side+hsp,bbox_bottom) != 0)
{
    // Assuming the x is in the middle of object or at least not too close to its bounding box.
    // Only need to lock into the position of the tile he's into. Either side is the same.
    x = floor(x/32)*32;
    hsp = 0;
}

// Vertical collison
if (vsp > 0)    bbox_side = bbox_bottom;
else            bbox_side = bbox_top;

if (tilemap_get_at_pixel(tilemap,bbox_left,bbox_side+vsp) != 0)
|| (tilemap_get_at_pixel(tilemap,bbox_right,bbox_side+vsp) != 0)
{
    y = floor(y/32)*32;
    vsp = 0;
}

// "x += hsp" was duplicated. Moved it here for easier readability.
x += hsp;
y += vsp;
This just makes the player jump around everywhere.
 

TheouAegis

Member
The 1st post I made was how you do it with the joystick. Replace The reference to direction and speed with the 2 lines I posted earlier.
 
The 1st post I made was how you do it with the joystick. Replace The reference to direction and speed with the 2 lines I posted earlier.
Ok, I put something like this
Code:
hsp = dcos(jDir)*jDis/10
vsp = dsin(jDir)*jDis/10 

obj_blob.x += hsp;
obj_blob.y += vsp;
is that correct? It's moving but moving all crazy
 
So how would I detect a collision with the tilemap with my current joystick code, without using vsp and hsp? I would think that would be a little more simple as I already have my character movement the way I want. I know I have to use tilemap_get_at_pixel but how do I detect it with point_direction or whatever?
 
What you have to do for tile collisions :
  1. Figure out where your object is going to be at end of this step, using his position and whatever value you use to make him move
  2. Check if at this position he's going to collide with tiles.
  3. If yes, prevent him from going there (bring his speed down to zero) and put the object close to the tile.
It doesn't matter if you do it with hsp, vsp or speed or whatever. The basic logic stays the same.
 
What you have to do for tile collisions :
  1. Figure out where your object is going to be at end of this step, using his position and whatever value you use to make him move
  2. Check if at this position he's going to collide with tiles.
  3. If yes, prevent him from going there (bring his speed down to zero) and put the object close to the tile.
It doesn't matter if you do it with hsp, vsp or speed or whatever. The basic logic stays the same.
I understand the concept of it and I can get it with keyboard controls but any attempt I make using the virtual joystick is where I run into issues.
 
What you have to do for tile collisions :
  1. Figure out where your object is going to be at end of this step, using his position and whatever value you use to make him move
  2. Check if at this position he's going to collide with tiles.
  3. If yes, prevent him from going there (bring his speed down to zero) and put the object close to the tile.
It doesn't matter if you do it with hsp, vsp or speed or whatever. The basic logic stays the same.
I got it, I had to move point on the sprite to bottom center instead of middle center. Seems to be working right now.
 
Top