botcontroller.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. function BotController(game) {
  2. this.decisionDelay = 10;
  3. this.lastDecision = 0;
  4. this.shipState = "idle";
  5. this.shootDelay = 0;
  6. this.targetedEnemy = null;
  7. this.init = function() {
  8. };
  9. this.reset = function(ship) {
  10. this.shipState = "idle";
  11. };
  12. this.makeDecisions = function(ship) {
  13. this.shootDelay--;
  14. this.avoidPlanets(ship);
  15. this.avoidStars(ship);
  16. switch(this.shipState) {
  17. case "idle":
  18. ship.idle();
  19. if(this.decisionDelay <= 0) {
  20. this.decideNextAction(ship);
  21. this.decisionDelay = 10;
  22. }
  23. this.decisionDelay--;
  24. break;
  25. case "takeoff":
  26. this.takeOff(ship);
  27. break;
  28. case "hunt":
  29. this.targetEnemy(ship);
  30. break;
  31. case "captureplanet":
  32. this.capturePlanet(ship);
  33. break;
  34. case "heal":
  35. this.heal(ship);
  36. break;
  37. case "combat":
  38. this.targetEnemy(ship);
  39. break;
  40. }
  41. };
  42. this.decideNextAction = function(ship) {
  43. this.lastDecision = parseInt(4 * Math.random());
  44. if(ship.touching != null) {
  45. this.lastDecision = 3;
  46. }
  47. if(ship.health < parseInt(ship.maxHealth / 2)) {
  48. this.lastDecision = 4;
  49. }
  50. switch(this.lastDecision) {
  51. case 0:
  52. this.shipState = "idle";
  53. break;
  54. case 1:
  55. this.shipState = "captureplanet";
  56. break;
  57. case 2:
  58. this.shipState = "hunt";
  59. break;
  60. case 3:
  61. this.shipState = "takeoff";
  62. break;
  63. case 4:
  64. this.shipState = "heal";
  65. break;
  66. case 5:
  67. this.shipState = "fight";
  68. break;
  69. }
  70. }
  71. this.takeOff = function(ship) {
  72. var nearestSystem = game.getNearestSystem(game, ship);
  73. var nearestPlanet = game.getNearestPlanet(nearestSystem, ship);
  74. var nearestPlanetDistance = game.calculateDistanceTo(ship, nearestPlanet);
  75. if(nearestPlanetDistance > 300) {
  76. this.shipState = "idle";
  77. return;
  78. }
  79. var oppositeFromPlanetAngle = system.game.calculateAngleTo(nearestPlanet, ship) + Math.PI;
  80. ship.targetAngle = oppositeFromPlanetAngle;
  81. ship.accelerate();
  82. };
  83. this.avoidStars = function(ship) {
  84. //if star is directly in front
  85. //calculate time to slow down
  86. //if
  87. }
  88. this.avoidPlanets = function(ship) {
  89. //if star is directly in front
  90. //calculate time to slow down
  91. //if
  92. }
  93. this.targetEnemy = function(ship) {
  94. this.targetedEnemy = null;
  95. if(ship.touching != null) {
  96. this.shipState = "idle";
  97. return;
  98. }
  99. var nearestShip = game.getNearestShip(game, ship);
  100. if(nearestShip == null || nearestShip.isDead) {
  101. this.shipState = "idle";
  102. this.decisionDelay = 0;
  103. return;
  104. }
  105. this.targetedEnemy = nearestShip;
  106. var nearestShipDistance = game.calculateDistanceTo(ship, nearestShip);
  107. if(nearestShipDistance > 500) {
  108. var nearestShipAngle = game.calculateAngleTo(ship, nearestShip);
  109. ship.targetAngle = nearestShipAngle + Math.PI;
  110. ship.accelerate();
  111. }/* else if(nearestShipDistance > 250 && !this.matchesVelocity(ship, nearestShip)) {
  112. this.adjustVelocity(ship, nearestShip, nearestShipAngle);
  113. }*/ else if(nearestShipDistance < 250) {
  114. var nearestShipAngle = game.calculateAngleTo(ship, nearestShip);
  115. var predictedAngle = Math.atan2(ship.position.y - (nearestShip.position.y + nearestShip.velocity.y * 20) , ship.position.x - (nearestShip.position.x + nearestShip.velocity.x * 20));
  116. ship.targetAngle = predictedAngle + Math.PI;
  117. if(this.shootDelay <= 0) {
  118. ship.shoot();
  119. this.shootDelay = parseInt(20 * Math.random());
  120. }
  121. }
  122. //get nearest enemy ship
  123. //if within x distance, chase
  124. //if velocity > enemy velocity, slow down
  125. //if within x distance, shoot
  126. }
  127. this.matchesVelocity = function(ship, other) {
  128. return false;
  129. }
  130. this.adjustVelocity = function(ship, other, angle) {
  131. ship.idle();
  132. var otherVector = {x: other.velocity.x, y: other.velocity.y};
  133. var shipVector = {x: ship.velocity.x, y: ship.velocity.y};
  134. var shipMagnitude = Math.abs(Math.sqrt(Math.pow(ship.velocity.x, 2) + Math.pow(ship.velocity.y, 2)));
  135. var otherMagnitude = Math.abs(Math.sqrt(Math.pow(other.velocity.x, 2) + Math.pow(other.velocity.y, 2)));
  136. var dotProduct = shipVector.x * otherVector.x + shipVector.y + otherVector.y;
  137. var newangle = Math.acos(dotProduct / (shipMagnitude * otherMagnitude));
  138. ship.targetAngle = newangle;
  139. ship.accelerate();
  140. //get heading of other ship
  141. //get heading of current ship
  142. //find vector difference in velocities
  143. //change angle of current ship to apply thrust in appropriate direction
  144. //ship accelerate
  145. }
  146. this.capturePlanet = function(ship) {
  147. this.shipState = "idle";
  148. //get nearest unclaimed planet
  149. //travel to
  150. //if within x distance, go towards
  151. //if within x distance, slow down
  152. //interact with
  153. //if within x distance, land
  154. }
  155. this.heal = function(ship) {
  156. if(ship.health == ship.maxHealth) {
  157. this.shipState = "takeoff";
  158. }
  159. //if health is low
  160. //get nearest claimed planet
  161. //travel to
  162. //if within x distance, go towards
  163. //if within x distance, slow down
  164. //interact with
  165. //if within x distance, land
  166. //if health is max, launch
  167. }
  168. this.getColor = function() {
  169. var random = parseInt(4* Math.random());
  170. switch(random) {
  171. case 0:
  172. return "#DDDD33";
  173. case 1:
  174. return "#DD33DD";
  175. case 2:
  176. return "#33DD33";
  177. case 3:
  178. return "#3333DD";
  179. }
  180. };
  181. this.debugDraw = function(ship, context) {
  182. return false;
  183. //combat markers
  184. if(this.shipState == "hunt" && this.targetedEnemy != null) {
  185. context.lineWidth = 1;
  186. context.strokeStyle = "crimson";
  187. context.beginPath();
  188. context.moveTo(ship.position.x,ship.position.y);
  189. context.lineTo(this.targetedEnemy.position.x, this.targetedEnemy.position.y);
  190. context.stroke();
  191. context.beginPath();
  192. context.arc(this.targetedEnemy.position.x, this.targetedEnemy.position.y, 20, 0, 2 * Math.PI);
  193. context.stroke();
  194. }
  195. context.save();
  196. context.translate(ship.position.x, ship.position.y);
  197. context.lineWidth = 1;
  198. context.strokeStyle = "limegreen";
  199. context.beginPath();
  200. context.moveTo(0,0);
  201. context.lineTo(400 * ship.acceleration.x, 400 * ship.acceleration.y);
  202. context.stroke();
  203. context.strokeStyle = "cornflowerblue";
  204. var last = {x:0, y: 0};
  205. for(var i = 0; i < 400; i++) {
  206. context.beginPath();
  207. context.moveTo(last.x + ship.width, last.y + ship.height);
  208. last.x += (i * ship.acceleration.x + ship.velocity.x);
  209. last.y += (i * ship.acceleration.y + ship.velocity.y);
  210. context.lineTo(last.x + ship.width, last.y + ship.height);
  211. context.stroke();
  212. }
  213. var last = {x:0, y: 0};
  214. for(var i = 0; i < 400; i++) {
  215. context.beginPath();
  216. context.moveTo(last.x - ship.width, last.y - ship.height);
  217. last.x += (i * ship.acceleration.x + ship.velocity.x);
  218. last.y += (i * ship.acceleration.y + ship.velocity.y);
  219. context.lineTo(last.x - ship.width, last.y - ship.height);
  220. context.stroke();
  221. }
  222. context.restore();
  223. };
  224. };