not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

642 lines
23 KiB

  1. define([
  2. "sugar-web/activity/activity",
  3. "sugar-web/env",
  4. "sugar-web/graphics/icon",
  5. "webL10n",
  6. "sugar-web/graphics/presencepalette",
  7. "toolpalette",
  8. "humane"
  9. ], function (activity, env, icon, webL10n, presencepalette, toolpalette, humane) {
  10. // Manipulate the DOM only when it is ready.
  11. requirejs(['domReady!'], function (doc) {
  12. activity.setup();
  13. // initiating the level palette (for easy/ medium/ hard)
  14. var levelButton = document.getElementById("level-button");
  15. var levels = [
  16. {"id": 1, "title": webL10n.get("easy")},
  17. {"id": 2, "title": webL10n.get("medium")},
  18. {"id": 3, "title": webL10n.get("hard")}
  19. ];
  20. levelpalette = new toolpalette.FilterPalette(levelButton, undefined);
  21. levelpalette.setCategories(levels);
  22. levelpalette.addEventListener('filter', function () {
  23. setLevel(levelpalette.getFilter());
  24. levelpalette.popDown();
  25. });
  26. // initiating the filter palette (for add/ sub/ multiplication)
  27. var filterButton = document.getElementById("filter-button");
  28. var filter = [
  29. {"id": 1, "title": "+"},
  30. {"id": 2, "title": "-"},
  31. {"id": 3, "title": "x"},
  32. {"id": 4, "title": "+ / x / -"}
  33. ];
  34. fpalette = new toolpalette.FilterPalette(filterButton, undefined);
  35. fpalette.setCategories(filter);
  36. fpalette.addEventListener('filter', function () {
  37. setOperation(fpalette.getFilter());
  38. fpalette.popDown();
  39. });
  40. // initializing network palette
  41. // Link presence palette
  42. var presence = null;
  43. var isHost = false;
  44. var networkpalette = new presencepalette.PresencePalette(document.getElementById("network-button"), undefined);
  45. networkpalette.addEventListener('shared', function () {
  46. networkpalette.popDown();
  47. presence = activity.getPresenceObject(function (error, network) {
  48. if (error) {
  49. console.log("Sharing error");
  50. return;
  51. }
  52. network.createSharedActivity('org.sugarlabs.SprintMath', function (groupId) {
  53. console.log("Activity shared");
  54. // disable toolbar buttons functionally
  55. hidetoolbarbuttons();
  56. isHost = true;
  57. });
  58. network.onDataReceived(onNetworkDataReceived);
  59. network.onSharedActivityUserChanged(onNetworkUserChanged);
  60. });
  61. });
  62. // Initialize the activity.
  63. var play = false; // whether the game is playing (True) or ended (False)
  64. var score; // score of the user in the game
  65. var action; // instance of the interval
  66. var time; // time remaining in the game
  67. var questions = []; // array to hold all 200 random questions
  68. var questionNumber = 0; // index of current question
  69. var gameLevel = "easy"; // game level (easy/med/hard)
  70. var gameOperation = 1; // game operation (add/sub/multiply)
  71. var gameOverMessages = []; // in case of presence stores all game over messages
  72. var gamePlaying = []; // in case of presence stores all users that are playing
  73. var restart= false;
  74. // function to hide a particular DOM element
  75. function hide(Id) {
  76. document.getElementById(Id).style.display = "none";
  77. }
  78. // function to show a particular DOM element
  79. function show(Id) {
  80. document.getElementById(Id).style.display = "block";
  81. }
  82. // function to run when game over
  83. function gameOver() {
  84. clearInterval(action);
  85. document.getElementById("timeremaining").innerHTML = 60;
  86. hide("time");
  87. hide("correct");
  88. hide("score");
  89. hide("wrong");
  90. hide("box1");
  91. hide("box2");
  92. hide("box3");
  93. hide("box4");
  94. show("gameOver");
  95. setGameOverMessage();
  96. play = false;
  97. restart= true;
  98. if(!play && presence && isHost){
  99. hidetoolbarbuttons();
  100. }
  101. }
  102. // to set game over message after game is finished
  103. function setGameOverMessage() {
  104. if (presence) {
  105. presence.sendMessage(presence.getSharedInfo().id, {
  106. user: presence.getUserInfo(),
  107. content: {
  108. action: 'gameover',
  109. data: score
  110. }
  111. });
  112. gameOverMessages.push({"user": currentenv.user, "score": score});
  113. showAllUserScores();
  114. } else {
  115. document.getElementById("gameOver").innerHTML = webL10n.get("GameOver", {
  116. name: currentenv.user.name,
  117. score: score
  118. });
  119. document.getElementById("gameOver").style.backgroundColor = currentenv.user.colorvalue.stroke;
  120. document.getElementById("gameOver").style.color = currentenv.user.colorvalue.fill;
  121. }
  122. document.getElementById("question").innerHTML = '';
  123. for (var i = 1; i < 5; i++) {
  124. document.getElementById("box" + i).innerHTML = '';
  125. }
  126. }
  127. // to show all presence user scores
  128. function showAllUserScores() {
  129. var div = document.createElement("div");
  130. for (i = 0; i < gameOverMessages.length; i++) {
  131. var div_child = document.createElement("div");
  132. div_child.innerHTML = webL10n.get("GameOver", {
  133. name: gameOverMessages[i].user.name,
  134. score: gameOverMessages[i].score
  135. });
  136. div_child.style.backgroundColor= gameOverMessages[i].user.colorvalue.stroke;
  137. div_child.style.color= gameOverMessages[i].user.colorvalue.fill;
  138. div.appendChild(div_child)
  139. }
  140. for (i=0;i<gamePlaying.length;i++){
  141. var div_child = document.createElement("div");
  142. div_child.innerHTML = webL10n.get("GamePlaying", {
  143. name: gamePlaying[i].name
  144. });
  145. div_child.style.backgroundColor= gamePlaying[i].colorvalue.stroke;
  146. div_child.style.color= gamePlaying[i].colorvalue.fill;
  147. div.appendChild(div_child)
  148. }
  149. document.getElementById("gameOver").innerHTML = '';
  150. document.getElementById("gameOver").appendChild(div);
  151. }
  152. // starts the timer
  153. function startCountdown() {
  154. action = setInterval(function () {
  155. time -= 1;
  156. document.getElementById("timeremaining").innerHTML = time;
  157. if (time == 0) {
  158. gameOver();
  159. }
  160. }, 1000);
  161. }
  162. // setting event listeners on answer boxes
  163. for (var i = 1; i < 5; i++) {
  164. document.getElementById("box" + i).onclick = function () {
  165. var Correctans = questions[questionNumber].answer;
  166. if (play) {
  167. if (this.innerHTML == Correctans) {
  168. score++;
  169. document.getElementById("scorevalue").innerHTML = score;
  170. hide("wrong");
  171. show("correct");
  172. setTimeout(function () {
  173. hide("correct");
  174. }, 1000);
  175. // generateQuestion();
  176. questionNumber++;
  177. displayCurrentQuestion();
  178. } else {
  179. show("wrong");
  180. hide("correct");
  181. setTimeout(function () {
  182. hide("wrong");
  183. }, 1000);
  184. }
  185. }
  186. }
  187. }
  188. // function to start a new game
  189. function startGame() {
  190. clearInterval(action);
  191. score = 0;
  192. play = true;
  193. time = 60;
  194. questionNumber = 0;
  195. document.getElementById("scorevalue").innerHTML = score;
  196. hide("gameOver");
  197. show("time");
  198. show("box1");
  199. show("box2");
  200. show("box3");
  201. show("box4");
  202. show("score");
  203. startCountdown();
  204. if (!presence) {
  205. questions = [];
  206. generateQuestions();
  207. }
  208. else if(isHost) {
  209. gameOverMessages=[];
  210. gamePlaying=[];
  211. gamePlaying.push(currentenv.user);
  212. }
  213. if(restart && !isHost){
  214. gamePlaying.push(currentenv.user)
  215. adduser();
  216. }
  217. // disable toolbar buttons in case of presence and display question
  218. if(play && presence){
  219. if(isHost){
  220. questions=[]
  221. generateQuestions()
  222. }
  223. // disable toolbar buttons functionally
  224. hidetoolbarbuttons();
  225. displayCurrentQuestion();
  226. }
  227. }
  228. // function to resume an old game
  229. function resumeGame() {
  230. document.getElementById("scorevalue").innerHTML = score;
  231. document.getElementById("timeremaining").innerHTML = time;
  232. show("time");
  233. startCountdown();
  234. displayCurrentQuestion();
  235. }
  236. // generate questions (will generate 200 questions at the start of the game)
  237. function generateQuestions() {
  238. for (i = 0; i < 200; i++) {
  239. // level factor decides which questions will be taken
  240. var levelFactor = 5;
  241. // levels logic
  242. if (gameLevel === 'easy') levelFactor = 5;
  243. else if (gameLevel === 'medium') levelFactor = 7;
  244. else if (gameLevel === 'hard') levelFactor = 10;
  245. // operation logic
  246. var z = 1;
  247. if (gameOperation === 4) {
  248. z = 1 + Math.round(3 * Math.random());
  249. } else {
  250. z = gameOperation;
  251. }
  252. var x = 1 + Math.round((levelFactor - 1) * Math.random());
  253. var y = 1 + Math.round((levelFactor - 1) * Math.random());
  254. var currentQues, currentAns;
  255. if (z === 1) {
  256. currentAns = x + y;
  257. currentQues = x + "+" + y;
  258. } else if (z === 2) {
  259. if (x >= y) {
  260. currentAns = x - y;
  261. currentQues = x + "-" + y;
  262. } else {
  263. currentAns = y - x;
  264. currentQues = y + "-" + x;
  265. }
  266. } else {
  267. currentAns = x * y;
  268. currentQues = x + "x" + y;
  269. }
  270. var choices = [currentAns];
  271. for (var j = 1; j < 4; j++) {
  272. var wrongans;
  273. do {
  274. if (gameOperation === 1 || gameOperation === 2) wrongans = (1 + Math.round((levelFactor + levelFactor) * Math.random()));
  275. else wrongans = (1 + Math.round((levelFactor * levelFactor) * Math.random()));
  276. } while (choices.indexOf(wrongans) > -1);
  277. choices.push(wrongans);
  278. }
  279. shuffleArray(choices);
  280. questions.push({
  281. "question": currentQues,
  282. "answer": currentAns,
  283. "choices": choices
  284. })
  285. }
  286. if(presence && isHost){
  287. presence.sendMessage(presence.getSharedInfo().id, {
  288. user: presence.getUserInfo(),
  289. content: {
  290. action: 'init',
  291. data: questions,
  292. gameover: gameOverMessages,
  293. gameplaying: gamePlaying
  294. }
  295. });
  296. }
  297. displayCurrentQuestion();
  298. }
  299. // shuffle array
  300. function shuffleArray(array) {
  301. for (var i = array.length - 1; i > 0; i--) {
  302. var j = Math.floor(Math.random() * (i + 1));
  303. var temp = array[i];
  304. array[i] = array[j];
  305. array[j] = temp;
  306. }
  307. }
  308. // set current question (will set the current question in the html DOM)
  309. function displayCurrentQuestion() {
  310. var CurrentQues = questions[questionNumber].question;
  311. var choices = questions[questionNumber].choices;
  312. // display question
  313. document.getElementById("question").innerHTML = CurrentQues;
  314. // display answers
  315. for (var i = 1; i < 5; i++) {
  316. document.getElementById("box" + i).innerHTML = choices[i - 1];
  317. }
  318. }
  319. document.getElementById("restart-button").onclick = startGame;
  320. // Sugar functions
  321. document.getElementById("stop-button").addEventListener('click', function (event) {
  322. console.log("writing...");
  323. object_store = {
  324. "play": play,
  325. "score": score,
  326. "timeremaining": time,
  327. "questions": questions,
  328. "questionNumber": questionNumber,
  329. "gameLevel": gameLevel,
  330. "gameOperation": gameOperation
  331. };
  332. var jsonData = JSON.stringify(object_store);
  333. activity.getDatastoreObject().setDataAsText(jsonData);
  334. activity.getDatastoreObject().save(function (error) {
  335. if (error === null) {
  336. console.log("write done.");
  337. } else {
  338. console.log("write failed.");
  339. }
  340. });
  341. });
  342. env.getEnvironment(function (err, environment) {
  343. currentenv = environment;
  344. var fill = currentenv.user.colorvalue.fill;
  345. var stroke = currentenv.user.colorvalue.stroke;
  346. setColor(fill, stroke);
  347. var defaultLanguage = (typeof chrome != 'undefined' && chrome.app && chrome.app.runtime) ? chrome.i18n.getUILanguage() : navigator.language;
  348. var language = environment.user ? environment.user.language : defaultLanguage;
  349. webL10n.language.code = language;
  350. // Load from datastore
  351. if (!environment.objectId) {
  352. startGame();
  353. } else {
  354. activity.getDatastoreObject().loadAsText(function (error, metadata, data) {
  355. if (error == null && data != null) {
  356. stored_data = JSON.parse(data);
  357. play = stored_data.play;
  358. score = stored_data.score;
  359. time = stored_data.timeremaining;
  360. questions = stored_data.questions;
  361. questionNumber = stored_data.questionNumber;
  362. gameLevel = stored_data.gameLevel;
  363. gameOperation = stored_data.gameOperation;
  364. if (play && time>0) {
  365. resumeGame()
  366. } else {
  367. startGame()
  368. }
  369. } else {
  370. console.log(error);
  371. }
  372. });
  373. }
  374. if (environment.sharedId) {
  375. // disable toolbar buttons functionally
  376. hidetoolbarbuttons();
  377. presence = activity.getPresenceObject(function (error, network) {
  378. network.onDataReceived(onNetworkDataReceived);
  379. network.onSharedActivityUserChanged(onNetworkUserChanged);
  380. });
  381. }
  382. });
  383. window.addEventListener("localized", function () {
  384. // Set current language to Sugarizer
  385. document.getElementById("timeString").innerHTML = webL10n.get("Time");
  386. document.getElementById("scoreString").innerHTML = webL10n.get("Score");
  387. document.getElementById("correct").innerHTML = webL10n.get("correct");
  388. document.getElementById("wrong").innerHTML = webL10n.get("wrong");
  389. var levels = [
  390. {"id": 1, "title": webL10n.get("easy")},
  391. {"id": 2, "title": webL10n.get("medium")},
  392. {"id": 3, "title": webL10n.get("hard")}
  393. ];
  394. levelpalette.setCategories(levels);
  395. });
  396. // network callback
  397. var onNetworkDataReceived = function (msg) {
  398. if (presence.getUserInfo().networkId === msg.user.networkId) {
  399. return;
  400. }
  401. switch (msg.content.action) {
  402. case 'init':
  403. if(gamePlaying.length===0) {
  404. questions = msg.content.data;
  405. gameOverMessages = msg.content.gameover;
  406. gamePlaying = msg.content.gameplaying;
  407. startGame();
  408. }
  409. break;
  410. case 'adduser':
  411. // add user
  412. gamePlaying= msg.content.data;
  413. showAllUserScores();
  414. break;
  415. case 'removeuser':
  416. // remove user
  417. gamePlaying= msg.content.data;
  418. if(gamePlaying.length===0 && isHost) showtoolbarbuttons();
  419. showAllUserScores();
  420. break;
  421. case 'gameover':
  422. // remove user from playing array
  423. gamePlaying = gamePlaying.filter(function (user) {
  424. return user.name !== msg.user.name
  425. });
  426. if (presence) {
  427. presence.sendMessage(presence.getSharedInfo().id, {
  428. user: presence.getUserInfo(),
  429. content: {
  430. action: 'removeuser',
  431. data: gamePlaying
  432. }
  433. });
  434. }
  435. // add user in game over array
  436. gameOverMessages.push({"user": msg.user, "score": msg.content.data});
  437. showAllUserScores();
  438. break;
  439. }
  440. };
  441. var onNetworkUserChanged = function (msg) {
  442. if (isHost) {
  443. presence.sendMessage(presence.getSharedInfo().id, {
  444. user: presence.getUserInfo(),
  445. content: {
  446. action: 'init',
  447. data: questions,
  448. gameover: gameOverMessages,
  449. gameplaying: gamePlaying
  450. }
  451. });
  452. if(msg.move === 1) {
  453. gamePlaying.push(msg.user);
  454. adduser();
  455. }
  456. if(msg.move===-1) {
  457. gamePlaying = gamePlaying.filter(function (user) {
  458. return user.name !== msg.user.name
  459. });
  460. removeuser();
  461. }
  462. showAllUserScores();
  463. }
  464. var userName = msg.user.name.replace('<', '&lt;').replace('>', '&gt;');
  465. if(msg.move === 1){
  466. humane.log(webL10n.get("joined", {
  467. name: userName
  468. }));
  469. }else{
  470. humane.log(webL10n.get("left", {
  471. name: userName
  472. }));
  473. }
  474. };
  475. function adduser() {
  476. presence.sendMessage(presence.getSharedInfo().id, {
  477. user: presence.getUserInfo(),
  478. content: {
  479. action: 'adduser',
  480. data: gamePlaying
  481. }
  482. });
  483. }
  484. function removeuser() {
  485. presence.sendMessage(presence.getSharedInfo().id, {
  486. user: presence.getUserInfo(),
  487. content: {
  488. action: 'removeuser',
  489. data: gamePlaying
  490. }
  491. });
  492. }
  493. // function to set color theme based on User Colors
  494. function setColor(fill, stroke) {
  495. // set colors based on user stroke and fill colors
  496. document.getElementById("box1").style.backgroundColor = stroke;
  497. document.getElementById("box2").style.backgroundColor = stroke;
  498. document.getElementById("box3").style.backgroundColor = stroke;
  499. document.getElementById("box4").style.backgroundColor = stroke;
  500. // dynamically change the font color between white and black based on the fill and stroke colors
  501. // to provide better user experience
  502. if (tinycolor(stroke).isLight()) {
  503. document.getElementById("choices").style.color = "black";
  504. // document.getElementById("time_score_container").style.color = "black";
  505. } else {
  506. document.getElementById("choices").style.color = "white";
  507. // document.getElementById("time_score_container").style.color = "white";
  508. }
  509. document.getElementById("container").style.color = fill;
  510. }
  511. // set level
  512. function setLevel(e) {
  513. var level = gameLevel;
  514. if (e === 1) {
  515. level = "easy";
  516. } else if (e === 2) {
  517. level = "medium";
  518. } else if (e === 3) {
  519. level = "hard";
  520. }
  521. if (gameLevel !== level) {
  522. gameLevel = level;
  523. startGame();
  524. }
  525. }
  526. // set operation
  527. function setOperation(e) {
  528. if (gameOperation !== e) {
  529. gameOperation = e;
  530. startGame();
  531. }
  532. }
  533. // show toolbar buttons
  534. function showtoolbarbuttons() {
  535. // enable toolbar buttons functionally
  536. document.getElementById("restart-button").disabled = false;
  537. document.getElementById("filter-button").disabled = false;
  538. document.getElementById("level-button").disabled = false;
  539. document.getElementById("network-button").disabled = false;
  540. // enable toolbar buttons visually
  541. document.getElementById("restart-button").classList.remove('disabled');
  542. document.getElementById("filter-button").classList.remove('disabled');
  543. document.getElementById("level-button").classList.remove('disabled');
  544. document.getElementById("network-button").classList.remove('disabled');
  545. }
  546. // hide toolbar buttons
  547. function hidetoolbarbuttons() {
  548. // disable toolbar buttons functionally
  549. document.getElementById("restart-button").disabled = true;
  550. document.getElementById("filter-button").disabled = true;
  551. document.getElementById("level-button").disabled = true;
  552. document.getElementById("network-button").disabled = true;
  553. // disable toolbar buttons visually
  554. document.getElementById("restart-button").classList.add('disabled');
  555. document.getElementById("filter-button").classList.add('disabled');
  556. document.getElementById("level-button").classList.add('disabled');
  557. document.getElementById("network-button").classList.add('disabled');
  558. }
  559. });
  560. });