collector.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /* describes a sprite that is moving on the screen, collecting pickups */
  2. class Collector {
  3. /* initialize */
  4. constructor(world_game) {
  5. /* save instance of game, to interact with it */
  6. this.world_game = world_game;
  7. /* constant states */
  8. this.WAITING = 0;
  9. this.MOVING = 1;
  10. /* starting state (timer is used for animations) */
  11. this.state = this.WAITING;
  12. this.timer_max = Collector.new_timer;
  13. this.timer = this.timer_max -1;
  14. /* collector's textures */
  15. this.texture_run_array = [];
  16. this.texture_stand = loader.resources["images/darek_stand.png"].texture;
  17. for (let i = 0; i < 8; i++) {
  18. let tex = loader.resources["images/darek_run_" +i +".png"].texture;
  19. this.texture_run_array.push(tex);
  20. }
  21. /* collector's sprite */
  22. this.sprite = new PIXI.Sprite( this.texture_stand );
  23. this.sprite.anchor = {x:0.5, y:0.5};
  24. /* start from either left or right side of the screen, random height */
  25. this.sprite.x = Math.random() *2 > 1 ?
  26. -this.sprite.width/2 :
  27. width +this.sprite.width/2;
  28. this.sprite.y = Math.floor( Math.random() *height );
  29. /* add collector to screen, based on his y value
  30. * so it appears properly in front or behind objects
  31. * also calculate its position inside the y sorted array
  32. */
  33. let ground = world_game.ground_container;
  34. let position = ground.children.length;
  35. let y = this.sprite.y +this.sprite.height/2;
  36. for (let i = 0; i < ground.children.length; i++) {
  37. let y2 = ground.children[i].y +ground.children[i].height;
  38. if (y < y2) {
  39. position = i;
  40. break;
  41. }
  42. }
  43. world_game.ground_container.addChildAt(this.sprite, position);
  44. /* target pickup. -1 means there is no target,
  45. * any other greater value is the index of target pickup
  46. */
  47. this.target = -1;
  48. /* when targeting a pickup, save old location, and pickup's location,
  49. * in order to animate between them
  50. */
  51. this.old_loc = new PIXI.Point(0, 0);
  52. this.new_loc = new PIXI.Point(0, 0);
  53. } /* constructor */
  54. /* animate, move sprite and collect crystals */
  55. update() {
  56. /* advance animation */
  57. this.timer++;
  58. /* animation ended */
  59. if (this.timer >= this.timer_max) {
  60. /* based on what was being animated */
  61. switch (this.state) {
  62. /* collector was waiting */
  63. case this.WAITING:
  64. /* 50% it will wait for another second */
  65. if ( Math.random() < 0.5 ) {
  66. this.sprite.scale.x *= -1;
  67. this.timer -= 30;
  68. }
  69. /* start running towards a pickup with new speed */
  70. else {
  71. this.timer_max = Collector.new_timer;
  72. this.change_state(this.MOVING);
  73. }
  74. break;
  75. /* collector was moving */
  76. case this.MOVING:
  77. default:
  78. /* stop running and wait */
  79. this.change_state(this.WAITING);
  80. break;
  81. } /* switch state */
  82. }
  83. /* animation is still active */
  84. else {
  85. /* depending on what is being animated */
  86. switch (this.state) {
  87. /* collector is waiting */
  88. case this.WAITING:
  89. /* every 30 frames, there's 10% chance collector
  90. * will look on a different side (like he is searching)
  91. */
  92. if (this.timer % 30 == 0 && Math.random() < 0.1) {
  93. this.sprite.scale.x *= -1;
  94. }
  95. break;
  96. /* collector is running */
  97. case this.MOVING:
  98. /* move sprite from old location, to new location, based on timer/timer_max */
  99. this.sprite.x = this.old_loc.x +((this.new_loc.x -this.old_loc.x) /this.timer_max *this.timer);
  100. this.sprite.y = this.old_loc.y +((this.new_loc.y -this.old_loc.y) /this.timer_max *this.timer);
  101. /* check if collector moved behind or in front of another object */
  102. let ground = this.world_game.ground_container;
  103. let pos = ground.getChildIndex(this.sprite);
  104. while (pos > 0 && (this.sprite.y +this.sprite.height/2) <= (ground.children[pos-1].y +ground.children[pos-1].height/2)) {
  105. ground.swapChildren(this.sprite, ground.children[pos-1]);
  106. pos--;
  107. }
  108. while (pos < ground.children.length-1 &&
  109. (this.sprite.y +this.sprite.height/2) >=
  110. (ground.children[pos+1].y +ground.children[pos+1].height/2)) {
  111. ground.swapChildren(this.sprite, ground.children[pos+1]);
  112. pos++;
  113. }
  114. /* animate collector */
  115. this.sprite.texture = this.texture_run_array[ Math.floor( (this.timer /5) %8 ) ];
  116. break;
  117. } /* switch state */
  118. } /* animation is still running */
  119. } /* update end */
  120. /* randomly select a new pickup as target */
  121. find_target() {
  122. /* pickups alias */
  123. let pickups = this.world_game.spawner.array;
  124. /* if no pickups, no target is selected */
  125. if (pickups.length == 0) {
  126. this.target = -1;
  127. return;
  128. }
  129. /* pick new target from pickup array, randomly */
  130. this.target = Math.floor( Math.random() *pickups.length );
  131. /* save current location */
  132. this.old_loc.x = this.sprite.position.x;
  133. this.old_loc.y = this.sprite.position.y;
  134. /* save target location */
  135. this.new_loc.x = pickups[this.target].position.x;
  136. this.new_loc.y = pickups[this.target].position.y
  137. +pickups[this.target].height/2
  138. -this.sprite.height/2;
  139. /* face either left or right, to new target */
  140. this.sprite.scale.x =
  141. this.new_loc.x > this.old_loc.x ? 1 : -1;
  142. } /* end find_target */
  143. /* a specific pickup was collected, if it was this collector's target,
  144. * stop running for it, and start waiting again
  145. */
  146. notify_collected(i) {
  147. /* pickup collected was target,
  148. * start waiting
  149. */
  150. if (this.target == i) {
  151. this.change_state(this.WAITING);
  152. return;
  153. }
  154. /* target had higher index than pickup collected,
  155. * since pickup array is sliced, move target one space below.
  156. */
  157. if (this.target > i) {
  158. this.target--;
  159. }
  160. } /* end notify_collected */
  161. /* change between states */
  162. change_state(STATE) {
  163. /* depending on current state */
  164. switch (this.state) {
  165. /* previous state was waiting */
  166. case this.WAITING:
  167. /* change state, reset animation, find new target (TO FIX) */
  168. this.find_target();
  169. if (this.target == -1) {
  170. this.timer = 0;
  171. }
  172. else {
  173. this.state = STATE;
  174. this.timer = 0;
  175. }
  176. break;
  177. /* previous state was moving */
  178. case this.MOVING:
  179. default:
  180. /* change to new state */
  181. this.state = STATE;
  182. /* animation was finished and not interrupted */
  183. if (this.timer >= this.timer_max) {
  184. /* save target and notify game that this collector is collecting
  185. * a specific pickup
  186. * but first remove it from self, so it doesn't notify itself
  187. */
  188. let target = this.target;
  189. this.target = -1;
  190. this.world_game.pickup(target); /* TO FIX */
  191. }
  192. /* reset animation */
  193. this.timer = 0;
  194. /* reset animation frame */
  195. this.sprite.texture = this.texture_stand;
  196. break;
  197. }
  198. } /* change_state */
  199. } /* Collector */