Browse Source

- ifractions now has information boxes accessed via '?' icons on both menus - still need to finish text and i18n
- added new images (for infobox)

laira 3 years ago
parent
commit
b1fdaff8a2

BIN
assets/img/info-box/c1-A.png


BIN
assets/img/info-box/c1-B.png


BIN
assets/img/info-box/dif-1.png


BIN
assets/img/info-box/dif-5.png


BIN
assets/img/info-box/operation_equals.png


BIN
assets/img/info-box/operation_minus.png


BIN
assets/img/info-box/operation_mixed.png


BIN
assets/img/info-box/operation_plus.png


BIN
assets/img/info-box/s1-A.png


BIN
assets/img/info-box/s1-B.png


BIN
assets/img/info-box/s2.png


+ 7 - 0
assets/lang/en_US

@@ -23,3 +23,10 @@ show=Show
 square=Quadrangles
 title=Fractions
 welcome=Hi
+infoBox_squareOne=.
+infoBox_squareTwo=.
+infoBox_circleOne=.
+infoBox_mode=.
+infoBox_oper=.
+infoBox_diff=.
+infoBox_misc=.

+ 7 - 0
assets/lang/es_PE

@@ -23,3 +23,10 @@ show=Mostrar
 square=Cuadrilateros
 title=Fracciones
 welcome=Hola
+infoBox_squareOne=.
+infoBox_squareTwo=.
+infoBox_circleOne=.
+infoBox_mode=.
+infoBox_oper=.
+infoBox_diff=.
+infoBox_misc=.

+ 7 - 0
assets/lang/fr_FR

@@ -23,3 +23,10 @@ show=Afficher les
 square=Quadrangles
 title=Fractions
 welcome=Salut
+infoBox_squareOne=.
+infoBox_squareTwo=.
+infoBox_circleOne=.
+infoBox_mode=.
+infoBox_oper=.
+infoBox_diff=.
+infoBox_misc=.

+ 7 - 0
assets/lang/it_IT

@@ -23,3 +23,10 @@ show=Mostra le
 square=Quadrilateri
 title=Frazioni
 welcome=Ciao
+infoBox_squareOne=.
+infoBox_squareTwo=.
+infoBox_circleOne=.
+infoBox_mode=.
+infoBox_oper=.
+infoBox_diff=.
+infoBox_misc=.

+ 16 - 0
assets/lang/pt_BR

@@ -23,3 +23,19 @@ show=Mostrar
 square=Quadriláteros
 title=Frações
 welcome=Olá
+
+infoBox_squareOne=Este jogo tem temática rural, onde você joga como um trator que precisa empurrar uma porção de blocos para preencher o buraco no chão.<br>Este jogo representa frações como subdivisões de quadriláteros.<br>A soma e subtração de frações é representada como a “ida” e “volta” do trator, respectivamente.
+
+infoBox_squareTwo=Este jogo tem a temática da criança querendo chegar à escola à pé.<br>Este jogo representa frações como subdivisões de quadriláteros.<br>Aborda igualdade de frações como diferentes subdivisões em dois retângulos de mesmo tamanho.
+
+infoBox_circleOne=Este jogo tem temática de voo, onde você joga como uma criança querendo viajar num balão para chegar até a escola.<br>Este jogo representa frações como arcos.<br>A circunferência do arco é equivalente à distância da criança até o balão.<br>Este jogo aborda soma e subtração de frações como ida e volta da criança, mas também considera ambas operações de uma só vez.
+
+infoBox_mode=São variações do jogo selecionado da tela anterior.
+infoBox_oper=Tendo selecionado o modo de jogo, escolha a operação matemática envolvendo frações que será estudada com o jogo (soma, subtração, igualdade etc). Diferentes jogos cobrem diferentes operações.
+infoBox_diff=são representada por números inteiros, tal que quantomaior o valor, mais difícil o jogo
+infoBox_misc=.
+
+plus=Soma
+minus=Subtração
+mixed=Soma e Subtração
+equals=Igualdade

+ 123 - 46
index.html

@@ -22,6 +22,7 @@ www.usp.br/line
       margin-right: auto;
       display: block;
     }
