/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.throwCooldown = 0;
self.throwRate = 120; // Start throwing every 2 seconds
self.update = function () {
self.throwCooldown--;
if (self.throwCooldown <= 0) {
self.throwSlipper();
self.throwCooldown = self.throwRate;
}
};
self.throwSlipper = function () {
var slipper = new Slipper();
slipper.x = self.x;
slipper.y = self.y;
// Calculate direction toward player
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
slipper.velocityX = dx / distance * 6;
slipper.velocityY = dy / distance * 6;
slippers.push(slipper);
game.addChild(slipper);
LK.getSound('throw').play();
};
self.setThrowRate = function (rate) {
self.throwRate = rate;
};
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 () {
// Check if player reached exit
if (self.intersects(player)) {
if (hasKey) {
self.onReached();
} else {
// Flash red if no key
LK.effects.flashObject(self, 0xff0000, 300);
}
} else {
// Add visual feedback when player is close to exit
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 300) {
// Make exit glow when player is near - green if has key, red if not
var color = hasKey ? 0x00ff00 : 0xff0000;
exitGraphics.tint = color;
exitGraphics.alpha = 0.7 + Math.sin(LK.ticks * 0.1) * 0.3;
} else {
exitGraphics.tint = 0xFFFFFF;
exitGraphics.alpha = 1;
}
}
};
self.onReached = function () {
LK.getSound('complete').play();
LK.setScore(LK.getScore() + 100);
scoreTxt.setText(LK.getScore());
// Add door opening animation
tween(exitGraphics, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, 500, function () {
// Check if score has reached 70000 before advancing section
if (LK.getScore() >= 70000) {
currentSection++;
// Change background when reaching score threshold
game.setBackgroundColor(0x2c3e50);
if (currentSection > maxSections) {
LK.showYouWin();
} else {
setupSection();
}
} else {
// If score hasn't reached 70000, restart current section
setupSection();
}
});
};
return self;
});
var Key = Container.expand(function () {
var self = Container.call(this);
var keyGraphics = self.attachAsset('slipper', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFFD700
});
keyGraphics.rotation = Math.PI / 4;
self.collected = false;
self.update = function () {
// Rotate key for visual effect
keyGraphics.rotation += 0.05;
// Bob up and down
self.y += Math.sin(LK.ticks * 0.1) * 0.5;
// Check if player collected key
if (self.intersects(player) && !self.collected) {
self.collected = true;
hasKey = true;
LK.effects.flashObject(self, 0xFFD700, 500);
LK.setScore(LK.getScore() + 50);
scoreTxt.setText(LK.getScore());
self.shouldRemove = true;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.speed = 8;
self.invulnerable = false;
self.invulnerableTime = 0;
self.update = function () {
if (self.invulnerable) {
self.invulnerableTime--;
if (self.invulnerableTime <= 0) {
self.invulnerable = false;
playerGraphics.alpha = 1;
} else {
playerGraphics.alpha = Math.sin(self.invulnerableTime * 0.3) * 0.5 + 0.5;
}
}
// Keep player within bounds
if (self.x < 40) self.x = 40;
if (self.x > 2008) self.x = 2008;
if (self.y < 40) self.y = 40;
if (self.y > 2692) self.y = 2692;
};
self.takeDamage = function () {
if (self.invulnerable) return;
self.health--;
self.invulnerable = true;
self.invulnerableTime = 120; // 2 seconds at 60fps
LK.getSound('hit').play();
LK.effects.flashObject(self, 0xff0000, 500);
if (self.health <= 0) {
LK.showGameOver();
}
};
return self;
});
var Slipper = Container.expand(function () {
var self = Container.call(this);
var slipperGraphics = self.attachAsset('slipper', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.lifetime = 300; // 5 seconds at 60fps
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.lifetime--;
// Remove if off screen or lifetime expired
if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832 || self.lifetime <= 0) {
self.shouldRemove = true;
}
// Check collision with walls
for (var i = 0; i < walls.length; i++) {
if (self.intersects(walls[i])) {
self.shouldRemove = true;
break;
}
}
// Check collision with player
if (self.intersects(player) && !player.invulnerable) {
player.takeDamage();
self.shouldRemove = true;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x34495e
});
/****
* Game Code
****/
var player;
var enemies = [];
var slippers = [];
var keys = [];
var walls = [];
var exit;
var currentSection = 1;
var maxSections = 5;
var dragNode = null;
var hasKey = false;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var healthTxt = new Text2('Health: 3', {
size: 60,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 120;
healthTxt.y = 120;
LK.gui.topLeft.addChild(healthTxt);
var sectionTxt = new Text2('Section: 1', {
size: 60,
fill: 0xFFFFFF
});
sectionTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(sectionTxt);
function setupSection() {
// Clear existing enemies and slippers
for (var i = 0; i < enemies.length; i++) {
enemies[i].destroy();
}
enemies = [];
for (var i = 0; i < slippers.length; i++) {
slippers[i].destroy();
}
slippers = [];
for (var i = 0; i < keys.length; i++) {
keys[i].destroy();
}
keys = [];
for (var i = 0; i < walls.length; i++) {
walls[i].destroy();
}
walls = [];
// Update UI
sectionTxt.setText('Section: ' + currentSection);
// Reset player position
player.x = 200;
player.y = 2600;
// Reset key status
hasKey = false;
// Create key for this section
var key = new Key();
key.x = 1000 + Math.random() * 600;
key.y = 1000 + Math.random() * 800;
keys.push(key);
game.addChild(key);
// Create exit
if (exit) {
exit.destroy();
}
exit = new Exit();
exit.x = 1800;
exit.y = 200;
game.addChild(exit);
// Add door entrance animation
var exitGraphics = exit.children[0];
exitGraphics.scaleX = 0.1;
exitGraphics.scaleY = 0.1;
exitGraphics.alpha = 0;
tween(exitGraphics, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, 800);
// Create enemies based on section
var enemyCount = Math.min(currentSection, 3);
for (var i = 0; i < enemyCount; i++) {
var enemy = new Enemy();
enemy.x = 400 + i * 600;
enemy.y = 400 + i * 300;
// Increase difficulty by reducing throw rate
var throwRate = Math.max(60, 120 - currentSection * 10);
enemy.setThrowRate(throwRate);
enemies.push(enemy);
game.addChild(enemy);
}
// Add some walls for cover
for (var i = 0; i < 3; i++) {
var wall = game.addChild(LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 600 + i * 400,
y: 1000 + i * 200,
scaleX: 3,
scaleY: 6
}));
walls.push(wall);
}
}
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
}
}
// Initialize game
player = new Player();
game.addChild(player);
setupSection();
// Event handlers
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = player;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
game.update = function () {
// Update health display
healthTxt.setText('Health: ' + player.health);
// Update slippers
for (var i = slippers.length - 1; i >= 0; i--) {
var slipper = slippers[i];
if (slipper.shouldRemove) {
slipper.destroy();
slippers.splice(i, 1);
}
}
// Update keys
for (var i = keys.length - 1; i >= 0; i--) {
var key = keys[i];
if (key.shouldRemove) {
key.destroy();
keys.splice(i, 1);
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.throwCooldown = 0;
self.throwRate = 120; // Start throwing every 2 seconds
self.update = function () {
self.throwCooldown--;
if (self.throwCooldown <= 0) {
self.throwSlipper();
self.throwCooldown = self.throwRate;
}
};
self.throwSlipper = function () {
var slipper = new Slipper();
slipper.x = self.x;
slipper.y = self.y;
// Calculate direction toward player
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
slipper.velocityX = dx / distance * 6;
slipper.velocityY = dy / distance * 6;
slippers.push(slipper);
game.addChild(slipper);
LK.getSound('throw').play();
};
self.setThrowRate = function (rate) {
self.throwRate = rate;
};
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 () {
// Check if player reached exit
if (self.intersects(player)) {
if (hasKey) {
self.onReached();
} else {
// Flash red if no key
LK.effects.flashObject(self, 0xff0000, 300);
}
} else {
// Add visual feedback when player is close to exit
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 300) {
// Make exit glow when player is near - green if has key, red if not
var color = hasKey ? 0x00ff00 : 0xff0000;
exitGraphics.tint = color;
exitGraphics.alpha = 0.7 + Math.sin(LK.ticks * 0.1) * 0.3;
} else {
exitGraphics.tint = 0xFFFFFF;
exitGraphics.alpha = 1;
}
}
};
self.onReached = function () {
LK.getSound('complete').play();
LK.setScore(LK.getScore() + 100);
scoreTxt.setText(LK.getScore());
// Add door opening animation
tween(exitGraphics, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, 500, function () {
// Check if score has reached 70000 before advancing section
if (LK.getScore() >= 70000) {
currentSection++;
// Change background when reaching score threshold
game.setBackgroundColor(0x2c3e50);
if (currentSection > maxSections) {
LK.showYouWin();
} else {
setupSection();
}
} else {
// If score hasn't reached 70000, restart current section
setupSection();
}
});
};
return self;
});
var Key = Container.expand(function () {
var self = Container.call(this);
var keyGraphics = self.attachAsset('slipper', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFFD700
});
keyGraphics.rotation = Math.PI / 4;
self.collected = false;
self.update = function () {
// Rotate key for visual effect
keyGraphics.rotation += 0.05;
// Bob up and down
self.y += Math.sin(LK.ticks * 0.1) * 0.5;
// Check if player collected key
if (self.intersects(player) && !self.collected) {
self.collected = true;
hasKey = true;
LK.effects.flashObject(self, 0xFFD700, 500);
LK.setScore(LK.getScore() + 50);
scoreTxt.setText(LK.getScore());
self.shouldRemove = true;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.speed = 8;
self.invulnerable = false;
self.invulnerableTime = 0;
self.update = function () {
if (self.invulnerable) {
self.invulnerableTime--;
if (self.invulnerableTime <= 0) {
self.invulnerable = false;
playerGraphics.alpha = 1;
} else {
playerGraphics.alpha = Math.sin(self.invulnerableTime * 0.3) * 0.5 + 0.5;
}
}
// Keep player within bounds
if (self.x < 40) self.x = 40;
if (self.x > 2008) self.x = 2008;
if (self.y < 40) self.y = 40;
if (self.y > 2692) self.y = 2692;
};
self.takeDamage = function () {
if (self.invulnerable) return;
self.health--;
self.invulnerable = true;
self.invulnerableTime = 120; // 2 seconds at 60fps
LK.getSound('hit').play();
LK.effects.flashObject(self, 0xff0000, 500);
if (self.health <= 0) {
LK.showGameOver();
}
};
return self;
});
var Slipper = Container.expand(function () {
var self = Container.call(this);
var slipperGraphics = self.attachAsset('slipper', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.lifetime = 300; // 5 seconds at 60fps
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.lifetime--;
// Remove if off screen or lifetime expired
if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832 || self.lifetime <= 0) {
self.shouldRemove = true;
}
// Check collision with walls
for (var i = 0; i < walls.length; i++) {
if (self.intersects(walls[i])) {
self.shouldRemove = true;
break;
}
}
// Check collision with player
if (self.intersects(player) && !player.invulnerable) {
player.takeDamage();
self.shouldRemove = true;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x34495e
});
/****
* Game Code
****/
var player;
var enemies = [];
var slippers = [];
var keys = [];
var walls = [];
var exit;
var currentSection = 1;
var maxSections = 5;
var dragNode = null;
var hasKey = false;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var healthTxt = new Text2('Health: 3', {
size: 60,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 120;
healthTxt.y = 120;
LK.gui.topLeft.addChild(healthTxt);
var sectionTxt = new Text2('Section: 1', {
size: 60,
fill: 0xFFFFFF
});
sectionTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(sectionTxt);
function setupSection() {
// Clear existing enemies and slippers
for (var i = 0; i < enemies.length; i++) {
enemies[i].destroy();
}
enemies = [];
for (var i = 0; i < slippers.length; i++) {
slippers[i].destroy();
}
slippers = [];
for (var i = 0; i < keys.length; i++) {
keys[i].destroy();
}
keys = [];
for (var i = 0; i < walls.length; i++) {
walls[i].destroy();
}
walls = [];
// Update UI
sectionTxt.setText('Section: ' + currentSection);
// Reset player position
player.x = 200;
player.y = 2600;
// Reset key status
hasKey = false;
// Create key for this section
var key = new Key();
key.x = 1000 + Math.random() * 600;
key.y = 1000 + Math.random() * 800;
keys.push(key);
game.addChild(key);
// Create exit
if (exit) {
exit.destroy();
}
exit = new Exit();
exit.x = 1800;
exit.y = 200;
game.addChild(exit);
// Add door entrance animation
var exitGraphics = exit.children[0];
exitGraphics.scaleX = 0.1;
exitGraphics.scaleY = 0.1;
exitGraphics.alpha = 0;
tween(exitGraphics, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, 800);
// Create enemies based on section
var enemyCount = Math.min(currentSection, 3);
for (var i = 0; i < enemyCount; i++) {
var enemy = new Enemy();
enemy.x = 400 + i * 600;
enemy.y = 400 + i * 300;
// Increase difficulty by reducing throw rate
var throwRate = Math.max(60, 120 - currentSection * 10);
enemy.setThrowRate(throwRate);
enemies.push(enemy);
game.addChild(enemy);
}
// Add some walls for cover
for (var i = 0; i < 3; i++) {
var wall = game.addChild(LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 600 + i * 400,
y: 1000 + i * 200,
scaleX: 3,
scaleY: 6
}));
walls.push(wall);
}
}
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
}
}
// Initialize game
player = new Player();
game.addChild(player);
setupSection();
// Event handlers
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = player;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
game.update = function () {
// Update health display
healthTxt.setText('Health: ' + player.health);
// Update slippers
for (var i = slippers.length - 1; i >= 0; i--) {
var slipper = slippers[i];
if (slipper.shouldRemove) {
slipper.destroy();
slippers.splice(i, 1);
}
}
// Update keys
for (var i = keys.length - 1; i >= 0; i--) {
var key = keys[i];
if (key.shouldRemove) {
key.destroy();
keys.splice(i, 1);
}
}
};
pixel art sliper. In-Game asset. 2d. High contrast. No shadows
pixel art kid. In-Game asset. 2d. High contrast. No shadows
pixel art wall. In-Game asset. 2d. High contrast. No shadows
pixel art mom. In-Game asset. 2d. High contrast. No shadows
Pixel Art Door. In-Game asset. 2d. High contrast. No shadows