完成机器人碰撞检测

This commit is contained in:
aozhiwei 2019-03-21 11:55:53 +08:00
parent a36c071f88
commit 122c6286a0
6 changed files with 152 additions and 59 deletions

View File

@ -4,6 +4,7 @@
#include "android.h" #include "android.h"
#include "movement.h" #include "movement.h"
#include "room.h" #include "room.h"
#include "metamgr.h"
void AndroidAI::Update(int delta_time) void AndroidAI::Update(int delta_time)
{ {
@ -11,9 +12,7 @@ void AndroidAI::Update(int delta_time)
switch (state) { switch (state) {
case AS_thinking: case AS_thinking:
{ {
if (state_elapsed_time < 1000) { if (state_elapsed_time > 1500 + rand() % 3000) {
DoThink();
} else {
int rnd = rand(); int rnd = rand();
if (rnd % 100 < 30) { if (rnd % 100 < 30) {
ChangeToState(AS_moving); ChangeToState(AS_moving);
@ -25,7 +24,7 @@ void AndroidAI::Update(int delta_time)
break; break;
case AS_moving: case AS_moving:
{ {
if (state_elapsed_time < 1000) { if (state_elapsed_time < 1000 + rand() % 2000) {
DoMove(); DoMove();
} else { } else {
int rnd = rand(); int rnd = rand();
@ -51,20 +50,6 @@ void AndroidAI::Update(int delta_time)
} }
} }
break; break;
case AS_moving_and_attack:
{
if (state_elapsed_time < 1000) {
DoMoveAndAttack();
} else {
int rnd = rand();
if (rnd % 100 < 30) {
ChangeToState(AS_moving);
} else if (rnd % 100 < 50) {
ChangeToState(AS_attack);
}
}
}
break;
} }
} }
@ -72,15 +57,38 @@ void AndroidAI::ChangeToState(AndroidState_e to_state)
{ {
state = to_state; state = to_state;
state_elapsed_time = 0; state_elapsed_time = 0;
} switch (state) {
case AS_moving:
void AndroidAI::DoThink() {
{ Human* hum = (Human*)owner;
float angle = ((float)rand() / RAND_MAX) * 2.0f;
hum->move_dir = Vector2D(1.0f, 0);
hum->move_dir.Rotate(angle);
hum->move_dir.Normalize();
}
break;
default:
break;
}
} }
void AndroidAI::DoMove() void AndroidAI::DoMove()
{ {
#if 1
Human* hum = (Human*)owner;
int speed = std::max(1, (int)hum->GetSpeed());
for (int i = 0; i < speed; ++i) {
Vector2D old_pos = owner->pos;
owner->pos = owner->pos + hum->move_dir * (i + 1);
if (IsCollision()) {
owner->pos = old_pos;
if (i == 0) {
FindPath();
break;
}
}
}
#else
if (owner->movement) { if (owner->movement) {
if (owner->movement->Arrived()) { if (owner->movement->Arrived()) {
float distance = 8.0f + rand() % 10; float distance = 8.0f + rand() % 10;
@ -94,6 +102,7 @@ void AndroidAI::DoMove()
} }
} }
} }
#endif
} }
void AndroidAI::DoAttack() void AndroidAI::DoAttack()
@ -109,25 +118,104 @@ void AndroidAI::DoAttack()
} }
} }
void AndroidAI::DoMoveAndAttack() bool AndroidAI::IsCollision()
{ {
if (owner->movement) { //检查x轴
if (owner->movement->Arrived()) { if (owner->pos.x < 0.001f || owner->pos.x > owner->room->map_meta->i->width()) {
float distance = 8.0f + rand() % 10; return false;
Vector2D out_pos; }
if (owner->room->RandomPos((Human*)owner, distance, out_pos)) { //检查y轴
owner->movement->ClearPath(); if (owner->pos.y < 0.001f || owner->pos.x > owner->room->map_meta->i->height()) {
owner->movement->AddPathPoint(out_pos, distance, owner->GetSpeed()); return false;
}
int detection_flags = 0;
a8::SetBitFlag(detection_flags, ET_Obstacle);
a8::SetBitFlag(detection_flags, ET_Building);
std::vector<Entity*> objects;
owner->room->CollisionDetection(this->owner, detection_flags, objects);
return !objects.empty();
}
void AndroidAI::FindPath()
{
Human* hum = (Human*)owner;
Vector2D old_pos = owner->pos;
{
float dot = Vector2D::UP.Dot(hum->move_dir);
if (std::abs(dot) <= 0.001f) { //相互垂直
//向上
owner->pos = owner->pos + Vector2D::UP;
if (IsCollision()) {
//向下
owner->pos = old_pos;
owner->pos = owner->pos + Vector2D::DOWN;
if (IsCollision()) {
return;
}
} }
} } else if (dot > 0.001f) { //基本相同
if (owner->updated_times % 2 == 0) { //向右
Human* enemy = owner->room->FindEnemy((Human*)owner); owner->pos = owner->pos + Vector2D::RIGHT;
if (enemy) { if (IsCollision()) {
Human* sender = (Human*)owner; //向上
Vector2D shot_dir = enemy->pos; owner->pos = old_pos;
shot_dir.Normalize(); owner->pos = owner->pos + Vector2D::UP;
sender->Shot(shot_dir); if (IsCollision()) {
return;
}
}
} else if (dot < 0.001f) { //基本相反
//向右
owner->pos = owner->pos + Vector2D::RIGHT;
if (IsCollision()) {
//向下
owner->pos = old_pos;
owner->pos = owner->pos + Vector2D::DOWN;
if (IsCollision()) {
return;
}
} }
} }
} }
{
float dot = Vector2D::DOWN.Dot(hum->move_dir);
if (std::abs(dot) <= 0.001f) { //相互垂直
//向下
owner->pos = owner->pos + Vector2D::DOWN;
if (IsCollision()) {
//向上
owner->pos = old_pos;
owner->pos = owner->pos + Vector2D::UP;
if (IsCollision()) {
return;
}
}
} else if (dot > 0.001f) { //基本相同
//向左
owner->pos = owner->pos + Vector2D::LEFT;
if (IsCollision()) {
//向下
owner->pos = old_pos;
owner->pos = owner->pos + Vector2D::DOWN;
if (IsCollision()) {
return;
}
}
} else if (dot < 0.001f) { //基本相反
//向左
owner->pos = owner->pos + Vector2D::LEFT;
if (IsCollision()) {
//向上
owner->pos = old_pos;
owner->pos = owner->pos + Vector2D::UP;
if (IsCollision()) {
return;
}
}
}
}
} }

