User prompt
oyunda oynaya basınca geri tuşu yok
User prompt
Son kontrolleri yap
User prompt
YARIŞ TEK TUR OLSUN
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.horseData = flatHorseData;' Line Number: 2255 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
HADİ SON KONTROLLERİ YAP
User prompt
neyse yorgunluğu falan iptal et ya vazgeçtim eski ayara dön
User prompt
yarış diyince yarış başlamıyor piste gidip yarışması lazım atın birini seçip yarış diyip yarışömam lazım
User prompt
yarış tuşu çalışmıyor
User prompt
tamam cooldownu yapma yorgunluk olsun o zaman bir kere yarıştıktan sonra
User prompt
yarış bozuldu yarışı düzenle benim kastım yarış tuşuna basınca hangi atla yarışmamızı istediğimizi sorsun ama o yarıştan sonra bir daha seçemeyelim bir maç cooldown u olsun
User prompt
yarış pisti hala küçük biraz büyüt yarışan atlar arasındaki mesafeyi arttır yan yana bitişik gözüküyorlar bizim atlarımızı göstermek için üstünde sarı yıldız olsun yarış diyince bir atımızı seçebilelim ve yorgunluk olsun hep bir atı yarıştıramayalım kondisyon falan aynı zamanda tek turda bitmesin 3 turda bitsin yarışlar
User prompt
atlar çok birbirine giriyor ve karışık pisti güzelleştir atların yarışını güzelleştir birbiri arasındaki mesafeyi aç ve kendi atımızın üstünde işaret olsun
User prompt
pisti kendin yap ve atları ona göre koştur daire şeklinde
Code edit (1 edits merged)
Please save this source code
User prompt
atlar ters yuvarlak çiziyor ama benim pistime uygun şekilde koşturmuyorsun hala çok dıştan koşuyorlar
User prompt
pist yuvarlak olduğu için atlar piste göre yarışması lazım ona göre ayarla ve son dokunuşları yap bu güncellemeden sonra oyunu yayınlayacağım.
User prompt
oyun mantık veya mekanik hata var gibi duruyor. Yardım kısmını düzenle yazılar kayık falan ortala ekranı
User prompt
para kısmı hatalı turnuva oynuyorum bir at finish çizgisine değdiği anda param çok fazla artmaya başlıyor hatalı oluyor ayrıca yardım kısmını eklememişsin
User prompt
yardım diye bir yer de olsun oyunu anlatan ayrıca mekanikleri ve görsel kaliteyi arttır grafik kalitesini arttır oyunun amacı nedir falan yaz yardım kısmına tüm dillerde de çevirirsin
User prompt
Please fix the bug: 'Uncaught ReferenceError: titleText is not defined' in or related to this line: 'if (titleText) {' Line Number: 1185
User prompt
dil destekleri çok kötü türkçe yapsam sadece belli yerlerde türkçe oluyor diğer yerlerde ingilizce oluyor tam kapsamlı yap turnuva yerine giriyorum back diyemiyorum kodları kontrol et tamamen. Arayüzü güzelleştir
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'btn.text.style.fill = isSelected ? '#f1c40f' : '#ffffff';' Line Number: 570
User prompt
Mağazayı güncelle ve kodları iyileştir aynı zamanda ayarları güncelle dil seçenekleri kısmını güzelleştir assetleri güncelle ve yeni assetler yap güzelleştir aı ile asset yap onları koy.
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.achievements = achievementSystem.achievements;' Line Number: 1503 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
assets leri güncelle ve oyun kalitesini arttır oyun ekrana göre biraz küçük görünüyor ayrıca bir kaç dil desteği daha ekle ve oyunu geliştir ve 26 yeni özellik ekle ↪💡 Consider importing and using the following plugins: @upit/storage.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Achievement = Container.expand(function () {
var self = Container.call(this);
self.achievements = {
firstWin: {
unlocked: false,
name: 'First Victory',
description: 'Win your first race'
},
tenWins: {
unlocked: false,
name: 'Champion',
description: 'Win 10 races'
},
firstBreed: {
unlocked: false,
name: 'Breeder',
description: 'Breed your first horse'
},
millionaire: {
unlocked: false,
name: 'Millionaire',
description: 'Earn $1,000,000'
},
collector: {
unlocked: false,
name: 'Collector',
description: 'Own 10 horses'
},
trainer: {
unlocked: false,
name: 'Master Trainer',
description: 'Train horses 50 times'
},
speedster: {
unlocked: false,
name: 'Speed Demon',
description: 'Have a horse with 100+ speed'
},
endurance: {
unlocked: false,
name: 'Endurance Master',
description: 'Have a horse with 100+ stamina'
}
};
self.checkAchievements = function () {
// Check first win
if (!self.achievements.firstWin.unlocked && LK.getScore() >= 1) {
self.unlockAchievement('firstWin');
}
// Check ten wins
if (!self.achievements.tenWins.unlocked && LK.getScore() >= 10) {
self.unlockAchievement('tenWins');
}
// Check millionaire
if (!self.achievements.millionaire.unlocked && totalEarnings >= 1000000) {
self.unlockAchievement('millionaire');
}
// Check collector
if (!self.achievements.collector.unlocked && horses.length >= 10) {
self.unlockAchievement('collector');
}
// Check trainer
if (!self.achievements.trainer.unlocked && trainingCount >= 50) {
self.unlockAchievement('trainer');
}
};
self.unlockAchievement = function (id) {
self.achievements[id].unlocked = true;
// Flatten achievements for storage
var flatAchievements = {};
for (var key in self.achievements) {
flatAchievements[key + '_unlocked'] = self.achievements[key].unlocked;
flatAchievements[key + '_name'] = self.achievements[key].name;
flatAchievements[key + '_description'] = self.achievements[key].description;
}
storage.achievements = flatAchievements;
LK.effects.flashScreen(0xffd700, 500);
};
return self;
});
var Help = Container.expand(function () {
var self = Container.call(this);
self.currentSection = 'overview';
self.sections = ['overview', 'horses', 'racing', 'breeding', 'economy', 'tips'];
self.sectionButtons = [];
self.contentText = [];
self.titleText = null;
self.backText = null;
self.helpContent = {
overview: {
en: "Welcome to Thoroughbred Legacy!\n\nThis is an elite horse racing simulation where you manage a stable of champion horses. Your goal is to build the most successful racing empire by breeding, training, and racing horses to victory.\n\nKey Features:\n• Breed and train thoroughbred horses\n• Compete in prestigious tournaments\n• Manage your stable's finances\n• Unlock achievements and upgrades\n• Experience dynamic weather effects",
tr: "Safkan Mirası'na Hoş Geldiniz!\n\nBu, şampiyon atlardan oluşan bir ahır yönettiğiniz elit bir at yarışı simülasyonudur. Amacınız, atları üreterek, eğiterek ve yarıştırarak en başarılı yarış imparatorluğunu kurmaktır.\n\nAna Özellikler:\n• Safkan atları üretin ve eğitin\n• Prestijli turnuvalarda yarışın\n• Ahırınızın finansmanını yönetin\n• Başarıları ve gelişmeleri açın\n• Dinamik hava etkilerini deneyimleyin",
ru: "Добро пожаловать в Наследие Чистокровных!\n\nЭто элитная симуляция скачек, где вы управляете конюшней чемпионских лошадей. Ваша цель - построить самую успешную скаковую империю, разводя, тренируя и участвуя в скачках.\n\nОсновные функции:\n• Разводите и тренируйте чистокровных лошадей\n• Участвуйте в престижных турнирах\n• Управляйте финансами конюшни\n• Открывайте достижения и улучшения\n• Испытайте динамические погодные эффекты"
},
horses: {
en: "Horse Management:\n\nEach horse has unique statistics:\n• Speed - Determines racing velocity\n• Stamina - Affects endurance in races\n• Temperament - Influences consistency\n• Energy - Current condition level\n• Age - Affects performance over time\n\nHorse Care:\n• Feed horses to restore energy\n• Visit veterinarian for health boosts\n• Train regularly to improve stats\n• Rest horses between races\n• Monitor aging effects on performance",
tr: "At Yönetimi:\n\nHer atın benzersiz istatistikleri vardır:\n• Hız - Yarış hızını belirler\n• Dayanıklılık - Yarışlarda dayanıklılığı etkiler\n• Mizaç - Tutarlılığı etkiler\n• Enerji - Mevcut kondisyon seviyesi\n• Yaş - Zaman içinde performansı etkiler\n\nAt Bakımı:\n• Enerjiyi yenilemek için atları besleyin\n• Sağlık artışı için veterinere gidin\n• İstatistikleri geliştirmek için düzenli eğitin\n• Yarışlar arasında atları dinlendirin\n• Yaşlanmanın performans üzerindeki etkilerini izleyin",
ru: "Управление лошадьми:\n\nКаждая лошадь имеет уникальную статистику:\n• Скорость - Определяет скорость в гонке\n• Выносливость - Влияет на выносливость в гонках\n• Темперамент - Влияет на стабильность\n• Энергия - Текущий уровень состояния\n• Возраст - Влияет на производительность со временем\n\nУход за лошадьми:\n• Кормите лошадей для восстановления энергии\n• Посещайте ветеринара для укрепления здоровья\n• Регулярно тренируйтесь для улучшения статистики\n• Давайте лошадям отдыхать между гонками\n• Следите за влиянием старения на производительность"
},
racing: {
en: "Racing System:\n\nRace Types:\n• Quick races for immediate rewards\n• Tournament competitions for big prizes\n• Championship events for prestige\n\nRace Mechanics:\n• Weather affects horse performance\n• Energy levels impact race results\n• Horse stats determine speed potential\n• Random events add excitement\n\nStrategy Tips:\n• Choose well-rested horses\n• Consider weather conditions\n• Match horse strengths to race type\n• Manage energy carefully",
tr: "Yarış Sistemi:\n\nYarış Türleri:\n• Hızlı ödüller için hızlı yarışlar\n• Büyük ödüller için turnuva yarışmaları\n• Prestij için şampiyonluk etkinlikleri\n\nYarış Mekanikleri:\n• Hava durumu at performansını etkiler\n• Enerji seviyeleri yarış sonuçlarını etkiler\n• At istatistikleri hız potansiyelini belirler\n• Rastgele olaylar heyecan katar\n\nStrateji İpuçları:\n• İyi dinlenmiş atları seçin\n• Hava koşullarını göz önünde bulundurun\n• At güçlerini yarış türüne uygun hale getirin\n• Enerjiyi dikkatli yönetin",
ru: "Система гонок:\n\nТипы гонок:\n• Быстрые гонки за немедленные награды\n• Турнирные соревнования за большие призы\n• Чемпионские события за престиж\n\nМеханика гонок:\n• Погода влияет на производительность лошадей\n• Уровни энергии влияют на результаты гонок\n• Статистика лошадей определяет скоростной потенциал\n• Случайные события добавляют волнения\n\nСтратегические советы:\n• Выбирайте отдохнувших лошадей\n• Учитывайте погодные условия\n• Сопоставляйте сильные стороны лошадей с типом гонки\n• Тщательно управляйте энергией"
},
breeding: {
en: "Breeding System:\n\nBreeding Basics:\n• Combine two horses to create offspring\n• Foals inherit parent characteristics\n• Stats are averaged with random variation\n• Better parents produce better foals\n\nBreeding Strategy:\n• Choose complementary parent stats\n• Consider age and performance history\n• Breed champions for superior offspring\n• Maintain genetic diversity\n\nBreeding Costs:\n• Breeding fee: $5,000\n• Veterinary care for pregnant mares\n• Training costs for young horses\n• Time investment for development",
tr: "Üretim Sistemi:\n\nÜretim Temelleri:\n• Yavru oluşturmak için iki atı birleştirin\n• Yavrular ebeveyn özelliklerini miras alır\n• İstatistikler rastgele varyasyonla ortalaması alınır\n• Daha iyi ebeveynler daha iyi yavrular üretir\n\nÜretim Stratejisi:\n• Tamamlayıcı ebeveyn istatistiklerini seçin\n• Yaş ve performans geçmişini göz önünde bulundurun\n• Üstün yavrular için şampiyonları üretin\n• Genetik çeşitliliği koruyun\n\nÜretim Maliyetleri:\n• Üretim ücreti: $5,000\n• Gebe kısraklar için veteriner bakımı\n• Genç atlar için eğitim maliyetleri\n• Gelişim için zaman yatırımı",
ru: "Система разведения:\n\nОсновы разведения:\n• Объедините двух лошадей для создания потомства\n• Жеребята наследуют характеристики родителей\n• Статистика усредняется со случайными вариациями\n• Лучшие родители производят лучших жеребят\n\nСтратегия разведения:\n• Выбирайте дополняющие родительские статистики\n• Учитывайте возраст и историю производительности\n• Разводите чемпионов для превосходного потомства\n• Поддерживайте генетическое разнообразие\n\nЗатраты на разведение:\n• Плата за разведение: $5,000\n• Ветеринарный уход за беременными кобылами\n• Расходы на обучение молодых лошадей\n• Временные инвестиции для развития"
},
economy: {
en: "Economic Management:\n\nIncome Sources:\n• Race winnings (varies by competition)\n• Tournament prizes ($25k - $200k)\n• Breeding services to other stables\n• Selling trained horses\n\nExpenses:\n• Horse training ($1,000 per session)\n• Veterinary care ($1,000 - $5,000)\n• Feeding costs ($500 per meal)\n• Equipment upgrades ($10,000+)\n• Breeding fees ($5,000)\n\nFinancial Tips:\n• Maintain cash reserves for opportunities\n• Invest in profitable horses\n• Balance training costs with results\n• Consider long-term breeding investments",
tr: "Ekonomik Yönetim:\n\nGelir Kaynakları:\n• Yarış kazançları (yarışmaya göre değişir)\n• Turnuva ödülleri ($25k - $200k)\n• Diğer ahırlara üretim hizmetleri\n• Eğitilmiş atları satma\n\nGiderler:\n• At eğitimi (seans başına $1,000)\n• Veteriner bakımı ($1,000 - $5,000)\n• Beslenme maliyetleri (öğün başına $500)\n• Ekipman geliştirmeleri ($10,000+)\n• Üretim ücretleri ($5,000)\n\nFinansal İpuçları:\n• Fırsatlar için nakit rezerv bulundurun\n• Karlı atlara yatırım yapın\n• Eğitim maliyetlerini sonuçlarla dengeleyin\n• Uzun vadeli üretim yatırımlarını düşünün",
ru: "Экономическое управление:\n\nИсточники дохода:\n• Выигрыши в гонках (варьируется в зависимости от соревнования)\n• Призы турниров ($25k - $200k)\n• Услуги разведения для других конюшен\n• Продажа обученных лошадей\n\nРасходы:\n• Тренировка лошадей ($1,000 за сессию)\n• Ветеринарная помощь ($1,000 - $5,000)\n• Расходы на кормление ($500 за прием пищи)\n• Обновления оборудования ($10,000+)\n• Плата за разведение ($5,000)\n\nФинансовые советы:\n• Поддерживайте денежные резервы для возможностей\n• Инвестируйте в прибыльных лошадей\n• Балансируйте затраты на обучение с результатами\n• Рассмотрите долгосрочные инвестиции в разведение"
},
tips: {
en: "Advanced Tips & Strategies:\n\nOptimal Training:\n• Train horses when energy is high\n• Focus on weak stats for balanced development\n• Don't overtrain - rest is important\n• Monitor age-related stat declines\n\nRace Strategy:\n• Save your best horses for tournaments\n• Consider weather effects on performance\n• Match horse types to race distances\n• Build experience gradually\n\nLong-term Success:\n• Invest in breeding superior bloodlines\n• Diversify your stable portfolio\n• Plan for horse retirement\n• Maintain steady income streams\n• Unlock all achievements for bonuses",
tr: "Gelişmiş İpuçları ve Stratejiler:\n\nOptimal Eğitim:\n• Enerji yüksekken atları eğitin\n• Dengeli gelişim için zayıf istatistiklere odaklanın\n• Aşırı eğitim yapmayın - dinlenme önemlidir\n• Yaşa bağlı istatistik düşüşlerini izleyin\n\nYarış Stratejisi:\n• En iyi atlarınızı turnuvalar için saklayın\n• Hava etkilerini performans üzerinde düşünün\n• At türlerini yarış mesafelerine uygun hale getirin\n• Deneyimi kademeli olarak artırın\n\nUzun vadeli Başarı:\n• Üstün kan hatlarını üretmeye yatırım yapın\n• Ahır portföyünüzü çeşitlendirin\n• At emekliliği için plan yapın\n• Sabit gelir akışları sürdürün\n• Bonuslar için tüm başarıları açın",
ru: "Продвинутые советы и стратегии:\n\nОптимальная тренировка:\n• Тренируйте лошадей при высокой энергии\n• Сосредоточьтесь на слабых статистиках для сбалансированного развития\n• Не перетренируйтесь - отдых важен\n• Следите за возрастными снижениями статистики\n\nСтратегия гонок:\n• Сохраните лучших лошадей для турниров\n• Учитывайте влияние погоды на производительность\n• Сопоставьте типы лошадей с дистанциями гонок\n• Постепенно накапливайте опыт\n\nДолгосрочный успех:\n• Инвестируйте в разведение превосходных родословных\n• Диверсифицируйте портфель конюшни\n• Планируйте выход лошадей на пенсию\n• Поддерживайте стабильные потоки доходов\n• Разблокируйте все достижения для бонусов"
}
};
self.setupUI = function () {
var background = self.attachAsset('menuBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
self.titleText = new Text2('', {
size: 80,
fill: '#ecf0f1'
});
self.titleText.anchor.set(0.5, 0.5);
self.titleText.x = 1024;
self.titleText.y = 200;
self.addChild(self.titleText);
// Section buttons
for (var i = 0; i < self.sections.length; i++) {
var section = self.sections[i];
var sectionBtn = self.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 200 + i % 3 * 300,
y: 350 + Math.floor(i / 3) * 100
});
var sectionText = new Text2(section.toUpperCase(), {
size: 24,
fill: '#ffffff'
});
sectionText.anchor.set(0.5, 0.5);
sectionText.x = 200 + i % 3 * 300;
sectionText.y = 350 + Math.floor(i / 3) * 100;
sectionText.sectionId = section;
self.addChild(sectionText);
self.sectionButtons.push({
button: sectionBtn,
text: sectionText,
section: section,
x: 200 + i % 3 * 300,
y: 350 + Math.floor(i / 3) * 100
});
}
self.refreshContent();
self.backText = new Text2('', {
size: 45,
fill: '#ffffff'
});
self.backText.anchor.set(0.5, 0.5);
self.backText.x = 1024;
self.backText.y = 2500;
self.addChild(self.backText);
var backBtn = self.attachAsset('backButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2500
});
};
self.refreshContent = function () {
// Clear existing content
for (var i = 0; i < self.contentText.length; i++) {
if (self.contentText[i].destroy) {
self.contentText[i].destroy();
}
}
self.contentText = [];
var content = self.helpContent[self.currentSection][currentLanguage] || self.helpContent[self.currentSection]['en'];
var lines = content.split('\n');
var yPos = 600;
for (var i = 0; i < lines.length; i++) {
var line = lines[i].trim();
if (line.length === 0) {
yPos += 20;
continue;
}
// Handle long lines by wrapping text
var maxLineLength = 70;
if (line.length > maxLineLength && line.indexOf('•') !== 0) {
var words = line.split(' ');
var currentLine = '';
for (var w = 0; w < words.length; w++) {
if ((currentLine + words[w]).length > maxLineLength) {
if (currentLine.length > 0) {
var wrappedLine = new Text2(currentLine.trim(), {
size: 30,
fill: '#ffffff'
});
wrappedLine.anchor.set(0.5, 0.5);
wrappedLine.x = 1024;
wrappedLine.y = yPos;
self.addChild(wrappedLine);
self.contentText.push(wrappedLine);
yPos += 35;
}
currentLine = words[w] + ' ';
} else {
currentLine += words[w] + ' ';
}
}
if (currentLine.trim().length > 0) {
var finalLine = new Text2(currentLine.trim(), {
size: 30,
fill: '#ffffff'
});
finalLine.anchor.set(0.5, 0.5);
finalLine.x = 1024;
finalLine.y = yPos;
self.addChild(finalLine);
self.contentText.push(finalLine);
yPos += 35;
}
} else {
var fontSize = line.indexOf('•') === 0 ? 28 : line.indexOf(':') > 0 ? 34 : 30;
var textColor = line.indexOf(':') > 0 ? '#3498db' : '#ffffff';
var contentLine = new Text2(line, {
size: fontSize,
fill: textColor
});
contentLine.anchor.set(0.5, 0.5);
contentLine.x = 1024;
contentLine.y = yPos;
self.addChild(contentLine);
self.contentText.push(contentLine);
yPos += fontSize + 15;
}
}
};
self.updateLanguage = function () {
if (self.titleText) {
self.titleText.setText(translations[currentLanguage].help || 'HELP & GUIDE');
}
if (self.backText) {
self.backText.setText(translations[currentLanguage].back || 'BACK');
}
self.refreshContent();
};
self.down = function (x, y, obj) {
if (!obj || !obj.parent || !obj.parent.toGlobal) {
var localPos = {
x: x,
y: y
};
} else {
var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
}
// Check section buttons
for (var i = 0; i < self.sectionButtons.length; i++) {
var btn = self.sectionButtons[i];
if (localPos.x >= btn.x - 125 && localPos.x <= btn.x + 125 && localPos.y >= btn.y - 60 && localPos.y <= btn.y + 60) {
self.currentSection = btn.section;
self.refreshContent();
LK.getSound('buttonClick').play();
break;
}
}
// Check back button
if (localPos.x >= 874 && localPos.x <= 1174 && localPos.y >= 2440 && localPos.y <= 2560) {
currentView = 'menu';
updateView();
LK.getSound('buttonClick').play();
}
};
return self;
});
var Horse = Container.expand(function (config) {
var self = Container.call(this);
config = config || {};
// Horse stats
self.name = config.name || 'Unnamed Horse';
self.speed = config.speed || Math.random() * 50 + 50;
self.stamina = config.stamina || Math.random() * 50 + 50;
self.temperament = config.temperament || Math.random() * 50 + 50;
self.age = config.age || 2;
self.raceWins = config.raceWins || 0;
self.value = config.value || 10000;
self.currentEnergy = 100;
self.maxEnergy = 100;
// Visual representation
var horseBody = self.attachAsset('horse', {
anchorX: 0.5,
anchorY: 0.5
});
var jockeySprite = self.attachAsset('jockey', {
anchorX: 0.5,
anchorY: 0.5,
y: -20
});
// Racing properties
self.racePosition = 0;
self.raceSpeed = 0;
self.isRacing = false;
self.train = function (type) {
switch (type) {
case 'speed':
self.speed += Math.random() * 5 + 2;
break;
case 'stamina':
self.stamina += Math.random() * 5 + 2;
break;
case 'temperament':
self.temperament += Math.random() * 5 + 2;
break;
}
self.currentEnergy = Math.max(0, self.currentEnergy - 20);
};
self.rest = function () {
self.currentEnergy = Math.min(self.maxEnergy, self.currentEnergy + 30);
};
self.breed = function (partner) {
var offspring = new Horse({
speed: (self.speed + partner.speed) / 2 + (Math.random() - 0.5) * 20,
stamina: (self.stamina + partner.stamina) / 2 + (Math.random() - 0.5) * 20,
temperament: (self.temperament + partner.temperament) / 2 + (Math.random() - 0.5) * 20,
age: 0,
name: 'Foal ' + Math.floor(Math.random() * 1000)
});
breedingCount++;
if (breedingCount === 1 && achievementSystem) {
achievementSystem.achievements.firstBreed.unlocked = true;
}
return offspring;
};
self.getRaceSpeed = function () {
var energyFactor = self.currentEnergy / self.maxEnergy;
return (self.speed * 0.6 + self.stamina * 0.4) * energyFactor;
};
self.update = function () {
if (self.isRacing) {
self.raceSpeed = self.getRaceSpeed() * (0.8 + Math.random() * 0.4);
self.racePosition += self.raceSpeed * 0.1;
// Calculate circular track position
var trackCenterX = 1024;
var trackCenterY = 1366;
var trackRadius = 550; // Match track radius exactly
// Convert linear race position to angle (0 to 2*PI for full lap)
var raceAngle = self.racePosition / 2000 * Math.PI * 2;
// Calculate horse position on circular track - keep horses on track
var laneVariation = Math.sin(self.racePosition * 0.01) * 5; // Small lane variation
var currentRadius = trackRadius + laneVariation;
self.x = trackCenterX + Math.cos(raceAngle) * currentRadius;
self.y = trackCenterY + Math.sin(raceAngle) * currentRadius;
// Adjust horse rotation to face direction of movement (tangent to circle)
self.rotation = raceAngle + Math.PI / 2;
// Energy drain during race
self.currentEnergy = Math.max(0, self.currentEnergy - 0.2);
}
};
return self;
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
var background = self.attachAsset('menuBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
var titleText = new Text2('', {
size: 80,
fill: '#ffffff'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 500;
self.addChild(titleText);
var playBtn = self.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1000
});
var playText = new Text2('', {
size: 50,
fill: '#ffffff'
});
playText.anchor.set(0.5, 0.5);
playText.x = 1024;
playText.y = 1000;
self.addChild(playText);
var tournamentBtn = self.attachAsset('tournamentButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1150
});
var tournamentText = new Text2('', {
size: 45,
fill: '#ffffff'
});
tournamentText.anchor.set(0.5, 0.5);
tournamentText.x = 1024;
tournamentText.y = 1150;
self.addChild(tournamentText);
var shopBtn = self.attachAsset('shopButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1300
});
var shopText = new Text2('', {
size: 45,
fill: '#ffffff'
});
shopText.anchor.set(0.5, 0.5);
shopText.x = 1024;
shopText.y = 1300;
self.addChild(shopText);
var settingsBtn = self.attachAsset('settingsButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1450
});
var settingsText = new Text2('', {
size: 45,
fill: '#ffffff'
});
settingsText.anchor.set(0.5, 0.5);
settingsText.x = 1024;
settingsText.y = 1450;
self.addChild(settingsText);
var helpBtn = self.attachAsset('settingsButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1600
});
var helpText = new Text2('', {
size: 45,
fill: '#ffffff'
});
helpText.anchor.set(0.5, 0.5);
helpText.x = 1024;
helpText.y = 1600;
self.addChild(helpText);
self.updateLanguage = function () {
titleText.setText(translations[currentLanguage].title);
playText.setText(translations[currentLanguage].play);
tournamentText.setText(translations[currentLanguage].tournament);
shopText.setText(translations[currentLanguage].shop);
settingsText.setText(translations[currentLanguage].settings);
helpText.setText(translations[currentLanguage].help);
};
self.down = function (x, y, obj) {
if (!obj || !obj.parent || !obj.parent.toGlobal) {
var localPos = {
x: x,
y: y
};
} else {
var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
}
// Check play button
if (localPos.x >= 774 && localPos.x <= 1274 && localPos.y >= 940 && localPos.y <= 1060) {
currentView = 'stable';
updateView();
LK.getSound('buttonClick').play();
}
// Check tournament button
if (localPos.x >= 824 && localPos.x <= 1224 && localPos.y >= 1090 && localPos.y <= 1210) {
currentView = 'tournament';
updateView();
LK.getSound('buttonClick').play();
}
// Check shop button
if (localPos.x >= 824 && localPos.x <= 1224 && localPos.y >= 1240 && localPos.y <= 1360) {
currentView = 'shop';
updateView();
LK.getSound('buttonClick').play();
}
// Check settings button
if (localPos.x >= 799 && localPos.x <= 1249 && localPos.y >= 1390 && localPos.y <= 1510) {
currentView = 'settings';
updateView();
LK.getSound('buttonClick').play();
}
// Check help button
if (localPos.x >= 799 && localPos.x <= 1249 && localPos.y >= 1540 && localPos.y <= 1660) {
currentView = 'help';
updateView();
LK.getSound('buttonClick').play();
}
};
return self;
});
var RaceView = Container.expand(function () {
var self = Container.call(this);
// Create circular race track
var trackOuter = self.attachAsset('circularTrack', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
var trackInner = self.attachAsset('trackInner', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
var finishLine = self.attachAsset('startFinishLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024 + 550,
y: 1366
});
var raceTitle = new Text2('RACE IN PROGRESS', {
size: 50,
fill: '#ffffff'
});
raceTitle.anchor.set(0.5, 0.5);
raceTitle.x = 1024;
raceTitle.y = 200;
self.addChild(raceTitle);
var trackInfo = new Text2('Professional Circular Track - Complete One Lap', {
size: 30,
fill: '#ffff00'
});
trackInfo.anchor.set(0.5, 0.5);
trackInfo.x = 1024;
trackInfo.y = 250;
self.addChild(trackInfo);
self.raceHorses = [];
self.setupRace = function () {
// Reset race state completely
self.raceFinished = false;
// Clear existing race horses
for (var i = 0; i < self.raceHorses.length; i++) {
if (self.raceHorses[i].destroy) {
self.raceHorses[i].destroy();
}
}
self.raceHorses = [];
// Add player's horses and AI horses
var raceHorsesList = [];
// Add player horses
for (var i = 0; i < Math.min(horses.length, 3); i++) {
raceHorsesList.push(horses[i]);
}
// Add AI horses to fill up to 6 total
while (raceHorsesList.length < 6) {
var aiHorse = new Horse({
name: 'AI Horse ' + (raceHorsesList.length + 1),
speed: Math.random() * 40 + 60,
stamina: Math.random() * 40 + 60,
temperament: Math.random() * 40 + 60
});
raceHorsesList.push(aiHorse);
}
// Position horses at start line on circular track
var trackCenterX = 1024;
var trackCenterY = 1366;
var trackRadius = 550; // Match track outer radius
for (var i = 0; i < raceHorsesList.length; i++) {
var horse = raceHorsesList[i];
// Position horses in lanes at starting line (right side of track)
var laneOffset = (i - 2.5) * 15; // Center lanes around middle
horse.x = trackCenterX + trackRadius;
horse.y = trackCenterY + laneOffset;
horse.racePosition = 0;
horse.isRacing = true;
horse.currentEnergy = horse.maxEnergy;
horse.rotation = Math.PI / 2; // Face forward initially
self.addChild(horse);
self.raceHorses.push(horse);
}
};
self.checkRaceFinish = function () {
// Don't check if race is already finished
if (self.raceFinished) {
return true;
}
for (var i = 0; i < self.raceHorses.length; i++) {
var horse = self.raceHorses[i];
if (horse.racePosition >= 2000 && !self.raceFinished) {
// Race finished - one complete lap
self.finishRace(horse);
return true;
}
}
return false;
};
self.raceFinished = false;
self.finishRace = function (winner) {
// Prevent multiple race finish triggers
if (self.raceFinished) {
return;
}
self.raceFinished = true;
// Stop all horses
for (var i = 0; i < self.raceHorses.length; i++) {
self.raceHorses[i].isRacing = false;
}
// Check if winner is player's horse
var isPlayerWinner = false;
for (var i = 0; i < horses.length; i++) {
if (horses[i] === winner) {
isPlayerWinner = true;
winner.raceWins++;
break;
}
}
// Award money based on tournament or regular race - only once
var prize = 0;
if (tournamentSystem.currentTournament) {
if (isPlayerWinner) {
prize = tournamentSystem.currentTournament.prize;
tournamentSystem.completeTournament();
} else {
prize = Math.floor(tournamentSystem.currentTournament.prize * 0.1); // Small participation prize
}
} else {
if (isPlayerWinner) {
prize = 10000;
LK.setScore(LK.getScore() + 1);
LK.getSound('crowdCheer').play();
} else {
prize = 2000; // Participation prize
}
}
// Only award money once
money += prize;
totalEarnings += prize;
updateMoneyDisplay();
// Clear race state to prevent further money awards
for (var i = 0; i < self.raceHorses.length; i++) {
self.raceHorses[i].racePosition = 0;
}
// Return to stable after 3 seconds
LK.setTimeout(function () {
currentView = 'stable';
updateView();
}, 3000);
};
return self;
});
var SettingsMenu = Container.expand(function () {
var self = Container.call(this);
var background = self.attachAsset('settingsBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
var panel = self.attachAsset('settingsPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
var titleText = new Text2('', {
size: 80,
fill: '#ecf0f1'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
self.addChild(titleText);
var languageLabel = new Text2('', {
size: 50,
fill: '#3498db'
});
languageLabel.anchor.set(0.5, 0.5);
languageLabel.x = 1024;
languageLabel.y = 500;
self.addChild(languageLabel);
// Language data with flag colors
var languages = [{
name: 'English',
code: 'en',
flag: 0xff0000
}, {
name: 'Русский',
code: 'ru',
flag: 0x0080ff
}, {
name: 'Français',
code: 'fr',
flag: 0x0000ff
}, {
name: 'Türkçe',
code: 'tr',
flag: 0xff0000
}, {
name: 'Español',
code: 'es',
flag: 0xffff00
}, {
name: 'Deutsch',
code: 'de',
flag: 0x000000
}, {
name: '中文',
code: 'zh',
flag: 0xff0000
}, {
name: '日本語',
code: 'ja',
flag: 0xff0000
}, {
name: 'Italiano',
code: 'it',
flag: 0x00ff00
}, {
name: 'Português',
code: 'pt',
flag: 0x00ff00
}];
self.languageButtons = [];
for (var i = 0; i < languages.length; i++) {
var lang = languages[i];
var isSelected = currentLanguage === lang.code;
var btnAsset = isSelected ? 'selectedLanguage' : 'languageButton';
var langBtn = self.attachAsset(btnAsset, {
anchorX: 0.5,
anchorY: 0.5,
x: 350 + i % 4 * 350,
y: 700 + Math.floor(i / 4) * 150
});
var flagIcon = self.attachAsset('languageFlag', {
anchorX: 0.5,
anchorY: 0.5,
x: 250 + i % 4 * 350,
y: 700 + Math.floor(i / 4) * 150
});
flagIcon.tint = lang.flag;
var langText = new Text2(lang.name, {
size: 26,
fill: isSelected ? '#f1c40f' : '#ffffff'
});
langText.anchor.set(0.5, 0.5);
langText.x = 380 + i % 4 * 350;
langText.y = 700 + Math.floor(i / 4) * 150;
langText.langCode = lang.code;
self.addChild(langText);
self.languageButtons.push({
button: langBtn,
flag: flagIcon,
text: langText,
code: lang.code,
x: 350 + i % 4 * 350,
y: 700 + Math.floor(i / 4) * 150
});
}
// Audio settings
var audioLabel = new Text2('Audio Settings', {
size: 45,
fill: '#e67e22'
});
audioLabel.anchor.set(0.5, 0.5);
audioLabel.x = 1024;
audioLabel.y = 1400;
self.addChild(audioLabel);
var volumeLabel = new Text2('Master Volume: 100%', {
size: 35,
fill: '#95a5a6'
});
volumeLabel.anchor.set(0.5, 0.5);
volumeLabel.x = 1024;
volumeLabel.y = 1500;
self.addChild(volumeLabel);
var backBtn = self.attachAsset('backButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1700
});
var backText = new Text2('', {
size: 40,
fill: '#ffffff'
});
backText.anchor.set(0.5, 0.5);
backText.x = 1024;
backText.y = 1700;
self.addChild(backText);
self.updateLanguage = function () {
titleText.setText(translations[currentLanguage].settings || 'SETTINGS');
languageLabel.setText(translations[currentLanguage].language || 'Choose Language:');
backText.setText(translations[currentLanguage].back || 'BACK');
// Update button selection
for (var i = 0; i < self.languageButtons.length; i++) {
var btn = self.languageButtons[i];
var isSelected = currentLanguage === btn.code;
btn.text.fill = isSelected ? '#f1c40f' : '#ffffff';
}
};
self.down = function (x, y, obj) {
if (!obj || !obj.parent || !obj.parent.toGlobal) {
var localPos = {
x: x,
y: y
};
} else {
var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
}
// Check language buttons
for (var i = 0; i < self.languageButtons.length; i++) {
var btn = self.languageButtons[i];
if (localPos.x >= btn.x - 210 && localPos.x <= btn.x + 210 && localPos.y >= btn.y - 60 && localPos.y <= btn.y + 60) {
if (currentLanguage !== btn.code) {
currentLanguage = btn.code;
storage.language = currentLanguage;
updateAllLanguages();
LK.getSound('buttonClick').play();
LK.effects.flashScreen(0x3498db, 200);
// Refresh UI to update selection
currentView = 'settings';
updateView();
}
break;
}
}
// Check back button
if (localPos.x >= 874 && localPos.x <= 1174 && localPos.y >= 1640 && localPos.y <= 1760) {
currentView = 'menu';
updateView();
LK.getSound('buttonClick').play();
}
};
return self;
});
var Shop = Container.expand(function () {
var self = Container.call(this);
self.currentCategory = 'basic';
self.categories = ['basic', 'premium', 'legendary'];
self.categoryButtons = [];
self.itemButtons = [];
self.items = {
basic: {
feed: {
name: 'Premium Feed',
price: 5000,
effect: 'energy',
description: 'Restores horse energy',
icon: 'speedBoost'
},
medicine: {
name: 'Energy Boost',
price: 8000,
effect: 'health',
description: 'Increases max energy',
icon: 'healthBoost'
},
vitamins: {
name: 'Vitamins',
price: 10000,
effect: 'stamina',
description: 'Improves stamina',
icon: 'staminaBoost'
}
},
premium: {
equipment: {
name: 'Racing Equipment',
price: 15000,
effect: 'speed',
description: 'Professional racing gear',
icon: 'speedBoost'
},
training: {
name: 'Advanced Training',
price: 20000,
effect: 'training',
description: 'Elite training program',
icon: 'staminaBoost'
},
superFeed: {
name: 'Super Feed',
price: 25000,
effect: 'superEnergy',
description: 'Premium nutrition boost',
icon: 'healthBoost'
}
},
legendary: {
geneticBoost: {
name: 'Genetic Enhancement',
price: 100000,
effect: 'genetic',
description: 'Permanent stat boost',
icon: 'gemIcon'
},
championGear: {
name: 'Champion Gear',
price: 150000,
effect: 'champion',
description: 'Legendary equipment set',
icon: 'speedBoost'
},
immortalElixir: {
name: 'Immortal Elixir',
price: 200000,
effect: 'immortal',
description: 'Stops aging process',
icon: 'healthBoost'
}
}
};
self.setupUI = function () {
var background = self.attachAsset('shopBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
var titleText = new Text2(translations[currentLanguage].shop || 'Elite Horse Shop', {
size: 90,
fill: '#ecf0f1'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 250;
self.addChild(titleText);
// Category buttons
for (var i = 0; i < self.categories.length; i++) {
var category = self.categories[i];
var categoryBtn = self.attachAsset('shopButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 400 + i * 400,
y: 400
});
var categoryText = new Text2(category.toUpperCase(), {
size: 35,
fill: '#ffffff'
});
categoryText.anchor.set(0.5, 0.5);
categoryText.x = 400 + i * 400;
categoryText.y = 400;
categoryText.categoryId = category;
self.addChild(categoryText);
self.categoryButtons.push({
button: categoryBtn,
text: categoryText,
category: category
});
}
self.refreshItems();
var backBtn = self.attachAsset('backButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2400
});
var backText = new Text2(translations[currentLanguage].back || 'Back', {
size: 45,
fill: '#ffffff'
});
backText.anchor.set(0.5, 0.5);
backText.x = 1024;
backText.y = 2400;
self.addChild(backText);
};
self.refreshItems = function () {
// Clear existing item buttons
for (var i = 0; i < self.itemButtons.length; i++) {
if (self.itemButtons[i].destroy) {
self.itemButtons[i].destroy();
}
}
self.itemButtons = [];
var items = self.items[self.currentCategory];
var yPos = 600;
var itemIndex = 0;
for (var itemId in items) {
var item = items[itemId];
var cardType = self.currentCategory === 'legendary' ? 'legendaryItem' : self.currentCategory === 'premium' ? 'premiumItem' : 'itemCard';
var itemCard = self.attachAsset(cardType, {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: yPos
});
var itemIcon = self.attachAsset(item.icon, {
anchorX: 0.5,
anchorY: 0.5,
x: 650,
y: yPos
});
var itemText = new Text2(item.name, {
size: 40,
fill: '#ffffff'
});
itemText.anchor.set(0, 0.5);
itemText.x = 750;
itemText.y = yPos - 30;
self.addChild(itemText);
var priceText = new Text2('$' + item.price, {
size: 35,
fill: '#f1c40f'
});
priceText.anchor.set(0, 0.5);
priceText.x = 750;
priceText.y = yPos;
self.addChild(priceText);
var descText = new Text2(item.description, {
size: 28,
fill: '#bdc3c7'
});
descText.anchor.set(0, 0.5);
descText.x = 750;
descText.y = yPos + 35;
self.addChild(descText);
self.itemButtons.push({
card: itemCard,
icon: itemIcon,
itemId: itemId,
y: yPos
});
yPos += 220;
itemIndex++;
}
};
self.purchaseItem = function (itemId) {
var item = self.items[self.currentCategory][itemId];
if (money >= item.price) {
money -= item.price;
totalEarnings += item.price;
self.applyItemEffect(item.effect, item);
updateMoneyDisplay();
LK.getSound('coinSound').play();
LK.effects.flashScreen(0x00ff00, 300);
return true;
}
return false;
};
self.applyItemEffect = function (effect, item) {
if (horses.length > 0) {
var horse = horses[selectedHorseIndex || 0];
switch (effect) {
case 'energy':
horse.currentEnergy = horse.maxEnergy;
break;
case 'health':
horse.maxEnergy += 15;
break;
case 'speed':
horse.speed += 8;
break;
case 'stamina':
horse.stamina += 8;
break;
case 'training':
horse.train('speed');
horse.train('stamina');
horse.train('temperament');
break;
case 'superEnergy':
horse.currentEnergy = horse.maxEnergy;
horse.maxEnergy += 25;
break;
case 'genetic':
horse.speed += 20;
horse.stamina += 20;
horse.temperament += 20;
break;
case 'champion':
horse.speed += 15;
horse.stamina += 15;
horse.value *= 2;
break;
case 'immortal':
horse.age = Math.max(2, horse.age - 5);
horse.maxEnergy += 50;
break;
}
}
};
self.down = function (x, y, obj) {
if (!obj || !obj.parent || !obj.parent.toGlobal) {
var localPos = {
x: x,
y: y
};
} else {
var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
}
// Check category buttons
for (var i = 0; i < self.categoryButtons.length; i++) {
var btnX = 400 + i * 400;
var btnY = 400;
if (localPos.x >= btnX - 240 && localPos.x <= btnX + 240 && localPos.y >= btnY - 70 && localPos.y <= btnY + 70) {
self.currentCategory = self.categoryButtons[i].category;
self.refreshItems();
LK.getSound('buttonClick').play();
break;
}
}
// Check item buttons
for (var i = 0; i < self.itemButtons.length; i++) {
var item = self.itemButtons[i];
if (localPos.x >= 724 && localPos.x <= 1324 && localPos.y >= item.y - 100 && localPos.y <= item.y + 100) {
if (self.purchaseItem(item.itemId)) {
self.refreshItems();
}
break;
}
}
// Check back button
if (localPos.x >= 874 && localPos.x <= 1174 && localPos.y >= 2330 && localPos.y <= 2470) {
currentView = 'menu';
updateView();
LK.getSound('buttonClick').play();
}
};
return self;
});
var StableView = Container.expand(function () {
var self = Container.call(this);
var background = self.attachAsset('stableBox', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
var titleText = new Text2('Your Stable', {
size: 60,
fill: '#ffffff'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
self.addChild(titleText);
// Action buttons - First row
var breedBtn = self.attachAsset('breedButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 512,
y: 1800
});
var breedText = new Text2('BREED', {
size: 35,
fill: '#ffffff'
});
breedText.anchor.set(0.5, 0.5);
breedText.x = 512;
breedText.y = 1800;
self.addChild(breedText);
var trainBtn = self.attachAsset('trainButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1800
});
var trainText = new Text2('TRAIN', {
size: 35,
fill: '#ffffff'
});
trainText.anchor.set(0.5, 0.5);
trainText.x = 1024;
trainText.y = 1800;
self.addChild(trainText);
var raceBtn = self.attachAsset('raceButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1536,
y: 1800
});
var raceText = new Text2('RACE', {
size: 35,
fill: '#ffffff'
});
raceText.anchor.set(0.5, 0.5);
raceText.x = 1536;
raceText.y = 1800;
self.addChild(raceText);
// Action buttons - Second row
var vetBtn = self.attachAsset('vetButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 512,
y: 1950
});
var vetText = new Text2('VET', {
size: 35,
fill: '#ffffff'
});
vetText.anchor.set(0.5, 0.5);
vetText.x = 512;
vetText.y = 1950;
self.addChild(vetText);
var feedBtn = self.attachAsset('feedButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1950
});
var feedText = new Text2('FEED', {
size: 35,
fill: '#ffffff'
});
feedText.anchor.set(0.5, 0.5);
feedText.x = 1024;
feedText.y = 1950;
self.addChild(feedText);
var upgradeBtn = self.attachAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1536,
y: 1950
});
var upgradeText = new Text2('UPGRADE', {
size: 35,
fill: '#ffffff'
});
upgradeText.anchor.set(0.5, 0.5);
upgradeText.x = 1536;
upgradeText.y = 1950;
self.addChild(upgradeText);
self.horseIcons = [];
self.updateHorseDisplay = function () {
// Clear existing icons
for (var i = 0; i < self.horseIcons.length; i++) {
self.horseIcons[i].destroy();
}
self.horseIcons = [];
// Add current horses
for (var i = 0; i < horses.length; i++) {
var horse = horses[i];
var icon = self.attachAsset('horseIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 600 + i % 3 * 200,
y: 500 + Math.floor(i / 3) * 100
});
var nameText = new Text2(horse.name, {
size: 20,
fill: '#ffffff'
});
nameText.anchor.set(0.5, 0.5);
nameText.x = 600 + i % 3 * 200;
nameText.y = 550 + Math.floor(i / 3) * 100;
self.addChild(nameText);
var statsText = new Text2('Speed: ' + Math.floor(horse.speed) + ' Energy: ' + Math.floor(horse.currentEnergy), {
size: 16,
fill: '#ffffff'
});
statsText.anchor.set(0.5, 0.5);
statsText.x = 600 + i % 3 * 200;
statsText.y = 570 + Math.floor(i / 3) * 100;
self.addChild(statsText);
self.horseIcons.push(icon);
}
};
self.updateLanguage = function () {
titleText.setText(translations[currentLanguage].yourStable);
breedText.setText(translations[currentLanguage].breed);
trainText.setText(translations[currentLanguage].train);
raceText.setText(translations[currentLanguage].race);
vetText.setText(translations[currentLanguage].vet);
feedText.setText(translations[currentLanguage].feed);
upgradeText.setText(translations[currentLanguage].upgrade);
};
self.down = function (x, y, obj) {
// Safety check for obj.parent
if (!obj || !obj.parent || !obj.parent.toGlobal) {
var localPos = {
x: x,
y: y
};
} else {
var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
}
// Check breed button
if (localPos.x >= 312 && localPos.x <= 712 && localPos.y >= 1740 && localPos.y <= 1860) {
if (horses.length >= 2) {
var offspring = horses[0].breed(horses[1]);
horses.push(offspring);
money -= 5000;
self.updateHorseDisplay();
updateMoneyDisplay();
LK.getSound('buttonClick').play();
}
}
// Check train button
if (localPos.x >= 824 && localPos.x <= 1224 && localPos.y >= 1740 && localPos.y <= 1860) {
if (horses.length > 0) {
horses[0].train('speed');
money -= 1000;
trainingCount++;
self.updateHorseDisplay();
updateMoneyDisplay();
LK.getSound('training').play();
}
}
// Check race button
if (localPos.x >= 1336 && localPos.x <= 1736 && localPos.y >= 1740 && localPos.y <= 1860) {
if (horses.length > 0) {
startRace();
}
}
// Check vet button
if (localPos.x >= 312 && localPos.x <= 712 && localPos.y >= 1890 && localPos.y <= 2010) {
if (horses.length > 0) {
currentView = 'vet';
updateView();
LK.getSound('buttonClick').play();
}
}
// Check feed button
if (localPos.x >= 824 && localPos.x <= 1224 && localPos.y >= 1890 && localPos.y <= 2010) {
if (horses.length > 0 && money >= 500) {
horses[0].currentEnergy = Math.min(horses[0].maxEnergy, horses[0].currentEnergy + 50);
money -= 500;
self.updateHorseDisplay();
updateMoneyDisplay();
LK.getSound('buttonClick').play();
}
}
// Check upgrade button
if (localPos.x >= 1336 && localPos.x <= 1736 && localPos.y >= 1890 && localPos.y <= 2010) {
if (horses.length > 0 && money >= 10000) {
horses[0].speed += 5;
horses[0].stamina += 5;
money -= 10000;
self.updateHorseDisplay();
updateMoneyDisplay();
LK.getSound('buttonClick').play();
}
}
};
return self;
});
var Tournament = Container.expand(function () {
var self = Container.call(this);
self.tournaments = [{
name: 'Spring Classic',
prize: 25000,
difficulty: 'easy',
entryFee: 2000
}, {
name: 'Summer Championship',
prize: 50000,
difficulty: 'medium',
entryFee: 5000
}, {
name: 'Grand Prix',
prize: 100000,
difficulty: 'hard',
entryFee: 10000
}, {
name: 'Ultimate Derby',
prize: 200000,
difficulty: 'extreme',
entryFee: 20000
}];
self.currentTournament = null;
self.tournamentProgress = 0;
self.titleText = null;
self.backText = null;
self.setupUI = function () {
var background = self.attachAsset('menuBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
self.titleText = new Text2(translations[currentLanguage].tournaments || 'Tournaments', {
size: 80,
fill: '#ffffff'
});
self.titleText.anchor.set(0.5, 0.5);
self.titleText.x = 1024;
self.titleText.y = 300;
self.addChild(self.titleText);
var yPos = 600;
for (var i = 0; i < self.tournaments.length; i++) {
var tournament = self.tournaments[i];
var tournamentBtn = self.attachAsset('tournamentButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: yPos
});
var tournamentText = new Text2(tournament.name + ' - Prize: $' + tournament.prize, {
size: 28,
fill: '#ffffff'
});
tournamentText.anchor.set(0.5, 0.5);
tournamentText.x = 1024;
tournamentText.y = yPos;
self.addChild(tournamentText);
yPos += 150;
}
var backBtn = self.attachAsset('backButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2200
});
self.backText = new Text2(translations[currentLanguage].back || 'Back', {
size: 40,
fill: '#ffffff'
});
self.backText.anchor.set(0.5, 0.5);
self.backText.x = 1024;
self.backText.y = 2200;
self.addChild(self.backText);
};
self.updateLanguage = function () {
if (self.titleText) {
self.titleText.setText(translations[currentLanguage].tournaments || 'Tournaments');
}
if (self.backText) {
self.backText.setText(translations[currentLanguage].back || 'Back');
}
};
self.enterTournament = function (tournamentIndex) {
var tournament = self.tournaments[tournamentIndex];
if (money >= tournament.entryFee) {
money -= tournament.entryFee;
self.currentTournament = tournament;
self.tournamentProgress = 0;
updateMoneyDisplay();
return true;
}
return false;
};
self.completeTournament = function () {
if (self.currentTournament) {
money += self.currentTournament.prize;
totalEarnings += self.currentTournament.prize;
self.currentTournament = null;
updateMoneyDisplay();
LK.getSound('victory').play();
}
};
self.down = function (x, y, obj) {
if (!obj || !obj.parent || !obj.parent.toGlobal) {
var localPos = {
x: x,
y: y
};
} else {
var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
}
// Check tournament buttons
var yPos = 600;
for (var i = 0; i < self.tournaments.length; i++) {
if (localPos.x >= 824 && localPos.x <= 1224 && localPos.y >= yPos - 60 && localPos.y <= yPos + 60) {
if (self.enterTournament(i)) {
currentView = 'race';
updateView();
LK.getSound('buttonClick').play();
}
break;
}
yPos += 150;
}
// Check back button
if (localPos.x >= 874 && localPos.x <= 1174 && localPos.y >= 2140 && localPos.y <= 2260) {
currentView = 'menu';
updateView();
LK.getSound('buttonClick').play();
}
};
return self;
});
var Veterinarian = Container.expand(function () {
var self = Container.call(this);
self.treatments = {
checkup: {
name: 'Health Checkup',
price: 1000,
effect: 'health'
},
energy: {
name: 'Energy Treatment',
price: 2000,
effect: 'energy'
},
performance: {
name: 'Performance Boost',
price: 5000,
effect: 'performance'
},
recovery: {
name: 'Recovery Therapy',
price: 3000,
effect: 'recovery'
}
};
self.titleText = null;
self.backText = null;
self.setupUI = function () {
var background = self.attachAsset('menuBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
self.titleText = new Text2(translations[currentLanguage].veterinarian || 'Veterinarian', {
size: 80,
fill: '#ffffff'
});
self.titleText.anchor.set(0.5, 0.5);
self.titleText.x = 1024;
self.titleText.y = 300;
self.addChild(self.titleText);
var yPos = 600;
for (var treatmentId in self.treatments) {
var treatment = self.treatments[treatmentId];
var treatmentBtn = self.attachAsset('vetButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: yPos
});
var treatmentText = new Text2(treatment.name + ' - $' + treatment.price, {
size: 30,
fill: '#ffffff'
});
treatmentText.anchor.set(0.5, 0.5);
treatmentText.x = 1024;
treatmentText.y = yPos;
self.addChild(treatmentText);
yPos += 150;
}
var backBtn = self.attachAsset('backButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2200
});
self.backText = new Text2(translations[currentLanguage].back || 'Back', {
size: 40,
fill: '#ffffff'
});
self.backText.anchor.set(0.5, 0.5);
self.backText.x = 1024;
self.backText.y = 2200;
self.addChild(self.backText);
};
self.updateLanguage = function () {
if (self.titleText) {
self.titleText.setText(translations[currentLanguage].veterinarian || 'Veterinarian');
}
if (self.backText) {
self.backText.setText(translations[currentLanguage].back || 'Back');
}
};
self.performTreatment = function (treatmentId) {
var treatment = self.treatments[treatmentId];
if (money >= treatment.price && horses.length > 0) {
money -= treatment.price;
self.applyTreatment(treatment.effect);
updateMoneyDisplay();
return true;
}
return false;
};
self.applyTreatment = function (effect) {
if (horses.length > 0) {
var horse = horses[0];
switch (effect) {
case 'health':
horse.maxEnergy += 20;
break;
case 'energy':
horse.currentEnergy = horse.maxEnergy;
break;
case 'performance':
horse.speed += 10;
horse.stamina += 10;
break;
case 'recovery':
horse.currentEnergy = horse.maxEnergy;
horse.speed += 5;
break;
}
}
};
self.down = function (x, y, obj) {
if (!obj || !obj.parent || !obj.parent.toGlobal) {
var localPos = {
x: x,
y: y
};
} else {
var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
}
// Check treatment buttons
var yPos = 600;
for (var treatmentId in self.treatments) {
if (localPos.x >= 824 && localPos.x <= 1224 && localPos.y >= yPos - 75 && localPos.y <= yPos + 75) {
if (self.performTreatment(treatmentId)) {
LK.getSound('buttonClick').play();
LK.effects.flashScreen(0x00ff00, 300);
}
break;
}
yPos += 150;
}
// Check back button
if (localPos.x >= 874 && localPos.x <= 1174 && localPos.y >= 2140 && localPos.y <= 2260) {
currentView = 'stable';
updateView();
LK.getSound('buttonClick').play();
}
};
return self;
});
var Weather = Container.expand(function () {
var self = Container.call(this);
self.conditions = ['sunny', 'rainy', 'cloudy', 'windy'];
self.currentWeather = 'sunny';
self.weatherIcon = null;
self.init = function () {
self.weatherIcon = self.attachAsset('weatherIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 1900,
y: 150
});
self.updateWeather();
};
self.updateWeather = function () {
self.currentWeather = self.conditions[Math.floor(Math.random() * self.conditions.length)];
switch (self.currentWeather) {
case 'sunny':
self.weatherIcon.tint = 0xffff00;
break;
case 'rainy':
self.weatherIcon.tint = 0x0080ff;
break;
case 'cloudy':
self.weatherIcon.tint = 0x808080;
break;
case 'windy':
self.weatherIcon.tint = 0x90ee90;
break;
}
};
self.getSpeedModifier = function () {
switch (self.currentWeather) {
case 'sunny':
return 1.1;
case 'rainy':
return 0.9;
case 'cloudy':
return 1.0;
case 'windy':
return 0.95;
default:
return 1.0;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228B22
});
/****
* Game Code
****/
// Language translations
var translations = {
en: {
title: 'Thoroughbred Legacy',
play: 'PLAY',
settings: 'SETTINGS',
language: 'Language:',
back: 'BACK',
yourStable: 'Your Stable',
breed: 'BREED',
train: 'TRAIN',
race: 'RACE',
money: 'Money: $',
wins: 'Wins: ',
help: 'HELP & GUIDE',
shop: 'SHOP',
tournament: 'TOURNAMENT',
vet: 'VETERINARIAN',
feed: 'FEED',
upgrade: 'UPGRADE'
},
ru: {
title: 'Наследие Чистокровных',
play: 'ИГРАТЬ',
settings: 'НАСТРОЙКИ',
language: 'Язык:',
back: 'НАЗАД',
yourStable: 'Ваша Конюшня',
breed: 'РАЗВЕДЕНИЕ',
train: 'ТРЕНИРОВКА',
race: 'ГОНКА',
money: 'Деньги: $',
wins: 'Побед: ',
help: 'ПОМОЩЬ И РУКОВОДСТВО'
},
fr: {
title: 'Héritage Pur-Sang',
play: 'JOUER',
settings: 'PARAMÈTRES',
language: 'Langue:',
back: 'RETOUR',
yourStable: 'Votre Écurie',
breed: 'ÉLEVAGE',
train: 'ENTRAÎNER',
race: 'COURSE',
money: 'Argent: $',
wins: 'Victoires: ',
help: 'AIDE ET GUIDE'
},
tr: {
title: 'Safkan Mirası',
play: 'OYNA',
settings: 'AYARLAR',
language: 'Dil Seçimi:',
back: 'GERİ',
yourStable: 'Ahırınız',
breed: 'ÜRETME',
train: 'EĞİTİM',
race: 'YARIŞ',
money: 'Para: $',
wins: 'Galibiyet: ',
upgrade: 'GELİŞTİRME',
shop: 'ELİT AT MAĞAZASI',
tournament: 'TURNUVA',
vet: 'VETERİNER',
feed: 'BESLENME',
weather: 'Hava Durumu',
achievements: 'Başarılar',
statistics: 'İstatistikler',
basic: 'TEMEL',
premium: 'PREMİUM',
legendary: 'EFSANEVİ',
audio: 'Ses Ayarları',
volume: 'Ana Ses: %',
tournaments: 'Turnuvalar',
veterinarian: 'Veteriner Hekim',
selectHorse: 'At Seçin',
horseStats: 'At İstatistikleri',
speed: 'Hız',
stamina: 'Dayanıklılık',
energy: 'Enerji',
age: 'Yaş',
value: 'Değer',
raceWins: 'Yarış Zaferleri',
temperament: 'Mizaç',
help: 'YARDIM VE KILAVUZ'
},
es: {
title: 'Legado Pura Sangre',
play: 'JUGAR',
settings: 'CONFIGURACIÓN',
language: 'Idioma:',
back: 'VOLVER',
yourStable: 'Tu Establo',
breed: 'CRIAR',
train: 'ENTRENAR',
race: 'CARRERA',
money: 'Dinero: $',
wins: 'Victorias: ',
upgrade: 'MEJORAR',
shop: 'TIENDA',
tournament: 'TORNEO',
vet: 'VETERINARIO',
feed: 'ALIMENTAR',
weather: 'Clima',
achievements: 'Logros',
statistics: 'Estadísticas',
help: 'AYUDA Y GUÍA'
},
de: {
title: 'Vollblut Erbe',
play: 'SPIELEN',
settings: 'EINSTELLUNGEN',
language: 'Sprache:',
back: 'ZURÜCK',
yourStable: 'Dein Stall',
breed: 'ZÜCHTEN',
train: 'TRAINIEREN',
race: 'RENNEN',
money: 'Geld: $',
wins: 'Siege: ',
upgrade: 'VERBESSERN',
shop: 'LADEN',
tournament: 'TURNIER',
vet: 'TIERARZT',
feed: 'FÜTTERN',
weather: 'Wetter',
achievements: 'Erfolge',
statistics: 'Statistiken',
help: 'HILFE UND ANLEITUNG'
},
zh: {
title: '纯血传承',
play: '开始游戏',
settings: '设置',
language: '语言:',
back: '返回',
yourStable: '你的马厩',
breed: '繁殖',
train: '训练',
race: '比赛',
money: '金钱: $',
wins: '胜利: ',
upgrade: '升级',
shop: '商店',
tournament: '锦标赛',
vet: '兽医',
feed: '喂养',
weather: '天气',
achievements: '成就',
statistics: '统计',
help: '帮助和指南'
},
ja: {
title: 'サラブレッドの遺産',
play: 'プレイ',
settings: '設定',
language: '言語:',
back: '戻る',
yourStable: 'あなたの厩舎',
breed: '繁殖',
train: '訓練',
race: 'レース',
money: 'お金: $',
wins: '勝利: ',
upgrade: 'アップグレード',
shop: 'ショップ',
tournament: 'トーナメント',
vet: '獣医',
feed: '餌やり',
weather: '天気',
achievements: '実績',
statistics: '統計',
help: 'ヘルプとガイド'
},
it: {
title: 'Eredità Purosangue',
play: 'GIOCA',
settings: 'IMPOSTAZIONI',
language: 'Lingua:',
back: 'INDIETRO',
yourStable: 'La Tua Scuderia',
breed: 'ALLEVARE',
train: 'ALLENARE',
race: 'CORSA',
money: 'Denaro: $',
wins: 'Vittorie: ',
upgrade: 'MIGLIORARE',
shop: 'NEGOZIO',
tournament: 'TORNEO',
vet: 'VETERINARIO',
feed: 'NUTRIRE',
weather: 'Tempo',
achievements: 'Risultati',
statistics: 'Statistiche',
help: 'AIUTO E GUIDA'
},
pt: {
title: 'Legado Puro Sangue',
play: 'JOGAR',
settings: 'CONFIGURAÇÕES',
language: 'Idioma:',
back: 'VOLTAR',
yourStable: 'Seu Estábulo',
breed: 'CRIAR',
train: 'TREINAR',
race: 'CORRIDA',
money: 'Dinheiro: $',
wins: 'Vitórias: ',
upgrade: 'MELHORAR',
shop: 'LOJA',
tournament: 'TORNEIO',
vet: 'VETERINÁRIO',
feed: 'ALIMENTAR',
weather: 'Tempo',
achievements: 'Conquistas',
statistics: 'Estatísticas',
help: 'AJUDA E GUIA'
}
};
// Load saved language or default to English
var currentLanguage = storage.language || 'en';
// Game state
var currentView = 'menu';
var horses = [];
var money = 50000;
var raceInProgress = false;
var totalEarnings = storage.totalEarnings || 0;
var trainingCount = storage.trainingCount || 0;
var breedingCount = storage.breedingCount || 0;
var selectedHorseIndex = 0;
var weatherSystem = null;
var achievementSystem = null;
var shopSystem = null;
var tournamentSystem = null;
var veterinarianSystem = null;
var helpSystem = null;
var currentWeather = 'sunny';
var gameTime = 0;
var seasonalBonus = 1.0;
// UI Elements
var moneyText = new Text2('Money: $' + money, {
size: 40,
fill: '#ffffff'
});
moneyText.anchor.set(0, 0);
moneyText.x = 150;
moneyText.y = 50;
LK.gui.topLeft.addChild(moneyText);
var scoreText = new Text2('Wins: ' + LK.getScore(), {
size: 40,
fill: '#ffffff'
});
scoreText.anchor.set(1, 0);
scoreText.x = -50;
scoreText.y = 50;
LK.gui.topRight.addChild(scoreText);
// Views
var mainMenu = new MainMenu();
var settingsMenu = new SettingsMenu();
var stableView = new StableView();
var raceView = new RaceView();
// Initialize game systems
weatherSystem = new Weather();
achievementSystem = new Achievement();
shopSystem = new Shop();
tournamentSystem = new Tournament();
veterinarianSystem = new Veterinarian();
helpSystem = new Help();
// Setup weather system
weatherSystem.init();
game.addChild(weatherSystem);
// Load achievements from storage
if (storage.achievements) {
// Reconstruct achievements from flattened storage
var flatAchievements = storage.achievements;
for (var key in achievementSystem.achievements) {
if (flatAchievements[key + '_unlocked'] !== undefined) {
achievementSystem.achievements[key].unlocked = flatAchievements[key + '_unlocked'];
}
if (flatAchievements[key + '_name'] !== undefined) {
achievementSystem.achievements[key].name = flatAchievements[key + '_name'];
}
if (flatAchievements[key + '_description'] !== undefined) {
achievementSystem.achievements[key].description = flatAchievements[key + '_description'];
}
}
}
// Initialize with starter horses
horses.push(new Horse({
name: 'Thunder',
speed: 70,
stamina: 65,
temperament: 60
}));
horses.push(new Horse({
name: 'Lightning',
speed: 60,
stamina: 70,
temperament: 65
}));
function updateMoneyDisplay() {
moneyText.setText(translations[currentLanguage].money + money);
scoreText.setText(translations[currentLanguage].wins + LK.getScore());
}
function updateAllLanguages() {
updateMoneyDisplay();
if (mainMenu.parent) {
mainMenu.updateLanguage();
}
if (settingsMenu.parent) {
settingsMenu.updateLanguage();
}
if (stableView.parent) {
stableView.updateLanguage();
}
}
function updateView() {
// Remove all views
if (mainMenu.parent) {
game.removeChild(mainMenu);
}
if (settingsMenu.parent) {
game.removeChild(settingsMenu);
}
if (stableView.parent) {
game.removeChild(stableView);
}
if (raceView.parent) {
game.removeChild(raceView);
}
// Add current view
if (currentView === 'menu') {
game.addChild(mainMenu);
mainMenu.updateLanguage();
raceInProgress = false;
LK.playMusic('menuMusic');
} else if (currentView === 'settings') {
game.addChild(settingsMenu);
settingsMenu.updateLanguage();
raceInProgress = false;
} else if (currentView === 'stable') {
game.addChild(stableView);
stableView.updateHorseDisplay();
stableView.updateLanguage();
raceInProgress = false;
LK.playMusic('stableMusic');
} else if (currentView === 'race') {
game.addChild(raceView);
raceView.setupRace();
raceInProgress = true;
LK.getSound('hoofbeats').play();
LK.playMusic('raceMusic');
} else if (currentView === 'shop') {
shopSystem.setupUI();
game.addChild(shopSystem);
raceInProgress = false;
} else if (currentView === 'tournament') {
tournamentSystem.setupUI();
game.addChild(tournamentSystem);
if (tournamentSystem.updateLanguage) {
tournamentSystem.updateLanguage();
}
raceInProgress = false;
} else if (currentView === 'vet') {
veterinarianSystem.setupUI();
game.addChild(veterinarianSystem);
if (veterinarianSystem.updateLanguage) {
veterinarianSystem.updateLanguage();
}
raceInProgress = false;
} else if (currentView === 'help') {
if (helpSystem.parent) {
game.removeChild(helpSystem);
}
helpSystem.setupUI();
game.addChild(helpSystem);
if (helpSystem.updateLanguage) {
helpSystem.updateLanguage();
}
raceInProgress = false;
}
}
function startRace() {
if (horses.length > 0) {
currentView = 'race';
updateView();
}
}
// Helper functions
function saveGameProgress() {
storage.money = money;
storage.totalEarnings = totalEarnings;
storage.trainingCount = trainingCount;
storage.breedingCount = breedingCount;
// Flatten achievements for storage
var flatAchievements = {};
for (var key in achievementSystem.achievements) {
flatAchievements[key + '_unlocked'] = achievementSystem.achievements[key].unlocked;
flatAchievements[key + '_name'] = achievementSystem.achievements[key].name;
flatAchievements[key + '_description'] = achievementSystem.achievements[key].description;
}
storage.achievements = flatAchievements;
// Flatten horse data for storage
var flatHorseData = [];
for (var i = 0; i < horses.length; i++) {
flatHorseData.push([horses[i].name, horses[i].speed, horses[i].stamina, horses[i].temperament, horses[i].age, horses[i].raceWins, horses[i].value, horses[i].currentEnergy, horses[i].maxEnergy]);
}
storage.horseData = flatHorseData;
}
function loadGameProgress() {
if (storage.money) {
money = storage.money;
}
if (storage.totalEarnings) {
totalEarnings = storage.totalEarnings;
}
if (storage.trainingCount) {
trainingCount = storage.trainingCount;
}
if (storage.breedingCount) {
breedingCount = storage.breedingCount;
}
if (storage.achievements) {
// Reconstruct achievements from flattened storage
var flatAchievements = storage.achievements;
for (var key in achievementSystem.achievements) {
if (flatAchievements[key + '_unlocked'] !== undefined) {
achievementSystem.achievements[key].unlocked = flatAchievements[key + '_unlocked'];
}
if (flatAchievements[key + '_name'] !== undefined) {
achievementSystem.achievements[key].name = flatAchievements[key + '_name'];
}
if (flatAchievements[key + '_description'] !== undefined) {
achievementSystem.achievements[key].description = flatAchievements[key + '_description'];
}
}
}
if (storage.horseData) {
horses = [];
for (var i = 0; i < storage.horseData.length; i++) {
var horseArray = storage.horseData[i];
horses.push(new Horse({
name: horseArray[0],
speed: horseArray[1],
stamina: horseArray[2],
temperament: horseArray[3],
age: horseArray[4],
raceWins: horseArray[5],
value: horseArray[6],
currentEnergy: horseArray[7],
maxEnergy: horseArray[8]
}));
}
}
}
function getWeatherBonus() {
return weatherSystem.getSpeedModifier() * seasonalBonus;
}
function generateRandomHorseName() {
var names = ['Thunder', 'Lightning', 'Storm', 'Blaze', 'Spirit', 'Shadow', 'Comet', 'Star', 'Flash', 'Dash', 'Wind', 'Fire', 'Rain', 'Snow', 'Frost', 'Dawn', 'Dusk', 'Moon', 'Sun', 'Sky'];
return names[Math.floor(Math.random() * names.length)] + ' ' + Math.floor(Math.random() * 1000);
}
// Load saved progress
loadGameProgress();
// Initialize view
updateView();
// Play background music
LK.playMusic('stableMusic');
// Main game loop
game.update = function () {
gameTime++;
// Update weather every 30 seconds (1800 ticks)
if (gameTime % 1800 === 0) {
weatherSystem.updateWeather();
currentWeather = weatherSystem.currentWeather;
}
// Update seasonal bonus
seasonalBonus = Math.sin(gameTime / 10800) * 0.2 + 1.0;
if (raceInProgress && raceView.parent) {
raceView.checkRaceFinish();
}
// Auto-rest horses when not racing
if (!raceInProgress) {
for (var i = 0; i < horses.length; i++) {
if (horses[i].currentEnergy < horses[i].maxEnergy) {
horses[i].currentEnergy = Math.min(horses[i].maxEnergy, horses[i].currentEnergy + 0.1);
}
}
}
// Update achievements
achievementSystem.checkAchievements();
// Save progress every 10 seconds
if (gameTime % 600 === 0) {
storage.totalEarnings = totalEarnings;
storage.trainingCount = trainingCount;
storage.breedingCount = breedingCount;
// Flatten achievements for storage
var flatAchievements = {};
for (var key in achievementSystem.achievements) {
flatAchievements[key + '_unlocked'] = achievementSystem.achievements[key].unlocked;
flatAchievements[key + '_name'] = achievementSystem.achievements[key].name;
flatAchievements[key + '_description'] = achievementSystem.achievements[key].description;
}
storage.achievements = flatAchievements;
}
// Enhanced win condition - 25 race wins
if (LK.getScore() >= 25) {
LK.showYouWin();
}
// Enhanced lose condition - out of money and no horses
if (money <= 0 && horses.length === 0) {
LK.showGameOver();
}
// Random events
if (gameTime % 3600 === 0 && Math.random() < 0.1) {
// Random bonus money
var bonus = Math.floor(Math.random() * 5000) + 1000;
money += bonus;
totalEarnings += bonus;
updateMoneyDisplay();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -356,20 +356,19 @@
if (self.isRacing) {
self.raceSpeed = self.getRaceSpeed() * (0.8 + Math.random() * 0.4);
self.racePosition += self.raceSpeed * 0.1;
// Calculate circular track position
- // Track center at (1024, 1366), radius adjusted to follow track image more closely
var trackCenterX = 1024;
var trackCenterY = 1366;
- var trackRadius = 600; // Reduced radius to stay closer to track
+ var trackRadius = 550; // Match track radius exactly
// Convert linear race position to angle (0 to 2*PI for full lap)
- var raceAngle = self.racePosition / 1850 * Math.PI * 2;
- // Calculate horse position on circular track with lane offset
- var laneOffset = self.racePosition % 100 * 0.5; // Dynamic lane positioning
- var currentRadius = trackRadius + laneOffset;
+ var raceAngle = self.racePosition / 2000 * Math.PI * 2;
+ // Calculate horse position on circular track - keep horses on track
+ var laneVariation = Math.sin(self.racePosition * 0.01) * 5; // Small lane variation
+ var currentRadius = trackRadius + laneVariation;
self.x = trackCenterX + Math.cos(raceAngle) * currentRadius;
self.y = trackCenterY + Math.sin(raceAngle) * currentRadius;
- // Adjust horse rotation to face direction of movement
+ // Adjust horse rotation to face direction of movement (tangent to circle)
self.rotation = raceAngle + Math.PI / 2;
// Energy drain during race
self.currentEnergy = Math.max(0, self.currentEnergy - 0.2);
}
@@ -513,30 +512,36 @@
return self;
});
var RaceView = Container.expand(function () {
var self = Container.call(this);
- // Create race track
- var track = self.attachAsset('trackSegment', {
+ // Create circular race track
+ var trackOuter = self.attachAsset('circularTrack', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
- var finishLine = self.attachAsset('finish', {
+ var trackInner = self.attachAsset('trackInner', {
anchorX: 0.5,
anchorY: 0.5,
- x: 1824,
+ x: 1024,
y: 1366
});
+ var finishLine = self.attachAsset('startFinishLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024 + 550,
+ y: 1366
+ });
var raceTitle = new Text2('RACE IN PROGRESS', {
size: 50,
fill: '#ffffff'
});
raceTitle.anchor.set(0.5, 0.5);
raceTitle.x = 1024;
raceTitle.y = 200;
self.addChild(raceTitle);
- var trackInfo = new Text2('Circular Track - One Lap Race', {
+ var trackInfo = new Text2('Professional Circular Track - Complete One Lap', {
size: 30,
fill: '#ffff00'
});
trackInfo.anchor.set(0.5, 0.5);
@@ -572,15 +577,15 @@
}
// Position horses at start line on circular track
var trackCenterX = 1024;
var trackCenterY = 1366;
- var baseRadius = 600; // Adjusted to match track better
+ var trackRadius = 550; // Match track outer radius
for (var i = 0; i < raceHorsesList.length; i++) {
var horse = raceHorsesList[i];
- // Position horses in lanes around the starting point
- var laneRadius = baseRadius + i * 10; // Smaller lane spacing
- horse.x = trackCenterX + laneRadius;
- horse.y = trackCenterY;
+ // Position horses in lanes at starting line (right side of track)
+ var laneOffset = (i - 2.5) * 15; // Center lanes around middle
+ horse.x = trackCenterX + trackRadius;
+ horse.y = trackCenterY + laneOffset;
horse.racePosition = 0;
horse.isRacing = true;
horse.currentEnergy = horse.maxEnergy;
horse.rotation = Math.PI / 2; // Face forward initially
@@ -594,10 +599,10 @@
return true;
}
for (var i = 0; i < self.raceHorses.length; i++) {
var horse = self.raceHorses[i];
- if (horse.racePosition >= 1850 && !self.raceFinished) {
- // Race finished
+ if (horse.racePosition >= 2000 && !self.raceFinished) {
+ // Race finished - one complete lap
self.finishRace(horse);
return true;
}
}