コード例 #1
0
ファイル: Octree.cpp プロジェクト: inyeolsohnn/ConsoleApp4
void Octree::split()
{
	float subX = bounds.cent.x;
	float subY = bounds.cent.y;
	float subZ = bounds.cent.z;

	Moo::Vector3D halfD = bounds.cent - bounds.min;
	int nextLevel = level + 1;
	//lower layer cells(0-3)
	Moo::BoundingBox box0(bounds.min, bounds.cent);
	std::shared_ptr<Octree> oct0 = std::make_shared<Octree>(nextLevel, box0, &*this, this->cr);

	Moo::Vector3D box1Min(bounds.min.x, bounds.min.y, bounds.cent.z);
	Moo::Vector3D box1Max = box1Min + halfD;
	Moo::BoundingBox box1(box1Min, box1Max);
	std::shared_ptr<Octree> oct1 = std::make_shared<Octree>(nextLevel, box1, &*this, this->cr);

	Moo::Vector3D box2Min(bounds.cent.x, bounds.min.y, bounds.cent.z);
	Moo::Vector3D box2Max = box2Min + halfD;
	Moo::BoundingBox box2(box2Min, box2Max);
	std::shared_ptr<Octree> oct2 = std::make_shared<Octree>(nextLevel, box2, &*this, this->cr);

	Moo::Vector3D box3Min(bounds.cent.x, bounds.min.y, bounds.min.z);
	Moo::Vector3D box3Max = box3Min + halfD;
	Moo::BoundingBox box3(box3Min, box3Max);
	std::shared_ptr<Octree> oct3 = std::make_shared<Octree>(nextLevel, box3, &*this, this->cr);

	//upper layer cells(4-7)
	Moo::Vector3D box4Min(bounds.min.x, bounds.cent.y, bounds.min.z);
	Moo::Vector3D box4Max = box4Min + halfD;
	Moo::BoundingBox box4(box4Min, box4Max);
	std::shared_ptr<Octree> oct4 = std::make_shared<Octree>(nextLevel, box4, &*this, this->cr);

	Moo::Vector3D box5Min(bounds.min.x, bounds.cent.y, bounds.cent.z);
	Moo::Vector3D box5Max = box5Min + halfD;
	Moo::BoundingBox box5(box5Min, box5Max);
	std::shared_ptr<Octree> oct5 = std::make_shared<Octree>(nextLevel, box5, &*this, this->cr);

	Moo::Vector3D box6Min = bounds.cent;
	Moo::Vector3D box6Max = bounds.max;
	Moo::BoundingBox box6(box6Min, box6Max);
	std::shared_ptr<Octree> oct6 = std::make_shared<Octree>(nextLevel, box6, &*this, this->cr);

	Moo::Vector3D box7Min(bounds.cent.x, bounds.cent.y, bounds.min.z);
	Moo::Vector3D box7Max = box7Min + bounds.cent;
	Moo::BoundingBox box7(box7Min, box7Max);
	std::shared_ptr<Octree> oct7 = std::make_shared<Octree>(nextLevel, box7, &*this, this->cr);

	childNode[0] = oct0;
	childNode[1] = oct1;
	childNode[2] = oct2;
	childNode[3] = oct3;
	childNode[4] = oct4;
	childNode[5] = oct5;
	childNode[6] = oct6;
	childNode[7] = oct7;
	
}
コード例 #2
0
ファイル: GameServer.cpp プロジェクト: dahin/fefu-mmorpg
//==============================================================================
bool GameServer::IsPositionWrong(float x, float y, Actor* actor)
{
  if (levelMap_.GetCell(x, y) != '.')
  {
    return true;
  }

  if (levelMap_.GetCell(x + 0.4f, y) != '.'
      || levelMap_.GetCell(x - 0.4f, y) != '.'
      || levelMap_.GetCell(x, y - 0.4f) != '.'
      || levelMap_.GetCell(x, y + 0.4f) != '.')
  {
    return true;
  }

  for (auto p : actors_)
  {
    if (p == actor
        || p->GetType() == EActorType::ITEM)
    {
      continue;
    }

    if (p->GetPosition().x >= 0
        && p->GetPosition().y >= 0)
    {
      Box box0(actor->GetPosition(), actor->GetSize(), actor->GetSize());
      Box box1(p->GetPosition(), p->GetSize(), p->GetSize());

      if (box0.Intersect(box1))
      {
        return true;
      }
    }
  }
  return false;
}
コード例 #3
0
ファイル: GameServer.cpp プロジェクト: dahin/fefu-mmorpg
//==============================================================================
void GameServer::tick()
{
  /*float dt = (time_.elapsed() - lastTime_) * 0.001f;*/
  lastTime_ = time_.elapsed();

  /*if (actors_.size() < 100 && !testingStageActive_)
  {
    GenMonsters_();
  }*/

  auto collideWithGrid = [=](Actor* actor, EActorDirection direction)
  {
    auto& p = *actor;

    float x = p.GetPosition().x;
    float y = p.GetPosition().y;

    bool collided = false;

    if ((levelMap_.GetCell(x + 0.49f, y - 0.51f) != '.'
        || levelMap_.GetCell(x + 0.49f, y + 0.49f) != '.')
        && levelMap_.GetCell(x - slideThreshold_+ 0.5f, y) == '.'
        && (direction == EActorDirection::NORTH
        || direction == EActorDirection::SOUTH))
    {
      p.SetPosition(Vector2(x - slideThreshold_+ 0.0001f, p.GetPosition().y));
    }

    if (levelMap_.GetCell(x + slideThreshold_- 0.5f, y) == '.'
        &&((levelMap_.GetCell(x - 0.5f, y - 0.51f) != '.'
        || levelMap_.GetCell(x - 0.5f, y + 0.49f) != '.')
        && (direction == EActorDirection::NORTH
        || direction == EActorDirection::SOUTH)))
    {
      p.SetPosition(Vector2(x + slideThreshold_- 0.0001f, p.GetPosition().y));
    }

    if (levelMap_.GetCell(x, y - slideThreshold_ + 0.5f) == '.'
        && (levelMap_.GetCell(x - 0.51f, y + 0.49f) != '.'
        || levelMap_.GetCell(x + 0.49f, y + 0.49f) != '.')
        && (direction == EActorDirection::EAST
        || direction == EActorDirection::WEST))
    {
      p.SetPosition(Vector2(p.GetPosition().x, y - slideThreshold_+ 0.0001f));
    }

    if ((levelMap_.GetCell(x + 0.49f, y - 0.5f) != '.'
        || levelMap_.GetCell(x - 0.51f, y - 0.5f) != '.')
        && levelMap_.GetCell(x, y + slideThreshold_- 0.5f) == '.'
        && (direction == EActorDirection::EAST
        || direction == EActorDirection::WEST))
    {
      p.SetPosition(Vector2(p.GetPosition().x, y + slideThreshold_ - 0.001f));
    }

    if (levelMap_.GetCell(x + 0.5f, y) != '.')
    {
      p.SetPosition(Vector2(round(x + 0.5f) - 0.5f, p.GetPosition().y));
      collided = true;
    }

    if (levelMap_.GetCell(x - 0.51f, y) != '.')
    {
      p.SetPosition(Vector2(round(x - 0.5f) + 0.5f, p.GetPosition().y));
      collided = true;
    }

    if (levelMap_.GetCell(x, y + 0.5f) != '.')
    {
      p.SetPosition(Vector2(p.GetPosition().x, round(y + 0.5f) - 0.5f));
      collided = true;
    }

    if (levelMap_.GetCell(x, y - 0.51f) != '.')
    {
      p.SetPosition(Vector2(p.GetPosition().x, round(y - 0.5f) + 0.5f));
      collided = true;
    }

    if (collided)
    {
      actor->OnCollideWorld();
    }
  };

  for (Actor* actor: actors_)
  {
    if (actor->GetType() == EActorType::MONSTER)
    {
      Monster* monster = dynamic_cast<Monster*>(actor);
      Creature* target = monster->target;
      float distance2;
      Vector2 m_pos = actor->GetPosition();
      if (target && target != nullptr)
      {
        Vector2 t_pos = target->GetPosition();
        distance2 = Sqr(m_pos.x - t_pos.x)
                    + Sqr(m_pos.y - t_pos.y);
        if (distance2 < 25)
        {
          if (abs(m_pos.x - t_pos.x - 1.0f) < playerVelocity_
              && m_pos.x - t_pos.x - 1.0f != 0)
          {
            monster->SetPosition(Vector2(t_pos.x + 1.0f, m_pos.y));
            monster->SetDirection(EActorDirection::NONE);
          }

          if (abs(m_pos.y - t_pos.y + 1.0f) < playerVelocity_
              && m_pos.y - t_pos.y + 1.0f != 0)
          {
            monster->SetPosition(Vector2(m_pos.x, t_pos.y - 1.0f));
            monster->SetDirection(EActorDirection::NONE);
          }

          if (m_pos.x < t_pos.x - 1.0f)
          {
            monster->SetDirection(EActorDirection::EAST);
          }
          else if (m_pos.x > t_pos.x + 1.0f)
          {
            monster->SetDirection(EActorDirection::WEST);
          }
          else if (m_pos.y < t_pos.y - 1.0f)
          {
            monster->SetDirection(EActorDirection::SOUTH);
          }
          else if (m_pos.y > t_pos.y + 1.0f)
          {
            monster->SetDirection(EActorDirection::NORTH);
          }
        }
      }

      if (!target
          || target == nullptr
          || distance2 >= 5)
      {
        for (Actor* tar : actors_)
        {
          if (tar != monster)
          {
            bool b = false;
            if (tar->GetType() != EActorType::ITEM
                && tar->GetType () != EActorType::PROJECTILE)
            {
              Creature* m = dynamic_cast<Creature*>(tar);

              QStringList str = monster->Flags.filter("HATE");
              for (QString hate: str)
              {
                if (Hates[hate] == m->GetRace())
                {
                  b = true;
                  break;
                }
              }

              if (b)
              {
                Vector2 t_pos = tar->GetPosition();
                distance2 = Sqr(m_pos.x - t_pos.x) + Sqr(m_pos.y - t_pos.y);
                // Dasha told 5^2 is a protocol defined const
                if (distance2 < 25)
                {
                  monster->target = m;
                  break;
                }
              }
            }
          }
        }
      }
    }

    if (actor->GetType() == EActorType::MONSTER
        || actor->GetType() == EActorType::PLAYER)
    {
      Creature* monster = dynamic_cast<Creature*>(actor);
      if (monster->GetHealth() <= 0)
      {
        KillActor_(actor);
        break;
      }
    }
  }

  for (Actor* actor: actors_)
  {
    if (!actor
        || actor == nullptr)
    {
      break;
    }

    auto v = directionToVector[static_cast<unsigned>(actor->GetDirection())] ;
    actor->SetVelocity(v);
    float dt = playerVelocity_;
    Vector2 old_pos = actor->GetPosition();
    Vector2 new_pos = old_pos + v * (dt + 0.001);
    Vector2 old_pos2 = old_pos + v * 0.51;
    levelMap_.RemoveActor(actor);
    EActorDirection d = actor->GetDirection();
    float x = new_pos.x;
    float y = new_pos.y;
    if (levelMap_.GetCell(old_pos2.x, old_pos2.y) != '#'
        && d != EActorDirection::NONE
        && (((levelMap_.GetCell(x - slideThreshold_+ 0.5f, y) == '.'
              && levelMap_.GetCell(x + slideThreshold_- 0.5f, y) == '.')
             && (d == EActorDirection::NORTH
                 || d == EActorDirection::SOUTH))
            || ((levelMap_.GetCell(x, y - slideThreshold_+ 0.5f) == '.'
                 && levelMap_.GetCell(x, y + slideThreshold_- 0.5f) == '.')
                && (d == EActorDirection::EAST
                    || d == EActorDirection::WEST))))
    {
      if (levelMap_.GetCell(new_pos.x, new_pos.y) == '.')
      {
        if (!actor->Update(dt)
            && actor->GetType () == EActorType::PROJECTILE)
        {
          static_cast<Projectile*>(actor)->death = true;
        }
        collideWithGrid(actor, d);
      }
      else if (levelMap_.GetCell(x , y) != '.'
               && playerVelocity_ >= 1)
      {
        bool b = false;
        for (float i = 0.01; i <= dt; i += 0.01)
        {
          new_pos = old_pos + v * i + v * 0.5f;
          if (levelMap_.GetCell(new_pos.x, new_pos.y) == '#' && !b)
          {
            actor->Update(i - 0.01);
            b = true;
          }
        }
      }
      else
      {
        if (actor->GetType () == EActorType::PROJECTILE)
        {
          static_cast<Projectile*>(actor)->death = true;
        }
      }
    }
    else
    {
      if (actor
          && actor != nullptr)
      {
        if (actor->GetType () == EActorType::PROJECTILE)
        {
          static_cast<Projectile*>(actor)->death = true;
        }
        else
        {
          actor->OnCollideWorld();
        }
      }
    }

    if (actor->GetType() == EActorType::PLAYER)
    {
      Player* player = dynamic_cast<Player*>(actor);
      if (player->GetHealth() < player->GetMaxHealth())
      {
        player->SetHealth(player->GetHealth() + 1);
      }
    }

    if (actor->GetType() == EActorType::MONSTER)
    {
      Monster* monster = dynamic_cast<Monster*>(actor);
      Creature* target = monster->target;
      if (target && target->GetHealth() > 0)
      {
        Vector2 m_pos = actor->GetPosition();
        Vector2 t_pos = target->GetPosition();
        float distance2 = Sqr(m_pos.x - t_pos.x)
                          + Sqr(m_pos.y - t_pos.y);

        if (distance2 <= Sqr(pickUpRadius_))
        {
          events_ << monster->atack(target);
          events_ << target->atack(monster);
        }
      }
    }

    for (Actor* neighbour : actors_)
    {
      if (actor == nullptr
          || neighbour == nullptr
          || actor == neighbour
          || neighbour->GetType() == EActorType::ITEM
          || (actor->GetType() == EActorType::PROJECTILE
              && neighbour->GetType() == EActorType::PROJECTILE))
      {
        break;
      }

      Box box0(neighbour->GetPosition(), 0.9f, 0.9f);
      Box box1(actor->GetPosition(), 0.9f, 0.9f);

      if (box0.Intersect(box1))
      {
        actor->OnCollideActor(neighbour);
        neighbour->OnCollideActor(actor);
        if (actor->GetType() == EActorType::PROJECTILE)
        {
          static_cast<Projectile*>(actor)->death = true;
          if (neighbour->GetType () == EActorType::MONSTER)
          {
            Monster* monster = dynamic_cast<Monster*>(neighbour);
            if (monster->GetHealth () <= 0)
            {
              GetItems(monster);
            }
          }
        }
        else if (neighbour->GetType() == EActorType::PROJECTILE)
        {
          static_cast<Projectile*>(neighbour)->death = true;

          if (actor->GetType() == EActorType::MONSTER)
          {
            Monster* monster = dynamic_cast<Monster*>(actor);
            if (monster->GetHealth () <= 0)
            {
              GetItems(monster);
            }
          }
        }
        else if (neighbour->GetType() != EActorType::ITEM)
        {
          actor->SetPosition(old_pos);
        }
      }
    }
    if (actor->GetType() == EActorType::PROJECTILE
        && static_cast<Projectile*>(actor)->death)
    {
      QVariantMap ans1;
      ans1["radius"] = 1.0f;
      ans1["x"] = actor->GetPosition ().x;
      ans1["y"] = actor->GetPosition ().y;
      QVariantMap ans;
      ans["explode"] = ans1;
      events_  << ans;
      idToActor_.erase(actor->GetId());
      actors_.erase(std::remove(actors_.begin(), actors_.end(), actor), actors_.end());
      delete actor;
      actor = nullptr;
    }
    else
    {
      levelMap_.IndexActor(actor);
    }
  }

  QVariantMap tickMessage;
  tickMessage["tick"] = tick_;
  tickMessage["events"] = events_;
  events_.clear();
  emit broadcastMessage(QString(QJsonDocument::fromVariant(tickMessage).toJson()));
  tick_++;
}