User prompt
it doesn't seem to affect the next buy or sell action
User prompt
Add four buttons labeled 1, 5, 10, and 25 above the first pair of Buy and Sell buttons in the stock list. Function: - When the player clicks one of these 4 buttons at the top, it should update the value shown in each of the textboxes located between the Buy and Sell buttons. - This value determines how many shares will be bought or sold when the Buy or Sell button is clicked. - These buttons should NOT affect any previous purchases or existing holdings — they only change the number of shares that will be involved in the next Buy or Sell action. Visual Layout: - Place the four buttons (1, 5, 10, 25) in a horizontal row above the Buy and Sell section. - Highlight the currently selected amount if possible, so the player knows what quantity is active.
User prompt
Add four buttons labeled 1, 5, 10, and 25 above the first pair of Buy and Sell buttons in the stock list. Function: - When the player clicks one of these buttons, it should update the value shown in the textbox located between the Buy and Sell buttons. - This value determines how many shares will be bought or sold when the Buy or Sell button is clicked. - These buttons should NOT affect any previous purchases or existing holdings — they only change the number of shares that will be involved in the next Buy or Sell action. Visual Layout: - Place the four buttons (1, 5, 10, 25) in a horizontal row above the Buy and Sell section. - Fix the spacings after placing these buttons, if needed. - Highlight the currently selected amount if possible, so the player knows what quantity is active.
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'text')' in or related to this line: 'if (parseInt(amountTxt.text, 10) === quickAmounts[i]) {' Line Number: 123
User prompt
Add four buttons labeled 1, 5, 10, and 25 above the first pair of Buy and Sell buttons in the stock list. Function: - When the player clicks one of these buttons, it should update the value shown in the textbox located between the Buy and Sell buttons. - This value determines how many shares will be bought or sold when the Buy or Sell button is clicked. - These buttons should NOT affect any previous purchases or existing holdings — they only change the number of shares that will be involved in the next Buy or Sell action. Visual Layout: - Place the four buttons (1, 5, 10, 25) in a horizontal row above the Buy and Sell section for each stock. - Highlight the currently selected amount if possible, so the player knows what quantity is active.
User prompt
display total cash top right corner
User prompt
add 1, 5, 10 and 25 as buttons on top of the first buy and sell buttons, they will affect how many shares will be bought so update the text boxes between all buy and sell buttons when 1, 5, 10 or 25 is selected
User prompt
Please fix the bug: 'Maximum call stack size exceeded' in or related to this line: 'optBg._setVisible(v);' Line Number: 178
User prompt
okay add dropdown list with selections 1, 5, 10 and 50 between the buy and sell buttons and buy correct number of shares according to the selection
User prompt
total money still isn't displayed at the top right corner, total profit needs a label to the left of it, text boxes between buy and sell buttons don't work
User prompt
display total cash (stock values not included) at the top right corner, display total profit & loss at the end of profit column, also add a textbox between buy and sell buttons so that investors can put how many shares they want to buy
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'fill')' in or related to this line: 'profitTxt.style.fill = profitColor;' Line Number: 126
Code edit (1 edits merged)
Please save this source code
User prompt
SimuTrade: Stock Market Simulator
Initial prompt
Create a stock market simulation game called “SimuTrade”. Core Rules: - The player starts with 10,000 currency. - There are 10 fictional companies across different sectors. - Each company has a live stock price that fluctuates over time. Game Mechanics: - Display a table showing each company’s stock price, updated every 10 seconds. - Allow the player to buy or sell shares at current price. - Store the player’s portfolio, showing: - Company name - Number of shares owned - Average purchase price - Current value - Profit or loss per company - Update the player's total cash and portfolio value after every transaction. - End condition: optionally, after 5 or 10 minutes, show final wealth or profit ranking. Stock Price Logic: - Each company’s stock price changes every 10 seconds. - Use random fluctuations: ±1% to ±10% - Occasionally, simulate news events that cause dramatic changes (±25%) Interface: - Show player’s current balance at the top. - Show stock list with real-time updates. - Buy/Sell buttons for each stock. - Show player’s holdings and profit/loss.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // StockRow: A row in the stock table, with price, holdings, buy/sell buttons var StockRow = Container.expand(function () { var self = Container.call(this); // Properties self.companyIndex = 0; // 0-9 self.companyName = ''; self.colorId = ''; self.price = 0; self.holdings = 0; self.lastPrice = 0; // UI elements var yPad = 0; // Stock icon var icon = self.attachAsset(self.colorId, { anchorX: 0.5, anchorY: 0.5, x: 80, y: 60 + yPad, scaleX: 0.7, scaleY: 0.7 }); // Company name var nameTxt = new Text2(self.companyName, { size: 48, fill: 0xFFFFFF }); nameTxt.x = 160; nameTxt.y = 30 + yPad; nameTxt.anchor.set(0, 0); self.addChild(nameTxt); // Price text var priceTxt = new Text2('', { size: 48, fill: 0xF1C40F }); priceTxt.x = 500; priceTxt.y = 30 + yPad; priceTxt.anchor.set(0, 0); self.addChild(priceTxt); // Holdings text var holdingsTxt = new Text2('', { size: 48, fill: 0x2ECC71 }); holdingsTxt.x = 800; holdingsTxt.y = 30 + yPad; holdingsTxt.anchor.set(0, 0); self.addChild(holdingsTxt); // Profit text var profitTxt = new Text2('', { size: 48, fill: 0xFFFFFF }); profitTxt.x = 1100; profitTxt.y = 30 + yPad; profitTxt.anchor.set(0, 0); self.addChild(profitTxt); // --- Quick Amount Select Buttons --- var quickAmounts = [1, 5, 10, 25]; var quickAmountBtns = []; var quickAmountTxts = []; var selectedQuickAmount = 1; var quickBtnY = 10 + yPad; // above buy/sell row var quickBtnStartX = 1450 - 90; // leftmost button var quickBtnSpacing = 70; for (var i = 0; i < quickAmounts.length; i++) { var btnX = quickBtnStartX + i * quickBtnSpacing; var btn = self.attachAsset('buyBtn', { anchorX: 0.5, anchorY: 0.5, x: btnX, y: quickBtnY, scaleX: 0.5, scaleY: 0.5 }); var txt = new Text2('' + quickAmounts[i], { size: 32, fill: 0x222a36 }); txt.anchor.set(0.5, 0.5); txt.x = btnX; txt.y = quickBtnY; self.addChild(txt); // Highlight if selected (function (idx, btn, txt) { btn.down = function (x, y, obj) { selectedQuickAmount = quickAmounts[idx]; amountTxt.setText('' + selectedQuickAmount); updateQuickAmountHighlight(); }; })(i, btn, txt); quickAmountBtns.push(btn); quickAmountTxts.push(txt); self.addChild(txt); } // Highlight function function updateQuickAmountHighlight() { for (var i = 0; i < quickAmounts.length; i++) { if (parseInt(amountTxt.text, 10) === quickAmounts[i]) { quickAmountBtns[i].alpha = 1; quickAmountTxts[i].setStyle({ fill: 0x2ECC71 }); } else { quickAmountBtns[i].alpha = 0.7; quickAmountTxts[i].setStyle({ fill: 0x222A36 }); } } } updateQuickAmountHighlight(); // Buy button var buyBtn = self.attachAsset('buyBtn', { anchorX: 0.5, anchorY: 0.5, x: 1450, y: 60 + yPad }); var buyTxt = new Text2('Buy', { size: 36, fill: 0xFFFFFF }); buyTxt.anchor.set(0.5, 0.5); buyTxt.x = buyBtn.x; buyTxt.y = buyBtn.y; self.addChild(buyTxt); // Amount textbox (between buy and sell) var amountBoxBg = self.attachAsset('buyBtn', { anchorX: 0.5, anchorY: 0.5, x: 1575, y: 60 + yPad, scaleX: 0.7, scaleY: 0.7 }); var amountTxt = new Text2('1', { size: 36, fill: 0x222a36 }); amountTxt.anchor.set(0.5, 0.5); amountTxt.x = amountBoxBg.x; amountTxt.y = amountBoxBg.y; self.addChild(amountTxt); // Touch to edit amount (prompt for number) amountBoxBg.down = function (x, y, obj) { var current = parseInt(amountTxt.text, 10); if (isNaN(current) || current < 1) current = 1; var entered = prompt("Enter number of shares:", current); var val = parseInt(entered, 10); if (isNaN(val) || val < 1) val = 1; amountTxt.setText('' + val); selectedQuickAmount = val; updateQuickAmountHighlight(); }; // Sell button var sellBtn = self.attachAsset('sellBtn', { anchorX: 0.5, anchorY: 0.5, x: 1700, y: 60 + yPad }); var sellTxt = new Text2('Sell', { size: 36, fill: 0xFFFFFF }); sellTxt.anchor.set(0.5, 0.5); sellTxt.x = sellBtn.x; sellTxt.y = sellBtn.y; self.addChild(sellTxt); // Update UI self.updateUI = function () { nameTxt.setText(self.companyName); priceTxt.setText('₲' + self.price); holdingsTxt.setText(self.holdings + ' shares'); var profit = (self.price - self.lastPrice) * self.holdings; var profitColor = "#ffffff"; if (profit > 0) profitColor = "#2ecc71"; if (profit < 0) profitColor = "#e74c3c"; profitTxt.setText((profit >= 0 ? '+' : '') + profit); // Use setStyle to update fill color safely profitTxt.setStyle({ fill: profitColor }); }; // Buy handler buyBtn.down = function (x, y, obj) { // Buy N shares if enough cash var amount = parseInt(amountTxt.text, 10); if (isNaN(amount) || amount < 1) amount = 1; var maxBuy = Math.floor(playerCash / self.price); var buyCount = Math.min(amount, maxBuy); if (buyCount > 0) { playerCash -= self.price * buyCount; self.holdings += buyCount; self.updateUI(); updateCashUI(); } }; // Sell handler sellBtn.down = function (x, y, obj) { // Sell N shares if holding var amount = parseInt(amountTxt.text, 10); if (isNaN(amount) || amount < 1) amount = 1; var sellCount = Math.min(amount, self.holdings); if (sellCount > 0) { playerCash += self.price * sellCount; self.holdings -= sellCount; self.updateUI(); updateCashUI(); } }; // For updating price and profit self.setPrice = function (newPrice) { self.lastPrice = self.price; self.price = newPrice; self.updateUI(); }; // For updating holdings externally self.setHoldings = function (newHoldings) { self.holdings = newHoldings; self.updateUI(); }; // For updating profit display externally self.updateProfit = function () { self.updateUI(); }; // For setting up after construction self.init = function (companyIndex, companyName, colorId, price) { self.companyIndex = companyIndex; self.companyName = companyName; self.colorId = colorId; self.price = price; self.lastPrice = price; icon.setAsset(colorId); self.updateUI(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222a36 }); /**** * Game Code ****/ // --- Game Data --- // 10 company colors for stocks (distinct, visually clear) // Button shapes var companyNames = ["AlphaTech", "BetaBank", "GammaFoods", "DeltaPharma", "EpsilonEnergy", "ZetaAuto", "EtaRetail", "ThetaMedia", "IotaLogix", "KappaSpace"]; var companyColors = ['stockA', 'stockB', 'stockC', 'stockD', 'stockE', 'stockF', 'stockG', 'stockH', 'stockI', 'stockJ']; // Initial prices (randomized a bit for variety) var initialPrices = []; for (var i = 0; i < 10; i++) { initialPrices[i] = 80 + Math.floor(Math.random() * 40) * 5; // 80-280 } // Player state var playerCash = 10000; var playerHoldings = []; for (var i = 0; i < 10; i++) playerHoldings[i] = 0; // Stock state var stockPrices = []; var stockLastPrices = []; for (var i = 0; i < 10; i++) { stockPrices[i] = initialPrices[i]; stockLastPrices[i] = initialPrices[i]; } // Timer var gameDurationSec = 300; // 5 minutes var timeLeft = gameDurationSec; var timerInterval = null; // UI elements var cashTxt = null; var timerTxt = null; var wealthTxt = null; var stockRows = []; var tableContainer = null; // --- UI Setup --- // Cash display (top right, avoid top left 100x100) cashTxt = new Text2('Cash: ₲' + playerCash, { size: 72, fill: 0xF1C40F }); cashTxt.anchor.set(1, 0); cashTxt.x = 0; // x/y are ignored for gui.topRight, but set to 0 for clarity cashTxt.y = 0; LK.gui.topRight.addChild(cashTxt); // Timer display (top center) timerTxt = new Text2('05:00', { size: 72, fill: 0xFFFFFF }); timerTxt.anchor.set(0.5, 0); timerTxt.x = 2048 / 2; timerTxt.y = 40; LK.gui.top.addChild(timerTxt); // Wealth display (below timer) wealthTxt = new Text2('Wealth: ₲' + playerCash, { size: 56, fill: 0x2ECC71 }); wealthTxt.anchor.set(0.5, 0); wealthTxt.x = 2048 / 2; wealthTxt.y = 130; LK.gui.top.addChild(wealthTxt); // Table container (centered, scroll not needed for 10 rows) tableContainer = new Container(); tableContainer.x = 0; tableContainer.y = 300; game.addChild(tableContainer); // Table header var headerY = 0; var header = new Text2("Company Price Holdings Profit ", { size: 48, fill: 0xBDC3C7 }); header.anchor.set(0, 0); header.x = 160; header.y = headerY; tableContainer.addChild(header); // Total Profit/Loss label and display (at end of profit column) var totalProfitLabel = new Text2('Total Profit:', { size: 48, fill: 0xBDC3C7 }); totalProfitLabel.anchor.set(1, 0); totalProfitLabel.x = 1090; totalProfitLabel.y = 80 + 10 * 120 + 10; tableContainer.addChild(totalProfitLabel); var totalProfitTxt = new Text2('', { size: 48, fill: 0xFFFFFF }); totalProfitTxt.anchor.set(0, 0); totalProfitTxt.x = 1110; totalProfitTxt.y = 80 + 10 * 120 + 10; // below last row tableContainer.addChild(totalProfitTxt); // --- Stock Rows --- for (var i = 0; i < 10; i++) { var row = new StockRow(); row.init(i, companyNames[i], companyColors[i], stockPrices[i]); row.y = 80 + i * 120; tableContainer.addChild(row); stockRows.push(row); } // Update total profit/loss function updateTotalProfit() { var totalProfit = 0; for (var i = 0; i < 10; i++) { var profit = (stockPrices[i] - stockLastPrices[i]) * stockRows[i].holdings; totalProfit += profit; } var profitColor = "#ffffff"; if (totalProfit > 0) profitColor = "#2ecc71"; if (totalProfit < 0) profitColor = "#e74c3c"; totalProfitTxt.setText((totalProfit >= 0 ? '+' : '') + totalProfit); totalProfitTxt.setStyle({ fill: profitColor }); } // --- UI Update Functions --- function updateCashUI() { cashTxt.setText('Cash: ₲' + playerCash); updateWealthUI(); updateTotalProfit(); } function updateWealthUI() { var wealth = playerCash; for (var i = 0; i < 10; i++) { wealth += playerHoldings[i] * stockPrices[i]; } wealthTxt.setText('Wealth: ₲' + wealth); } function updateTimerUI() { var min = Math.floor(timeLeft / 60); var sec = timeLeft % 60; var t = (min < 10 ? '0' : '') + min + ':' + (sec < 10 ? '0' : '') + sec; timerTxt.setText(t); } // --- Stock Price Update Logic --- // Simulate price changes every 10 seconds function updateStockPrices() { for (var i = 0; i < 10; i++) { stockLastPrices[i] = stockPrices[i]; // Random walk: -8% to +8% var pct = Math.random() * 0.16 - 0.08; // Occasionally, a "news event" (1 in 8 chance): -25% to +25% if (Math.random() < 0.125) { pct = Math.random() * 0.5 - 0.25; } var newPrice = Math.max(10, Math.round(stockPrices[i] * (1 + pct))); stockPrices[i] = newPrice; // Update row stockRows[i].setPrice(newPrice); playerHoldings[i] = stockRows[i].holdings; } updateWealthUI(); updateTotalProfit(); } // --- Timer Logic --- function tickTimer() { timeLeft -= 1; if (timeLeft < 0) timeLeft = 0; updateTimerUI(); if (timeLeft === 0) { endGame(); } } // --- End Game --- function endGame() { // Calculate final wealth var finalWealth = playerCash; for (var i = 0; i < 10; i++) { finalWealth += playerHoldings[i] * stockPrices[i]; } // Show game over (handled by LK) LK.showGameOver(); } // --- Game Update Loop --- game.update = function () { // No per-frame logic needed for this MVP }; // --- Start Game Logic --- function startGame() { // Reset state playerCash = 10000; for (var i = 0; i < 10; i++) { stockPrices[i] = initialPrices[i]; stockLastPrices[i] = initialPrices[i]; playerHoldings[i] = 0; stockRows[i].setPrice(stockPrices[i]); stockRows[i].setHoldings(0); } timeLeft = gameDurationSec; updateCashUI(); updateTimerUI(); updateWealthUI(); // Start price update interval (every 10s) if (timerInterval) LK.clearInterval(timerInterval); timerInterval = LK.setInterval(function () { updateStockPrices(); }, 10000); // Start timer (every 1s) if (game._timerTick) LK.clearInterval(game._timerTick); game._timerTick = LK.setInterval(function () { tickTimer(); }, 1000); } // --- Start the game --- startGame();
===================================================================
--- original.js
+++ change.js
@@ -62,8 +62,63 @@
profitTxt.x = 1100;
profitTxt.y = 30 + yPad;
profitTxt.anchor.set(0, 0);
self.addChild(profitTxt);
+ // --- Quick Amount Select Buttons ---
+ var quickAmounts = [1, 5, 10, 25];
+ var quickAmountBtns = [];
+ var quickAmountTxts = [];
+ var selectedQuickAmount = 1;
+ var quickBtnY = 10 + yPad; // above buy/sell row
+ var quickBtnStartX = 1450 - 90; // leftmost button
+ var quickBtnSpacing = 70;
+ for (var i = 0; i < quickAmounts.length; i++) {
+ var btnX = quickBtnStartX + i * quickBtnSpacing;
+ var btn = self.attachAsset('buyBtn', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: btnX,
+ y: quickBtnY,
+ scaleX: 0.5,
+ scaleY: 0.5
+ });
+ var txt = new Text2('' + quickAmounts[i], {
+ size: 32,
+ fill: 0x222a36
+ });
+ txt.anchor.set(0.5, 0.5);
+ txt.x = btnX;
+ txt.y = quickBtnY;
+ self.addChild(txt);
+ // Highlight if selected
+ (function (idx, btn, txt) {
+ btn.down = function (x, y, obj) {
+ selectedQuickAmount = quickAmounts[idx];
+ amountTxt.setText('' + selectedQuickAmount);
+ updateQuickAmountHighlight();
+ };
+ })(i, btn, txt);
+ quickAmountBtns.push(btn);
+ quickAmountTxts.push(txt);
+ self.addChild(txt);
+ }
+ // Highlight function
+ function updateQuickAmountHighlight() {
+ for (var i = 0; i < quickAmounts.length; i++) {
+ if (parseInt(amountTxt.text, 10) === quickAmounts[i]) {
+ quickAmountBtns[i].alpha = 1;
+ quickAmountTxts[i].setStyle({
+ fill: 0x2ECC71
+ });
+ } else {
+ quickAmountBtns[i].alpha = 0.7;
+ quickAmountTxts[i].setStyle({
+ fill: 0x222A36
+ });
+ }
+ }
+ }
+ updateQuickAmountHighlight();
// Buy button
var buyBtn = self.attachAsset('buyBtn', {
anchorX: 0.5,
anchorY: 0.5,
@@ -96,15 +151,16 @@
amountTxt.y = amountBoxBg.y;
self.addChild(amountTxt);
// Touch to edit amount (prompt for number)
amountBoxBg.down = function (x, y, obj) {
- // On mobile, prompt is supported in LK sandbox for numeric input
var current = parseInt(amountTxt.text, 10);
if (isNaN(current) || current < 1) current = 1;
var entered = prompt("Enter number of shares:", current);
var val = parseInt(entered, 10);
if (isNaN(val) || val < 1) val = 1;
amountTxt.setText('' + val);
+ selectedQuickAmount = val;
+ updateQuickAmountHighlight();
};
// Sell button
var sellBtn = self.attachAsset('sellBtn', {
anchorX: 0.5,