From 8f0b65e07c44bbf23e589ad991e9c0e2511c079f Mon Sep 17 00:00:00 2001 From: Miriam Ruiz Date: Fri, 20 Apr 2012 17:03:22 +0200 Subject: [PATCH] Fixed Collision --- engine/game.py | 82 ++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/engine/game.py b/engine/game.py index b6c475e..4526ac1 100644 --- a/engine/game.py +++ b/engine/game.py @@ -171,7 +171,8 @@ def start(screen, map_filename, hero): step_y = speed_factor * speed * dt * direction_y / dir_len if metadata_layer is not None: try: - step_x, step_y = check_collision(hero_pos_x, hero_pos_y, step_x, step_y, hero.width, hero.height, metadata_layer, tile_properties) + step_x, step_y = check_movement(hero_pos_x, hero_pos_y, step_x, step_y, \ + hero.width, hero.height, metadata_layer, tile_properties) except: pass hero_pos_x += step_x @@ -196,11 +197,46 @@ def start(screen, map_filename, hero): else: renderer.render_layer(screen, sprite_layer) + tile_width = metadata_layer.tilewidth + tile_height = metadata_layer.tileheight + tile_x_left = int((hero_pos_x - hero.width // 2) // tile_width) + tile_x_right = int((hero_pos_x + hero.width // 2) // tile_width + 1) + tile_y_up = int((hero_pos_y - hero.height) // tile_height) + tile_y_down = int((hero_pos_y) // tile_height + 1) + #show_rectangle(screen, renderer, hero_pos_x - 2, hero_pos_y - 2, 5, 5) + show_rectangle(screen, renderer, tile_x_left * tile_width - 2, tile_y_up * tile_height - 2, 5, 5) + show_rectangle(screen, renderer, tile_x_left * tile_width - 2, tile_y_down * tile_height - 2, 5, 5) + show_rectangle(screen, renderer, tile_x_right * tile_width - 2, tile_y_up * tile_height - 2, 5, 5) + show_rectangle(screen, renderer, tile_x_right * tile_width - 2, tile_y_down * tile_height - 2, 5, 5) + pygame.display.flip() +def show_rectangle(screen, renderer, x, y, w, h): + pygame.draw.rect(screen, (255, 255, 255), (x - renderer._render_cam_rect.x, y - renderer._render_cam_rect.y, w, h)) + # ----------------------------------------------------------------------------- -def check_collision(hero_pos_x, hero_pos_y, step_x, step_y, \ +def check_collision(hero_pos_x, hero_pos_y, hero_width, hero_height, metadata_layer, tile_properties): + tile_width = metadata_layer.tilewidth + tile_height = metadata_layer.tileheight + + half_hero_width = hero_width // 2 + half_hero_height = hero_height // 2 + + tile_x_left = int((hero_pos_x - half_hero_width) // tile_width) + tile_x_right = int((hero_pos_x + half_hero_width) // tile_width + 1) + tile_y_up = int((hero_pos_y - hero_height) // tile_height) + tile_y_down = int((hero_pos_y) // tile_height + 1) + + for y in range(tile_y_up, tile_y_down): + for x in range(tile_x_left, tile_x_right): + gid = metadata_layer.content2D[x][y] + if gid in tile_properties: + return True + + return False + +def check_movement(hero_pos_x, hero_pos_y, step_x, step_y, \ hero_width, hero_height, metadata_layer, tile_properties): """ Checks collision of the hero against the world. Its not the best way to @@ -219,39 +255,45 @@ def check_collision(hero_pos_x, hero_pos_y, step_x, step_y, \ half_hero_width = hero_width // 2 half_hero_height = hero_height // 2 + tile_x_left = int((hero_pos_x - half_hero_width) // tile_width) + tile_x_right = int((hero_pos_x + half_hero_width) // tile_width + 1) + tile_y_up = int((hero_pos_y - hero_height) // tile_height) + tile_y_down = int((hero_pos_y) // tile_height + 1) + if step_x < 0: - sx = int((hero_pos_x - half_hero_width) // tile_width) - ex = int((hero_pos_x - half_hero_width - step_x) // tile_width) + sx = tile_x_left + ex = int((hero_pos_x - half_hero_width + step_x) // tile_width) elif step_x > 0: - sx = int((hero_pos_x + half_hero_width) // tile_width) + sx = tile_x_right ex = int((hero_pos_x + half_hero_width + step_x) // tile_width) else: sx = int((hero_pos_x) // tile_width) ex = sx if step_y < 0: - sy = int((hero_pos_y - hero_height) // tile_height) - ey = int((hero_pos_y - hero_height - step_y) // tile_height) + sy = tile_y_up + ey = int((hero_pos_y - hero_height + step_y) // tile_height) elif step_y > 0: - sy = int((hero_pos_y) // tile_height) + sy = tile_y_down ey = int((hero_pos_y + step_y) // tile_height) else: - sy = int((hero_pos_y) // tile_height) + sy = int((hero_pos_y - half_hero_height) // tile_height) ey = sy - gid = metadata_layer.content2D[sx][sy] - if gid in tile_properties: - return 0,0 + for y in range(tile_y_up, tile_y_down): + gid = metadata_layer.content2D[ex][y] + if gid in tile_properties: + step_x = 0 + ex = sx - gid = metadata_layer.content2D[ex][sy] - if gid in tile_properties: - step_x = 0 - ex = sx + xl = int((hero_pos_x - half_hero_width + step_x) // tile_width) + xr = int((hero_pos_x + half_hero_width + step_x) // tile_width + 1) - gid = metadata_layer.content2D[ex][ey] - if gid in tile_properties: - step_y = 0 - ey = sy + for x in range(xl, xr): + gid = metadata_layer.content2D[x][ey] + if gid in tile_properties: + step_y = 0 + ey = sy # return the step the hero should do return step_x, step_y -- 2.11.4.GIT