完成机器人碰撞检测

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 "movement.h"
#include "room.h"
#include "metamgr.h"
void AndroidAI::Update(int delta_time)
{
@ -11,9 +12,7 @@ void AndroidAI::Update(int delta_time)
switch (state) {
case AS_thinking:
{
if (state_elapsed_time < 1000) {
DoThink();
} else {
if (state_elapsed_time > 1500 + rand() % 3000) {
int rnd = rand();
if (rnd % 100 < 30) {
ChangeToState(AS_moving);
@ -25,7 +24,7 @@ void AndroidAI::Update(int delta_time)
break;
case AS_moving:
{
if (state_elapsed_time < 1000) {
if (state_elapsed_time < 1000 + rand() % 2000) {
DoMove();
} else {
int rnd = rand();
@ -51,20 +50,6 @@ void AndroidAI::Update(int delta_time)
}
}
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_elapsed_time = 0;
}
void AndroidAI::DoThink()
switch (state) {
case AS_moving:
{
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()
{
#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->Arrived()) {
float distance = 8.0f + rand() % 10;
@ -94,6 +102,7 @@ void AndroidAI::DoMove()
}
}
}
#endif
}
void AndroidAI::DoAttack()
@ -109,25 +118,104 @@ void AndroidAI::DoAttack()
}
}
void AndroidAI::DoMoveAndAttack()
bool AndroidAI::IsCollision()
{
if (owner->movement) {
if (owner->movement->Arrived()) {
float distance = 8.0f + rand() % 10;
Vector2D out_pos;
if (owner->room->RandomPos((Human*)owner, distance, out_pos)) {
owner->movement->ClearPath();
owner->movement->AddPathPoint(out_pos, distance, owner->GetSpeed());
//检查x轴
if (owner->pos.x < 0.001f || owner->pos.x > owner->room->map_meta->i->width()) {
return false;
}
//检查y轴
if (owner->pos.y < 0.001f || owner->pos.x > owner->room->map_meta->i->height()) {
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;
}
}
if (owner->updated_times % 2 == 0) {
Human* enemy = owner->room->FindEnemy((Human*)owner);
if (enemy) {
Human* sender = (Human*)owner;
Vector2D shot_dir = enemy->pos;
shot_dir.Normalize();
sender->Shot(shot_dir);
} else if (dot > 0.001f) { //基本相同
//向右
owner->pos = owner->pos + Vector2D::RIGHT;
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::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_moving,
AS_attack,
AS_moving_and_attack,
AS_attack
};
class Human;
@ -24,9 +23,9 @@ private:
void ChangeToState(AndroidState_e to_state);
void DoThink();
void DoMove();
void DoAttack();
void DoMoveAndAttack();
bool IsCollision();
void FindPath();
};

View File

@ -5,6 +5,11 @@
#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)
{
pb_obj->set_x(x);
@ -20,30 +25,30 @@ Vector2D& Vector2D::Normalize()
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;
}
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);
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);
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;
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);
return Vector2D(v[0], v[1]);
@ -61,7 +66,7 @@ Vector2D Vector2D::Perp()
return Vector2D(y, -x);
}
float Vector2D::Dot(const Vector2D& v)
float Vector2D::Dot(const Vector2D& v) const
{
return x*v.x + y*v.y;
}

View File

@ -24,14 +24,18 @@ struct Vector2D
void ToPB(cs::MFVector2D* pb_obj);
Vector2D& Normalize();
bool operator == (const Vector2D& b);
Vector2D operator + (const Vector2D& b);
Vector2D operator - (const Vector2D& b);
Vector2D operator * (float scale);
Vector2D operator / (float scale);
bool operator == (const Vector2D& b) const;
Vector2D operator + (const Vector2D& b) const;
Vector2D operator - (const Vector2D& b) const;
Vector2D operator * (float scale) const;
Vector2D operator / (float scale) const;
Vector2D Rotate(float angle);
Vector2D Perp();
float Dot(const Vector2D& v);
float Dot(const Vector2D& v) const;
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
{
_CMPing = 101;
// _CMLogin = 103;
_CMJoin = 103;
_CMMove = 201;
@ -18,10 +17,8 @@ enum SMMessageId_e
{
_SMPing = 101;
_SMRpcError = 102;
// _SMLogin = 103;
_SMJoinedNotify = 103;
_SMMapInfo = 1002;
_SMPlayerInfo = 1003;
_SMUpdate = 1004;

View File

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