/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bike = Container.expand(function () { var self = Container.call(this); var bikeBody = self.attachAsset('bike', { anchorX: 0.5, anchorY: 0.5 }); var frontWheel = self.attachAsset('wheel', { anchorX: 0.5, anchorY: 0.5, x: 25, y: 15 }); var backWheel = self.attachAsset('wheel', { anchorX: 0.5, anchorY: 0.5, x: -25, y: 15 }); self.velocityY = 0; self.gravity = 0.8; self.jumpPower = -18; self.isGrounded = false; self.groundY = 0; self.jump = function (chargeMultiplier) { if (self.isGrounded) { var jumpStrength = self.jumpPower * (1 + chargeMultiplier); self.velocityY = jumpStrength; self.isGrounded = false; LK.getSound('jump').play(); } }; self.update = function () { // Apply gravity self.velocityY += self.gravity; self.y += self.velocityY; // Ground collision if (self.y >= self.groundY) { self.y = self.groundY; self.velocityY = 0; self.isGrounded = true; } // Animate wheels frontWheel.rotation += 0.3; backWheel.rotation += 0.3; // Bike tilt based on velocity bikeBody.rotation = self.velocityY * 0.02; }; return self; }); var GroundSegment = Container.expand(function () { var self = Container.call(this); var groundGraphics = self.attachAsset('ground', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -18; self.update = function () { self.x += self.speed; }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 1 }); self.speed = -18; self.update = function () { self.x += self.speed; }; return self; }); var Ramp = Container.expand(function () { var self = Container.call(this); var rampGraphics = self.attachAsset('ramp', { anchorX: 0.5, anchorY: 1 }); self.speed = -18; self.update = function () { self.x += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var bike; var obstacles = []; var ramps = []; var groundSegments = []; var gameSpeed = 18; var distanceScore = 0; var isGameRunning = true; var groundLevel = 2400; var lastObstacleSpawn = 0; var spawnDistance = 300; var currentLevel = 1; var levelDistance = 500; // Distance between level changes var levelConfigs = [ // Level 1: Easy - Single obstacles { obstacleChance: 0.6, rampChance: 0.4, minSpacing: 250, maxSpacing: 400, patterns: ['single'] }, // Level 2: Medium - Paired obstacles { obstacleChance: 0.7, rampChance: 0.3, minSpacing: 200, maxSpacing: 350, patterns: ['single', 'double'] }, // Level 3: Hard - Triple obstacles and gaps { obstacleChance: 0.75, rampChance: 0.25, minSpacing: 180, maxSpacing: 300, patterns: ['single', 'double', 'triple'] }, // Level 4: Expert - Mixed patterns with tight spacing { obstacleChance: 0.8, rampChance: 0.2, minSpacing: 150, maxSpacing: 250, patterns: ['single', 'double', 'triple', 'staggered'] }, // Level 5: Master - All patterns with minimal spacing { obstacleChance: 0.85, rampChance: 0.15, minSpacing: 120, maxSpacing: 200, patterns: ['single', 'double', 'triple', 'staggered', 'wall'] }]; var isCharging = false; var chargeStartTime = 0; var currentCharge = 0; var maxCharge = 100; var chargeRate = 2; // Create score display var scoreTxt = new Text2('Distance: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create jump meter background var meterBg = LK.getAsset('obstacle', { anchorX: 0, anchorY: 0, scaleX: 4, scaleY: 0.5, tint: 0x333333 }); meterBg.x = 100; meterBg.y = 150; LK.gui.topLeft.addChild(meterBg); // Create jump meter fill var meterFill = LK.getAsset('obstacle', { anchorX: 0, anchorY: 0, scaleX: 0, scaleY: 0.5, tint: 0x00ff00 }); meterFill.x = 100; meterFill.y = 150; LK.gui.topLeft.addChild(meterFill); // Create jump meter label var meterLabel = new Text2('JUMP POWER', { size: 40, fill: 0xFFFFFF }); meterLabel.anchor.set(0, 0); meterLabel.x = 100; meterLabel.y = 100; LK.gui.topLeft.addChild(meterLabel); // Create level indicator var levelTxt = new Text2('LEVEL 1', { size: 60, fill: 0xFFFF00 }); levelTxt.anchor.set(1, 0); LK.gui.topRight.addChild(levelTxt); // Add sky background var skyBackground = game.addChild(LK.getAsset('sky', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 1366 / 2 })); // Create bike bike = game.addChild(new Bike()); bike.x = 400; bike.y = groundLevel; bike.groundY = groundLevel; // Initialize ground segments function createGroundSegments() { for (var i = 0; i < 15; i++) { var segment = new GroundSegment(); segment.x = i * 200; segment.y = groundLevel + 40; groundSegments.push(segment); game.addChild(segment); } } createGroundSegments(); // Spawn obstacle patterns based on current level function spawnObstaclePattern(pattern) { switch (pattern) { case 'single': spawnSingleObstacle(); break; case 'double': spawnDoubleObstacles(); break; case 'triple': spawnTripleObstacles(); break; case 'staggered': spawnStaggeredObstacles(); break; case 'wall': spawnWallObstacles(); break; default: spawnSingleObstacle(); } } // Single obstacle function spawnSingleObstacle() { var obstacle = new Obstacle(); obstacle.x = 2200; obstacle.y = groundLevel; obstacle.speed = -gameSpeed; obstacles.push(obstacle); game.addChild(obstacle); } // Double obstacles - side by side gap function spawnDoubleObstacles() { var obstacle1 = new Obstacle(); obstacle1.x = 2200; obstacle1.y = groundLevel; obstacle1.speed = -gameSpeed; obstacles.push(obstacle1); game.addChild(obstacle1); var obstacle2 = new Obstacle(); obstacle2.x = 2280; obstacle2.y = groundLevel; obstacle2.speed = -gameSpeed; obstacles.push(obstacle2); game.addChild(obstacle2); } // Triple obstacles - requires precise jumping function spawnTripleObstacles() { for (var i = 0; i < 3; i++) { var obstacle = new Obstacle(); obstacle.x = 2200 + i * 70; obstacle.y = groundLevel; obstacle.speed = -gameSpeed; obstacles.push(obstacle); game.addChild(obstacle); } } // Staggered obstacles - different heights function spawnStaggeredObstacles() { var obstacle1 = new Obstacle(); obstacle1.x = 2200; obstacle1.y = groundLevel; obstacle1.speed = -gameSpeed; obstacles.push(obstacle1); game.addChild(obstacle1); var obstacle2 = new Obstacle(); obstacle2.x = 2300; obstacle2.y = groundLevel - 60; obstacle2.speed = -gameSpeed; obstacles.push(obstacle2); game.addChild(obstacle2); } // Wall pattern - high obstacle requiring max jump function spawnWallObstacles() { var obstacle1 = new Obstacle(); obstacle1.x = 2200; obstacle1.y = groundLevel; obstacle1.speed = -gameSpeed; obstacles.push(obstacle1); game.addChild(obstacle1); var obstacle2 = new Obstacle(); obstacle2.x = 2200; obstacle2.y = groundLevel - 60; obstacle2.speed = -gameSpeed; obstacles.push(obstacle2); game.addChild(obstacle2); } // Legacy single obstacle function for compatibility function spawnObstacle() { spawnSingleObstacle(); } // Spawn ramp function spawnRamp() { var ramp = new Ramp(); ramp.x = 2200; ramp.y = groundLevel; ramp.speed = -gameSpeed; ramps.push(ramp); game.addChild(ramp); } // Game input - start charging game.down = function (x, y, obj) { if (isGameRunning && bike.isGrounded) { isCharging = true; chargeStartTime = LK.ticks; currentCharge = 0; } }; // Game input - release jump game.up = function (x, y, obj) { if (isGameRunning && isCharging) { var chargeMultiplier = currentCharge / maxCharge; bike.jump(chargeMultiplier); isCharging = false; currentCharge = 0; } }; // Main game loop game.update = function () { if (!isGameRunning) return; // Update jump charge system if (isCharging && bike.isGrounded) { currentCharge += chargeRate; if (currentCharge > maxCharge) { currentCharge = maxCharge; } } else if (!bike.isGrounded) { isCharging = false; currentCharge = 0; } // Update jump meter UI var fillPercent = currentCharge / maxCharge; meterFill.scaleX = 4 * fillPercent; // Change color based on charge level if (fillPercent < 0.3) { meterFill.tint = 0xff0000; // Red } else if (fillPercent < 0.7) { meterFill.tint = 0xffff00; // Yellow } else { meterFill.tint = 0x00ff00; // Green } // Update distance score distanceScore += 1; LK.setScore(Math.floor(distanceScore / 10)); scoreTxt.setText('Distance: ' + Math.floor(distanceScore / 10)); // Update level indicator levelTxt.setText('LEVEL ' + currentLevel); // Increase game speed gradually if (LK.ticks % 300 === 0) { gameSpeed += 1.2; } // Update ground segments for (var i = groundSegments.length - 1; i >= 0; i--) { var segment = groundSegments[i]; segment.speed = -gameSpeed; if (segment.x < -200) { segment.x = (groundSegments.length - 1) * 200; } } // Update current level based on distance var newLevel = Math.min(5, Math.floor(distanceScore / levelDistance) + 1); if (newLevel !== currentLevel) { currentLevel = newLevel; } // Get current level configuration var config = levelConfigs[currentLevel - 1]; // Spawn obstacles and ramps based on current level if (distanceScore - lastObstacleSpawn > spawnDistance) { var randomValue = Math.random(); if (randomValue < config.obstacleChance) { // Choose random pattern from current level patterns var patterns = config.patterns; var randomPattern = patterns[Math.floor(Math.random() * patterns.length)]; spawnObstaclePattern(randomPattern); } else { spawnRamp(); } lastObstacleSpawn = distanceScore; spawnDistance = config.minSpacing + Math.random() * (config.maxSpacing - config.minSpacing); } // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; obstacle.speed = -gameSpeed; // Remove off-screen obstacles if (obstacle.x < -100) { obstacle.destroy(); obstacles.splice(i, 1); continue; } // Collision detection if (bike.intersects(obstacle)) { // Game over isGameRunning = false; LK.getSound('crash').play(); LK.showGameOver(); return; } } // Update ramps for (var i = ramps.length - 1; i >= 0; i--) { var ramp = ramps[i]; ramp.speed = -gameSpeed; // Remove off-screen ramps if (ramp.x < -100) { ramp.destroy(); ramps.splice(i, 1); continue; } // Ramp boost effect if (bike.intersects(ramp) && bike.isGrounded) { bike.velocityY = bike.jumpPower * 1.2; bike.isGrounded = false; } } // Check if bike fell off the track if (bike.y > groundLevel + 200) { isGameRunning = false; LK.getSound('crash').play(); LK.showGameOver(); } }; // Start background music LK.playMusic('1crossbikecountryracetheme');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bike = Container.expand(function () {
var self = Container.call(this);
var bikeBody = self.attachAsset('bike', {
anchorX: 0.5,
anchorY: 0.5
});
var frontWheel = self.attachAsset('wheel', {
anchorX: 0.5,
anchorY: 0.5,
x: 25,
y: 15
});
var backWheel = self.attachAsset('wheel', {
anchorX: 0.5,
anchorY: 0.5,
x: -25,
y: 15
});
self.velocityY = 0;
self.gravity = 0.8;
self.jumpPower = -18;
self.isGrounded = false;
self.groundY = 0;
self.jump = function (chargeMultiplier) {
if (self.isGrounded) {
var jumpStrength = self.jumpPower * (1 + chargeMultiplier);
self.velocityY = jumpStrength;
self.isGrounded = false;
LK.getSound('jump').play();
}
};
self.update = function () {
// Apply gravity
self.velocityY += self.gravity;
self.y += self.velocityY;
// Ground collision
if (self.y >= self.groundY) {
self.y = self.groundY;
self.velocityY = 0;
self.isGrounded = true;
}
// Animate wheels
frontWheel.rotation += 0.3;
backWheel.rotation += 0.3;
// Bike tilt based on velocity
bikeBody.rotation = self.velocityY * 0.02;
};
return self;
});
var GroundSegment = Container.expand(function () {
var self = Container.call(this);
var groundGraphics = self.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -18;
self.update = function () {
self.x += self.speed;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1
});
self.speed = -18;
self.update = function () {
self.x += self.speed;
};
return self;
});
var Ramp = Container.expand(function () {
var self = Container.call(this);
var rampGraphics = self.attachAsset('ramp', {
anchorX: 0.5,
anchorY: 1
});
self.speed = -18;
self.update = function () {
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var bike;
var obstacles = [];
var ramps = [];
var groundSegments = [];
var gameSpeed = 18;
var distanceScore = 0;
var isGameRunning = true;
var groundLevel = 2400;
var lastObstacleSpawn = 0;
var spawnDistance = 300;
var currentLevel = 1;
var levelDistance = 500; // Distance between level changes
var levelConfigs = [
// Level 1: Easy - Single obstacles
{
obstacleChance: 0.6,
rampChance: 0.4,
minSpacing: 250,
maxSpacing: 400,
patterns: ['single']
},
// Level 2: Medium - Paired obstacles
{
obstacleChance: 0.7,
rampChance: 0.3,
minSpacing: 200,
maxSpacing: 350,
patterns: ['single', 'double']
},
// Level 3: Hard - Triple obstacles and gaps
{
obstacleChance: 0.75,
rampChance: 0.25,
minSpacing: 180,
maxSpacing: 300,
patterns: ['single', 'double', 'triple']
},
// Level 4: Expert - Mixed patterns with tight spacing
{
obstacleChance: 0.8,
rampChance: 0.2,
minSpacing: 150,
maxSpacing: 250,
patterns: ['single', 'double', 'triple', 'staggered']
},
// Level 5: Master - All patterns with minimal spacing
{
obstacleChance: 0.85,
rampChance: 0.15,
minSpacing: 120,
maxSpacing: 200,
patterns: ['single', 'double', 'triple', 'staggered', 'wall']
}];
var isCharging = false;
var chargeStartTime = 0;
var currentCharge = 0;
var maxCharge = 100;
var chargeRate = 2;
// Create score display
var scoreTxt = new Text2('Distance: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create jump meter background
var meterBg = LK.getAsset('obstacle', {
anchorX: 0,
anchorY: 0,
scaleX: 4,
scaleY: 0.5,
tint: 0x333333
});
meterBg.x = 100;
meterBg.y = 150;
LK.gui.topLeft.addChild(meterBg);
// Create jump meter fill
var meterFill = LK.getAsset('obstacle', {
anchorX: 0,
anchorY: 0,
scaleX: 0,
scaleY: 0.5,
tint: 0x00ff00
});
meterFill.x = 100;
meterFill.y = 150;
LK.gui.topLeft.addChild(meterFill);
// Create jump meter label
var meterLabel = new Text2('JUMP POWER', {
size: 40,
fill: 0xFFFFFF
});
meterLabel.anchor.set(0, 0);
meterLabel.x = 100;
meterLabel.y = 100;
LK.gui.topLeft.addChild(meterLabel);
// Create level indicator
var levelTxt = new Text2('LEVEL 1', {
size: 60,
fill: 0xFFFF00
});
levelTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(levelTxt);
// Add sky background
var skyBackground = game.addChild(LK.getAsset('sky', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1366 / 2
}));
// Create bike
bike = game.addChild(new Bike());
bike.x = 400;
bike.y = groundLevel;
bike.groundY = groundLevel;
// Initialize ground segments
function createGroundSegments() {
for (var i = 0; i < 15; i++) {
var segment = new GroundSegment();
segment.x = i * 200;
segment.y = groundLevel + 40;
groundSegments.push(segment);
game.addChild(segment);
}
}
createGroundSegments();
// Spawn obstacle patterns based on current level
function spawnObstaclePattern(pattern) {
switch (pattern) {
case 'single':
spawnSingleObstacle();
break;
case 'double':
spawnDoubleObstacles();
break;
case 'triple':
spawnTripleObstacles();
break;
case 'staggered':
spawnStaggeredObstacles();
break;
case 'wall':
spawnWallObstacles();
break;
default:
spawnSingleObstacle();
}
}
// Single obstacle
function spawnSingleObstacle() {
var obstacle = new Obstacle();
obstacle.x = 2200;
obstacle.y = groundLevel;
obstacle.speed = -gameSpeed;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Double obstacles - side by side gap
function spawnDoubleObstacles() {
var obstacle1 = new Obstacle();
obstacle1.x = 2200;
obstacle1.y = groundLevel;
obstacle1.speed = -gameSpeed;
obstacles.push(obstacle1);
game.addChild(obstacle1);
var obstacle2 = new Obstacle();
obstacle2.x = 2280;
obstacle2.y = groundLevel;
obstacle2.speed = -gameSpeed;
obstacles.push(obstacle2);
game.addChild(obstacle2);
}
// Triple obstacles - requires precise jumping
function spawnTripleObstacles() {
for (var i = 0; i < 3; i++) {
var obstacle = new Obstacle();
obstacle.x = 2200 + i * 70;
obstacle.y = groundLevel;
obstacle.speed = -gameSpeed;
obstacles.push(obstacle);
game.addChild(obstacle);
}
}
// Staggered obstacles - different heights
function spawnStaggeredObstacles() {
var obstacle1 = new Obstacle();
obstacle1.x = 2200;
obstacle1.y = groundLevel;
obstacle1.speed = -gameSpeed;
obstacles.push(obstacle1);
game.addChild(obstacle1);
var obstacle2 = new Obstacle();
obstacle2.x = 2300;
obstacle2.y = groundLevel - 60;
obstacle2.speed = -gameSpeed;
obstacles.push(obstacle2);
game.addChild(obstacle2);
}
// Wall pattern - high obstacle requiring max jump
function spawnWallObstacles() {
var obstacle1 = new Obstacle();
obstacle1.x = 2200;
obstacle1.y = groundLevel;
obstacle1.speed = -gameSpeed;
obstacles.push(obstacle1);
game.addChild(obstacle1);
var obstacle2 = new Obstacle();
obstacle2.x = 2200;
obstacle2.y = groundLevel - 60;
obstacle2.speed = -gameSpeed;
obstacles.push(obstacle2);
game.addChild(obstacle2);
}
// Legacy single obstacle function for compatibility
function spawnObstacle() {
spawnSingleObstacle();
}
// Spawn ramp
function spawnRamp() {
var ramp = new Ramp();
ramp.x = 2200;
ramp.y = groundLevel;
ramp.speed = -gameSpeed;
ramps.push(ramp);
game.addChild(ramp);
}
// Game input - start charging
game.down = function (x, y, obj) {
if (isGameRunning && bike.isGrounded) {
isCharging = true;
chargeStartTime = LK.ticks;
currentCharge = 0;
}
};
// Game input - release jump
game.up = function (x, y, obj) {
if (isGameRunning && isCharging) {
var chargeMultiplier = currentCharge / maxCharge;
bike.jump(chargeMultiplier);
isCharging = false;
currentCharge = 0;
}
};
// Main game loop
game.update = function () {
if (!isGameRunning) return;
// Update jump charge system
if (isCharging && bike.isGrounded) {
currentCharge += chargeRate;
if (currentCharge > maxCharge) {
currentCharge = maxCharge;
}
} else if (!bike.isGrounded) {
isCharging = false;
currentCharge = 0;
}
// Update jump meter UI
var fillPercent = currentCharge / maxCharge;
meterFill.scaleX = 4 * fillPercent;
// Change color based on charge level
if (fillPercent < 0.3) {
meterFill.tint = 0xff0000; // Red
} else if (fillPercent < 0.7) {
meterFill.tint = 0xffff00; // Yellow
} else {
meterFill.tint = 0x00ff00; // Green
}
// Update distance score
distanceScore += 1;
LK.setScore(Math.floor(distanceScore / 10));
scoreTxt.setText('Distance: ' + Math.floor(distanceScore / 10));
// Update level indicator
levelTxt.setText('LEVEL ' + currentLevel);
// Increase game speed gradually
if (LK.ticks % 300 === 0) {
gameSpeed += 1.2;
}
// Update ground segments
for (var i = groundSegments.length - 1; i >= 0; i--) {
var segment = groundSegments[i];
segment.speed = -gameSpeed;
if (segment.x < -200) {
segment.x = (groundSegments.length - 1) * 200;
}
}
// Update current level based on distance
var newLevel = Math.min(5, Math.floor(distanceScore / levelDistance) + 1);
if (newLevel !== currentLevel) {
currentLevel = newLevel;
}
// Get current level configuration
var config = levelConfigs[currentLevel - 1];
// Spawn obstacles and ramps based on current level
if (distanceScore - lastObstacleSpawn > spawnDistance) {
var randomValue = Math.random();
if (randomValue < config.obstacleChance) {
// Choose random pattern from current level patterns
var patterns = config.patterns;
var randomPattern = patterns[Math.floor(Math.random() * patterns.length)];
spawnObstaclePattern(randomPattern);
} else {
spawnRamp();
}
lastObstacleSpawn = distanceScore;
spawnDistance = config.minSpacing + Math.random() * (config.maxSpacing - config.minSpacing);
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
obstacle.speed = -gameSpeed;
// Remove off-screen obstacles
if (obstacle.x < -100) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision detection
if (bike.intersects(obstacle)) {
// Game over
isGameRunning = false;
LK.getSound('crash').play();
LK.showGameOver();
return;
}
}
// Update ramps
for (var i = ramps.length - 1; i >= 0; i--) {
var ramp = ramps[i];
ramp.speed = -gameSpeed;
// Remove off-screen ramps
if (ramp.x < -100) {
ramp.destroy();
ramps.splice(i, 1);
continue;
}
// Ramp boost effect
if (bike.intersects(ramp) && bike.isGrounded) {
bike.velocityY = bike.jumpPower * 1.2;
bike.isGrounded = false;
}
}
// Check if bike fell off the track
if (bike.y > groundLevel + 200) {
isGameRunning = false;
LK.getSound('crash').play();
LK.showGameOver();
}
};
// Start background music
LK.playMusic('1crossbikecountryracetheme');