From 2decdfd641ba6ca36b45c70cfbafa95ab2d34f28 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Thu, 13 Jun 2019 11:44:33 +0800 Subject: [PATCH] 1 --- server/gameserver/mapservice.cc | 89 ++++++++++++++++++++++++++++++--- server/gameserver/mapservice.h | 6 +-- 2 files changed, 85 insertions(+), 10 deletions(-) diff --git a/server/gameserver/mapservice.cc b/server/gameserver/mapservice.cc index d2b4ae4..fb41cfc 100644 --- a/server/gameserver/mapservice.cc +++ b/server/gameserver/mapservice.cc @@ -1,5 +1,6 @@ #include "precompile.h" +#include #include #include "mapservice.h" @@ -13,6 +14,18 @@ MapService::MapService() MapService::~MapService() { + for (auto pair : node_hash_) { + CellNode* node = pair.second; + while (node) { + CellNode* pdelnode = node; + node = node->next; + + list_del_init(&pdelnode->entry); + delete pdelnode; + } + } + node_hash_.clear(); + if (map_cells_) { free(map_cells_); map_cells_ = nullptr; @@ -41,24 +54,85 @@ void MapService::UnInit() void MapService::AddCollider(ColliderComponent* collider) { - int grid_id = GetGridId(collider->owner->pos.x, collider->owner->pos.y); + CellNode* top_node = nullptr; + CellNode* bot_node = nullptr; switch (collider->type) { case CT_Aabb: - { - - } - break; case CT_Circle: { + AabbCollider aabb; + if (collider->type == CT_Aabb) { + aabb = *((AabbCollider*)collider); + } else if (collider->type == CT_Circle) { + CircleCollider* circle_box = (CircleCollider*)collider; + aabb.owner = circle_box->owner; + aabb._min.x = circle_box->owner->pos.x - circle_box->rad; + aabb._min.y = circle_box->owner->pos.y - circle_box->rad; + aabb._max.x = circle_box->owner->pos.x + circle_box->rad; + aabb._max.y = circle_box->owner->pos.y + circle_box->rad; + } else { + return; + } + float min_x = (collider->owner->pos + aabb._min).x - 2; + float min_y = (collider->owner->pos + aabb._min).y - 2; + float max_x = (collider->owner->pos + aabb._max).x + 2; + float max_y = (collider->owner->pos + aabb._max).y + 2; + int min_grid_x = ceil(min_x / cell_width_); + int min_grid_y = ceil(min_y / cell_width_); + int max_grid_x = ceil(max_x / cell_width_); + int max_grid_y = ceil(max_y / cell_width_); + if (!(min_grid_x >= 0 && max_grid_x < map_width_)) { + abort(); + } + if (!(min_grid_y >= 0 && max_grid_y < map_height_)) { + abort(); + } + for (int x = min_grid_x; x < max_grid_x; ++x) { + for (int y = min_grid_y; y < max_grid_y; ++y) { + int grid_id = x + y * map_width_; + list_head* head = &map_cells_[grid_id]; + if (head->next == nullptr && head->prev == nullptr) { + INIT_LIST_HEAD(head); + } + CellNode* node = new CellNode(); + node->collider = collider; + list_add_tail(&node->entry, head); + node->next = top_node; + top_node = node; + if (!bot_node) { + bot_node = node; + } + } + } } break; } + if (top_node) { + auto pair = node_hash_.find(collider); + if (pair != node_hash_.end()) { + bot_node->next = pair->second; + pair->second = top_node; + } else { + node_hash_[collider] = top_node; + } + } } void MapService::RemoveCollider(ColliderComponent* collider) { + auto pair = node_hash_.find(collider); + if (pair != node_hash_.end()) { + CellNode* node = pair->second; + while (node) { + CellNode* pdelnode = node; + node = node->next; + list_del_init(&pdelnode->entry); + delete pdelnode; + } + node_hash_.erase(pair); + } } bool MapService::Walkable(float world_x, float world_y) @@ -68,10 +142,11 @@ bool MapService::Walkable(float world_x, float world_y) return false; } list_head& node = map_cells_[grid_id]; - return node.next == nullptr && node.prev == nullptr; + return (node.next == nullptr && node.prev == nullptr) || + list_empty(&node); } -void MapService::TouhcAroundCell(float world_x, float world_y, +void MapService::TouchAroundCell(float world_x, float world_y, std::function callback) { diff --git a/server/gameserver/mapservice.h b/server/gameserver/mapservice.h index 13827d7..8cae1c8 100644 --- a/server/gameserver/mapservice.h +++ b/server/gameserver/mapservice.h @@ -5,7 +5,7 @@ class ColliderComponent; struct CellNode { ColliderComponent* collider; - list_head entity; + list_head entry; CellNode* next = nullptr; }; @@ -21,7 +21,7 @@ class MapService void AddCollider(ColliderComponent* collider); void RemoveCollider(ColliderComponent* collider); bool Walkable(float world_x, float world_y); - void TouhcAroundCell(float world_x, float world_y, + void TouchAroundCell(float world_x, float world_y, std::function callback); private: @@ -34,6 +34,6 @@ class MapService int cell_width_ = 0; int max_grid_id_ = 0; int grid_offset_arr_[9] = {0}; - std::map node_hash_; + std::map node_hash_; };