View File

@ -6,8 +6,7 @@ enum AndroidState_e
{ {
AS_thinking, AS_thinking,
AS_moving, AS_moving,
AS_attack, AS_attack
AS_moving_and_attack,
}; };
class Human; class Human;
@ -24,9 +23,9 @@ private:
void ChangeToState(AndroidState_e to_state); void ChangeToState(AndroidState_e to_state);
void DoThink();
void DoMove(); void DoMove();
void DoAttack(); void DoAttack();
void DoMoveAndAttack();
bool IsCollision();
void FindPath();
}; };

View File

@ -5,6 +5,11 @@
#include "cs_proto.pb.h" #include "cs_proto.pb.h"
const Vector2D Vector2D::UP = Vector2D(0.0f, 1.0f);
const Vector2D Vector2D::RIGHT = Vector2D(1.0f, 0.0f);
const Vector2D Vector2D::DOWN = Vector2D(0.0f, -1.0f);
const Vector2D Vector2D::LEFT = Vector2D(-1.0f, 0.0f);
void Vector2D::ToPB(cs::MFVector2D* pb_obj) void Vector2D::ToPB(cs::MFVector2D* pb_obj)
{ {
pb_obj->set_x(x); pb_obj->set_x(x);
@ -20,30 +25,30 @@ Vector2D& Vector2D::Normalize()
return *this; return *this;
} }
bool Vector2D::operator == (const Vector2D& b) bool Vector2D::operator == (const Vector2D& b) const
{ {
return std::abs(x - b.x) < 0.01f && std::abs(y - b.y) < 0.01f; return std::abs(x - b.x) < 0.01f && std::abs(y - b.y) < 0.01f;
} }
Vector2D Vector2D::operator + (const Vector2D& b) Vector2D Vector2D::operator + (const Vector2D& b) const
{ {
Eigen::Vector2f v = Eigen::Vector2f(x, y) + Eigen::Vector2f(b.x, b.y); Eigen::Vector2f v = Eigen::Vector2f(x, y) + Eigen::Vector2f(b.x, b.y);
return Vector2D(v[0], v[1]); return Vector2D(v[0], v[1]);
} }
Vector2D Vector2D::operator - (const Vector2D& b) Vector2D Vector2D::operator - (const Vector2D& b) const
{ {
Eigen::Vector2f v = Eigen::Vector2f(x, y) - Eigen::Vector2f(b.x, b.y); Eigen::Vector2f v = Eigen::Vector2f(x, y) - Eigen::Vector2f(b.x, b.y);
return Vector2D(v[0], v[1]); return Vector2D(v[0], v[1]);
} }
Vector2D Vector2D::operator * (float scale) Vector2D Vector2D::operator * (float scale) const
{ {
Eigen::Vector2f v = Eigen::Vector2f(x, y) * scale; Eigen::Vector2f v = Eigen::Vector2f(x, y) * scale;
return Vector2D(v[0], v[1]); return Vector2D(v[0], v[1]);
} }
Vector2D Vector2D::operator / (float scale) Vector2D Vector2D::operator / (float scale) const
{ {
Eigen::Vector2f v = Eigen::Vector2f(x, y) * (1.0 / scale); Eigen::Vector2f v = Eigen::Vector2f(x, y) * (1.0 / scale);
return Vector2D(v[0], v[1]); return Vector2D(v[0], v[1]);
@ -61,7 +66,7 @@ Vector2D Vector2D::Perp()
return Vector2D(y, -x); return Vector2D(y, -x);
} }
float Vector2D::Dot(const Vector2D& v) float Vector2D::Dot(const Vector2D& v) const
{ {
return x*v.x + y*v.y; return x*v.x + y*v.y;
} }

