Code edit (1 edits merged)
Please save this source code
User prompt
When you score 1000000 points, play a new sound asset instead of the zeus voice
User prompt
When you score 1000000 points, play another sound
User prompt
"Design a score text for a mythical slot game similar to 'Gates of Olympus'. The font should be bold, divine, and slightly ornate, inspired by ancient Greek lettering. Use golden gradient colors with a subtle glowing effect, making it look powerful and sacred. The text should be easy to read and suitable for a high-fantasy game UI. Background: transparent.
Code edit (1 edits merged)
Please save this source code
User prompt
give an extra 5000 points every time gem_zeus appears on the screen
User prompt
give each gem_zeus an extra 5000 points
User prompt
play a sound when the score is 100000
User prompt
combo not working, let it work
User prompt
gem_zeus let the score count
Code edit (1 edits merged)
Please save this source code
User prompt
let music be turned off at startup
User prompt
background music is still too loud
User prompt
fix background music volume still 100%
User prompt
background music too loud
User prompt
background music volume 10%
User prompt
music mute button at the bottom right
User prompt
no music on/off in pause menu
User prompt
pause menu does not appear
User prompt
olympus_theme on/off button not showing in pause menu
User prompt
olympus_theme on/off button not showing in pause menu
User prompt
get olympus_theme on/off button in pause menu
User prompt
Please fix the bug: 'LK.enablePauseMenu is not a function' in or related to this line: 'LK.enablePauseMenu();' Line Number: 789
User prompt
add pause menu
User prompt
have a button to turn on/off background music in the pause menu
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Gem class var Gem = Container.expand(function () { var self = Container.call(this); // Properties self.gemType = null; // 'red', 'blue', etc. self.row = 0; self.col = 0; self.isMoving = false; self.isMatched = false; self.multiplier = 1; // For Zeus or special gems // Attach asset self.setType = function (type) { self.gemType = type; if (self.gemAsset) { self.removeChild(self.gemAsset); } var assetId = 'gem_' + type; self.gemAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Zeus gem: add a glow effect (tint) if (type === 'zeus') { self.gemAsset.tint = 0xadd8ff; } }; // Animate match (fade out) self.animateMatch = function (_onFinish) { self.isMoving = true; tween(self.gemAsset, { alpha: 0 }, { duration: 250, easing: tween.easeIn, onFinish: function onFinish() { self.isMoving = false; if (_onFinish) { _onFinish(); } } }); }; // Animate swap (move to new position) self.animateMove = function (targetX, targetY, _onFinish2) { self.isMoving = true; tween(self, { x: targetX, y: targetY }, { duration: 180, easing: tween.easeInOut, onFinish: function onFinish() { self.isMoving = false; if (_onFinish2) { _onFinish2(); } } }); }; // Reset alpha after match self.resetAlpha = function () { self.gemAsset.alpha = 1; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a2236 }); /**** * Game Code ****/ // --- Game Constants --- // Gems: 6 types + Zeus special var GRID_ROWS = 8; var GRID_COLS = 8; var GEM_SIZE = 200; // px, including margin var GEM_TYPES = ['red', 'blue', 'green', 'yellow', 'purple', 'orange']; var ZEUS_CHANCE = 0.07; // Chance for Zeus gem to spawn on refill var MOVES_LIMIT = 30; // --- Game State --- var grid = []; // 2D array [row][col] of Gem var selectedGem = null; var swappingGem = null; var canInput = true; var score = 0; var movesLeft = MOVES_LIMIT; var multiplier = 1; var comboCount = 0; var powerMeter = 0; var powerMeterMax = 10; var isPowerActive = false; var movesMade = 0; // Track number of moves made // --- UI Elements --- var scoreTxt = new Text2('Score: 0', { size: 90, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var powerMeterTxt = new Text2('⚡ 0/10', { size: 70, fill: 0x00E6E6 }); powerMeterTxt.anchor.set(0.5, 0); LK.gui.bottom.addChild(powerMeterTxt); // Combo text at the bottom of the screen var comboTxt = new Text2('', { size: 100, fill: "#fff" }); comboTxt.anchor.set(0.5, 1); LK.gui.bottom.addChild(comboTxt); // --- Board Position --- var boardOffsetX = (2048 - GRID_COLS * GEM_SIZE) / 2; var boardOffsetY = 300; // --- Helper Functions --- function getGemAt(row, col) { if (row < 0 || row >= GRID_ROWS || col < 0 || col >= GRID_COLS) { return null; } return grid[row][col]; } function setGemAt(row, col, gem) { grid[row][col] = gem; if (gem) { gem.row = row; gem.col = col; } } function gemWorldPos(row, col) { return { x: boardOffsetX + col * GEM_SIZE + GEM_SIZE / 2, y: boardOffsetY + row * GEM_SIZE + GEM_SIZE / 2 }; } function randomGemType() { // Zeus gems only spawn after 2 moves have been made if (movesMade >= 2 && Math.random() < ZEUS_CHANCE) { return 'zeus'; } return GEM_TYPES[Math.floor(Math.random() * GEM_TYPES.length)]; } function updateUI() { scoreTxt.setText('Score: ' + score); powerMeterTxt.setText('⚡ ' + powerMeter + '/' + powerMeterMax); } function deselectGem() { if (selectedGem && selectedGem.gemAsset) { selectedGem.gemAsset.scaleX = 1; selectedGem.gemAsset.scaleY = 1; } selectedGem = null; } function selectGem(gem) { deselectGem(); selectedGem = gem; if (gem && gem.gemAsset) { gem.gemAsset.scaleX = 1.2; gem.gemAsset.scaleY = 1.2; } } function areAdjacent(gem1, gem2) { if (!gem1 || !gem2) { return false; } var dr = Math.abs(gem1.row - gem2.row); var dc = Math.abs(gem1.col - gem2.col); return dr + dc === 1; } function swapGems(gem1, gem2, animate, onFinish) { // Swap in grid var r1 = gem1.row, c1 = gem1.col; var r2 = gem2.row, c2 = gem2.col; setGemAt(r1, c1, gem2); setGemAt(r2, c2, gem1); // Animate var pos1 = gemWorldPos(r1, c1); var pos2 = gemWorldPos(r2, c2); if (animate) { gem1.animateMove(pos2.x, pos2.y, function () { gem2.animateMove(pos1.x, pos1.y, function () { if (onFinish) { onFinish(); } }); }); } else { gem1.x = pos2.x; gem1.y = pos2.y; gem2.x = pos1.x; gem2.y = pos1.y; if (onFinish) { onFinish(); } } } function refillBoard(onFinish) { var falling = 0; for (var col = 0; col < GRID_COLS; col++) { var emptyRows = []; for (var row = GRID_ROWS - 1; row >= 0; row--) { if (!grid[row][col]) { emptyRows.push(row); } } // Improved falling logic: process from bottom up, for each cell, if empty, pull down the nearest gem above for (var row = GRID_ROWS - 1; row >= 0; row--) { if (!grid[row][col]) { // Find the nearest gem above var found = false; for (var r2 = row - 1; r2 >= 0; r2--) { var gem = grid[r2][col]; if (gem) { setGemAt(row, col, gem); setGemAt(r2, col, null); var pos = gemWorldPos(row, col); falling++; gem.animateMove(pos.x, pos.y, function () { falling--; }); found = true; break; } } // If nothing found above, spawn new gem if (!found) { var newGem = new Gem(); var type = randomGemType(); newGem.setType(type); setGemAt(row, col, newGem); var pos = gemWorldPos(row, col); newGem.x = pos.x; newGem.y = pos.y - GEM_SIZE * 2; // Drop from above game.addChild(newGem); falling++; newGem.animateMove(pos.x, pos.y, function () { falling--; }); } } } } // Wait for all falling to finish var _wait = function wait() { if (falling > 0) { LK.setTimeout(_wait, 40); } else { if (onFinish) { onFinish(); } } }; _wait(); } function findMatches() { var matches = []; // Horizontal for (var row = 0; row < GRID_ROWS; row++) { var streak = 1; for (var col = 1; col <= GRID_COLS; col++) { var prev = getGemAt(row, col - 1); var curr = getGemAt(row, col); if (curr && prev && curr.gemType === prev.gemType && curr.gemType !== 'zeus') { streak++; } else { if (streak >= 3 && prev && prev.gemType !== 'zeus') { var match = []; for (var k = 0; k < streak; k++) { match.push(getGemAt(row, col - 1 - k)); } matches.push(match); } streak = 1; } } } // Vertical for (var col = 0; col < GRID_COLS; col++) { var streak = 1; for (var row = 1; row <= GRID_ROWS; row++) { var prev = getGemAt(row - 1, col); var curr = getGemAt(row, col); if (curr && prev && curr.gemType === prev.gemType && curr.gemType !== 'zeus') { streak++; } else { if (streak >= 3 && prev && prev.gemType !== 'zeus') { var match = []; for (var k = 0; k < streak; k++) { match.push(getGemAt(row - 1 - k, col)); } matches.push(match); } streak = 1; } } } // Zeus gems: match any adjacent gems for (var row = 0; row < GRID_ROWS; row++) { for (var col = 0; col < GRID_COLS; col++) { var gem = getGemAt(row, col); if (gem && gem.gemType === 'zeus') { var adj = []; for (var dr = -1; dr <= 1; dr++) { for (var dc = -1; dc <= 1; dc++) { if (dr === 0 && dc === 0) { continue; } var n = getGemAt(row + dr, col + dc); if (n && n.gemType !== 'zeus') { adj.push(n); } } } if (adj.length > 0) { matches.push([gem].concat(adj)); } } } } return matches; } function markMatches(matches) { for (var i = 0; i < matches.length; i++) { for (var j = 0; j < matches[i].length; j++) { var gem = matches[i][j]; if (gem) { gem.isMatched = true; } } } } function removeMatches(onFinish) { var removed = 0; for (var row = 0; row < GRID_ROWS; row++) { for (var col = 0; col < GRID_COLS; col++) { var gem = getGemAt(row, col); if (gem && gem.isMatched) { removed++; (function (gem, row, col) { gem.animateMatch(function () { game.removeChild(gem); setGemAt(row, col, null); removed--; }); })(gem, row, col); } } } // Wait for all to finish var _wait2 = function wait() { if (removed > 0) { LK.setTimeout(_wait2, 40); } else { if (onFinish) { onFinish(); } } }; _wait2(); } function resetGemFlags() { for (var row = 0; row < GRID_ROWS; row++) { for (var col = 0; col < GRID_COLS; col++) { var gem = getGemAt(row, col); if (gem) { gem.isMatched = false; gem.resetAlpha(); } } } } function triggerZeusPower(gem, onFinish) { // Randomly clear a row or column var mode = Math.random() < 0.5 ? 'row' : 'col'; var idx = mode === 'row' ? gem.row : gem.col; var gemsToClear = []; if (mode === 'row') { for (var c = 0; c < GRID_COLS; c++) { var g = getGemAt(idx, c); if (g && g !== gem) { gemsToClear.push(g); } } } else { for (var r = 0; r < GRID_ROWS; r++) { var g = getGemAt(r, idx); if (g && g !== gem) { gemsToClear.push(g); } } } // Animate Zeus gem (grow and explode) LK.getSound('zeus').play(); var originalScaleX = gem.gemAsset.scaleX; var originalScaleY = gem.gemAsset.scaleY; tween(gem.gemAsset, { scaleX: 2.5, scaleY: 2.5, alpha: 0 }, { duration: 400, easing: tween.cubicOut, onFinish: function onFinish() { gem.gemAsset.scaleX = originalScaleX; gem.gemAsset.scaleY = originalScaleY; gem.gemAsset.alpha = 1; } }); LK.effects.flashObject(gem, 0x00ffff, 400); // Mark for removal for (var i = 0; i < gemsToClear.length; i++) { gemsToClear[i].isMatched = true; } // Remove Zeus gem itself gem.isMatched = true; // Show multiplier popup var mult = 2 + Math.floor(Math.random() * 3); // 2x-4x multiplier = mult; LK.effects.flashScreen(0xadd8ff, 400); // Animate Zeus lightning (screen flash) if (onFinish) { LK.setTimeout(onFinish, 400); } } // Combo transfer state: track if we're in a combo chain (from first explosion to end) if (typeof comboTransferActive === "undefined") { var comboTransferActive = false; } function processMatches(matches, onFinish) { if (matches.length === 0) { // Combo chain ends here comboTransferActive = false; comboCount = 0; multiplier = 1; comboTxt.setText(''); updateUI(); if (onFinish) { onFinish(); } return; } // Combo chain starts on first explosion if (!comboTransferActive) { comboTransferActive = true; comboCount = 1; } else { comboCount++; } if (comboCount > 1) { LK.getSound('match').play(); LK.getSound('combo').play(); comboTxt.setText('Combo x' + comboCount); // Animate comboTxt: pop and fade in comboTxt.alpha = 0.2; comboTxt.scaleX = 1.8; comboTxt.scaleY = 1.8; tween(comboTxt, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 350, easing: tween.cubicOut, onFinish: function onFinish() { // Vibrate effect: rapid left-right shake var originalX = comboTxt.x; var vibrateTimes = 6; var vibrateDistance = 24; var vibrateDuration = 18; var _vibrateStep = function vibrateStep(i) { if (i > vibrateTimes) { comboTxt.x = originalX; return; } var dir = i % 2 === 0 ? 1 : -1; tween(comboTxt, { x: originalX + dir * vibrateDistance }, { duration: vibrateDuration, easing: tween.linear, onFinish: function onFinish() { tween(comboTxt, { x: originalX }, { duration: vibrateDuration, easing: tween.linear, onFinish: function onFinish() { _vibrateStep(i + 1); } }); } }); }; _vibrateStep(1); } }); } else { LK.getSound('match').play(); comboTxt.setText(''); // Optionally fade out comboTxt if needed tween(comboTxt, { alpha: 0 }, { duration: 200, easing: tween.linear }); } // Increase each gem_zeus multiplier by 1 for each combo for (var i = 0; i < matches.length; i++) { for (var j = 0; j < matches[i].length; j++) { var gem = matches[i][j]; if (gem && gem.gemType === 'zeus') { if (typeof gem.multiplier !== 'number') { gem.multiplier = 1; } gem.multiplier += 1; } } } // Score: 100 per gem, * multiplier, * combo var gemsMatched = 0; var zeusTriggered = false; for (var i = 0; i < matches.length; i++) { for (var j = 0; j < matches[i].length; j++) { var gem = matches[i][j]; if (gem && !gem.isMatched) { // Count all gems, including zeus, towards score gemsMatched++; if (gem.gemType === 'zeus') { zeusTriggered = true; } } } } // Power meter powerMeter += gemsMatched; if (powerMeter > powerMeterMax) { powerMeter = powerMeterMax; } // If Zeus, trigger power if (zeusTriggered) { for (var i = 0; i < matches.length; i++) { for (var j = 0; j < matches[i].length; j++) { var gem = matches[i][j]; if (gem && gem.gemType === 'zeus') { triggerZeusPower(gem, function () { markMatches(matches); removeMatches(function () { refillBoard(function () { resetGemFlags(); var newMatches = findMatches(); processMatches(newMatches, onFinish); }); }); }); return; } } } } else { // No Zeus, normal match markMatches(matches); removeMatches(function () { score += gemsMatched * 100 * multiplier * comboCount; updateUI(); refillBoard(function () { resetGemFlags(); var newMatches = findMatches(); processMatches(newMatches, onFinish); }); }); } } function trySwapAndMatch(gem1, gem2) { canInput = false; LK.getSound('swap').play(); swapGems(gem1, gem2, true, function () { var matches = findMatches(); if (matches.length > 0) { movesLeft--; movesMade++; // Increment movesMade after a valid move updateUI(); processMatches(matches, function () { canInput = true; checkGameEnd(); }); } else { // No match, swap back swapGems(gem1, gem2, true, function () { canInput = true; }); } }); } function checkGameEnd() { // Endless mode: do nothing, never trigger game over } // --- Power Meter Activation --- function activatePower() { if (powerMeter < powerMeterMax || isPowerActive) { return; } isPowerActive = true; LK.getSound('powerup').play(); // Randomly clear 2 rows or columns var cleared = 0; for (var i = 0; i < 2; i++) { var mode = Math.random() < 0.5 ? 'row' : 'col'; var idx = Math.floor(Math.random() * (mode === 'row' ? GRID_ROWS : GRID_COLS)); for (var j = 0; j < (mode === 'row' ? GRID_COLS : GRID_ROWS); j++) { var gem = mode === 'row' ? getGemAt(idx, j) : getGemAt(j, idx); if (gem) { gem.isMatched = true; cleared++; } } } LK.effects.flashScreen(0xffff00, 600); removeMatches(function () { score += cleared * 200 * multiplier; powerMeter = 0; isPowerActive = false; updateUI(); refillBoard(function () { resetGemFlags(); var newMatches = findMatches(); processMatches(newMatches, function () { canInput = true; checkGameEnd(); }); }); }); } // --- Board Initialization --- function fillBoardNoMatches() { // Fill board, avoid initial matches for (var row = 0; row < GRID_ROWS; row++) { grid[row] = []; for (var col = 0; col < GRID_COLS; col++) { var gem = new Gem(); var type; do { // Prevent Zeus from spawning at game start do { type = randomGemType(); } while (type === 'zeus'); gem.setType(type); setGemAt(row, col, gem); } while (col >= 2 && getGemAt(row, col - 1).gemType === type && getGemAt(row, col - 2).gemType === type || row >= 2 && getGemAt(row - 1, col).gemType === type && getGemAt(row - 2, col).gemType === type); var pos = gemWorldPos(row, col); gem.x = pos.x; gem.y = pos.y; game.addChild(gem); } } } // --- Input Handling --- game.down = function (x, y, obj) { if (!canInput) { return; } // Convert to board coordinates var bx = x - boardOffsetX; var by = y - boardOffsetY; var col = Math.floor(bx / GEM_SIZE); var row = Math.floor(by / GEM_SIZE); var gem = getGemAt(row, col); if (!gem) { return; } if (selectedGem === gem) { deselectGem(); return; } if (!selectedGem) { selectGem(gem); } else { if (areAdjacent(selectedGem, gem)) { swappingGem = gem; trySwapAndMatch(selectedGem, gem); deselectGem(); } else { selectGem(gem); } } }; game.move = function (x, y, obj) { // No drag-swap for now (tap only) }; game.up = function (x, y, obj) { // No drag-swap for now (tap only) }; // --- Power Meter Tap (activate power) --- powerMeterTxt.interactive = true; powerMeterTxt.down = function (x, y, obj) { if (powerMeter >= powerMeterMax && canInput) { canInput = false; activatePower(); } }; // No custom pause menu logic; rely on LK's built-in pause menu // --- Music Mute Button --- var musicMuted = true; var musicBtn = new Text2('🔇', { size: 110, fill: "#fff" }); musicBtn.anchor.set(1, 1); musicBtn.x = 0; // Will be positioned by LK.gui.bottomRight musicBtn.y = 0; musicBtn.interactive = true; musicBtn.down = function (x, y, obj) { musicMuted = !musicMuted; if (musicMuted) { LK.stopMusic(); musicBtn.setText('🔇'); } else { LK.playMusic('olympus_theme', { volume: 0.02, fade: { start: 0, end: 1, duration: 600 } }); musicBtn.setText('🔊'); } }; LK.gui.bottomRight.addChild(musicBtn); // --- Game Update --- game.update = function () { // Play music if not playing and not muted if (!game._musicStarted && !musicMuted) { LK.playMusic('olympus_theme', { volume: 0.02, fade: { start: 0, end: 1, duration: 1000 } }); game._musicStarted = true; } if (!game._musicStarted && musicMuted) { // Don't play music, but mark as started to prevent repeated checks game._musicStarted = true; } // Prevent input during animations // (Handled by canInput flag) }; // Add pause menu support // LK's built-in pause menu is enabled by default; no need to call LK.enablePauseMenu() // --- Game Start --- function startGame() { // Reset state grid = []; selectedGem = null; swappingGem = null; canInput = true; score = 0; movesLeft = MOVES_LIMIT; multiplier = 1; comboCount = 0; powerMeter = 0; isPowerActive = false; movesMade = 0; // Reset movesMade on game start updateUI(); // Remove all children except UI for (var i = game.children.length - 1; i >= 0; i--) { var ch = game.children[i]; game.removeChild(ch); } fillBoardNoMatches(); } startGame();
===================================================================
--- original.js
+++ change.js
@@ -456,11 +456,12 @@
}
// Combo chain starts on first explosion
if (!comboTransferActive) {
comboTransferActive = true;
- // You can add any "combo start" logic here if needed
+ comboCount = 1;
+ } else {
+ comboCount++;
}
- comboCount++;
if (comboCount > 1) {
LK.getSound('match').play();
LK.getSound('combo').play();
comboTxt.setText('Combo x' + comboCount);
diamond. In-Game asset. 2d. High contrast. No shadows
strawberry. In-Game asset. 2d. High contrast. No shadows
banana. In-Game asset. 2d. High contrast. No shadows
Emerald. In-Game asset. 2d. High contrast. No shadows
eggplant. In-Game asset. 2d. High contrast. No shadows
Orange. In-Game asset. 2d. High contrast. No shadows
white lightning but in a yellow neon frame. In-Game asset. 2d. High contrast. No shadows