+
     #textbox {
       position: absolute;
       margin-left: auto;
@@ -32,6 +33,7 @@ www.usp.br/line
       text-align: center;
       visibility: hidden;
     }
+
     input[type=text] {
       background-color: #fff;
       padding: 15px 40px;
@@ -42,9 +44,58 @@ www.usp.br/line
       color: #000;
       text-align: center;
     }
+
     input:focus {
       outline: 3px solid #85accc;
     }
+
+    /* The Modal (background) */
+    .modal {
+      display: none;
+      /* Hidden by default */
+      position: fixed;
+      /* Stay in place */
+      z-index: 1;
+      /* Sit on top */
+      padding-top: 155px;
+      /* Location of the box */
+      left: 0;
+      top: 0;
+      width: 100%;
+      /* Full width */
+      height: 100%;
+      /* Full height */
+      overflow: auto;
+      /* Enable scroll if needed */
+      background-color: rgb(0, 0, 0);
+      /* Fallback color */
+      background-color: rgba(0, 0, 0, 0.4);
+      /* Black w/ opacity */
+    }
+
+    /* Modal Content */
+    .modal-content {
+      background-color: #fefefe;
+      margin: auto;
+      padding: 20px;
+      border: 1px solid #888;
+      width: 50%;
+    }
+
+    /* The Close Button */
+    .close {
+      color: #aaaaaa;
+      float: right;
+      font-size: 28px;
+      font-weight: bold;
+    }
+
+    .close:hover,
+    .close:focus {
+      color: #000;
+      text-decoration: none;
+      cursor: pointer;
+    }
   </style>
 
 </head>
@@ -53,62 +104,88 @@ www.usp.br/line
 
   <div class="container">
 
-    <div class="clearfix"></div>
+    <div class="clearfix">
+    </div>
 
     <div class="panel panel-primary">
-      <div class="panel-heading">iFractions game :: by LInE</div>
+
+      <div class="panel-heading">
+        iFractions game :: by LInE
+      </div>
+
       <div class="panel-body">
-        <canvas id="iFractions-canvas"></canvas> <!-- iFractions game -->
-        <div id="textbox" onsubmit="return false"> <!-- Textbox to get player name -->
+
+        <!-- iFractions game -->
+        <canvas id="iFractions-canvas"></canvas>
+
+        <!-- Textbox to get player name -->
+        <div id="textbox" onsubmit="return false">
           <input type="text" id="textbox-content" value="" size="13" maxlength="36">
         </div>
+
+        <!-- Display fps in debugmode -->
+        <div id="display-fps"></div>
+
+
+
+        <!-- The Modal -->
+        <div id="myModal" class="modal">
+
+          <!-- Modal content -->
+          <div class="modal-content">
+            <span class="close">&times;</span>
+            <div id='infobox-content'></div>
+          </div>
+
+        </div>
+
       </div>
+
     </div>
 
-    <div id="display-fps"><!-- Display fps in debugmode --></div>
+    <!-- Load all js files -->
+    <script src="js/preMenu.js"></script>
+    <script src="js/menu.js"></script>
+    <script src="js/customMenu.js"></script>
+    <script src="js/map.js"></script>
+    <script src="js/circleOne.js"></script>
+    <script src="js/squareOne.js"></script>
+    <script src="js/squareTwo.js"></script>
+    <script src="js/gameMechanics.js"></script>
+    <script src="js/globals.js"></script>
 
-  </div>
+    <script>
+      const displayFps = document.getElementById("display-fps");
 
