/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var LightOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('lightOrb', {
anchorX: 0.5,
anchorY: 0.5
});
self.glowTimer = 0;
self.update = function () {
// Pulsing glow effect
self.glowTimer += 0.15;
var glow = 0.7 + Math.sin(self.glowTimer) * 0.3;
orbGraphics.alpha = glow;
orbGraphics.scaleX = glow;
orbGraphics.scaleY = glow;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var lightRadius = self.attachAsset('lightRadius', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.1
});
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.lightLevel = 1.0;
self.speed = 8;
self.update = function () {
// Gradually dim the light over time
self.lightLevel -= 0.001;
if (self.lightLevel < 0.2) {
self.lightLevel = 0.2;
}
lightRadius.alpha = self.lightLevel * 0.15;
var scale = self.lightLevel * 1.5;
lightRadius.scaleX = scale;
lightRadius.scaleY = scale;
};
self.addLight = function () {
self.lightLevel += 0.2;
if (self.lightLevel > 1.0) {
self.lightLevel = 1.0;
}
};
return self;
});
var Shadow = Container.expand(function () {
var self = Container.call(this);
var shadowGraphics = self.attachAsset('shadow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
self.speed = 2;
self.targetX = 0;
self.targetY = 0;
self.changeDirectionTimer = 0;
self.update = function () {
// Move towards player with some randomness
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
// Add some random movement
moveX += (Math.random() - 0.5) * 2;
moveY += (Math.random() - 0.5) * 2;
self.x += moveX;
self.y += moveY;
}
// Occasionally change direction randomly
self.changeDirectionTimer++;
if (self.changeDirectionTimer > 60) {
self.changeDirectionTimer = 0;
if (Math.random() < 0.3) {
self.targetX = Math.random() * 2048;
self.targetY = Math.random() * 2732;
}
}
// Pulse effect for creepy appearance
shadowGraphics.alpha = 0.6 + Math.sin(LK.ticks * 0.1) * 0.2;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game variables
var player;
var shadows = [];
var lightOrbs = [];
var shadowSpawnTimer = 0;
var orbSpawnTimer = 0;
var gameTime = 0;
var dragActive = false;
// UI Elements
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var timeTxt = new Text2('Time: 0s', {
size: 60,
fill: 0xFFFFFF
});
timeTxt.anchor.set(0, 0);
timeTxt.x = 200;
timeTxt.y = 50;
LK.gui.topLeft.addChild(timeTxt);
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
// Spawn initial shadows
for (var i = 0; i < 3; i++) {
spawnShadow();
}
// Spawn initial orbs
for (var i = 0; i < 2; i++) {
spawnLightOrb();
}
// Start ambient music
LK.playMusic('ambient');
function spawnShadow() {
var shadow = new Shadow();
// Spawn from screen edges
var edge = Math.floor(Math.random() * 4);
switch (edge) {
case 0:
// Top
shadow.x = Math.random() * 2048;
shadow.y = -50;
break;
case 1:
// Right
shadow.x = 2098;
shadow.y = Math.random() * 2732;
break;
case 2:
// Bottom
shadow.x = Math.random() * 2048;
shadow.y = 2782;
break;
case 3:
// Left
shadow.x = -50;
shadow.y = Math.random() * 2732;
break;
}
shadow.targetX = player.x;
shadow.targetY = player.y;
shadow.speed = 1.5 + Math.random() * 2;
shadows.push(shadow);
game.addChild(shadow);
}
function spawnLightOrb() {
var orb = new LightOrb();
orb.x = 200 + Math.random() * 1648; // Keep away from edges
orb.y = 200 + Math.random() * 2332;
lightOrbs.push(orb);
game.addChild(orb);
}
function handleMove(x, y, obj) {
if (dragActive) {
player.x = x;
player.y = y;
// Keep player within bounds
if (player.x < 50) player.x = 50;
if (player.x > 1998) player.x = 1998;
if (player.y < 50) player.y = 50;
if (player.y > 2682) player.y = 2682;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragActive = true;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragActive = false;
};
game.update = function () {
gameTime++;
// Update time display
var seconds = Math.floor(gameTime / 60);
timeTxt.setText('Time: ' + seconds + 's');
// Update shadow targets to follow player
for (var i = 0; i < shadows.length; i++) {
shadows[i].targetX = player.x;
shadows[i].targetY = player.y;
// Increase shadow speed over time
if (gameTime % 600 === 0) {
// Every 10 seconds
shadows[i].speed += 0.5;
}
}
// Spawn more shadows over time
shadowSpawnTimer++;
var spawnRate = Math.max(300 - Math.floor(gameTime / 100), 120); // Get faster over time
if (shadowSpawnTimer >= spawnRate) {
shadowSpawnTimer = 0;
spawnShadow();
}
// Spawn light orbs periodically
orbSpawnTimer++;
if (orbSpawnTimer >= 240) {
// Every 4 seconds
orbSpawnTimer = 0;
if (lightOrbs.length < 4) {
spawnLightOrb();
}
}
// Check shadow collisions
for (var i = shadows.length - 1; i >= 0; i--) {
var shadow = shadows[i];
if (player.intersects(shadow)) {
// Player death
LK.getSound('death').play();
LK.effects.flashScreen(0xff0000, 1500);
// Death animation
tween(player, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 1000,
onFinish: function onFinish() {
LK.showGameOver();
}
});
return;
}
}
// Check light orb collection
for (var i = lightOrbs.length - 1; i >= 0; i--) {
var orb = lightOrbs[i];
if (player.intersects(orb)) {
// Collect orb
LK.getSound('collect').play();
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
player.addLight();
// Flash orb before removing
tween(orb, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
orb.destroy();
}
});
lightOrbs.splice(i, 1);
}
}
// Remove shadows that are too far off screen
for (var i = shadows.length - 1; i >= 0; i--) {
var shadow = shadows[i];
if (shadow.x < -200 || shadow.x > 2248 || shadow.y < -200 || shadow.y > 2932) {
shadow.destroy();
shadows.splice(i, 1);
}
}
// Limit maximum shadows to prevent lag
if (shadows.length > 12) {
var oldestShadow = shadows.shift();
oldestShadow.destroy();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var LightOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('lightOrb', {
anchorX: 0.5,
anchorY: 0.5
});
self.glowTimer = 0;
self.update = function () {
// Pulsing glow effect
self.glowTimer += 0.15;
var glow = 0.7 + Math.sin(self.glowTimer) * 0.3;
orbGraphics.alpha = glow;
orbGraphics.scaleX = glow;
orbGraphics.scaleY = glow;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var lightRadius = self.attachAsset('lightRadius', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.1
});
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.lightLevel = 1.0;
self.speed = 8;
self.update = function () {
// Gradually dim the light over time
self.lightLevel -= 0.001;
if (self.lightLevel < 0.2) {
self.lightLevel = 0.2;
}
lightRadius.alpha = self.lightLevel * 0.15;
var scale = self.lightLevel * 1.5;
lightRadius.scaleX = scale;
lightRadius.scaleY = scale;
};
self.addLight = function () {
self.lightLevel += 0.2;
if (self.lightLevel > 1.0) {
self.lightLevel = 1.0;
}
};
return self;
});
var Shadow = Container.expand(function () {
var self = Container.call(this);
var shadowGraphics = self.attachAsset('shadow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
self.speed = 2;
self.targetX = 0;
self.targetY = 0;
self.changeDirectionTimer = 0;
self.update = function () {
// Move towards player with some randomness
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
// Add some random movement
moveX += (Math.random() - 0.5) * 2;
moveY += (Math.random() - 0.5) * 2;
self.x += moveX;
self.y += moveY;
}
// Occasionally change direction randomly
self.changeDirectionTimer++;
if (self.changeDirectionTimer > 60) {
self.changeDirectionTimer = 0;
if (Math.random() < 0.3) {
self.targetX = Math.random() * 2048;
self.targetY = Math.random() * 2732;
}
}
// Pulse effect for creepy appearance
shadowGraphics.alpha = 0.6 + Math.sin(LK.ticks * 0.1) * 0.2;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game variables
var player;
var shadows = [];
var lightOrbs = [];
var shadowSpawnTimer = 0;
var orbSpawnTimer = 0;
var gameTime = 0;
var dragActive = false;
// UI Elements
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var timeTxt = new Text2('Time: 0s', {
size: 60,
fill: 0xFFFFFF
});
timeTxt.anchor.set(0, 0);
timeTxt.x = 200;
timeTxt.y = 50;
LK.gui.topLeft.addChild(timeTxt);
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
// Spawn initial shadows
for (var i = 0; i < 3; i++) {
spawnShadow();
}
// Spawn initial orbs
for (var i = 0; i < 2; i++) {
spawnLightOrb();
}
// Start ambient music
LK.playMusic('ambient');
function spawnShadow() {
var shadow = new Shadow();
// Spawn from screen edges
var edge = Math.floor(Math.random() * 4);
switch (edge) {
case 0:
// Top
shadow.x = Math.random() * 2048;
shadow.y = -50;
break;
case 1:
// Right
shadow.x = 2098;
shadow.y = Math.random() * 2732;
break;
case 2:
// Bottom
shadow.x = Math.random() * 2048;
shadow.y = 2782;
break;
case 3:
// Left
shadow.x = -50;
shadow.y = Math.random() * 2732;
break;
}
shadow.targetX = player.x;
shadow.targetY = player.y;
shadow.speed = 1.5 + Math.random() * 2;
shadows.push(shadow);
game.addChild(shadow);
}
function spawnLightOrb() {
var orb = new LightOrb();
orb.x = 200 + Math.random() * 1648; // Keep away from edges
orb.y = 200 + Math.random() * 2332;
lightOrbs.push(orb);
game.addChild(orb);
}
function handleMove(x, y, obj) {
if (dragActive) {
player.x = x;
player.y = y;
// Keep player within bounds
if (player.x < 50) player.x = 50;
if (player.x > 1998) player.x = 1998;
if (player.y < 50) player.y = 50;
if (player.y > 2682) player.y = 2682;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragActive = true;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragActive = false;
};
game.update = function () {
gameTime++;
// Update time display
var seconds = Math.floor(gameTime / 60);
timeTxt.setText('Time: ' + seconds + 's');
// Update shadow targets to follow player
for (var i = 0; i < shadows.length; i++) {
shadows[i].targetX = player.x;
shadows[i].targetY = player.y;
// Increase shadow speed over time
if (gameTime % 600 === 0) {
// Every 10 seconds
shadows[i].speed += 0.5;
}
}
// Spawn more shadows over time
shadowSpawnTimer++;
var spawnRate = Math.max(300 - Math.floor(gameTime / 100), 120); // Get faster over time
if (shadowSpawnTimer >= spawnRate) {
shadowSpawnTimer = 0;
spawnShadow();
}
// Spawn light orbs periodically
orbSpawnTimer++;
if (orbSpawnTimer >= 240) {
// Every 4 seconds
orbSpawnTimer = 0;
if (lightOrbs.length < 4) {
spawnLightOrb();
}
}
// Check shadow collisions
for (var i = shadows.length - 1; i >= 0; i--) {
var shadow = shadows[i];
if (player.intersects(shadow)) {
// Player death
LK.getSound('death').play();
LK.effects.flashScreen(0xff0000, 1500);
// Death animation
tween(player, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 1000,
onFinish: function onFinish() {
LK.showGameOver();
}
});
return;
}
}
// Check light orb collection
for (var i = lightOrbs.length - 1; i >= 0; i--) {
var orb = lightOrbs[i];
if (player.intersects(orb)) {
// Collect orb
LK.getSound('collect').play();
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
player.addLight();
// Flash orb before removing
tween(orb, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
orb.destroy();
}
});
lightOrbs.splice(i, 1);
}
}
// Remove shadows that are too far off screen
for (var i = shadows.length - 1; i >= 0; i--) {
var shadow = shadows[i];
if (shadow.x < -200 || shadow.x > 2248 || shadow.y < -200 || shadow.y > 2932) {
shadow.destroy();
shadows.splice(i, 1);
}
}
// Limit maximum shadows to prevent lag
if (shadows.length > 12) {
var oldestShadow = shadows.shift();
oldestShadow.destroy();
}
};
it’s sad and scared . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
make it a super scary skeleton. In-Game asset. 2d. High contrast. No shadows
it’s a coin. In-Game asset. 2d. High contrast. No shadows
make it shine affect. In-Game asset. 2d. High contrast. No shadows