I have created my own map editor for my 2d game but the collision in it is very buggy. Can any of you pros. recommend a good article with methods of creating a tile based game? Thanks.
Map Editor/Tile Based Games
Blitz3D Forums/Blitz3D Beginners Area/Map Editor/Tile Based Games Are you asking specifically about character-to-tile collisions and collision response?
Yes. Character-to-tile collisions. Doesn't this collision work the same as any other?:|
Why would all collisions systems work the same way?
For example, here's my tile collision system for my 2d platformer. It's very simplistic, handling only solid and empty tiles, and behaving badly if velocity > tile_dimensions.
For example, here's my tile collision system for my 2d platformer. It's very simplistic, handling only solid and empty tiles, and behaving badly if velocity > tile_dimensions.
function physics_move_actor(a.actor) ; moves an actor according to vx and vy, does tile collisions ; abbreviation pmg.map_grid = world\map\physical_map_grid ; reset physics feedback a\bump_left = false a\bump_right = false a\bump_top = false a\bump_bottom = false ;; STAGE 1: prevent actors from leaving the physical map max_x2 = pmg\width * pmg\tile_width - 1 max_y2 = pmg\height * pmg\tile_height - 1 if a\pos\x1+a\vx < 0 then rect_moveX1(a\pos, 0) : a\vx = 0 : a\bump_left = true if a\pos\y1+a\vy < 0 then rect_moveY1(a\pos, 0) : a\vy = 0 : a\bump_top = true if a\pos\x2+a\vx > max_x2 then rect_moveX2(a\pos, max_x2) : a\vx = 0 : a\bump_right = true if a\pos\y2+a\vy > max_y2 then rect_moveY2(a\pos, max_y2) : a\vy = 0 : a\bump_bottom = true ;; STAGE 2: prevent movement into physical_map tiles which act as walls ; figure out what tiles our current position overlaps, and what tiles our position would overlap after a full move tile_x1_cur = floor( (a\pos\x1) / pmg\tile_width) tile_x2_cur = ceil( (a\pos\x2) / pmg\tile_width) - 1 tile_y1_cur = floor( (a\pos\y1) / pmg\tile_height) tile_y2_cur = ceil( (a\pos\y2) / pmg\tile_height) - 1 tile_x1_dest = floor( (a\pos\x1+a\vx) / pmg\tile_width) tile_x2_dest = ceil( (a\pos\x2+a\vx) / pmg\tile_width) - 1 tile_y1_dest = floor( (a\pos\y1+a\vy) / pmg\tile_height) tile_y2_dest = ceil( (a\pos\y2+a\vy) / pmg\tile_height) - 1 ; try to move up (if we can't, move next to the wall and reset velocity on this axis to 0) if tile_y1_dest < tile_y1_cur then blocked = false for tile_x = tile_x1_cur to tile_x2_cur if vector_get(pmg\tile_data, (tile_x) + pmg\width * (tile_y1_dest)) = MAP_LOGIC_SOLID then blocked = true : exit next if blocked then rect_moveY1(a\pos, (tile_y1_cur) * pmg\tile_height) ; move actor to border a\vy = 0 ; lose velocity a\bump_top = true else tile_y1_cur = tile_y1_dest : tile_y2_cur = tile_y2_dest ; pretend we just moved in this direction endif endif ; try to move down (if we can't, move next to the wall and reset velocity on this axis to 0) if tile_y2_dest > tile_y2_cur then blocked = false for tile_x = tile_x1_cur to tile_x2_cur if vector_get(pmg\tile_data, (tile_x) + pmg\width * (tile_y2_dest)) = MAP_LOGIC_SOLID then blocked = true : exit next if blocked then rect_moveY2(a\pos, (tile_y2_cur+1) * pmg\tile_height) ; move actor to border a\vy = 0 ; lose velocity a\bump_bottom = true else tile_y1_cur = tile_y1_dest : tile_y2_cur = tile_y2_dest ; pretend we just moved in this direction endif endif ; try to move left (if we can't, move next to the wall and reset velocity on this axis to 0) if tile_x1_dest < tile_x1_cur then blocked = false for tile_y = tile_y1_cur to tile_y2_cur if vector_get(pmg\tile_data, (tile_x1_dest) + pmg\width * (tile_y)) = MAP_LOGIC_SOLID then blocked = true : exit next if blocked then rect_moveX1(a\pos, (tile_x1_cur) * pmg\tile_width) ; move actor to border a\vx = 0 ; lose velocity a\bump_left = true else tile_x1_cur = tile_x1_dest : tile_x2_cur = tile_x2_dest ; pretend we just moved in this direction endif endif ; try to move right (if we can't, move next to the wall and reset velocity on this axis to 0) if tile_x2_dest > tile_x2_cur then blocked = false for tile_y = tile_y1_cur to tile_y2_cur if vector_get(pmg\tile_data, (tile_x2_dest) + pmg\width * (tile_y)) = MAP_LOGIC_SOLID then blocked = true : exit next if blocked then rect_moveX2(a\pos, (tile_x2_cur+1) * pmg\tile_width) ; move actor to border a\vx = 0 ; lose velocity a\bump_right = true else tile_x1_cur = tile_x1_dest : tile_x2_cur = tile_x2_dest ; pretend we just moved in this direction endif endif ;; STAGE 3: move the actor rect_moveBy(a\pos, a\vx, a\vy) end function
I'll check out that code you posted later, looks easy to understand :o)