/****
* 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;
};