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;
|
pos = pos + dir * gun_meta->i->bullet_speed() / 20.0f;
|
||||||
float distance = (pos - born_pos).Norm();
|
float distance = (pos - born_pos).Norm();
|
||||||
if (meta->i->_inventory_slot() == 5 ||
|
room->grid_service.MoveBullet(this);
|
||||||
meta->i->_inventory_slot() == 6) {
|
if (room->OverBorder(pos, gun_meta->i->bullet_rad())) {
|
||||||
std::vector<Entity*> objects;
|
if (IsBomb()){
|
||||||
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) {
|
|
||||||
ProcBomb();
|
ProcBomb();
|
||||||
|
} else {
|
||||||
|
room->RemoveObjectLater(this);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::vector<Entity*> objects;
|
std::set<Entity*> objects;
|
||||||
int detection_flags = 0;
|
for (auto& grid : grid_list) {
|
||||||
{
|
for (Entity* entity : grid->entity_list) {
|
||||||
a8::SetBitFlag(detection_flags, ET_Obstacle);
|
switch (entity->entity_type) {
|
||||||
a8::SetBitFlag(detection_flags, ET_Player);
|
case ET_Obstacle:
|
||||||
}
|
case ET_Building:
|
||||||
room->CollisionDetection(this, detection_flags, objects);
|
case ET_Player:
|
||||||
if (!objects.empty() || distance > gun_meta->i->range()) {
|
{
|
||||||
deleted = true;
|
if (TestCollision(entity)) {
|
||||||
if (!objects.empty()) {
|
objects.insert(entity);
|
||||||
OnHit(objects);
|
}
|
||||||
|
}
|
||||||
|
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();
|
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) {
|
for (auto& target : objects) {
|
||||||
switch (target->entity_type) {
|
switch (target->entity_type) {
|
||||||
@ -125,3 +137,9 @@ void Bullet::ProcBomb()
|
|||||||
}
|
}
|
||||||
room->RemoveObjectLater(this);
|
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:
|
private:
|
||||||
|
|
||||||
void OnHit(std::vector<Entity*>& objects);
|
void OnHit(std::set<Entity*>& objects);
|
||||||
void ProcBomb();
|
void ProcBomb();
|
||||||
|
bool IsBomb();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CircleCollider* self_collider_ = nullptr;
|
CircleCollider* self_collider_ = nullptr;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "collider.h"
|
#include "collider.h"
|
||||||
#include "room.h"
|
#include "room.h"
|
||||||
#include "building.h"
|
#include "building.h"
|
||||||
|
#include "human.h"
|
||||||
|
|
||||||
Entity::Entity()
|
Entity::Entity()
|
||||||
{
|
{
|
||||||
@ -71,7 +72,9 @@ void Entity::FindLocationWithTarget(Entity* target)
|
|||||||
{
|
{
|
||||||
a8::SetBitFlag(detection_flags, ET_Obstacle);
|
a8::SetBitFlag(detection_flags, ET_Obstacle);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
room->CollisionDetection(this, detection_flags, objects);
|
room->CollisionDetection(this, detection_flags, objects);
|
||||||
|
#endif
|
||||||
if (objects.empty()) {
|
if (objects.empty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -83,18 +86,15 @@ void Entity::FindLocationWithTarget(Entity* target)
|
|||||||
|
|
||||||
void Entity::BroadcastFullState()
|
void Entity::BroadcastFullState()
|
||||||
{
|
{
|
||||||
#if 0
|
std::set<GridCell*> grid_list;
|
||||||
room->TouchPlayerList(a8::XParams()
|
room->grid_service.Get123456789(grid_id, grid_list);
|
||||||
.SetSender(obstacle),
|
for (auto& grid : grid_list) {
|
||||||
[] (Player* hum, a8::XParams& param)
|
for (Human* hum : grid->human_list) {
|
||||||
{
|
hum->AddToNewObjects(this);
|
||||||
Obstacle* obstacle = (Obstacle*)param.sender.GetUserData();
|
}
|
||||||
hum->AddToNewObjects(obstacle);
|
}
|
||||||
});
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::BroadcastDeleteState()
|
void Entity::BroadcastDeleteState()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "gridservice.h"
|
#include "gridservice.h"
|
||||||
#include "human.h"
|
#include "human.h"
|
||||||
|
#include "bullet.h"
|
||||||
|
|
||||||
GridService::GridService()
|
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)
|
void GridService::AddEntity(Entity* entity)
|
||||||
{
|
{
|
||||||
int x = (int)entity->pos.x + cell_width_;
|
int x = (int)entity->pos.x + cell_width_;
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
class Entity;
|
class Entity;
|
||||||
class Human;
|
class Human;
|
||||||
|
class Bullet;
|
||||||
|
|
||||||
struct GridCell
|
struct GridCell
|
||||||
{
|
{
|
||||||
std::set<Human*> human_list;
|
std::set<Human*> human_list;
|
||||||
std::set<Entity*> entity_list;
|
std::set<Entity*> entity_list;
|
||||||
|
std::set<Bullet*> bullet_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -37,6 +39,9 @@ class GridService
|
|||||||
void AddHuman(Human* hum);
|
void AddHuman(Human* hum);
|
||||||
void MoveHuman(Human* hum);
|
void MoveHuman(Human* hum);
|
||||||
|
|
||||||
|
void AddBullet(Bullet* bullet);
|
||||||
|
void MoveBullet(Bullet* bullet);
|
||||||
|
|
||||||
void AddEntity(Entity* entity);
|
void AddEntity(Entity* entity);
|
||||||
|
|
||||||
bool HumanInGridList(Human* hum, std::set<GridCell*>& grid_list);
|
bool HumanInGridList(Human* hum, std::set<GridCell*>& grid_list);
|
||||||
|
@ -246,27 +246,8 @@ void Human::RecalcSelfCollider()
|
|||||||
|
|
||||||
bool Human::IsCollision()
|
bool Human::IsCollision()
|
||||||
{
|
{
|
||||||
//检查x轴
|
if (room->OverBorder(pos, meta->i->radius())){
|
||||||
{
|
return true;
|
||||||
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 (a8::HasBitFlag(status, HS_Jump)) {
|
if (a8::HasBitFlag(status, HS_Jump)) {
|
||||||
@ -305,16 +286,6 @@ bool Human::IsCollision()
|
|||||||
return !objects.empty();
|
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()
|
void Human::FindPath()
|
||||||
{
|
{
|
||||||
Vector2D old_pos = pos;
|
Vector2D old_pos = pos;
|
||||||
@ -669,7 +640,9 @@ void Human::FindLocation()
|
|||||||
a8::SetBitFlag(detection_flags, ET_Obstacle);
|
a8::SetBitFlag(detection_flags, ET_Obstacle);
|
||||||
a8::SetBitFlag(detection_flags, ET_Player);
|
a8::SetBitFlag(detection_flags, ET_Player);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
room->CollisionDetection(this, detection_flags, objects);
|
room->CollisionDetection(this, detection_flags, objects);
|
||||||
|
#endif
|
||||||
if (objects.empty()) {
|
if (objects.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,6 @@ class Human : public Entity
|
|||||||
void Shot(Vector2D& target_dir);
|
void Shot(Vector2D& target_dir);
|
||||||
void RecalcSelfCollider();
|
void RecalcSelfCollider();
|
||||||
bool IsCollision();
|
bool IsCollision();
|
||||||
ColliderComponent* GetFirstCollision();
|
|
||||||
void FindPath();
|
void FindPath();
|
||||||
float GetRadius();
|
float GetRadius();
|
||||||
float GetMaxHP();
|
float GetMaxHP();
|
||||||
|
@ -233,54 +233,6 @@ Human* Room::FindEnemy(Human* hum)
|
|||||||
return !enemys.empty() ? enemys[0] : nullptr;
|
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)
|
void Room::BuildingBoxBoundCollisionDetection(Entity* sender, std::vector<Entity*>& objects)
|
||||||
{
|
{
|
||||||
ColliderComponent* a_collider = sender->GetBoxBound();
|
ColliderComponent* a_collider = sender->GetBoxBound();
|
||||||
@ -486,6 +438,7 @@ void Room::CreateBullet(Human* hum, MetaData::Equip* gun_meta,
|
|||||||
bullet->entity_uniid = AllocUniid();
|
bullet->entity_uniid = AllocUniid();
|
||||||
bullet->Initialize();
|
bullet->Initialize();
|
||||||
AddObjectLater(bullet);
|
AddObjectLater(bullet);
|
||||||
|
grid_service.AddBullet(bullet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Room::RemoveObjectLater(Entity* entity)
|
void Room::RemoveObjectLater(Entity* entity)
|
||||||
@ -534,6 +487,33 @@ void Room::OnHumanDie(Human* hum)
|
|||||||
--alive_count_;
|
--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()
|
int Room::NewTeam()
|
||||||
{
|
{
|
||||||
++current_teamid;
|
++current_teamid;
|
||||||
|
@ -57,7 +57,6 @@ public:
|
|||||||
void AddPlayer(Player* hum);
|
void AddPlayer(Player* hum);
|
||||||
Human* FindEnemy(Human* 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 BuildingBoxBoundCollisionDetection(Entity* sender, std::vector<Entity*>& objects);
|
||||||
void RemoveObjectLater(Entity* entity);
|
void RemoveObjectLater(Entity* entity);
|
||||||
|
|
||||||
@ -80,6 +79,7 @@ public:
|
|||||||
Vector2D pos, Vector2D dir, float fly_distance);
|
Vector2D pos, Vector2D dir, float fly_distance);
|
||||||
|
|
||||||
void OnHumanDie(Human* hum);
|
void OnHumanDie(Human* hum);
|
||||||
|
bool OverBorder(const Vector2D pos, float radius);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned short AllocUniid();
|
unsigned short AllocUniid();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user