PageRenderTime 53ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/www/javascripts/tutorial.js

https://github.com/samjohn/daisythedinosaur
JavaScript | 278 lines | 229 code | 8 blank | 41 comment | 55 complexity | 04414afac35405b17eb3c4b674087d89 MD5 | raw file
  1. var Step = Backbone.Model.extend({
  2. defaults: {
  3. title: "",
  4. description: "",
  5. elements: []
  6. },
  7. undraw: function() {
  8. _.each(this.get('elements'), function(e){
  9. e.remove();
  10. })
  11. },
  12. success: function() {
  13. var buttons;
  14. if (this == this.collection.last()) {
  15. buttons = [{
  16. text: "You win! Go to freeplay mode",
  17. click: function() {
  18. $(this).dialog("close");
  19. window.location.href = "freeplay.html";
  20. }
  21. }];
  22. } else {
  23. buttons = [{
  24. text: "Try the next challenge",
  25. click: function() { $(this).dialog("close"); }
  26. }];
  27. }
  28. $('#success').dialog({
  29. modal: true,
  30. dialogClass: 'success',
  31. width: 600,
  32. title: "Congratulations!",
  33. buttons: buttons
  34. });
  35. },
  36. star: function(left, topCoord) {
  37. var star = Stage.paper.path("M100,225, S125,190,350,175, L115,375, L200,100, S250,200,285,375, M285,375, S192.5,315,100,225").attr('stroke-width', 0).attr('fill', 'gold').transform("R10,100,100S.25,T" + left + "," + topCoord );
  38. var glow = star.glow({width: '2'}).transform("R5");
  39. return [star, glow];
  40. },
  41. prompt: function() {
  42. this.get('draw')(this);
  43. $('#current-step #command-library .command').hide();
  44. _.each(this.get('methods'), function(method) {
  45. $("#current-step").find("." + method ).show();
  46. });
  47. $(".tutorial .title").html( this.get('title'));
  48. $(".tutorial .text").html(this.get('description'));
  49. }
  50. });
  51. var Tutorial = Backbone.Collection.extend({
  52. prompt: function() {
  53. var currentStep = this.currentStep();
  54. currentStep.prompt(currentStep);
  55. if (currentStep == this.first()) {
  56. $(".tutorial .previous-step").hide();
  57. } else {
  58. $(".tutorial .previous-step").show();
  59. }
  60. },
  61. model: Step,
  62. currentStep: function() {
  63. var currentStep = window.localStorage.getItem('current-step');
  64. if (currentStep == undefined || isNaN(currentStep)) {
  65. currentStep = 0;
  66. window.localStorage.setItem("current-step", 0);
  67. } else {
  68. currentStep = parseInt(currentStep);
  69. }
  70. return this.at(currentStep);
  71. },
  72. moveStep: function(displacement) {
  73. var currentStep = this.currentStep();
  74. currentStep.undraw();
  75. var tutorial = this;
  76. var stepIndex = parseInt(window.localStorage.getItem('current-step'), 10);
  77. if((currentStep == this.first() && displacement < 0)|| (currentStep == this.last() && displacement > 0)) {
  78. Stage.dino.animate({x: Stage.position.x, y: Stage.position.y}, 0, 'linear', function() {
  79. setTimeout(function() {tutorial.prompt()},400);
  80. $(".nestedCommands").remove();
  81. $("#command-area > .command-list").html('');
  82. });
  83. } else {
  84. Stage.dino.animate({x: Stage.position.x, y: Stage.position.y}, 0, 'linear', function() {
  85. setTimeout(function() {tutorial.prompt()},400);
  86. window.localStorage.setItem("current-step", stepIndex + displacement);
  87. $(".nestedCommands").remove();
  88. $("#command-area > .command-list").html('');
  89. });
  90. }
  91. },
  92. runSpec: function() {
  93. if (this.currentStep().get('spec')()) {
  94. this.moveStep(1);
  95. this.currentStep().success();
  96. }
  97. }
  98. });
  99. var tutorial = new Tutorial([
  100. {
  101. title: "First Step",
  102. description: "Hello and welcome to hopscotch!<br/><br/>"+
  103. "Try figuring out how to move Daisy so that she stops in the center of the star.",
  104. spec: function() {
  105. return (Stage.dino.attr('x') >= 150);
  106. },
  107. draw: function(model) {
  108. model.set("elements", model.star(0,-80));
  109. },
  110. methods: ["move"]
  111. },
  112. {
  113. title: "Reach for the clouds!",
  114. description: "Now the circle is a little higher. Use the jump method to reach it.",
  115. spec: function() {
  116. var gotSteps = _.map($('.program .command .name'), function(command){return $(command).html()});
  117. var x = 50;
  118. // Cheating and assuming they only move forward
  119. var hitTheStar = false;
  120. _.map(gotSteps, function(step) {
  121. if (step == "move") {
  122. x += 100;
  123. } else if (step == "jump" && x == 150) {
  124. hitTheStar = true;
  125. }
  126. });
  127. return hitTheStar;
  128. },
  129. draw: function(model) {
  130. model.set('elements', model.star(0,-170));
  131. },
  132. methods: ["move", "jump"]
  133. },
  134. {
  135. title: "Make daisy dizzy",
  136. description: "Make daisy spin five times.",
  137. spec: function() {
  138. var numSpins = _.foldl($('.program .command .name'), function(memo, command) {
  139. if ($(command).html() == 'spin') {
  140. return memo + 1;
  141. } else {
  142. return memo;
  143. }
  144. }, 0);
  145. return (numSpins > 4);
  146. },
  147. draw: function(model) {},
  148. methods: ["move", "jump", "spin"]
  149. },
  150. {
  151. title: "Loop-de-loop",
  152. description: "Try making Daisy spin 5 times while only using the spin method once. Hint: put the spin inside the repeat 5.",
  153. spec: function() {
  154. var numLoops = _.foldl($('.program .command .name'), function(memo, command) {
  155. if ($(command).html() == 'repeat') {
  156. return memo + 1;
  157. } else {
  158. return memo;
  159. }
  160. }, 0);
  161. var totalSpins = _.foldl($('.program .command .name'), function(memo, command) {
  162. if ($(command).html() == 'spin') {
  163. return memo + 1;
  164. } else {
  165. return memo;
  166. }
  167. }, 0);
  168. var numLoopSpins = _.foldl($('.nestedCommands .command .name'), function(memo, command) {
  169. if ($(command).html() == 'spin') {
  170. return memo + 1;
  171. } else {
  172. return memo;
  173. }
  174. }, 0);
  175. return (totalSpins == 1 && numLoopSpins == 1 && numLoops > 0);
  176. },
  177. draw: function(model) {},
  178. methods: ["move", "jump", "spin", "loop"]
  179. },
  180. {
  181. title: "Control Daisy yourself",
  182. description: "Here's something new: when. If you put a method inside when it will run every time you shake (or touch). Try moving Daisy to the end of the screen using only when.",
  183. spec: function() {
  184. var numWhen = _.foldl($('.program .command .name'), function(memo, command) {
  185. if ($(command).html() == 'when') {
  186. return memo + 1;
  187. } else {
  188. return memo;
  189. }
  190. }, 0);
  191. var numNestedMove = _.foldl($('.nestedCommands .command .name'), function(memo, command) {
  192. if ($(command).html() == 'move') {
  193. return memo + 1;
  194. } else {
  195. return memo;
  196. }
  197. }, 0);
  198. var unNestedMove = _.foldl($('#command-area .command .name'), function(memo, command) {
  199. if ($(command).html() == 'move') {
  200. return memo + 1;
  201. } else {
  202. return memo;
  203. }
  204. }, 0);
  205. var hitStar = false;
  206. if (Stage.dino.attr('x') > 730) {
  207. hitStar = true;
  208. } else if (numWhen > 0 && numNestedMove > 0 && unNestedMove == 0) {
  209. setTimeout(function() {
  210. tutorial.runSpec()
  211. }, 1000);
  212. }
  213. return hitStar;
  214. },
  215. draw: function(model) {
  216. model.set('elements', model.star(580,-80));
  217. },
  218. methods: ["move", "jump", "spin", "loop", "when"]
  219. }
  220. ]);
  221. $(function() {
  222. tutorial.prompt();
  223. $(".tutorial .previous-step").bind("click", function(e) {
  224. e.preventDefault();
  225. tutorial.moveStep(-1);
  226. });
  227. });
  228. // For development purposes
  229. window.resetTutorial = function() {
  230. window.localStorage.setItem("current-step", 0);
  231. }
  232. // $.extend({}, Step_old, {
  233. // title: "Moonwalk to the sun",
  234. // description: "Try turning the dino around and walking backwards- it can moonwalk! See if you can moonwalk the dino all the way to the sun and make him big enough to touch it.",
  235. // spec: function() {
  236. // var height = Stage.dino.attr('height');
  237. // var x = Stage.dino.attr('x');
  238. // if (x > 680 && height > 140 ) {
  239. // var numTurns = _.foldl($('.program .command .name'), function(memo, command) {
  240. // if ($(command).html() == 'turn') {
  241. // return memo + 1;
  242. // } else {
  243. // return memo;
  244. // }
  245. // }, 0);
  246. // var numBackward = _.foldl($('.program .command .args option:selected'), function(memo, command) {
  247. // if ($(command).html() == 'Backward') {
  248. // return memo + 1;
  249. // } else {
  250. // return memo;
  251. // }
  252. // }, 0);
  253. // if (numTurns%2 == 1 && numBackward > 6) {
  254. // return true
  255. // } else {
  256. // return false
  257. // }
  258. // } else {
  259. // return false
  260. // }
  261. // },
  262. // draw: function() {
  263. // this.elements = [
  264. // ];
  265. // }
  266. // }),
  267. // $.extend({}, Step_old, {
  268. // title: "Great Work!",
  269. // description: "<h1>OK, you've mastered all we can teach you. Make Daisy do a dance!</h1>"
  270. // })