Mover.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright (c) 2008-2022 the Urho3D project
  2. // License: MIT
  3. #include <Urho3D/Urho2D/AnimatedSprite2D.h>
  4. #include <Urho3D/Urho2D/AnimationSet2D.h>
  5. #include <Urho3D/Core/Context.h>
  6. #include <Urho3D/IO/MemoryBuffer.h>
  7. #include <Urho3D/Scene/Scene.h>
  8. #include <Urho3D/Scene/SceneEvents.h>
  9. #include <Urho3D/DebugNew.h>
  10. #include "Mover.h"
  11. Mover::Mover(Context* context) :
  12. LogicComponent(context),
  13. speed_(0.8f),
  14. currentPathID_(1),
  15. emitTime_(0.0f),
  16. fightTimer_(0.0f),
  17. flip_(0.0f)
  18. {
  19. // Only the scene update event is needed: unsubscribe from the rest for optimization
  20. SetUpdateEventMask(USE_UPDATE);
  21. }
  22. void Mover::RegisterObject(Context* context)
  23. {
  24. context->RegisterFactory<Mover>();
  25. // These macros register the class attribute to the Context for automatic load / save handling.
  26. // We specify the Default attribute mode which means it will be used both for saving into file, and network replication.
  27. URHO3D_MIXED_ACCESSOR_ATTRIBUTE("Path", GetPathAttr, SetPathAttr, Vector<unsigned char>, Variant::emptyBuffer, AM_DEFAULT);
  28. URHO3D_ATTRIBUTE("Speed", float, speed_, 0.8f, AM_DEFAULT);
  29. URHO3D_ATTRIBUTE("Current Path ID", int, currentPathID_, 1, AM_DEFAULT);
  30. URHO3D_ATTRIBUTE("Emit Time", float, emitTime_, 0.0f, AM_DEFAULT);
  31. URHO3D_ATTRIBUTE("Fight Timer", float, fightTimer_, 0.0f, AM_DEFAULT);
  32. URHO3D_ATTRIBUTE("Flip Animation", float, flip_, 0.0f, AM_DEFAULT);
  33. }
  34. void Mover::SetPathAttr(const Vector<unsigned char>& value)
  35. {
  36. if (value.Empty())
  37. return;
  38. MemoryBuffer buffer(value);
  39. while (!buffer.IsEof())
  40. path_.Push(buffer.ReadVector2());
  41. }
  42. Vector<unsigned char> Mover::GetPathAttr() const
  43. {
  44. VectorBuffer buffer;
  45. for (const Vector2& point : path_)
  46. buffer.WriteVector2(point);
  47. return buffer.GetBuffer();
  48. }
  49. void Mover::Update(float timeStep)
  50. {
  51. if (path_.Size() < 2)
  52. return;
  53. // Handle Orc states (idle/wounded/fighting)
  54. if (node_->GetName() == "Orc")
  55. {
  56. auto* animatedSprite = node_->GetComponent<AnimatedSprite2D>();
  57. String anim = "run";
  58. // Handle wounded state
  59. if (emitTime_ > 0.0f)
  60. {
  61. emitTime_ += timeStep;
  62. anim = "dead";
  63. // Handle dead
  64. if (emitTime_ >= 3.0f)
  65. {
  66. node_->Remove();
  67. return;
  68. }
  69. }
  70. else
  71. {
  72. // Handle fighting state
  73. if (fightTimer_ > 0.0f)
  74. {
  75. anim = "attack";
  76. flip_ = GetScene()->GetChild("Imp", true)->GetPosition().x_ - node_->GetPosition().x_;
  77. fightTimer_ += timeStep;
  78. if (fightTimer_ >= 3.0f)
  79. fightTimer_ = 0.0f; // Reset
  80. }
  81. // Flip Orc animation according to speed, or player position when fighting
  82. animatedSprite->SetFlipX(flip_ >= 0.0f);
  83. }
  84. // Animate
  85. if (animatedSprite->GetAnimation() != anim)
  86. animatedSprite->SetAnimation(anim);
  87. }
  88. // Don't move if fighting or wounded
  89. if (fightTimer_ > 0.0f || emitTime_ > 0.0f)
  90. return;
  91. // Set direction and move to target
  92. Vector2 dir = path_[currentPathID_] - node_->GetPosition2D();
  93. Vector2 dirNormal = dir.Normalized();
  94. node_->Translate(Vector3(dirNormal.x_, dirNormal.y_, 0.0f) * Abs(speed_) * timeStep);
  95. flip_ = dir.x_;
  96. // Check for new target to reach
  97. if (Abs(dir.Length()) < 0.1f)
  98. {
  99. if (speed_ > 0.0f)
  100. {
  101. if (currentPathID_ + 1 < path_.Size())
  102. currentPathID_ = currentPathID_ + 1;
  103. else
  104. {
  105. // If loop, go to first waypoint, which equates to last one (and never reverse)
  106. if (path_[currentPathID_] == path_[0])
  107. {
  108. currentPathID_ = 1;
  109. return;
  110. }
  111. // Reverse path if not looping
  112. currentPathID_ = currentPathID_ - 1;
  113. speed_ = -speed_;
  114. }
  115. }
  116. else
  117. {
  118. if (currentPathID_ - 1 >= 0)
  119. currentPathID_ = currentPathID_ - 1;
  120. else
  121. {
  122. currentPathID_ = 1;
  123. speed_ = -speed_;
  124. }
  125. }
  126. }
  127. }