View File

@ -24,14 +24,18 @@ struct Vector2D
void ToPB(cs::MFVector2D* pb_obj); void ToPB(cs::MFVector2D* pb_obj);
Vector2D& Normalize(); Vector2D& Normalize();
bool operator == (const Vector2D& b); bool operator == (const Vector2D& b) const;
Vector2D operator + (const Vector2D& b); Vector2D operator + (const Vector2D& b) const;
Vector2D operator - (const Vector2D& b); Vector2D operator - (const Vector2D& b) const;
Vector2D operator * (float scale); Vector2D operator * (float scale) const;
Vector2D operator / (float scale); Vector2D operator / (float scale) const;
Vector2D Rotate(float angle); Vector2D Rotate(float angle);
Vector2D Perp(); Vector2D Perp();
float Dot(const Vector2D& v); float Dot(const Vector2D& v) const;
float Norm(); float Norm();
static const Vector2D UP;
static const Vector2D DOWN;
static const Vector2D LEFT;
static const Vector2D RIGHT;
}; };

View File

@ -4,7 +4,6 @@ package cs;
enum CMMessageId_e enum CMMessageId_e
{ {
_CMPing = 101; _CMPing = 101;
// _CMLogin = 103;
_CMJoin = 103; _CMJoin = 103;
_CMMove = 201; _CMMove = 201;
@ -18,10 +17,8 @@ enum SMMessageId_e
{ {
_SMPing = 101; _SMPing = 101;
_SMRpcError = 102; _SMRpcError = 102;
// _SMLogin = 103;
_SMJoinedNotify = 103; _SMJoinedNotify = 103;
_SMMapInfo = 1002; _SMMapInfo = 1002;
_SMPlayerInfo = 1003; _SMPlayerInfo = 1003;
_SMUpdate = 1004; _SMUpdate = 1004;

View File

@ -574,7 +574,7 @@ message SMUpdate
optional int32 gasT = 16; optional int32 gasT = 16;
optional MFGasData gas_data = 17; optional MFGasData gas_data = 17;
repeated MFTeamData team_data = 18; repeated MFTeamData team_data = 18;
repeated MFTeamData teams = 19; repeated MFTeamInfo teams = 19;
repeated MFBullet bullets = 20; // repeated MFBullet bullets = 20; //
repeated MFShot shots = 21; // repeated MFShot shots = 21; //
repeated MFExplosion explosions = 22; // repeated MFExplosion explosions = 22; //