This commit is contained in:
aozhiwei 2019-06-13 11:44:33 +08:00
parent b0013b1852
commit 2decdfd641
2 changed files with 85 additions and 10 deletions

View File

@ -1,5 +1,6 @@
#include "precompile.h"
#include <math.h>
#include <memory.h>
#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<bool (ColliderComponent*)> callback)
{

View File

@ -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<bool (ColliderComponent*)> 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<ColliderComponent*, CellNode> node_hash_;
std::map<ColliderComponent*, CellNode*> node_hash_;
};