C
ChaosX2
Guest
Hello,
I've been working on a tile collision system based on pixels and I would really appreciate any help in correcting my formula for the left, right, and bottom collisions (I have top working). Here's the other thread where I discovered the system and made an attempt if you need context for the problem.
The gist of it is that you create a surface to draw the tile sheet on and store it's data in a buffer, you then create a series of for loops to count the blank space (pixels) within the tiles and then store that count within a different buffer. It then calculates when a collision happens based on some comparisons. The for loop labeled "Top" works perfect but the other directions are off and I can't figure out why :/ I will be greatly indebted to anyone that can offer support to help figure out what's up.
TILE_SIZE is 64 and TILE_MAX is 1024. The tiles are on a 2048 x 2048 tile sheet.
Below is the script where you would use the player's x, y, and direction as the arguments
I've been working on a tile collision system based on pixels and I would really appreciate any help in correcting my formula for the left, right, and bottom collisions (I have top working). Here's the other thread where I discovered the system and made an attempt if you need context for the problem.
The gist of it is that you create a surface to draw the tile sheet on and store it's data in a buffer, you then create a series of for loops to count the blank space (pixels) within the tiles and then store that count within a different buffer. It then calculates when a collision happens based on some comparisons. The for loop labeled "Top" works perfect but the other directions are off and I can't figure out why :/ I will be greatly indebted to anyone that can offer support to help figure out what's up.
TILE_SIZE is 64 and TILE_MAX is 1024. The tiles are on a 2048 x 2048 tile sheet.
Code:
//Draw Event
global.topHeightBuff = buffer_create(TILE_SIZE * TILE_MAX, buffer_fast, 1);
global.bottomHeightBuff = buffer_create(TILE_SIZE * TILE_MAX, buffer_fast, 1);
global.leftWidthBuff = buffer_create(TILE_SIZE * TILE_MAX, buffer_fast, 1);
global.rightWidthBuff = buffer_create(TILE_SIZE * TILE_MAX, buffer_fast, 1);
//Surface & buffer to store tiles
var surf = surface_create(2048, 2048);
var buff = buffer_create(TILE_SIZE * TILE_MAX * TILE_SIZE * 4, buffer_fixed, 1);
surface_set_target(surf);
draw_clear_alpha(0,0);
//Loop through tiles to draw
for (var i = 0; i < TILE_MAX; i++)
{
var j = i mod 32;
var k = i div 32;
draw_tile(ts_EGM, i, 0, j * TILE_SIZE, k * TILE_SIZE);
}
surface_reset_target();
buffer_get_surface(buff, surf, 0, 0, 0);
//Nested loops to count the exact pixels of each tile
//Top
var t_y = 0;
for(var xx = 0; xx < (TILE_SIZE * TILE_MAX); xx++)
{
var count = 0;
if(xx > 0 && xx mod 2048 == 0)
{
//if(_y <= 1984)
t_y +=(TILE_SIZE - 1);
}
for(var yy = t_y; yy < (t_y + TILE_SIZE); yy++)
{
var pixel = buffer_peek(buff, (xx + (yy * TILE_SIZE * 32)) * 4, buffer_u32);
if((pixel&0xff000000) != 0 || count == TILE_SIZE) break;
count++;
}
buffer_poke(global.topHeightBuff, xx, buffer_u8, count);
}
//Down
var d_y = TILE_SIZE - 1;
//Nested loop to count the exact pixels of each tile
for(var xx = 0; xx < TILE_SIZE * TILE_MAX; xx++)
{
var count = 0;
if(xx > 0 && xx mod 2048 == 0)
{
//if(_y <= 1984)
d_y += TILE_SIZE;
}
for(var yy = d_y; yy >= (d_y - (TILE_SIZE - 1)); yy--)
{
var pixel = buffer_peek(buff, (xx + (yy * TILE_SIZE * 32)) * 4, buffer_u32);
if((pixel&0xff000000) != 0 || count == TILE_SIZE) break;
count++;
}
buffer_poke(global.bottomHeightBuff, xx, buffer_u8, count);
}
//Left
var l_x = 0;
for (var yy = 0; yy < TILE_SIZE * TILE_MAX; yy++)
{
var count = 0;
if(yy > 0 && yy mod 2048 == 0)
l_x += (TILE_SIZE - 1);
for (var xx = l_x; xx < (l_x + TILE_SIZE); xx++)
{
var pixel = buffer_peek(buff, (xx + (yy * TILE_SIZE * 32)) * 4, buffer_u32);
if ((pixel&0xff000000) != 0 || count == TILE_SIZE) break;
count++;
}
buffer_poke(global.leftWidthBuff, yy, buffer_u8, count);
}
//Right
var r_x = TILE_SIZE - 1;
for (var yy = 0; yy < TILE_SIZE * TILE_MAX; yy++)
{
var count = 0;
if(yy > 0 && yy mod 2048 == 0)
r_x += TILE_SIZE;
for (xx = r_x; xx >= (r_x - (TILE_SIZE - 1)); xx--)
{
var pixel = buffer_peek(buff, (xx + (yy * TILE_SIZE * 32)) * 4, buffer_u32);
if ((pixel&0xff000000) != 0 || count == TILE_SIZE) break;
count++;
}
buffer_poke(global.rightWidthBuff, yy, buffer_u8, count);
}
buffer_delete(buff);
surface_free(surf);
room_goto_next();
Code:
var _x = argument0; //x position
var _y = argument1; //y position
var dir = argument2; // direction player is facing
//Perform collision calculations
var t = tilemap_get_at_pixel(tile_id, _x, _y) & tile_index_mask;
var column = (_x&(TILE_SIZE - 1)) + (t * TILE_SIZE);
var row = (_y&(TILE_SIZE - 1)) - (t * TILE_SIZE);
var h_top = buffer_peek(global.topHeightBuff, column, buffer_u8);
var h_bottom = buffer_peek(global.bottomHeightBuff, column, buffer_u8);
var w_left = buffer_peek(global.leftWidthBuff, row, buffer_u8);
var w_right = buffer_peek(global.rightWidthBuff, row, buffer_u8);
var xx = _x&(TILE_SIZE - 1);
var yy = _y&(TILE_SIZE - 1);
//Left collisions
if(dir == 0)
{
if(w_left == 0) return true;
if(w_left == TILE_SIZE) return false;
if(xx <= w_left) return true;
return false;
buffer_delete(global.leftWidthBuff);
}
//Bottom collisions
if(dir == 90)
{
if(h_bottom == 0) return true;
if(h_bottom == TILE_SIZE) return false;
if(yy <= h_bottom) return true;
return false;
buffer_delete(global.bottomHeightBuff);
}
//Right collisions
if(dir == 180)
{
if(w_right == 0) return true;
if(w_right == TILE_SIZE) return false;
if(xx >= w_right) return true;
return false;
buffer_delete(global.rightWidthBuff);
}
//Top collisions
if(dir == 270)
{
if (h_top == 0) return true;
if(h_top == TILE_SIZE) return false;
if(yy >= h_top) return true;
return false;
buffer_delete(global.topHeightBuff);
}