/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Car = Container.expand(function () { var self = Container.call(this); var carGraphics = self.attachAsset('car', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.driftSpeed = 0; self.maxDriftSpeed = 7; self.driftDecay = 0.9; self.isDrifting = false; self.angle = 0; self.startDrift = function (direction) { self.isDrifting = true; self.driftSpeed = direction * self.maxDriftSpeed; LK.getSound('drift').play(); }; self.update = function () { // Apply drift movement self.x += self.driftSpeed; // Decay drift speed - slower decay after distance 1000 makes car harder to control var currentDriftDecay = distanceTraveled >= 1000 ? 0.95 : self.driftDecay; self.driftSpeed *= currentDriftDecay; // Update visual angle based on drift self.angle = self.driftSpeed * 0.1; carGraphics.rotation = self.angle; // Stop drifting when speed is low if (Math.abs(self.driftSpeed) < 0.5) { self.isDrifting = false; self.driftSpeed = 0; } }; return self; }); var RoadSegment = Container.expand(function () { var self = Container.call(this); // Road center piece var roadGraphics = self.attachAsset('road', { anchorX: 0.5, anchorY: 0.5 }); // Left cliff var leftCliff = self.attachAsset('cliff', { anchorX: 1, anchorY: 0.5 }); leftCliff.x = -200; // Right cliff var rightCliff = self.attachAsset('cliff', { anchorX: 0, anchorY: 0.5 }); rightCliff.x = 200; self.turnDirection = 0; // -1 for left, 1 for right, 0 for straight self.speed = 8; self.setTurn = function (direction) { self.turnDirection = direction; if (direction !== 0) { roadGraphics.tint = direction < 0 ? 0x4444ff : 0xff4444; } }; self.update = function () { self.y += self.speed; }; return self; }); var Tree = Container.expand(function () { var self = Container.call(this); // Tree trunk var trunk = self.attachAsset('treeTrunk', { anchorX: 0.5, anchorY: 1 }); trunk.y = 0; // Tree foliage var foliage = self.attachAsset('tree', { anchorX: 0.5, anchorY: 1 }); foliage.y = -20; self.speed = 8; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var gameStarted = false; var languageSelected = false; var selectedLanguage = null; var showingInstructions = false; var car; var roadSegments = []; var trees = []; var gameSpeed = 12; var maxGameSpeed = 20; var distanceTraveled = 0; var lastSegmentY = 0; var segmentSpacing = 120; var curveIntensity = 80; var nextTurnType = 0; var turnSequence = [1, -1, 1, 1, -1, -1, 1, 0, -1, 1, -1, 1, 1, -1, -1, 1, 0, -1, 1, -1, 1, 1, -1, 0, 1, -1, -1, 1, 1, -1]; var turnIndex = 0; var treeSpacing = 200; var lastTreeY = 0; // Create score display var scoreTxt = new Text2('Distance: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Language selection UI var languageTitle = new Text2('Select Language / Dil Seçin', { size: 120, fill: 0xFFFFFF }); languageTitle.anchor.set(0.5, 0.5); languageTitle.x = 1024; languageTitle.y = 800; game.addChild(languageTitle); var englishButton = new Text2('English', { size: 100, fill: 0x00ff00 }); englishButton.anchor.set(0.5, 0.5); englishButton.x = 1024; englishButton.y = 1200; game.addChild(englishButton); var turkishButton = new Text2('Türkçe', { size: 100, fill: 0x00ff00 }); turkishButton.anchor.set(0.5, 0.5); turkishButton.x = 1024; turkishButton.y = 1400; game.addChild(turkishButton); var instructionText = new Text2('', { size: 80, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 0.5); instructionText.x = 1024; instructionText.y = 1366; // Initialize car car = game.addChild(new Car()); car.x = 1024; // Center horizontally car.y = 2200; // Near bottom of screen // Create initial road segments with curved positioning function createRoadSegment(y, turnDirection, xOffset) { var segment = new RoadSegment(); segment.x = 1024 + (xOffset || 0); // Center horizontally with offset for curves segment.y = y; segment.setTurn(turnDirection); segment.xOffset = xOffset || 0; return segment; } // Initialize road with curved positioning var currentXOffset = 0; for (var i = 0; i < 20; i++) { var turnDir = turnSequence[turnIndex % turnSequence.length]; // Calculate curve based on turn direction if (turnDir !== 0) { currentXOffset += turnDir * curveIntensity; // Create aggressive curve } var segment = createRoadSegment(lastSegmentY - i * segmentSpacing, turnDir, currentXOffset); roadSegments.push(segment); game.addChild(segment); turnIndex++; } // Initialize trees on both sides for (var i = 0; i < 15; i++) { // Left side trees var leftTree = new Tree(); leftTree.x = 150; // Far left edge leftTree.y = lastTreeY - i * treeSpacing; leftTree.speed = gameSpeed; trees.push(leftTree); game.addChild(leftTree); // Right side trees var rightTree = new Tree(); rightTree.x = 1898; // Far right edge rightTree.y = lastTreeY - i * treeSpacing; rightTree.speed = gameSpeed; trees.push(rightTree); game.addChild(rightTree); } // Input handling game.down = function (x, y, obj) { if (!languageSelected) { // Check if English button was tapped if (x > 524 && x < 1524 && y > 1150 && y < 1250) { selectedLanguage = 'en'; languageSelected = true; showingInstructions = true; // Hide language selection UI languageTitle.visible = false; englishButton.visible = false; turkishButton.visible = false; // Show English instructions instructionText.setText('Stay on the brown road\nDo not touch the white cliffs!'); game.addChild(instructionText); } // Check if Turkish button was tapped else if (x > 524 && x < 1524 && y > 1350 && y < 1450) { selectedLanguage = 'tr'; languageSelected = true; showingInstructions = true; // Hide language selection UI languageTitle.visible = false; englishButton.visible = false; turkishButton.visible = false; // Show Turkish instructions instructionText.setText('Kahverengi yolda gidin\nSakın beyazlara değmeyin!'); game.addChild(instructionText); } } else if (showingInstructions) { // Any tap while showing instructions starts the game showingInstructions = false; gameStarted = true; instructionText.visible = false; } else if (gameStarted) { if (x < 1024) { // Left side tap - drift left car.startDrift(-1); } else { // Right side tap - drift right car.startDrift(1); } } }; // Main game loop game.update = function () { if (!gameStarted) { return; } // Update distance and score distanceTraveled += gameSpeed * 0.1; scoreTxt.setText('Distance: ' + Math.floor(distanceTraveled)); LK.setScore(Math.floor(distanceTraveled)); // Gradually increase speed more gently, but faster after distance 1000 var speedIncreaseRate = distanceTraveled >= 1000 ? 0.6 : 0.3; var speedIncreaseInterval = distanceTraveled >= 1000 ? 180 : 300; if (LK.ticks % speedIncreaseInterval === 0 && gameSpeed < maxGameSpeed) { gameSpeed += speedIncreaseRate; for (var i = 0; i < roadSegments.length; i++) { roadSegments[i].speed = gameSpeed; } // Update tree speeds too for (var i = 0; i < trees.length; i++) { trees[i].speed = gameSpeed; } } // Manage trees - remove off-screen trees for (var i = trees.length - 1; i >= 0; i--) { var tree = trees[i]; if (tree.y > 2800) { tree.destroy(); trees.splice(i, 1); } } // Add new trees at the top var topTree = trees.length > 0 ? trees[0] : null; if (!topTree || topTree.y > -treeSpacing) { var newY = topTree ? topTree.y - treeSpacing : -treeSpacing; // Left side tree var leftTree = new Tree(); leftTree.x = 150; leftTree.y = newY; leftTree.speed = gameSpeed; trees.unshift(leftTree); game.addChild(leftTree); // Right side tree var rightTree = new Tree(); rightTree.x = 1898; rightTree.y = newY; rightTree.speed = gameSpeed; trees.unshift(rightTree); game.addChild(rightTree); } // Move road segments and create new ones for (var i = roadSegments.length - 1; i >= 0; i--) { var segment = roadSegments[i]; // Remove segments that are off screen if (segment.y > 2800) { segment.destroy(); roadSegments.splice(i, 1); continue; } // Check collision with cliff edges only (not road edges) if (Math.abs(segment.y - car.y) < 50) { // Check collision with left cliff (car width is 120, so check car edges) var leftCliffRight = segment.x - 200; // Left cliff right edge var carLeftEdge = car.x - 60; // Car's left edge // Check collision with right cliff var rightCliffLeft = segment.x + 200; // Right cliff left edge var carRightEdge = car.x + 60; // Car's right edge // Only die if car edges actually touch cliff edges if (carRightEdge < leftCliffRight || carLeftEdge > rightCliffLeft) { // Car hit the cliff LK.getSound('crash').play(); LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } } } // Add new road segments at the top with curved positioning var topSegment = roadSegments[0]; if (topSegment && topSegment.y > -segmentSpacing) { var newY = topSegment.y - segmentSpacing; var turnDir = turnSequence[turnIndex % turnSequence.length]; var newXOffset = topSegment.xOffset || 0; var currentCurveIntensity = distanceTraveled >= 1000 ? curveIntensity * 1.5 : curveIntensity; if (turnDir !== 0) { newXOffset += turnDir * currentCurveIntensity; // Continue the aggressive curve } var newSegment = createRoadSegment(newY, turnDir, newXOffset); roadSegments.unshift(newSegment); game.addChild(newSegment); turnIndex++; } // Find current road segment for visual feedback (no automatic turning) var currentSegment = null; for (var i = 0; i < roadSegments.length; i++) { if (Math.abs(roadSegments[i].y - car.y) < 75) { currentSegment = roadSegments[i]; break; } } // Player must manually drift to follow the curved road // No automatic turning - relies purely on player skill // Allow car to move freely but keep within screen bounds if (car.x < 100) car.x = 100; if (car.x > 1948) car.x = 1948; };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Car = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.driftSpeed = 0;
self.maxDriftSpeed = 7;
self.driftDecay = 0.9;
self.isDrifting = false;
self.angle = 0;
self.startDrift = function (direction) {
self.isDrifting = true;
self.driftSpeed = direction * self.maxDriftSpeed;
LK.getSound('drift').play();
};
self.update = function () {
// Apply drift movement
self.x += self.driftSpeed;
// Decay drift speed - slower decay after distance 1000 makes car harder to control
var currentDriftDecay = distanceTraveled >= 1000 ? 0.95 : self.driftDecay;
self.driftSpeed *= currentDriftDecay;
// Update visual angle based on drift
self.angle = self.driftSpeed * 0.1;
carGraphics.rotation = self.angle;
// Stop drifting when speed is low
if (Math.abs(self.driftSpeed) < 0.5) {
self.isDrifting = false;
self.driftSpeed = 0;
}
};
return self;
});
var RoadSegment = Container.expand(function () {
var self = Container.call(this);
// Road center piece
var roadGraphics = self.attachAsset('road', {
anchorX: 0.5,
anchorY: 0.5
});
// Left cliff
var leftCliff = self.attachAsset('cliff', {
anchorX: 1,
anchorY: 0.5
});
leftCliff.x = -200;
// Right cliff
var rightCliff = self.attachAsset('cliff', {
anchorX: 0,
anchorY: 0.5
});
rightCliff.x = 200;
self.turnDirection = 0; // -1 for left, 1 for right, 0 for straight
self.speed = 8;
self.setTurn = function (direction) {
self.turnDirection = direction;
if (direction !== 0) {
roadGraphics.tint = direction < 0 ? 0x4444ff : 0xff4444;
}
};
self.update = function () {
self.y += self.speed;
};
return self;
});
var Tree = Container.expand(function () {
var self = Container.call(this);
// Tree trunk
var trunk = self.attachAsset('treeTrunk', {
anchorX: 0.5,
anchorY: 1
});
trunk.y = 0;
// Tree foliage
var foliage = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 1
});
foliage.y = -20;
self.speed = 8;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var gameStarted = false;
var languageSelected = false;
var selectedLanguage = null;
var showingInstructions = false;
var car;
var roadSegments = [];
var trees = [];
var gameSpeed = 12;
var maxGameSpeed = 20;
var distanceTraveled = 0;
var lastSegmentY = 0;
var segmentSpacing = 120;
var curveIntensity = 80;
var nextTurnType = 0;
var turnSequence = [1, -1, 1, 1, -1, -1, 1, 0, -1, 1, -1, 1, 1, -1, -1, 1, 0, -1, 1, -1, 1, 1, -1, 0, 1, -1, -1, 1, 1, -1];
var turnIndex = 0;
var treeSpacing = 200;
var lastTreeY = 0;
// Create score display
var scoreTxt = new Text2('Distance: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Language selection UI
var languageTitle = new Text2('Select Language / Dil Seçin', {
size: 120,
fill: 0xFFFFFF
});
languageTitle.anchor.set(0.5, 0.5);
languageTitle.x = 1024;
languageTitle.y = 800;
game.addChild(languageTitle);
var englishButton = new Text2('English', {
size: 100,
fill: 0x00ff00
});
englishButton.anchor.set(0.5, 0.5);
englishButton.x = 1024;
englishButton.y = 1200;
game.addChild(englishButton);
var turkishButton = new Text2('Türkçe', {
size: 100,
fill: 0x00ff00
});
turkishButton.anchor.set(0.5, 0.5);
turkishButton.x = 1024;
turkishButton.y = 1400;
game.addChild(turkishButton);
var instructionText = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 1366;
// Initialize car
car = game.addChild(new Car());
car.x = 1024; // Center horizontally
car.y = 2200; // Near bottom of screen
// Create initial road segments with curved positioning
function createRoadSegment(y, turnDirection, xOffset) {
var segment = new RoadSegment();
segment.x = 1024 + (xOffset || 0); // Center horizontally with offset for curves
segment.y = y;
segment.setTurn(turnDirection);
segment.xOffset = xOffset || 0;
return segment;
}
// Initialize road with curved positioning
var currentXOffset = 0;
for (var i = 0; i < 20; i++) {
var turnDir = turnSequence[turnIndex % turnSequence.length];
// Calculate curve based on turn direction
if (turnDir !== 0) {
currentXOffset += turnDir * curveIntensity; // Create aggressive curve
}
var segment = createRoadSegment(lastSegmentY - i * segmentSpacing, turnDir, currentXOffset);
roadSegments.push(segment);
game.addChild(segment);
turnIndex++;
}
// Initialize trees on both sides
for (var i = 0; i < 15; i++) {
// Left side trees
var leftTree = new Tree();
leftTree.x = 150; // Far left edge
leftTree.y = lastTreeY - i * treeSpacing;
leftTree.speed = gameSpeed;
trees.push(leftTree);
game.addChild(leftTree);
// Right side trees
var rightTree = new Tree();
rightTree.x = 1898; // Far right edge
rightTree.y = lastTreeY - i * treeSpacing;
rightTree.speed = gameSpeed;
trees.push(rightTree);
game.addChild(rightTree);
}
// Input handling
game.down = function (x, y, obj) {
if (!languageSelected) {
// Check if English button was tapped
if (x > 524 && x < 1524 && y > 1150 && y < 1250) {
selectedLanguage = 'en';
languageSelected = true;
showingInstructions = true;
// Hide language selection UI
languageTitle.visible = false;
englishButton.visible = false;
turkishButton.visible = false;
// Show English instructions
instructionText.setText('Stay on the brown road\nDo not touch the white cliffs!');
game.addChild(instructionText);
}
// Check if Turkish button was tapped
else if (x > 524 && x < 1524 && y > 1350 && y < 1450) {
selectedLanguage = 'tr';
languageSelected = true;
showingInstructions = true;
// Hide language selection UI
languageTitle.visible = false;
englishButton.visible = false;
turkishButton.visible = false;
// Show Turkish instructions
instructionText.setText('Kahverengi yolda gidin\nSakın beyazlara değmeyin!');
game.addChild(instructionText);
}
} else if (showingInstructions) {
// Any tap while showing instructions starts the game
showingInstructions = false;
gameStarted = true;
instructionText.visible = false;
} else if (gameStarted) {
if (x < 1024) {
// Left side tap - drift left
car.startDrift(-1);
} else {
// Right side tap - drift right
car.startDrift(1);
}
}
};
// Main game loop
game.update = function () {
if (!gameStarted) {
return;
}
// Update distance and score
distanceTraveled += gameSpeed * 0.1;
scoreTxt.setText('Distance: ' + Math.floor(distanceTraveled));
LK.setScore(Math.floor(distanceTraveled));
// Gradually increase speed more gently, but faster after distance 1000
var speedIncreaseRate = distanceTraveled >= 1000 ? 0.6 : 0.3;
var speedIncreaseInterval = distanceTraveled >= 1000 ? 180 : 300;
if (LK.ticks % speedIncreaseInterval === 0 && gameSpeed < maxGameSpeed) {
gameSpeed += speedIncreaseRate;
for (var i = 0; i < roadSegments.length; i++) {
roadSegments[i].speed = gameSpeed;
}
// Update tree speeds too
for (var i = 0; i < trees.length; i++) {
trees[i].speed = gameSpeed;
}
}
// Manage trees - remove off-screen trees
for (var i = trees.length - 1; i >= 0; i--) {
var tree = trees[i];
if (tree.y > 2800) {
tree.destroy();
trees.splice(i, 1);
}
}
// Add new trees at the top
var topTree = trees.length > 0 ? trees[0] : null;
if (!topTree || topTree.y > -treeSpacing) {
var newY = topTree ? topTree.y - treeSpacing : -treeSpacing;
// Left side tree
var leftTree = new Tree();
leftTree.x = 150;
leftTree.y = newY;
leftTree.speed = gameSpeed;
trees.unshift(leftTree);
game.addChild(leftTree);
// Right side tree
var rightTree = new Tree();
rightTree.x = 1898;
rightTree.y = newY;
rightTree.speed = gameSpeed;
trees.unshift(rightTree);
game.addChild(rightTree);
}
// Move road segments and create new ones
for (var i = roadSegments.length - 1; i >= 0; i--) {
var segment = roadSegments[i];
// Remove segments that are off screen
if (segment.y > 2800) {
segment.destroy();
roadSegments.splice(i, 1);
continue;
}
// Check collision with cliff edges only (not road edges)
if (Math.abs(segment.y - car.y) < 50) {
// Check collision with left cliff (car width is 120, so check car edges)
var leftCliffRight = segment.x - 200; // Left cliff right edge
var carLeftEdge = car.x - 60; // Car's left edge
// Check collision with right cliff
var rightCliffLeft = segment.x + 200; // Right cliff left edge
var carRightEdge = car.x + 60; // Car's right edge
// Only die if car edges actually touch cliff edges
if (carRightEdge < leftCliffRight || carLeftEdge > rightCliffLeft) {
// Car hit the cliff
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
}
// Add new road segments at the top with curved positioning
var topSegment = roadSegments[0];
if (topSegment && topSegment.y > -segmentSpacing) {
var newY = topSegment.y - segmentSpacing;
var turnDir = turnSequence[turnIndex % turnSequence.length];
var newXOffset = topSegment.xOffset || 0;
var currentCurveIntensity = distanceTraveled >= 1000 ? curveIntensity * 1.5 : curveIntensity;
if (turnDir !== 0) {
newXOffset += turnDir * currentCurveIntensity; // Continue the aggressive curve
}
var newSegment = createRoadSegment(newY, turnDir, newXOffset);
roadSegments.unshift(newSegment);
game.addChild(newSegment);
turnIndex++;
}
// Find current road segment for visual feedback (no automatic turning)
var currentSegment = null;
for (var i = 0; i < roadSegments.length; i++) {
if (Math.abs(roadSegments[i].y - car.y) < 75) {
currentSegment = roadSegments[i];
break;
}
}
// Player must manually drift to follow the curved road
// No automatic turning - relies purely on player skill
// Allow car to move freely but keep within screen bounds
if (car.x < 100) car.x = 100;
if (car.x > 1948) car.x = 1948;
};