User prompt
(The first to reach 2000 chips wins) this text not visiable. Change this text position to bet button down position and reduce scale like %70
User prompt
(The first to reach 2000 chips wins) this text not visiable. Change this text position to bet button down position
User prompt
"(The first to reach 2000 chips wins)" this text not visiable on the screen fix position
User prompt
- bet button text must be "BET 100" - add a text to bottom centre of the screen "(The first to reach 2000 chips wins)" this text is every time punchscale. And this text color changing like rainbow every time
User prompt
everyones money will be reset refreshing the page. First reach 2000 wil be win. If money is 0 it wil be eliminated (player aswell).
User prompt
i add 2 new sounds on the folders. Add thoose int he game
User prompt
Add a hype/energetic/exciting soundtrack to the plane. When it start to fly this sound must be start. When it explode stop the sound and activate explode sound
User prompt
Do this changes: bot1 name: Jack, name color: blue , dot color: blue bot2 name: Arthur, name color: pink, dot color: pink bot3 name: John, name color: orange , dot color: orange
User prompt
Remove player chip icon. Add win lose indicator text player too.
User prompt
Fix bots random cashout time. It must be random. Add a hack to bot. Bot will be win almost every time (bot winrate should be like %75).
User prompt
rotate the flight with line arc. Its shown like flight particle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
- Flight is Foreward of the line like 100px. Fix this. - Every round older dots must be removed
User prompt
-Fix the flight position. It not perfectly fit on the graph line tip - add a color to balances.It represent his own color codes.
User prompt
Please fix the bug: 'Cannot set properties of null (setting 'anchorX')' in or related to this line: 'chipIcon.anchorX = 0.5;' Line Number: 383
User prompt
-add a color for every player. If they withdraw it show on graph wiht his colorcoded dot. - Remove chip icons in balances - Fix win or lose text. It need to show when losing with whit red color. It shown green when wining.
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'bot.displayTxt.style.fill = "#fff";' Line Number: 641
User prompt
-Every player place only 100 chips. Add bot win or lose status. If it win text is green and additional chips shows like "+40 chips" top of his balance.
User prompt
Add 3 bots to the game. Bot name should be likle bot1 bot2... . These bots can be playable like player. We can see their balance. Every one start with 1000 chip. First, reach 10000 chips will win the game. (The bots can bet and withdraw)
User prompt
This balance text placement must be center of the screen, top of the bet button. And bet button text must be "bet 100"
User prompt
add balance text and chip icon top of the bet button.
User prompt
The bet button must be placed in the bottom center. Balance text is at the top of this bet button.
User prompt
balance text is too big and its off the screen. Fix this
User prompt
The flight must be placed on the graph line tip. And the camera must follow this flight. It needs to don't go off the screen
User prompt
add graph background. The graph show multiplier and time
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { balance: 1000 }); /**** * Classes ****/ // Button class var GameButton = Container.expand(function () { var self = Container.call(this); self.bg = null; self.label = null; self.setAsset = function (assetId, labelText, color) { if (self.bg) self.bg.destroy(); self.bg = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); if (color !== undefined) self.bg.tint = color; if (self.label) self.label.destroy(); self.label = new Text2(labelText, { size: 60, fill: "#fff" }); self.label.anchor.set(0.5, 0.5); self.addChild(self.label); }; self.setText = function (txt) { if (self.label) self.label.setText(txt); }; return self; }); // GraphBackground class: draws the multiplier vs time graph as a grid and curve var GraphBackground = Container.expand(function () { var self = Container.call(this); // Graph area (leave margin for axes) self.graphX = 180; self.graphY = 420; self.graphW = 2048 - 360; self.graphH = 900; // For curve drawing self.maxTicks = 600; // 10s at 60fps self.maxMultiplier = 20; // Draw grid lines and axes self.drawGrid = function () { // Remove previous children while (self.children.length) self.children[0].destroy(); // Draw horizontal grid lines (multiplier) for (var i = 1; i <= 5; i++) { var y = self.graphY + self.graphH - i * self.graphH / 5; var line = LK.getAsset('betBtn', { anchorX: 0, anchorY: 0, x: self.graphX, y: y }); line.width = self.graphW; line.height = 4; line.tint = 0x2c3e50; line.alpha = 0.18; self.addChild(line); // Multiplier label var mult = (i * self.maxMultiplier / 5).toFixed(0) + "x"; var label = new Text2(mult, { size: 38, fill: "#fff", stroke: "#222", strokeThickness: 4, fontWeight: "bold" }); label.anchor.set(1, 0.5); label.x = self.graphX - 18; label.y = y + 2; label.alpha = 0.7; self.addChild(label); } // Draw vertical grid lines (time) for (var j = 0; j <= 6; j++) { var x = self.graphX + j * self.graphW / 6; var vline = LK.getAsset('betBtn', { anchorX: 0, anchorY: 0, x: x, y: self.graphY }); vline.width = 4; vline.height = self.graphH; vline.tint = 0x2c3e50; vline.alpha = 0.18; self.addChild(vline); // Time label var t = (j * self.maxTicks / 60 / 6).toFixed(1) + "s"; var tlabel = new Text2(t, { size: 34, fill: "#fff", stroke: "#222", strokeThickness: 4, fontWeight: "bold" }); tlabel.anchor.set(0.5, 0); tlabel.x = x; tlabel.y = self.graphY + self.graphH + 8; tlabel.alpha = 0.7; self.addChild(tlabel); } }; // Draw the curve for the current round self.drawCurve = function (ticksElapsed, crashed) { // Remove previous curve if any if (self.curveNodes) { for (var i = 0; i < self.curveNodes.length; i++) { self.curveNodes[i].destroy(); } } self.curveNodes = []; // Draw curve as small dots for each tick var lastX = null, lastY = null; var maxDrawTicks = crashed ? ticksElapsed : Math.min(ticksElapsed, self.maxTicks); for (var t = 0; t <= maxDrawTicks; t += 2) { var mult = Math.max(1, Math.floor(100 * Math.pow(1.002, t * 2)) / 100); if (mult > self.maxMultiplier) break; var px = self.graphX + t / self.maxTicks * self.graphW; var py = self.graphY + self.graphH - mult / self.maxMultiplier * self.graphH; // Draw dot var dot = LK.getAsset('chip', { anchorX: 0.5, anchorY: 0.5, x: px, y: py }); dot.width = 18; dot.height = 18; dot.tint = crashed && t === maxDrawTicks ? 0xff3333 : 0x3a8ee6; dot.alpha = crashed && t === maxDrawTicks ? 1 : 0.7; self.addChild(dot); self.curveNodes.push(dot); // Optionally, connect with a line (simulate with thin box) if (lastX !== null && lastY !== null) { var dx = px - lastX; var dy = py - lastY; var dist = Math.sqrt(dx * dx + dy * dy); var line = LK.getAsset('betBtn', { anchorX: 0, anchorY: 0.5, x: lastX, y: lastY }); line.width = dist; line.height = 8; line.tint = 0x3a8ee6; line.alpha = 0.5; // Angle line.rotation = Math.atan2(dy, dx); self.addChild(line); self.curveNodes.push(line); } lastX = px; lastY = py; } }; self.drawGrid(); return self; }); // Default balance // Plane class var Plane = Container.expand(function () { var self = Container.call(this); var planeGfx = self.attachAsset('plane', { anchorX: 0.5, anchorY: 0.5 }); self.crashed = false; self.setCrashed = function () { self.crashed = true; // Show crash effect var crash = LK.getAsset('crash', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); self.addChild(crash); tween(crash, { alpha: 0 }, { duration: 700, onFinish: function onFinish() { crash.destroy(); } }); // Fade out plane tween(planeGfx, { alpha: 0 }, { duration: 700 }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a2233 }); /**** * Game Code ****/ // New sounds added to the game // Plane explosion sound effect // Hype/energetic soundtrack for flight // --- Game State Variables --- // Plane (the flying object) // Bet button // Cashout button // Crash explosion // Virtual chip var balance = storage.balance || 1000; var betAmount = 100; var minBet = 10; var maxBet = 1000; var betStep = 10; var inRound = false; var hasBet = false; var hasCashedOut = false; var roundMultiplier = 1.00; var roundStartTick = 0; var crashTick = 0; var cashoutMultiplier = 0; var plane = null; var crashHappened = false; var lastTick = 0; var betBtn = null; var cashoutBtn = null; var betAmountTxt = null; var balanceTxt = null; var multiplierTxt = null; var infoTxt = null; var chipIcon = null; // --- Player and Bot Colors --- var playerColor = 0xFFE066; // gold/yellow for player // Bot color codes: Jack (blue), Arthur (pink), John (orange) var botColors = [0x3a8ee6, 0xff69b4, 0xffa500]; // blue, pink, orange var botNameColors = [0x3a8ee6, 0xff69b4, 0xffa500]; // name text color matches dot color // --- Bot State --- var bots = [{ name: "Jack", balance: 1000, betAmount: 0, hasBet: false, hasCashedOut: false, cashoutMultiplier: 0, displayTxt: null, chipIcon: null, win: 0, color: botColors[0], nameColor: botNameColors[0], dotColor: botColors[0] }, { name: "Arthur", balance: 1000, betAmount: 0, hasBet: false, hasCashedOut: false, cashoutMultiplier: 0, displayTxt: null, chipIcon: null, win: 0, color: botColors[1], nameColor: botNameColors[1], dotColor: botColors[1] }, { name: "John", balance: 1000, betAmount: 0, hasBet: false, hasCashedOut: false, cashoutMultiplier: 0, displayTxt: null, chipIcon: null, win: 0, color: botColors[2], nameColor: botNameColors[2], dotColor: botColors[2] }]; var botWinTarget = 10000; var botWinner = null; // --- GUI Elements --- // --- Graph Background --- var graphBg = new GraphBackground(); game.addChild(graphBg); // --- GUI Elements --- multiplierTxt = new Text2("1.00x", { size: 180, fill: 0xFFE066, stroke: "#222", strokeThickness: 10, dropShadow: true, dropShadowColor: "#000", dropShadowDistance: 8, dropShadowAngle: Math.PI / 2, dropShadowBlur: 8, fontWeight: "bold" }); multiplierTxt.anchor.set(0.5, 0); multiplierTxt.y = 40; LK.gui.top.addChild(multiplierTxt); // Info text (centered, below multiplier, with shadow and spacing) infoTxt = new Text2("Place your bet!", { size: 70, fill: "#fff", stroke: "#222", strokeThickness: 6, dropShadow: true, dropShadowColor: "#000", dropShadowDistance: 4, dropShadowAngle: Math.PI / 2, dropShadowBlur: 6, fontWeight: "bold" }); infoTxt.anchor.set(0.5, 0); infoTxt.y = multiplierTxt.y + multiplierTxt.height + 20; LK.gui.top.addChild(infoTxt); balanceTxt = new Text2("Balance: $" + balance, { size: 60, fill: playerColor, stroke: "#222", strokeThickness: 5, fontWeight: "bold" }); balanceTxt.anchor.set(0.5, 1); // Bet amount display (larger, bolder) betAmountTxt = new Text2("Bet: $" + betAmount, { size: 90, fill: "#fff", stroke: "#222", strokeThickness: 6, fontWeight: "bold" }); betAmountTxt.anchor.set(1, 0.5); betAmountTxt.x = 2048 - 60; LK.gui.topRight.addChild(betAmountTxt); // --- Bet Button --- betBtn = new GameButton(); betBtn.setAsset('betBtn', "BET", 0x2ecc40); betBtn.bg.width = 520; betBtn.bg.height = 180; betBtn.bg.radius = 40; betBtn.bg.dropShadow = true; betBtn.bg.dropShadowColor = 0x222222; betBtn.bg.dropShadowDistance = 8; betBtn.bg.dropShadowAngle = Math.PI / 2; betBtn.bg.dropShadowBlur = 8; // Centered horizontally, near bottom betBtn.x = 2048 / 2; betBtn.y = 2732 - 180; betBtn.anchorX = 0.5; betBtn.anchorY = 0.5; game.addChild(betBtn); // --- Balance text and chip icon above bet button (centered) --- // Center balance text horizontally above bet button balanceTxt.anchor.set(0.5, 1); balanceTxt.x = betBtn.x; balanceTxt.y = betBtn.y - betBtn.bg.height / 2 - 30; // --- Player win/lose indicator text (above balance) --- var playerWinFloatTxt = null; // Center balance text horizontally above bet button game.addChild(balanceTxt); // --- Add bot balance and chip display above bet button --- var botDisplayYOffset = 60; for (var i = 0; i < bots.length; i++) { // Balance text for bot var botTxt = new Text2(bots[i].name + ": $" + bots[i].balance, { size: 44, fill: bots[i].nameColor, stroke: "#222", strokeThickness: 4, fontWeight: "bold" }); botTxt.anchor.set(0.5, 1); botTxt.x = betBtn.x - 400 + i * 400; botTxt.y = balanceTxt.y - 120; bots[i].displayTxt = botTxt; game.addChild(botTxt); } // Update bet button text to "bet 100" betBtn.setText("bet " + betAmount); // --- Cashout Button --- cashoutBtn = new GameButton(); cashoutBtn.setAsset('cashoutBtn', "CASHOUT", 0xe67e22); cashoutBtn.bg.width = 520; cashoutBtn.bg.height = 180; cashoutBtn.bg.radius = 40; cashoutBtn.bg.dropShadow = true; cashoutBtn.bg.dropShadowColor = 0x222222; cashoutBtn.bg.dropShadowDistance = 8; cashoutBtn.bg.dropShadowAngle = Math.PI / 2; cashoutBtn.bg.dropShadowBlur = 8; // Centered horizontally, same Y as betBtn cashoutBtn.x = 2048 / 2; cashoutBtn.y = 2732 - 180; cashoutBtn.anchorX = 0.5; cashoutBtn.anchorY = 0.5; game.addChild(cashoutBtn); cashoutBtn.visible = false; // --- Bet Amount Adjust (plus/minus buttons) --- var betMinusBtn = new GameButton(); betMinusBtn.setAsset('betBtn', "-", 0x16a085); betMinusBtn.bg.width = 120; betMinusBtn.bg.height = 120; betMinusBtn.bg.radius = 60; betMinusBtn.x = 2048 - 420; betMinusBtn.y = 180; LK.gui.topRight.addChild(betMinusBtn); var betPlusBtn = new GameButton(); betPlusBtn.setAsset('betBtn', "+", 0x16a085); betPlusBtn.bg.width = 120; betPlusBtn.bg.height = 120; betPlusBtn.bg.radius = 60; betPlusBtn.x = 2048 - 180; betPlusBtn.y = 180; LK.gui.topRight.addChild(betPlusBtn); betMinusBtn.down = function (x, y, obj) { if (inRound) return; betAmount -= betStep; if (betAmount < minBet) betAmount = maxBet; betAmountTxt.setText("Bet: $" + betAmount); }; betPlusBtn.down = function (x, y, obj) { if (inRound) return; betAmount += betStep; if (betAmount > maxBet) betAmount = minBet; betAmountTxt.setText("Bet: $" + betAmount); }; // --- Bet Button Handler --- betBtn.down = function (x, y, obj) { if (inRound || hasBet) return; if (balance < betAmount) { infoTxt.setText("Not enough balance!"); return; } hasBet = true; infoTxt.setText("Waiting for takeoff..."); betBtn.setText("WAIT"); betBtn.bg.tint = 0xaaaaaa; // Deduct bet immediately balance -= betAmount; storage.balance = balance; balanceTxt.setText("Balance: $" + balance); if (typeof balanceTxt.setFill === "function") balanceTxt.setFill(playerColor); // Start round after short delay LK.setTimeout(startRound, 900); }; // --- Cashout Button Handler --- cashoutBtn.down = function (x, y, obj) { if (!inRound || !hasBet || hasCashedOut || crashHappened) return; hasCashedOut = true; cashoutMultiplier = roundMultiplier; var win = Math.floor(betAmount * cashoutMultiplier); balance += win; storage.balance = balance; balanceTxt.setText("Balance: $" + balance); if (typeof balanceTxt.setFill === "function") balanceTxt.setFill(playerColor); infoTxt.setText("You cashed out: $" + win + " (" + cashoutMultiplier.toFixed(2) + "x)"); // Show floating win text above balance if (playerWinFloatTxt) { playerWinFloatTxt.destroy(); playerWinFloatTxt = null; } playerWinFloatTxt = new Text2("+" + win + " chips", { size: 48, fill: 0x3FDC5A, stroke: "#222", strokeThickness: 5, fontWeight: "bold" }); playerWinFloatTxt.anchor.set(0.5, 1); playerWinFloatTxt.x = balanceTxt.x; playerWinFloatTxt.y = balanceTxt.y - 60; game.addChild(playerWinFloatTxt); tween(playerWinFloatTxt, { y: playerWinFloatTxt.y - 60, alpha: 0 }, { duration: 1200, onFinish: function onFinish() { if (playerWinFloatTxt) { playerWinFloatTxt.destroy(); playerWinFloatTxt = null; } } }); // Show color-coded dot on graph at cashout point if (typeof graphBg !== "undefined") { var cashoutTick = LK.ticks - roundStartTick; var mult = Math.max(1, Math.floor(100 * Math.pow(1.002, cashoutTick * 2)) / 100); if (mult > graphBg.maxMultiplier) mult = graphBg.maxMultiplier; var px = graphBg.graphX + cashoutTick / graphBg.maxTicks * graphBg.graphW; var py = graphBg.graphY + graphBg.graphH - mult / graphBg.maxMultiplier * graphBg.graphH; var dot = LK.getAsset('chip', { anchorX: 0.5, anchorY: 0.5, x: px, y: py }); dot.width = 32; dot.height = 32; dot.tint = playerColor; dot.alpha = 1; game.addChild(dot); // Track for removal next round if (!game.cashoutDots) game.cashoutDots = []; game.cashoutDots.push(dot); // Animate dot pop dot.scaleX = dot.scaleY = 0.5; tween(dot, { scaleX: 1, scaleY: 1 }, { duration: 300 }); // Optionally fade out after a while LK.setTimeout(function () { dot.alpha = 0.7; }, 1200); } cashoutBtn.visible = false; betBtn.visible = false; // Animate plane off screen if (plane) { tween(plane, { y: -200 }, { duration: 800, easing: tween.cubicOut, onFinish: function onFinish() { endRound(); } }); } else { endRound(); } }; // --- Start Round --- function startRound() { inRound = true; crashHappened = false; hasCashedOut = false; cashoutMultiplier = 0; roundMultiplier = 1.00; roundStartTick = LK.ticks; // Remove all previous player/bot cashout dots if (typeof game.cashoutDots !== "undefined" && game.cashoutDots && game.cashoutDots.length) { for (var i = 0; i < game.cashoutDots.length; i++) { if (game.cashoutDots[i] && typeof game.cashoutDots[i].destroy === "function") { game.cashoutDots[i].destroy(); } } game.cashoutDots = []; } else { game.cashoutDots = []; } // Remove player win/lose indicator if present if (playerWinFloatTxt) { playerWinFloatTxt.destroy(); playerWinFloatTxt = null; } // Random crash time: between 2s and 8s (120-480 ticks) crashTick = roundStartTick + 120 + Math.floor(Math.random() * 360); // Place plane at bottom center if (plane) plane.destroy(); plane = new Plane(); plane.x = 2048 / 2; plane.y = 2732 - 600; game.addChild(plane); // Animate plane takeoff tween(plane, { y: 2732 / 2 }, { duration: 1200, easing: tween.cubicOut }); // Start hype soundtrack LK.playMusic('hype_flight', { fade: { start: 0, end: 1, duration: 600 } }); // UI betBtn.visible = false; cashoutBtn.visible = true; cashoutBtn.setText("CASHOUT"); cashoutBtn.bg.tint = 0xe67e22; infoTxt.setText("Flying... Tap CASHOUT to win!"); multiplierTxt.setText("1.00x"); } // --- End Round --- function endRound() { inRound = false; hasBet = false; hasCashedOut = false; betBtn.visible = true; betBtn.setText("BET"); betBtn.bg.tint = 0x2ecc40; cashoutBtn.visible = false; if (plane) { plane.destroy(); plane = null; } // If player lost, show info if (crashHappened && !cashoutMultiplier) { infoTxt.setText("Crashed! You lost $" + betAmount); } else if (!crashHappened && cashoutMultiplier) { infoTxt.setText("You won $" + Math.floor(betAmount * cashoutMultiplier) + "!"); } else { infoTxt.setText("Place your bet!"); } // Reset multiplier display multiplierTxt.setText("1.00x"); // Update bet amount display betAmountTxt.setText("Bet: $" + betAmount); } // --- Crash Handler --- function handleCrash() { crashHappened = true; // Stop hype soundtrack and play explosion sound LK.stopMusic(); LK.getSound('plane_explode').play(); if (plane) plane.setCrashed(); cashoutBtn.visible = false; betBtn.visible = false; if (!hasCashedOut) { cashoutMultiplier = 0; // Show crash info infoTxt.setText("Crashed! You lost $" + betAmount); // Show floating lose text above balance if (playerWinFloatTxt) { playerWinFloatTxt.destroy(); playerWinFloatTxt = null; } playerWinFloatTxt = new Text2("-" + betAmount + " chips", { size: 48, fill: 0xFF3333, stroke: "#222", strokeThickness: 5, fontWeight: "bold" }); playerWinFloatTxt.anchor.set(0.5, 1); playerWinFloatTxt.x = balanceTxt.x; playerWinFloatTxt.y = balanceTxt.y - 60; game.addChild(playerWinFloatTxt); tween(playerWinFloatTxt, { y: playerWinFloatTxt.y - 60, alpha: 0 }, { duration: 1200, onFinish: function onFinish() { if (playerWinFloatTxt) { playerWinFloatTxt.destroy(); playerWinFloatTxt = null; } } }); // End round after short delay LK.setTimeout(endRound, 1200); } else { // Already cashed out, just end round LK.setTimeout(endRound, 800); } } // --- Main Game Update --- game.update = function () { if (!inRound) { // Reset bot round state if not in round for (var b = 0; b < bots.length; b++) { bots[b].hasBet = false; bots[b].hasCashedOut = false; bots[b].betAmount = 0; bots[b].cashoutMultiplier = 0; bots[b].win = 0; } return; } // Calculate multiplier: Exponential growth, e.g. 1.00x to ~20x in 8s var ticksElapsed = LK.ticks - roundStartTick; // Multiplier formula: 1.002^(ticksElapsed*2) for smooth curve roundMultiplier = Math.max(1, Math.floor(100 * Math.pow(1.002, ticksElapsed * 2)) / 100); multiplierTxt.setText(roundMultiplier.toFixed(2) + "x"); // --- Bot logic: Place bets at start of round --- for (var b = 0; b < bots.length; b++) { var bot = bots[b]; // Place bet if not already bet and round just started if (!bot.hasBet && ticksElapsed < 10) { // All bots always bet 100 chips if enough balance var botBet = 100; if (bot.balance >= botBet) { bot.betAmount = botBet; bot.balance -= botBet; bot.hasBet = true; bot.hasCashedOut = false; bot.cashoutMultiplier = 0; bot.win = 0; // Reset win/lose status color and text if (bot.displayTxt) { bot.displayTxt.setText(bot.name + ": $" + bot.balance); if (typeof bot.displayTxt.setFill === "function") { bot.displayTxt.setFill("#fff"); } } // Remove any win/lose floating text if present if (bot.winFloatTxt) { bot.winFloatTxt.destroy(); bot.winFloatTxt = null; } } } } // --- Bot logic: Cash out at random multiplier --- for (var b = 0; b < bots.length; b++) { var bot = bots[b]; if (bot.hasBet && !bot.hasCashedOut && !crashHappened) { // Each bot picks a random cashout multiplier at bet time, with 75% winrate hack if (!bot.targetCashout) { // Calculate the crash multiplier for this round var crashTicks = crashTick - roundStartTick; var crashMult = Math.max(1, Math.floor(100 * Math.pow(1.002, crashTicks * 2)) / 100); // 75% chance to win (cashout before crash), 25% to lose (cashout after crash) var willWin = Math.random() < 0.75; if (willWin) { // Pick a random cashout between 1.5x and just before crash multiplier (with margin) var minMult = 1.5; var maxMult = Math.max(minMult + 0.1, crashMult - 0.2); // leave margin to avoid edge if (maxMult < minMult) maxMult = minMult + 0.1; bot.targetCashout = minMult + Math.random() * (maxMult - minMult); // Clamp to max 5x for realism if (bot.targetCashout > 5) bot.targetCashout = 1.5 + Math.random() * 3.5; } else { // Pick a random cashout after crash (guaranteed lose) var minLose = crashMult + 0.1; var maxLose = Math.max(minLose + 0.1, crashMult + 2.0); bot.targetCashout = minLose + Math.random() * (maxLose - minLose); // Clamp to max 8x if (bot.targetCashout > 8) bot.targetCashout = 6 + Math.random() * 2; } } if (roundMultiplier >= bot.targetCashout) { // Cash out! bot.hasCashedOut = true; bot.cashoutMultiplier = roundMultiplier; bot.win = Math.floor(bot.betAmount * bot.cashoutMultiplier) - bot.betAmount; bot.balance += bot.betAmount + bot.win; // Show color-coded dot on graph at cashout point if (typeof graphBg !== "undefined") { var cashoutTick = ticksElapsed; var mult = Math.max(1, Math.floor(100 * Math.pow(1.002, cashoutTick * 2)) / 100); if (mult > graphBg.maxMultiplier) mult = graphBg.maxMultiplier; var px = graphBg.graphX + cashoutTick / graphBg.maxTicks * graphBg.graphW; var py = graphBg.graphY + graphBg.graphH - mult / graphBg.maxMultiplier * graphBg.graphH; var dot = LK.getAsset('chip', { anchorX: 0.5, anchorY: 0.5, x: px, y: py }); dot.width = 32; dot.height = 32; dot.tint = bot.dotColor; dot.alpha = 1; game.addChild(dot); // Track for removal next round if (!game.cashoutDots) game.cashoutDots = []; game.cashoutDots.push(dot); // Animate dot pop dot.scaleX = dot.scaleY = 0.5; tween(dot, { scaleX: 1, scaleY: 1 }, { duration: 300 }); // Optionally fade out after a while LK.setTimeout(function () { dot.alpha = 0.7; }, 1200); } // Show win status: green text, floating "+chips" if (bot.displayTxt) { bot.displayTxt.setText(bot.name + ": $" + bot.balance); if (typeof bot.displayTxt.setFill === "function") { bot.displayTxt.setFill("#3fdc5a"); } // Show floating "+chips" above bot balance if (bot.win > 0) { var floatTxt = new Text2("+" + bot.win + " chips", { size: 38, fill: 0x3FDC5A, stroke: "#222", strokeThickness: 4, fontWeight: "bold" }); floatTxt.anchor.set(0.5, 1); floatTxt.x = bot.displayTxt.x; floatTxt.y = bot.displayTxt.y - 60; game.addChild(floatTxt); bot.winFloatTxt = floatTxt; // Animate float up and fade out tween(floatTxt, { y: floatTxt.y - 60, alpha: 0 }, { duration: 1200, onFinish: function onFinish() { floatTxt.destroy(); } }); } } } } // If crash happened and bot didn't cash out, reset targetCashout if (crashHappened && !bot.hasCashedOut) { bot.targetCashout = null; } } // --- Bot logic: Handle crash (lose bet if not cashed out) --- if (crashHappened) { for (var b = 0; b < bots.length; b++) { var bot = bots[b]; if (bot.hasBet && !bot.hasCashedOut) { // Lost bet, nothing to add bot.betAmount = 0; bot.cashoutMultiplier = 0; bot.targetCashout = null; // Show lose status: red text and floating lose text if (bot.displayTxt) { bot.displayTxt.setText(bot.name + ": $" + bot.balance); if (typeof bot.displayTxt.setFill === "function") { bot.displayTxt.setFill("#ff3333"); } // Show floating "-100 chips" above bot balance var floatTxt = new Text2("-100 chips", { size: 38, fill: 0xFF3333, stroke: "#222", strokeThickness: 4, fontWeight: "bold" }); floatTxt.anchor.set(0.5, 1); floatTxt.x = bot.displayTxt.x; floatTxt.y = bot.displayTxt.y - 60; game.addChild(floatTxt); bot.winFloatTxt = floatTxt; // Animate float up and fade out tween(floatTxt, { y: floatTxt.y - 60, alpha: 0 }, { duration: 1200, onFinish: function onFinish() { floatTxt.destroy(); } }); } } } } // --- Bot win detection --- if (!botWinner) { for (var b = 0; b < bots.length; b++) { if (bots[b].balance >= botWinTarget) { botWinner = bots[b].name; infoTxt.setText(botWinner + " wins the game!"); // Optionally, end the game or reset after a delay LK.setTimeout(function () { LK.showYouWin(); }, 1800); } } } // Animate plane moving along the graph curve and make camera follow if (plane && !plane.crashed) { // Calculate the graph tip position for the current tick var graphX = graphBg.graphX; var graphY = graphBg.graphY; var graphW = graphBg.graphW; var graphH = graphBg.graphH; var maxTicks = graphBg.maxTicks; var maxMultiplier = graphBg.maxMultiplier; // Calculate current multiplier var mult = Math.max(1, Math.floor(100 * Math.pow(1.002, ticksElapsed * 2)) / 100); if (mult > maxMultiplier) mult = maxMultiplier; // Calculate the tip position on the graph var px = graphX + ticksElapsed / maxTicks * graphW; var py = graphY + graphH - mult / maxMultiplier * graphH; // Clamp px, py to graph area if (px < graphX) px = graphX; if (px > graphX + graphW) px = graphX + graphW; if (py < graphY) py = graphY; if (py > graphY + graphH) py = graphY + graphH; // Place plane at the tip of the graph, perfectly aligned to the curve // Adjust for plane's width/height so its nose is at the tip if (plane.children && plane.children.length > 0) { var planeGfx = plane.children[0]; // Assume plane is facing right, anchorX: 0.5, anchorY: 0.5 // Move plane so its front (right edge) is at (px, py) // Offset by half width to the left plane.x = px + planeGfx.width / 2 - planeGfx.width; // nose exactly at tip plane.y = py; // --- Calculate tangent angle for rotation --- // Use two points: current tick and a small delta before (or after if at start) var deltaT = 2; var t0 = Math.max(0, ticksElapsed - deltaT); var t1 = ticksElapsed; var mult0 = Math.max(1, Math.floor(100 * Math.pow(1.002, t0 * 2)) / 100); var mult1 = Math.max(1, Math.floor(100 * Math.pow(1.002, t1 * 2)) / 100); if (mult0 > maxMultiplier) mult0 = maxMultiplier; if (mult1 > maxMultiplier) mult1 = maxMultiplier; var px0 = graphX + t0 / maxTicks * graphW; var py0 = graphY + graphH - mult0 / maxMultiplier * graphH; var px1 = graphX + t1 / maxTicks * graphW; var py1 = graphY + graphH - mult1 / maxMultiplier * graphH; var dx = px1 - px0; var dy = py1 - py0; // If dx,dy is zero (shouldn't happen), fallback to 0 var angle = 0; if (dx !== 0 || dy !== 0) { angle = Math.atan2(dy, dx); } // Set plane rotation to match tangent planeGfx.rotation = angle; } else { plane.x = px; plane.y = py; } // Camera follow: shift the graphBg and all game elements so the plane stays visible and centered horizontally if possible // Calculate desired camera offset so plane is centered, but clamp so graph doesn't go off screen var desiredCenterX = 2048 / 2; var cameraOffsetX = desiredCenterX - px; // Clamp cameraOffsetX so graphBg doesn't go off screen var minOffsetX = 2048 - (graphX + graphW); // rightmost: graph right edge at screen right var maxOffsetX = -graphX; // leftmost: graph left edge at screen left if (cameraOffsetX < minOffsetX) cameraOffsetX = minOffsetX; if (cameraOffsetX > maxOffsetX) cameraOffsetX = maxOffsetX; // Apply camera offset to graphBg and plane (plane is already at px,py so just move graphBg) graphBg.x = cameraOffsetX; // If you have other game elements that should move with the camera, offset them by cameraOffsetX as well } // Draw/update graph curve if (typeof graphBg !== "undefined") { graphBg.drawCurve(ticksElapsed, crashHappened); } // Crash? if (LK.ticks >= crashTick && !crashHappened) { handleCrash(); } }; // --- Reset on Game Over (handled by LK) --- // --- Touchscreen: Prevent elements in top left 100x100 // (All GUI elements are placed away from top left) // --- Initial UI State --- betBtn.visible = true; cashoutBtn.visible = false; infoTxt.setText("Place your bet!"); multiplierTxt.setText("1.00x"); balanceTxt.setText("Balance: $" + balance); if (typeof balanceTxt.setFill === "function") balanceTxt.setFill(playerColor); betAmountTxt.setText("Bet: $" + betAmount);
===================================================================
--- original.js
+++ change.js
@@ -212,8 +212,9 @@
/****
* Game Code
****/
+// New sounds added to the game
// Plane explosion sound effect
// Hype/energetic soundtrack for flight
// --- Game State Variables ---
// Plane (the flying object)