/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Block = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = GAME_SPEED;
self.update = function () {
self.x -= self.speed;
};
return self;
});
var Cube = Container.expand(function () {
var self = Container.call(this);
var cubeGraphics = self.attachAsset('cube', {
anchorX: 0.5,
anchorY: 1.0
});
self.isJumping = false;
self.jumpSpeed = 0;
self.gravity = 0.8;
self.jumpPower = -18;
self.groundY = GROUND_Y;
self.jump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.jumpSpeed = self.jumpPower;
LK.getSound('jump').play();
}
};
self.update = function () {
if (self.isJumping) {
self.jumpSpeed += self.gravity;
self.y += self.jumpSpeed;
if (self.y >= self.groundY) {
self.y = self.groundY;
self.isJumping = false;
self.jumpSpeed = 0;
}
}
};
return self;
});
var Spike = Container.expand(function () {
var self = Container.call(this);
var spikeGraphics = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = GAME_SPEED;
self.update = function () {
self.x -= self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game states
var GAME_STATE_MENU = 0;
var GAME_STATE_PLAYING = 1;
var currentGameState = GAME_STATE_MENU;
var GAME_SPEED = 8;
var GROUND_Y = 2400;
var OBSTACLE_SPAWN_X = 2200;
var MIN_OBSTACLE_DISTANCE = 120;
var MAX_OBSTACLE_DISTANCE = 250;
game.setBackgroundColor(0x87CEEB);
// Create ground line visual reference
var groundLine = LK.getAsset('block', {
anchorX: 0,
anchorY: 0,
scaleX: 25,
scaleY: 0.3
});
groundLine.x = 0;
groundLine.y = GROUND_Y;
game.addChild(groundLine);
// Create cube
var cube = game.addChild(new Cube());
cube.x = 300;
cube.y = GROUND_Y;
// Create score display
var scoreTxt = new Text2('Distance: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(scoreTxt);
scoreTxt.visible = false; // Hidden during menu
// Create menu elements
var titleTxt = new Text2('GEOMETRY CUBE', {
size: 120,
fill: 0xFFFFFF
});
titleTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(titleTxt);
var playButton = new Text2('TAP TO PLAY', {
size: 80,
fill: 0x00FF00
});
playButton.anchor.set(0.5, 0.5);
playButton.y = 200;
LK.gui.center.addChild(playButton);
// Hide game elements during menu
cube.visible = false;
groundLine.visible = false;
// Game variables
var obstacles = [];
var gameDistance = 0;
var nextObstacleDistance = 300;
var gameRunning = true;
var difficultyTimer = 0;
// Input handling
game.down = function (x, y, obj) {
if (currentGameState === GAME_STATE_MENU) {
startGame();
} else if (gameRunning) {
cube.jump();
}
};
// Start game function
function startGame() {
currentGameState = GAME_STATE_PLAYING;
// Hide menu elements
titleTxt.visible = false;
playButton.visible = false;
// Show game elements
cube.visible = true;
groundLine.visible = true;
scoreTxt.visible = true;
// Start music
LK.playMusic('music01');
}
// Obstacle creation
function createRandomObstacle() {
var obstacleType = Math.random() < 0.6 ? 'spike' : 'block';
var obstacle;
if (obstacleType === 'spike') {
obstacle = new Spike();
} else {
obstacle = new Block();
}
obstacle.x = OBSTACLE_SPAWN_X;
obstacle.y = GROUND_Y;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Check collision between cube and obstacle
function checkCollision(cube, obstacle) {
var cubeLeft = cube.x - 40;
var cubeRight = cube.x + 40;
var cubeTop = cube.y - 80;
var cubeBottom = cube.y;
var obstacleLeft = obstacle.x - obstacle.children[0].width * 0.5;
var obstacleRight = obstacle.x + obstacle.children[0].width * 0.5;
var obstacleTop = obstacle.y - obstacle.children[0].height;
var obstacleBottom = obstacle.y;
// For spikes, reduce collision area to make them less deadly
if (obstacle instanceof Spike) {
obstacleLeft = obstacle.x - obstacle.children[0].width * 0.3;
obstacleRight = obstacle.x + obstacle.children[0].width * 0.3;
obstacleTop = obstacle.y - obstacle.children[0].height * 0.6;
}
return cubeLeft < obstacleRight && cubeRight > obstacleLeft && cubeTop < obstacleBottom && cubeBottom > obstacleTop;
}
// Game over
function handleGameOver() {
gameRunning = false;
LK.getSound('hit').play();
// Stop music
LK.stopMusic();
// Flash effect
LK.effects.flashScreen(0xFF0000, 800);
// Show game over after brief delay
LK.setTimeout(function () {
LK.showGameOver();
// Reset to menu state after game over
currentGameState = GAME_STATE_MENU;
// Show menu elements again
titleTxt.visible = true;
playButton.visible = true;
// Hide game elements
cube.visible = false;
groundLine.visible = false;
scoreTxt.visible = false;
// Reset game variables
gameDistance = 0;
nextObstacleDistance = 300;
gameRunning = true;
GAME_SPEED = 8;
difficultyTimer = 0;
// Clear obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].destroy();
}
obstacles = [];
// Reset cube position
cube.x = 300;
cube.y = GROUND_Y;
cube.isJumping = false;
cube.jumpSpeed = 0;
}, 500);
}
// Main game loop
game.update = function () {
if (currentGameState === GAME_STATE_MENU || !gameRunning) return;
// Update distance score
gameDistance += GAME_SPEED / 10;
scoreTxt.setText('Distance: ' + Math.floor(gameDistance));
LK.setScore(Math.floor(gameDistance));
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer % 1800 === 0) {
// Every 30 seconds at 60fps
GAME_SPEED += 1;
// Update obstacle speeds
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].speed = GAME_SPEED;
}
}
// Spawn obstacles
if (gameDistance >= nextObstacleDistance) {
createRandomObstacle();
nextObstacleDistance = gameDistance + MIN_OBSTACLE_DISTANCE + Math.random() * (MAX_OBSTACLE_DISTANCE - MIN_OBSTACLE_DISTANCE);
}
// Update and check obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
// Check collision with cube
if (checkCollision(cube, obstacle)) {
// Check if it's a block - only kill from front collision
if (obstacle instanceof Block) {
// For blocks, only trigger game over if cube hits from the front
// (cube's right side hits block's left side)
var cubeRight = cube.x + 40;
var blockLeft = obstacle.x - obstacle.children[0].width * 0.5;
if (cubeRight >= blockLeft && cube.x < obstacle.x) {
handleGameOver();
return;
}
} else {
// For spikes, collision from any angle is deadly
handleGameOver();
return;
}
}
// Remove off-screen obstacles
if (obstacle.x < -200) {
obstacle.destroy();
obstacles.splice(i, 1);
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Block = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = GAME_SPEED;
self.update = function () {
self.x -= self.speed;
};
return self;
});
var Cube = Container.expand(function () {
var self = Container.call(this);
var cubeGraphics = self.attachAsset('cube', {
anchorX: 0.5,
anchorY: 1.0
});
self.isJumping = false;
self.jumpSpeed = 0;
self.gravity = 0.8;
self.jumpPower = -18;
self.groundY = GROUND_Y;
self.jump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.jumpSpeed = self.jumpPower;
LK.getSound('jump').play();
}
};
self.update = function () {
if (self.isJumping) {
self.jumpSpeed += self.gravity;
self.y += self.jumpSpeed;
if (self.y >= self.groundY) {
self.y = self.groundY;
self.isJumping = false;
self.jumpSpeed = 0;
}
}
};
return self;
});
var Spike = Container.expand(function () {
var self = Container.call(this);
var spikeGraphics = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = GAME_SPEED;
self.update = function () {
self.x -= self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game states
var GAME_STATE_MENU = 0;
var GAME_STATE_PLAYING = 1;
var currentGameState = GAME_STATE_MENU;
var GAME_SPEED = 8;
var GROUND_Y = 2400;
var OBSTACLE_SPAWN_X = 2200;
var MIN_OBSTACLE_DISTANCE = 120;
var MAX_OBSTACLE_DISTANCE = 250;
game.setBackgroundColor(0x87CEEB);
// Create ground line visual reference
var groundLine = LK.getAsset('block', {
anchorX: 0,
anchorY: 0,
scaleX: 25,
scaleY: 0.3
});
groundLine.x = 0;
groundLine.y = GROUND_Y;
game.addChild(groundLine);
// Create cube
var cube = game.addChild(new Cube());
cube.x = 300;
cube.y = GROUND_Y;
// Create score display
var scoreTxt = new Text2('Distance: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(scoreTxt);
scoreTxt.visible = false; // Hidden during menu
// Create menu elements
var titleTxt = new Text2('GEOMETRY CUBE', {
size: 120,
fill: 0xFFFFFF
});
titleTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(titleTxt);
var playButton = new Text2('TAP TO PLAY', {
size: 80,
fill: 0x00FF00
});
playButton.anchor.set(0.5, 0.5);
playButton.y = 200;
LK.gui.center.addChild(playButton);
// Hide game elements during menu
cube.visible = false;
groundLine.visible = false;
// Game variables
var obstacles = [];
var gameDistance = 0;
var nextObstacleDistance = 300;
var gameRunning = true;
var difficultyTimer = 0;
// Input handling
game.down = function (x, y, obj) {
if (currentGameState === GAME_STATE_MENU) {
startGame();
} else if (gameRunning) {
cube.jump();
}
};
// Start game function
function startGame() {
currentGameState = GAME_STATE_PLAYING;
// Hide menu elements
titleTxt.visible = false;
playButton.visible = false;
// Show game elements
cube.visible = true;
groundLine.visible = true;
scoreTxt.visible = true;
// Start music
LK.playMusic('music01');
}
// Obstacle creation
function createRandomObstacle() {
var obstacleType = Math.random() < 0.6 ? 'spike' : 'block';
var obstacle;
if (obstacleType === 'spike') {
obstacle = new Spike();
} else {
obstacle = new Block();
}
obstacle.x = OBSTACLE_SPAWN_X;
obstacle.y = GROUND_Y;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Check collision between cube and obstacle
function checkCollision(cube, obstacle) {
var cubeLeft = cube.x - 40;
var cubeRight = cube.x + 40;
var cubeTop = cube.y - 80;
var cubeBottom = cube.y;
var obstacleLeft = obstacle.x - obstacle.children[0].width * 0.5;
var obstacleRight = obstacle.x + obstacle.children[0].width * 0.5;
var obstacleTop = obstacle.y - obstacle.children[0].height;
var obstacleBottom = obstacle.y;
// For spikes, reduce collision area to make them less deadly
if (obstacle instanceof Spike) {
obstacleLeft = obstacle.x - obstacle.children[0].width * 0.3;
obstacleRight = obstacle.x + obstacle.children[0].width * 0.3;
obstacleTop = obstacle.y - obstacle.children[0].height * 0.6;
}
return cubeLeft < obstacleRight && cubeRight > obstacleLeft && cubeTop < obstacleBottom && cubeBottom > obstacleTop;
}
// Game over
function handleGameOver() {
gameRunning = false;
LK.getSound('hit').play();
// Stop music
LK.stopMusic();
// Flash effect
LK.effects.flashScreen(0xFF0000, 800);
// Show game over after brief delay
LK.setTimeout(function () {
LK.showGameOver();
// Reset to menu state after game over
currentGameState = GAME_STATE_MENU;
// Show menu elements again
titleTxt.visible = true;
playButton.visible = true;
// Hide game elements
cube.visible = false;
groundLine.visible = false;
scoreTxt.visible = false;
// Reset game variables
gameDistance = 0;
nextObstacleDistance = 300;
gameRunning = true;
GAME_SPEED = 8;
difficultyTimer = 0;
// Clear obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].destroy();
}
obstacles = [];
// Reset cube position
cube.x = 300;
cube.y = GROUND_Y;
cube.isJumping = false;
cube.jumpSpeed = 0;
}, 500);
}
// Main game loop
game.update = function () {
if (currentGameState === GAME_STATE_MENU || !gameRunning) return;
// Update distance score
gameDistance += GAME_SPEED / 10;
scoreTxt.setText('Distance: ' + Math.floor(gameDistance));
LK.setScore(Math.floor(gameDistance));
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer % 1800 === 0) {
// Every 30 seconds at 60fps
GAME_SPEED += 1;
// Update obstacle speeds
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].speed = GAME_SPEED;
}
}
// Spawn obstacles
if (gameDistance >= nextObstacleDistance) {
createRandomObstacle();
nextObstacleDistance = gameDistance + MIN_OBSTACLE_DISTANCE + Math.random() * (MAX_OBSTACLE_DISTANCE - MIN_OBSTACLE_DISTANCE);
}
// Update and check obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
// Check collision with cube
if (checkCollision(cube, obstacle)) {
// Check if it's a block - only kill from front collision
if (obstacle instanceof Block) {
// For blocks, only trigger game over if cube hits from the front
// (cube's right side hits block's left side)
var cubeRight = cube.x + 40;
var blockLeft = obstacle.x - obstacle.children[0].width * 0.5;
if (cubeRight >= blockLeft && cube.x < obstacle.x) {
handleGameOver();
return;
}
} else {
// For spikes, collision from any angle is deadly
handleGameOver();
return;
}
}
// Remove off-screen obstacles
if (obstacle.x < -200) {
obstacle.destroy();
obstacles.splice(i, 1);
}
}
};