/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.bobOffset = Math.random() * Math.PI * 2;
self.collect = function () {
if (self.collected) return;
self.collected = true;
coinsCollected++;
LK.setScore(LK.getScore() + 10);
// Animate collection
tween(self, {
scaleX: 0,
scaleY: 0
}, {
duration: 300
});
tween(coinGraphics, {
tint: 0xFFFFFF
}, {
duration: 300
});
LK.getSound('coinCollect').play();
};
self.update = function () {
if (!self.collected) {
// Gentle bobbing animation
coinGraphics.y = Math.sin(LK.ticks * 0.1 + self.bobOffset) * 5;
coinGraphics.rotation += 0.02;
}
};
return self;
});
var Dragon = Container.expand(function () {
var self = Container.call(this);
var dragonGraphics = self.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.maxHealth = 3;
self.invulnerable = false;
self.invulnerabilityTime = 0;
self.takeDamage = function () {
if (self.invulnerable) return false;
self.health--;
self.invulnerable = true;
self.invulnerabilityTime = 120; // 2 seconds at 60fps
// Flash red when taking damage
tween(dragonGraphics, {
tint: 0xFF0000
}, {
duration: 200
});
tween(dragonGraphics, {
tint: 0xFFFFFF
}, {
duration: 200
});
LK.getSound('damage').play();
return true;
};
self.update = function () {
if (self.invulnerable) {
self.invulnerabilityTime--;
if (self.invulnerabilityTime <= 0) {
self.invulnerable = false;
}
// Flicker during invulnerability
dragonGraphics.alpha = self.invulnerabilityTime % 10 < 5 ? 0.5 : 1.0;
} else {
dragonGraphics.alpha = 1.0;
}
};
return self;
});
var Exit = Container.expand(function () {
var self = Container.call(this);
var exitGraphics = self.attachAsset('exit', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Pulsing animation for exit
var pulse = Math.sin(LK.ticks * 0.05) * 0.1 + 1;
exitGraphics.scaleX = pulse;
exitGraphics.scaleY = pulse;
};
return self;
});
var Knight = Container.expand(function () {
var self = Container.call(this);
var knightGraphics = self.attachAsset('knight', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1;
self.direction = Math.random() * Math.PI * 2;
self.patrolRadius = 200;
self.startX = 0;
self.startY = 0;
self.chaseRadius = 150;
self.isChasing = false;
self.setPatrolCenter = function (x, y) {
self.startX = x;
self.startY = y;
};
self.update = function () {
var dx = dragon.x - self.x;
var dy = dragon.y - self.y;
var distanceToPlayer = Math.sqrt(dx * dx + dy * dy);
if (distanceToPlayer < self.chaseRadius) {
// Chase the dragon
self.isChasing = true;
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed * 1.5;
self.y += Math.sin(angle) * self.speed * 1.5;
knightGraphics.tint = 0xFF6666; // Angry red tint when chasing
} else {
// Patrol behavior
self.isChasing = false;
knightGraphics.tint = 0xFFFFFF;
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
var distanceFromStart = Math.sqrt((self.x - self.startX) * (self.x - self.startX) + (self.y - self.startY) * (self.y - self.startY));
if (distanceFromStart > self.patrolRadius) {
self.direction = Math.atan2(self.startY - self.y, self.startX - self.x);
}
if (Math.random() < 0.02) {
self.direction += (Math.random() - 0.5) * 0.5;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F2F
});
/****
* Game Code
****/
// Game state variables
var dragon;
var knights = [];
var coins = [];
var exit;
var coinsCollected = 0;
var totalHoard = storage.totalHoard || 0;
var currentLevel = 1;
var dragNode = null;
// UI Elements
var healthText = new Text2('Health: 3', {
size: 60,
fill: 0xFF0000
});
healthText.anchor.set(0, 0);
LK.gui.topRight.addChild(healthText);
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var hoardText = new Text2('Hoard: ' + totalHoard, {
size: 50,
fill: 0xFFD700
});
hoardText.anchor.set(0, 1);
LK.gui.bottomLeft.addChild(hoardText);
// Initialize level
function initializeLevel() {
// Clear existing objects
knights.forEach(function (knight) {
knight.destroy();
});
coins.forEach(function (coin) {
coin.destroy();
});
if (exit) exit.destroy();
knights = [];
coins = [];
coinsCollected = 0;
// Create dragon
dragon = game.addChild(new Dragon());
dragon.x = 200;
dragon.y = 2400; // Start near bottom
// Create exit at top
exit = game.addChild(new Exit());
exit.x = 1024;
exit.y = 300;
// Create coins scattered throughout level
for (var i = 0; i < 15; i++) {
var coin = game.addChild(new Coin());
coin.x = 300 + Math.random() * 1400;
coin.y = 500 + Math.random() * 1800;
coins.push(coin);
}
// Create knights
var knightCount = Math.min(3 + currentLevel, 8);
for (var i = 0; i < knightCount; i++) {
var knight = game.addChild(new Knight());
knight.x = 400 + Math.random() * 1200;
knight.y = 600 + Math.random() * 1600;
knight.setPatrolCenter(knight.x, knight.y);
knights.push(knight);
}
}
// Handle movement
function handleMove(x, y, obj) {
if (dragNode && dragon.health > 0) {
dragon.x = x;
dragon.y = y;
// Keep dragon within bounds
dragon.x = Math.max(60, Math.min(dragon.x, 1988));
dragon.y = Math.max(60, Math.min(dragon.y, 2672));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (dragon.health > 0) {
dragNode = dragon;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game update loop
game.update = function () {
if (dragon.health <= 0) return;
// Update UI
healthText.setText('Health: ' + dragon.health);
scoreText.setText('Score: ' + LK.getScore());
hoardText.setText('Hoard: ' + totalHoard);
// Check coin collection
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (!coin.collected && dragon.intersects(coin)) {
coin.collect();
}
// Remove collected coins after animation
if (coin.collected && coin.scaleX <= 0) {
coin.destroy();
coins.splice(i, 1);
}
}
// Check knight collisions
for (var i = 0; i < knights.length; i++) {
var knight = knights[i];
if (dragon.intersects(knight)) {
if (dragon.takeDamage()) {
if (dragon.health <= 0) {
LK.showGameOver();
return;
}
}
}
}
// Check exit collision
if (dragon.intersects(exit)) {
// Level complete
totalHoard += coinsCollected;
storage.totalHoard = totalHoard;
LK.getSound('levelComplete').play();
if (currentLevel >= 3) {
LK.showYouWin();
} else {
currentLevel++;
// Flash screen green for level complete
LK.effects.flashScreen(0x00FF00, 1000);
// Initialize next level after delay
LK.setTimeout(function () {
initializeLevel();
}, 1500);
}
}
};
// Initialize the first level
initializeLevel(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.bobOffset = Math.random() * Math.PI * 2;
self.collect = function () {
if (self.collected) return;
self.collected = true;
coinsCollected++;
LK.setScore(LK.getScore() + 10);
// Animate collection
tween(self, {
scaleX: 0,
scaleY: 0
}, {
duration: 300
});
tween(coinGraphics, {
tint: 0xFFFFFF
}, {
duration: 300
});
LK.getSound('coinCollect').play();
};
self.update = function () {
if (!self.collected) {
// Gentle bobbing animation
coinGraphics.y = Math.sin(LK.ticks * 0.1 + self.bobOffset) * 5;
coinGraphics.rotation += 0.02;
}
};
return self;
});
var Dragon = Container.expand(function () {
var self = Container.call(this);
var dragonGraphics = self.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.maxHealth = 3;
self.invulnerable = false;
self.invulnerabilityTime = 0;
self.takeDamage = function () {
if (self.invulnerable) return false;
self.health--;
self.invulnerable = true;
self.invulnerabilityTime = 120; // 2 seconds at 60fps
// Flash red when taking damage
tween(dragonGraphics, {
tint: 0xFF0000
}, {
duration: 200
});
tween(dragonGraphics, {
tint: 0xFFFFFF
}, {
duration: 200
});
LK.getSound('damage').play();
return true;
};
self.update = function () {
if (self.invulnerable) {
self.invulnerabilityTime--;
if (self.invulnerabilityTime <= 0) {
self.invulnerable = false;
}
// Flicker during invulnerability
dragonGraphics.alpha = self.invulnerabilityTime % 10 < 5 ? 0.5 : 1.0;
} else {
dragonGraphics.alpha = 1.0;
}
};
return self;
});
var Exit = Container.expand(function () {
var self = Container.call(this);
var exitGraphics = self.attachAsset('exit', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Pulsing animation for exit
var pulse = Math.sin(LK.ticks * 0.05) * 0.1 + 1;
exitGraphics.scaleX = pulse;
exitGraphics.scaleY = pulse;
};
return self;
});
var Knight = Container.expand(function () {
var self = Container.call(this);
var knightGraphics = self.attachAsset('knight', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1;
self.direction = Math.random() * Math.PI * 2;
self.patrolRadius = 200;
self.startX = 0;
self.startY = 0;
self.chaseRadius = 150;
self.isChasing = false;
self.setPatrolCenter = function (x, y) {
self.startX = x;
self.startY = y;
};
self.update = function () {
var dx = dragon.x - self.x;
var dy = dragon.y - self.y;
var distanceToPlayer = Math.sqrt(dx * dx + dy * dy);
if (distanceToPlayer < self.chaseRadius) {
// Chase the dragon
self.isChasing = true;
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed * 1.5;
self.y += Math.sin(angle) * self.speed * 1.5;
knightGraphics.tint = 0xFF6666; // Angry red tint when chasing
} else {
// Patrol behavior
self.isChasing = false;
knightGraphics.tint = 0xFFFFFF;
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
var distanceFromStart = Math.sqrt((self.x - self.startX) * (self.x - self.startX) + (self.y - self.startY) * (self.y - self.startY));
if (distanceFromStart > self.patrolRadius) {
self.direction = Math.atan2(self.startY - self.y, self.startX - self.x);
}
if (Math.random() < 0.02) {
self.direction += (Math.random() - 0.5) * 0.5;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F2F
});
/****
* Game Code
****/
// Game state variables
var dragon;
var knights = [];
var coins = [];
var exit;
var coinsCollected = 0;
var totalHoard = storage.totalHoard || 0;
var currentLevel = 1;
var dragNode = null;
// UI Elements
var healthText = new Text2('Health: 3', {
size: 60,
fill: 0xFF0000
});
healthText.anchor.set(0, 0);
LK.gui.topRight.addChild(healthText);
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var hoardText = new Text2('Hoard: ' + totalHoard, {
size: 50,
fill: 0xFFD700
});
hoardText.anchor.set(0, 1);
LK.gui.bottomLeft.addChild(hoardText);
// Initialize level
function initializeLevel() {
// Clear existing objects
knights.forEach(function (knight) {
knight.destroy();
});
coins.forEach(function (coin) {
coin.destroy();
});
if (exit) exit.destroy();
knights = [];
coins = [];
coinsCollected = 0;
// Create dragon
dragon = game.addChild(new Dragon());
dragon.x = 200;
dragon.y = 2400; // Start near bottom
// Create exit at top
exit = game.addChild(new Exit());
exit.x = 1024;
exit.y = 300;
// Create coins scattered throughout level
for (var i = 0; i < 15; i++) {
var coin = game.addChild(new Coin());
coin.x = 300 + Math.random() * 1400;
coin.y = 500 + Math.random() * 1800;
coins.push(coin);
}
// Create knights
var knightCount = Math.min(3 + currentLevel, 8);
for (var i = 0; i < knightCount; i++) {
var knight = game.addChild(new Knight());
knight.x = 400 + Math.random() * 1200;
knight.y = 600 + Math.random() * 1600;
knight.setPatrolCenter(knight.x, knight.y);
knights.push(knight);
}
}
// Handle movement
function handleMove(x, y, obj) {
if (dragNode && dragon.health > 0) {
dragon.x = x;
dragon.y = y;
// Keep dragon within bounds
dragon.x = Math.max(60, Math.min(dragon.x, 1988));
dragon.y = Math.max(60, Math.min(dragon.y, 2672));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (dragon.health > 0) {
dragNode = dragon;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game update loop
game.update = function () {
if (dragon.health <= 0) return;
// Update UI
healthText.setText('Health: ' + dragon.health);
scoreText.setText('Score: ' + LK.getScore());
hoardText.setText('Hoard: ' + totalHoard);
// Check coin collection
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (!coin.collected && dragon.intersects(coin)) {
coin.collect();
}
// Remove collected coins after animation
if (coin.collected && coin.scaleX <= 0) {
coin.destroy();
coins.splice(i, 1);
}
}
// Check knight collisions
for (var i = 0; i < knights.length; i++) {
var knight = knights[i];
if (dragon.intersects(knight)) {
if (dragon.takeDamage()) {
if (dragon.health <= 0) {
LK.showGameOver();
return;
}
}
}
}
// Check exit collision
if (dragon.intersects(exit)) {
// Level complete
totalHoard += coinsCollected;
storage.totalHoard = totalHoard;
LK.getSound('levelComplete').play();
if (currentLevel >= 3) {
LK.showYouWin();
} else {
currentLevel++;
// Flash screen green for level complete
LK.effects.flashScreen(0x00FF00, 1000);
// Initialize next level after delay
LK.setTimeout(function () {
initializeLevel();
}, 1500);
}
}
};
// Initialize the first level
initializeLevel();