controller.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. var Controller = function(){
  2. this.grid_size = {x: 20, y: 20};
  3. this.initial_length = 1;
  4. this.time_step = 400;
  5. this.maximum_spawns = 5;
  6. this.collectibles = [];
  7. this.views = [];
  8. this.snake = new Snake(this.initial_length);
  9. this.canTurn = true;
  10. this.facts_shown = {};
  11. this.counter = 0;
  12. var pos0 = {x: -1, y: -1};
  13. this.score = 0;
  14. var pp = possible_particles();
  15. this.possible_collectibles = [];
  16. for (var p in pp){
  17. this.possible_collectibles.push({collectible: pp[p], probability: pp[p].appearence_probabilty});
  18. }
  19. createjs.DisplayObject.suppressCrossDomainErrors = true;
  20. this.stage = new createjs.Stage("demoCanvas");
  21. }
  22. Controller.prototype.update_views = function(){
  23. for(var view in this.views){
  24. this.views[view].update();
  25. }
  26. }
  27. Controller.prototype.spawn_collectibles = function(){
  28. var collectible = get_random_element_with_probabilities(this.possible_collectibles);
  29. if (!collectible) {
  30. return;
  31. }
  32. collectible = Object.create(collectible.collectible);
  33. var rnd_pos = this.get_random_position();
  34. if (!this.is_position_occupied(rnd_pos)) {
  35. collectible.position = rnd_pos;
  36. this.add_collectible(collectible);
  37. }
  38. }
  39. Controller.prototype.add_collectible = function(collectible){
  40. if(collectible.half_life > 0){
  41. collectible.decay_time = createjs.Ticker.getTime() + collectible.half_life;
  42. }
  43. this.collectibles.push(collectible);
  44. this.add_view(new ParticleView(collectible));
  45. }
  46. Controller.prototype.add_physicist = function(){
  47. //var new_physicist = Object.create(this.snake.physicists[this.snake.physicists.length - 1]);
  48. var new_physicist = new Physicist(this, {x: 0, y: 0});//Object.create(physicist.physicist);
  49. new_physicist.position = this.snake.physicists[this.snake.physicists.length - 1].position;
  50. new_physicist.direction = this.snake.physicists[this.snake.physicists.length - 1].direction;
  51. this.snake.physicists.push(new_physicist);
  52. this.add_view(new PhysicistView(new_physicist));
  53. }
  54. Controller.prototype.start_game = function(){
  55. // this.session = new Session();
  56. var c = this;
  57. createjs.Ticker.on("tick", function(e) {
  58. c.tick(e);
  59. });
  60. createjs.Ticker.timingMode = createjs.Ticker.RAF;
  61. this.bind_events();
  62. this.time = 0;
  63. this.score = 0;
  64. this.update_interface();
  65. for(phModel in controller.snake.physicists) {
  66. var model = controller.snake.physicists[phModel];
  67. var phView = new PhysicistView(model);
  68. this.add_view(phView);
  69. }
  70. }
  71. Controller.prototype.add_view = function(view){
  72. this.stage.addChild(view);
  73. this.views.push(view);
  74. }
  75. Controller.prototype.bind_events = function(){
  76. var c = this;
  77. window.onkeydown = function(e){
  78. var direction = null;
  79. var dir = {x: c.snake.physicists[0].direction.x, y: c.snake.physicists[0].direction.y};
  80. switch (e.keyCode) {
  81. case 37:
  82. case 65:
  83. if(dir.x == 1)
  84. {
  85. break;}
  86. else {
  87. direction = {x: -1, y: 0};
  88. break;
  89. }
  90. case 38:
  91. case 87:
  92. if(dir.y == 1)
  93. {
  94. break;}
  95. else {
  96. direction = {x: 0, y: -1};
  97. break;
  98. }
  99. case 39:
  100. case 68:
  101. if(dir.x == -1)
  102. {
  103. break;}
  104. else {
  105. direction = {x: 1, y: 0};
  106. break;
  107. }
  108. case 40:
  109. case 83:
  110. if(dir.y == -1)
  111. {
  112. break;}
  113. else {
  114. direction = {x: 0, y: 1};
  115. break;
  116. }
  117. }
  118. if (direction && c.canTurn){
  119. c.turn_snake(direction);
  120. c.canTurn = false;
  121. }
  122. }
  123. }
  124. Controller.prototype.turn_snake = function(direction){
  125. this.snake.physicists[0].direction = direction;
  126. }
  127. Controller.prototype.tick = function(event){
  128. if(event.paused) {
  129. return;
  130. }
  131. if(event.time - this.time > this.time_step) {
  132. this.time = event.time;
  133. var next_cell = this.get_next_cell_position();
  134. var next_cell_content = this.is_position_occupied(next_cell);
  135. if (next_cell.is_initial !== true && next_cell_content && next_cell_content.physicist) {
  136. this.game_over();
  137. }
  138. this.snake.move(next_cell);
  139. this.canTurn = true;
  140. this.physicists_count();
  141. if (next_cell_content && next_cell_content.collectible) {
  142. this.snake.physicists[0].collect(next_cell_content.collectible);
  143. }
  144. if(this.collectibles.length < this.maximum_spawns) {
  145. this.spawn_collectibles();
  146. }
  147. this.update_views();
  148. }
  149. this.check_decays();
  150. this.stage.update(event);
  151. }
  152. Controller.prototype.check_decays = function(){
  153. for(var pIndex in this.collectibles) {
  154. var p = this.collectibles[pIndex];
  155. if(p.half_life && p.decays && p.decays.length
  156. && (createjs.Ticker.getTime() > p.decay_time)) {
  157. var offset = {x: 0, y: 0};
  158. var counter = 0;
  159. var decay = get_random_element_with_probabilities(p.decays);
  160. if (!decay) {
  161. return;
  162. }
  163. for(var daughterInd in decay.particles) {
  164. if(counter % 2){
  165. offset.x = - offset.x;
  166. offset.y = - offset.y;
  167. } else {
  168. offset.x = Math.floor((Math.random() * this.grid_size.x / 10)) % this.grid_size.x;
  169. offset.y = Math.floor((Math.random() * this.grid_size.y / 10)) % this.grid_size.y;
  170. }
  171. while(this.is_position_occupied(offset)){
  172. offset.x++;
  173. offset.y++;
  174. }
  175. var daughter = this.get_particle_by_type(decay.particles[counter], p.position);
  176. daughter.start_time = createjs.Ticker.getTime();
  177. daughter.target = {
  178. time: daughter.start_time + 500,
  179. x: daughter.position.x + offset.x,
  180. y: daughter.position.y + offset.y
  181. }
  182. daughter.decays = null;
  183. this.add_collectible(daughter);
  184. counter++;
  185. }
  186. this.remove_collectible(p);
  187. }
  188. }
  189. }
  190. Controller.prototype.get_particle_by_type = function(ptype, position){
  191. for (var pIndex in this.possible_collectibles){
  192. var cc = this.possible_collectibles[pIndex];
  193. if (cc.collectible.type == ptype){
  194. cc = Object.create(cc.collectible);
  195. var pos = Object.create(position);
  196. cc.position = pos;
  197. return cc;
  198. }
  199. }
  200. }
  201. Controller.prototype.get_next_cell_position = function(){
  202. var ph0 = this.snake.physicists[0];
  203. var next_cell = Object.create(ph0.position);
  204. if (ph0.direction.x == 0 && ph0.direction.y == 0) {
  205. next_cell.is_initial = true;
  206. } else {
  207. next_cell.is_initial = false;
  208. }
  209. next_cell.x += ph0.direction.x;
  210. next_cell.y += ph0.direction.y;
  211. if (next_cell.x < 0) {
  212. next_cell.x = this.grid_size.x - 1;
  213. }
  214. if (next_cell.y < 0) {
  215. next_cell.y = this.grid_size.y - 1;
  216. }
  217. if (next_cell.x == this.grid_size.x) {
  218. next_cell.x = 0;
  219. }
  220. if (next_cell.y == this.grid_size.y) {
  221. next_cell.y = 0;
  222. }
  223. return next_cell;
  224. }
  225. Controller.prototype.get_random_position = function(){
  226. return {
  227. x: Math.floor(Math.random()*this.grid_size.x),
  228. y: Math.floor(Math.random()*this.grid_size.y)
  229. };
  230. }
  231. Controller.prototype.is_position_occupied = function(position){
  232. var phs = this.snake.physicists;
  233. for (var ph in phs){
  234. var pos = phs[ph].position;
  235. if (pos.x == position.x && pos.y == position.y) return {physicist:phs[ph]};
  236. }
  237. for (var c in this.collectibles){
  238. var pos = this.collectibles[c].position;
  239. if (pos.x == position.x && pos.y == position.y) return {collectible:this.collectibles[c]};
  240. }
  241. return null;
  242. }
  243. Controller.prototype.hit_test = function(particle){
  244. for (var ph_i in this.snake.physicists){
  245. var ph = this.snake.physicists[ph_i];
  246. if (ph.view.hitTest(particle.position.x, particle.position.y)) {
  247. ph.collect(particle);
  248. }
  249. }
  250. }
  251. Controller.prototype.remove_collectible = function(collectible){
  252. var i = this.collectibles.indexOf(collectible);
  253. if (i > -1) {
  254. this.collectibles.splice(i, 1);
  255. }
  256. i = -1;
  257. i = this.views.indexOf(collectible.view);
  258. if (i > -1) {
  259. this.views.splice(i, 1);
  260. }
  261. this.stage.removeChild(collectible.view);
  262. }
  263. var get_random_element_with_probabilities = function(array){
  264. var previous_probability = 0;
  265. var rnd = Math.random();
  266. for (ind in array){
  267. var probability = array[ind].probability;
  268. if (rnd < probability + previous_probability) return array[ind];
  269. previous_probability += probability;
  270. }
  271. return null;
  272. }
  273. Controller.prototype.physicists_count = function(){
  274. if(this.counter >= 1) {
  275. this.add_physicist();
  276. this.counter = 0;
  277. }
  278. }
  279. Controller.prototype.game_over = function(){
  280. alert("Game Over!\nScore: " + this.score);
  281. this.snake = new Snake(this.initial_length);
  282. this.canTurn = true;
  283. this.counter = 0;
  284. createjs.Ticker.reset();
  285. createjs.Ticker.init();
  286. for(var view in this.views){
  287. this.stage.removeChild(this.views[view]);
  288. }
  289. for(var collectible in this.collectibles){
  290. this.stage.removeChild(this.collectibles[collectible]);
  291. }
  292. this.collectibles = [];
  293. this.views = [];
  294. this.stage.clear();
  295. this.start_game()// ...
  296. }
  297. Controller.prototype.update_interface = function(){
  298. $("#score").html(this.score);
  299. }