Mover.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //
  2. // Copyright (c) 2008-2014 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include <Urho3D/Urho3D.h>
  23. #include <Urho3D/Urho2D/AnimatedSprite2D.h>
  24. #include <Urho3D/Urho2D/AnimationSet2D.h>
  25. #include <Urho3D/Core/Context.h>
  26. #include <Urho3D/IO/MemoryBuffer.h>
  27. #include <Urho3D/Scene/Scene.h>
  28. #include <Urho3D/Scene/SceneEvents.h>
  29. #include <Urho3D/DebugNew.h>
  30. #include "Mover.h"
  31. Mover::Mover(Context* context) :
  32. LogicComponent(context),
  33. speed_(0.8f),
  34. currentPathID_(1),
  35. emitTime_(0.0f),
  36. fightTimer_(0.0f),
  37. flip_(0.0f)
  38. {
  39. // Only the scene update event is needed: unsubscribe from the rest for optimization
  40. SetUpdateEventMask(USE_UPDATE);
  41. }
  42. void Mover::RegisterObject(Context* context)
  43. {
  44. context->RegisterFactory<Mover>();
  45. // These macros register the class attribute to the Context for automatic load / save handling.
  46. // We specify the Default attribute mode which means it will be used both for saving into file, and network replication.
  47. URHO3D_MIXED_ACCESSOR_ATTRIBUTE("Path", GetPathAttr, SetPathAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_DEFAULT);
  48. URHO3D_ATTRIBUTE("Speed", float, speed_, 0.8f, AM_DEFAULT);
  49. URHO3D_ATTRIBUTE("Current Path ID", int, currentPathID_, 1, AM_DEFAULT);
  50. URHO3D_ATTRIBUTE("Emit Time", float, emitTime_, 0.0f, AM_DEFAULT);
  51. URHO3D_ATTRIBUTE("Fight Timer", float, fightTimer_, 0.0f, AM_DEFAULT);
  52. URHO3D_ATTRIBUTE("Flip Animation", float, flip_, 0.0f, AM_DEFAULT);
  53. }
  54. void Mover::SetPathAttr(const PODVector<unsigned char>& value)
  55. {
  56. if (value.Empty())
  57. return;
  58. MemoryBuffer buffer(value);
  59. while (!buffer.IsEof())
  60. path_.Push(buffer.ReadVector2());
  61. }
  62. PODVector<unsigned char> Mover::GetPathAttr() const
  63. {
  64. VectorBuffer buffer;
  65. for (unsigned i = 0; i < path_.Size(); ++i)
  66. buffer.WriteVector2(path_[i]);
  67. return buffer.GetBuffer();
  68. }
  69. void Mover::Update(float timeStep)
  70. {
  71. if (path_.Size() < 2)
  72. return;
  73. // Handle Orc states (idle/wounded/fighting)
  74. if (node_->GetName() == "Orc")
  75. {
  76. auto* animatedSprite = node_->GetComponent<AnimatedSprite2D>();
  77. String anim = "run";
  78. // Handle wounded state
  79. if (emitTime_ > 0.0f)
  80. {
  81. emitTime_ += timeStep;
  82. anim = "dead";
  83. // Handle dead
  84. if (emitTime_ >= 3.0f)
  85. {
  86. node_->Remove();
  87. return;
  88. }
  89. }
  90. else
  91. {
  92. // Handle fighting state
  93. if (fightTimer_ > 0.0f)
  94. {
  95. anim = "attack";
  96. flip_ = GetScene()->GetChild("Imp", true)->GetPosition().x_ - node_->GetPosition().x_;
  97. fightTimer_ += timeStep;
  98. if (fightTimer_ >= 3.0f)
  99. fightTimer_ = 0.0f; // Reset
  100. }
  101. // Flip Orc animation according to speed, or player position when fighting
  102. animatedSprite->SetFlipX(flip_ >= 0.0f);
  103. }
  104. // Animate
  105. if (animatedSprite->GetAnimation() != anim)
  106. animatedSprite->SetAnimation(anim);
  107. }
  108. // Don't move if fighting or wounded
  109. if (fightTimer_ > 0.0f || emitTime_ > 0.0f)
  110. return;
  111. // Set direction and move to target
  112. Vector2 dir = path_[currentPathID_] - node_->GetPosition2D();
  113. Vector2 dirNormal = dir.Normalized();
  114. node_->Translate(Vector3(dirNormal.x_, dirNormal.y_, 0.0f) * Abs(speed_) * timeStep);
  115. flip_ = dir.x_;
  116. // Check for new target to reach
  117. if (Abs(dir.Length()) < 0.1f)
  118. {
  119. if (speed_ > 0.0f)
  120. {
  121. if (currentPathID_ + 1 < path_.Size())
  122. currentPathID_ = currentPathID_ + 1;
  123. else
  124. {
  125. // If loop, go to first waypoint, which equates to last one (and never reverse)
  126. if (path_[currentPathID_] == path_[0])
  127. {
  128. currentPathID_ = 1;
  129. return;
  130. }
  131. // Reverse path if not looping
  132. currentPathID_ = currentPathID_ - 1;
  133. speed_ = -speed_;
  134. }
  135. }
  136. else
  137. {
  138. if (currentPathID_ - 1 >= 0)
  139. currentPathID_ = currentPathID_ - 1;
  140. else
  141. {
  142. currentPathID_ = 1;
  143. speed_ = -speed_;
  144. }
  145. }
  146. }
  147. }