User prompt
bet de seçtiğimiz at 1. olursa 50 altın 2. olursa 30 3. olursa 10 altın kazanalım
User prompt
bet butonlarını %15 büyüt
User prompt
bet 10 yazılarının yerine bet textunu buton olarak koy
Code edit (1 edits merged)
Please save this source code
User prompt
0 paramız olduğunda atımızın olduğu alanla simetrik karşısında sag tarafta bir alan çıksın çalış butonuna bastığımızda 15 saniye geri saysın ve 10 gold kazanalım ve buton kaybolsun artık 0 paramız olmadığı için
User prompt
atımızınparamız da atımızın özellikleri gibi kalıcı olmalı yoksa sınırsız para harcayabiliyoruz
User prompt
oyunu baştan başlattığımızda atımızın özellikleri kalıcı olsa da paramız değil
User prompt
diğer atların sayısını 40 yap
User prompt
bet e tıkladıktan sonra yarışmacı atlar değişmemeli
User prompt
olmadı seçtiğim slot kazandı ama kaybettin diyor
User prompt
bir bet slotu seçtiğimde seçtiğim slottaki at kazansa da bahsi kazanamıyorum sanırım bet yaptıktan sonra atlar değiştiği için
User prompt
atımızın texturesini ourhorse ourhorse2 ourhorse3 ourhorse4 ourhorse5 ile 5 fps lik gif yap
User prompt
atımızın texture boyutunda yüksekliğini %5 azaltıp uzunluğunu %5 artır
User prompt
atımızın görüntüsü yarış yaptıktan sonra kayboluyor
User prompt
ourhose texturesini ekle bizim atımıza
User prompt
atımız için ourhorse texturesine 5 resim yükledim nasil gif yaparız
User prompt
fix
User prompt
koşu alanı %90 bet alanı %10 olsun
User prompt
koşu alanını biraz daha uzat bet 10 kısmından alıp
User prompt
koşu sahası uzatılabilir bet 10 kısmının %40 oranında kı kısmını kısalt o alanı koşu alanına ver bet 10 yazısının yerini kalan alanlarda tekrar ayarla
User prompt
enter race dediğimizde atımız yarışa girmiyor. en alltaki at yerine atımız girmeli
User prompt
atımızın ekranı fazla aşşaıda
User prompt
biraz daha artır statların ekrana göre yüksekliğini de artır bizim atımızın ekranında
User prompt
Please fix the bug: 'Cannot set properties of null (setting 'x')' in or related to this line: 'playerHorse.x = PLAYER_HORSE_X;' Line Number: 273
User prompt
atımızın ekranının yüksekliğini artır statları gözükmüyor
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Horse class for both TV and player horses var Horse = Container.expand(function () { var self = Container.call(this); // Asset: Each horse gets a colored ellipse as body and a number label var colorList = [0x8e44ad, 0xe67e22, 0x16a085, 0xc0392b, 0x2980b9, 0xf1c40f, 0x2ecc71, 0x34495e, 0xd35400, 0x1abc9c, 0x7f8c8d, 0x27ae60, 0x9b59b6, 0x2c3e50, 0xe74c3c, 0x3498db, 0xf39c12, 0x95a5a6, 0x22313f, 0x6ab04c]; // colorIndex is set on instance self.colorIndex = 0; self.number = 1; // 1-20 self.isPlayer = false; // true if this is the player's horse // Stats self.speed = 10; self.stamina = 10; self.luck = 10; // For race self.lane = 0; // 0-5 self.progress = 0; // 0-1 self.energy = 0; // stamina left self.finished = false; self.finishTime = 0; // Visuals self.body = self.attachAsset('horseBody_' + self.colorIndex, { anchorX: 0.5, anchorY: 0.5, width: 90 * 1.32, height: 60 * 1.32, color: colorList[self.colorIndex % colorList.length], shape: 'ellipse' }); self.label = new Text2(self.number + '', { size: 40, fill: "#fff" }); self.label.anchor.set(0.5, 0.5); self.addChild(self.label); // For player horse, show "YOU" label self.youLabel = null; if (self.isPlayer) { self.youLabel = new Text2("YOU", { size: 32, fill: "#fff" }); self.youLabel.anchor.set(0.5, 0); self.youLabel.y = 40; self.addChild(self.youLabel); } // Set color and number self.setHorse = function (colorIndex, number, isPlayer) { self.colorIndex = colorIndex; self.number = number; self.isPlayer = !!isPlayer; self.body.tint = colorList[self.colorIndex % colorList.length]; self.label.setText(self.number + ''); if (self.isPlayer && !self.youLabel) { self.youLabel = new Text2("YOU", { size: 32, fill: "#fff" }); self.youLabel.anchor.set(0.5, 0); self.youLabel.y = 40; self.addChild(self.youLabel); } if (!self.isPlayer && self.youLabel) { self.removeChild(self.youLabel); self.youLabel = null; } }; // Set stats self.setStats = function (speed, stamina, luck) { self.speed = speed; self.stamina = stamina; self.luck = luck; }; // Reset for race self.resetRace = function () { self.progress = 0; self.energy = self.stamina; self.finished = false; self.finishTime = 0; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ // --- GLOBALS --- var NUM_HORSES = 20; var NUM_LANES = 6; var RACE_LENGTH = 1400; // px, length of the track var TV_TOP = 220; // px from top (moved down by 100) var TV_HEIGHT = 700; // px, height of TV race area var TV_LEFT = 120; var TV_WIDTH = 1800; var LANE_HEIGHT = 100 * 1.15; var HORSE_SIZE = 90; var PLAYER_HORSE_Y = 2200; // moved down by 100 var PLAYER_HORSE_X = 220; var GOLD_START = 100; var BET_COST = 10; var UPGRADE_COST = 20; var BET_PRIZE = 40; var PLAYER_PRIZE = 100; // --- STATE --- var gold = storage.gold || GOLD_START; var playerStats = storage.playerStats || { speed: 10, stamina: 10, luck: 10 }; var playerHorseNum = storage.playerHorseNum || 20; // always 20 var horses = []; // all 20 horses (Horse instances, not attached) var tvHorses = []; // 6 horses in current race (Horse instances, attached) var playerHorse = null; // player's horse (Horse instance, attached) var raceInProgress = false; var raceTimer = 0; var raceResults = []; var betHorseNum = null; // number of horse player bet on (1-20) var playerEntered = false; // did player enter their horse? var raceCountdown = 0; // ticks left before race starts var raceMessage = ''; var messageTimeout = null; // --- UI ELEMENTS --- var goldTxt = new Text2('', { size: 70, fill: 0xFFD700 }); goldTxt.anchor.set(0, 0); LK.gui.top.addChild(goldTxt); goldTxt.x = 120; goldTxt.y = 10; var betTxt = new Text2('', { size: 50, fill: "#fff" }); betTxt.anchor.set(0.5, 0); LK.gui.top.addChild(betTxt); betTxt.x = 2048 / 2; betTxt.y = 10; var messageTxt = new Text2('', { size: 60, fill: "#fff" }); messageTxt.anchor.set(0.5, 0.5); LK.gui.center.addChild(messageTxt); messageTxt.visible = false; // --- TV RACE BOARD --- var tvBoard = LK.getAsset('tvBoard', { anchorX: 0, anchorY: 0, width: TV_WIDTH, height: TV_HEIGHT, color: 0x222244, shape: 'box', x: TV_LEFT, y: TV_TOP }); game.addChild(tvBoard); // --- TV LANE LINES --- for (var i = 1; i < NUM_LANES; i++) { var line = LK.getAsset('laneLine' + i, { anchorX: 0, anchorY: 0, width: TV_WIDTH, height: 4, color: 0x444466, shape: 'box', x: TV_LEFT, y: TV_TOP + i * LANE_HEIGHT }); game.addChild(line); } // --- TV FINISH LINE --- var finishLine = LK.getAsset('finishLine', { anchorX: 0, anchorY: 0, width: 8, height: TV_HEIGHT, color: 0xffffff, shape: 'box', x: TV_LEFT + RACE_LENGTH, y: TV_TOP }); game.addChild(finishLine); // --- PLAYER HORSE AREA --- var playerArea = LK.getAsset('playerArea', { anchorX: 0, anchorY: 0, width: 500, height: 540, // increased height to show more stats color: 0x222244, shape: 'box', x: 60, y: PLAYER_HORSE_Y - 60 // move area a bit lower to match new height }); game.addChild(playerArea); // --- PLAYER HORSE STATS TEXT --- var playerStatsTxt = new Text2('', { size: 48, fill: "#fff" }); playerStatsTxt.anchor.set(0, 0); playerStatsTxt.x = playerArea.x + 20; playerStatsTxt.y = playerArea.y + 320; // move stats text lower game.addChild(playerStatsTxt); // --- UPGRADE BUTTON --- var upgradeBtn = LK.getAsset('upgradeBtn', { anchorX: 0.5, anchorY: 0.5, width: 220, height: 80, color: 0x27ae60, shape: 'box', x: playerArea.x + 130, y: playerArea.y + 460 // move button lower }); game.addChild(upgradeBtn); var upgradeTxt = new Text2('Upgrade (20)', { size: 36, fill: "#fff" }); upgradeTxt.anchor.set(0.5, 0.5); upgradeTxt.x = upgradeBtn.x; upgradeTxt.y = upgradeBtn.y; game.addChild(upgradeTxt); // --- ENTER RACE BUTTON --- var enterBtn = LK.getAsset('enterBtn', { anchorX: 0.5, anchorY: 0.5, width: 220, height: 80, color: 0x2980b9, shape: 'box', x: playerArea.x + 350, y: playerArea.y + 460 // move button lower }); game.addChild(enterBtn); var enterTxt = new Text2('Enter Race', { size: 36, fill: "#fff" }); enterTxt.anchor.set(0.5, 0.5); enterTxt.x = enterBtn.x; enterTxt.y = enterBtn.y; game.addChild(enterTxt); // --- BET BUTTONS (for each TV horse) --- // Move player horse lower as well playerHorse.x = PLAYER_HORSE_X; playerHorse.y = PLAYER_HORSE_Y + 80; var betBtns = []; var betBtnTxts = []; for (var i = 0; i < NUM_LANES; i++) { var btn = LK.getAsset('betBtn' + i, { anchorX: 0.5, anchorY: 0.5, width: 120 * 1.32, height: 60 * 1.32, color: 0xe67e22, shape: 'box', x: TV_LEFT + RACE_LENGTH + 180, y: TV_TOP + i * LANE_HEIGHT + LANE_HEIGHT / 2 }); game.addChild(btn); betBtns.push(btn); var txt = new Text2('Bet', { size: 32 * 1.32, fill: "#fff" }); txt.anchor.set(0.5, 0.5); txt.x = btn.x; txt.y = btn.y; game.addChild(txt); betBtnTxts.push(txt); } // --- HORSE ASSET INIT (for all 20 horses) --- for (var i = 0; i < NUM_HORSES; i++) { var h = new Horse(); h.setHorse(i, i + 1, false); // Random stats for TV horses var s = 40 + Math.floor(Math.random() * 61); // 40-100 var st = 40 + Math.floor(Math.random() * 61); var l = 40 + Math.floor(Math.random() * 61); h.setStats(s, st, l); horses.push(h); } // --- PLAYER HORSE INIT --- playerHorse = new Horse(); playerHorse.setHorse(NUM_HORSES - 1, playerHorseNum, true); playerHorse.setStats(playerStats.speed, playerStats.stamina, playerStats.luck); playerHorse.x = PLAYER_HORSE_X; playerHorse.y = PLAYER_HORSE_Y; game.addChild(playerHorse); // --- FUNCTIONS --- function updateGoldText() { goldTxt.setText("Gold: " + gold); } function updatePlayerStatsText() { playerStatsTxt.setText("Speed: " + playerHorse.speed + "\nStamina: " + playerHorse.stamina + "\nLuck: " + playerHorse.luck); } function showMessage(msg, duration) { messageTxt.setText(msg); messageTxt.visible = true; if (messageTimeout) LK.clearTimeout(messageTimeout); if (duration) { messageTimeout = LK.setTimeout(function () { messageTxt.visible = false; }, duration); } } function hideMessage() { messageTxt.visible = false; if (messageTimeout) LK.clearTimeout(messageTimeout); } function saveState() { storage.gold = gold; storage.playerStats = { speed: playerHorse.speed, stamina: playerHorse.stamina, luck: playerHorse.luck }; storage.playerHorseNum = playerHorseNum; } // Pick 6 random horses for TV race (optionally include player horse) function pickRaceHorses(includePlayer) { var pool = []; for (var i = 0; i < NUM_HORSES - 1; i++) pool.push(i); // 0-18 if (includePlayer) pool.push(NUM_HORSES - 1); // 19 var selected = []; while (selected.length < NUM_LANES) { var idx = Math.floor(Math.random() * pool.length); selected.push(pool[idx]); pool.splice(idx, 1); } return selected; } // Start a new race (after betting phase) function startRace() { raceInProgress = true; raceResults = []; raceTimer = 0; raceMessage = ''; hideMessage(); // Reset TV horses for (var i = 0; i < tvHorses.length; i++) { game.removeChild(tvHorses[i]); } tvHorses = []; // Pick horses var includePlayer = playerEntered; var selected = pickRaceHorses(includePlayer); for (var i = 0; i < NUM_LANES; i++) { var hidx = selected[i]; var h; if (hidx === NUM_HORSES - 1) { // Player horse h = playerHorse; h.setHorse(NUM_HORSES - 1, playerHorseNum, true); h.setStats(playerHorse.speed, playerHorse.stamina, playerHorse.luck); } else { h = horses[hidx]; h.setHorse(hidx, hidx + 1, false); } h.lane = i; h.resetRace(); h.x = TV_LEFT + 40; h.y = TV_TOP + i * LANE_HEIGHT + LANE_HEIGHT / 2; h.scaleX = 1.1; h.scaleY = 1.1; game.addChild(h); tvHorses.push(h); } // Set bet buttons for (var i = 0; i < NUM_LANES; i++) { betBtns[i].visible = false; betBtnTxts[i].visible = false; } // Start race after short countdown raceCountdown = 60; // 1 second showMessage("Race starting!", 1000); } // End race, show results, pay out function endRace() { raceInProgress = false; var winner = raceResults[0]; var winnerNum = winner.number; var playerWin = false; var playerPlace = -1; for (var i = 0; i < raceResults.length; i++) { if (raceResults[i].isPlayer) { playerPlace = i + 1; break; } } var msg = "Winner: #" + winnerNum; if (betHorseNum !== null) { if (betHorseNum === winnerNum) { gold += BET_PRIZE; msg += "\nYou won your bet! (+40)"; playerWin = true; } else { msg += "\nYou lost your bet."; } } if (playerEntered) { if (playerPlace === 1) { gold += PLAYER_PRIZE; msg += "\nYour horse WON! (+100)"; } else if (playerPlace > 0) { msg += "\nYour horse placed #" + playerPlace; } else { msg += "\nYour horse did not finish."; } } updateGoldText(); saveState(); showMessage(msg, 2500); // After a delay, start new betting phase LK.setTimeout(function () { startBettingPhase(); }, 2500); } // Start betting phase: show 6 horses, allow bet/enter function startBettingPhase() { raceInProgress = false; playerEntered = false; betHorseNum = null; raceResults = []; hideMessage(); // Remove TV horses for (var i = 0; i < tvHorses.length; i++) { game.removeChild(tvHorses[i]); } tvHorses = []; // Pick 6 horses (player horse not included yet) var selected = pickRaceHorses(false); for (var i = 0; i < NUM_LANES; i++) { var hidx = selected[i]; var h = horses[hidx]; h.setHorse(hidx, hidx + 1, false); h.lane = i; h.resetRace(); h.x = TV_LEFT + 40; h.y = TV_TOP + i * LANE_HEIGHT + LANE_HEIGHT / 2; h.scaleX = 1.1; h.scaleY = 1.1; game.addChild(h); tvHorses.push(h); } // Set bet buttons for (var i = 0; i < NUM_LANES; i++) { betBtns[i].visible = true; betBtnTxts[i].visible = true; betBtnTxts[i].setText("Bet (10)"); } betTxt.setText("Pick a horse to bet on, or enter your own!"); } // --- BUTTON HANDLERS --- // Bet buttons for (var i = 0; i < NUM_LANES; i++) { (function (idx) { betBtns[idx].down = function (x, y, obj) { if (raceInProgress || betHorseNum !== null || gold < BET_COST) return; if (!tvHorses[idx]) return; // Defensive: avoid undefined betHorseNum = tvHorses[idx].number; gold -= BET_COST; updateGoldText(); saveState(); betTxt.setText("Bet placed on #" + betHorseNum + ". Waiting for race..."); for (var j = 0; j < NUM_LANES; j++) { betBtns[j].visible = false; betBtnTxts[j].visible = false; } // Start race after short delay LK.setTimeout(function () { startRace(); }, 1000); }; })(i); } // Upgrade button upgradeBtn.down = function (x, y, obj) { if (raceInProgress) return; if (gold < UPGRADE_COST) { showMessage("Not enough gold!", 1200); return; } gold -= UPGRADE_COST; updateGoldText(); // Randomly pick stat to upgrade var statNames = ['speed', 'stamina', 'luck']; var idx = Math.floor(Math.random() * 3); var stat = statNames[idx]; playerHorse[stat] += 1 + Math.floor(Math.random() * 3); // +1~3 updatePlayerStatsText(); saveState(); showMessage("Upgraded " + stat + "!", 1000); }; // Enter race button enterBtn.down = function (x, y, obj) { if (raceInProgress || playerEntered) return; // Only allow if player's horse is not already in TV horses for (var i = 0; i < tvHorses.length; i++) { if (tvHorses[i].isPlayer) { showMessage("Already entered!", 1000); return; } } playerEntered = true; betTxt.setText("You entered your horse! Waiting for race..."); for (var j = 0; j < NUM_LANES; j++) { betBtns[j].visible = false; betBtnTxts[j].visible = false; } // Start race after short delay LK.setTimeout(function () { startRace(); }, 1000); }; // --- GAME UPDATE LOOP --- game.update = function () { // Update UI updateGoldText(); updatePlayerStatsText(); // Race countdown if (raceCountdown > 0) { raceCountdown--; if (raceCountdown === 0) { showMessage("Go!", 600); } return; } // Race in progress if (raceInProgress) { var finishedCount = 0; for (var i = 0; i < tvHorses.length; i++) { var h = tvHorses[i]; if (h.finished) { finishedCount++; continue; } // Calculate move var baseSpeed = h.speed / 100 * 8 + 2; // 2-10 px per tick var luckFactor = 1 + (Math.random() - 0.5) * (h.luck / 200); // up to +/- luck/200 var move = baseSpeed * luckFactor; if (h.energy > 0) { h.energy -= 0.04; } else { move *= 0.6; // tired } h.progress += move / RACE_LENGTH; if (h.progress >= 1) { h.progress = 1; h.finished = true; h.finishTime = raceTimer; raceResults.push(h); } h.x = TV_LEFT + 40 + h.progress * (RACE_LENGTH - 80); } raceTimer++; // If all finished, end race if (raceResults.length === tvHorses.length) { endRace(); } } }; // --- INITIALIZE --- updateGoldText(); updatePlayerStatsText(); startBettingPhase();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Horse class for both TV and player horses
var Horse = Container.expand(function () {
var self = Container.call(this);
// Asset: Each horse gets a colored ellipse as body and a number label
var colorList = [0x8e44ad, 0xe67e22, 0x16a085, 0xc0392b, 0x2980b9, 0xf1c40f, 0x2ecc71, 0x34495e, 0xd35400, 0x1abc9c, 0x7f8c8d, 0x27ae60, 0x9b59b6, 0x2c3e50, 0xe74c3c, 0x3498db, 0xf39c12, 0x95a5a6, 0x22313f, 0x6ab04c];
// colorIndex is set on instance
self.colorIndex = 0;
self.number = 1; // 1-20
self.isPlayer = false; // true if this is the player's horse
// Stats
self.speed = 10;
self.stamina = 10;
self.luck = 10;
// For race
self.lane = 0; // 0-5
self.progress = 0; // 0-1
self.energy = 0; // stamina left
self.finished = false;
self.finishTime = 0;
// Visuals
self.body = self.attachAsset('horseBody_' + self.colorIndex, {
anchorX: 0.5,
anchorY: 0.5,
width: 90 * 1.32,
height: 60 * 1.32,
color: colorList[self.colorIndex % colorList.length],
shape: 'ellipse'
});
self.label = new Text2(self.number + '', {
size: 40,
fill: "#fff"
});
self.label.anchor.set(0.5, 0.5);
self.addChild(self.label);
// For player horse, show "YOU" label
self.youLabel = null;
if (self.isPlayer) {
self.youLabel = new Text2("YOU", {
size: 32,
fill: "#fff"
});
self.youLabel.anchor.set(0.5, 0);
self.youLabel.y = 40;
self.addChild(self.youLabel);
}
// Set color and number
self.setHorse = function (colorIndex, number, isPlayer) {
self.colorIndex = colorIndex;
self.number = number;
self.isPlayer = !!isPlayer;
self.body.tint = colorList[self.colorIndex % colorList.length];
self.label.setText(self.number + '');
if (self.isPlayer && !self.youLabel) {
self.youLabel = new Text2("YOU", {
size: 32,
fill: "#fff"
});
self.youLabel.anchor.set(0.5, 0);
self.youLabel.y = 40;
self.addChild(self.youLabel);
}
if (!self.isPlayer && self.youLabel) {
self.removeChild(self.youLabel);
self.youLabel = null;
}
};
// Set stats
self.setStats = function (speed, stamina, luck) {
self.speed = speed;
self.stamina = stamina;
self.luck = luck;
};
// Reset for race
self.resetRace = function () {
self.progress = 0;
self.energy = self.stamina;
self.finished = false;
self.finishTime = 0;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// --- GLOBALS ---
var NUM_HORSES = 20;
var NUM_LANES = 6;
var RACE_LENGTH = 1400; // px, length of the track
var TV_TOP = 220; // px from top (moved down by 100)
var TV_HEIGHT = 700; // px, height of TV race area
var TV_LEFT = 120;
var TV_WIDTH = 1800;
var LANE_HEIGHT = 100 * 1.15;
var HORSE_SIZE = 90;
var PLAYER_HORSE_Y = 2200; // moved down by 100
var PLAYER_HORSE_X = 220;
var GOLD_START = 100;
var BET_COST = 10;
var UPGRADE_COST = 20;
var BET_PRIZE = 40;
var PLAYER_PRIZE = 100;
// --- STATE ---
var gold = storage.gold || GOLD_START;
var playerStats = storage.playerStats || {
speed: 10,
stamina: 10,
luck: 10
};
var playerHorseNum = storage.playerHorseNum || 20; // always 20
var horses = []; // all 20 horses (Horse instances, not attached)
var tvHorses = []; // 6 horses in current race (Horse instances, attached)
var playerHorse = null; // player's horse (Horse instance, attached)
var raceInProgress = false;
var raceTimer = 0;
var raceResults = [];
var betHorseNum = null; // number of horse player bet on (1-20)
var playerEntered = false; // did player enter their horse?
var raceCountdown = 0; // ticks left before race starts
var raceMessage = '';
var messageTimeout = null;
// --- UI ELEMENTS ---
var goldTxt = new Text2('', {
size: 70,
fill: 0xFFD700
});
goldTxt.anchor.set(0, 0);
LK.gui.top.addChild(goldTxt);
goldTxt.x = 120;
goldTxt.y = 10;
var betTxt = new Text2('', {
size: 50,
fill: "#fff"
});
betTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(betTxt);
betTxt.x = 2048 / 2;
betTxt.y = 10;
var messageTxt = new Text2('', {
size: 60,
fill: "#fff"
});
messageTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(messageTxt);
messageTxt.visible = false;
// --- TV RACE BOARD ---
var tvBoard = LK.getAsset('tvBoard', {
anchorX: 0,
anchorY: 0,
width: TV_WIDTH,
height: TV_HEIGHT,
color: 0x222244,
shape: 'box',
x: TV_LEFT,
y: TV_TOP
});
game.addChild(tvBoard);
// --- TV LANE LINES ---
for (var i = 1; i < NUM_LANES; i++) {
var line = LK.getAsset('laneLine' + i, {
anchorX: 0,
anchorY: 0,
width: TV_WIDTH,
height: 4,
color: 0x444466,
shape: 'box',
x: TV_LEFT,
y: TV_TOP + i * LANE_HEIGHT
});
game.addChild(line);
}
// --- TV FINISH LINE ---
var finishLine = LK.getAsset('finishLine', {
anchorX: 0,
anchorY: 0,
width: 8,
height: TV_HEIGHT,
color: 0xffffff,
shape: 'box',
x: TV_LEFT + RACE_LENGTH,
y: TV_TOP
});
game.addChild(finishLine);
// --- PLAYER HORSE AREA ---
var playerArea = LK.getAsset('playerArea', {
anchorX: 0,
anchorY: 0,
width: 500,
height: 540,
// increased height to show more stats
color: 0x222244,
shape: 'box',
x: 60,
y: PLAYER_HORSE_Y - 60 // move area a bit lower to match new height
});
game.addChild(playerArea);
// --- PLAYER HORSE STATS TEXT ---
var playerStatsTxt = new Text2('', {
size: 48,
fill: "#fff"
});
playerStatsTxt.anchor.set(0, 0);
playerStatsTxt.x = playerArea.x + 20;
playerStatsTxt.y = playerArea.y + 320; // move stats text lower
game.addChild(playerStatsTxt);
// --- UPGRADE BUTTON ---
var upgradeBtn = LK.getAsset('upgradeBtn', {
anchorX: 0.5,
anchorY: 0.5,
width: 220,
height: 80,
color: 0x27ae60,
shape: 'box',
x: playerArea.x + 130,
y: playerArea.y + 460 // move button lower
});
game.addChild(upgradeBtn);
var upgradeTxt = new Text2('Upgrade (20)', {
size: 36,
fill: "#fff"
});
upgradeTxt.anchor.set(0.5, 0.5);
upgradeTxt.x = upgradeBtn.x;
upgradeTxt.y = upgradeBtn.y;
game.addChild(upgradeTxt);
// --- ENTER RACE BUTTON ---
var enterBtn = LK.getAsset('enterBtn', {
anchorX: 0.5,
anchorY: 0.5,
width: 220,
height: 80,
color: 0x2980b9,
shape: 'box',
x: playerArea.x + 350,
y: playerArea.y + 460 // move button lower
});
game.addChild(enterBtn);
var enterTxt = new Text2('Enter Race', {
size: 36,
fill: "#fff"
});
enterTxt.anchor.set(0.5, 0.5);
enterTxt.x = enterBtn.x;
enterTxt.y = enterBtn.y;
game.addChild(enterTxt);
// --- BET BUTTONS (for each TV horse) ---
// Move player horse lower as well
playerHorse.x = PLAYER_HORSE_X;
playerHorse.y = PLAYER_HORSE_Y + 80;
var betBtns = [];
var betBtnTxts = [];
for (var i = 0; i < NUM_LANES; i++) {
var btn = LK.getAsset('betBtn' + i, {
anchorX: 0.5,
anchorY: 0.5,
width: 120 * 1.32,
height: 60 * 1.32,
color: 0xe67e22,
shape: 'box',
x: TV_LEFT + RACE_LENGTH + 180,
y: TV_TOP + i * LANE_HEIGHT + LANE_HEIGHT / 2
});
game.addChild(btn);
betBtns.push(btn);
var txt = new Text2('Bet', {
size: 32 * 1.32,
fill: "#fff"
});
txt.anchor.set(0.5, 0.5);
txt.x = btn.x;
txt.y = btn.y;
game.addChild(txt);
betBtnTxts.push(txt);
}
// --- HORSE ASSET INIT (for all 20 horses) ---
for (var i = 0; i < NUM_HORSES; i++) {
var h = new Horse();
h.setHorse(i, i + 1, false);
// Random stats for TV horses
var s = 40 + Math.floor(Math.random() * 61); // 40-100
var st = 40 + Math.floor(Math.random() * 61);
var l = 40 + Math.floor(Math.random() * 61);
h.setStats(s, st, l);
horses.push(h);
}
// --- PLAYER HORSE INIT ---
playerHorse = new Horse();
playerHorse.setHorse(NUM_HORSES - 1, playerHorseNum, true);
playerHorse.setStats(playerStats.speed, playerStats.stamina, playerStats.luck);
playerHorse.x = PLAYER_HORSE_X;
playerHorse.y = PLAYER_HORSE_Y;
game.addChild(playerHorse);
// --- FUNCTIONS ---
function updateGoldText() {
goldTxt.setText("Gold: " + gold);
}
function updatePlayerStatsText() {
playerStatsTxt.setText("Speed: " + playerHorse.speed + "\nStamina: " + playerHorse.stamina + "\nLuck: " + playerHorse.luck);
}
function showMessage(msg, duration) {
messageTxt.setText(msg);
messageTxt.visible = true;
if (messageTimeout) LK.clearTimeout(messageTimeout);
if (duration) {
messageTimeout = LK.setTimeout(function () {
messageTxt.visible = false;
}, duration);
}
}
function hideMessage() {
messageTxt.visible = false;
if (messageTimeout) LK.clearTimeout(messageTimeout);
}
function saveState() {
storage.gold = gold;
storage.playerStats = {
speed: playerHorse.speed,
stamina: playerHorse.stamina,
luck: playerHorse.luck
};
storage.playerHorseNum = playerHorseNum;
}
// Pick 6 random horses for TV race (optionally include player horse)
function pickRaceHorses(includePlayer) {
var pool = [];
for (var i = 0; i < NUM_HORSES - 1; i++) pool.push(i); // 0-18
if (includePlayer) pool.push(NUM_HORSES - 1); // 19
var selected = [];
while (selected.length < NUM_LANES) {
var idx = Math.floor(Math.random() * pool.length);
selected.push(pool[idx]);
pool.splice(idx, 1);
}
return selected;
}
// Start a new race (after betting phase)
function startRace() {
raceInProgress = true;
raceResults = [];
raceTimer = 0;
raceMessage = '';
hideMessage();
// Reset TV horses
for (var i = 0; i < tvHorses.length; i++) {
game.removeChild(tvHorses[i]);
}
tvHorses = [];
// Pick horses
var includePlayer = playerEntered;
var selected = pickRaceHorses(includePlayer);
for (var i = 0; i < NUM_LANES; i++) {
var hidx = selected[i];
var h;
if (hidx === NUM_HORSES - 1) {
// Player horse
h = playerHorse;
h.setHorse(NUM_HORSES - 1, playerHorseNum, true);
h.setStats(playerHorse.speed, playerHorse.stamina, playerHorse.luck);
} else {
h = horses[hidx];
h.setHorse(hidx, hidx + 1, false);
}
h.lane = i;
h.resetRace();
h.x = TV_LEFT + 40;
h.y = TV_TOP + i * LANE_HEIGHT + LANE_HEIGHT / 2;
h.scaleX = 1.1;
h.scaleY = 1.1;
game.addChild(h);
tvHorses.push(h);
}
// Set bet buttons
for (var i = 0; i < NUM_LANES; i++) {
betBtns[i].visible = false;
betBtnTxts[i].visible = false;
}
// Start race after short countdown
raceCountdown = 60; // 1 second
showMessage("Race starting!", 1000);
}
// End race, show results, pay out
function endRace() {
raceInProgress = false;
var winner = raceResults[0];
var winnerNum = winner.number;
var playerWin = false;
var playerPlace = -1;
for (var i = 0; i < raceResults.length; i++) {
if (raceResults[i].isPlayer) {
playerPlace = i + 1;
break;
}
}
var msg = "Winner: #" + winnerNum;
if (betHorseNum !== null) {
if (betHorseNum === winnerNum) {
gold += BET_PRIZE;
msg += "\nYou won your bet! (+40)";
playerWin = true;
} else {
msg += "\nYou lost your bet.";
}
}
if (playerEntered) {
if (playerPlace === 1) {
gold += PLAYER_PRIZE;
msg += "\nYour horse WON! (+100)";
} else if (playerPlace > 0) {
msg += "\nYour horse placed #" + playerPlace;
} else {
msg += "\nYour horse did not finish.";
}
}
updateGoldText();
saveState();
showMessage(msg, 2500);
// After a delay, start new betting phase
LK.setTimeout(function () {
startBettingPhase();
}, 2500);
}
// Start betting phase: show 6 horses, allow bet/enter
function startBettingPhase() {
raceInProgress = false;
playerEntered = false;
betHorseNum = null;
raceResults = [];
hideMessage();
// Remove TV horses
for (var i = 0; i < tvHorses.length; i++) {
game.removeChild(tvHorses[i]);
}
tvHorses = [];
// Pick 6 horses (player horse not included yet)
var selected = pickRaceHorses(false);
for (var i = 0; i < NUM_LANES; i++) {
var hidx = selected[i];
var h = horses[hidx];
h.setHorse(hidx, hidx + 1, false);
h.lane = i;
h.resetRace();
h.x = TV_LEFT + 40;
h.y = TV_TOP + i * LANE_HEIGHT + LANE_HEIGHT / 2;
h.scaleX = 1.1;
h.scaleY = 1.1;
game.addChild(h);
tvHorses.push(h);
}
// Set bet buttons
for (var i = 0; i < NUM_LANES; i++) {
betBtns[i].visible = true;
betBtnTxts[i].visible = true;
betBtnTxts[i].setText("Bet (10)");
}
betTxt.setText("Pick a horse to bet on, or enter your own!");
}
// --- BUTTON HANDLERS ---
// Bet buttons
for (var i = 0; i < NUM_LANES; i++) {
(function (idx) {
betBtns[idx].down = function (x, y, obj) {
if (raceInProgress || betHorseNum !== null || gold < BET_COST) return;
if (!tvHorses[idx]) return; // Defensive: avoid undefined
betHorseNum = tvHorses[idx].number;
gold -= BET_COST;
updateGoldText();
saveState();
betTxt.setText("Bet placed on #" + betHorseNum + ". Waiting for race...");
for (var j = 0; j < NUM_LANES; j++) {
betBtns[j].visible = false;
betBtnTxts[j].visible = false;
}
// Start race after short delay
LK.setTimeout(function () {
startRace();
}, 1000);
};
})(i);
}
// Upgrade button
upgradeBtn.down = function (x, y, obj) {
if (raceInProgress) return;
if (gold < UPGRADE_COST) {
showMessage("Not enough gold!", 1200);
return;
}
gold -= UPGRADE_COST;
updateGoldText();
// Randomly pick stat to upgrade
var statNames = ['speed', 'stamina', 'luck'];
var idx = Math.floor(Math.random() * 3);
var stat = statNames[idx];
playerHorse[stat] += 1 + Math.floor(Math.random() * 3); // +1~3
updatePlayerStatsText();
saveState();
showMessage("Upgraded " + stat + "!", 1000);
};
// Enter race button
enterBtn.down = function (x, y, obj) {
if (raceInProgress || playerEntered) return;
// Only allow if player's horse is not already in TV horses
for (var i = 0; i < tvHorses.length; i++) {
if (tvHorses[i].isPlayer) {
showMessage("Already entered!", 1000);
return;
}
}
playerEntered = true;
betTxt.setText("You entered your horse! Waiting for race...");
for (var j = 0; j < NUM_LANES; j++) {
betBtns[j].visible = false;
betBtnTxts[j].visible = false;
}
// Start race after short delay
LK.setTimeout(function () {
startRace();
}, 1000);
};
// --- GAME UPDATE LOOP ---
game.update = function () {
// Update UI
updateGoldText();
updatePlayerStatsText();
// Race countdown
if (raceCountdown > 0) {
raceCountdown--;
if (raceCountdown === 0) {
showMessage("Go!", 600);
}
return;
}
// Race in progress
if (raceInProgress) {
var finishedCount = 0;
for (var i = 0; i < tvHorses.length; i++) {
var h = tvHorses[i];
if (h.finished) {
finishedCount++;
continue;
}
// Calculate move
var baseSpeed = h.speed / 100 * 8 + 2; // 2-10 px per tick
var luckFactor = 1 + (Math.random() - 0.5) * (h.luck / 200); // up to +/- luck/200
var move = baseSpeed * luckFactor;
if (h.energy > 0) {
h.energy -= 0.04;
} else {
move *= 0.6; // tired
}
h.progress += move / RACE_LENGTH;
if (h.progress >= 1) {
h.progress = 1;
h.finished = true;
h.finishTime = raceTimer;
raceResults.push(h);
}
h.x = TV_LEFT + 40 + h.progress * (RACE_LENGTH - 80);
}
raceTimer++;
// If all finished, end race
if (raceResults.length === tvHorses.length) {
endRace();
}
}
};
// --- INITIALIZE ---
updateGoldText();
updatePlayerStatsText();
startBettingPhase();