Prechádzať zdrojové kódy

now the same ifractions can be used both inside and ouside moodle by setting boolean variable 'moodle'

laira 3 rokov pred
rodič
commit
f5fa48dc3d
10 zmenil súbory, kde vykonal 543 pridanie a 309 odobranie
  1. 2 0
      index.html
  2. 20 7
      js/circleOne.js
  3. 211 199
      js/customMenu.js
  4. 40 22
      js/globals.js
  5. 129 0
      js/integrationFunctions.js
  6. 16 4
      js/map.js
  7. 76 63
      js/menu.js
  8. 12 2
      js/preMenu.js
  9. 20 7
      js/squareOne.js
  10. 17 5
      js/squareTwo.js

+ 2 - 0
index.html

@@ -153,6 +153,8 @@ www.usp.br/line
     <script src="js/squareTwo.js"></script>
     <script src="js/gameMechanics.js"></script>
     <script src="js/globals.js"></script>
+    <!-- MOODLE MODIF. -->
+    <script src="js/integrationFunctions.js"></script>
 
     <script>
       const displayFps = document.getElementById("display-fps");

+ 20 - 7
js/circleOne.js

@@ -30,7 +30,7 @@
  *
  * @namespace
  */
-const circleOne = {
+ const circleOne = {
 
   /**
    * Main code
@@ -80,11 +80,21 @@ const circleOne = {
     this.trace.alpha = 0;
 
     // Calls function that loads navigation icons
-    navigationIcons.func_addIcons(
-      true, true, true, // Left buttons
-      true, false,      // Right buttons
-      'customMenu', this.func_viewHelp
-    );
+
+    // MOODLE MODIF.
+    if (moodle) {
+      navigationIcons.func_addIcons(
+        false, false, false, // Left buttons
+        true, false,         // Right buttons
+        false, false
+      );
+    } else {
+      navigationIcons.func_addIcons(
+        true, true, true, // Left buttons
+        true, false,      // Right buttons
+        'customMenu', this.func_viewHelp
+      );
+    }
 
     // CIRCLES AND FRACTIONS
     this.circles = {
@@ -593,6 +603,9 @@ const circleOne = {
       + ', valCircles: ' + self.divisorsList
       + ' balloonX: ' + self.basket.x
       + ', selIndex: ' + self.fractionIndex;
-    sendToDB(data);
+
+    // MOODLE MODIF.
+    if (moodle) sendToDB(data, self.result, game.timer.elapsed);
+    else sendToDB(data);
   }
 };

+ 211 - 199
js/customMenu.js

@@ -21,239 +21,251 @@ const customMenuState = {
    */
   create: function () {
 
-    const iconScale = 0.7;
-    const baseY = 270 - 40;
-    this.menuIcons = [];
-
-    // Background color
-    game.add.graphic.rect(0, 0, 900, 600, undefined, 0, colors.blueBckg, 1);
-    // Floor
-    for (let i = 0; i < defaultWidth / 100; i++) { game.add.image(i * 100, 501, 'floor'); }
-
-    // Overtitle : Selected game
-    game.add.text(defaultWidth / 2, 40, game.lang.game + ": " + menuState.menuIcons, textStyles.h4_brown);
-    // Title : Customize the selected game
-    game.add.text(defaultWidth / 2, 80, game.lang.custom_game, textStyles.h1_green);
-
-    // Loads navigation icons
-    navigationIcons.func_addIcons(
-      true, false, false,
-      true, true,
-      'menu', false);
-
-    let x = 150;
-    let y = 200 - 40;
-    let width = 5;
-    let height = 280 + 80;
-    let offsetW = 600 / 6;
-    let offsetH, infoIcon;
-
-    // Label 'Game Mode'
-    game.add.text(x + offsetW - 12, y, game.lang.game_mode, textStyles.h2_blue_2);
-
-    infoIcon = game.add.image(x + 2 * offsetW - 30, y - 40, 'info', 0.5, 0.6);
-    infoIcon.anchor(0.5, 0.5);
-    infoIcon.iconType = 'infoIcon';
-    infoIcon.id = 'gameMode';
-    this.menuIcons.push(infoIcon);
-
-    // Label 'Operation'
-    game.add.text(x + 3 * offsetW, y, game.lang.operation, textStyles.h2_blue_2);
-
-    infoIcon = game.add.image(x + 4 * offsetW - 30, y - 40, 'info', 0.5, 0.6);
-    infoIcon.anchor(0.5, 0.5);
-    infoIcon.iconType = 'infoIcon';
-    infoIcon.id = 'gameOperation';
-    this.menuIcons.push(infoIcon);
-
-    // Label 'Difficulty'
-    game.add.text(x + 5 * offsetW, y, game.lang.difficulty, textStyles.h2_blue_2);
-
-    infoIcon = game.add.image(x + 6 * offsetW - 30, y - 40, 'info', 0.5, 0.6);
-    infoIcon.anchor(0.5, 0.5);
-    infoIcon.iconType = 'infoIcon';
-    infoIcon.id = 'gameDifficulty';
-    this.menuIcons.push(infoIcon);
-
-    // Horizontal line
-    game.add.graphic.rect(x - 25, y + 10, 600 + 50, width, undefined, 0, colors.blueMenuLine).anchor(0, 0.5);
-    // Vertical lines
-    game.add.graphic.rect(x + 2 * offsetW, y - 25, width, height, undefined, 0, colors.blueMenuLine).anchor(0.5, 0);
-    game.add.graphic.rect(x + 4 * offsetW, y - 25, width, height, undefined, 0, colors.blueMenuLine).anchor(0.5, 0);
-
-    // --------------------------- TURN ON/OFF FRACTION LABELS / RECTANGLE GUIDE
-
-    // Horizontal line
-    game.add.graphic.rect(x + 4 * offsetW, y + 136, 200 + 25, width, undefined, 0, colors.blueMenuLine).anchor(0, 0.5);
-
-    // Label 'Show Fractions / Auxiliar rectangles'
-    game.add.text(x + 5 * offsetW, y + 102, game.lang.show, textStyles.h4_blue_2);
-
-    infoIcon = game.add.image(x + 6 * offsetW + 20, y + 102, 'info', 0.5, 0.6);
-    infoIcon.anchor(0.5, 0.5);
-    infoIcon.iconType = 'infoIcon';
-    infoIcon.id = 'gameMisc';
-    this.menuIcons.push(infoIcon);
-
-    let auxText;
-    if (gameTypeString == 'squareTwo') {
-      auxText = game.lang.aux_rectangle;
-      game.add.text(x + 5 * offsetW + 10, y + 102 + 24, auxText, textStyles.h4_blue_2);
+    // MOODLE MODIF.
+    if (moodle && iLMparameters.iLM_PARAM_SendAnswer == 'false') {
+      game.state.start('map');
     } else {
-      auxText = game.lang.title;
-      game.add.text(x + 5 * offsetW, y + 102 + 24, auxText, textStyles.h2_blue_2);
-    }
 
-    // Selection box
-    y += 40;
-    const frame = (fractionLabel) ? 1 : 0;
+      const iconScale = 0.7;
+      const baseY = 270 - 40;
+      this.menuIcons = [];
+
+      // Background color
+      game.add.graphic.rect(0, 0, 900, 600, undefined, 0, colors.blueBckg, 1);
+      // Floor
+      for (let i = 0; i < defaultWidth / 100; i++) { game.add.image(i * 100, 501, 'floor'); }
+
+      // Overtitle : Selected game
+      game.add.text(defaultWidth / 2, 40, game.lang.game + ": " + menuState.menuIcons, textStyles.h4_brown);
+      // Title : Customize the selected game
+      game.add.text(defaultWidth / 2, 80, game.lang.custom_game, textStyles.h1_green);
+
+      // Loads navigation icons
+      navigationIcons.func_addIcons(
+        true, false, false,
+        true, true,
+        'menu', false);
+
+      let x = 150;
+      let y = 200 - 40;
+      let width = 5;
+      let height = 280 + 80;
+      let offsetW = 600 / 6;
+      let offsetH, infoIcon;
+
+      // Label 'Game Mode'
+      game.add.text(x + offsetW - 12, y, game.lang.game_mode, textStyles.h2_blue_2);
+
+      infoIcon = game.add.image(x + 2 * offsetW - 30, y - 40, 'info', 0.5, 0.6);
+      infoIcon.anchor(0.5, 0.5);
+      infoIcon.iconType = 'infoIcon';
+      infoIcon.id = 'gameMode';
+      this.menuIcons.push(infoIcon);
+
+      // Label 'Operation'
+      game.add.text(x + 3 * offsetW, y, game.lang.operation, textStyles.h2_blue_2);
+
+      infoIcon = game.add.image(x + 4 * offsetW - 30, y - 40, 'info', 0.5, 0.6);
+      infoIcon.anchor(0.5, 0.5);
+      infoIcon.iconType = 'infoIcon';
+      infoIcon.id = 'gameOperation';
+      this.menuIcons.push(infoIcon);
+
+      // Label 'Difficulty'
+      game.add.text(x + 5 * offsetW, y, game.lang.difficulty, textStyles.h2_blue_2);
+
+      infoIcon = game.add.image(x + 6 * offsetW - 30, y - 40, 'info', 0.5, 0.6);
+      infoIcon.anchor(0.5, 0.5);
+      infoIcon.iconType = 'infoIcon';
+      infoIcon.id = 'gameDifficulty';
+      this.menuIcons.push(infoIcon);
+
+      // Horizontal line
+      game.add.graphic.rect(x - 25, y + 10, 600 + 50, width, undefined, 0, colors.blueMenuLine).anchor(0, 0.5);
+      // Vertical lines
+      game.add.graphic.rect(x + 2 * offsetW, y - 25, width, height, undefined, 0, colors.blueMenuLine).anchor(0.5, 0);
+      game.add.graphic.rect(x + 4 * offsetW, y - 25, width, height, undefined, 0, colors.blueMenuLine).anchor(0.5, 0);
+
+      // --------------------------- TURN ON/OFF FRACTION LABELS / RECTANGLE GUIDE
+
+      // Horizontal line
+      game.add.graphic.rect(x + 4 * offsetW, y + 136, 200 + 25, width, undefined, 0, colors.blueMenuLine).anchor(0, 0.5);
+
+      // Label 'Show Fractions / Auxiliar rectangles'
+      game.add.text(x + 5 * offsetW, y + 102, game.lang.show, textStyles.h4_blue_2);
+
+      infoIcon = game.add.image(x + 6 * offsetW + 20, y + 102, 'info', 0.5, 0.6);
+      infoIcon.anchor(0.5, 0.5);
+      infoIcon.iconType = 'infoIcon';
+      infoIcon.id = 'gameMisc';
+      this.menuIcons.push(infoIcon);
+
+      let auxText;
+      if (gameTypeString == 'squareTwo') {
+        auxText = game.lang.aux_rectangle;
+        game.add.text(x + 5 * offsetW + 10, y + 102 + 24, auxText, textStyles.h4_blue_2);
+      } else {
+        auxText = game.lang.title;
+        game.add.text(x + 5 * offsetW, y + 102 + 24, auxText, textStyles.h2_blue_2);
+      }
+
+      // Selection box
+      y += 40;
+      const frame = (fractionLabel) ? 1 : 0;
 
-    const selectionBox = game.add.sprite(x + 5 * offsetW, y + 102 + 24 - 2, 'select', frame, 0.11);
-    selectionBox.anchor(0.5, 0.5);
-    selectionBox.iconType = 'selectionBox';
-    this.menuIcons.push(selectionBox);
+      const selectionBox = game.add.sprite(x + 5 * offsetW, y + 102 + 24 - 2, 'select', frame, 0.11);
+      selectionBox.anchor(0.5, 0.5);
+      selectionBox.iconType = 'selectionBox';
+      this.menuIcons.push(selectionBox);
 
-    // --------------------------- GAME MODE ICONS
+      // --------------------------- GAME MODE ICONS
 
-    x = 150 + offsetW;
-    y = baseY;
-    offsetH = this.func_getOffset(height, info[gameTypeString].gameModeType.length);
+      x = 150 + offsetW;
+      y = baseY;
+      offsetH = this.func_getOffset(height, info[gameTypeString].gameModeType.length);
 
-    for (let i = 0; i < info[gameTypeString].gameModeTypeUrl.length; i++, y += offsetH) {
-      const icon = game.add.sprite(x, y, info[gameTypeString].gameModeTypeUrl[i], 0, iconScale, 1);
-      icon.anchor(0.5, 0.5);
+      for (let i = 0; i < info[gameTypeString].gameModeTypeUrl.length; i++, y += offsetH) {
+        const icon = game.add.sprite(x, y, info[gameTypeString].gameModeTypeUrl[i], 0, iconScale, 1);
+        icon.anchor(0.5, 0.5);
+
+        icon.gameModeType = info[gameTypeString].gameModeType[i];
+        icon.iconType = 'gameMode';
+        if (i == 0) {
+          gameModeType = icon.gameModeType;
+          icon.curFrame = 1;
+        }
 
-      icon.gameModeType = info[gameTypeString].gameModeType[i];
-      icon.iconType = 'gameMode';
-      if (i == 0) {
-        gameModeType = icon.gameModeType;
-        icon.curFrame = 1;
+        this.menuIcons.push(icon);
       }
 
-      this.menuIcons.push(icon);
-    }
+      // --------------------------- GAME OPERATION ICONS
+
+      x += 2 * offsetW;
+      y = baseY;
+      offsetH = this.func_getOffset(height, info[gameTypeString].gameOperationType.length);
+
+      let icon;
+      let aux = [];
+      aux['squareOne'] = [
+        ['operation_plus', 'Plus'],
+        ['operation_minus', 'Minus']
+      ];
+      aux['circleOne'] = [
+        ['operation_plus', 'Plus'],
+        ['operation_minus', 'Minus'],
+        ['operation_mixed', 'Mixed']
+      ];
+      aux['squareTwo'] = [
+        ['operation_equals', 'Equals'],
+      ];
+
+      // Placing math operation icons
+      for (let i = 0; i < aux[gameTypeString].length; i++, y += offsetH) {
+        icon = game.add.sprite(x, y, aux[gameTypeString][i][0], 0, iconScale, 1);
+        icon.anchor(0.5, 0.5);
+
+        icon.gameOperationType = aux[gameTypeString][i][1];
+        icon.iconType = 'gameOperation';
+
+        if (i == 0) {
+          gameOperationType = icon.gameOperationType;
+          icon.curFrame = 1;
+        }
 
-    // --------------------------- GAME OPERATION ICONS
-
-    x += 2 * offsetW;
-    y = baseY;
-    offsetH = this.func_getOffset(height, info[gameTypeString].gameOperationType.length);
-
-    let icon;
-    let aux = [];
-    aux['squareOne'] = [
-      ['operation_plus', 'Plus'],
-      ['operation_minus', 'Minus']
-    ];
-    aux['circleOne'] = [
-      ['operation_plus', 'Plus'],
-      ['operation_minus', 'Minus'],
-      ['operation_mixed', 'Mixed']
-    ];
-    aux['squareTwo'] = [
-      ['operation_equals', 'Equals'],
-    ];
-
-    // Placing math operation icons
-    for (let i = 0; i < aux[gameTypeString].length; i++, y += offsetH) {
-      icon = game.add.sprite(x, y, aux[gameTypeString][i][0], 0, iconScale, 1);
-      icon.anchor(0.5, 0.5);
-
-      icon.gameOperationType = aux[gameTypeString][i][1];
-      icon.iconType = 'gameOperation';
-
-      if (i == 0) {
-        gameOperationType = icon.gameOperationType;
-        icon.curFrame = 1;
+        this.menuIcons.push(icon);
       }
 
-      this.menuIcons.push(icon);
-    }
+      // --------------------------- DIFFICULTY ICONS
 
-    // --------------------------- DIFFICULTY ICONS
+      x = (gameTypeString == 'squareOne') ? 625 : 585;
+      y = baseY - 25;
 
-    x = (gameTypeString == 'squareOne') ? 625 : 585;
-    y = baseY - 25;
+      for (let i = 0; i < info[gameTypeString].gameDifficulty; i++) {
+        // Parameters
+        const curX = x + (30 + 10) * i;
 
-    for (let i = 0; i < info[gameTypeString].gameDifficulty; i++) {
-      // Parameters
-      const curX = x + (30 + 10) * i;
+        // Difficulty menuIcons
+        const icon = game.add.graphic.rect(curX, y, 30, 30, undefined, 0, colors.gray, 1);
+        icon.anchor(0.5, 0.5);
+        icon.difficulty = i + 1;
+        icon.iconType = 'difficulty';
 
-      // Difficulty menuIcons
-      const icon = game.add.graphic.rect(curX, y, 30, 30, undefined, 0, colors.gray, 1);
-      icon.anchor(0.5, 0.5);
-      icon.difficulty = i + 1;
-      icon.iconType = 'difficulty';
+        if (i == 0) {
+          gameDifficulty = icon.difficulty;
+          icon.fillColor = colors.blue;
+        }
+        this.menuIcons.push(icon);
 
-      if (i == 0) {
-        gameDifficulty = icon.difficulty;
-        icon.fillColor = colors.blue;
+        // Difficulty numbers
+        game.add.text(curX, y + 7, i + 1, textStyles.h4_white);
       }
-      this.menuIcons.push(icon);
 
-      // Difficulty numbers
-      game.add.text(curX, y + 7, i + 1, textStyles.h4_white);
-    }
+      // --------------------------- ENTER ICON
 
-    // --------------------------- ENTER ICON
+      // MOODLE MODIF.
+      if (!moodle) {
 
-    x = defaultWidth - 100;
-    y = defaultHeight - 110;
+        x = defaultWidth - 100;
+        y = defaultHeight - 110;
 
-    const enterIcon = game.add.image(x, y, 'bush');
-    enterIcon.anchor(0.5, 0.5);
-    enterIcon.iconType = 'enter';
+        const enterIcon = game.add.image(x, y, 'bush');
+        enterIcon.anchor(0.5, 0.5);
+        enterIcon.iconType = 'enter';
 
-    this.menuIcons.push(enterIcon);
+        this.menuIcons.push(enterIcon);
 
-    this.enterText = game.add.text(x, y, game.lang.continue, textStyles.h4_white);
+        this.enterText = game.add.text(x, y, game.lang.continue, textStyles.h4_white);
 
-    // --------------------------- INFO BOX
+      }
 
-    this.infoBox = document.getElementById('myModal');
+      // --------------------------- INFO BOX
 
-    // When the user clicks on the 'x', close the modal
-    document.getElementsByClassName('close')[0].onclick = function () {
-      self.infoBox.style.display = 'none';
-    }
+      this.infoBox = document.getElementById('myModal');
 
-    // When the user clicks anywhere outside of the modal, close it
-    window.onclick = function (event) {
-      if (event.target == self.infoBox) {
+      // When the user clicks on the 'x', close the modal
+      document.getElementsByClassName('close')[0].onclick = function () {
         self.infoBox.style.display = 'none';
       }
-    }
 
-    this.infoBoxContent = {
-      gameMode: {
-        title: '<b>' + game.lang.game_mode + '</b>',
-        body: game.lang.infoBox_mode,
-        img: '' // '<center> <img width=300 src="./assets/img/info-box/s1-A.png"> <img width=300 src="./assets/img/info-box/s1-B.png"> </center>'
-      },
-      gameOperation: {
-        title: '<b>' + game.lang.operation + '</b>',
-        body: game.lang.infoBox_oper,
-        img: '<center> <img width=50 src="./assets/img/info-box/operation_plus.png"> ' + game.lang.plus +
-        ' <img width=50 src="./assets/img/info-box/operation_minus.png"> ' + game.lang.minus +
-        ' <img width=50 src="./assets/img/info-box/operation_mixed.png"> ' + game.lang.mixed +
-        ' <img width=50 src="./assets/img/info-box/operation_equals.png"> ' + game.lang.equals + ' </center>',
-      },
-      gameDifficulty: {
-        title: '<b>' + game.lang.difficulty + '</b>',
-        body: game.lang.infoBox_diff,
-        img: '<center> <img width=150 src="./assets/img/info-box/dif-1.png"><img width=150 src="./assets/img/info-box/dif-5.png">'
-      },
-      gameMisc: {
-        title: '<b>' + game.lang.show + ' ' + auxText + '</b>',
-        body: game.lang.infoBox_misc,
-        img: '' //'<center> <img width=300 src="./assets/img/info-box/c1-A.png"> <img width=300 src="./assets/img/info-box/c1-B.png"> </center>',
+      // When the user clicks anywhere outside of the modal, close it
+      window.onclick = function (event) {
+        if (event.target == self.infoBox) {
+          self.infoBox.style.display = 'none';
+        }
       }
-    };
 
-    // ------------- EVENTS
+      this.infoBoxContent = {
+        gameMode: {
+          title: '<b>' + game.lang.game_mode + '</b>',
+          body: game.lang.infoBox_mode,
+          img: '' // '<center> <img width=300 src="./assets/img/info-box/s1-A.png"> <img width=300 src="./assets/img/info-box/s1-B.png"> </center>'
+        },
+        gameOperation: {
+          title: '<b>' + game.lang.operation + '</b>',
+          body: game.lang.infoBox_oper,
+          img: '<center> <img width=50 src="./assets/img/info-box/operation_plus.png"> ' + game.lang.plus +
+            ' <img width=50 src="./assets/img/info-box/operation_minus.png"> ' + game.lang.minus +
+            ' <img width=50 src="./assets/img/info-box/operation_mixed.png"> ' + game.lang.mixed +
+            ' <img width=50 src="./assets/img/info-box/operation_equals.png"> ' + game.lang.equals + ' </center>',
+        },
+        gameDifficulty: {
+          title: '<b>' + game.lang.difficulty + '</b>',
+          body: game.lang.infoBox_diff,
+          img: '<center> <img width=150 src="./assets/img/info-box/dif-1.png"><img width=150 src="./assets/img/info-box/dif-5.png">'
+        },
+        gameMisc: {
+          title: '<b>' + game.lang.show + ' ' + auxText + '</b>',
+          body: game.lang.infoBox_misc,
+          img: '' //'<center> <img width=300 src="./assets/img/info-box/c1-A.png"> <img width=300 src="./assets/img/info-box/c1-B.png"> </center>',
+        }
+      };
+
+      // ------------- EVENTS
 
-    game.event.add('click', this.func_onInputDown);
-    game.event.add('mousemove', this.func_onInputOver);
+      game.event.add('click', this.func_onInputDown);
+      game.event.add('mousemove', this.func_onInputOver);
+
+    }
 
   },
 

+ 40 - 22
js/globals.js

@@ -80,6 +80,13 @@ let gameDifficulty;
  * @type {boolean}
  */
 const debugMode = false;
+// MOODLE MODIF.
+/**
+ * defines if the game is suposed to run online or on moodle
+ * if true, on moodle
+ * if false, online
+ */
+const moodle = false;
 /**
  * Turns game audio ON/OFF
  * @type {boolean}
@@ -253,7 +260,7 @@ const textStyles = {
   h2_brown: { font: '26px Arial,sans-serif', fill: colors.darkRed, align: 'center' }, // Map difficulty label
   h4_brown: { font: '20px Arial,sans-serif', fill: colors.darkRed, align: 'center' }, // Menu overtitle
   p_brown: { font: '14px Arial,sans-serif', fill: colors.darkRed, align: 'center' }, // Map difficulty label
-  
+
   h2_blue_2: { font: '26px Arial,sans-serif', fill: colors.blue, align: 'center' }, // Menu subtitle
   h4_blue_2: { font: '20px Arial,sans-serif', fill: colors.blue, align: 'center' }, // Menu subtitle
   h2_blue: { font: '26px Arial,sans-serif', fill: colors.darkBlue, align: 'center' }, // Fractions
@@ -536,34 +543,45 @@ const navigationIcons = {
  */
 const sendToDB = function (extraData) {
 
-  // Create some variables we need to send to our PHP file
-  // Attention: this names must be compactible to data table (MySQL server)
-  // @see php/save.php
-  const data = 'line_ip=143.107.45.11' // INSERT database server IP
-    + '&line_name=' + playerName
-    + '&line_lang=' + langstring
-    + extraData;
+  // MOODLE MODIF.
+  if (moodle) {
+
+    if (self.result) moodleVar.hits[mapPosition - 1]++;
+    else moodleVar.errors[mapPosition - 1]++;
+
+    moodleVar.time[mapPosition - 1] += game.timer.elapsed;
+
+  } else {
 
-  const url = 'php/save.php';
+    // Create some variables we need to send to our PHP file
+    // Attention: this names must be compactible to data table (MySQL server)
+    // @see php/save.php
+    const data = 'line_ip=143.107.45.11' // INSERT database server IP
+      + '&line_name=' + playerName
+      + '&line_lang=' + langstring
+      + extraData;
 
-  const hr = new XMLHttpRequest();
+    const url = 'php/save.php';
 
-  hr.open('POST', url, true);
+    const hr = new XMLHttpRequest();
 
-  hr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+    hr.open('POST', url, true);
 
-  hr.onreadystatechange = function () {
-    if (debugMode) console.log(hr);
-    if (hr.readyState == 4 && hr.status == 200) {
-      if (debugMode) console.log(hr.responseText);
+    hr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+
+    hr.onreadystatechange = function () {
+      if (debugMode) console.log(hr);
+      if (hr.readyState == 4 && hr.status == 200) {
+        if (debugMode) console.log(hr.responseText);
+      }
     }
-  }
 
-  hr.send(data); // Actually execute the request
+    hr.send(data); // Actually execute the request
 
-  if (debugMode) {
-    console.log('processing...');
-    console.log(data);
-  }
+    if (debugMode) {
+      console.log('processing...');
+      console.log(data);
+    }
 
+  }
 };

+ 129 - 0
js/integrationFunctions.js

@@ -0,0 +1,129 @@
+// MOODLE MODIF.
+
+console.log("integrationFunctions.js: start.");
+
+const moodleVar = {
+  hits: [0,0,0,0],
+  errors: [0,0,0,0],
+  time: [0,0,0,0]
+}
+
+let getParameterByName = function (name) {
+  var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
+  return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : null;
+}
+
+const iLMparameters = {
+  iLM_PARAM_ServerToGetAnswerURL: getParameterByName("iLM_PARAM_ServerToGetAnswerURL"),
+  iLM_PARAM_SendAnswer: getParameterByName("iLM_PARAM_SendAnswer"),
+  iLM_PARAM_AssignmentURL: getParameterByName("iLM_PARAM_AssignmentURL"),
+  iLM_PARAM_Assignment: getParameterByName("iLM_PARAM_Assignment"),
+  lang: getParameterByName("lang")
+};
+
+function getAnswer() {
+  console.log("integrationFunctions.js: start getAnswer()");
+  let str = '';
+  if (iLMparameters.iLM_PARAM_SendAnswer == 'false') { // professor
+    str += 'gameTypeString:' + gameTypeString
+      + '\ngameShape:' + gameShape
+      + '\ngameModeType:' + gameModeType
+      + '\ngameOperationType:' + gameOperationType
+      + '\ngameDifficulty:' + gameDifficulty
+      + '\nfractionLabel:' + fractionLabel
+      + '\nresults:';
+    for (let i = 0; i < moodleVar.hits.length; i++) {
+      str += '{level:' + (i + 1)
+        + ',hits:' + moodleVar.hits[i]
+        + ',errors:' + moodleVar.errors[i]
+        + ',timeElapsed:' + moodleVar.time[i]
+        + '}';
+    }
+  } else { // professor
+    if (!gameType) {
+      alert("Erro: Você precisa escolher pelo menos um jogo");
+      return x;
+    }
+
+    moodleVar.hits = [0, 0, 0, 0];
+    moodleVar.errors = [0, 0, 0, 0];
+    moodleVar.time = [0, 0, 0, 0];
+
+    str += 'gameTypeString:' + gameTypeString
+      + '\ngameShape:' + gameShape
+      + '\ngameModeType:' + gameModeType
+      + '\ngameOperationType:' + gameOperationType
+      + '\ngameDifficulty:' + gameDifficulty
+      + '\nfractionLabel:' + fractionLabel;
+  }
+  console.log("-----------------");
+  console.log(str); 
+  console.log("-----------------");
+
+  console.log("integrationFunctions.js: end getAnswer()");
+  return str;
+}
+
+function getEvaluation() {
+  if (iLMparameters.iLM_PARAM_SendAnswer == 'false') { // aluno
+    const nota = 1;
+    parent.getEvaluationCallback(nota);
+    return nota;
+  }
+}
+
+function decodificaArquivo(text) {
+  let gameInfo = {};
+  let line = text.split('\n');
+  line.forEach(cur => {
+    try {
+      let newline = cur.split(':');
+      const chave = newline[0].replace(/^\s+|\s+$/g, '');
+      const valor = newline[1].replace(/^\s+|\s+$/g, '');
+      gameInfo[chave.trim()] = valor.trim();
+    } catch (Error) { if (debugMode) console.log('Sintax error'); }
+  });
+  gameTypeString = gameInfo['gameTypeString'];
+  gameShape = gameInfo['gameShape'];
+  gameModeType = gameInfo['gameModeType'];
+  gameOperationType = gameInfo['gameOperationType'];
+  gameDifficulty = parseInt(gameInfo['gameDifficulty']);
+  fractionLabel = gameInfo['fractionLabel'];
+  console.log("decodificaArquivo:", gameTypeString, gameShape, gameModeType, gameOperationType, gameDifficulty, fractionLabel);
+  mapPosition = 0; // Map position
+  mapMove = true; // Move no next point
+  completedLevels = 0; // Reset the game progress when entering a new level
+
+  if (iLMparameters.iLM_PARAM_SendAnswer == 'false') { // aluno
+    iLMparameters.return_get_answer = 1;
+    iLMparameters.iLM_PARAM_ActivityEvaluation = ((mapPosition == 4) ? 1 : 0);
+    iLMparameters.iLM_PARAM_ArchiveContent = text;
+  } else { // professor
+    iLMparameters.iLM_PARAM_ActivityEvaluation = 0;
+    iLMparameters.iLM_PARAM_ArchiveContent = text;
+  }
+
+  game.state.start('customMenu');
+}
+
+function getiLMContent() {
+  const url = iLMparameters.iLM_PARAM_Assignment;
+  if (iLMparameters.iLM_PARAM_Assignment == null) {
+    console.log("integrationFunctions.js: getiLMContent(): NAO existe arquivo FRC para ser carregado (iLMparameters.iLM_PARAM_Assignment vazio), finalize.");
+    return;
+  }
+  console.log("integrationFunctions.js: getiLMContent(): tenta pegar arquivo de " + url);
+  let gameFile = new XMLHttpRequest();
+  gameFile.open("GET", url, true);
+  gameFile.send();
+  gameFile.responseType = "text";
+  gameFile.onreadystatechange = function () {
+    if (gameFile.readyState === 4 && gameFile.status === 200) {
+      const text = gameFile.responseText;
+      decodificaArquivo(text);
+    }
+  }
+  console.log("integrationFunctions.js: getiLMContent(): final");
+}
+
+console.log("integrationFunctions.js: end.");

+ 16 - 4
js/map.js

@@ -17,9 +17,19 @@ const mapState = {
     game.add.image(0, 40, 'bgmap');
 
     // Calls function that loads navigation icons
-    navigationIcons.func_addIcons(true, true, false, // Left icons
-      false, false, // Right icons
-      'customMenu', false);
+
+    // MOODLE MODIF.
+    if (moodle) {
+      navigationIcons.func_addIcons(
+        false, false, false, // Left icons
+        false, false,        // Right icons
+        false, false);
+    } else {
+      navigationIcons.func_addIcons(
+        true, true, false, // Left icons
+        false, false,      // Right icons
+        'customMenu', false);
+    }
 
     // Progress bar
     const percentText = 4 * 25;
@@ -342,7 +352,9 @@ const endState = {
         self.animate = false;
         completedLevels = 0;
         game.animation.stop(self.character.animation[0]);
-        game.state.start('menu');
+
+        // MOODLE MODIF.
+        if (!moodle) game.state.start('menu');
 
       }
 

+ 76 - 63
js/menu.js

@@ -21,91 +21,104 @@ const menuState = {
    */
   create: function () {
 
-    // Background color
-    game.add.graphic.rect(0, 0, 900, 600, undefined, 0, colors.blueBckg, 1);
-    // Floor
-    for (let i = 0; i < defaultWidth / 100; i++) { game.add.image(i * 100, 501, 'floor'); }
+    // MOODLE MODIF.
+    if (moodle && iLMparameters.iLM_PARAM_SendAnswer == 'false') {
 
-    // Overtitle: Welcome, <player name>!
-    game.add.text(defaultWidth / 2, 40, game.lang.welcome + ', ' + playerName + '!', textStyles.h4_brown);
-    // Title : Select a game
-    game.add.text(defaultWidth / 2, 80, game.lang.menu_title, textStyles.h1_green);
-    // Subtitle : <game mode> 
-    this.lbl_game = game.add.text(defaultWidth / 2, 110, '', textStyles.h2_blue_2);
+      playerName = 'Aluno'; // TODO pegar o nome do aluno no bd do moodle
+      getiLMContent();
 
-    // Loads navigation icons
-    navigationIcons.func_addIcons(
-      false, false, false,
-      true, true,
-      false, false);
+    } else {
 
-    // INFO ICONS
+      // MOODLE MODIF.
+      if (moodle && iLMparameters.iLM_PARAM_SendAnswer == 'true') playerName = 'Professor';
 
-    this.menuIcons = [];
-    let infoIcon;
+      // Background color
+      game.add.graphic.rect(0, 0, 900, 600, undefined, 0, colors.blueBckg, 1);
+      // Floor
+      for (let i = 0; i < defaultWidth / 100; i++) { game.add.image(i * 100, 501, 'floor'); }
 
-    // --------------------------- GAME ICONS 
+      // Overtitle: Welcome, <player name>!
+      game.add.text(defaultWidth / 2, 40, game.lang.welcome + ', ' + playerName + '!', textStyles.h4_brown);
+      // Title : Select a game
+      game.add.text(defaultWidth / 2, 80, game.lang.menu_title, textStyles.h1_green);
+      // Subtitle : <game mode> 
+      this.lbl_game = game.add.text(defaultWidth / 2, 110, '', textStyles.h2_blue_2);
 
-    const offset = defaultWidth / (info.gameType.length + 1);
+      // Loads navigation icons
+      navigationIcons.func_addIcons(
+        false, false, false,
+        true, true,
+        false, false);
 
-    for (let i = 0, x = offset; i < info.gameType.length; i++, x += offset) {
+      // INFO ICONS
 
-      const icon = game.add.image(x, defaultHeight / 2 - 70, info.gameTypeUrl[i], 1);
-      icon.anchor(0.5, 0.5);
+      this.menuIcons = [];
+      let infoIcon;
 
-      icon.gameShape = info.gameShape[i];
-      icon.gameType = info.gameType[i];
-      icon.iconType = 'game';
+      // --------------------------- GAME ICONS 
 
-      this.menuIcons.push(icon);
+      const offset = defaultWidth / (info.gameType.length + 1);
 
-      // "more information" button
-      infoIcon = game.add.image(x + 70, defaultHeight / 2 - 70 - 80, 'info', 0.6, 0.6);
-      infoIcon.anchor(0.5, 0.5);
-      infoIcon.iconType = 'infoIcon';
-      infoIcon.id = icon.gameType;
-      this.menuIcons.push(infoIcon);
+      for (let i = 0, x = offset; i < info.gameType.length; i++, x += offset) {
 
-    }
+        const icon = game.add.image(x, defaultHeight / 2 - 70, info.gameTypeUrl[i], 1);
+        icon.anchor(0.5, 0.5);
 
-    // --------------------------- INFO BOX
+        icon.gameShape = info.gameShape[i];
+        icon.gameType = info.gameType[i];
+        icon.iconType = 'game';
 
-    this.infoBox = document.getElementById('myModal');
+        this.menuIcons.push(icon);
 
-    // When the user clicks on the 'x', close the modal
-    document.getElementsByClassName('close')[0].onclick = function () {
-      self.infoBox.style.display = 'none';
-    }
+        // "more information" button
+        infoIcon = game.add.image(x + 70, defaultHeight / 2 - 70 - 80, 'info', 0.6, 0.6);
+        infoIcon.anchor(0.5, 0.5);
+        infoIcon.iconType = 'infoIcon';
+        infoIcon.id = icon.gameType;
+        this.menuIcons.push(infoIcon);
+
+      }
+
+      // --------------------------- INFO BOX
+
+      this.infoBox = document.getElementById('myModal');
 
-    // When the user clicks anywhere outside of the modal, close it
-    window.onclick = function (event) {
-      if (event.target == self.infoBox) {
+      // When the user clicks on the 'x', close the modal
+      document.getElementsByClassName('close')[0].onclick = function () {
         self.infoBox.style.display = 'none';
       }
-    }
 
-    this.infoBoxContent = {
-      squareOne: {
-        title: '<b>' + game.lang.game.toLowerCase() + ':</b> ' + game.lang.square + ' I',
-        body: game.lang.infoBox_squareOne,
-        img: '<center> <img width=300 src="./assets/img/info-box/s1-A.png"> <img width=300 src="./assets/img/info-box/s1-B.png"> </center>'
-      },
-      squareTwo: {
-        title: '<b>' + game.lang.game.toLowerCase() + ':</b> ' + game.lang.square + ' II',
-        body: game.lang.infoBox_squareTwo,
-        img: '<center> <img width=400 src="./assets/img/info-box/s2.png"> </center>',
-      },
-      circleOne: {
-        title: '<b>' + game.lang.game.toLowerCase() + ':</b> ' + game.lang.circle + ' I',
-        body: game.lang.infoBox_circleOne,
-        img: '<center> <img width=300 src="./assets/img/info-box/c1-A.png"> <img width=300 src="./assets/img/info-box/c1-B.png"> </center>',
+      // When the user clicks anywhere outside of the modal, close it
+      window.onclick = function (event) {
+        if (event.target == self.infoBox) {
+          self.infoBox.style.display = 'none';
+        }
       }
-    };
 
-    // ------------- EVENTS
+      this.infoBoxContent = {
+        squareOne: {
+          title: '<b>' + game.lang.game.toLowerCase() + ':</b> ' + game.lang.square + ' I',
+          body: game.lang.infoBox_squareOne,
+          img: '<center> <img width=300 src="./assets/img/info-box/s1-A.png"> <img width=300 src="./assets/img/info-box/s1-B.png"> </center>'
+        },
+        squareTwo: {
+          title: '<b>' + game.lang.game.toLowerCase() + ':</b> ' + game.lang.square + ' II',
+          body: game.lang.infoBox_squareTwo,
+          img: '<center> <img width=400 src="./assets/img/info-box/s2.png"> </center>',
+        },
+        circleOne: {
+          title: '<b>' + game.lang.game.toLowerCase() + ':</b> ' + game.lang.circle + ' I',
+          body: game.lang.infoBox_circleOne,
+          img: '<center> <img width=300 src="./assets/img/info-box/c1-A.png"> <img width=300 src="./assets/img/info-box/c1-B.png"> </center>',
+        }
+      };
+
+      // ------------- EVENTS
+
+      game.event.add('click', this.func_onInputDown);
+      game.event.add('mousemove', this.func_onInputOver);
 
-    game.event.add('click', this.func_onInputDown);
-    game.event.add('mousemove', this.func_onInputOver);
+    }
 
   },
 

+ 12 - 2
js/preMenu.js

@@ -22,8 +22,17 @@ const bootState = {
    * Main code
    */
   create: function () {
+
     // Calls first screen seen by the player
-    game.state.start('lang');
+
+    // MOODLE MODIF.
+    if (moodle) {
+      loadLangState.firstTime = false;
+      langString = 'pt_BR';
+      game.state.start('loadLang');
+    } else {
+      game.state.start('lang');
+    }
   }
 };
 
@@ -286,8 +295,9 @@ const nameState = {
     if (audioStatus) game.audio.beepSound.play();
     if (debugMode) console.log('Username: ' + playerName);
 
+    // MOODLE MODIF.
     // Calls 'menu' state
-    game.state.start('menu');
+    if (!moodle) game.state.start('menu');
   }
 
 };

+ 20 - 7
js/squareOne.js

@@ -67,11 +67,21 @@ const squareOne = {
     for (let i = 0; i < 9; i++) { game.add.image(i * 100, 501, 'floor'); }
 
     // Calls function that loads navigation icons
-    navigationIcons.func_addIcons(
-      true, true, true,   // Left icons
-      true, false,        // Right icons
-      'customMenu', this.func_viewHelp
-    );
+
+    // MOODLE MODIF.
+    if (moodle) {
+      navigationIcons.func_addIcons(
+        false, false, false, // Left icons
+        true, false,         // Right icons
+        false, false
+      );
+    } else {
+      navigationIcons.func_addIcons(
+        true, true, true,   // Left icons
+        true, false,        // Right icons
+        'customMenu', this.func_viewHelp
+      );
+    }
 
     // TRACTOR 
     this.tractor = game.add.sprite(this.startX, 445, 'tractor', 0, 0.8);
@@ -393,7 +403,7 @@ const squareOne = {
         }
 
         self.floor.index = -1;
-      // On game mode B
+        // On game mode B
       } else {
         for (let i in self.stck.blocks) {
           self.stck.blocks[i].alpha = 0.5; // Back to normal
@@ -665,7 +675,10 @@ const squareOne = {
       + ', valBlocks: ' + self.divisorsList // Ends in ','
       + ' blockIndex: ' + self.stck.index
       + ', floorIndex: ' + self.floor.index;
-    sendToDB(data);
+
+    // MOODLE MODIF.  
+    if (moodle) sendToDB(data, self.result, game.timer.elapsed);
+    else sendToDB(data);
   },
 
 };

+ 17 - 5
js/squareTwo.js

@@ -71,10 +71,19 @@ const squareTwo = {
     for (let i = 0; i < 9; i++) { game.add.image(i * 100, 501, 'floor'); }
 
     // Calls function that loads navigation icons
-    navigationIcons.func_addIcons(
-      true, true, false,
-      true, false,
-      'customMenu', false);
+
+    // MOODLE MODIF.
+    if (moodle) {
+      navigationIcons.func_addIcons(
+        false, false, false, // Left buttons
+        true, false,         // Right buttons
+        false, false);
+    } else {
+      navigationIcons.func_addIcons(
+        true, true, false, // Left buttons
+        true, false,       // Right buttons
+        'customMenu', false);
+    }
 
     // Add kid
     this.kidAnimation = game.add.sprite(100, 470, 'kid_standing', 5, 0.8);
@@ -461,7 +470,10 @@ const squareTwo = {
       + ', valueA: ' + self.A.selected
       + ', numBlocksB: ' + self.B.blocks.length
       + ', valueB: ' + self.B.selected;
-    sendToDB(data);
+
+    // MOODLE MODIF.
+    if (moodle) sendToDB(data, self.result, game.timer.elapsed);
+    else sendToDB(data);
   }
 
 };