1
This commit is contained in:
parent
b0013b1852
commit
2decdfd641
@ -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)
|
||||
{
|
||||
|
||||
|
@ -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_;
|
||||
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user