User prompt
fakeLiquidDestination should appear like other liquids, behind the vial (z-index talking)
User prompt
fix fakeLiquidDestination position : it should start above top liquid in the vial
User prompt
revert fakeLiquidDestination grow direction
User prompt
Please fix the bug: 'Timeout.tick error: null is not an object (evaluating 'selectedTube.removeChild')' in or related to this line: 'selectedTube.removeChild(fakeLiquidSource);' Line Number: 270
User prompt
Please fix the bug: 'Timeout.tick error: undefined is not an object (evaluating 'topLiquid.ratio')' in or related to this line: 'destinationLiquidGraphics.height += 20 * (topLiquid.ratio / selectedTube.height);' Line Number: 235
User prompt
For pouring animation, add new temporary height-animated fake liquids. Remove them at animation end. Don’t alter logic
User prompt
Only liquid stream anim works. Levels of liquids (heights) are not animated. Fix that seriously
User prompt
Rework the animation as it’s not working. Be careful of not altering logic
User prompt
Add the liquids height grow and shrink for pouring animation but without interfering with the game logic , so Don’t rely on renderLiquids For that
User prompt
Add the liquids height grow and shrink for pouring animation but without interfering with the game logic
User prompt
Please fix the bug: 'Timeout.tick error: selectedTube is null' in or related to this line: 'selectedTube.x += (targetX - selectedTube.x) * 0.1;' Line Number: 273
User prompt
continue fix the Mixing of logic and the graphics in the pouring animation if needed
User prompt
fix the Mixing of logic and the graphics in the pouring animation. Make only one step to avoid error "FAILURE: Integration failed, target source not found. Please try again."
User prompt
Restore the control that prevent pouring a color in anotherone !
User prompt
Please apply a radical solution to make it impossible to have ratios of 0.4999999999999999 or 1.0000000000000001 etc
User prompt
oh no !!! now pouring 0.25 of blue in 0.25 of red is allowed and results in the disparition of the blue !!
User prompt
Fix error in console : Uncaught TypeError: selectedTube.liquids[(selectedTube.liquids.length - 1)] is undefined
User prompt
floating point issue is still here. Fix it correctly ratios must must must only be multiples of BASE_LIQUID_RATIO (0.25)
User prompt
There is a regression, now when pouring 0.25 in 0.75 is results in 1.0000000000002 and the tube is not considered properly filled!
User prompt
ok, but now the situation is : when you try to pour 0.5 of liquid for ex Blue in a tube containing for ex 0.25 of red and 0.5 of Blue : You can't! move is considered invalid. The correct behaviour is to pour 0.25 of blue in destination tube and keep 0.25 in selected tube
User prompt
Please fix the bug: 'Timeout.tick error: liquid is null' in or related to this line: 'self.addLiquid(liquid, liquid.ratio);' Line Number: 240
User prompt
previous fix now make the following situation : when you pour 0.5 of liquid for ex Blue in a tube containing for ex 0.25 of red and 0.5 of Blue result is the destination tube with 0.25 red and 0.75 of blue, but selected tube has no more bule; that is 0.25 of blue has disapeared !)
User prompt
Fix bug when you can pour 0.5 of liquid for ex Blue in a tube containing for ex 0.25 of red and 0.5 of Blue (resulting in a tube with 0.25 red and 1.0 of blue, that is 1.25 !)
Code edit (1 edits merged)
Please save this source code
Code edit (4 edits merged)
Please save this source code
/**** * Classes ****/ var LiquidBase = Container.expand(function (color) { var self = Container.call(this); self.color = color; var liquidGraphics = self.attachAsset('liquidBase', { anchorX: 0.5, anchorY: 0.0 }); liquidGraphics.tint = colorList[color]; return self; }); var LiquidStream = Container.expand(function (color) { var self = Container.call(this); self.color = color; var liquidGraphics = self.attachAsset('liquidBase', { width: 10, anchorX: 0.5, anchorY: 0, alpha: 0 }); liquidGraphics.tint = colorList[color]; self.init = function (x, y, color) { self.height = 0; self.x = x; self.y = y + 430; liquidGraphics.tint = colorList[color]; liquidGraphics.alpha = 1; }; self.stop = function () { liquidGraphics.alpha = 0; }; return self; }); var Vial = Container.expand(function () { var self = Container.call(this); // Attach graphical representation var tubeGraphics = self.attachAsset('tube', { anchorX: 0.5, anchorY: 0.0, alpha: 0.5 }); self.fillHeight = tubeGraphics.height - 25 - 100; self.baseX = 0; // Initialize baseX to store the base x-coordinate self.baseY = 0; // Initialize baseY to store the base y-coordinate self.baseLiquidY = tubeGraphics.height - 25; self.addChild(tubeGraphics); self.liquids = []; // Initialize functional representation self.addLiquid = function (liquid, ratio) { var totalRatio = self.liquids.reduce(function (sum, liquid) { return sum + liquid.ratio; }, 0); if (totalRatio + ratio > 1) { ratio = 1 - totalRatio; // Adjust ratio to fit within the tube's capacity } // Fix floating-point precision issue ratio = Math.round(ratio / BASE_LIQUID_RATIO) * BASE_LIQUID_RATIO; ratio = parseFloat(ratio.toFixed(2)); if (self.liquids.length > 0 && self.liquids[self.liquids.length - 1].color === liquid.color) { self.liquids[self.liquids.length - 1].ratio += ratio; } else { if (ratio > 0) { var newLiquid = { color: liquid.color, index: self.liquids.length, ratio: ratio }; self.liquids.push(newLiquid); } } // Ensure the total ratio does not exceed 1 var totalRatio = self.liquids.reduce(function (sum, liquid) { return sum + liquid.ratio; }, 0); if (totalRatio > 1) { var excessRatio = totalRatio - 1; self.liquids[self.liquids.length - 1].ratio -= excessRatio; if (self.liquids[self.liquids.length - 1].ratio <= 0) { self.liquids.pop(); } } }; self.removeLiquid = function (ratio) { if (self.liquids.length > 0) { var topLiquid = self.liquids[self.liquids.length - 1]; if (ratio >= topLiquid.ratio) { var removedLiquid = self.liquids.pop(); if (self.liquids.length > 0 && self.liquids[self.liquids.length - 1].color === removedLiquid.color) { self.liquids[self.liquids.length - 1].ratio += removedLiquid.ratio; } return removedLiquid; } else { topLiquid.ratio -= ratio; // Fix floating-point precision issue var removedRatio = Math.round(ratio / BASE_LIQUID_RATIO) * BASE_LIQUID_RATIO; removedRatio = parseFloat(removedRatio.toFixed(2)); if (topLiquid.ratio <= 0) { self.liquids.pop(); } return { color: topLiquid.color, ratio: removedRatio }; } } return null; }; self.containsPoint = function (point) { var bounds = self.getBounds(); return point.x >= bounds.x && point.x <= bounds.x + bounds.width && point.y >= bounds.y + bounds.height; }; self.canPour = function (destinationTube) { if (self.liquids.length === 0) { return 0; // No liquid to pour } if (destinationTube.liquids.length === 0) { return 1; // Destination tube is empty, can pour all } var topLiquid = self.liquids[self.liquids.length - 1]; var destinationTopLiquid = destinationTube.liquids[destinationTube.liquids.length - 1]; if (topLiquid.color !== destinationTopLiquid.color) { return 0; // Different colors, cannot pour } var sameColorCount = 0; for (var i = self.liquids.length - 1; i >= 0; i--) { if (self.liquids[i].color === topLiquid.color) { sameColorCount++; } else { break; } } var totalRatio = destinationTube.liquids.reduce(function (sum, liquid) { return sum + liquid.ratio; }, 0); var availableSpace = 1 - totalRatio; return Math.min(sameColorCount, availableSpace) / sameColorCount; }; self.renderLiquids = function () { // Remove all existing liquid graphics for (var i = self.children.length - 1; i >= 0; i--) { if (self.children[i] !== tubeGraphics) { self.removeChild(self.children[i]); } } // Add new liquid graphics based on the current state of self.liquids var cumulativeHeight = 0; for (var j = 0; j < self.liquids.length; j++) { var liquid = self.liquids[j]; var liquidGraphics = self.attachAsset('liquidBase', { anchorX: 0.5, anchorY: 1.0 }); liquidGraphics.tint = colorList[liquid.color]; liquidGraphics.y = self.baseLiquidY - cumulativeHeight; // Adjust the offset to prevent liquids from appearing out of the vial bottom liquidGraphics.height = self.fillHeight * liquid.ratio; cumulativeHeight += liquidGraphics.height; self.addChildAt(liquidGraphics, 0); // Add debug text for liquidGraphics.y for index 0 and tubeGraphics.height if (j === 0) { updateDebugText('.y for index 0: ' + liquidGraphics.y + ' | .height: ' + tubeGraphics.height); } } }; self.down = function (x, y, obj) { var liquidInfo = self.liquids.map(function (liquid) { return liquid.color + ": " + liquid.ratio; }).join(", "); updateDebugText("Vial : " + liquidInfo); if (selectedTube === self) { self.scale.set(1, 1); // Reset the scale of the selected tube self.y += selectionYOffset; // Restore the tube to its initial position LK.getSound('drop').play(); selectedTube = null; // Unselect the tube } else if (selectedTube) { var pourRatio = selectedTube.canPour(self); if (pourRatio > 0 || pourRatio === 0 && selectedTube.liquids.length > 0 && selectedTube.liquids[selectedTube.liquids.length - 1].ratio > 0) { // Phase 1: Move the selected vial near the destination vial, then rotate it var originalX = selectedTube.x; var originalY = selectedTube.y; var targetX = selectedTube.x < self.x ? self.x - 50 : self.x + 50; // Adjust the target position based on the side of the destination tube var targetY = self.y - 200; // Adjust the target position as needed var rotationDirection = selectedTube.x < self.x ? Math.PI / 4 : -Math.PI / 4; // Determine rotation direction var moveAndRotate = function moveAndRotate() { selectedTube.x = targetX; selectedTube.y = targetY; selectedTube.rotation = rotationDirection; // Rotate the selected tube // Initialize a liquidStream at the top of the selected tube if (selectedTube && selectedTube.liquids.length > 0) { isPouring = true; if (!liquidStream) { liquidStream = new LiquidStream(selectedTube.liquids[selectedTube.liquids.length - 1].color); game.addChildAt(liquidStream, 0); // Ensure liquidStream is behind vials } var xDelta = selectedTube.x < self.x ? 50 : -50; liquidStream.init(selectedTube.x + xDelta, selectedTube.y - selectedTube.height / 2, selectedTube.liquids[selectedTube.liquids.length - 1].color); } // Make the LiquidStream height grow to simulate pouring // Play pouring sound LK.getSound('pouring').play(); var pourInterval = LK.setInterval(function () { if (selectedTube && selectedTube.liquids.length > 0 && liquidStream.height < selectedTube.height) { liquidStream.height += 20; // Adjust the growth rate as needed // Shrink the height of the top liquid in the selected tube var selectedTopLiquid = selectedTube.liquids[selectedTube.liquids.length - 1]; var shrinkRatio = Math.min(0.01, selectedTopLiquid.ratio); // Ensure we don't shrink more than available selectedTopLiquid.ratio -= shrinkRatio; // Adjust the shrink rate as needed selectedTopLiquid.ratio = parseFloat(selectedTopLiquid.ratio.toFixed(2)); if (selectedTopLiquid.ratio <= 0) { selectedTube.liquids.pop(); // Remove the liquid if its ratio is zero } selectedTube.renderLiquids(); // Grow the height of the top liquid in the destination tube var destinationTopLiquid = self.liquids[self.liquids.length - 1]; if (destinationTopLiquid && destinationTopLiquid.color === selectedTopLiquid.color) { destinationTopLiquid.ratio += shrinkRatio; // Adjust the growth rate as needed destinationTopLiquid.ratio = parseFloat(destinationTopLiquid.ratio.toFixed(2)); } else { var totalRatio = self.liquids.reduce(function (sum, liquid) { return sum + liquid.ratio; }, 0); if (totalRatio + shrinkRatio <= 1) { self.addLiquid(new LiquidBase(selectedTopLiquid.color), shrinkRatio); } } self.renderLiquids(); } else { LK.clearInterval(pourInterval); liquidStream.stop(); // Call stop function at the end of pouring isPouring = false; LK.getSound('pouring').stop(); // Stop pouring sound if (selectedTube) { selectedTube.x = selectedTube.baseX; selectedTube.y = selectedTube.baseY; } if (selectedTube) { selectedTube.rotation = 0; } } }, 16); // 60 FPS // Proceed to the next phase after a short delay LK.setTimeout(function () { // Phase 2 and 3 will be implemented later if (selectedTube && selectedTube.liquids.length > 0) { var liquid = selectedTube.removeLiquid(Math.min(pourRatio, selectedTube.liquids[selectedTube.liquids.length - 1].ratio)); if (liquid) { self.addLiquid(liquid, liquid.ratio); } selectedTube.renderLiquids(); self.renderLiquids(); selectedTube.x = originalX; selectedTube.y = originalY; selectedTube.rotation = 0; // Reset rotation selectedTube.y += selectionYOffset; // Restore the selected tube to its initial position selectedTube.scale.set(1, 1); // Reset the scale of the previously selected tube selectedTube = null; } if (puzzleManager.checkWinCondition()) { // Play 'goodJob' sound LK.getSound('goodJob').play(); // Level up and initialize a new round currentLevel++; levelTxt.setText('Level: ' + currentLevel); initRound(); } else { if (isPlaying && self.liquids[self.liquids.length - 1].ratio === 1) { LK.getSound('yes').play(); } else { LK.getSound('drop').play(); } } }, 500); // Adjust the delay as needed }; // Move the selected tube to the target position var moveInterval = LK.setInterval(function () { if (selectedTube && Math.abs(selectedTube.x - targetX) < 5 && Math.abs(selectedTube.y - targetY) < 5) { LK.clearInterval(moveInterval); moveAndRotate(); } else { selectedTube.x += (targetX - selectedTube.x) * 0.1; selectedTube.y += (targetY - selectedTube.y) * 0.1; selectedTube.rotation += (rotationDirection - selectedTube.rotation) * 0.1; // Rotate the tube while moving } }, 16); // 60 FPS } else { if (selectedTube) { selectedTube.scale.set(1, 1); // Reset the scale if selection is wrong selectedTube.y += selectionYOffset; // Restore the previously selected tube to its initial position LK.getSound('wrong').play(); // Play wrong sound } selectedTube = null; } } else { LK.getSound('tap').play(); selectedTube = self; self.y -= selectionYOffset; // Move the selected tube up by selectionYOffset game.setChildIndex(self, game.children.length - 1); // Bring the selected vial to the front } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 //Init game with black background }); /**** * Game Code ****/ var pourInterval; // Global variable to track pouring state var isPouring = false; function deepCopyVials(vials) { return (vials || []).map(function (vial) { var newVial = new Vial(); vial.liquids.forEach(function (liquid) { newVial.addLiquid(new LiquidBase(liquid.color), liquid.ratio); }); return newVial; }); } // Function to update debug text function updateDebugText(info) { if (debugTxt) { debugTxt.setText(info); } } // Create an instance of the PuzzleManager var PuzzleManager = function PuzzleManager() { var self = this; self.liquids = []; // Public property to store liquids self.initVials = function () { var positions = []; var nbVials = Math.min(currentLevel + 1, 10); log("initVials : nbVials =", nbVials); if (nbVials > maxPerLine) { log("Bigger board..."); board.height = 1700; } self.vials = []; // Add liquidStream to the game before vials to ensure it is always behind if (!liquidStream) { liquidStream = new LiquidStream('blue'); // Default color, will be updated later game.addChild(liquidStream); } for (var i = 0; i < nbVials; i++) { self.vials.push(new Vial()); } var spacingX = 2048 / (Math.min(nbVials, maxPerLine) + 1); var tubeHeight = LK.getAsset('tube', {}).height; var spacingY = nbVials <= maxPerLine ? (2732 - tubeHeight) / 2 : 2732 / Math.ceil(nbVials / maxPerLine); for (var i = 0; i < nbVials; i++) { positions.push({ x: spacingX * (i % maxPerLine + 1), y: nbVials <= maxPerLine ? (2732 - tubeHeight) / 2 : spacingY * Math.floor(i / maxPerLine) + 500 }); } for (var i = 0; i < self.vials.length; i++) { self.vials[i].x = positions[i].x; self.vials[i].y = positions[i].y; // Adjust if (self.vials.length > maxPerLine) { if (i < maxPerLine) { self.vials[i].y -= 50; // Move the first row up by 300 } else { self.vials[i].y -= 350; // Move the second row up by 500 } } self.vials[i].baseX = self.vials[i].x; // Store base x-coordinate self.vials[i].baseY = self.vials[i].y; // Store base y-coordinate game.addChild(self.vials[i]); } }; // Initialize liquids self.initLiquids = function (level) { // Create and initialize liquid objects based on level if (level === 1) { self.liquids = [new LiquidBase('green')]; } else { if (level === 2) { self.liquids = [new LiquidBase('blue'), new LiquidBase('green')]; } else { self.liquids = []; for (var i = 0; i < level; i++) { var colorName = Object.keys(colorList)[i % Object.keys(colorList).length]; self.liquids.push(new LiquidBase(colorName)); } } } }; self.distributeLiquids = function () { // Helper function to shuffle an array function shuffle(array) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = array[i]; array[i] = array[j]; array[j] = temp; } } // Distribute initialized liquids into the provided vials if (self.vials.length === 0) { return; } if (currentLevel === 1) { self.vials[0].addLiquid(self.liquids[0], 0.25); self.vials[1].addLiquid(self.liquids[0], 0.75); } else if (currentLevel === 2) { self.vials[0].addLiquid(self.liquids[0], 0.5); self.vials[1].addLiquid(self.liquids[1], 0.5); self.vials[2].addLiquid(self.liquids[0], 0.5); self.vials[2].addLiquid(self.liquids[1], 0.5); } else { var totalPortions = (self.vials.length - 1) * (1 / BASE_LIQUID_RATIO); var portionsPerColor = Math.floor(totalPortions / self.liquids.length); var portions = self.liquids.flatMap(function (liquid) { return Array(portionsPerColor).fill(liquid.color); }); shuffle(portions); var attempts = 0; var maxAttempts = 1000; while (attempts < maxAttempts) { var portionIndex = 0; for (var i = 0; i < self.vials.length - 1; i++) { self.vials[i].liquids = []; var vialPortions = totalPortions / (self.vials.length - 1); for (var j = 0; j < vialPortions; j++) { var color = portions[portionIndex++]; var liquid = self.liquids.find(function (l) { return l.color === color; }); if (liquid) { self.vials[i].addLiquid(liquid, BASE_LIQUID_RATIO); } } } if (self.isSolvable()) { break; } attempts++; shuffle(portions); } lastDistributionConfig = deepCopyVials(self.vials); } }; self.isSolvable = function () { var visitedStates = []; var stateQueue = []; function serializeState(vials) { return vials.map(function (vial) { return vial.liquids.map(function (liquid) { return liquid.color + ":" + liquid.ratio; }).join(","); }).join("|"); } function isSolved(vials) { return vials.every(function (vial) { return vial.liquids.length === 0 || vial.liquids.every(function (liquid) { return liquid.color === vial.liquids[0].color; }); }); } function getNextStates(vials) { var nextStates = []; for (var i = 0; i < vials.length; i++) { for (var j = 0; j < vials.length; j++) { if (i !== j && vials[i].canPour(vials[j]) > 0) { var newVials = deepCopyVials(vials); var liquid = newVials[i].removeLiquid(newVials[i].canPour(newVials[j])); newVials[j].addLiquid(liquid, liquid.ratio); nextStates.push(newVials); } } } return nextStates; } stateQueue.push(deepCopyVials(self.vials)); visitedStates.push(serializeState(self.vials)); var maxDepth = 1000; var heuristicLimit = 100; var heuristicChecks = 0; var depth = 0; while (stateQueue.length > 0 && depth < maxDepth) { var currentState = stateQueue.shift(); if (isSolved(currentState)) { return true; } var nextStates = getNextStates(currentState); heuristicChecks++; if (heuristicChecks > heuristicLimit) { return false; } for (var k = 0; k < nextStates.length; k++) { var nextState = nextStates[k]; var serializedState = serializeState(nextState); if (visitedStates.indexOf(serializedState) === -1) { visitedStates.push(serializedState); stateQueue.push(nextState); } } depth++; } return false; }; self.reloadDistribution = function () { var savedVials = lastDistributionConfig; if (self.vials && Array.isArray(self.vials) && self.vials.length > 0) { self.vials.forEach(function (vial, i) { if (savedVials[i]) { vial.liquids = savedVials[i].liquids.map(function (liquid) { return { color: liquid.color, ratio: liquid.ratio }; }); vial.renderLiquids(); } }); } }; // Check for win conditions self.checkWinCondition = function () { // Implement logic to check if the puzzle is solved var colorArray = []; if (!self.vials || self.vials.length === 0) { return false; // No vials to check } for (var i = 0; i < self.vials.length; i++) { if (self.vials[i].liquids.length > 0) { var firstColor = self.vials[i].liquids[0].color; if (colorArray.indexOf(firstColor) !== -1) { return false; // Color already found in another vial } colorArray.push(firstColor); for (var j = 1; j < self.vials[i].liquids.length; j++) { if (self.vials[i].liquids[j].color !== firstColor) { return false; // Different colors in the same vial } } } } return true; }; // Initialize the puzzle manager self.init = function (level) { self.initVials(); self.initLiquids(level); self.distributeLiquids(); for (var i = 0; i < self.vials.length; i++) { self.vials[i].renderLiquids(); } updateDebugText('Puzzle Solvable: ' + self.isSolvable()); }; return self; }; var BASE_LIQUID_RATIO = 0.25; var currentLevel = 1; // TEMP DEBUG 1; var maxPerLine = 5; var score = 0; var isPlaying = false; var roundDuration = 60; // Global variable for round duration var selectionYOffset = 300; var distributionConfigurations = []; var lastDistributionConfig = null; var liquidStream; var scoreTxt; var timerTxt; var debugTxt; var restartButton; var isDebug = true; var board; var colorList = { blue: 0x0000FF, // DodgerBlue green: 0x00FF00, // LimeGreen red: 0xFF0000, // OrangeRed white: 0xFFFFFF, // White yellow: 0xFFFF00, // Yellow purple: 0x800080, // Purple cyan: 0x00FFFF, // Cyan magenta: 0xFF00FF, // Magenta orange: 0xFFA500, // Orange pink: 0xFFC0CB // Pink }; function log() { if (isDebug) { var _console; (_console = console).log.apply(_console, arguments); } } // Function to update score function updateScore(newScore) { score = newScore; if (scoreTxt) { if (newScore) { scoreTxt.setText(newScore.toString()); } else { scoreTxt.setText('0'); } } } // Function to update timer function updateTimer(newTime) { timeLeft = newTime; timerTxt.setText(timeLeft.toString()); } // Game update function game.update = function () { // Update timer if (LK.ticks % 60 == 0) { // Decrease time every second updateTimer(timeLeft - 1); if (timeLeft <= 0) { if (selectedTube) { selectedTube.scale.set(1, 1); // Reset the scale of the selected tube // Update debug text with current time and score updateDebugText('Time: ' + timeLeft + ' | Score: ' + score); } initRound(true); // Reset the time counter updateTimer(roundDuration); } } }; function initUI() { // Add background image var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChildAt(background, 0); // Ensure background is behind all other elements // Add board asset board = LK.getAsset('board', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, // Increase the size of the board scaleY: 1.2, // Increase the size of the board x: 2048 / 2, y: 2732 / 2 }); game.addChild(board); scoreTxt = new Text2('0', { size: 140, fill: "#ffffff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); timerTxt = new Text2('60', { size: 140, fill: "#ffffff" }); timerTxt.anchor.set(1, 0); LK.gui.topRight.addChild(timerTxt); // Create debug text debugTxt = new Text2('Debug Info', { size: 50, fill: "#FFFFFF" }); debugTxt.anchor.set(0, 1); LK.gui.bottomLeft.addChild(debugTxt); levelTxt = new Text2('Level: ' + currentLevel, { size: 100, fill: "#ffffff" }); levelTxt.anchor.set(1, 1); LK.gui.bottomRight.addChild(levelTxt); restartButton = LK.getAsset('restartRound', { anchorX: 0.5, anchorY: 0.5, x: 612, y: 130 }); game.addChild(restartButton); restartButton.down = function () { LK.getSound('reset').play(); initRound(true); }; } function initRound(reset) { log("initRound started with reset:", reset); // Remove previous vials if (isPouring) { log("Removing previous vials"); isPouring = false; if (selectedTube) { if (selectedTube) { selectedTube.x = selectedTube.baseX; selectedTube.y = selectedTube.baseY; if (selectedTube) { if (selectedTube) { selectedTube.rotation = 0; } } } } if (pourInterval) { LK.clearInterval(pourInterval); } liquidStream.stop(); } if (reset && lastDistributionConfig) { log("Reloading last distribution configuration:", lastDistributionConfig); puzzleManager.reloadDistribution(); } else { if (puzzleManager.vials) { for (var i = 0; i < puzzleManager.vials.length; i++) { game.removeChild(puzzleManager.vials[i]); } } log("Initializing puzzle manager for level:", currentLevel); puzzleManager.init(currentLevel); lastDistributionConfig = deepCopyVials(puzzleManager.vials); log("Level configuration saved:", lastDistributionConfig); } selectedTube = null; if (puzzleManager.vials && puzzleManager.vials.length > 0) { log("Restoring vial properties"); puzzleManager.vials.forEach(function (vial) { vial.scale.set(1, 1); // Reset the scale of each vial vial.x = vial.baseX; // Restore base x-coordinate vial.y = vial.baseY; // Restore base y-coordinate vial.rotation = 0; // Reset rotation }); } selectedTube = null; timeLeft = roundDuration; // Initialize the timer with the global round duration log("initRound completed"); } // Function to initialize the game function initializeGame() { score = 0; // Initialize the score with 0 initUI(); updateScore(score); puzzleManager = new PuzzleManager(); initRound(); updateTimer(timeLeft); isPlaying = true; } initializeGame();
===================================================================
--- original.js
+++ change.js
@@ -55,8 +55,9 @@
ratio = 1 - totalRatio; // Adjust ratio to fit within the tube's capacity
}
// Fix floating-point precision issue
ratio = Math.round(ratio / BASE_LIQUID_RATIO) * BASE_LIQUID_RATIO;
+ ratio = parseFloat(ratio.toFixed(2));
if (self.liquids.length > 0 && self.liquids[self.liquids.length - 1].color === liquid.color) {
self.liquids[self.liquids.length - 1].ratio += ratio;
} else {
if (ratio > 0) {
@@ -92,8 +93,9 @@
} else {
topLiquid.ratio -= ratio;
// Fix floating-point precision issue
var removedRatio = Math.round(ratio / BASE_LIQUID_RATIO) * BASE_LIQUID_RATIO;
+ removedRatio = parseFloat(removedRatio.toFixed(2));
if (topLiquid.ratio <= 0) {
self.liquids.pop();
}
return {
@@ -202,16 +204,18 @@
// Shrink the height of the top liquid in the selected tube
var selectedTopLiquid = selectedTube.liquids[selectedTube.liquids.length - 1];
var shrinkRatio = Math.min(0.01, selectedTopLiquid.ratio); // Ensure we don't shrink more than available
selectedTopLiquid.ratio -= shrinkRatio; // Adjust the shrink rate as needed
+ selectedTopLiquid.ratio = parseFloat(selectedTopLiquid.ratio.toFixed(2));
if (selectedTopLiquid.ratio <= 0) {
selectedTube.liquids.pop(); // Remove the liquid if its ratio is zero
}
selectedTube.renderLiquids();
// Grow the height of the top liquid in the destination tube
var destinationTopLiquid = self.liquids[self.liquids.length - 1];
if (destinationTopLiquid && destinationTopLiquid.color === selectedTopLiquid.color) {
destinationTopLiquid.ratio += shrinkRatio; // Adjust the growth rate as needed
+ destinationTopLiquid.ratio = parseFloat(destinationTopLiquid.ratio.toFixed(2));
} else {
var totalRatio = self.liquids.reduce(function (sum, liquid) {
return sum + liquid.ratio;
}, 0);
Basic white Restart icon (rounded arrow). UI
Une classe d’une école de sorcière sans les élèves.
un sablier de sorcière.
a bubble.
exploded broken glass
Yound generously beautifull teacher witch smiling, with glasses, a black witch hat, holding a little brown book in her hands and looking at the camera. wearing light black clothes. Torso head and hat should appear.
tap
Sound effect
drop
Sound effect
reset
Sound effect
wrong
Sound effect
yes
Sound effect
goodJob
Sound effect
pouring
Sound effect
welcome
Sound effect
rememberTheRules
Sound effect
letsgo
Sound effect
hurryUp
Sound effect
boom
Sound effect
tryAgain
Sound effect
rainbowBoom
Sound effect
youDidIt
Sound effect
letmetry
Sound effect
rainbowMix
Sound effect
thankYou1
Sound effect
thankYou2
Sound effect
thankYou3
Sound effect
thankYou4
Sound effect
bonusTime
Sound effect