Code edit (1 edits merged)
Please save this source code
User prompt
Pixel Runner: Endless Adventure
Initial prompt
"Develop a 2D endless runner game with simple yet engaging mechanics. The player controls a pixel-art character (such as a dinosaur or another unique figure) that automatically runs across a scrolling landscape. The objective is to jump over obstacles like cacti, rocks, and flying creatures while gradually increasing the difficulty as the game progresses. The game should feature smooth physics-based movement, responsive jump mechanics, and a minimalist but visually appealing design. Integrate a dynamic day-night cycle, score tracking, and optional power-ups for variety. The game should be optimized for both desktop and mobile play, ensuring seamless performance and intuitive controls.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Background = Container.expand(function () {
var self = Container.call(this);
// Background properties
self.dayTime = true;
self.transitionProgress = 0;
// Create day and night backgrounds
var dayBg = self.attachAsset('dayBackground', {
anchorX: 0,
anchorY: 0,
alpha: 1
});
var nightBg = self.attachAsset('nightBackground', {
anchorX: 0,
anchorY: 0,
alpha: 0
});
// Progress day-night cycle
self.updateCycle = function (progress) {
// Full cycle every 60 seconds
self.transitionProgress = progress;
if (progress < 0.5) {
// Day to night transition
dayBg.alpha = 1 - progress * 2;
nightBg.alpha = progress * 2;
} else {
// Night to day transition
dayBg.alpha = (progress - 0.5) * 2;
nightBg.alpha = 1 - (progress - 0.5) * 2;
}
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
// Coin properties
self.speed = 8;
self.collected = false;
// Create coin sprite
var coinSprite = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
// Animation
self.animationOffset = Math.random() * Math.PI * 2;
// Update method called every frame
self.update = function () {
if (self.collected) {
return true;
}
self.x -= self.speed;
// Bobbing animation
self.y += Math.sin(LK.ticks * 0.05 + self.animationOffset) * 0.7;
// Remove if moved off screen
if (self.x < -coinSprite.width) {
self.destroy();
return true; // Signal for removal
}
return false;
};
// Collect coin
self.collect = function () {
if (!self.collected) {
self.collected = true;
LK.getSound('coin_collect').play();
// Animate coin collection
tween(self, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
return true;
}
return false;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
// Obstacle properties
self.speed = 8;
// Create obstacle sprite
var obstacleSprite = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1.0
});
// Update method called every frame
self.update = function () {
self.x -= self.speed;
// Remove if moved off screen
if (self.x < -obstacleSprite.width) {
self.destroy();
return true; // Signal for removal
}
return false;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
// Player properties
self.isJumping = false;
self.jumpVelocity = 0;
self.gravity = 0.5;
self.jumpPower = -15;
self.isAlive = true;
// Create player sprite
var playerSprite = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Jump method
self.jump = function () {
if (!self.isJumping && self.isAlive) {
self.isJumping = true;
self.jumpVelocity = self.jumpPower;
LK.getSound('jump').play();
}
};
// Update method called every frame
self.update = function () {
if (!self.isAlive) {
return;
}
// Apply gravity and handle jumping
if (self.isJumping) {
self.y += self.jumpVelocity;
self.jumpVelocity += self.gravity;
// Check if player landed back on ground
if (self.y >= groundY - playerSprite.height / 2) {
self.y = groundY - playerSprite.height / 2;
self.isJumping = false;
self.jumpVelocity = 0;
}
}
};
// Handle collision with obstacle
self.hitObstacle = function () {
if (!self.isAlive) {
return;
}
self.isAlive = false;
LK.getSound('obstacle_hit').play();
// Flash player red
LK.effects.flashObject(self, 0xff0000, 500);
// Game over
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game state variables
var player;
var obstacles = [];
var coins = [];
var groundY;
var background;
var spawnTimer;
var coinTimer;
var score = 0;
var distance = 0;
var gameSpeed = 1;
var gameTime = 0;
var isGameRunning = false;
// UI elements
var scoreTxt;
var distanceTxt;
// Initialize the game
function initGame() {
// Reset game state
isGameRunning = true;
score = 0;
distance = 0;
gameSpeed = 1;
gameTime = 0;
// Remove any existing objects
while (obstacles.length) {
obstacles[0].destroy();
obstacles.shift();
}
while (coins.length) {
coins[0].destroy();
coins.shift();
}
// Create background
background = new Background();
game.addChild(background);
// Create ground
var ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0
});
groundY = 2732 - 100;
ground.y = groundY;
game.addChild(ground);
// Create player
player = new Player();
player.x = 300;
player.y = groundY - player.height / 2;
game.addChild(player);
// Setup UI
setupUI();
// Setup timers for obstacle and coin spawning
spawnTimer = LK.setInterval(spawnObstacle, 2000);
coinTimer = LK.setInterval(spawnCoin, 1500);
// Play background music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.8,
duration: 1000
}
});
}
// Setup UI elements
function setupUI() {
// Score text
scoreTxt = new Text2('Score: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreTxt);
// Distance text
distanceTxt = new Text2('Distance: 0m', {
size: 70,
fill: 0xFFFFFF
});
distanceTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(distanceTxt);
distanceTxt.y = 80;
}
// Spawn an obstacle
function spawnObstacle() {
if (!isGameRunning) {
return;
}
var obstacle = new Obstacle();
obstacle.x = 2048 + obstacle.width;
obstacle.y = groundY;
obstacle.speed = 8 * gameSpeed;
game.addChild(obstacle);
obstacles.push(obstacle);
}
// Spawn a coin
function spawnCoin() {
if (!isGameRunning) {
return;
}
var coin = new Coin();
coin.x = 2048 + coin.width;
coin.y = groundY - 150 - Math.random() * 150;
coin.speed = 8 * gameSpeed;
game.addChild(coin);
coins.push(coin);
}
// Update score
function updateScore(points) {
score += points;
scoreTxt.setText('Score: ' + score);
LK.setScore(score);
}
// Update distance
function updateDistance(dist) {
distance += dist;
distanceTxt.setText('Distance: ' + Math.floor(distance) + 'm');
}
// Check collisions
function checkCollisions() {
if (!player.isAlive) {
return;
}
// Check obstacle collisions
for (var i = 0; i < obstacles.length; i++) {
if (player.intersects(obstacles[i])) {
player.hitObstacle();
break;
}
}
// Check coin collisions
for (var j = coins.length - 1; j >= 0; j--) {
if (player.intersects(coins[j])) {
if (coins[j].collect()) {
updateScore(10);
coins.splice(j, 1);
}
}
}
}
// Game tap/click event
game.down = function (x, y, obj) {
player.jump();
};
// Game update loop
game.update = function () {
if (!isGameRunning) {
return;
}
// Update game time and day-night cycle
gameTime += 1 / 60; // Assuming 60 FPS
background.updateCycle(gameTime % 60 / 60);
// Update player
player.update();
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
if (obstacles[i].update()) {
obstacles.splice(i, 1);
}
}
// Update coins
for (var j = coins.length - 1; j >= 0; j--) {
if (coins[j].update()) {
coins.splice(j, 1);
}
}
// Check collisions
checkCollisions();
// Update score and distance
updateDistance(0.1 * gameSpeed);
// Increase game speed over time
if (LK.ticks % 300 === 0) {
gameSpeed = Math.min(gameSpeed + 0.1, 3.0);
// Update existing objects with new speed
for (var k = 0; k < obstacles.length; k++) {
obstacles[k].speed = 8 * gameSpeed;
}
for (var l = 0; l < coins.length; l++) {
coins[l].speed = 8 * gameSpeed;
}
}
};
// Initialize the game when it's loaded
initGame(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,359 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+
+/****
+* Classes
+****/
+var Background = Container.expand(function () {
+ var self = Container.call(this);
+ // Background properties
+ self.dayTime = true;
+ self.transitionProgress = 0;
+ // Create day and night backgrounds
+ var dayBg = self.attachAsset('dayBackground', {
+ anchorX: 0,
+ anchorY: 0,
+ alpha: 1
+ });
+ var nightBg = self.attachAsset('nightBackground', {
+ anchorX: 0,
+ anchorY: 0,
+ alpha: 0
+ });
+ // Progress day-night cycle
+ self.updateCycle = function (progress) {
+ // Full cycle every 60 seconds
+ self.transitionProgress = progress;
+ if (progress < 0.5) {
+ // Day to night transition
+ dayBg.alpha = 1 - progress * 2;
+ nightBg.alpha = progress * 2;
+ } else {
+ // Night to day transition
+ dayBg.alpha = (progress - 0.5) * 2;
+ nightBg.alpha = 1 - (progress - 0.5) * 2;
+ }
+ };
+ return self;
+});
+var Coin = Container.expand(function () {
+ var self = Container.call(this);
+ // Coin properties
+ self.speed = 8;
+ self.collected = false;
+ // Create coin sprite
+ var coinSprite = self.attachAsset('coin', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Animation
+ self.animationOffset = Math.random() * Math.PI * 2;
+ // Update method called every frame
+ self.update = function () {
+ if (self.collected) {
+ return true;
+ }
+ self.x -= self.speed;
+ // Bobbing animation
+ self.y += Math.sin(LK.ticks * 0.05 + self.animationOffset) * 0.7;
+ // Remove if moved off screen
+ if (self.x < -coinSprite.width) {
+ self.destroy();
+ return true; // Signal for removal
+ }
+ return false;
+ };
+ // Collect coin
+ self.collect = function () {
+ if (!self.collected) {
+ self.collected = true;
+ LK.getSound('coin_collect').play();
+ // Animate coin collection
+ tween(self, {
+ alpha: 0,
+ scaleX: 2,
+ scaleY: 2
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ self.destroy();
+ }
+ });
+ return true;
+ }
+ return false;
+ };
+ return self;
+});
+var Obstacle = Container.expand(function () {
+ var self = Container.call(this);
+ // Obstacle properties
+ self.speed = 8;
+ // Create obstacle sprite
+ var obstacleSprite = self.attachAsset('obstacle', {
+ anchorX: 0.5,
+ anchorY: 1.0
+ });
+ // Update method called every frame
+ self.update = function () {
+ self.x -= self.speed;
+ // Remove if moved off screen
+ if (self.x < -obstacleSprite.width) {
+ self.destroy();
+ return true; // Signal for removal
+ }
+ return false;
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ // Player properties
+ self.isJumping = false;
+ self.jumpVelocity = 0;
+ self.gravity = 0.5;
+ self.jumpPower = -15;
+ self.isAlive = true;
+ // Create player sprite
+ var playerSprite = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Jump method
+ self.jump = function () {
+ if (!self.isJumping && self.isAlive) {
+ self.isJumping = true;
+ self.jumpVelocity = self.jumpPower;
+ LK.getSound('jump').play();
+ }
+ };
+ // Update method called every frame
+ self.update = function () {
+ if (!self.isAlive) {
+ return;
+ }
+ // Apply gravity and handle jumping
+ if (self.isJumping) {
+ self.y += self.jumpVelocity;
+ self.jumpVelocity += self.gravity;
+ // Check if player landed back on ground
+ if (self.y >= groundY - playerSprite.height / 2) {
+ self.y = groundY - playerSprite.height / 2;
+ self.isJumping = false;
+ self.jumpVelocity = 0;
+ }
+ }
+ };
+ // Handle collision with obstacle
+ self.hitObstacle = function () {
+ if (!self.isAlive) {
+ return;
+ }
+ self.isAlive = false;
+ LK.getSound('obstacle_hit').play();
+ // Flash player red
+ LK.effects.flashObject(self, 0xff0000, 500);
+ // Game over
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 1000);
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x87CEEB
+});
+
+/****
+* Game Code
+****/
+// Game state variables
+var player;
+var obstacles = [];
+var coins = [];
+var groundY;
+var background;
+var spawnTimer;
+var coinTimer;
+var score = 0;
+var distance = 0;
+var gameSpeed = 1;
+var gameTime = 0;
+var isGameRunning = false;
+// UI elements
+var scoreTxt;
+var distanceTxt;
+// Initialize the game
+function initGame() {
+ // Reset game state
+ isGameRunning = true;
+ score = 0;
+ distance = 0;
+ gameSpeed = 1;
+ gameTime = 0;
+ // Remove any existing objects
+ while (obstacles.length) {
+ obstacles[0].destroy();
+ obstacles.shift();
+ }
+ while (coins.length) {
+ coins[0].destroy();
+ coins.shift();
+ }
+ // Create background
+ background = new Background();
+ game.addChild(background);
+ // Create ground
+ var ground = LK.getAsset('ground', {
+ anchorX: 0,
+ anchorY: 0
+ });
+ groundY = 2732 - 100;
+ ground.y = groundY;
+ game.addChild(ground);
+ // Create player
+ player = new Player();
+ player.x = 300;
+ player.y = groundY - player.height / 2;
+ game.addChild(player);
+ // Setup UI
+ setupUI();
+ // Setup timers for obstacle and coin spawning
+ spawnTimer = LK.setInterval(spawnObstacle, 2000);
+ coinTimer = LK.setInterval(spawnCoin, 1500);
+ // Play background music
+ LK.playMusic('gameMusic', {
+ fade: {
+ start: 0,
+ end: 0.8,
+ duration: 1000
+ }
+ });
+}
+// Setup UI elements
+function setupUI() {
+ // Score text
+ scoreTxt = new Text2('Score: 0', {
+ size: 70,
+ fill: 0xFFFFFF
+ });
+ scoreTxt.anchor.set(1, 0);
+ LK.gui.topRight.addChild(scoreTxt);
+ // Distance text
+ distanceTxt = new Text2('Distance: 0m', {
+ size: 70,
+ fill: 0xFFFFFF
+ });
+ distanceTxt.anchor.set(0, 0);
+ LK.gui.topRight.addChild(distanceTxt);
+ distanceTxt.y = 80;
+}
+// Spawn an obstacle
+function spawnObstacle() {
+ if (!isGameRunning) {
+ return;
+ }
+ var obstacle = new Obstacle();
+ obstacle.x = 2048 + obstacle.width;
+ obstacle.y = groundY;
+ obstacle.speed = 8 * gameSpeed;
+ game.addChild(obstacle);
+ obstacles.push(obstacle);
+}
+// Spawn a coin
+function spawnCoin() {
+ if (!isGameRunning) {
+ return;
+ }
+ var coin = new Coin();
+ coin.x = 2048 + coin.width;
+ coin.y = groundY - 150 - Math.random() * 150;
+ coin.speed = 8 * gameSpeed;
+ game.addChild(coin);
+ coins.push(coin);
+}
+// Update score
+function updateScore(points) {
+ score += points;
+ scoreTxt.setText('Score: ' + score);
+ LK.setScore(score);
+}
+// Update distance
+function updateDistance(dist) {
+ distance += dist;
+ distanceTxt.setText('Distance: ' + Math.floor(distance) + 'm');
+}
+// Check collisions
+function checkCollisions() {
+ if (!player.isAlive) {
+ return;
+ }
+ // Check obstacle collisions
+ for (var i = 0; i < obstacles.length; i++) {
+ if (player.intersects(obstacles[i])) {
+ player.hitObstacle();
+ break;
+ }
+ }
+ // Check coin collisions
+ for (var j = coins.length - 1; j >= 0; j--) {
+ if (player.intersects(coins[j])) {
+ if (coins[j].collect()) {
+ updateScore(10);
+ coins.splice(j, 1);
+ }
+ }
+ }
+}
+// Game tap/click event
+game.down = function (x, y, obj) {
+ player.jump();
+};
+// Game update loop
+game.update = function () {
+ if (!isGameRunning) {
+ return;
+ }
+ // Update game time and day-night cycle
+ gameTime += 1 / 60; // Assuming 60 FPS
+ background.updateCycle(gameTime % 60 / 60);
+ // Update player
+ player.update();
+ // Update obstacles
+ for (var i = obstacles.length - 1; i >= 0; i--) {
+ if (obstacles[i].update()) {
+ obstacles.splice(i, 1);
+ }
+ }
+ // Update coins
+ for (var j = coins.length - 1; j >= 0; j--) {
+ if (coins[j].update()) {
+ coins.splice(j, 1);
+ }
+ }
+ // Check collisions
+ checkCollisions();
+ // Update score and distance
+ updateDistance(0.1 * gameSpeed);
+ // Increase game speed over time
+ if (LK.ticks % 300 === 0) {
+ gameSpeed = Math.min(gameSpeed + 0.1, 3.0);
+ // Update existing objects with new speed
+ for (var k = 0; k < obstacles.length; k++) {
+ obstacles[k].speed = 8 * gameSpeed;
+ }
+ for (var l = 0; l < coins.length; l++) {
+ coins[l].speed = 8 * gameSpeed;
+ }
+ }
+};
+// Initialize the game when it's loaded
+initGame();
\ No newline at end of file