This commit is contained in:
aozhiwei 2019-06-13 14:32:14 +08:00
parent 2decdfd641
commit 78a30a1f4e
4 changed files with 57 additions and 10 deletions

View File

@ -34,6 +34,7 @@ void Building::RecalcSelfCollider()
collider->_max = Vector2D(obj.x() + obj.width()/2.0 - meta->i->tilewidth()/2.0,
obj.y() + obj.height()/2.0 - meta->i->tileheight()/2.0);
AddCollider(collider);
room->map_service.AddCollider(collider);
}
}

View File

@ -42,9 +42,20 @@ void MapService::Init(int width, int height, int cell_width)
cell_width_ = cell_width;
max_grid_id_ = map_width_ * map_height_;
grid_offset_arr_[0] = - (map_width_ + 1);
grid_offset_arr_[1] = - (map_width_ + 0);
grid_offset_arr_[2] = - (map_width_ + -1);
grid_offset_arr_[3] = - 1;
grid_offset_arr_[4] = 0;
grid_offset_arr_[5] = 1;
grid_offset_arr_[6] = map_width_ - 1;
grid_offset_arr_[7] = map_width_;
grid_offset_arr_[8] = map_width_ + 1;
map_cells_ = (list_head*)malloc(sizeof(list_head) * width * height);
memset(map_cells_, sizeof(list_head) * width * height, 0);
}
void MapService::UnInit()
@ -54,6 +65,9 @@ void MapService::UnInit()
void MapService::AddCollider(ColliderComponent* collider)
{
#if MAP_SERVICE
return;
#endif
CellNode* top_node = nullptr;
CellNode* bot_node = nullptr;
switch (collider->type) {
@ -146,17 +160,30 @@ bool MapService::Walkable(float world_x, float world_y)
list_empty(&node);
}
void MapService::TouchAroundCell(float world_x, float world_y,
std::function<bool (ColliderComponent*)> callback)
void MapService::GetColliders(float world_x, float world_y, std::set<ColliderComponent*>& colliders)
{
int center_grid_id = GetGridId(world_x, world_y);
if (center_grid_id < 0 || center_grid_id >= max_grid_id_) {
return;
}
for (size_t i = 0; i < a8::ArraySize(grid_offset_arr_); ++i) {
int grid_id = center_grid_id + grid_offset_arr_[i];
if (grid_id >= 0 && grid_id < max_grid_id_) {
list_head* head = &map_cells_[grid_id];
if (head->next == nullptr && head->prev == nullptr) {
continue;
}
struct CellNode *node, *tmp;
struct list_head tv_list;
list_for_each_entry_safe(node, tmp, &tv_list, entry) {
colliders.insert(node->collider);
}
}
}
}
int MapService::GetGridId(float world_x, float world_y)
{
int x = world_x + cell_width_;
int y = world_y + cell_width_;
assert(x >= 0 && y >= 0);
int grid_id = x/cell_width_ + (y/cell_width_) * map_width_;
int grid_id = world_x/cell_width_ + (world_y/cell_width_) * map_width_;
return grid_id;
}

View File

@ -21,8 +21,7 @@ class MapService
void AddCollider(ColliderComponent* collider);
void RemoveCollider(ColliderComponent* collider);
bool Walkable(float world_x, float world_y);
void TouchAroundCell(float world_x, float world_y,
std::function<bool (ColliderComponent*)> callback);
void GetColliders(float world_x, float world_y, std::set<ColliderComponent*>& colliders);
private:
int GetGridId(float world_x, float world_y);

View File

@ -34,6 +34,24 @@ void Obstacle::RecalcSelfCollider()
self_collider2_ = new AabbCollider();
self_collider2_->owner = this;
AddCollider(self_collider2_);
Vector2D old_pos = pos;
{
pos = Vector2D(building->pos.x + door_state1->x() - building->meta->i->tilewidth() / 2.0,
building->pos.y + door_state1->y() - building->meta->i->tileheight() / 2.0);
self_collider2_->_min = Vector2D(0.0f - door_state0->width() / 2.0f,
0.0f - door_state0->height() / 2.0f);
self_collider2_->_max = Vector2D(door_state0->width() / 2.0f, door_state0->height() / 2.0f);
room->map_service.AddCollider(self_collider2_);
}
{
pos = Vector2D(building->pos.x + door_state0->x() - building->meta->i->tilewidth() / 2.0,
building->pos.y + door_state0->y() - building->meta->i->tileheight() / 2.0);
self_collider2_->_min = Vector2D(0.0f - door_state1->width() / 2.0f,
0.0f - door_state1->height() / 2.0f);
self_collider2_->_max = Vector2D(door_state1->width() / 2.0f, door_state1->height() / 2.0f);
room->map_service.AddCollider(self_collider2_);
}
pos = old_pos;
}
if (door_state == DoorStateClose) {
self_collider2_->_min = Vector2D(0.0f - door_state0->width() / 2.0f,
@ -55,6 +73,7 @@ void Obstacle::RecalcSelfCollider()
}
self_collider_->pos = Vector2D();
self_collider_->rad = meta->i->height() / 2.0;
room->map_service.AddCollider(self_collider_);
}
break;
case 2:
@ -66,6 +85,7 @@ void Obstacle::RecalcSelfCollider()
}
self_collider2_->_min = Vector2D(meta->i->width() / -2.0f, meta->i->height() / -2.0f);
self_collider2_->_max = Vector2D(meta->i->width() / 2.0f, meta->i->height() / 2.0f);
room->map_service.AddCollider(self_collider2_);
}
break;
}