#include "ge_physics.h" #include "ge_collision_box.h" typedef struct { ge_vector2i_t position; ge_vector2i_t size; ge_int_t tile_size; ge_phy_layers_t* layers; // 二维layer数组 } ge_phy_tilemap_t; static inline int check_tilemap_collision(ge_phy_tilemap_t* tilemap, ge_phy_box_t* entity_collision) { Assert(tilemap->tile_size > 0); const int tile_size_int = tilemap->tile_size; // 计算瓦片地图的网格尺寸(列数和行数) const int grid_cols = tilemap->size.x / tile_size_int; const int grid_rows = tilemap->size.y / tile_size_int; // 计算实体碰撞盒在瓦片地图局部坐标系中的位置 const ge_vector2i_t local_entity_pos = GE_VEC2I_SUB( entity_collision->position, tilemap->position ); // 计算实体边界(使用闭区间) const int entity_left = local_entity_pos.x; const int entity_top = local_entity_pos.y; const int entity_right = entity_left + entity_collision->size.x - 1; // 闭区间右边界 const int entity_bottom = entity_top + entity_collision->size.y - 1; // 闭区间下边界 // 计算覆盖的瓦片范围 const int start_tile_x = GE_MAX(0, entity_left / tile_size_int); const int start_tile_y = GE_MAX(0, entity_top / tile_size_int); const int end_tile_x = GE_MIN(grid_cols - 1, entity_right / tile_size_int); const int end_tile_y = GE_MIN(grid_rows - 1, entity_bottom / tile_size_int); // 遍历实体覆盖的瓦片区域 for (int y = start_tile_y; y <= end_tile_y; y++) { for (int x = start_tile_x; x <= end_tile_x; x++) { // 计算当前瓦片的边界(开区间) const int tile_left = x * tile_size_int; const int tile_top = y * tile_size_int; const int tile_right = tile_left + tile_size_int; // 开区间右边界 const int tile_bottom = tile_top + tile_size_int; // 开区间下边界 // 检查实体是否实际接触到瓦片内部 const int overlap_x = entity_left < tile_right && entity_right > tile_left; const int overlap_y = entity_top < tile_bottom && entity_bottom > tile_top; if (overlap_x && overlap_y && tilemap->layers[y * grid_cols + x] != 0) { return 1; // 检测到碰撞 } } } return 0; // 无碰撞 }