1
This commit is contained in:
parent
7a95ca7c51
commit
07535d954f
@ -26,32 +26,44 @@ void Bullet::Update(int delta_time)
|
||||
{
|
||||
pos = pos + dir * gun_meta->i->bullet_speed() / 20.0f;
|
||||
float distance = (pos - born_pos).Norm();
|
||||
if (meta->i->_inventory_slot() == 5 ||
|
||||
meta->i->_inventory_slot() == 6) {
|
||||
std::vector<Entity*> objects;
|
||||
int detection_flags = 0;
|
||||
{
|
||||
a8::SetBitFlag(detection_flags, ET_Obstacle);
|
||||
a8::SetBitFlag(detection_flags, ET_Building);
|
||||
}
|
||||
room->CollisionDetection(this, detection_flags, objects);
|
||||
if (!objects.empty() || distance >= fly_distance) {
|
||||
room->grid_service.MoveBullet(this);
|
||||
if (room->OverBorder(pos, gun_meta->i->bullet_rad())) {
|
||||
if (IsBomb()){
|
||||
ProcBomb();
|
||||
} else {
|
||||
room->RemoveObjectLater(this);
|
||||
}
|
||||
} else {
|
||||
std::vector<Entity*> objects;
|
||||
int detection_flags = 0;
|
||||
{
|
||||
a8::SetBitFlag(detection_flags, ET_Obstacle);
|
||||
a8::SetBitFlag(detection_flags, ET_Player);
|
||||
}
|
||||
room->CollisionDetection(this, detection_flags, objects);
|
||||
if (!objects.empty() || distance > gun_meta->i->range()) {
|
||||
deleted = true;
|
||||
if (!objects.empty()) {
|
||||
OnHit(objects);
|
||||
std::set<Entity*> objects;
|
||||
for (auto& grid : grid_list) {
|
||||
for (Entity* entity : grid->entity_list) {
|
||||
switch (entity->entity_type) {
|
||||
case ET_Obstacle:
|
||||
case ET_Building:
|
||||
case ET_Player:
|
||||
{
|
||||
if (TestCollision(entity)) {
|
||||
objects.insert(entity);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}//end for
|
||||
if (!objects.empty() || distance > gun_meta->i->range()) {
|
||||
if (IsBomb()) {
|
||||
ProcBomb();
|
||||
} else {
|
||||
deleted = true;
|
||||
if (!objects.empty()) {
|
||||
OnHit(objects);
|
||||
}
|
||||
room->RemoveObjectLater(this);
|
||||
}
|
||||
room->RemoveObjectLater(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,7 +79,7 @@ void Bullet::RecalcSelfCollider()
|
||||
self_collider_->rad = gun_meta->i->bullet_rad();
|
||||
}
|
||||
|
||||
void Bullet::OnHit(std::vector<Entity*>& objects)
|
||||
void Bullet::OnHit(std::set<Entity*>& objects)
|
||||
{
|
||||
for (auto& target : objects) {
|
||||
switch (target->entity_type) {
|
||||
@ -125,3 +137,9 @@ void Bullet::ProcBomb()
|
||||
}
|
||||
room->RemoveObjectLater(this);
|
||||
}
|
||||
|
||||
bool Bullet::IsBomb()
|
||||
{
|
||||
return meta->i->_inventory_slot() == 5 ||
|
||||
meta->i->_inventory_slot() == 6;
|
||||
}
|
||||
|
@ -29,8 +29,9 @@ class Bullet : public Entity
|
||||
|
||||
private:
|
||||
|
||||
void OnHit(std::vector<Entity*>& objects);
|
||||
void OnHit(std::set<Entity*>& objects);
|
||||
void ProcBomb();
|
||||
bool IsBomb();
|
||||
|
||||
private:
|
||||
CircleCollider* self_collider_ = nullptr;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "collider.h"
|
||||
#include "room.h"
|
||||
#include "building.h"
|
||||
#include "human.h"
|
||||
|
||||
Entity::Entity()
|
||||
{
|
||||
@ -71,7 +72,9 @@ void Entity::FindLocationWithTarget(Entity* target)
|
||||
{
|
||||
a8::SetBitFlag(detection_flags, ET_Obstacle);
|
||||
}
|
||||
#if 0
|
||||
room->CollisionDetection(this, detection_flags, objects);
|
||||
#endif
|
||||
if (objects.empty()) {
|
||||
break;
|
||||
}
|
||||
@ -83,18 +86,15 @@ void Entity::FindLocationWithTarget(Entity* target)
|
||||
|
||||
void Entity::BroadcastFullState()
|
||||
{
|
||||
#if 0
|
||||
room->TouchPlayerList(a8::XParams()
|
||||
.SetSender(obstacle),
|
||||
[] (Player* hum, a8::XParams& param)
|
||||
{
|
||||
Obstacle* obstacle = (Obstacle*)param.sender.GetUserData();
|
||||
hum->AddToNewObjects(obstacle);
|
||||
});
|
||||
#endif
|
||||
std::set<GridCell*> grid_list;
|
||||
room->grid_service.Get123456789(grid_id, grid_list);
|
||||
for (auto& grid : grid_list) {
|
||||
for (Human* hum : grid->human_list) {
|
||||
hum->AddToNewObjects(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::BroadcastDeleteState()
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "gridservice.h"
|
||||
#include "human.h"
|
||||
#include "bullet.h"
|
||||
|
||||
GridService::GridService()
|
||||
{
|
||||
@ -139,6 +140,40 @@ void GridService::MoveHuman(Human* hum)
|
||||
}
|
||||
}
|
||||
|
||||
void GridService::AddBullet(Bullet* bullet)
|
||||
{
|
||||
int x = (int)bullet->pos.x + cell_width_;
|
||||
int y = (int)bullet->pos.y + cell_width_;
|
||||
if (BroderOverFlow(x, y)) {
|
||||
abort();
|
||||
}
|
||||
bullet->grid_id = x/cell_width_ + (y/cell_width_) * cell_count_per_row_;
|
||||
if (bullet->grid_id == 0 || bullet->grid_id > max_grid_id_) {
|
||||
abort();
|
||||
}
|
||||
cells_[bullet->grid_id].bullet_list.insert(bullet);
|
||||
Get123456789(bullet->grid_id, bullet->grid_list);
|
||||
}
|
||||
|
||||
void GridService::MoveBullet(Bullet* bullet)
|
||||
{
|
||||
int new_x = (int)bullet->pos.x + cell_width_;
|
||||
int new_y = (int)bullet->pos.y + cell_width_;
|
||||
int new_grid_id = new_x/cell_width_ + (new_y/cell_width_) * cell_count_per_row_;
|
||||
if (new_grid_id != bullet->grid_id) {
|
||||
std::set<GridCell*> inc_grid_list;
|
||||
std::set<GridCell*> dec_grid_list;
|
||||
std::set<GridCell*> old_grid_list = bullet->grid_list;
|
||||
ComputeDiff(bullet->grid_id, new_grid_id,
|
||||
bullet->grid_list,
|
||||
inc_grid_list,
|
||||
dec_grid_list);
|
||||
cells_[bullet->grid_id].bullet_list.erase(bullet);
|
||||
cells_[new_grid_id].bullet_list.insert(bullet);
|
||||
bullet->grid_id = new_grid_id;
|
||||
}
|
||||
}
|
||||
|
||||
void GridService::AddEntity(Entity* entity)
|
||||
{
|
||||
int x = (int)entity->pos.x + cell_width_;
|
||||
|
@ -2,11 +2,13 @@
|
||||
|
||||
class Entity;
|
||||
class Human;
|
||||
class Bullet;
|
||||
|
||||
struct GridCell
|
||||
{
|
||||
std::set<Human*> human_list;
|
||||
std::set<Entity*> entity_list;
|
||||
std::set<Bullet*> bullet_list;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -37,6 +39,9 @@ class GridService
|
||||
void AddHuman(Human* hum);
|
||||
void MoveHuman(Human* hum);
|
||||
|
||||
void AddBullet(Bullet* bullet);
|
||||
void MoveBullet(Bullet* bullet);
|
||||
|
||||
void AddEntity(Entity* entity);
|
||||
|
||||
bool HumanInGridList(Human* hum, std::set<GridCell*>& grid_list);
|
||||
|
@ -246,27 +246,8 @@ void Human::RecalcSelfCollider()
|
||||
|
||||
bool Human::IsCollision()
|
||||
{
|
||||
//检查x轴
|
||||
{
|
||||
int left_x = pos.x - meta->i->radius();
|
||||
if (left_x < 0.001f) {
|
||||
return true;
|
||||
}
|
||||
int right_x = pos.x + meta->i->radius();
|
||||
if (right_x > MAP_WIDTH) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//检查y轴
|
||||
{
|
||||
int up_y = pos.y + meta->i->radius();
|
||||
if (up_y > MAP_HEIGHT) {
|
||||
return true;
|
||||
}
|
||||
int down_y = pos.y - meta->i->radius();
|
||||
if (down_y < 0.001f) {
|
||||
return true;
|
||||
}
|
||||
if (room->OverBorder(pos, meta->i->radius())){
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a8::HasBitFlag(status, HS_Jump)) {
|
||||
@ -305,16 +286,6 @@ bool Human::IsCollision()
|
||||
return !objects.empty();
|
||||
}
|
||||
|
||||
ColliderComponent* Human::GetFirstCollision()
|
||||
{
|
||||
int detection_flags = 0;
|
||||
a8::SetBitFlag(detection_flags, ET_Obstacle);
|
||||
a8::SetBitFlag(detection_flags, ET_Building);
|
||||
std::vector<Entity*> objects;
|
||||
room->CollisionDetection(this, detection_flags, objects);
|
||||
return objects.empty() ? *objects[0]->colliders.begin() : nullptr;
|
||||
}
|
||||
|
||||
void Human::FindPath()
|
||||
{
|
||||
Vector2D old_pos = pos;
|
||||
@ -669,7 +640,9 @@ void Human::FindLocation()
|
||||
a8::SetBitFlag(detection_flags, ET_Obstacle);
|
||||
a8::SetBitFlag(detection_flags, ET_Player);
|
||||
}
|
||||
#if 0
|
||||
room->CollisionDetection(this, detection_flags, objects);
|
||||
#endif
|
||||
if (objects.empty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -98,7 +98,6 @@ class Human : public Entity
|
||||
void Shot(Vector2D& target_dir);
|
||||
void RecalcSelfCollider();
|
||||
bool IsCollision();
|
||||
ColliderComponent* GetFirstCollision();
|
||||
void FindPath();
|
||||
float GetRadius();
|
||||
float GetMaxHP();
|
||||
|
@ -233,54 +233,6 @@ Human* Room::FindEnemy(Human* hum)
|
||||
return !enemys.empty() ? enemys[0] : nullptr;
|
||||
}
|
||||
|
||||
void Room::CollisionDetection(Entity* sender, int detection_flags, std::vector<Entity*>& objects)
|
||||
{
|
||||
assert(uniid_hash_.size() < 2000);
|
||||
for (auto& pair : uniid_hash_) {
|
||||
if (sender == pair.second) {
|
||||
continue;
|
||||
}
|
||||
#if 1
|
||||
if (std::abs(sender->pos.x - pair.second->pos.x) > 1000 ||
|
||||
std::abs(sender->pos.y - pair.second->pos.y) > 1000){
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (a8::HasBitFlag(detection_flags, ET_Player) && pair.second->entity_type == ET_Player) {
|
||||
if (sender->entity_type == ET_Bullet) {
|
||||
Bullet* bullet = (Bullet*)sender;
|
||||
Human* hum = (Human*)pair.second;
|
||||
#if 1
|
||||
if (hum != bullet->player) {
|
||||
#else
|
||||
if (hum != bullet->player &&
|
||||
(hum->team_id == 0 || bullet->player->team_id != hum->team_id)) {
|
||||
#endif
|
||||
if (bullet->TestCollision(hum)) {
|
||||
objects.push_back(hum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (a8::HasBitFlag(detection_flags, ET_Obstacle) && pair.second->entity_type == ET_Obstacle) {
|
||||
if (sender->entity_type == ET_Bullet || sender->entity_type == ET_Player) {
|
||||
if (pair.second != sender &&
|
||||
(sender->last_collision_door == nullptr || sender->last_collision_door != pair.second) &&
|
||||
sender->TestCollision(pair.second)) {
|
||||
objects.push_back(pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (a8::HasBitFlag(detection_flags, ET_Building) && pair.second->entity_type == ET_Building) {
|
||||
if (sender->entity_type == ET_Bullet || sender->entity_type == ET_Player) {
|
||||
if (pair.second != sender && sender->TestCollision(pair.second)) {
|
||||
objects.push_back(pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Room::BuildingBoxBoundCollisionDetection(Entity* sender, std::vector<Entity*>& objects)
|
||||
{
|
||||
ColliderComponent* a_collider = sender->GetBoxBound();
|
||||
@ -486,6 +438,7 @@ void Room::CreateBullet(Human* hum, MetaData::Equip* gun_meta,
|
||||
bullet->entity_uniid = AllocUniid();
|
||||
bullet->Initialize();
|
||||
AddObjectLater(bullet);
|
||||
grid_service.AddBullet(bullet);
|
||||
}
|
||||
|
||||
void Room::RemoveObjectLater(Entity* entity)
|
||||
@ -534,6 +487,33 @@ void Room::OnHumanDie(Human* hum)
|
||||
--alive_count_;
|
||||
}
|
||||
|
||||
bool Room::OverBorder(const Vector2D pos, float radius)
|
||||
{
|
||||
//检查x轴
|
||||
{
|
||||
int left_x = pos.x - radius;
|
||||
if (left_x < 0.001f) {
|
||||
return true;
|
||||
}
|
||||
int right_x = pos.x + radius;
|
||||
if (right_x > MAP_WIDTH) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//检查y轴
|
||||
{
|
||||
int up_y = pos.y + radius;
|
||||
if (up_y > MAP_HEIGHT) {
|
||||
return true;
|
||||
}
|
||||
int down_y = pos.y - radius;
|
||||
if (down_y < 0.001f) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int Room::NewTeam()
|
||||
{
|
||||
++current_teamid;
|
||||
|
@ -57,7 +57,6 @@ public:
|
||||
void AddPlayer(Player* hum);
|
||||
Human* FindEnemy(Human* hum);
|
||||
|
||||
void CollisionDetection(Entity* sender, int detection_flags, std::vector<Entity*>& objects);
|
||||
void BuildingBoxBoundCollisionDetection(Entity* sender, std::vector<Entity*>& objects);
|
||||
void RemoveObjectLater(Entity* entity);
|
||||
|
||||
@ -80,6 +79,7 @@ public:
|
||||
Vector2D pos, Vector2D dir, float fly_distance);
|
||||
|
||||
void OnHumanDie(Human* hum);
|
||||
bool OverBorder(const Vector2D pos, float radius);
|
||||
|
||||
private:
|
||||
unsigned short AllocUniid();
|
||||
|
Loading…
x
Reference in New Issue
Block a user