-  <!-- Load all js files -->
-  <script src="js/preMenu.js"></script>
-  <script src="js/menu.js"></script>
-  <script src="js/customMenu.js"></script>
-  <script src="js/map.js"></script>
-  <script src="js/circleOne.js"></script>
-  <script src="js/squareOne.js"></script>
-  <script src="js/squareTwo.js"></script>
-  <script src="js/gameMechanics.js"></script>
-  <script src="js/globals.js"></script>
-  <script>
-    const displayFps = document.getElementById("display-fps");
-
-    canvas = document.getElementById("iFractions-canvas");
-    canvas.width = defaultWidth;
-    canvas.height = defaultHeight;
-
-    const context = canvas.getContext("2d");
-
-    info.start();
-
-    // CREATING GAME STATES
-    game.state.add('boot', bootState);
-    game.state.add('lang', langState);
-    game.state.add('loadLang', loadLangState);
-    game.state.add('name', nameState);
-
-    game.state.add('menu', menuState);
-    game.state.add('customMenu', customMenuState);
-
-    game.state.add('map', mapState);
-    game.state.add('end', endState);
-
-    game.state.add('squareOne', squareOne);
-    game.state.add('circleOne', circleOne);
-    game.state.add('squareTwo', squareTwo);
-
-    // CALLING FIRST GAME STATE
-    game.state.start('boot');
-  </script>
+      canvas = document.getElementById("iFractions-canvas");
+      canvas.width = defaultWidth;
+      canvas.height = defaultHeight;
+
+      const context = canvas.getContext("2d");
+
+      info.start();
+
+      // CREATING GAME STATES
+      game.state.add('boot', bootState);
+      game.state.add('lang', langState);
+      game.state.add('loadLang', loadLangState);
+      game.state.add('name', nameState);
+
+      game.state.add('menu', menuState);
+      game.state.add('customMenu', customMenuState);
+
+      game.state.add('map', mapState);
+      game.state.add('end', endState);
+
+      game.state.add('squareOne', squareOne);
+      game.state.add('circleOne', circleOne);
+      game.state.add('squareTwo', squareTwo);
+
+      // CALLING FIRST GAME STATE
+      game.state.start('boot');
+    </script>
+
+  </div>
 
 </body>
 

+ 73 - 56
js/customMenu.js

