User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'down')' in or related to this line: 'self.down.call(this, x, y, obj);' Line Number: 343
User prompt
scale everything 40 % again
User prompt
scale everything up 40 %
User prompt
not easy to be wining
User prompt
make more long spin
User prompt
make real rule logic of spin
User prompt
make more long spin
User prompt
make long rolling
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'call')' in or related to this line: 'Button.prototype.down.call(this, x, y, obj);' Line Number: 343
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'down')' in or related to this line: 'self.down.call(this, x, y, obj);' Line Number: 355
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'call')' in or related to this line: 'Button.prototype.down.call(this, x, y, obj);' Line Number: 350
Code edit (1 edits merged)
Please save this source code
User prompt
Lucky Spin Jackpot
Initial prompt
make jackpot machine game with 3 symbol
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { coins: 100 }); /**** * Classes ****/ var Button = Container.expand(function (text, width, height) { var self = Container.call(this); var background = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: width || 200, height: height || 80 }); var label = new Text2(text || 'Button', { size: 36, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); self.disabled = false; self.setText = function (newText) { label.setText(newText); return self; }; self.disable = function () { self.disabled = true; background.alpha = 0.5; return self; }; self.enable = function () { self.disabled = false; background.alpha = 1.0; return self; }; self.down = function (x, y, obj) { if (!self.disabled) { background.alpha = 0.7; } }; self.up = function (x, y, obj) { if (!self.disabled) { background.alpha = 1.0; } }; return self; }); var Lever = Container.expand(function () { var self = Container.call(this); self.isDown = false; self.isAnimating = false; self.onPullComplete = null; var base = self.attachAsset('leverBase', { anchorX: 0.5, anchorY: 1.0 }); var handle = self.attachAsset('leverHandle', { anchorX: 0.5, anchorY: 1.0, y: -50 }); var knob = self.attachAsset('leverKnob', { anchorX: 0.5, anchorY: 0.5, y: -275 }); self.down = function (x, y, obj) { if (!self.isAnimating && !self.isDown) { self.isDown = true; self.pullDown(); } }; self.pullDown = function () { self.isAnimating = true; LK.getSound('leverPull').play(); // Animate the lever down tween(handle, { rotation: Math.PI / 3 }, { duration: 300, easing: tween.bounceOut, onFinish: function onFinish() { // Pull complete, trigger callback if (self.onPullComplete) { self.onPullComplete(); } // Return to original position after delay LK.setTimeout(function () { tween(handle, { rotation: 0 }, { duration: 500, easing: tween.elasticOut, onFinish: function onFinish() { self.isAnimating = false; self.isDown = false; } }); }, 500); } }); }; return self; }); var Reel = Container.expand(function () { var self = Container.call(this); self.isSpinning = false; self.spinSpeed = 0; self.spinTime = 0; self.maxSpinTime = 0; self.finalSymbol = 0; self.onStopCallback = null; var background = self.attachAsset('reelBackground', { anchorX: 0.5, anchorY: 0.5 }); var symbols = []; var symbolPositions = [-140, 0, 140]; for (var i = 0; i < 3; i++) { var symbol = new SymbolDisplay(); symbol.setSymbol(Math.floor(Math.random() * 3) + 1); symbol.y = symbolPositions[i]; symbols.push(symbol); self.addChild(symbol); } self.getCurrentSymbol = function () { // The middle symbol is the active one return symbols[1].symbolValue; }; self.spin = function (duration, finalSymbolValue, callback) { self.isSpinning = true; self.spinSpeed = 80; // Increase speed for long rolling effect self.spinTime = 0; self.maxSpinTime = duration; self.finalSymbol = finalSymbolValue; self.onStopCallback = callback; return self; }; self.update = function () { if (!self.isSpinning) { return; } self.spinTime += 1 / 60; // assuming 60 FPS // Move symbols down for (var i = 0; i < symbols.length; i++) { symbols[i].y += self.spinSpeed; // If a symbol goes beyond the visible area, move it to the top if (symbols[i].y > 280) { symbols[i].y = -280; // Randomize symbols during spin if (self.spinTime < self.maxSpinTime - 0.5) { symbols[i].setSymbol(Math.floor(Math.random() * 3) + 1); } else { // When approaching end, set to final values var offset = i - 1; var targetSymbol = (self.finalSymbol + offset) % 3 + 1; symbols[i].setSymbol(targetSymbol); } } } // Slow down and stop at the right time if (self.spinTime >= self.maxSpinTime) { self.isSpinning = false; // Ensure the middle symbol is exactly at y=0 for (var j = 0; j < symbols.length; j++) { symbols[j].y = symbolPositions[j]; } LK.getSound('reelStop').play(); if (self.onStopCallback) { self.onStopCallback(); } } else if (self.spinTime > self.maxSpinTime - 0.5) { // Slow down gradually self.spinSpeed = Math.max(5, self.spinSpeed * 0.98); // Adjust slow down rate for long rolling effect } }; return self; }); var SymbolDisplay = Container.expand(function () { var self = Container.call(this); self.symbolValue = 0; self.symbolGraphic = null; self.setSymbol = function (symbolId) { if (self.symbolGraphic) { self.removeChild(self.symbolGraphic); } self.symbolValue = symbolId; var assetId = 'symbol' + symbolId; self.symbolGraphic = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); return self; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Bar // Lemon // Cherry // Game state var coins = storage.coins || 100; var betAmount = 10; var isSpinning = false; var spinResults = [0, 0, 0]; var reels = []; var activeReels = 0; // Constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var REEL_SPACING = 200; var SYMBOL_VALUES = { "1-1-1": 30, // Reduce win amount for three cherries "2-2-2": 60, // Reduce win amount for three lemons "3-3-3": 120, // Reduce win amount for three bars (jackpot) "1-1-2": 15, // Two cherries and a lemon "1-1-3": 15, // Two cherries and a bar "2-2-1": 15, // Two lemons and a cherry "2-2-3": 15, // Two lemons and a bar "1-2-3": 5 // One of each }; // Create main slot machine components var slotMachine = new Container(); game.addChild(slotMachine); slotMachine.x = GAME_WIDTH / 2; slotMachine.y = GAME_HEIGHT / 2 - 196; // Background var background = slotMachine.addChild(LK.getAsset('slotBackground', { anchorX: 0.5, anchorY: 0.5 })); // Main frame var frame = slotMachine.addChild(LK.getAsset('slotFrame', { anchorX: 0.5, anchorY: 0.5, y: -98 })); // Add 3 reels for (var i = 0; i < 3; i++) { var reel = new Reel(); reel.x = (i - 1) * REEL_SPACING * 1.96; reel.y = -98; slotMachine.addChild(reel); reels.push(reel); } // Payline indicators var leftIndicator = slotMachine.addChild(LK.getAsset('paylineIndicator', { anchorX: 0.5, anchorY: 0.5, x: -686, y: -98 })); var rightIndicator = slotMachine.addChild(LK.getAsset('paylineIndicator', { anchorX: 0.5, anchorY: 0.5, x: 686, y: -98 })); // Lever var lever = new Lever(); lever.x = 784; lever.y = 294; slotMachine.addChild(lever); // Set up lever callback lever.onPullComplete = function () { if (!isSpinning && coins >= betAmount) { startSpin(); } }; // Create UI elements var coinsDisplay = new Text2("Coins: " + coins, { size: 60, fill: 0xFFD700 }); coinsDisplay.anchor.set(0.5, 0.5); LK.gui.top.addChild(coinsDisplay); coinsDisplay.y = 196; var betButton = new Button("Bet: " + betAmount, 200, 80); betButton.x = GAME_WIDTH / 2; betButton.y = GAME_HEIGHT - 588; game.addChild(betButton); var cashOutButton = new Button("Cash Out", 200, 80); cashOutButton.x = GAME_WIDTH / 2 + 490; cashOutButton.y = GAME_HEIGHT - 588; game.addChild(cashOutButton); var spinButton = new Button("SPIN", 200, 80); spinButton.x = GAME_WIDTH / 2 - 490; spinButton.y = GAME_HEIGHT - 588; game.addChild(spinButton); var winText = new Text2("", { size: 70, fill: 0xFFD700 }); winText.anchor.set(0.5, 0.5); winText.y = GAME_HEIGHT / 2 + 490; winText.x = GAME_WIDTH / 2; game.addChild(winText); // Button event handlers spinButton.down = function (x, y, obj) { this.down.call(this, x, y, obj); if (!isSpinning && coins >= betAmount) { startSpin(); } }; betButton.down = function (x, y, obj) { this.down.call(this, x, y, obj); if (!isSpinning) { cycleBet(); } }; cashOutButton.down = function (x, y, obj) { this.down.call(this, x, y, obj); if (!isSpinning) { storage.coins = coins; LK.showYouWin(); } }; // Game functions function updateCoinsDisplay() { coinsDisplay.setText("Coins: " + coins); storage.coins = coins; } function cycleBet() { var betOptions = [5, 10, 25, 50, 100]; var currentIndex = betOptions.indexOf(betAmount); var nextIndex = (currentIndex + 1) % betOptions.length; betAmount = betOptions[nextIndex]; // Don't allow bets higher than current coins if (betAmount > coins) { betAmount = betOptions[0]; } betButton.setText("Bet: " + betAmount); } function startSpin() { if (isSpinning) { return; } // Deduct coins for the bet coins -= betAmount; updateCoinsDisplay(); // Clear any previous win display winText.setText(""); // Disable buttons during spin spinButton.disable(); betButton.disable(); isSpinning = true; activeReels = 0; LK.getSound('reelSpin').play(); // Generate random results for each reel for (var i = 0; i < 3; i++) { spinResults[i] = Math.floor(Math.random() * 4) + 1; // Increase range to reduce winning probability if (spinResults[i] > 3) { spinResults[i] = 1; } // Map any value greater than 3 back to 1 } // Spin each reel with staggered timing for (var i = 0; i < reels.length; i++) { var spinDuration = 5 + i * 1.0; // Further increase duration for an even longer rolling effect reels[i].spin(spinDuration, spinResults[i], function () { activeReels++; if (activeReels >= 3) { spinCompleted(); } }); } } function spinCompleted() { isSpinning = false; // Enable buttons again spinButton.enable(); betButton.enable(); // Check for winning combinations var combination = spinResults.join('-'); var winAmount = 0; // Check exact combinations if (SYMBOL_VALUES[combination]) { winAmount = SYMBOL_VALUES[combination] * betAmount / 10; } else { // Check for pairs (same symbol in first two positions) if (spinResults[0] === spinResults[1]) { winAmount = 2 * betAmount / 10; } else if (spinResults[1] === spinResults[2]) { winAmount = 2 * betAmount / 10; } else if (spinResults[0] === spinResults[2]) { winAmount = 2 * betAmount / 10; } } if (winAmount > 0) { // Award winnings coins += winAmount; updateCoinsDisplay(); // Display win message winText.setText("WIN: " + winAmount + " COINS!"); // Play appropriate sound if (combination === "3-3-3") { // Jackpot win! LK.getSound('jackpot').play(); LK.effects.flashScreen(0xFFD700, 1000); // Gold flash for jackpot } else { LK.getSound('win').play(); } } // Check if player is out of coins if (coins <= 0) { LK.setTimeout(function () { LK.showGameOver(); }, 2000); } } // Start background music LK.playMusic('bgMusic', { fade: { start: 0, end: 0.3, duration: 1000 } }); // Update function game.update = function () { // Update all reels for (var i = 0; i < reels.length; i++) { reels[i].update(); } // Disable spin button if not enough coins if (coins < betAmount && !spinButton.disabled) { spinButton.disable(); } else if (coins >= betAmount && spinButton.disabled && !isSpinning) { spinButton.enable(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
coins: 100
});
/****
* Classes
****/
var Button = Container.expand(function (text, width, height) {
var self = Container.call(this);
var background = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
width: width || 200,
height: height || 80
});
var label = new Text2(text || 'Button', {
size: 36,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.disabled = false;
self.setText = function (newText) {
label.setText(newText);
return self;
};
self.disable = function () {
self.disabled = true;
background.alpha = 0.5;
return self;
};
self.enable = function () {
self.disabled = false;
background.alpha = 1.0;
return self;
};
self.down = function (x, y, obj) {
if (!self.disabled) {
background.alpha = 0.7;
}
};
self.up = function (x, y, obj) {
if (!self.disabled) {
background.alpha = 1.0;
}
};
return self;
});
var Lever = Container.expand(function () {
var self = Container.call(this);
self.isDown = false;
self.isAnimating = false;
self.onPullComplete = null;
var base = self.attachAsset('leverBase', {
anchorX: 0.5,
anchorY: 1.0
});
var handle = self.attachAsset('leverHandle', {
anchorX: 0.5,
anchorY: 1.0,
y: -50
});
var knob = self.attachAsset('leverKnob', {
anchorX: 0.5,
anchorY: 0.5,
y: -275
});
self.down = function (x, y, obj) {
if (!self.isAnimating && !self.isDown) {
self.isDown = true;
self.pullDown();
}
};
self.pullDown = function () {
self.isAnimating = true;
LK.getSound('leverPull').play();
// Animate the lever down
tween(handle, {
rotation: Math.PI / 3
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Pull complete, trigger callback
if (self.onPullComplete) {
self.onPullComplete();
}
// Return to original position after delay
LK.setTimeout(function () {
tween(handle, {
rotation: 0
}, {
duration: 500,
easing: tween.elasticOut,
onFinish: function onFinish() {
self.isAnimating = false;
self.isDown = false;
}
});
}, 500);
}
});
};
return self;
});
var Reel = Container.expand(function () {
var self = Container.call(this);
self.isSpinning = false;
self.spinSpeed = 0;
self.spinTime = 0;
self.maxSpinTime = 0;
self.finalSymbol = 0;
self.onStopCallback = null;
var background = self.attachAsset('reelBackground', {
anchorX: 0.5,
anchorY: 0.5
});
var symbols = [];
var symbolPositions = [-140, 0, 140];
for (var i = 0; i < 3; i++) {
var symbol = new SymbolDisplay();
symbol.setSymbol(Math.floor(Math.random() * 3) + 1);
symbol.y = symbolPositions[i];
symbols.push(symbol);
self.addChild(symbol);
}
self.getCurrentSymbol = function () {
// The middle symbol is the active one
return symbols[1].symbolValue;
};
self.spin = function (duration, finalSymbolValue, callback) {
self.isSpinning = true;
self.spinSpeed = 80; // Increase speed for long rolling effect
self.spinTime = 0;
self.maxSpinTime = duration;
self.finalSymbol = finalSymbolValue;
self.onStopCallback = callback;
return self;
};
self.update = function () {
if (!self.isSpinning) {
return;
}
self.spinTime += 1 / 60; // assuming 60 FPS
// Move symbols down
for (var i = 0; i < symbols.length; i++) {
symbols[i].y += self.spinSpeed;
// If a symbol goes beyond the visible area, move it to the top
if (symbols[i].y > 280) {
symbols[i].y = -280;
// Randomize symbols during spin
if (self.spinTime < self.maxSpinTime - 0.5) {
symbols[i].setSymbol(Math.floor(Math.random() * 3) + 1);
} else {
// When approaching end, set to final values
var offset = i - 1;
var targetSymbol = (self.finalSymbol + offset) % 3 + 1;
symbols[i].setSymbol(targetSymbol);
}
}
}
// Slow down and stop at the right time
if (self.spinTime >= self.maxSpinTime) {
self.isSpinning = false;
// Ensure the middle symbol is exactly at y=0
for (var j = 0; j < symbols.length; j++) {
symbols[j].y = symbolPositions[j];
}
LK.getSound('reelStop').play();
if (self.onStopCallback) {
self.onStopCallback();
}
} else if (self.spinTime > self.maxSpinTime - 0.5) {
// Slow down gradually
self.spinSpeed = Math.max(5, self.spinSpeed * 0.98); // Adjust slow down rate for long rolling effect
}
};
return self;
});
var SymbolDisplay = Container.expand(function () {
var self = Container.call(this);
self.symbolValue = 0;
self.symbolGraphic = null;
self.setSymbol = function (symbolId) {
if (self.symbolGraphic) {
self.removeChild(self.symbolGraphic);
}
self.symbolValue = symbolId;
var assetId = 'symbol' + symbolId;
self.symbolGraphic = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
return self;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Bar
// Lemon
// Cherry
// Game state
var coins = storage.coins || 100;
var betAmount = 10;
var isSpinning = false;
var spinResults = [0, 0, 0];
var reels = [];
var activeReels = 0;
// Constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var REEL_SPACING = 200;
var SYMBOL_VALUES = {
"1-1-1": 30,
// Reduce win amount for three cherries
"2-2-2": 60,
// Reduce win amount for three lemons
"3-3-3": 120,
// Reduce win amount for three bars (jackpot)
"1-1-2": 15,
// Two cherries and a lemon
"1-1-3": 15,
// Two cherries and a bar
"2-2-1": 15,
// Two lemons and a cherry
"2-2-3": 15,
// Two lemons and a bar
"1-2-3": 5 // One of each
};
// Create main slot machine components
var slotMachine = new Container();
game.addChild(slotMachine);
slotMachine.x = GAME_WIDTH / 2;
slotMachine.y = GAME_HEIGHT / 2 - 196;
// Background
var background = slotMachine.addChild(LK.getAsset('slotBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
// Main frame
var frame = slotMachine.addChild(LK.getAsset('slotFrame', {
anchorX: 0.5,
anchorY: 0.5,
y: -98
}));
// Add 3 reels
for (var i = 0; i < 3; i++) {
var reel = new Reel();
reel.x = (i - 1) * REEL_SPACING * 1.96;
reel.y = -98;
slotMachine.addChild(reel);
reels.push(reel);
}
// Payline indicators
var leftIndicator = slotMachine.addChild(LK.getAsset('paylineIndicator', {
anchorX: 0.5,
anchorY: 0.5,
x: -686,
y: -98
}));
var rightIndicator = slotMachine.addChild(LK.getAsset('paylineIndicator', {
anchorX: 0.5,
anchorY: 0.5,
x: 686,
y: -98
}));
// Lever
var lever = new Lever();
lever.x = 784;
lever.y = 294;
slotMachine.addChild(lever);
// Set up lever callback
lever.onPullComplete = function () {
if (!isSpinning && coins >= betAmount) {
startSpin();
}
};
// Create UI elements
var coinsDisplay = new Text2("Coins: " + coins, {
size: 60,
fill: 0xFFD700
});
coinsDisplay.anchor.set(0.5, 0.5);
LK.gui.top.addChild(coinsDisplay);
coinsDisplay.y = 196;
var betButton = new Button("Bet: " + betAmount, 200, 80);
betButton.x = GAME_WIDTH / 2;
betButton.y = GAME_HEIGHT - 588;
game.addChild(betButton);
var cashOutButton = new Button("Cash Out", 200, 80);
cashOutButton.x = GAME_WIDTH / 2 + 490;
cashOutButton.y = GAME_HEIGHT - 588;
game.addChild(cashOutButton);
var spinButton = new Button("SPIN", 200, 80);
spinButton.x = GAME_WIDTH / 2 - 490;
spinButton.y = GAME_HEIGHT - 588;
game.addChild(spinButton);
var winText = new Text2("", {
size: 70,
fill: 0xFFD700
});
winText.anchor.set(0.5, 0.5);
winText.y = GAME_HEIGHT / 2 + 490;
winText.x = GAME_WIDTH / 2;
game.addChild(winText);
// Button event handlers
spinButton.down = function (x, y, obj) {
this.down.call(this, x, y, obj);
if (!isSpinning && coins >= betAmount) {
startSpin();
}
};
betButton.down = function (x, y, obj) {
this.down.call(this, x, y, obj);
if (!isSpinning) {
cycleBet();
}
};
cashOutButton.down = function (x, y, obj) {
this.down.call(this, x, y, obj);
if (!isSpinning) {
storage.coins = coins;
LK.showYouWin();
}
};
// Game functions
function updateCoinsDisplay() {
coinsDisplay.setText("Coins: " + coins);
storage.coins = coins;
}
function cycleBet() {
var betOptions = [5, 10, 25, 50, 100];
var currentIndex = betOptions.indexOf(betAmount);
var nextIndex = (currentIndex + 1) % betOptions.length;
betAmount = betOptions[nextIndex];
// Don't allow bets higher than current coins
if (betAmount > coins) {
betAmount = betOptions[0];
}
betButton.setText("Bet: " + betAmount);
}
function startSpin() {
if (isSpinning) {
return;
}
// Deduct coins for the bet
coins -= betAmount;
updateCoinsDisplay();
// Clear any previous win display
winText.setText("");
// Disable buttons during spin
spinButton.disable();
betButton.disable();
isSpinning = true;
activeReels = 0;
LK.getSound('reelSpin').play();
// Generate random results for each reel
for (var i = 0; i < 3; i++) {
spinResults[i] = Math.floor(Math.random() * 4) + 1; // Increase range to reduce winning probability
if (spinResults[i] > 3) {
spinResults[i] = 1;
} // Map any value greater than 3 back to 1
}
// Spin each reel with staggered timing
for (var i = 0; i < reels.length; i++) {
var spinDuration = 5 + i * 1.0; // Further increase duration for an even longer rolling effect
reels[i].spin(spinDuration, spinResults[i], function () {
activeReels++;
if (activeReels >= 3) {
spinCompleted();
}
});
}
}
function spinCompleted() {
isSpinning = false;
// Enable buttons again
spinButton.enable();
betButton.enable();
// Check for winning combinations
var combination = spinResults.join('-');
var winAmount = 0;
// Check exact combinations
if (SYMBOL_VALUES[combination]) {
winAmount = SYMBOL_VALUES[combination] * betAmount / 10;
} else {
// Check for pairs (same symbol in first two positions)
if (spinResults[0] === spinResults[1]) {
winAmount = 2 * betAmount / 10;
} else if (spinResults[1] === spinResults[2]) {
winAmount = 2 * betAmount / 10;
} else if (spinResults[0] === spinResults[2]) {
winAmount = 2 * betAmount / 10;
}
}
if (winAmount > 0) {
// Award winnings
coins += winAmount;
updateCoinsDisplay();
// Display win message
winText.setText("WIN: " + winAmount + " COINS!");
// Play appropriate sound
if (combination === "3-3-3") {
// Jackpot win!
LK.getSound('jackpot').play();
LK.effects.flashScreen(0xFFD700, 1000); // Gold flash for jackpot
} else {
LK.getSound('win').play();
}
}
// Check if player is out of coins
if (coins <= 0) {
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
}
}
// Start background music
LK.playMusic('bgMusic', {
fade: {
start: 0,
end: 0.3,
duration: 1000
}
});
// Update function
game.update = function () {
// Update all reels
for (var i = 0; i < reels.length; i++) {
reels[i].update();
}
// Disable spin button if not enough coins
if (coins < betAmount && !spinButton.disabled) {
spinButton.disable();
} else if (coins >= betAmount && spinButton.disabled && !isSpinning) {
spinButton.enable();
}
};