/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = -4;
self.health = 10;
self.defeated = false;
self.attackTimer = 0;
self.takeDamage = function () {
self.health--;
LK.effects.flashObject(self, 0xff0000, 300);
if (self.health <= 0) {
self.defeated = true;
LK.setScore(LK.getScore() + 100);
}
};
self.update = function () {
if (!self.defeated) {
self.x += self.speed;
self.attackTimer++;
// Boss movement pattern
if (self.attackTimer % 120 === 0) {
self.y += Math.sin(self.attackTimer * 0.05) * 5;
}
}
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -8;
self.collected = false;
self.bobTimer = 0;
self.collect = function () {
if (!self.collected) {
self.collected = true;
LK.setScore(LK.getScore() + 5);
LK.getSound('coin').play();
self.alpha = 0;
}
};
self.update = function () {
self.x += self.speed;
self.bobTimer++;
coinGraphics.y = Math.sin(self.bobTimer * 0.2) * 10;
coinGraphics.rotation += 0.1;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = -8;
self.health = 1;
self.defeated = false;
self.takeDamage = function () {
self.health--;
if (self.health <= 0) {
self.defeated = true;
LK.effects.flashObject(self, 0xff0000, 200);
LK.setScore(LK.getScore() + 10);
}
};
self.update = function () {
if (!self.defeated) {
self.x += self.speed;
}
};
return self;
});
var Ground = Container.expand(function () {
var self = Container.call(this);
var groundGraphics = self.attachAsset('ground', {
anchorX: 0,
anchorY: 0
});
self.speed = -8;
self.update = function () {
self.x += self.speed;
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 1.0
});
self.isJumping = false;
self.jumpSpeed = 0;
self.groundY = 2500;
self.health = 3;
self.attackCooldown = 0;
self.powerUpTimer = 0;
self.hasPowerUp = false;
self.jump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.jumpSpeed = -25;
LK.getSound('jump').play();
}
};
self.attack = function () {
if (self.attackCooldown <= 0) {
self.attackCooldown = 20;
LK.getSound('attack').play();
// Flash hero blue for attack
LK.effects.flashObject(self, 0x00ffff, 300);
return true;
}
return false;
};
self.takeDamage = function () {
if (self.powerUpTimer > 0) return; // Invulnerable during power-up
self.health--;
LK.effects.flashObject(self, 0xff0000, 500);
LK.getSound('hit').play();
if (self.health <= 0) {
LK.showGameOver();
}
};
self.collectPowerUp = function () {
self.hasPowerUp = true;
self.powerUpTimer = 300; // 5 seconds at 60fps
heroGraphics.tint = 0xffff00; // Yellow tint for power-up
LK.getSound('powerup').play();
};
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
if (self.powerUpTimer > 0) {
self.powerUpTimer--;
if (self.powerUpTimer <= 0) {
self.hasPowerUp = false;
heroGraphics.tint = 0xffffff; // Reset tint
}
}
// Handle jumping physics
if (self.isJumping) {
self.jumpSpeed += 1.2; // Gravity
self.y += self.jumpSpeed;
if (self.y >= self.groundY) {
self.y = self.groundY;
self.isJumping = false;
self.jumpSpeed = 0;
}
}
};
return self;
});
var Pit = Container.expand(function () {
var self = Container.call(this);
var pitGraphics = self.attachAsset('pit', {
anchorX: 0,
anchorY: 0
});
self.speed = -8;
self.update = function () {
self.x += self.speed;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -8;
self.collected = false;
self.pulseTimer = 0;
self.collect = function () {
if (!self.collected) {
self.collected = true;
self.alpha = 0;
}
};
self.update = function () {
self.x += self.speed;
self.pulseTimer++;
var scale = 1 + Math.sin(self.pulseTimer * 0.3) * 0.3;
powerUpGraphics.scaleX = scale;
powerUpGraphics.scaleY = scale;
powerUpGraphics.rotation += 0.15;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Game variables
var hero;
var groundPieces = [];
var pits = [];
var enemies = [];
var bosses = [];
var coins = [];
var powerUps = [];
var gameSpeed = 8;
var spawnTimer = 0;
var levelDistance = 0;
var currentLevel = 1;
// Initialize hero
hero = game.addChild(new Hero());
hero.x = 300;
hero.y = hero.groundY;
// Create UI
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
var healthTxt = new Text2('Health: 3', {
size: 80,
fill: 0xFF0000
});
healthTxt.anchor.set(0, 0);
healthTxt.y = 100;
LK.gui.topRight.addChild(healthTxt);
var levelTxt = new Text2('Level: 1', {
size: 80,
fill: 0x00FF00
});
levelTxt.anchor.set(0, 0);
levelTxt.y = 200;
LK.gui.topRight.addChild(levelTxt);
// Initialize ground
function createGroundPiece(x) {
var ground = game.addChild(new Ground());
ground.x = x;
ground.y = 2560;
groundPieces.push(ground);
return ground;
}
// Create initial ground
for (var i = 0; i < 15; i++) {
createGroundPiece(i * 200);
}
function spawnPit(x) {
var pit = game.addChild(new Pit());
pit.x = x;
pit.y = 2560;
pits.push(pit);
}
function spawnEnemy(x) {
var enemy = game.addChild(new Enemy());
enemy.x = x;
enemy.y = hero.groundY;
enemies.push(enemy);
}
function spawnBoss(x) {
var boss = game.addChild(new Boss());
boss.x = x;
boss.y = hero.groundY;
bosses.push(boss);
}
function spawnCoin(x) {
var coin = game.addChild(new Coin());
coin.x = x;
coin.y = hero.groundY - 150;
coins.push(coin);
}
function spawnPowerUp(x) {
var powerUp = game.addChild(new PowerUp());
powerUp.x = x;
powerUp.y = hero.groundY - 200;
powerUps.push(powerUp);
}
// Game input handling
game.down = function (x, y, obj) {
var heroPos = hero.getBounds();
var tapPos = {
x: x,
y: y
};
// Check if tapping on or near an enemy to attack
var attacked = false;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (!enemy.defeated && enemy.x > hero.x - 100 && enemy.x < hero.x + 200) {
if (hero.attack()) {
enemy.takeDamage();
attacked = true;
break;
}
}
}
// Check boss attacks
for (var i = 0; i < bosses.length; i++) {
var boss = bosses[i];
if (!boss.defeated && boss.x > hero.x - 150 && boss.x < hero.x + 300) {
if (hero.attack()) {
boss.takeDamage();
attacked = true;
break;
}
}
}
// If not attacking, jump
if (!attacked) {
hero.jump();
}
};
game.update = function () {
spawnTimer++;
levelDistance += gameSpeed;
// Update UI
scoreTxt.setText('Score: ' + LK.getScore());
healthTxt.setText('Health: ' + hero.health);
levelTxt.setText('Level: ' + currentLevel);
// Level progression
if (levelDistance > currentLevel * 3000) {
currentLevel++;
gameSpeed += 1;
}
// Spawn objects
if (spawnTimer % 60 === 0) {
var spawnX = 2200;
var rand = Math.random();
if (rand < 0.1) {
spawnPit(spawnX);
} else if (rand < 0.25) {
spawnEnemy(spawnX);
} else if (rand < 0.35) {
spawnCoin(spawnX);
} else if (rand < 0.4) {
spawnPowerUp(spawnX);
}
// Boss spawn every 1000 points
if (LK.getScore() > 0 && LK.getScore() % 1000 === 0 && spawnTimer % 600 === 0) {
spawnBoss(spawnX + 200);
}
}
// Spawn new ground pieces
if (spawnTimer % 30 === 0) {
var lastGround = groundPieces[groundPieces.length - 1];
if (lastGround && lastGround.x < 2500) {
createGroundPiece(lastGround.x + 200);
}
}
// Clean up off-screen ground pieces
for (var i = groundPieces.length - 1; i >= 0; i--) {
var ground = groundPieces[i];
if (ground.x < -300) {
ground.destroy();
groundPieces.splice(i, 1);
}
}
// Handle pits
for (var i = pits.length - 1; i >= 0; i--) {
var pit = pits[i];
// Check if hero falls into pit
if (hero.intersects(pit) && hero.y >= pit.y - 30) {
hero.takeDamage();
}
// Clean up off-screen pits
if (pit.x < -200) {
pit.destroy();
pits.splice(i, 1);
}
}
// Handle enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Check collision with hero
if (!enemy.defeated && hero.intersects(enemy)) {
hero.takeDamage();
enemy.defeated = true;
}
// Clean up off-screen or defeated enemies
if (enemy.x < -100 || enemy.defeated) {
if (enemy.defeated && enemy.alpha > 0) {
tween(enemy, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
enemy.destroy();
}
});
} else if (enemy.x < -100) {
enemy.destroy();
}
enemies.splice(i, 1);
}
}
// Handle bosses
for (var i = bosses.length - 1; i >= 0; i--) {
var boss = bosses[i];
// Check collision with hero
if (!boss.defeated && hero.intersects(boss)) {
hero.takeDamage();
}
// Clean up off-screen or defeated bosses
if (boss.x < -200 || boss.defeated) {
if (boss.defeated && boss.alpha > 0) {
tween(boss, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
boss.destroy();
}
});
} else if (boss.x < -200) {
boss.destroy();
}
bosses.splice(i, 1);
}
}
// Handle coins
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
// Check collection
if (!coin.collected && hero.intersects(coin)) {
coin.collect();
}
// Clean up off-screen or collected coins
if (coin.x < -100 || coin.collected) {
coin.destroy();
coins.splice(i, 1);
}
}
// Handle power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
// Check collection
if (!powerUp.collected && hero.intersects(powerUp)) {
powerUp.collect();
hero.collectPowerUp();
}
// Clean up off-screen or collected power-ups
if (powerUp.x < -100 || powerUp.collected) {
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Win condition - reaching high score
if (LK.getScore() >= 5000) {
LK.showYouWin();
}
};
// Start background music
LK.playMusic('bgmusic'); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = -4;
self.health = 10;
self.defeated = false;
self.attackTimer = 0;
self.takeDamage = function () {
self.health--;
LK.effects.flashObject(self, 0xff0000, 300);
if (self.health <= 0) {
self.defeated = true;
LK.setScore(LK.getScore() + 100);
}
};
self.update = function () {
if (!self.defeated) {
self.x += self.speed;
self.attackTimer++;
// Boss movement pattern
if (self.attackTimer % 120 === 0) {
self.y += Math.sin(self.attackTimer * 0.05) * 5;
}
}
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -8;
self.collected = false;
self.bobTimer = 0;
self.collect = function () {
if (!self.collected) {
self.collected = true;
LK.setScore(LK.getScore() + 5);
LK.getSound('coin').play();
self.alpha = 0;
}
};
self.update = function () {
self.x += self.speed;
self.bobTimer++;
coinGraphics.y = Math.sin(self.bobTimer * 0.2) * 10;
coinGraphics.rotation += 0.1;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = -8;
self.health = 1;
self.defeated = false;
self.takeDamage = function () {
self.health--;
if (self.health <= 0) {
self.defeated = true;
LK.effects.flashObject(self, 0xff0000, 200);
LK.setScore(LK.getScore() + 10);
}
};
self.update = function () {
if (!self.defeated) {
self.x += self.speed;
}
};
return self;
});
var Ground = Container.expand(function () {
var self = Container.call(this);
var groundGraphics = self.attachAsset('ground', {
anchorX: 0,
anchorY: 0
});
self.speed = -8;
self.update = function () {
self.x += self.speed;
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 1.0
});
self.isJumping = false;
self.jumpSpeed = 0;
self.groundY = 2500;
self.health = 3;
self.attackCooldown = 0;
self.powerUpTimer = 0;
self.hasPowerUp = false;
self.jump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.jumpSpeed = -25;
LK.getSound('jump').play();
}
};
self.attack = function () {
if (self.attackCooldown <= 0) {
self.attackCooldown = 20;
LK.getSound('attack').play();
// Flash hero blue for attack
LK.effects.flashObject(self, 0x00ffff, 300);
return true;
}
return false;
};
self.takeDamage = function () {
if (self.powerUpTimer > 0) return; // Invulnerable during power-up
self.health--;
LK.effects.flashObject(self, 0xff0000, 500);
LK.getSound('hit').play();
if (self.health <= 0) {
LK.showGameOver();
}
};
self.collectPowerUp = function () {
self.hasPowerUp = true;
self.powerUpTimer = 300; // 5 seconds at 60fps
heroGraphics.tint = 0xffff00; // Yellow tint for power-up
LK.getSound('powerup').play();
};
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
if (self.powerUpTimer > 0) {
self.powerUpTimer--;
if (self.powerUpTimer <= 0) {
self.hasPowerUp = false;
heroGraphics.tint = 0xffffff; // Reset tint
}
}
// Handle jumping physics
if (self.isJumping) {
self.jumpSpeed += 1.2; // Gravity
self.y += self.jumpSpeed;
if (self.y >= self.groundY) {
self.y = self.groundY;
self.isJumping = false;
self.jumpSpeed = 0;
}
}
};
return self;
});
var Pit = Container.expand(function () {
var self = Container.call(this);
var pitGraphics = self.attachAsset('pit', {
anchorX: 0,
anchorY: 0
});
self.speed = -8;
self.update = function () {
self.x += self.speed;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -8;
self.collected = false;
self.pulseTimer = 0;
self.collect = function () {
if (!self.collected) {
self.collected = true;
self.alpha = 0;
}
};
self.update = function () {
self.x += self.speed;
self.pulseTimer++;
var scale = 1 + Math.sin(self.pulseTimer * 0.3) * 0.3;
powerUpGraphics.scaleX = scale;
powerUpGraphics.scaleY = scale;
powerUpGraphics.rotation += 0.15;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Game variables
var hero;
var groundPieces = [];
var pits = [];
var enemies = [];
var bosses = [];
var coins = [];
var powerUps = [];
var gameSpeed = 8;
var spawnTimer = 0;
var levelDistance = 0;
var currentLevel = 1;
// Initialize hero
hero = game.addChild(new Hero());
hero.x = 300;
hero.y = hero.groundY;
// Create UI
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
var healthTxt = new Text2('Health: 3', {
size: 80,
fill: 0xFF0000
});
healthTxt.anchor.set(0, 0);
healthTxt.y = 100;
LK.gui.topRight.addChild(healthTxt);
var levelTxt = new Text2('Level: 1', {
size: 80,
fill: 0x00FF00
});
levelTxt.anchor.set(0, 0);
levelTxt.y = 200;
LK.gui.topRight.addChild(levelTxt);
// Initialize ground
function createGroundPiece(x) {
var ground = game.addChild(new Ground());
ground.x = x;
ground.y = 2560;
groundPieces.push(ground);
return ground;
}
// Create initial ground
for (var i = 0; i < 15; i++) {
createGroundPiece(i * 200);
}
function spawnPit(x) {
var pit = game.addChild(new Pit());
pit.x = x;
pit.y = 2560;
pits.push(pit);
}
function spawnEnemy(x) {
var enemy = game.addChild(new Enemy());
enemy.x = x;
enemy.y = hero.groundY;
enemies.push(enemy);
}
function spawnBoss(x) {
var boss = game.addChild(new Boss());
boss.x = x;
boss.y = hero.groundY;
bosses.push(boss);
}
function spawnCoin(x) {
var coin = game.addChild(new Coin());
coin.x = x;
coin.y = hero.groundY - 150;
coins.push(coin);
}
function spawnPowerUp(x) {
var powerUp = game.addChild(new PowerUp());
powerUp.x = x;
powerUp.y = hero.groundY - 200;
powerUps.push(powerUp);
}
// Game input handling
game.down = function (x, y, obj) {
var heroPos = hero.getBounds();
var tapPos = {
x: x,
y: y
};
// Check if tapping on or near an enemy to attack
var attacked = false;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (!enemy.defeated && enemy.x > hero.x - 100 && enemy.x < hero.x + 200) {
if (hero.attack()) {
enemy.takeDamage();
attacked = true;
break;
}
}
}
// Check boss attacks
for (var i = 0; i < bosses.length; i++) {
var boss = bosses[i];
if (!boss.defeated && boss.x > hero.x - 150 && boss.x < hero.x + 300) {
if (hero.attack()) {
boss.takeDamage();
attacked = true;
break;
}
}
}
// If not attacking, jump
if (!attacked) {
hero.jump();
}
};
game.update = function () {
spawnTimer++;
levelDistance += gameSpeed;
// Update UI
scoreTxt.setText('Score: ' + LK.getScore());
healthTxt.setText('Health: ' + hero.health);
levelTxt.setText('Level: ' + currentLevel);
// Level progression
if (levelDistance > currentLevel * 3000) {
currentLevel++;
gameSpeed += 1;
}
// Spawn objects
if (spawnTimer % 60 === 0) {
var spawnX = 2200;
var rand = Math.random();
if (rand < 0.1) {
spawnPit(spawnX);
} else if (rand < 0.25) {
spawnEnemy(spawnX);
} else if (rand < 0.35) {
spawnCoin(spawnX);
} else if (rand < 0.4) {
spawnPowerUp(spawnX);
}
// Boss spawn every 1000 points
if (LK.getScore() > 0 && LK.getScore() % 1000 === 0 && spawnTimer % 600 === 0) {
spawnBoss(spawnX + 200);
}
}
// Spawn new ground pieces
if (spawnTimer % 30 === 0) {
var lastGround = groundPieces[groundPieces.length - 1];
if (lastGround && lastGround.x < 2500) {
createGroundPiece(lastGround.x + 200);
}
}
// Clean up off-screen ground pieces
for (var i = groundPieces.length - 1; i >= 0; i--) {
var ground = groundPieces[i];
if (ground.x < -300) {
ground.destroy();
groundPieces.splice(i, 1);
}
}
// Handle pits
for (var i = pits.length - 1; i >= 0; i--) {
var pit = pits[i];
// Check if hero falls into pit
if (hero.intersects(pit) && hero.y >= pit.y - 30) {
hero.takeDamage();
}
// Clean up off-screen pits
if (pit.x < -200) {
pit.destroy();
pits.splice(i, 1);
}
}
// Handle enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Check collision with hero
if (!enemy.defeated && hero.intersects(enemy)) {
hero.takeDamage();
enemy.defeated = true;
}
// Clean up off-screen or defeated enemies
if (enemy.x < -100 || enemy.defeated) {
if (enemy.defeated && enemy.alpha > 0) {
tween(enemy, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
enemy.destroy();
}
});
} else if (enemy.x < -100) {
enemy.destroy();
}
enemies.splice(i, 1);
}
}
// Handle bosses
for (var i = bosses.length - 1; i >= 0; i--) {
var boss = bosses[i];
// Check collision with hero
if (!boss.defeated && hero.intersects(boss)) {
hero.takeDamage();
}
// Clean up off-screen or defeated bosses
if (boss.x < -200 || boss.defeated) {
if (boss.defeated && boss.alpha > 0) {
tween(boss, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
boss.destroy();
}
});
} else if (boss.x < -200) {
boss.destroy();
}
bosses.splice(i, 1);
}
}
// Handle coins
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
// Check collection
if (!coin.collected && hero.intersects(coin)) {
coin.collect();
}
// Clean up off-screen or collected coins
if (coin.x < -100 || coin.collected) {
coin.destroy();
coins.splice(i, 1);
}
}
// Handle power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
// Check collection
if (!powerUp.collected && hero.intersects(powerUp)) {
powerUp.collect();
hero.collectPowerUp();
}
// Clean up off-screen or collected power-ups
if (powerUp.x < -100 || powerUp.collected) {
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Win condition - reaching high score
if (LK.getScore() >= 5000) {
LK.showYouWin();
}
};
// Start background music
LK.playMusic('bgmusic');