@@ -24,7 +24,6 @@ const customMenuState = {
     const iconScale = 0.7;
     const baseY = 270 - 40;
     this.menuIcons = [];
-    this.activeIcons = this.menuIcons;
 
     // Background color
     game.add.graphic.rect(0, 0, 900, 600, undefined, 0, colors.blueBckg, 1);
@@ -55,6 +54,7 @@ const customMenuState = {
     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'
@@ -63,6 +63,7 @@ const customMenuState = {
     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'
@@ -71,6 +72,7 @@ const customMenuState = {
     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
@@ -90,12 +92,16 @@ const customMenuState = {
     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') {
-      game.add.text(x + 5 * offsetW + 10, y + 102 + 24, game.lang.aux_rectangle, textStyles.h4_blue_2);
+      auxText = game.lang.aux_rectangle;
+      game.add.text(x + 5 * offsetW + 10, y + 102 + 24, auxText, textStyles.h4_blue_2);
     } else {
-      game.add.text(x + 5 * offsetW, y + 102 + 24, game.lang.title, textStyles.h2_blue_2);
+      auxText = game.lang.title;
+      game.add.text(x + 5 * offsetW, y + 102 + 24, auxText, textStyles.h2_blue_2);
     }
 
     // Selection box
@@ -202,25 +208,47 @@ const customMenuState = {
 
     this.enterText = game.add.text(x, y, game.lang.continue, textStyles.h4_white);
 
-    // --------------------------- INFORMATION BOX
+    // --------------------------- INFO BOX
 
-    let cur;
-    this.infoBoxElements = []; // grouped to be displayed/hidden when info box is oppened/closed
+    this.infoBox = document.getElementById('myModal');
 
-    cur = game.add.graphic.rect(0, 0, defaultWidth, defaultHeight, undefined, 0, colors.black, 0.6);
-    cur.alpha = 0;
-    cur.originalAlpha = 0.6;
-    this.infoBoxElements.push(cur);
+    // When the user clicks on the 'x', close the modal
+    document.getElementsByClassName('close')[0].onclick = function () {
+      self.infoBox.style.display = 'none';
+    }
 
-    cur = game.add.graphic.rect(100, 100, defaultWidth - 200, defaultHeight - 200, colors.blue, 2, colors.blueBckg, 1);
-    cur.alpha = 0;
-    this.infoBoxElements.push(cur);
+    // 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';
+      }
+    }
 
-    this.closeIcon = game.add.image(defaultWidth - 128, 125, 'close', 0.12);
-    this.closeIcon.anchor(0.5, 0.5);
-    this.closeIcon.alpha = 0;
-    this.closeIcon.iconType = 'infoBox';
-    this.infoBoxElements.push(this.closeIcon);
+    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
 
@@ -229,6 +257,20 @@ const customMenuState = {
 
   },
 
+  /**
+   * Displays game menu information boxes.
+   */
+  func_showInfoBox: function (icon) {
+    self.infoBox.style.display = 'block';
+
+    let msg = '<h3>' + self.infoBoxContent[icon.id].title + '</h3>'
+      + '<p>' + self.infoBoxContent[icon.id].body + '</p>'
+      + self.infoBoxContent[icon.id].img;
+
+    document.getElementById('infobox-content').innerHTML = msg;
+  },
+
+
   /**
    * Saves information selected by the player 
    * 
@@ -243,8 +285,7 @@ const customMenuState = {
       case 'gameMode': gameModeType = icon.gameModeType; break;
       case 'gameOperation': gameOperationType = icon.gameOperationType; break;
       case 'difficulty': gameDifficulty = icon.difficulty; break;
-      case 'infoIcon': self.func_showInfoBox(); break;
-      case 'infoBox': self.func_closeInfoBox(); break;
+      case 'infoIcon': self.func_showInfoBox(icon); break;
       case 'selectionBox':
         if (icon.curFrame == 0) {
           icon.curFrame = 1;
@@ -277,30 +318,6 @@ const customMenuState = {
     return width / (numberOfIcons + 1);
   },
 
-  /**
-   * Displays game menu information boxes.
-   */
-  func_showInfoBox: function () {
-    navigationIcons.func_addIcons( // Turn off navigation icons
-      false, false, false,
-      false, false,
-      false, false);
-    self.infoBoxElements.forEach(cur => { cur.alpha = (cur.originalAlpha) ? cur.originalAlpha : 1; }); // Make info box visible
-    self.activeIcons = [self.closeIcon]; // Update activeIcons to info box icons
-  },
-
-  /**
-   * Closes game menu information boxes.
-   */
-  func_closeInfoBox: function () {
-    navigationIcons.func_addIcons( // Turn on navigation icons
-      true, false, false,
-      true, true,
-      'menu', false);
-    self.infoBoxElements.forEach(cur => { cur.alpha = 0; }); // Make info box invisible
-    self.activeIcons = self.menuIcons; // Update activeIcons to custom menu icons
-  },
-
   /**
    * Called by mouse click event
    * 
@@ -311,8 +328,8 @@ const customMenuState = {
     let overIcon;
 
     // Check if clicked on an icon
-    for (let i in self.activeIcons) {
-      if (game.math.isOverIcon(x, y, self.activeIcons[i])) {
+    for (let i in self.menuIcons) {
+      if (game.math.isOverIcon(x, y, self.menuIcons[i])) {
         overIcon = i;
         break;
       }
@@ -321,9 +338,9 @@ const customMenuState = {
     // Update gui
     if (overIcon) { // if has clicked on an icon
       document.body.style.cursor = 'pointer';
-      self.activeIcons.forEach(cur => {
-        if (cur.iconType == self.activeIcons[overIcon].iconType) { // if its in the same icon category
-          if (cur == self.activeIcons[overIcon]) { // if its the clicked icon
+      self.menuIcons.forEach(cur => {
+        if (cur.iconType == self.menuIcons[overIcon].iconType) { // if its in the same icon category
+          if (cur == self.menuIcons[overIcon]) { // if its the clicked icon
             if (cur.iconType == 'gameMode' || cur.iconType == 'gameOperation') cur.curFrame = 1;
             else if (cur.iconType == 'difficulty') cur.fillColor = colors.blue;
           } else {
@@ -333,7 +350,7 @@ const customMenuState = {
         }
       });
 
-      self.func_load(self.activeIcons[overIcon]);
+      self.func_load(self.menuIcons[overIcon]);
 
     } else document.body.style.cursor = 'auto';
 
@@ -353,8 +370,8 @@ const customMenuState = {
     let overIcon;
 
     // Check if pointer is over an icon
-    for (let i in self.activeIcons) {
-      if (game.math.isOverIcon(x, y, self.activeIcons[i])) {
+    for (let i in self.menuIcons) {
+      if (game.math.isOverIcon(x, y, self.menuIcons[i])) {
         overIcon = i;
         break;
       }
@@ -363,9 +380,9 @@ const customMenuState = {
     // Update gui
     if (overIcon) { // if pointer is over icon
       document.body.style.cursor = 'pointer';
-      self.activeIcons.forEach(cur => {
-        if (cur.iconType == self.activeIcons[overIcon].iconType) { // if its in the same icon category
-          if (cur == self.activeIcons[overIcon]) { // if its the icon the pointer is over 
+      self.menuIcons.forEach(cur => {
+        if (cur.iconType == self.menuIcons[overIcon].iconType) { // if its in the same icon category
+          if (cur == self.menuIcons[overIcon]) { // if its the icon the pointer is over 
             if (cur.iconType == 'enter') self.enterText.style = textStyles.h3__white;
             cur.scale = cur.originalScale * 1.1;
           } else {
@@ -375,7 +392,7 @@ const customMenuState = {
       });
     } else { // if pointer is not over icon
       self.enterText.style = textStyles.h4_white;
-      self.activeIcons.forEach(cur => { cur.scale = cur.originalScale; });
+      self.menuIcons.forEach(cur => { cur.scale = cur.originalScale; });
       document.body.style.cursor = 'auto';
     }
 

+ 2 - 1
js/globals.js

@@ -252,7 +252,8 @@ 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

+ 57 - 62
js/menu.js

@@ -42,7 +42,6 @@ const menuState = {
     // INFO ICONS
 
     this.menuIcons = [];
-    this.activeIcons = this.menuIcons;
     let infoIcon;
 
     // --------------------------- GAME ICONS 
@@ -60,35 +59,48 @@ const menuState = {
 
       this.menuIcons.push(icon);
 
+      // "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);
 
     }
 
-    // --------------------------- INFORMATION BOX
+    // --------------------------- INFO BOX
 
-    let cur;
-    this.infoBoxElements = []; // grouped to be displayed/hidden when info box is oppened/closed
+    this.infoBox = document.getElementById('myModal');
 
-    cur = game.add.graphic.rect(0, 0, defaultWidth, defaultHeight, undefined, 0, colors.black, 0.6);
-    cur.alpha = 0;
-    cur.originalAlpha = 0.6;
-    this.infoBoxElements.push(cur);
+    // When the user clicks on the 'x', close the modal
+    document.getElementsByClassName('close')[0].onclick = function () {
+      self.infoBox.style.display = 'none';
+    }
 
-    cur = game.add.graphic.rect(100, 100, defaultWidth - 200, defaultHeight - 200, colors.blue, 2, colors.blueBckg, 1);
-    cur.alpha = 0;
-    //cur.shadow = true;
-    //cur.shadowColor = colors.black;
-    //cur.shadowBlur = 10;
-    this.infoBoxElements.push(cur);
+    // 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';
+      }
+    }
 
-    this.closeIcon = game.add.image(defaultWidth - 128, 125, 'close', 0.12);
-    this.closeIcon.anchor(0.5, 0.5);
-    this.closeIcon.alpha = 0;
-    this.closeIcon.iconType = 'infoBox';
-    this.infoBoxElements.push(this.closeIcon);
+    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
 
@@ -97,6 +109,19 @@ const menuState = {
 
   },
 
+  /**
+   * Displays game menu information boxes.
+   */
+  func_showInfoBox: function (icon) {
+    self.infoBox.style.display = 'block';
+
+    let msg = '<h3>' + self.infoBoxContent[icon.id].title + '</h3>'
+      + '<p>' + self.infoBoxContent[icon.id].body + '</p>'
+      + self.infoBoxContent[icon.id].img;
+
+    document.getElementById('infobox-content').innerHTML = msg;
+  },
+
   /**
    * Saves info from selected game and goes to next state
    * 
@@ -107,8 +132,7 @@ const menuState = {
     if (audioStatus) game.audio.beepSound.play();
 
     switch (icon.iconType) {
-      case 'infoIcon': self.func_showInfoBox(); break;
-      case 'infoBox': self.func_closeInfoBox(); break;
+      case 'infoIcon': self.func_showInfoBox(icon); break;
       case 'game':
         gameShape = icon.gameShape;
         gameTypeString = icon.gameType;
@@ -133,12 +157,7 @@ const menuState = {
    */
   func_showTitle: function (icon) {
 
-    let title;
-
-    switch (icon.gameShape) {
-      case 'circle': title = game.lang.circle; break;
-      case 'square': title = game.lang.square; break;
-    }
+    let title = game.lang[icon.gameShape];
 
     const type = icon.gameType.substring(icon.gameType.length - 3);
 
@@ -158,30 +177,6 @@ const menuState = {
     self.lbl_game.name = '';
   },
 
-  /**
-   * Displays game menu information boxes.
-   */
-  func_showInfoBox: function () {
-    navigationIcons.func_addIcons( // Turn off navigation icons
-      false, false, false,
-      false, false,
-      false, false);
-    self.infoBoxElements.forEach(cur => { cur.alpha = (cur.originalAlpha) ? cur.originalAlpha : 1; }); // Make info box visible
-    self.activeIcons = [self.closeIcon]; // Update activeIcons to info box icons
-  },
-
-  /**
-   * Closes game menu information boxes.
-   */
-  func_closeInfoBox: function () {
-    navigationIcons.func_addIcons( // Turn on navigation icons
-      false, false, false,
-      true, true,
-      false, false);
-    self.infoBoxElements.forEach(cur => { cur.alpha = 0; }); // Make info box invisible
-    self.activeIcons = self.menuIcons; // Update activeIcons to custom menu icons
-  },
-
   /**
    * Called by mouse click event
    * 
@@ -191,11 +186,11 @@ const menuState = {
     const x = mouseEvent.offsetX, y = mouseEvent.offsetY;
 
     // Check menu icons
-    for (let i in self.activeIcons) {
+    for (let i in self.menuIcons) {
       // If mouse is within the bounds of an icon
-      if (game.math.isOverIcon(x, y, self.activeIcons[i])) {
+      if (game.math.isOverIcon(x, y, self.menuIcons[i])) {
         // Click first valid icon
-        self.func_load(self.activeIcons[i]);
+        self.func_load(self.menuIcons[i]);
         break;
       }
     }
@@ -216,8 +211,8 @@ const menuState = {
     let overIcon;
 
     // Check menu icons
-    for (let i in self.activeIcons) {
-      if (game.math.isOverIcon(x, y, self.activeIcons[i])) {
+    for (let i in self.menuIcons) {
+      if (game.math.isOverIcon(x, y, self.menuIcons[i])) {
         overIcon = i;
         break;
       }
@@ -226,19 +221,19 @@ const menuState = {
     // Update gui
     if (overIcon) { // if pointer is over icon
       document.body.style.cursor = 'pointer';
-      self.activeIcons.forEach(cur => {
-        if (cur.iconType == self.activeIcons[overIcon].iconType) { // if its in the same icon category
-          if (cur == self.activeIcons[overIcon]) { // if its the icon the pointer is over 
-            if (cur.iconType == 'game') self.func_showTitle(cur);
+      if (self.menuIcons[overIcon].iconType == 'game') self.func_showTitle(self.menuIcons[overIcon]);
+      self.menuIcons.forEach(cur => {
+        if (cur.iconType == self.menuIcons[overIcon].iconType) { // if its in the same icon category
+          if (cur == self.menuIcons[overIcon]) { // if its the icon the pointer is over 
             cur.scale = cur.originalScale * 1.1;
           } else {
-            if (cur.iconType == 'game') self.func_clearTitle(cur);
             cur.scale = cur.originalScale;
           }
         }
       });
     } else { // if pointer is not over icon
-      self.activeIcons.forEach(cur => { cur.scale = cur.originalScale; });
+      self.func_clearTitle();
+      self.menuIcons.forEach(cur => { cur.scale = cur.originalScale; });
       document.body.style.cursor = 'auto';
     }