/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('darkBall', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.speed = 2; self.update = function () { // Follow player with tracking that depends on current world if (player) { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { // Increase tracking force in world 2 var trackingForce = currentWorld === 2 ? 0.3 : 0.1; self.velocityX += dx / distance * trackingForce; self.velocityY += dy / distance * trackingForce; } } self.x += self.velocityX; self.y += self.velocityY; // Bounce off walls if (self.x <= 50 || self.x >= 1998) { self.velocityX = -self.velocityX; LK.getSound('bounce').play(); } if (self.y <= 50 || self.y >= 2682) { self.velocityY = -self.velocityY; LK.getSound('bounce').play(); } // Keep ball within bounds if (self.x < 50) { self.x = 50; } if (self.x > 1998) { self.x = 1998; } if (self.y < 50) { self.y = 50; } if (self.y > 2682) { self.y = 2682; } }; return self; }); var Blood = Container.expand(function () { var self = Container.call(this); var bloodGraphics = self.attachAsset('blood', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; return self; }); var Portal = Container.expand(function () { var self = Container.call(this); var portalGraphics = self.attachAsset('portal', { anchorX: 0.5, anchorY: 0.5 }); // Portal pulsing animation self.pulseTime = 0; self.update = function () { self.pulseTime += 0.1; portalGraphics.scaleX = 1 + Math.sin(self.pulseTime) * 0.2; portalGraphics.scaleY = 1 + Math.sin(self.pulseTime) * 0.2; portalGraphics.alpha = 0.8 + Math.sin(self.pulseTime) * 0.2; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ // Game variables var player = null; var ball = null; var bloods = []; var totalBloods = 8; var collectedCount = 0; var dragNode = null; var playerHealth = 3; var maxHealth = 3; var currentWorld = 1; var maxWorlds = 2; var portal = null; var worldColors = [0x1a1a1a, 0x2d1b69]; // Dark gray for world 1, dark purple for world 2 var bloodTapCount = 0; var pinheadTriggered = false; // UI Elements var scoreTxt = new Text2('Blood: 0/' + totalBloods, { size: 100, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); // Add touch handler for Blood text scoreTxt.down = function (x, y, obj) { if (!pinheadTriggered) { bloodTapCount++; if (bloodTapCount >= 13) { pinheadTriggered = true; // Create scary image screen var scaryScreen = new Container(); scaryScreen.x = 0; scaryScreen.y = 0; // Add dark overlay var overlay = LK.getAsset('deathOverlay', { width: 2048, height: 2732, color: 0x000000, shape: 'box', alpha: 0.9 }); scaryScreen.addChild(overlay); // Add scary image var scaryImg = LK.getAsset('scaryImage', { anchorX: 0.5, anchorY: 0.5 }); scaryImg.x = 1024; scaryImg.y = 1366; scaryScreen.addChild(scaryImg); // Add to game game.addChild(scaryScreen); // Remove after 3 seconds LK.setTimeout(function () { scaryScreen.destroy(); }, 3000); } } }; LK.gui.top.addChild(scoreTxt); var healthTxt = new Text2('Health: ' + playerHealth + '/' + maxHealth, { size: 80, fill: 0xFF4444 }); healthTxt.anchor.set(0, 0); healthTxt.x = 120; healthTxt.y = 150; LK.gui.topLeft.addChild(healthTxt); var worldTxt = new Text2('World: ' + currentWorld + '/' + maxWorlds, { size: 80, fill: 0x9932cc }); worldTxt.anchor.set(1, 0); worldTxt.x = -120; worldTxt.y = 150; LK.gui.topRight.addChild(worldTxt); // Create player player = game.addChild(new Player()); player.x = 1024; player.y = 1366; // Create ball ball = game.addChild(new Ball()); ball.x = 500; ball.y = 500; // Set random initial velocity var angle = Math.random() * Math.PI * 2; ball.velocityX = Math.cos(angle) * ball.speed; ball.velocityY = Math.sin(angle) * ball.speed; // Function to create portal function createPortal() { if (portal) { portal.destroy(); } portal = game.addChild(new Portal()); // Place portal in a safe location portal.x = 1500 + Math.random() * 400; portal.y = 300 + Math.random() * 400; } // Function to create world function createWorld() { // Clear existing bloods for (var i = bloods.length - 1; i >= 0; i--) { bloods[i].destroy(); } bloods = []; collectedCount = 0; // Update background color based on world game.setBackgroundColor(worldColors[currentWorld - 1]); // Create bloods for current world var bloodsInWorld = currentWorld === 1 ? totalBloods : totalBloods + 2; // More bloods in world 2 for (var i = 0; i < bloodsInWorld; i++) { var blood = game.addChild(new Blood()); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { blood.x = 100 + Math.random() * 1848; blood.y = 100 + Math.random() * 2532; // Check distance from ball var distToBall = Math.sqrt(Math.pow(blood.x - ball.x, 2) + Math.pow(blood.y - ball.y, 2)); // Check distance from player var distToPlayer = Math.sqrt(Math.pow(blood.x - player.x, 2) + Math.pow(blood.y - player.y, 2)); if (distToBall > 200 && distToPlayer > 150) { validPosition = true; } attempts++; } bloods.push(blood); } // Create portal if not in final world if (currentWorld < maxWorlds) { createPortal(); } // Update UI scoreTxt.setText('Blood: ' + collectedCount + '/' + bloodsInWorld); worldTxt.setText('World: ' + currentWorld + '/' + maxWorlds); totalBloods = bloodsInWorld; } // Initialize first world createWorld(); // Movement handler function handleMove(x, y, obj) { if (dragNode) { // Keep player within bounds var newX = Math.max(40, Math.min(2008, x)); var newY = Math.max(40, Math.min(2692, y)); dragNode.x = newX; dragNode.y = newY; } } // Touch-based movement variables var touchActive = false; var touchStartX = 0; var touchStartY = 0; // Event handlers for touch movement game.move = function (x, y, obj) { if (touchActive) { touchStartX = x; touchStartY = y; } }; game.down = function (x, y, obj) { touchActive = true; touchStartX = x; touchStartY = y; }; game.up = function (x, y, obj) { touchActive = false; }; // Game update loop game.update = function () { // Handle touch movement if (touchActive) { // Move player based on touch input var moveX = (touchStartX - player.x) * 0.1; var moveY = (touchStartY - player.y) * 0.1; // Keep player within bounds var newX = Math.max(40, Math.min(2008, player.x + moveX)); var newY = Math.max(40, Math.min(2692, player.y + moveY)); player.x = newX; player.y = newY; } // Check collision with ball if (player.intersects(ball)) { if (player.lastColliding === undefined) { player.lastColliding = false; } if (!player.lastColliding) { // First frame of collision playerHealth--; healthTxt.setText('Health: ' + playerHealth + '/' + maxHealth); LK.effects.flashObject(player, 0xFF0000, 500); LK.effects.flashScreen(0xFF4444, 300); if (playerHealth <= 0) { // Create a container for the death screen var deathScreen = new Container(); deathScreen.x = 0; deathScreen.y = 0; // Add full black overlay to hide camera/face var overlay = LK.getAsset('deathOverlay', { width: 2048, height: 2732, color: 0x000000, shape: 'box', alpha: 1.0 }); deathScreen.addChild(overlay); // Add scary image var scaryImg = LK.getAsset('scaryImage', { anchorX: 0.5, anchorY: 0.5 }); scaryImg.x = 1024; scaryImg.y = 1366; deathScreen.addChild(scaryImg); // Add death text var deathText = new Text2('YOU DIED', { size: 150, fill: 0xFF0000 }); deathText.anchor.set(0.5, 0.5); deathText.x = 1024; deathText.y = 800; deathScreen.addChild(deathText); // Add the death screen to the game game.addChild(deathScreen); // Show game over after a delay LK.setTimeout(function () { LK.showGameOver(); }, 3000); return; } } player.lastColliding = true; } else { player.lastColliding = false; } // Check portal collision if (portal && player.intersects(portal)) { if (player.lastPortalColliding === undefined) { player.lastPortalColliding = false; } if (!player.lastPortalColliding && collectedCount >= totalBloods) { // All bloods collected, can use portal currentWorld++; if (currentWorld > maxWorlds) { LK.showYouWin(); return; } LK.getSound('portal').play(); LK.effects.flashScreen(0x9932cc, 800); createWorld(); // Reset player position player.x = 1024; player.y = 1366; } else if (!player.lastPortalColliding && collectedCount < totalBloods) { // Not all bloods collected, show feedback LK.effects.flashObject(portal, 0xFF0000, 500); } player.lastPortalColliding = true; } else { player.lastPortalColliding = false; } // Check blood collection for (var i = bloods.length - 1; i >= 0; i--) { var blood = bloods[i]; if (!blood.collected && player.intersects(blood)) { blood.collected = true; blood.destroy(); bloods.splice(i, 1); collectedCount++; LK.getSound('collect').play(); LK.effects.flashObject(player, 0x00FF00, 300); // Update score scoreTxt.setText('Blood: ' + collectedCount + '/' + totalBloods); // Check win condition for final world if (collectedCount >= totalBloods && currentWorld >= maxWorlds) { LK.showYouWin(); return; } } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('darkBall', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.speed = 2;
self.update = function () {
// Follow player with tracking that depends on current world
if (player) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
// Increase tracking force in world 2
var trackingForce = currentWorld === 2 ? 0.3 : 0.1;
self.velocityX += dx / distance * trackingForce;
self.velocityY += dy / distance * trackingForce;
}
}
self.x += self.velocityX;
self.y += self.velocityY;
// Bounce off walls
if (self.x <= 50 || self.x >= 1998) {
self.velocityX = -self.velocityX;
LK.getSound('bounce').play();
}
if (self.y <= 50 || self.y >= 2682) {
self.velocityY = -self.velocityY;
LK.getSound('bounce').play();
}
// Keep ball within bounds
if (self.x < 50) {
self.x = 50;
}
if (self.x > 1998) {
self.x = 1998;
}
if (self.y < 50) {
self.y = 50;
}
if (self.y > 2682) {
self.y = 2682;
}
};
return self;
});
var Blood = Container.expand(function () {
var self = Container.call(this);
var bloodGraphics = self.attachAsset('blood', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
return self;
});
var Portal = Container.expand(function () {
var self = Container.call(this);
var portalGraphics = self.attachAsset('portal', {
anchorX: 0.5,
anchorY: 0.5
});
// Portal pulsing animation
self.pulseTime = 0;
self.update = function () {
self.pulseTime += 0.1;
portalGraphics.scaleX = 1 + Math.sin(self.pulseTime) * 0.2;
portalGraphics.scaleY = 1 + Math.sin(self.pulseTime) * 0.2;
portalGraphics.alpha = 0.8 + Math.sin(self.pulseTime) * 0.2;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game variables
var player = null;
var ball = null;
var bloods = [];
var totalBloods = 8;
var collectedCount = 0;
var dragNode = null;
var playerHealth = 3;
var maxHealth = 3;
var currentWorld = 1;
var maxWorlds = 2;
var portal = null;
var worldColors = [0x1a1a1a, 0x2d1b69]; // Dark gray for world 1, dark purple for world 2
var bloodTapCount = 0;
var pinheadTriggered = false;
// UI Elements
var scoreTxt = new Text2('Blood: 0/' + totalBloods, {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
// Add touch handler for Blood text
scoreTxt.down = function (x, y, obj) {
if (!pinheadTriggered) {
bloodTapCount++;
if (bloodTapCount >= 13) {
pinheadTriggered = true;
// Create scary image screen
var scaryScreen = new Container();
scaryScreen.x = 0;
scaryScreen.y = 0;
// Add dark overlay
var overlay = LK.getAsset('deathOverlay', {
width: 2048,
height: 2732,
color: 0x000000,
shape: 'box',
alpha: 0.9
});
scaryScreen.addChild(overlay);
// Add scary image
var scaryImg = LK.getAsset('scaryImage', {
anchorX: 0.5,
anchorY: 0.5
});
scaryImg.x = 1024;
scaryImg.y = 1366;
scaryScreen.addChild(scaryImg);
// Add to game
game.addChild(scaryScreen);
// Remove after 3 seconds
LK.setTimeout(function () {
scaryScreen.destroy();
}, 3000);
}
}
};
LK.gui.top.addChild(scoreTxt);
var healthTxt = new Text2('Health: ' + playerHealth + '/' + maxHealth, {
size: 80,
fill: 0xFF4444
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 120;
healthTxt.y = 150;
LK.gui.topLeft.addChild(healthTxt);
var worldTxt = new Text2('World: ' + currentWorld + '/' + maxWorlds, {
size: 80,
fill: 0x9932cc
});
worldTxt.anchor.set(1, 0);
worldTxt.x = -120;
worldTxt.y = 150;
LK.gui.topRight.addChild(worldTxt);
// Create player
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
// Create ball
ball = game.addChild(new Ball());
ball.x = 500;
ball.y = 500;
// Set random initial velocity
var angle = Math.random() * Math.PI * 2;
ball.velocityX = Math.cos(angle) * ball.speed;
ball.velocityY = Math.sin(angle) * ball.speed;
// Function to create portal
function createPortal() {
if (portal) {
portal.destroy();
}
portal = game.addChild(new Portal());
// Place portal in a safe location
portal.x = 1500 + Math.random() * 400;
portal.y = 300 + Math.random() * 400;
}
// Function to create world
function createWorld() {
// Clear existing bloods
for (var i = bloods.length - 1; i >= 0; i--) {
bloods[i].destroy();
}
bloods = [];
collectedCount = 0;
// Update background color based on world
game.setBackgroundColor(worldColors[currentWorld - 1]);
// Create bloods for current world
var bloodsInWorld = currentWorld === 1 ? totalBloods : totalBloods + 2; // More bloods in world 2
for (var i = 0; i < bloodsInWorld; i++) {
var blood = game.addChild(new Blood());
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 50) {
blood.x = 100 + Math.random() * 1848;
blood.y = 100 + Math.random() * 2532;
// Check distance from ball
var distToBall = Math.sqrt(Math.pow(blood.x - ball.x, 2) + Math.pow(blood.y - ball.y, 2));
// Check distance from player
var distToPlayer = Math.sqrt(Math.pow(blood.x - player.x, 2) + Math.pow(blood.y - player.y, 2));
if (distToBall > 200 && distToPlayer > 150) {
validPosition = true;
}
attempts++;
}
bloods.push(blood);
}
// Create portal if not in final world
if (currentWorld < maxWorlds) {
createPortal();
}
// Update UI
scoreTxt.setText('Blood: ' + collectedCount + '/' + bloodsInWorld);
worldTxt.setText('World: ' + currentWorld + '/' + maxWorlds);
totalBloods = bloodsInWorld;
}
// Initialize first world
createWorld();
// Movement handler
function handleMove(x, y, obj) {
if (dragNode) {
// Keep player within bounds
var newX = Math.max(40, Math.min(2008, x));
var newY = Math.max(40, Math.min(2692, y));
dragNode.x = newX;
dragNode.y = newY;
}
}
// Touch-based movement variables
var touchActive = false;
var touchStartX = 0;
var touchStartY = 0;
// Event handlers for touch movement
game.move = function (x, y, obj) {
if (touchActive) {
touchStartX = x;
touchStartY = y;
}
};
game.down = function (x, y, obj) {
touchActive = true;
touchStartX = x;
touchStartY = y;
};
game.up = function (x, y, obj) {
touchActive = false;
};
// Game update loop
game.update = function () {
// Handle touch movement
if (touchActive) {
// Move player based on touch input
var moveX = (touchStartX - player.x) * 0.1;
var moveY = (touchStartY - player.y) * 0.1;
// Keep player within bounds
var newX = Math.max(40, Math.min(2008, player.x + moveX));
var newY = Math.max(40, Math.min(2692, player.y + moveY));
player.x = newX;
player.y = newY;
}
// Check collision with ball
if (player.intersects(ball)) {
if (player.lastColliding === undefined) {
player.lastColliding = false;
}
if (!player.lastColliding) {
// First frame of collision
playerHealth--;
healthTxt.setText('Health: ' + playerHealth + '/' + maxHealth);
LK.effects.flashObject(player, 0xFF0000, 500);
LK.effects.flashScreen(0xFF4444, 300);
if (playerHealth <= 0) {
// Create a container for the death screen
var deathScreen = new Container();
deathScreen.x = 0;
deathScreen.y = 0;
// Add full black overlay to hide camera/face
var overlay = LK.getAsset('deathOverlay', {
width: 2048,
height: 2732,
color: 0x000000,
shape: 'box',
alpha: 1.0
});
deathScreen.addChild(overlay);
// Add scary image
var scaryImg = LK.getAsset('scaryImage', {
anchorX: 0.5,
anchorY: 0.5
});
scaryImg.x = 1024;
scaryImg.y = 1366;
deathScreen.addChild(scaryImg);
// Add death text
var deathText = new Text2('YOU DIED', {
size: 150,
fill: 0xFF0000
});
deathText.anchor.set(0.5, 0.5);
deathText.x = 1024;
deathText.y = 800;
deathScreen.addChild(deathText);
// Add the death screen to the game
game.addChild(deathScreen);
// Show game over after a delay
LK.setTimeout(function () {
LK.showGameOver();
}, 3000);
return;
}
}
player.lastColliding = true;
} else {
player.lastColliding = false;
}
// Check portal collision
if (portal && player.intersects(portal)) {
if (player.lastPortalColliding === undefined) {
player.lastPortalColliding = false;
}
if (!player.lastPortalColliding && collectedCount >= totalBloods) {
// All bloods collected, can use portal
currentWorld++;
if (currentWorld > maxWorlds) {
LK.showYouWin();
return;
}
LK.getSound('portal').play();
LK.effects.flashScreen(0x9932cc, 800);
createWorld();
// Reset player position
player.x = 1024;
player.y = 1366;
} else if (!player.lastPortalColliding && collectedCount < totalBloods) {
// Not all bloods collected, show feedback
LK.effects.flashObject(portal, 0xFF0000, 500);
}
player.lastPortalColliding = true;
} else {
player.lastPortalColliding = false;
}
// Check blood collection
for (var i = bloods.length - 1; i >= 0; i--) {
var blood = bloods[i];
if (!blood.collected && player.intersects(blood)) {
blood.collected = true;
blood.destroy();
bloods.splice(i, 1);
collectedCount++;
LK.getSound('collect').play();
LK.effects.flashObject(player, 0x00FF00, 300);
// Update score
scoreTxt.setText('Blood: ' + collectedCount + '/' + totalBloods);
// Check win condition for final world
if (collectedCount >= totalBloods && currentWorld >= maxWorlds) {
LK.showYouWin();
return;
}
}
}
};
freddy kruger pixel. In-Game asset. 2d. High contrast. No shadows
ketchup. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
pinhead hellraiser pixel art. In-Game asset. 2d. High contrast. No shadows
pinhead face. In-Game asset. 2d. High contrast. No shadows