Prechádzať zdrojové kódy

s1 refactor and fix bug lowering blocks

lairaalmas 1 rok pred
rodič
commit
8360fa2da0
2 zmenil súbory, kde vykonal 148 pridanie a 173 odobranie
  1. 147 172
      src/js/games/squareOne.js
  2. 1 1
      src/js/globals/globals_debug.js

+ 147 - 172
src/js/games/squareOne.js

@@ -85,9 +85,9 @@ const squareOne = {
           : truckWidth, // Initial 'x' coordinate for the tractor and stacked blocks
       y0: context.canvas.height - game.image['floor_grass'].width * 1.5,
     };
-    renderBackground();
+    const divisor = gameDifficulty == 3 ? 4 : gameDifficulty; // Make sure valid divisors are 1, 2 and 4 (not 3)
 
-    // Calls function that loads navigation icons
+    renderBackground();
 
     // FOR MOODLE
     if (moodle) {
@@ -97,31 +97,26 @@ const squareOne = {
       navigation.add.right(['audio']);
     }
 
-    this.blocks = {
-      stack: {
-        list: [],
-        index: undefined, // (gameMode 'b') index of 'stacked' block selected by player
-
-        // Control variables for animation
-        curIndex: 0, // (needs to be 0)
-        curBlockEnd: undefined,
-
-        // Correct values
-        correctIndex: undefined, // (gameMode 'b') index of the CORRECT 'stacked' block
-      },
-      floor: {
-        list: [], // Group of 'floor' block objects
-        index: undefined, // (gameMode 'a') index of 'floor' block selected by player
-
-        // Control variables for animation
-        curIndex: -1, // (needs to be -1)
-
-        // Correct values
-        correctIndex: undefined, // (gameMode 'a') index of the CORRECT 'floor' block
-        correctX: undefined, // 'x' coordinate of CORRECT 'floor' block
-        correctXA: undefined, // Temporary variable
-        correctXB: undefined, // Temporary variable
-      },
+    this.stack = {
+      list: [],
+      selectedIndex: undefined,
+      correctIndex: undefined, // (gameMode 'b') index of the CORRECT 'stacked' block
+
+      curIndex: 0, // (needs to be 0)
+
+      curBlockEndX: undefined,
+    };
+    this.floor = {
+      list: [],
+      selectedIndex: undefined,
+      correctIndex: undefined, // (gameMode 'a') index of the CORRECT 'floor' block
+
+      curIndex: -1, // (needs to be -1)
+
+      selectedX: undefined,
+      correctX: undefined, // 'x' coordinate of CORRECT 'floor' block
+      correctXA: undefined, // Temporary variable
+      correctXB: undefined, // Temporary variable
     };
 
     let lineColor = undefined;
@@ -138,12 +133,14 @@ const squareOne = {
       this.control.direc,
       lineColor,
       fillColor,
-      this.control.lineWidth
+      this.control.lineWidth,
+      divisor
     );
     this.utils.renderFloorBlocks(
       this.control.direc,
       lineColor,
-      this.control.lineWidth
+      this.control.lineWidth,
+      divisor
     );
     this.utils.renderCharacters();
     this.utils.renderUI(this.control.direc);
@@ -184,15 +181,20 @@ const squareOne = {
      *
      * @returns {boolean}
      */
-    renderStackedBlocks: function (direc, lineColor, fillColor, lineWidth) {
+    renderStackedBlocks: function (
+      direc,
+      lineColor,
+      fillColor,
+      lineWidth,
+      divisor
+    ) {
       let restart = false;
       let hasBaseDifficulty = false; // Will be true after next for loop if level has at least one '1/difficulty' fraction (if false, restart)
 
       const max = gameMode == 'b' ? 10 : curMapPosition + 4; // Maximum number of stacked blocks for the level
       const total = game.math.randomInRange(curMapPosition + 2, max); // Current number of stacked blocks for the level
 
-      self.blocks.floor.correctXA =
-        self.default.x0 + self.default.width * direc;
+      self.floor.correctXA = self.default.x0 + self.default.width * direc;
       for (let i = 0; i < total; i++) {
         let curFractionItems = undefined;
         let font = undefined;
@@ -203,7 +205,7 @@ const squareOne = {
 
         const curBlockWidth = self.default.width / curDivisor; // Current width is a fraction of the default
         self.control.divisorsList += curDivisor + ','; // List of divisors (for postScore())
-        self.blocks.floor.correctXA += curBlockWidth * direc;
+        self.floor.correctXA += curBlockWidth * direc;
 
         const curBlock = game.add.geom.rect(
           self.default.x0,
@@ -216,14 +218,15 @@ const squareOne = {
           1
         );
         curBlock.anchor(gameOperation === 'minus' ? 1 : 0, 1);
+        curBlock.blockValue = divisor / curDivisor;
 
         // If game mode is (b), adding events to stacked blocks
         if (gameMode == 'b') {
           curBlock.alpha = 0.5;
-          curBlock.index = i;
+          curBlock.blockIndex = i;
         }
 
-        self.blocks.stack.list.push(curBlock);
+        self.stack.list.push(curBlock);
 
         // If 'show fractions' is turned on, create labels that display the fractions on the side of each block
         if (showFractions) {
@@ -282,21 +285,23 @@ const squareOne = {
         }
       }
 
+      // Computer generated correct stack index
+      if (gameMode === 'a') self.stack.selectedIndex = total - 1;
+
       // Will be used as a counter in update, adding in the width of each stacked block to check if the end matches the floor selected position
-      self.blocks.stack.curBlockEnd =
-        self.default.x0 + self.blocks.stack.list[0].width * direc;
+      // initial value is end of current block
+      self.stack.curBlockEndX =
+        self.default.x0 + self.stack.list[0].width * direc;
 
       // Check for errors (level too easy for its difficulty or end position out of bounds)
       if (
         !hasBaseDifficulty ||
         (gameOperation == 'plus' &&
-          (self.blocks.floor.correctXA < self.default.x0 + self.default.width ||
-            self.blocks.floor.correctXA >
-              self.default.x0 + 8 * self.default.width)) ||
+          (self.floor.correctXA < self.default.x0 + self.default.width ||
+            self.floor.correctXA > self.default.x0 + 8 * self.default.width)) ||
         (gameOperation == 'minus' &&
-          (self.blocks.floor.correctXA <
-            self.default.x0 - 8 * self.default.width ||
-            self.blocks.floor.correctXA > self.default.x0 - self.default.width))
+          (self.floor.correctXA < self.default.x0 - 8 * self.default.width ||
+            self.floor.correctXA > self.default.x0 - self.default.width))
       ) {
         restart = true; // If any error is found restart the level
       }
@@ -317,27 +322,22 @@ const squareOne = {
     /**
      * Create floor blocks for the level in create()
      */
-    renderFloorBlocks: function (direc, lineColor, lineWidth) {
-      // For each floor block
-      const divisor = gameDifficulty == 3 ? 4 : gameDifficulty; // Make sure valid divisors are 1, 2 and 4 (not 3)
-
+    renderFloorBlocks: function (direc, lineColor, lineWidth, divisor) {
       let total = 8 * divisor; // Number of floor blocks
 
       const blockWidth = self.default.width / divisor; // Width of each floor block
 
       // If game is type (b), selectiong a random floor x position
       if (gameMode == 'b') {
-        self.blocks.stack.correctIndex = game.math.randomInRange(
+        self.stack.correctIndex = game.math.randomInRange(
           0,
-          self.blocks.stack.list.length - 1
+          self.stack.list.length - 1
         ); // Correct stacked index
 
-        self.blocks.floor.correctXB =
-          self.default.x0 + self.default.width * direc;
+        self.floor.correctXB = self.default.x0 + self.default.width * direc;
 
-        for (let i = 0; i <= self.blocks.stack.correctIndex; i++) {
-          self.blocks.floor.correctXB +=
-            self.blocks.stack.list[i].width * direc; // Equivalent x position on the floor
+        for (let i = 0; i <= self.stack.correctIndex; i++) {
+          self.floor.correctXB += self.stack.list[i].width * direc; // Equivalent x position on the floor
         }
       }
 
@@ -346,20 +346,21 @@ const squareOne = {
       for (let i = 0; i < total; i++) {
         const curX =
           self.default.x0 + (self.default.width + i * blockWidth) * direc;
+
         if (flag && gameMode == 'a') {
           if (
-            (gameOperation == 'plus' && curX >= self.blocks.floor.correctXA) ||
-            (gameOperation == 'minus' && curX <= self.blocks.floor.correctXA)
+            (gameOperation == 'plus' && curX >= self.floor.correctXA) ||
+            (gameOperation == 'minus' && curX <= self.floor.correctXA)
           ) {
-            self.blocks.floor.correctIndex = i - 1; // Set index of correct floor block
+            self.floor.correctIndex = i - 1; // Set index of correct floor block
             flag = false;
           }
         }
 
         if (gameMode == 'b') {
           if (
-            (gameOperation == 'plus' && curX >= self.blocks.floor.correctXB) ||
-            (gameOperation == 'minus' && curX <= self.blocks.floor.correctXB)
+            (gameOperation == 'plus' && curX >= self.floor.correctXB) ||
+            (gameOperation == 'minus' && curX <= self.floor.correctXB)
           ) {
             total = i;
             break;
@@ -379,21 +380,23 @@ const squareOne = {
         );
         const anchor = gameOperation == 'minus' ? 1 : 0;
         curBlock.anchor(anchor, 0);
+        curBlock.blockValue = 1;
 
         // If game is type (a), adding events to floor blocks
         if (gameMode == 'a') {
           curBlock.alpha = 0.5;
-          curBlock.index = i;
+          curBlock.blockIndex = i;
         }
 
         // Add current label to group of labels
-        self.blocks.floor.list.push(curBlock);
+        self.floor.list.push(curBlock);
       }
 
-      if (gameMode == 'a')
-        self.blocks.floor.correctX = self.blocks.floor.correctXA;
-      else if (gameMode == 'b')
-        self.blocks.floor.correctX = self.blocks.floor.correctXB;
+      // Computer generated correct floor index
+      if (gameMode === 'b') self.floor.selectedIndex = total - 1;
+
+      if (gameMode == 'a') self.floor.correctX = self.floor.correctXA;
+      else if (gameMode == 'b') self.floor.correctX = self.floor.correctXB;
 
       // Creates labels on the floor to display the numbers
       for (let i = 0; i <= 8; i++) {
@@ -508,105 +511,80 @@ const squareOne = {
 
     // UPDATE
     animateTruck: () => {
-      const stack = self.blocks.stack;
-      const floor = self.blocks.floor;
+      const stack = self.stack;
+      const floor = self.floor;
 
       // Move
       self.tractor.x += self.animation.speed;
-      stack.list.forEach((cur) => (cur.x += self.animation.speed));
+      stack.list.forEach((block) => (block.x += self.animation.speed));
 
-      // If block is 1/n (not 1/1) there is an extra block space
-      // to go through before the start of next block
-      const restOfCurBlock =
+      // If the current block is 1/n (not 1/1) we need to consider the
+      // extra space the truck needs to pass after the blocks falls but
+      // before reaching the next block
+      const curBlockExtra =
         (self.default.width - stack.list[stack.curIndex].width) *
         self.control.direc;
 
-      if (
+      const hasPassedCurBlock =
         (gameOperation == 'plus' &&
-          stack.list[0].x >= stack.curBlockEnd + restOfCurBlock) ||
+          stack.list[0].x >= stack.curBlockEndX + curBlockExtra) ||
         (gameOperation == 'minus' &&
-          stack.list[0].x <= stack.curBlockEnd + restOfCurBlock)
-      ) {
-        self.utils.checkIfBlockFalls(stack, floor, restOfCurBlock);
-      }
+          stack.list[0].x <= stack.curBlockEndX + curBlockExtra);
+      if (hasPassedCurBlock) {
+        const endAnimation = self.utils.lowerBlocksHandler(stack, floor);
 
-      // WHEN REACHED END POSITION
-      if (stack.curIndex > stack.index || floor.curIndex == floor.index) {
-        self.animation.animateTruck = false;
-        self.control.checkAnswer = true;
-      }
-    },
-    checkIfBlockFalls: (stack, floor) => {
-      let lowerBlock = true;
-
-      const curEnd =
-        stack.list[0].x + stack.list[stack.curIndex].width * self.control.direc;
-
-      // If current index is (a) last stacked index (correct index - fixed)
-      // If current index is (b) selected stacked index
-      if (stack.curIndex == stack.index) {
-        // floor.index : (a) selected floor index
-        // floor.index : (b) last floor index (correct index - fixed)
-        const selectedEnd =
-          floor.list[floor.index].x + floor.list[0].width * self.control.direc;
-
-        // (a) last stacked block (fixed) doesnt fit selected gap AKA NOT ENOUGH FLOOR BLOCKS (DOESNT CHECK TOO MANY)
-        // (b) selected stacked index doesnt fit last floor gap (fixed) AKA TOO MANY STACKED BLOCKS (DOESNT CHECK NOT ENOUGH)
-        if (
-          (gameOperation == 'plus' && curEnd > selectedEnd) ||
-          (gameOperation == 'minus' && curEnd < selectedEnd)
-        ) {
-          lowerBlock = false;
+        if (!endAnimation) {
+          self.animation.animateTruck = false;
+          self.control.checkAnswer = true;
         }
-      } else {
-        // Update to next block end
-        stack.curBlockEnd +=
-          stack.list[stack.curIndex + 1].width * self.control.direc;
       }
+    },
+    lowerBlocksHandler: (stack, floor) => {
+      floor.curIndex += stack.list[stack.curIndex].blockValue;
 
-      // Fill floor gap
-      if (lowerBlock) {
-        // Until (a) selected floor index
-        // Until (b) last floor index (correct index - fixed)
-        // Updates floor index to be equivalent to stacked index (and change alpha so floor appears to be filled)
-        for (let i = 0; i <= floor.index; i++) {
-          if (
-            (gameOperation == 'plus' && floor.list[i].x < curEnd) ||
-            (gameOperation == 'minus' && floor.list[i].x > curEnd)
-          ) {
-            floor.list[i].alpha = 0;
-            floor.curIndex = i;
-          }
-        }
+      const tooManyStackBlocks = floor.curIndex > floor.selectedIndex;
+      if (tooManyStackBlocks) {
+        return false;
+      }
 
-        // Lower
-        stack.list[stack.curIndex].alpha = 0;
-        stack.list.forEach((cur) => {
-          cur.y += self.default.height;
-        });
+      // fill floor
+      for (let i = 0; i <= floor.curIndex; i++) {
+        floor.list[i].alpha = 0.5;
+      }
+      // lower blocks
+      stack.list.forEach((block) => {
+        block.y += self.default.height;
+      });
+      // hide current block
+      stack.list[stack.curIndex].alpha = 0;
+
+      const isLastFloorBlock = floor.curIndex === floor.selectedIndex;
+      const notEnoughStackBlocks = stack.curIndex === stack.list.length - 1;
+
+      if (isLastFloorBlock || notEnoughStackBlocks) {
+        return false;
       }
 
+      // update stack blocks
       stack.curIndex++;
+      stack.curBlockEndX +=
+        stack.list[stack.curIndex].width * self.control.direc;
+
+      return true;
     },
     checkAnswer: () => {
       game.timer.stop();
 
       game.animation.stop(self.tractor.animation[0]);
 
-      if (gameMode == 'a') {
-        self.control.isCorrect =
-          self.blocks.floor.index == self.blocks.floor.correctIndex;
-      } else {
-        self.control.isCorrect =
-          self.blocks.stack.index == self.blocks.stack.correctIndex;
-      }
+      self.control.isCorrect =
+        gameMode === 'a'
+          ? self.floor.selectedIndex === self.floor.correctIndex
+          : self.stack.selectedIndex === self.stack.correctIndex;
 
       // Give feedback to player and turns on sprite animation
       if (self.control.isCorrect) {
-        // Correct answer
         game.animation.play(self.tractor.animation[0]);
-
-        // Displays feedback image and sound
         game.add
           .image(
             context.canvas.width / 2,
@@ -619,8 +597,6 @@ const squareOne = {
         completedLevels++; // Increases number os finished levels
         if (isDebugMode) console.log('Completed Levels: ' + completedLevels);
       } else {
-        // Incorrect answer
-        // Displays feedback image and sound
         game.add
           .image(
             context.canvas.width / 2,
@@ -663,13 +639,13 @@ const squareOne = {
       if (!self.control.hasClicked) {
         // On gameMode (a)
         if (gameMode == 'a') {
-          const aux = self.blocks.floor.list[0];
+          const aux = self.floor.list[0];
           self.help.x =
-            self.blocks.floor.correctX - (aux.width / 2) * self.control.direc;
+            self.floor.correctX - (aux.width / 2) * self.control.direc;
           self.help.y = self.default.y0;
           // On gameMode (b)
         } else {
-          const aux = self.blocks.stack.list[self.blocks.stack.correctIndex];
+          const aux = self.stack.list[self.stack.correctIndex];
           self.help.x = aux.x + (aux.width / 2) * self.control.direc;
           self.help.y = aux.y;
         }
@@ -698,7 +674,7 @@ const squareOne = {
     /**
      * Function called by self.events.onInputDown() when player clicks on a valid rectangle.
      */
-    clickSquareHandler: function (selectedIndex, curSet) {
+    clickSquareHandler: function (clickedIndex, curSet) {
       if (!self.control.hasClicked && !self.animation.animateEnding) {
         document.body.style.cursor = 'auto';
         // Play beep sound
@@ -706,7 +682,7 @@ const squareOne = {
 
         // Hide labels
         if (showFractions) {
-          self.blocks.stack.list.forEach((block) => {
+          self.stack.list.forEach((block) => {
             block.fraction.labels.forEach((lbl) => {
               lbl.alpha = 0;
             });
@@ -715,28 +691,27 @@ const squareOne = {
         // Hide solution pointer
         if (self.help != undefined) self.help.alpha = 0;
         // Hide unselected blocks
-        for (let i = curSet.list.length - 1; i > selectedIndex; i--) {
+        for (let i = curSet.list.length - 1; i > clickedIndex; i--) {
           curSet.list[i].alpha = 0;
         }
 
         // Save selected index
-        curSet.index = selectedIndex; //curSet.list.length - 1;
+        curSet.selectedIndex = clickedIndex;
 
         if (gameMode == 'a') {
           self.arrow.alpha = 1;
-          // Save the other blocks index
-          self.blocks.stack.index = self.blocks.stack.list.length - 1;
         } else {
-          // Save the other blocks index
-          self.blocks.floor.index = self.blocks.floor.list.length - 1;
-          // Save the updated total stacked blocks to compare in update
-          curSet.list.length = curSet.index + 1;
+          // update list size
+          self.stack.list.length = curSet.selectedIndex + 1;
         }
 
+        self.floor.selectedX =
+          self.floor.list[self.floor.selectedIndex].x +
+          self.floor.list[0].width * self.control.direc;
+
         // Turn tractor animation on
         game.animation.play(self.tractor.animation[0]);
         self.animation.animateTruck = true;
-
         self.control.hasClicked = true;
       }
     },
@@ -751,21 +726,21 @@ const squareOne = {
 
         // On gameMode (a)
         if (gameMode == 'a') {
-          for (let i in self.blocks.floor.list) {
-            self.blocks.floor.list[i].alpha = i <= cur.index ? 1 : 0.5;
+          for (let i in self.floor.list) {
+            self.floor.list[i].alpha = i <= cur.blockIndex ? 1 : 0.5;
           }
 
           // Saves the index of the selected 'floor' block
-          self.blocks.floor.index = cur.index;
+          self.floor.selectedIndex = cur.blockIndex;
 
           // On gameMode (b)
         } else {
-          for (let i in self.blocks.stack.list) {
-            self.blocks.stack.list[i].alpha = i <= cur.index ? 0.5 : 0.2;
+          for (let i in self.stack.list) {
+            self.stack.list[i].alpha = i <= cur.blockIndex ? 0.5 : 0.2;
           }
 
           // Saves the index of the selected 'stack' block
-          self.blocks.stack.index = cur.index;
+          self.stack.selectedIndex = cur.blockIndex;
         }
       }
     },
@@ -778,18 +753,18 @@ const squareOne = {
 
         // On game mode (a)
         if (gameMode == 'a') {
-          for (let i in self.blocks.floor.list) {
-            self.blocks.floor.list[i].alpha = 0.5; // Back to normal
+          for (let i in self.floor.list) {
+            self.floor.list[i].alpha = 0.5; // Back to normal
           }
 
-          self.blocks.floor.index = -1;
+          self.floor.selectedIndex = undefined;
           // On game mode (b)
         } else {
-          for (let i in self.blocks.stack.list) {
-            self.blocks.stack.list[i].alpha = 0.5; // Back to normal
+          for (let i in self.stack.list) {
+            self.stack.list[i].alpha = 0.5; // Back to normal
           }
 
-          self.blocks.stack.index = -1;
+          self.stack.selectedIndex = undefined;
         }
       }
     },
@@ -805,11 +780,11 @@ const squareOne = {
       const x = game.math.getMouse(mouseEvent).x;
       const y = game.math.getMouse(mouseEvent).y;
 
-      const curSet = gameMode == 'a' ? self.blocks.floor : self.blocks.stack;
+      const curSet = gameMode == 'a' ? self.floor : self.stack;
 
       for (let i in curSet.list) {
         if (game.math.isOverIcon(x, y, curSet.list[i])) {
-          self.utils.clickSquareHandler(i, curSet);
+          self.utils.clickSquareHandler(+i, curSet);
           break;
         }
       }
@@ -840,7 +815,7 @@ const squareOne = {
           }
         }
 
-        self.blocks.floor.list.forEach((cur) => {
+        self.floor.list.forEach((cur) => {
           if (game.math.isOverIcon(x, y, cur)) {
             flagA = true;
             self.utils.overSquareHandler(cur);
@@ -851,7 +826,7 @@ const squareOne = {
       }
 
       if (gameMode == 'b') {
-        self.blocks.stack.list.forEach((cur) => {
+        self.stack.list.forEach((cur) => {
           if (game.math.isOverIcon(x, y, cur)) {
             flagB = true;
             self.utils.overSquareHandler(cur);
@@ -894,13 +869,13 @@ const squareOne = {
         game.timer.elapsed +
         '&line_deta=' +
         'numBlocks:' +
-        self.blocks.stack.list.length +
+        self.stack.list.length +
         ', valBlocks: ' +
         self.control.divisorsList + // Ends in ','
         ' blockIndex: ' +
-        self.blocks.stack.index +
+        self.stack.selectedIndex +
         ', floorIndex: ' +
-        self.blocks.floor.index;
+        self.floor.selectedIndex;
 
       // FOR MOODLE
       sendToDatabase(data);

+ 1 - 1
src/js/globals/globals_debug.js

@@ -7,7 +7,7 @@ const debugState = {
   customMenu: {
     status: true,
     getData: () => {
-      return { mode: 'a', operation: 'plus', difficulty: 1, label: true };
+      return { mode: 'a', operation: 'plus', difficulty: 3, label: true };
     },
   },
   map: { status: true },