/experiments/particles/Boids3D/src/org/gsdh/labs/flocking/Shark.as

https://github.com/gsdhdeveloper/GSDH-Labs
ActionScript | 163 lines | 121 code | 30 blank | 12 comment | 37 complexity | e5639251020f603b6f21e820084fe861 MD5 | raw file
  1. package org.gsdh.labs.flocking
  2. {
  3. import flash.display.Sprite;
  4. import flash.geom.Point;
  5. import flash.geom.Vector3D;
  6. /**
  7. * @author Chris Truter
  8. */
  9. public class Shark extends Sprite
  10. {
  11. private var _vel:Vector3D;
  12. public function Shark()
  13. {
  14. var dir:Number = Math.random() * Math.PI * 2;
  15. _vel = new Vector3D(
  16. 2 * Math.cos(dir),
  17. 2 * Math.sin(dir),
  18. 100 * Math.random()
  19. );
  20. draw();
  21. }
  22. private function draw():void
  23. {
  24. graphics.beginFill(0xff0000);
  25. //graphics.beginFill(0xffffff);
  26. graphics.moveTo( -12, -18);
  27. graphics.lineTo( 30, 0);
  28. graphics.lineTo( -12, 18);
  29. graphics.lineTo( -12, -18);
  30. graphics.endFill();
  31. }
  32. public function update(boids:Vector.<Boid>):void
  33. {
  34. var target:Vector3D = new Vector3D;
  35. var hitCount:Number = 0;
  36. var viewDistance:Number = 300;
  37. var maxDistSquared:Number = Config.SHARK_OR_PLANKTON == 0 ? viewDistance * viewDistance : 50 * 50;
  38. for (var i:int = 0; i < boids.length; i++)
  39. {
  40. var boid:Boid = boids[i];
  41. var dx:Number = boid.x - x;
  42. var dy:Number = boid.y - y;
  43. var dz:Number = boid.z - z;
  44. boid.targeted = false;
  45. if (Config.SHARK_OR_PLANKTON == 0)
  46. {
  47. if (dx < -viewDistance || dx > viewDistance || dy < -viewDistance || dy > viewDistance || dz < -240 || dz > 240)
  48. continue;
  49. }
  50. if (Config.SHARK_OR_PLANKTON == 1)
  51. {
  52. if (dx < -50 || dx > 50 || dy < -50 || dy > 50 || dz < -50 || dz > 50)
  53. continue;
  54. }
  55. var dist:Number = dx * dx + dy * dy + dz * dz;
  56. if (dist > maxDistSquared)
  57. continue;
  58. boid.targeted = true;
  59. target.x += boid.x;
  60. target.y += boid.y;
  61. target.z += boid.z;
  62. hitCount++;
  63. // TODO: show that he is interested
  64. }
  65. // average out target position
  66. if (hitCount > 0)
  67. {
  68. var mult:Number = 1 / hitCount;
  69. target.x *= mult;
  70. target.y *= mult;
  71. target.z *= mult;
  72. }
  73. else
  74. {
  75. target.x = x;
  76. target.y = y;
  77. target.z = z;
  78. }
  79. var acc:Vector3D = new Vector3D(target.x - x, target.y - y);
  80. var invMag:Number = 1 / Math.sqrt(acc.x * acc.x + acc.y * acc.y);
  81. if (!isNaN(invMag))
  82. {
  83. acc.x *= .2 * invMag;
  84. acc.y *= .2 * invMag;
  85. acc.z *= .2 * invMag;
  86. }
  87. if (isNaN(acc.x))
  88. acc.x = 0;
  89. if (isNaN(acc.y))
  90. acc.y = 0;
  91. if (isNaN(acc.z))
  92. acc.z = 0;
  93. if (Config.SHARK_OR_PLANKTON == 2)
  94. acc.x = acc.y = acc.z = 0;
  95. _vel.x += acc.x * (Config.SHARK_OR_PLANKTON ? -4 : 1);
  96. _vel.y += acc.y * (Config.SHARK_OR_PLANKTON ? -4 : 1);
  97. _vel.z += acc.z * (Config.SHARK_OR_PLANKTON ? -4 : 1);
  98. // bounce
  99. if (y < 0) { _vel.y *= -1; y = 0; }
  100. if (x < 0) { _vel.x *= -1; x = 0; }
  101. if (y > stage.stageHeight) { _vel.y *= -1; y = stage.stageHeight; }
  102. if (x > stage.stageWidth) { _vel.x *= -1; x = stage.stageWidth; }
  103. if (z < 0) { _vel.z *= -1; z = 0; }
  104. if (z > 400) { _vel.z *= -1; z = stage.stageWidth; }
  105. // slow
  106. if (y < 50) _vel.y += .2;
  107. if (x < 50) _vel.x += .2;
  108. if (y > stage.stageHeight - 50) _vel.y -= .2;
  109. if (x > stage.stageWidth - 50) _vel.x -= .2;
  110. var square:Number = _vel.x * _vel.x + _vel.y * _vel.y + _vel.z * _vel.z;
  111. var max_speed:Number = Config.SHARK_OR_PLANKTON ? 9 : 6;
  112. if (square > max_speed * max_speed)
  113. {
  114. invMag = 1 / Math.sqrt(square);
  115. _vel.x *= invMag * max_speed;
  116. _vel.y *= invMag * max_speed;
  117. _vel.z *= invMag * max_speed;
  118. }
  119. x += _vel.x * .5;
  120. y += _vel.y * .5;
  121. z += _vel.z * .5;
  122. //var angle:Number = Math.atan2(acc.y, acc.x);
  123. //rotation = angle / Math.PI * 180;
  124. square = _vel.x * _vel.x + _vel.y * _vel.y + _vel.z * _vel.z;
  125. var angle:Number = Math.atan2(_vel.y, _vel.x);
  126. rotationZ = angle / Math.PI * 180;
  127. var phi:Number = Math.acos(_vel.z / Math.sqrt(square)) - 90;
  128. rotationY = phi * 180 / Math.PI;
  129. //angle = Math.atan2(_vel.z, _vel.x);
  130. //rotationY = angle / Math.PI * 180;
  131. }
  132. }
  133. }