GameObject.as 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. const int CTRL_UP = 1;
  2. const int CTRL_DOWN = 2;
  3. const int CTRL_LEFT = 4;
  4. const int CTRL_RIGHT = 8;
  5. const int CTRL_FIRE = 16;
  6. const int CTRL_JUMP = 32;
  7. const int CTRL_ALL = 63;
  8. const int SIDE_NEUTRAL = 0;
  9. const int SIDE_PLAYER = 1;
  10. const int SIDE_ENEMY = 2;
  11. class GameObject : ScriptObject
  12. {
  13. bool onGround;
  14. bool isSliding;
  15. float duration;
  16. int health;
  17. int maxHealth;
  18. int side;
  19. int lastDamageSide;
  20. GameObject()
  21. {
  22. onGround = false;
  23. isSliding = false;
  24. duration = -1; // Infinite
  25. health = 0;
  26. maxHealth = 0;
  27. side = SIDE_NEUTRAL;
  28. lastDamageSide = SIDE_NEUTRAL;
  29. }
  30. void Create(const Vector3&in position, const Quaternion&in rotation)
  31. {
  32. }
  33. void FixedUpdate(float timeStep)
  34. {
  35. // Disappear when duration expired
  36. if (duration >= 0)
  37. {
  38. duration -= timeStep;
  39. if (duration <= 0)
  40. node.Remove();
  41. }
  42. }
  43. bool Damage(GameObject@ origin, int amount)
  44. {
  45. if ((origin.side == side) || (health == 0))
  46. return false;
  47. lastDamageSide = origin.side;
  48. health -= amount;
  49. if (health < 0)
  50. health = 0;
  51. return true;
  52. }
  53. bool Heal(int amount)
  54. {
  55. // By default do not heal
  56. return false;
  57. }
  58. void PlaySound(const String&in soundName)
  59. {
  60. // Create the sound channel
  61. SoundSource3D@ source = node.CreateComponent("SoundSource3D");
  62. Sound@ sound = cache.GetResource("Sound", soundName);
  63. source.SetDistanceAttenuation(200, 5000, 1);
  64. source.Play(sound);
  65. source.autoRemove = true;
  66. }
  67. Node@ SpawnObject(const Vector3&in position, const Quaternion&in rotation, const String&in className)
  68. {
  69. Node@ newNode = scene.CreateChild();
  70. // Create the script object with specified class
  71. GameObject@ object = cast<GameObject>(newNode.CreateScriptObject(scriptFile, className));
  72. if (object !is null)
  73. object.Create(position, rotation);
  74. return newNode;
  75. }
  76. Node@ SpawnParticleEffect(const Vector3&in position, const String&in effectName, float duration)
  77. {
  78. Node@ newNode = scene.CreateChild();
  79. newNode.position = position;
  80. // Create the particle emitter
  81. ParticleEmitter@ emitter = newNode.CreateComponent("ParticleEmitter");
  82. emitter.parameters = cache.GetResource("XMLFile", effectName);
  83. // Create a GameObject for managing the effect lifetime
  84. GameObject@ object = cast<GameObject>(newNode.CreateScriptObject(scriptFile, "GameObject"));
  85. object.duration = duration;
  86. return newNode;
  87. }
  88. Node@ SpawnSound(const Vector3&in position, const String&in soundName, float duration)
  89. {
  90. Node@ newNode = scene.CreateChild();
  91. newNode.position = position;
  92. // Create the sound source
  93. SoundSource3D@ source = newNode.CreateComponent("SoundSource3D");
  94. Sound@ sound = cache.GetResource("Sound", soundName);
  95. source.SetDistanceAttenuation(200, 5000, 1);
  96. source.Play(sound);
  97. // Create a GameObject for managing the sound lifetime
  98. GameObject@ object = cast<GameObject>(newNode.CreateScriptObject(scriptFile, "GameObject"));
  99. object.duration = duration;
  100. return newNode;
  101. }
  102. void HandleNodeCollision(StringHash eventType, VariantMap& eventData)
  103. {
  104. Node@ otherNode = eventData["OtherNode"].GetNode();
  105. CollisionShape@ otherShape = eventData["OtherShape"].GetCollisionShape();
  106. // If the other collision shape belongs to static geometry, perform world collision
  107. if (otherShape.collisionGroup == 2)
  108. WorldCollision(eventData);
  109. // If the other node is scripted, perform object-to-object collision
  110. GameObject@ otherObject = cast<GameObject>(otherNode.scriptObject);
  111. if (otherObject !is null)
  112. ObjectCollision(otherObject, eventData);
  113. }
  114. void WorldCollision(VariantMap& eventData)
  115. {
  116. VectorBuffer contacts = eventData["Contacts"].GetBuffer();
  117. while (!contacts.eof)
  118. {
  119. Vector3 contactPosition = contacts.ReadVector3();
  120. Vector3 contactNormal = contacts.ReadVector3();
  121. float contactDepth = contacts.ReadFloat();
  122. float contactVelocity = contacts.ReadFloat();
  123. // If contact is below node center and mostly vertical, assume it's ground contact
  124. if (contactPosition.y < node.position.y)
  125. {
  126. float level = Abs(contactNormal.y);
  127. if (level > 0.75)
  128. onGround = true;
  129. else
  130. {
  131. // If contact is somewhere inbetween vertical/horizontal, is sliding a slope
  132. if (level > 0.1)
  133. isSliding = true;
  134. }
  135. }
  136. }
  137. // Ground contact has priority over sliding contact
  138. if (onGround == true)
  139. isSliding = false;
  140. }
  141. void ObjectCollision(GameObject@ otherObject, VariantMap& eventData)
  142. {
  143. }
  144. void ResetWorldCollision()
  145. {
  146. RigidBody@ body = node.GetComponent("RigidBody");
  147. if (body.active)
  148. {
  149. onGround = false;
  150. isSliding = false;
  151. }
  152. else
  153. {
  154. // If body is not active, assume it rests on the ground
  155. onGround = true;
  156. isSliding = false;
  157. }
  158. }
  159. }