User prompt
The white lines shift the 90 degrees
User prompt
The white lines need to be roadlines and you get points when you avoid them, the road needs a city landscape around
User prompt
make the lines vertical and different lenghts
Code edit (1 edits merged)
Please save this source code
User prompt
Road Rhythm: Line Jump
Initial prompt
Design an engaging video game that showcases the front view of a car navigating through a variety of vibrant cityscapes. The primary objective of the game is for players to skillfully jump between different road lines as the car speeds along. To score points, players must click only when the car is traveling on sections of the road without any visible lines. Successfully timing these clicks will reward players with points, encouraging them to stay alert and focused. However, caution is keyโif players mistakenly jump over the road lines, they will incur a point penalty. In addition to the basic mechanics, the game could introduce unique challenges and power-ups, such as changing environments or obstacles that require quick reflexes, adding layers of complexity and excitement to the gameplay.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Building = Container.expand(function () { var self = Container.call(this); var buildingGraphics = self.attachAsset('building', { anchorX: 0.5, anchorY: 0 }); // Randomize building properties var shade = Math.floor(Math.random() * 40) + 40; buildingGraphics.tint = shade << 16 | shade << 8 | shade; buildingGraphics.height = Math.random() * 600 + 400; buildingGraphics.width = Math.random() * 100 + 100; // Add windows to buildings for a city look var windowCount = Math.floor(buildingGraphics.height / 80); var windowsPerRow = Math.floor(buildingGraphics.width / 40); for (var i = 0; i < windowCount; i++) { for (var j = 0; j < windowsPerRow; j++) { var windowLight = self.addChild(new Container()); var windowAsset = windowLight.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 20, height: 30, tint: 0xFFFF99 }); windowLight.x = j * 40 - buildingGraphics.width / 2 + 25; windowLight.y = i * 80 + 50; // Randomly light windows windowLight.alpha = Math.random() > 0.3 ? 0.8 : 0; } } self.speed = 10; // Default speed self.update = function () { self.y += self.speed; // Reset building when it goes off screen if (self.y > 2732 + buildingGraphics.height) { self.y = -buildingGraphics.height; self.x = Math.random() * 2048; var shade = Math.floor(Math.random() * 40) + 40; buildingGraphics.tint = shade << 16 | shade << 8 | shade; buildingGraphics.height = Math.random() * 600 + 400; buildingGraphics.width = Math.random() * 100 + 100; // Recreate windows when building resets self.removeChildren(1); // Keep only the main building graphic var windowCount = Math.floor(buildingGraphics.height / 80); var windowsPerRow = Math.floor(buildingGraphics.width / 40); for (var i = 0; i < windowCount; i++) { for (var j = 0; j < windowsPerRow; j++) { var windowLight = self.addChild(new Container()); var windowAsset = windowLight.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 20, height: 30, tint: 0xFFFF99 }); windowLight.x = j * 40 - buildingGraphics.width / 2 + 25; windowLight.y = i * 80 + 50; // Randomly light windows windowLight.alpha = Math.random() > 0.3 ? 0.8 : 0; } } } }; return self; }); var Car = Container.expand(function () { var self = Container.call(this); // Create car body var carGraphics = self.attachAsset('car', { anchorX: 0.5, anchorY: 0.5, tint: 0x3366CC // Blue car color }); // Add car windows var carWindshield = self.addChild(new Container()); var windshieldAsset = carWindshield.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 140, height: 80, tint: 0xCCEEFF }); carWindshield.y = -80; // Add headlights var leftHeadlight = self.addChild(new Container()); var leftHeadlightAsset = leftHeadlight.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 40, tint: 0xFFFFAA }); leftHeadlight.x = -60; leftHeadlight.y = -140; var rightHeadlight = self.addChild(new Container()); var rightHeadlightAsset = rightHeadlight.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 40, tint: 0xFFFFAA }); rightHeadlight.x = 60; rightHeadlight.y = -140; self.jumping = false; self.jumpHeight = 100; self.originalY = 0; self.lastY = 0; // Track last Y position for intersection detection self.jump = function () { if (self.jumping) { return; } self.jumping = true; self.originalY = self.y; // Jump animation using tween tween(self, { y: self.y - self.jumpHeight }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Fall back down tween(self, { y: self.originalY }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { self.jumping = false; } }); } }); // Play jump sound LK.getSound('jump').play(); }; self.down = function () { self.jump(); }; self.update = function () { self.lastY = self.y; // Create headlight glow effect if (LK.ticks % 5 === 0) { leftHeadlightAsset.alpha = 0.7 + Math.random() * 0.3; rightHeadlightAsset.alpha = 0.7 + Math.random() * 0.3; } }; return self; }); var Line = Container.expand(function () { var self = Container.call(this); // Create road line marking var lineGraphics = self.attachAsset('line', { anchorX: 0.5, anchorY: 0.5 }); // Make line horizontal lineGraphics.rotation = 0; // Road lines have consistent dimensions lineGraphics.width = 200; // Line width (horizontal) lineGraphics.height = 30; // Line height (thickness) self.lastY = 0; // Track last Y position for intersection detection self.speed = 15; // Default speed self.active = true; // Whether the line is active for scoring self.scored = false; // Whether this line has been scored already self.update = function () { self.lastY = self.y; // Store last position for collision detection self.y += self.speed; // Remove when off screen if (self.y > 2732 + lineGraphics.height / 2) { self.active = false; } }; return self; }); var ScoreEffect = Container.expand(function () { var self = Container.call(this); var effectGraphics = self.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.show = function (x, y, isPositive) { self.x = x; self.y = y; if (!isPositive) { effectGraphics.tint = 0xFF0000; } else { effectGraphics.tint = 0x00FF00; } // Animation for the effect tween(self, { alpha: 0, y: y - 100 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { self.alpha = 1; self.visible = false; } }); self.visible = true; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game variables var car; var lines = []; var buildings = []; var score = 0; var scoreText; var speedMultiplier = 1; var lineSpawnRate = 60; // Frames between line spawns var difficulty = 1; var isGameActive = true; var scoreEffects = []; var effectIndex = 0; var lastJumpScore = 0; // Create a sky background game.setBackgroundColor(0x87CEEB); // Light blue sky // Initialize the road var road = game.addChild(LK.getAsset('road', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, width: 1200, // Make the road narrower than the full width tint: 0x444444 // Darker gray for asphalt })); // Add road edges/sidewalks var leftSidewalk = game.addChild(LK.getAsset('building', { anchorX: 0, anchorY: 0.5, width: (2048 - road.width) / 2, height: 2732, x: 0, y: 2732 / 2, tint: 0x999999 // Light gray for sidewalk })); var rightSidewalk = game.addChild(LK.getAsset('building', { anchorX: 1, anchorY: 0.5, width: (2048 - road.width) / 2, height: 2732, x: 2048, y: 2732 / 2, tint: 0x999999 // Light gray for sidewalk })); // Initialize score display scoreText = new Text2('SCORE: 0', { size: 80, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 5 }); scoreText.anchor.set(0.5, 0); scoreText.y = 50; // Move down slightly from top LK.gui.top.addChild(scoreText); // Add game instructions var instructionsText = new Text2('Tap to jump! Avoid the white lines', { size: 60, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 4 }); instructionsText.anchor.set(0.5, 0); instructionsText.y = 150; LK.gui.top.addChild(instructionsText); // Create buildings for city skyline on both sides of the road for (var i = 0; i < 20; i++) { var building = new Building(); // Position buildings on either side of the road if (i % 2 === 0) { building.x = Math.random() * ((2048 - road.width) / 2 - 100) + 100; // Left side } else { building.x = 2048 - (2048 - road.width) / 2 + Math.random() * ((2048 - road.width) / 2 - 100) - 100; // Right side } building.y = Math.random() * 2732; buildings.push(building); game.addChild(building); } // Create car car = new Car(); car.x = 2048 / 2; car.y = 2732 - 400; game.addChild(car); // Create score effects pool for (var i = 0; i < 5; i++) { var effect = new ScoreEffect(); effect.visible = false; scoreEffects.push(effect); game.addChild(effect); } // Game click handler game.down = function (x, y, obj) { if (!isGameActive) { return; } // Check if car is already jumping if (!car.jumping) { car.jump(); // Check if car is over a road line var overLine = false; for (var i = 0; i < lines.length; i++) { // Check if the car is directly over a horizontal road line if (lines[i].active && Math.abs(lines[i].y - car.y) < 50) { overLine = true; break; } } // Score or penalty based on jump if (overLine) { // Penalty for jumping over a line score = Math.max(0, score - 5); // Show penalty effect var effect = scoreEffects[effectIndex]; effectIndex = (effectIndex + 1) % scoreEffects.length; effect.show(car.x, car.y - 50, false); // Play penalty sound LK.getSound('penalty').play(); } else { // Points for jumping on empty road var pointsGained = 10 * difficulty; score += pointsGained; lastJumpScore = pointsGained; // Show score effect var effect = scoreEffects[effectIndex]; effectIndex = (effectIndex + 1) % scoreEffects.length; effect.show(car.x, car.y - 50, true); // Play point sound LK.getSound('point').play(); } // Update score display scoreText.setText(score); LK.setScore(score); } }; // Game update function game.update = function () { if (!isGameActive) { return; } // Update car car.update(); // Update all lines for (var i = lines.length - 1; i >= 0; i--) { lines[i].update(); // Check for car passing line (for scoring without jumping) if (!lines[i].scored && !car.jumping && lines[i].lastY < car.y && lines[i].y >= car.y) { // Car drove over a line - subtract points score = Math.max(0, score - 2); scoreText.setText(score); LK.setScore(score); // Show penalty effect var effect = scoreEffects[effectIndex]; effectIndex = (effectIndex + 1) % scoreEffects.length; effect.show(car.x, car.y - 50, false); lines[i].scored = true; // Mark as scored } // Remove inactive lines if (!lines[i].active) { lines[i].destroy(); lines.splice(i, 1); } } // Update all buildings for (var i = 0; i < buildings.length; i++) { buildings[i].speed = 5 * speedMultiplier; buildings[i].update(); } // Create new lines at intervals - place them across the road width if (LK.ticks % Math.floor(lineSpawnRate / speedMultiplier) === 0) { var line = new Line(); line.x = 2048 / 2; // Center the line on the road line.y = -50; line.speed = 15 * speedMultiplier; lines.push(line); game.addChild(line); } // Increase difficulty over time if (LK.ticks % 600 === 0) { // Every 10 seconds difficulty += 0.1; speedMultiplier = 1 + (difficulty - 1) * 0.5; // Make lines spawn more frequently as difficulty increases lineSpawnRate = Math.max(15, 60 - difficulty * 5); } // Check for game over condition if (score < 0) { isGameActive = false; LK.showGameOver(); } // Check for win condition (arbitrary high score for demo) if (score >= 500) { isGameActive = false; LK.showYouWin(); } }; // Start background music LK.playMusic('bgmusic', { fade: { start: 0, end: 0.4, duration: 1000 } });
===================================================================
--- original.js
+++ change.js
@@ -17,8 +17,27 @@
var shade = Math.floor(Math.random() * 40) + 40;
buildingGraphics.tint = shade << 16 | shade << 8 | shade;
buildingGraphics.height = Math.random() * 600 + 400;
buildingGraphics.width = Math.random() * 100 + 100;
+ // Add windows to buildings for a city look
+ var windowCount = Math.floor(buildingGraphics.height / 80);
+ var windowsPerRow = Math.floor(buildingGraphics.width / 40);
+ for (var i = 0; i < windowCount; i++) {
+ for (var j = 0; j < windowsPerRow; j++) {
+ var windowLight = self.addChild(new Container());
+ var windowAsset = windowLight.attachAsset('building', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 20,
+ height: 30,
+ tint: 0xFFFF99
+ });
+ windowLight.x = j * 40 - buildingGraphics.width / 2 + 25;
+ windowLight.y = i * 80 + 50;
+ // Randomly light windows
+ windowLight.alpha = Math.random() > 0.3 ? 0.8 : 0;
+ }
+ }
self.speed = 10; // Default speed
self.update = function () {
self.y += self.speed;
// Reset building when it goes off screen
@@ -28,21 +47,75 @@
var shade = Math.floor(Math.random() * 40) + 40;
buildingGraphics.tint = shade << 16 | shade << 8 | shade;
buildingGraphics.height = Math.random() * 600 + 400;
buildingGraphics.width = Math.random() * 100 + 100;
+ // Recreate windows when building resets
+ self.removeChildren(1); // Keep only the main building graphic
+ var windowCount = Math.floor(buildingGraphics.height / 80);
+ var windowsPerRow = Math.floor(buildingGraphics.width / 40);
+ for (var i = 0; i < windowCount; i++) {
+ for (var j = 0; j < windowsPerRow; j++) {
+ var windowLight = self.addChild(new Container());
+ var windowAsset = windowLight.attachAsset('building', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 20,
+ height: 30,
+ tint: 0xFFFF99
+ });
+ windowLight.x = j * 40 - buildingGraphics.width / 2 + 25;
+ windowLight.y = i * 80 + 50;
+ // Randomly light windows
+ windowLight.alpha = Math.random() > 0.3 ? 0.8 : 0;
+ }
+ }
}
};
return self;
});
var Car = Container.expand(function () {
var self = Container.call(this);
+ // Create car body
var carGraphics = self.attachAsset('car', {
anchorX: 0.5,
- anchorY: 0.5
+ anchorY: 0.5,
+ tint: 0x3366CC // Blue car color
});
+ // Add car windows
+ var carWindshield = self.addChild(new Container());
+ var windshieldAsset = carWindshield.attachAsset('building', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 140,
+ height: 80,
+ tint: 0xCCEEFF
+ });
+ carWindshield.y = -80;
+ // Add headlights
+ var leftHeadlight = self.addChild(new Container());
+ var leftHeadlightAsset = leftHeadlight.attachAsset('scoreEffect', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 40,
+ height: 40,
+ tint: 0xFFFFAA
+ });
+ leftHeadlight.x = -60;
+ leftHeadlight.y = -140;
+ var rightHeadlight = self.addChild(new Container());
+ var rightHeadlightAsset = rightHeadlight.attachAsset('scoreEffect', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 40,
+ height: 40,
+ tint: 0xFFFFAA
+ });
+ rightHeadlight.x = 60;
+ rightHeadlight.y = -140;
self.jumping = false;
self.jumpHeight = 100;
self.originalY = 0;
+ self.lastY = 0; // Track last Y position for intersection detection
self.jump = function () {
if (self.jumping) {
return;
}
@@ -72,28 +145,39 @@
};
self.down = function () {
self.jump();
};
+ self.update = function () {
+ self.lastY = self.y;
+ // Create headlight glow effect
+ if (LK.ticks % 5 === 0) {
+ leftHeadlightAsset.alpha = 0.7 + Math.random() * 0.3;
+ rightHeadlightAsset.alpha = 0.7 + Math.random() * 0.3;
+ }
+ };
return self;
});
var Line = Container.expand(function () {
var self = Container.call(this);
- // Create vertical line with randomized length
+ // Create road line marking
var lineGraphics = self.attachAsset('line', {
anchorX: 0.5,
anchorY: 0.5
});
- // Make the line vertical by rotating it 90 degrees
- lineGraphics.rotation = Math.PI / 2;
- // Randomize line length
- lineGraphics.height = Math.random() * 400 + 200; // Random height between 200-600
- lineGraphics.width = 40; // Keep the width consistent (this becomes thickness of vertical line)
+ // Make line horizontal
+ lineGraphics.rotation = 0;
+ // Road lines have consistent dimensions
+ lineGraphics.width = 200; // Line width (horizontal)
+ lineGraphics.height = 30; // Line height (thickness)
+ self.lastY = 0; // Track last Y position for intersection detection
self.speed = 15; // Default speed
self.active = true; // Whether the line is active for scoring
+ self.scored = false; // Whether this line has been scored already
self.update = function () {
+ self.lastY = self.y; // Store last position for collision detection
self.y += self.speed;
// Remove when off screen
- if (self.y > 2732 + lineGraphics.width / 2) {
+ if (self.y > 2732 + lineGraphics.height / 2) {
self.active = false;
}
};
return self;
@@ -152,26 +236,68 @@
var isGameActive = true;
var scoreEffects = [];
var effectIndex = 0;
var lastJumpScore = 0;
+// Create a sky background
+game.setBackgroundColor(0x87CEEB); // Light blue sky
// Initialize the road
var road = game.addChild(LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
- y: 2732 / 2
+ y: 2732 / 2,
+ width: 1200,
+ // Make the road narrower than the full width
+ tint: 0x444444 // Darker gray for asphalt
}));
+// Add road edges/sidewalks
+var leftSidewalk = game.addChild(LK.getAsset('building', {
+ anchorX: 0,
+ anchorY: 0.5,
+ width: (2048 - road.width) / 2,
+ height: 2732,
+ x: 0,
+ y: 2732 / 2,
+ tint: 0x999999 // Light gray for sidewalk
+}));
+var rightSidewalk = game.addChild(LK.getAsset('building', {
+ anchorX: 1,
+ anchorY: 0.5,
+ width: (2048 - road.width) / 2,
+ height: 2732,
+ x: 2048,
+ y: 2732 / 2,
+ tint: 0x999999 // Light gray for sidewalk
+}));
// Initialize score display
-scoreText = new Text2('0', {
- size: 120,
- fill: 0xFFFFFF
+scoreText = new Text2('SCORE: 0', {
+ size: 80,
+ fill: 0xFFFFFF,
+ stroke: 0x000000,
+ strokeThickness: 5
});
scoreText.anchor.set(0.5, 0);
+scoreText.y = 50; // Move down slightly from top
LK.gui.top.addChild(scoreText);
-// Create buildings for background
-for (var i = 0; i < 10; i++) {
+// Add game instructions
+var instructionsText = new Text2('Tap to jump! Avoid the white lines', {
+ size: 60,
+ fill: 0xFFFFFF,
+ stroke: 0x000000,
+ strokeThickness: 4
+});
+instructionsText.anchor.set(0.5, 0);
+instructionsText.y = 150;
+LK.gui.top.addChild(instructionsText);
+// Create buildings for city skyline on both sides of the road
+for (var i = 0; i < 20; i++) {
var building = new Building();
- building.x = Math.random() * 2048;
+ // Position buildings on either side of the road
+ if (i % 2 === 0) {
+ building.x = Math.random() * ((2048 - road.width) / 2 - 100) + 100; // Left side
+ } else {
+ building.x = 2048 - (2048 - road.width) / 2 + Math.random() * ((2048 - road.width) / 2 - 100) - 100; // Right side
+ }
building.y = Math.random() * 2732;
buildings.push(building);
game.addChild(building);
}
@@ -194,14 +320,13 @@
}
// Check if car is already jumping
if (!car.jumping) {
car.jump();
- // Check if car is over a line or intersects with a vertical line
+ // Check if car is over a road line
var overLine = false;
for (var i = 0; i < lines.length; i++) {
- // For vertical lines, we need to check both X and Y proximity
- // The car should be within the vertical line's height range and close on X axis
- if (lines[i].active && Math.abs(lines[i].y - car.y) < 50 && Math.abs(lines[i].x - car.x) < 100) {
+ // Check if the car is directly over a horizontal road line
+ if (lines[i].active && Math.abs(lines[i].y - car.y) < 50) {
overLine = true;
break;
}
}
@@ -236,11 +361,25 @@
game.update = function () {
if (!isGameActive) {
return;
}
+ // Update car
+ car.update();
// Update all lines
for (var i = lines.length - 1; i >= 0; i--) {
lines[i].update();
+ // Check for car passing line (for scoring without jumping)
+ if (!lines[i].scored && !car.jumping && lines[i].lastY < car.y && lines[i].y >= car.y) {
+ // Car drove over a line - subtract points
+ score = Math.max(0, score - 2);
+ scoreText.setText(score);
+ LK.setScore(score);
+ // Show penalty effect
+ var effect = scoreEffects[effectIndex];
+ effectIndex = (effectIndex + 1) % scoreEffects.length;
+ effect.show(car.x, car.y - 50, false);
+ lines[i].scored = true; // Mark as scored
+ }
// Remove inactive lines
if (!lines[i].active) {
lines[i].destroy();
lines.splice(i, 1);
@@ -250,14 +389,13 @@
for (var i = 0; i < buildings.length; i++) {
buildings[i].speed = 5 * speedMultiplier;
buildings[i].update();
}
- // Create new lines at intervals
+ // Create new lines at intervals - place them across the road width
if (LK.ticks % Math.floor(lineSpawnRate / speedMultiplier) === 0) {
var line = new Line();
- // Position lines randomly across the road width
- line.x = Math.random() * (2048 - 400) + 200; // Random X between 200 and 1648
- line.y = -20;
+ line.x = 2048 / 2; // Center the line on the road
+ line.y = -50;
line.speed = 15 * speedMultiplier;
lines.push(line);
game.addChild(line);
}
@@ -265,8 +403,10 @@
if (LK.ticks % 600 === 0) {
// Every 10 seconds
difficulty += 0.1;
speedMultiplier = 1 + (difficulty - 1) * 0.5;
+ // Make lines spawn more frequently as difficulty increases
+ lineSpawnRate = Math.max(15, 60 - difficulty * 5);
}
// Check for game over condition
if (score < 0) {
isGameActive = false;