/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Oyuncu arabası var Car = Container.expand(function () { var self = Container.call(this); var carAsset = self.attachAsset('car', { anchorX: 0.5, anchorY: 0.5 }); self.width = carAsset.width; self.height = carAsset.height; return self; }); // Para (coin) var Coin = Container.expand(function () { var self = Container.call(this); var coinAsset = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.width = coinAsset.width; self.height = coinAsset.height; self.speed = 18; self.update = function () { self.y += self.speed; }; return self; }); // Vites butonu (D/R) var GearButton = Container.expand(function () { var self = Container.call(this); self.txt = new Text2('D', { size: 80, fill: "#fff" }); self.txt.anchor.set(0.5, 0.5); self.addChild(self.txt); self.gear = 'D'; // 'D' or 'R' self.setGear = function (gear) { self.gear = gear; self.txt.setText(gear); }; return self; }); // Engel var Obstacle = Container.expand(function () { var self = Container.call(this); var obsAsset = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.width = obsAsset.width; self.height = obsAsset.height; self.speed = 18; // Başlangıç hızı, oyun ilerledikçe artacak self.update = function () { self.y += self.speed; }; return self; }); // Pedal butonu (gaz/fren) var PedalButton = Container.expand(function () { var self = Container.call(this); self.txt = new Text2('Gaz', { size: 70, fill: "#fff" }); self.txt.anchor.set(0.5, 0.5); self.addChild(self.txt); self.type = 'gaz'; // 'gaz' or 'fren' self.setType = function (type) { self.type = type; self.txt.setText(type === 'gaz' ? 'Gaz' : 'Fren'); }; return self; }); // Yol kenarı dekoru var RoadEdge = Container.expand(function () { var self = Container.call(this); var edgeAsset = self.attachAsset('roadEdge', { anchorX: 0.5, anchorY: 0.5 }); self.width = edgeAsset.width; self.height = edgeAsset.height; self.speed = 18; self.update = function () { self.y += self.speed; }; return self; }); // Yol çizgisi var RoadLine = Container.expand(function () { var self = Container.call(this); var lineAsset = self.attachAsset('roadLine', { anchorX: 0.5, anchorY: 0.5 }); self.width = lineAsset.width; self.height = lineAsset.height; self.speed = 18; self.update = function () { self.y += self.speed; }; return self; }); // Dükkan simgesi var ShopIcon = Container.expand(function () { var self = Container.call(this); var shopAsset = self.attachAsset('shopIcon', { anchorX: 0.5, anchorY: 0.5 }); self.width = shopAsset.width; self.height = shopAsset.height; return self; }); // Direksiyon simidi var SteeringWheel = Container.expand(function () { var self = Container.call(this); self.txt = new Text2('🕹️', { size: 200, fill: "#fff" }); self.txt.anchor.set(0.5, 0.5); self.addChild(self.txt); // Görsel büyüklüğü ve alanı self.width = 260; self.height = 260; // Döndürme efekti için açı self.angle = 0; // Yana kaydırma için callback self.onSteer = null; // Basılı mı self.isDown = false; // Son X self.lastX = 0; // Sürükleme başlat self.down = function (x, y, obj) { self.isDown = true; self.lastX = x; }; // Sürükleme devam self.move = function (x, y, obj) { if (!self.isDown) return; var dx = x - self.lastX; self.lastX = x; self.angle += dx * 0.2; self.txt.rotation = self.angle * Math.PI / 180; if (self.onSteer) self.onSteer(dx); }; // Sürükleme bırak self.up = function (x, y, obj) { self.isDown = false; // Direksiyon açısını sıfırla (animasyonla) tween(self.txt, { rotation: 0 }, 200, { easing: 'easeOutQuad' }); self.angle = 0; }; return self; }); // Ağaç dekoru var Tree = Container.expand(function () { var self = Container.call(this); // Gövde var trunk = self.attachAsset('treeTrunk', { anchorX: 0.5, anchorY: 1.0, y: 180 }); // Yapraklar var leaves = self.attachAsset('treeLeaves', { anchorX: 0.5, anchorY: 0.5, y: 0, scaleX: 4.5, scaleY: 4.5 }); self.width = 600; self.height = 700; self.speed = 18; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Arka plan dekorları // Oyun alanı boyutları // Araba (oyuncu) için kutu şeklinde bir asset // Yol çizgisi için ince uzun kutu // Engel için kırmızı kutu var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; // Yolun genişliği (ekranın ortasında) var ROAD_WIDTH = 900; var ROAD_X = (GAME_WIDTH - ROAD_WIDTH) / 2; // Arabayı ve engelleri tutan değişkenler var car; var obstacles = []; var roadLines = []; var coins = []; var score = 0; var scoreTxt; var money = 0; var moneyTxt; var dragNode = null; var lastGameX = 0; var gameSpeed = 18; var ticksSinceStart = 0; var spawnInterval = 60; // Engel oluşturma aralığı (frame cinsinden) var minObstacleGap = 400; // Engeller arası minimum mesafe // Skor gösterimi (üstte, ortada) scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Para gösterimi (sağ üstte) moneyTxt = new Text2('₺0', { size: 90, fill: 0xFFD600 }); moneyTxt.anchor.set(1, 0); LK.gui.topRight.addChild(moneyTxt); // Duraklatma butonu (oyunu durdurmak için, sağ üstte) var pauseBtn = new Text2('⏸', { size: 120, fill: "#fff" }); pauseBtn.anchor.set(1, 0); pauseBtn.x = 0; pauseBtn.y = 340; LK.gui.topRight.addChild(pauseBtn); // Pause butonuna tıklama kontrolü için koordinatları sakla var pauseBtnArea = { x: GAME_WIDTH - 180, y: 340, width: 160, height: 160 }; // Dükkan açma butonu (duraklatma butonunun hemen altında) var shopBtn = new ShopIcon(); // Shop iconu yeşil yap if (shopBtn.children && shopBtn.children[0]) { shopBtn.children[0].tint = 0x00e676; } shopBtn.x = -320; // Daha sola kaydır (daha kolay tıklansın) shopBtn.y = pauseBtn.y + 180; LK.gui.topRight.addChild(shopBtn); // Shop butonuna tıklama kontrolü için koordinatları sakla var shopBtnArea = { x: GAME_WIDTH - 400, // daha sola kaydırıldı y: shopBtn.y, width: 160, height: 160 }; // Arka plan dekorları: yol kenarı ve ağaçlar var leftEdges = []; var rightEdges = []; var leftTrees = []; var rightTrees = []; var edgeCount = 8; var treeCount = 8; for (var i = 0; i < edgeCount; i++) { var lEdge = new RoadEdge(); lEdge.x = ROAD_X + 20; lEdge.y = i * 400 + 200; leftEdges.push(lEdge); game.addChild(lEdge); var rEdge = new RoadEdge(); rEdge.x = ROAD_X + ROAD_WIDTH - 20; rEdge.y = i * 400 + 200; rightEdges.push(rEdge); game.addChild(rEdge); } for (var i = 0; i < treeCount; i++) { var lTree = new Tree(); lTree.x = ROAD_X - 80; lTree.y = i * 400 + 100; leftTrees.push(lTree); game.addChild(lTree); var rTree = new Tree(); rTree.x = ROAD_X + ROAD_WIDTH + 80; rTree.y = i * 400 + 300; rightTrees.push(rTree); game.addChild(rTree); } // Arabayı oluştur ve konumlandır car = new Car(); game.addChild(car); car.x = GAME_WIDTH / 2; car.y = GAME_HEIGHT - 500; // Yol çizgilerini oluştur for (var i = 0; i < 7; i++) { var line = new RoadLine(); line.x = GAME_WIDTH / 2; line.y = i * 400 + 200; roadLines.push(line); game.addChild(line); } // Yol ayrımları için parametreler var forkActive = false; var forkXLeft = ROAD_X + ROAD_WIDTH * 0.25; var forkXRight = ROAD_X + ROAD_WIDTH * 0.75; var forkY = 900; var forkTimer = 0; var forkInterval = 900; // Her 900 frame'de bir yol ayrımı gelsin var forkChoice = null; // 'left' veya 'right' var forkVisuals = []; // Yol ayrımı görseli (çatalı) function showFork() { forkActive = true; forkChoice = null; // Sol ve sağ oklar var leftArrow = new Text2('⬅', { size: 180, fill: "#fff" }); leftArrow.anchor.set(0.5, 0.5); leftArrow.x = forkXLeft; leftArrow.y = forkY - 100; var rightArrow = new Text2('➡', { size: 180, fill: "#fff" }); rightArrow.anchor.set(0.5, 0.5); rightArrow.x = forkXRight; rightArrow.y = forkY - 100; forkVisuals.push(leftArrow, rightArrow); game.addChild(leftArrow); game.addChild(rightArrow); // Çatal çizgisi (görsel için iki yol çizgisi) for (var i = 0; i < 2; i++) { var forkLine = new RoadLine(); forkLine.x = i === 0 ? forkXLeft : forkXRight; forkLine.y = forkY; forkLine.speed = 0; forkVisuals.push(forkLine); game.addChild(forkLine); } } // Yol ayrımı görsellerini temizle function clearFork() { for (var i = 0; i < forkVisuals.length; i++) { forkVisuals[i].destroy(); } forkVisuals = []; forkActive = false; forkChoice = null; } // Vites butonları (D/R), gaz ve fren, direksiyon simidi var gearBtn = new GearButton(); gearBtn.x = 0; gearBtn.y = 0; gearBtn.setGear('D'); LK.gui.right.addChild(gearBtn); var pedalGaz = new PedalButton(); pedalGaz.setType('gaz'); pedalGaz.x = 0; pedalGaz.y = 180; LK.gui.right.addChild(pedalGaz); var pedalFren = new PedalButton(); pedalFren.setType('fren'); pedalFren.x = 0; pedalFren.y = 340; LK.gui.right.addChild(pedalFren); var steering = new SteeringWheel(); // Ekranın alt orta kısmına yerleştir (GUI overlay koordinatları ile) steering.x = LK.gui.center.width / 2; steering.y = LK.gui.bottom.height - 180; LK.gui.bottom.addChild(steering); // --- Fren butonu (sağ altta) --- var brakeBtn = new Text2('🛑', { size: 140, fill: "#fff" }); brakeBtn.anchor.set(1, 1); brakeBtn.x = LK.gui.bottomRight.width - 40; brakeBtn.y = LK.gui.bottomRight.height - 40; LK.gui.bottomRight.addChild(brakeBtn); // Brake button area for touch detection var brakeBtnArea = { x: GAME_WIDTH - 320, y: GAME_HEIGHT - 320, width: 260, height: 260 }; var brakePressed = false; // Oyun durumu için vites, gaz, fren var currentGear = 'D'; // 'D' veya 'R' var gazPressed = false; var frenPressed = false; // Direksiyon simidi ile araba kontrolü steering.onSteer = function (dx) { // dx: sağa/sola kaydırma miktarı if (!car) return; car.x += dx * 2.2; // Hassasiyet ayarı // Yol dışına çıkmasın var minX = ROAD_X + car.width / 2 + 10; var maxX = ROAD_X + ROAD_WIDTH - car.width / 2 - 10; if (car.x < minX) car.x = minX; if (car.x > maxX) car.x = maxX; }; // Oyun güncelleme fonksiyonu game.update = function () { ticksSinceStart++; // Yol kenarı ve ağaçları hareket ettir ve döngüsel olarak tekrar yukarıya al for (var i = 0; i < leftEdges.length; i++) { var lEdge = leftEdges[i]; lEdge.speed = gameSpeed; lEdge.update(); if (lEdge.y - lEdge.height / 2 > GAME_HEIGHT) { lEdge.y -= edgeCount * 400; } var rEdge = rightEdges[i]; rEdge.speed = gameSpeed; rEdge.update(); if (rEdge.y - rEdge.height / 2 > GAME_HEIGHT) { rEdge.y -= edgeCount * 400; } } for (var i = 0; i < leftTrees.length; i++) { var lTree = leftTrees[i]; lTree.speed = gameSpeed; lTree.update(); if (lTree.y - lTree.height / 2 > GAME_HEIGHT) { lTree.y -= treeCount * 400; } var rTree = rightTrees[i]; rTree.speed = gameSpeed; rTree.update(); if (rTree.y - rTree.height / 2 > GAME_HEIGHT) { rTree.y -= treeCount * 400; } } // Yol çizgilerini hareket ettir ve döngüsel olarak tekrar yukarıya al for (var i = 0; i < roadLines.length; i++) { var line = roadLines[i]; line.speed = gameSpeed; line.update(); if (line.y - line.height / 2 > GAME_HEIGHT) { line.y -= 7 * 400; } } // Yol ayrımı (fork) oluşturma ve yönetimi forkTimer++; if (!forkActive && forkTimer > forkInterval) { showFork(); forkTimer = 0; } // Eğer yol ayrımı aktifse, oyuncu seçim yapmalı if (forkActive) { // Araba çatal bölgesine geldi mi? if (!forkChoice && car.y < forkY + 100 && car.y > forkY - 100) { // Oyuncu sola veya sağa kayarsa seçim yap if (car.x < GAME_WIDTH / 2) { forkChoice = 'left'; } else if (car.x > GAME_WIDTH / 2) { forkChoice = 'right'; } if (forkChoice) { // Arabayı seçilen yola kaydır var targetX = forkChoice === 'left' ? forkXLeft : forkXRight; tween(car, { x: targetX }, 300, { easing: 'easeInOutQuad' }); // Yol çizgilerini de kaydır for (var i = 0; i < roadLines.length; i++) { tween(roadLines[i], { x: targetX }, 300, { easing: 'easeInOutQuad' }); } // 0.5 saniye sonra fork görsellerini kaldır LK.setTimeout(clearFork, 500); } } } // Engelleri hareket ettir for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.speed = gameSpeed; obs.update(); // Ekrandan çıktıysa sil if (obs.y - obs.height / 2 > GAME_HEIGHT + 100) { obs.destroy(); obstacles.splice(i, 1); score++; scoreTxt.setText(score); continue; } // Çarpışma kontrolü if (car.intersects(obs)) { LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } } // Paraları hareket ettir for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; coin.speed = gameSpeed; coin.update(); // Ekrandan çıktıysa sil if (coin.y - coin.height / 2 > GAME_HEIGHT + 100) { coin.destroy(); coins.splice(i, 1); continue; } // Araba ile çarpışma (para toplama) if (car.intersects(coin)) { money += 10; moneyTxt.setText('₺' + money); coin.destroy(); coins.splice(i, 1); continue; } } // Engel oluşturma (aralıkla) if (ticksSinceStart % spawnInterval === 0) { var obs = new Obstacle(); // Rastgele x konumu, yolun dışına çıkmasın var minX = ROAD_X + obs.width / 2 + 30; var maxX = ROAD_X + ROAD_WIDTH - obs.width / 2 - 30; obs.x = minX + Math.random() * (maxX - minX); obs.y = -obs.height / 2; obstacles.push(obs); game.addChild(obs); // %50 ihtimalle para da oluştur if (Math.random() < 0.5) { var coin = new Coin(); var minCoinX = ROAD_X + coin.width / 2 + 30; var maxCoinX = ROAD_X + ROAD_WIDTH - coin.width / 2 - 30; var tryCount = 0; var maxTries = 8; var validCoinPos = false; while (!validCoinPos && tryCount < maxTries) { coin.x = minCoinX + Math.random() * (maxCoinX - minCoinX); coin.y = -coin.height / 2 - 120; validCoinPos = true; // Check if coin would overlap with any obstacle at spawn for (var oi = 0; oi < obstacles.length; oi++) { var obs = obstacles[oi]; // Only check obstacles that are close to spawn Y if (Math.abs(obs.y - coin.y) < (obs.height + coin.height) / 2 + 40) { // Check X overlap if (Math.abs(obs.x - coin.x) < (obs.width + coin.width) / 2 + 10) { validCoinPos = false; break; } } } tryCount++; } if (validCoinPos) { coins.push(coin); game.addChild(coin); } else { coin.destroy(); } } } // Zorluk arttırma: zamanla hız ve engel sıklığı artar if (ticksSinceStart % 300 === 0 && gameSpeed < 38) { gameSpeed += 2; if (spawnInterval > 28) spawnInterval -= 4; } // Vites ve pedal kontrolleri // Fren butonu basılıysa araba tamamen dursun if (brakePressed) { // Arabayı tamamen durdur // Hiçbir hareket yok, gaz/fren/vites etkisiz // (car.y değişmez) // Ayrıca gaz/fren/vites etkisizleştirildiği için başka bir şey yapılmaz } else if (currentGear === 'D') { if (gazPressed) { car.y -= 10; if (car.y < GAME_HEIGHT / 2) car.y = GAME_HEIGHT / 2; } else if (frenPressed) { car.y += 8; if (car.y > GAME_HEIGHT - 500) car.y = GAME_HEIGHT - 500; } } else if (currentGear === 'R') { if (gazPressed) { car.y += 10; if (car.y > GAME_HEIGHT - 500) car.y = GAME_HEIGHT - 500; } else if (frenPressed) { car.y -= 8; if (car.y < GAME_HEIGHT / 2) car.y = GAME_HEIGHT / 2; } } // Skor güncellemesi (her frame değil, engel geçince artıyor) }; // Sürükleme işlemleri ve UI butonları game.down = function (x, y, obj) { // Vites butonuna tıklandı mı? var gearBtnBounds = LK.gui.right.toLocal(gearBtn.toGlobal({ x: 0, y: 0 })); if (x > GAME_WIDTH - 300 && y > 100 && y < 300) { // Vites değiştir if (currentGear === 'D') { currentGear = 'R'; gearBtn.setGear('R'); } else { currentGear = 'D'; gearBtn.setGear('D'); } return; } // Gaz pedalı if (x > GAME_WIDTH - 300 && y > 400 && y < 600) { gazPressed = true; return; } // Fren pedalı if (x > GAME_WIDTH - 300 && y > 600 && y < 800) { frenPressed = true; return; } // Fren butonu (sağ altta) if (x > brakeBtnArea.x && x < brakeBtnArea.x + brakeBtnArea.width && y > brakeBtnArea.y && y < brakeBtnArea.y + brakeBtnArea.height) { brakePressed = true; return; } // Dükkan açma butonu (duraklatma butonunun altında) // GUI overlay koordinatlarını oyun koordinatına çevir var shopBtnGlobal = LK.gui.topRight.toGlobal({ x: shopBtn.x, y: shopBtn.y }); if (x > shopBtnGlobal.x - shopBtn.width / 2 && x < shopBtnGlobal.x + shopBtn.width / 2 && y > shopBtnGlobal.y - shopBtn.height / 2 && y < shopBtnGlobal.y + shopBtn.height / 2) { LK.effects.flashScreen(0x00e676, 400); if (typeof LK.showShopMenu === "function") LK.showShopMenu(); return; } // Duraklatma butonu (sağ üstte) if (x > pauseBtnArea.x && x < pauseBtnArea.x + pauseBtnArea.width && y > pauseBtnArea.y && y < pauseBtnArea.y + pauseBtnArea.height) { LK.showPauseMenu(); return; } // Direksiyon simidi (sol alt) if (x < 400 && y > GAME_HEIGHT - 600) { // Direksiyon simidiyle sürükleme başlat if (steering && steering.down) steering.down(x, y, obj); // Arabayı da sürüklemeye başlat dragNode = car; lastGameX = x; return; } // Arabaya dokunulmuşsa veya ekrana dokunulmuşsa sürüklemeye başla if (x > car.x - car.width / 2 && x < car.x + car.width / 2 && y > car.y - car.height / 2 && y < car.y + car.height / 2) { dragNode = car; lastGameX = x; } else if (y > GAME_HEIGHT / 2 // Sadece alt yarıda sürüklemeye izin ver ) { dragNode = car; lastGameX = x; } }; game.move = function (x, y, obj) { if (dragNode === car) { // Eğer direksiyon simidi aktifse, onun move fonksiyonunu çağır if (steering && steering.isDown && steering.move) { steering.move(x, y, obj); } // Sürükleme ile araba hareketi devre dışı (direksiyon ile kontrol edilecek) // car.x değişimi steering.onSteer ile yapılacak } }; game.up = function (x, y, obj) { dragNode = null; gazPressed = false; frenPressed = false; brakePressed = false; if (steering && steering.isDown && steering.up) { steering.up(0, 0, null); } }; // Oyun başında skor ve para sıfırla score = 0; scoreTxt.setText(score); money = 0; moneyTxt.setText('₺' + money); currentGear = 'D'; gearBtn.setGear('D'); gazPressed = false; frenPressed = false;
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Oyuncu arabası
var Car = Container.expand(function () {
var self = Container.call(this);
var carAsset = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = carAsset.width;
self.height = carAsset.height;
return self;
});
// Para (coin)
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinAsset = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = coinAsset.width;
self.height = coinAsset.height;
self.speed = 18;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Vites butonu (D/R)
var GearButton = Container.expand(function () {
var self = Container.call(this);
self.txt = new Text2('D', {
size: 80,
fill: "#fff"
});
self.txt.anchor.set(0.5, 0.5);
self.addChild(self.txt);
self.gear = 'D'; // 'D' or 'R'
self.setGear = function (gear) {
self.gear = gear;
self.txt.setText(gear);
};
return self;
});
// Engel
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obsAsset = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = obsAsset.width;
self.height = obsAsset.height;
self.speed = 18; // Başlangıç hızı, oyun ilerledikçe artacak
self.update = function () {
self.y += self.speed;
};
return self;
});
// Pedal butonu (gaz/fren)
var PedalButton = Container.expand(function () {
var self = Container.call(this);
self.txt = new Text2('Gaz', {
size: 70,
fill: "#fff"
});
self.txt.anchor.set(0.5, 0.5);
self.addChild(self.txt);
self.type = 'gaz'; // 'gaz' or 'fren'
self.setType = function (type) {
self.type = type;
self.txt.setText(type === 'gaz' ? 'Gaz' : 'Fren');
};
return self;
});
// Yol kenarı dekoru
var RoadEdge = Container.expand(function () {
var self = Container.call(this);
var edgeAsset = self.attachAsset('roadEdge', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = edgeAsset.width;
self.height = edgeAsset.height;
self.speed = 18;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Yol çizgisi
var RoadLine = Container.expand(function () {
var self = Container.call(this);
var lineAsset = self.attachAsset('roadLine', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = lineAsset.width;
self.height = lineAsset.height;
self.speed = 18;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Dükkan simgesi
var ShopIcon = Container.expand(function () {
var self = Container.call(this);
var shopAsset = self.attachAsset('shopIcon', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = shopAsset.width;
self.height = shopAsset.height;
return self;
});
// Direksiyon simidi
var SteeringWheel = Container.expand(function () {
var self = Container.call(this);
self.txt = new Text2('🕹️', {
size: 200,
fill: "#fff"
});
self.txt.anchor.set(0.5, 0.5);
self.addChild(self.txt);
// Görsel büyüklüğü ve alanı
self.width = 260;
self.height = 260;
// Döndürme efekti için açı
self.angle = 0;
// Yana kaydırma için callback
self.onSteer = null;
// Basılı mı
self.isDown = false;
// Son X
self.lastX = 0;
// Sürükleme başlat
self.down = function (x, y, obj) {
self.isDown = true;
self.lastX = x;
};
// Sürükleme devam
self.move = function (x, y, obj) {
if (!self.isDown) return;
var dx = x - self.lastX;
self.lastX = x;
self.angle += dx * 0.2;
self.txt.rotation = self.angle * Math.PI / 180;
if (self.onSteer) self.onSteer(dx);
};
// Sürükleme bırak
self.up = function (x, y, obj) {
self.isDown = false;
// Direksiyon açısını sıfırla (animasyonla)
tween(self.txt, {
rotation: 0
}, 200, {
easing: 'easeOutQuad'
});
self.angle = 0;
};
return self;
});
// Ağaç dekoru
var Tree = Container.expand(function () {
var self = Container.call(this);
// Gövde
var trunk = self.attachAsset('treeTrunk', {
anchorX: 0.5,
anchorY: 1.0,
y: 180
});
// Yapraklar
var leaves = self.attachAsset('treeLeaves', {
anchorX: 0.5,
anchorY: 0.5,
y: 0,
scaleX: 4.5,
scaleY: 4.5
});
self.width = 600;
self.height = 700;
self.speed = 18;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Arka plan dekorları
// Oyun alanı boyutları
// Araba (oyuncu) için kutu şeklinde bir asset
// Yol çizgisi için ince uzun kutu
// Engel için kırmızı kutu
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
// Yolun genişliği (ekranın ortasında)
var ROAD_WIDTH = 900;
var ROAD_X = (GAME_WIDTH - ROAD_WIDTH) / 2;
// Arabayı ve engelleri tutan değişkenler
var car;
var obstacles = [];
var roadLines = [];
var coins = [];
var score = 0;
var scoreTxt;
var money = 0;
var moneyTxt;
var dragNode = null;
var lastGameX = 0;
var gameSpeed = 18;
var ticksSinceStart = 0;
var spawnInterval = 60; // Engel oluşturma aralığı (frame cinsinden)
var minObstacleGap = 400; // Engeller arası minimum mesafe
// Skor gösterimi (üstte, ortada)
scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Para gösterimi (sağ üstte)
moneyTxt = new Text2('₺0', {
size: 90,
fill: 0xFFD600
});
moneyTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(moneyTxt);
// Duraklatma butonu (oyunu durdurmak için, sağ üstte)
var pauseBtn = new Text2('⏸', {
size: 120,
fill: "#fff"
});
pauseBtn.anchor.set(1, 0);
pauseBtn.x = 0;
pauseBtn.y = 340;
LK.gui.topRight.addChild(pauseBtn);
// Pause butonuna tıklama kontrolü için koordinatları sakla
var pauseBtnArea = {
x: GAME_WIDTH - 180,
y: 340,
width: 160,
height: 160
};
// Dükkan açma butonu (duraklatma butonunun hemen altında)
var shopBtn = new ShopIcon();
// Shop iconu yeşil yap
if (shopBtn.children && shopBtn.children[0]) {
shopBtn.children[0].tint = 0x00e676;
}
shopBtn.x = -320; // Daha sola kaydır (daha kolay tıklansın)
shopBtn.y = pauseBtn.y + 180;
LK.gui.topRight.addChild(shopBtn);
// Shop butonuna tıklama kontrolü için koordinatları sakla
var shopBtnArea = {
x: GAME_WIDTH - 400,
// daha sola kaydırıldı
y: shopBtn.y,
width: 160,
height: 160
};
// Arka plan dekorları: yol kenarı ve ağaçlar
var leftEdges = [];
var rightEdges = [];
var leftTrees = [];
var rightTrees = [];
var edgeCount = 8;
var treeCount = 8;
for (var i = 0; i < edgeCount; i++) {
var lEdge = new RoadEdge();
lEdge.x = ROAD_X + 20;
lEdge.y = i * 400 + 200;
leftEdges.push(lEdge);
game.addChild(lEdge);
var rEdge = new RoadEdge();
rEdge.x = ROAD_X + ROAD_WIDTH - 20;
rEdge.y = i * 400 + 200;
rightEdges.push(rEdge);
game.addChild(rEdge);
}
for (var i = 0; i < treeCount; i++) {
var lTree = new Tree();
lTree.x = ROAD_X - 80;
lTree.y = i * 400 + 100;
leftTrees.push(lTree);
game.addChild(lTree);
var rTree = new Tree();
rTree.x = ROAD_X + ROAD_WIDTH + 80;
rTree.y = i * 400 + 300;
rightTrees.push(rTree);
game.addChild(rTree);
}
// Arabayı oluştur ve konumlandır
car = new Car();
game.addChild(car);
car.x = GAME_WIDTH / 2;
car.y = GAME_HEIGHT - 500;
// Yol çizgilerini oluştur
for (var i = 0; i < 7; i++) {
var line = new RoadLine();
line.x = GAME_WIDTH / 2;
line.y = i * 400 + 200;
roadLines.push(line);
game.addChild(line);
}
// Yol ayrımları için parametreler
var forkActive = false;
var forkXLeft = ROAD_X + ROAD_WIDTH * 0.25;
var forkXRight = ROAD_X + ROAD_WIDTH * 0.75;
var forkY = 900;
var forkTimer = 0;
var forkInterval = 900; // Her 900 frame'de bir yol ayrımı gelsin
var forkChoice = null; // 'left' veya 'right'
var forkVisuals = [];
// Yol ayrımı görseli (çatalı)
function showFork() {
forkActive = true;
forkChoice = null;
// Sol ve sağ oklar
var leftArrow = new Text2('⬅', {
size: 180,
fill: "#fff"
});
leftArrow.anchor.set(0.5, 0.5);
leftArrow.x = forkXLeft;
leftArrow.y = forkY - 100;
var rightArrow = new Text2('➡', {
size: 180,
fill: "#fff"
});
rightArrow.anchor.set(0.5, 0.5);
rightArrow.x = forkXRight;
rightArrow.y = forkY - 100;
forkVisuals.push(leftArrow, rightArrow);
game.addChild(leftArrow);
game.addChild(rightArrow);
// Çatal çizgisi (görsel için iki yol çizgisi)
for (var i = 0; i < 2; i++) {
var forkLine = new RoadLine();
forkLine.x = i === 0 ? forkXLeft : forkXRight;
forkLine.y = forkY;
forkLine.speed = 0;
forkVisuals.push(forkLine);
game.addChild(forkLine);
}
}
// Yol ayrımı görsellerini temizle
function clearFork() {
for (var i = 0; i < forkVisuals.length; i++) {
forkVisuals[i].destroy();
}
forkVisuals = [];
forkActive = false;
forkChoice = null;
}
// Vites butonları (D/R), gaz ve fren, direksiyon simidi
var gearBtn = new GearButton();
gearBtn.x = 0;
gearBtn.y = 0;
gearBtn.setGear('D');
LK.gui.right.addChild(gearBtn);
var pedalGaz = new PedalButton();
pedalGaz.setType('gaz');
pedalGaz.x = 0;
pedalGaz.y = 180;
LK.gui.right.addChild(pedalGaz);
var pedalFren = new PedalButton();
pedalFren.setType('fren');
pedalFren.x = 0;
pedalFren.y = 340;
LK.gui.right.addChild(pedalFren);
var steering = new SteeringWheel();
// Ekranın alt orta kısmına yerleştir (GUI overlay koordinatları ile)
steering.x = LK.gui.center.width / 2;
steering.y = LK.gui.bottom.height - 180;
LK.gui.bottom.addChild(steering);
// --- Fren butonu (sağ altta) ---
var brakeBtn = new Text2('🛑', {
size: 140,
fill: "#fff"
});
brakeBtn.anchor.set(1, 1);
brakeBtn.x = LK.gui.bottomRight.width - 40;
brakeBtn.y = LK.gui.bottomRight.height - 40;
LK.gui.bottomRight.addChild(brakeBtn);
// Brake button area for touch detection
var brakeBtnArea = {
x: GAME_WIDTH - 320,
y: GAME_HEIGHT - 320,
width: 260,
height: 260
};
var brakePressed = false;
// Oyun durumu için vites, gaz, fren
var currentGear = 'D'; // 'D' veya 'R'
var gazPressed = false;
var frenPressed = false;
// Direksiyon simidi ile araba kontrolü
steering.onSteer = function (dx) {
// dx: sağa/sola kaydırma miktarı
if (!car) return;
car.x += dx * 2.2; // Hassasiyet ayarı
// Yol dışına çıkmasın
var minX = ROAD_X + car.width / 2 + 10;
var maxX = ROAD_X + ROAD_WIDTH - car.width / 2 - 10;
if (car.x < minX) car.x = minX;
if (car.x > maxX) car.x = maxX;
};
// Oyun güncelleme fonksiyonu
game.update = function () {
ticksSinceStart++;
// Yol kenarı ve ağaçları hareket ettir ve döngüsel olarak tekrar yukarıya al
for (var i = 0; i < leftEdges.length; i++) {
var lEdge = leftEdges[i];
lEdge.speed = gameSpeed;
lEdge.update();
if (lEdge.y - lEdge.height / 2 > GAME_HEIGHT) {
lEdge.y -= edgeCount * 400;
}
var rEdge = rightEdges[i];
rEdge.speed = gameSpeed;
rEdge.update();
if (rEdge.y - rEdge.height / 2 > GAME_HEIGHT) {
rEdge.y -= edgeCount * 400;
}
}
for (var i = 0; i < leftTrees.length; i++) {
var lTree = leftTrees[i];
lTree.speed = gameSpeed;
lTree.update();
if (lTree.y - lTree.height / 2 > GAME_HEIGHT) {
lTree.y -= treeCount * 400;
}
var rTree = rightTrees[i];
rTree.speed = gameSpeed;
rTree.update();
if (rTree.y - rTree.height / 2 > GAME_HEIGHT) {
rTree.y -= treeCount * 400;
}
}
// Yol çizgilerini hareket ettir ve döngüsel olarak tekrar yukarıya al
for (var i = 0; i < roadLines.length; i++) {
var line = roadLines[i];
line.speed = gameSpeed;
line.update();
if (line.y - line.height / 2 > GAME_HEIGHT) {
line.y -= 7 * 400;
}
}
// Yol ayrımı (fork) oluşturma ve yönetimi
forkTimer++;
if (!forkActive && forkTimer > forkInterval) {
showFork();
forkTimer = 0;
}
// Eğer yol ayrımı aktifse, oyuncu seçim yapmalı
if (forkActive) {
// Araba çatal bölgesine geldi mi?
if (!forkChoice && car.y < forkY + 100 && car.y > forkY - 100) {
// Oyuncu sola veya sağa kayarsa seçim yap
if (car.x < GAME_WIDTH / 2) {
forkChoice = 'left';
} else if (car.x > GAME_WIDTH / 2) {
forkChoice = 'right';
}
if (forkChoice) {
// Arabayı seçilen yola kaydır
var targetX = forkChoice === 'left' ? forkXLeft : forkXRight;
tween(car, {
x: targetX
}, 300, {
easing: 'easeInOutQuad'
});
// Yol çizgilerini de kaydır
for (var i = 0; i < roadLines.length; i++) {
tween(roadLines[i], {
x: targetX
}, 300, {
easing: 'easeInOutQuad'
});
}
// 0.5 saniye sonra fork görsellerini kaldır
LK.setTimeout(clearFork, 500);
}
}
}
// Engelleri hareket ettir
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.speed = gameSpeed;
obs.update();
// Ekrandan çıktıysa sil
if (obs.y - obs.height / 2 > GAME_HEIGHT + 100) {
obs.destroy();
obstacles.splice(i, 1);
score++;
scoreTxt.setText(score);
continue;
}
// Çarpışma kontrolü
if (car.intersects(obs)) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
// Paraları hareket ettir
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
coin.speed = gameSpeed;
coin.update();
// Ekrandan çıktıysa sil
if (coin.y - coin.height / 2 > GAME_HEIGHT + 100) {
coin.destroy();
coins.splice(i, 1);
continue;
}
// Araba ile çarpışma (para toplama)
if (car.intersects(coin)) {
money += 10;
moneyTxt.setText('₺' + money);
coin.destroy();
coins.splice(i, 1);
continue;
}
}
// Engel oluşturma (aralıkla)
if (ticksSinceStart % spawnInterval === 0) {
var obs = new Obstacle();
// Rastgele x konumu, yolun dışına çıkmasın
var minX = ROAD_X + obs.width / 2 + 30;
var maxX = ROAD_X + ROAD_WIDTH - obs.width / 2 - 30;
obs.x = minX + Math.random() * (maxX - minX);
obs.y = -obs.height / 2;
obstacles.push(obs);
game.addChild(obs);
// %50 ihtimalle para da oluştur
if (Math.random() < 0.5) {
var coin = new Coin();
var minCoinX = ROAD_X + coin.width / 2 + 30;
var maxCoinX = ROAD_X + ROAD_WIDTH - coin.width / 2 - 30;
var tryCount = 0;
var maxTries = 8;
var validCoinPos = false;
while (!validCoinPos && tryCount < maxTries) {
coin.x = minCoinX + Math.random() * (maxCoinX - minCoinX);
coin.y = -coin.height / 2 - 120;
validCoinPos = true;
// Check if coin would overlap with any obstacle at spawn
for (var oi = 0; oi < obstacles.length; oi++) {
var obs = obstacles[oi];
// Only check obstacles that are close to spawn Y
if (Math.abs(obs.y - coin.y) < (obs.height + coin.height) / 2 + 40) {
// Check X overlap
if (Math.abs(obs.x - coin.x) < (obs.width + coin.width) / 2 + 10) {
validCoinPos = false;
break;
}
}
}
tryCount++;
}
if (validCoinPos) {
coins.push(coin);
game.addChild(coin);
} else {
coin.destroy();
}
}
}
// Zorluk arttırma: zamanla hız ve engel sıklığı artar
if (ticksSinceStart % 300 === 0 && gameSpeed < 38) {
gameSpeed += 2;
if (spawnInterval > 28) spawnInterval -= 4;
}
// Vites ve pedal kontrolleri
// Fren butonu basılıysa araba tamamen dursun
if (brakePressed) {
// Arabayı tamamen durdur
// Hiçbir hareket yok, gaz/fren/vites etkisiz
// (car.y değişmez)
// Ayrıca gaz/fren/vites etkisizleştirildiği için başka bir şey yapılmaz
} else if (currentGear === 'D') {
if (gazPressed) {
car.y -= 10;
if (car.y < GAME_HEIGHT / 2) car.y = GAME_HEIGHT / 2;
} else if (frenPressed) {
car.y += 8;
if (car.y > GAME_HEIGHT - 500) car.y = GAME_HEIGHT - 500;
}
} else if (currentGear === 'R') {
if (gazPressed) {
car.y += 10;
if (car.y > GAME_HEIGHT - 500) car.y = GAME_HEIGHT - 500;
} else if (frenPressed) {
car.y -= 8;
if (car.y < GAME_HEIGHT / 2) car.y = GAME_HEIGHT / 2;
}
}
// Skor güncellemesi (her frame değil, engel geçince artıyor)
};
// Sürükleme işlemleri ve UI butonları
game.down = function (x, y, obj) {
// Vites butonuna tıklandı mı?
var gearBtnBounds = LK.gui.right.toLocal(gearBtn.toGlobal({
x: 0,
y: 0
}));
if (x > GAME_WIDTH - 300 && y > 100 && y < 300) {
// Vites değiştir
if (currentGear === 'D') {
currentGear = 'R';
gearBtn.setGear('R');
} else {
currentGear = 'D';
gearBtn.setGear('D');
}
return;
}
// Gaz pedalı
if (x > GAME_WIDTH - 300 && y > 400 && y < 600) {
gazPressed = true;
return;
}
// Fren pedalı
if (x > GAME_WIDTH - 300 && y > 600 && y < 800) {
frenPressed = true;
return;
}
// Fren butonu (sağ altta)
if (x > brakeBtnArea.x && x < brakeBtnArea.x + brakeBtnArea.width && y > brakeBtnArea.y && y < brakeBtnArea.y + brakeBtnArea.height) {
brakePressed = true;
return;
}
// Dükkan açma butonu (duraklatma butonunun altında)
// GUI overlay koordinatlarını oyun koordinatına çevir
var shopBtnGlobal = LK.gui.topRight.toGlobal({
x: shopBtn.x,
y: shopBtn.y
});
if (x > shopBtnGlobal.x - shopBtn.width / 2 && x < shopBtnGlobal.x + shopBtn.width / 2 && y > shopBtnGlobal.y - shopBtn.height / 2 && y < shopBtnGlobal.y + shopBtn.height / 2) {
LK.effects.flashScreen(0x00e676, 400);
if (typeof LK.showShopMenu === "function") LK.showShopMenu();
return;
}
// Duraklatma butonu (sağ üstte)
if (x > pauseBtnArea.x && x < pauseBtnArea.x + pauseBtnArea.width && y > pauseBtnArea.y && y < pauseBtnArea.y + pauseBtnArea.height) {
LK.showPauseMenu();
return;
}
// Direksiyon simidi (sol alt)
if (x < 400 && y > GAME_HEIGHT - 600) {
// Direksiyon simidiyle sürükleme başlat
if (steering && steering.down) steering.down(x, y, obj);
// Arabayı da sürüklemeye başlat
dragNode = car;
lastGameX = x;
return;
}
// Arabaya dokunulmuşsa veya ekrana dokunulmuşsa sürüklemeye başla
if (x > car.x - car.width / 2 && x < car.x + car.width / 2 && y > car.y - car.height / 2 && y < car.y + car.height / 2) {
dragNode = car;
lastGameX = x;
} else if (y > GAME_HEIGHT / 2 // Sadece alt yarıda sürüklemeye izin ver
) {
dragNode = car;
lastGameX = x;
}
};
game.move = function (x, y, obj) {
if (dragNode === car) {
// Eğer direksiyon simidi aktifse, onun move fonksiyonunu çağır
if (steering && steering.isDown && steering.move) {
steering.move(x, y, obj);
}
// Sürükleme ile araba hareketi devre dışı (direksiyon ile kontrol edilecek)
// car.x değişimi steering.onSteer ile yapılacak
}
};
game.up = function (x, y, obj) {
dragNode = null;
gazPressed = false;
frenPressed = false;
brakePressed = false;
if (steering && steering.isDown && steering.up) {
steering.up(0, 0, null);
}
};
// Oyun başında skor ve para sıfırla
score = 0;
scoreTxt.setText(score);
money = 0;
moneyTxt.setText('₺' + money);
currentGear = 'D';
gearBtn.setGear('D');
gazPressed = false;
frenPressed = false;