Code edit (1 edits merged)
Please save this source code
User prompt
Forest Escape
Initial prompt
Create a simple endless runner game called 'Forest Escape'. The player controls a running character in the jungle. The character must jump over rocks, duck under tree branches, and avoid rivers. The game should get faster over time, and the player’s score increases the longer they survive.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 1.0
});
self.isJumping = false;
self.isDucking = false;
self.baseY = 0;
self.jumpSpeed = 0;
self.gravity = 1.2;
self.jump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.jumpSpeed = -22;
LK.getSound('jump').play();
}
};
self.duck = function () {
if (!self.isDucking && !self.isJumping) {
self.isDucking = true;
tween(characterGraphics, {
scaleY: 0.5
}, {
duration: 200
});
LK.getSound('duck').play();
}
};
self.stopDuck = function () {
if (self.isDucking) {
self.isDucking = false;
tween(characterGraphics, {
scaleY: 1.0
}, {
duration: 200
});
}
};
self.update = function () {
if (self.isJumping) {
self.jumpSpeed += self.gravity;
self.y += self.jumpSpeed;
if (self.y >= self.baseY) {
self.y = self.baseY;
self.isJumping = false;
self.jumpSpeed = 0;
}
}
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
self.speed = 8;
if (type === 'rock') {
var graphics = self.attachAsset('rock', {
anchorX: 0.5,
anchorY: 1.0
});
} else if (type === 'branch') {
var graphics = self.attachAsset('branch', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (type === 'river') {
var graphics = self.attachAsset('river', {
anchorX: 0.5,
anchorY: 1.0
});
}
self.update = function () {
self.x -= self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d5a3d
});
/****
* Game Code
****/
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 1.0,
x: 0,
y: 2732
}));
var character = game.addChild(new Character());
character.x = 300;
character.y = 2732 - 200;
character.baseY = character.y;
var obstacles = [];
var gameSpeed = 8;
var obstacleSpawnTimer = 0;
var obstacleSpawnDelay = 90;
var distance = 0;
var gameStarted = false;
var scoreTxt = new Text2('Distance: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var speedTxt = new Text2('Speed: 1.0x', {
size: 60,
fill: 0xFFFF00
});
speedTxt.anchor.set(1.0, 0);
speedTxt.y = 100;
LK.gui.topRight.addChild(speedTxt);
var instructionTxt = new Text2('Tap to Jump, Hold to Duck', {
size: 70,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.x = 2048 / 2;
instructionTxt.y = 2732 / 2 - 200;
game.addChild(instructionTxt);
var isHoldingDown = false;
function spawnObstacle() {
var obstacleTypes = ['rock', 'branch', 'river'];
var randomType = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];
var obstacle = new Obstacle(randomType);
obstacle.x = 2048 + 100;
obstacle.speed = gameSpeed;
if (randomType === 'rock' || randomType === 'river') {
obstacle.y = 2732 - 200;
} else if (randomType === 'branch') {
obstacle.y = 2732 - 300;
}
obstacles.push(obstacle);
game.addChild(obstacle);
}
function checkCollisions() {
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (character.intersects(obstacle)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
}
function updateGame() {
if (!gameStarted) return;
distance += gameSpeed / 10;
LK.setScore(Math.floor(distance));
scoreTxt.setText('Distance: ' + Math.floor(distance));
gameSpeed += 0.002;
var speedMultiplier = (gameSpeed / 8).toFixed(1);
speedTxt.setText('Speed: ' + speedMultiplier + 'x');
obstacleSpawnTimer++;
if (obstacleSpawnTimer >= obstacleSpawnDelay) {
spawnObstacle();
obstacleSpawnTimer = 0;
if (obstacleSpawnDelay > 45) {
obstacleSpawnDelay -= 0.5;
}
}
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
obstacle.speed = gameSpeed;
if (obstacle.x < -150) {
obstacle.destroy();
obstacles.splice(i, 1);
}
}
checkCollisions();
}
game.down = function (x, y, obj) {
if (!gameStarted) {
gameStarted = true;
instructionTxt.destroy();
}
isHoldingDown = true;
character.jump();
};
game.up = function (x, y, obj) {
isHoldingDown = false;
character.stopDuck();
};
var holdTimer = 0;
game.update = function () {
if (isHoldingDown) {
holdTimer++;
if (holdTimer > 10) {
character.duck();
}
} else {
holdTimer = 0;
}
updateGame();
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 1.0
});
self.isJumping = false;
self.isDucking = false;
self.baseY = 0;
self.jumpSpeed = 0;
self.gravity = 1.2;
self.jump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.jumpSpeed = -22;
LK.getSound('jump').play();
}
};
self.duck = function () {
if (!self.isDucking && !self.isJumping) {
self.isDucking = true;
tween(characterGraphics, {
scaleY: 0.5
}, {
duration: 200
});
LK.getSound('duck').play();
}
};
self.stopDuck = function () {
if (self.isDucking) {
self.isDucking = false;
tween(characterGraphics, {
scaleY: 1.0
}, {
duration: 200
});
}
};
self.update = function () {
if (self.isJumping) {
self.jumpSpeed += self.gravity;
self.y += self.jumpSpeed;
if (self.y >= self.baseY) {
self.y = self.baseY;
self.isJumping = false;
self.jumpSpeed = 0;
}
}
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
self.speed = 8;
if (type === 'rock') {
var graphics = self.attachAsset('rock', {
anchorX: 0.5,
anchorY: 1.0
});
} else if (type === 'branch') {
var graphics = self.attachAsset('branch', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (type === 'river') {
var graphics = self.attachAsset('river', {
anchorX: 0.5,
anchorY: 1.0
});
}
self.update = function () {
self.x -= self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d5a3d
});
/****
* Game Code
****/
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 1.0,
x: 0,
y: 2732
}));
var character = game.addChild(new Character());
character.x = 300;
character.y = 2732 - 200;
character.baseY = character.y;
var obstacles = [];
var gameSpeed = 8;
var obstacleSpawnTimer = 0;
var obstacleSpawnDelay = 90;
var distance = 0;
var gameStarted = false;
var scoreTxt = new Text2('Distance: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var speedTxt = new Text2('Speed: 1.0x', {
size: 60,
fill: 0xFFFF00
});
speedTxt.anchor.set(1.0, 0);
speedTxt.y = 100;
LK.gui.topRight.addChild(speedTxt);
var instructionTxt = new Text2('Tap to Jump, Hold to Duck', {
size: 70,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.x = 2048 / 2;
instructionTxt.y = 2732 / 2 - 200;
game.addChild(instructionTxt);
var isHoldingDown = false;
function spawnObstacle() {
var obstacleTypes = ['rock', 'branch', 'river'];
var randomType = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];
var obstacle = new Obstacle(randomType);
obstacle.x = 2048 + 100;
obstacle.speed = gameSpeed;
if (randomType === 'rock' || randomType === 'river') {
obstacle.y = 2732 - 200;
} else if (randomType === 'branch') {
obstacle.y = 2732 - 300;
}
obstacles.push(obstacle);
game.addChild(obstacle);
}
function checkCollisions() {
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (character.intersects(obstacle)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
}
function updateGame() {
if (!gameStarted) return;
distance += gameSpeed / 10;
LK.setScore(Math.floor(distance));
scoreTxt.setText('Distance: ' + Math.floor(distance));
gameSpeed += 0.002;
var speedMultiplier = (gameSpeed / 8).toFixed(1);
speedTxt.setText('Speed: ' + speedMultiplier + 'x');
obstacleSpawnTimer++;
if (obstacleSpawnTimer >= obstacleSpawnDelay) {
spawnObstacle();
obstacleSpawnTimer = 0;
if (obstacleSpawnDelay > 45) {
obstacleSpawnDelay -= 0.5;
}
}
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
obstacle.speed = gameSpeed;
if (obstacle.x < -150) {
obstacle.destroy();
obstacles.splice(i, 1);
}
}
checkCollisions();
}
game.down = function (x, y, obj) {
if (!gameStarted) {
gameStarted = true;
instructionTxt.destroy();
}
isHoldingDown = true;
character.jump();
};
game.up = function (x, y, obj) {
isHoldingDown = false;
character.stopDuck();
};
var holdTimer = 0;
game.update = function () {
if (isHoldingDown) {
holdTimer++;
if (holdTimer > 10) {
character.duck();
}
} else {
holdTimer = 0;
}
updateGame();
};