/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 20; self.direction = { x: 0, y: -1 }; // Default direction is upward self.update = function () { self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; }; return self; }); var CameraHead = Container.expand(function () { var self = Container.call(this); // Main camera body var body = self.attachAsset('cameraHead', { anchorX: 0.5, anchorY: 0.5 }); // Camera lens var lens = self.attachAsset('cameraLens', { anchorX: 0.5, anchorY: 0.5, y: -40 }); // Flash effect (initially invisible) var flashEffect = self.attachAsset('flash', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); // Public properties self.isShooting = false; self.shootCooldown = 0; self.flashEnabled = true; // Activate flash effect self.flash = function () { if (!self.flashEnabled) return; self.flashEnabled = false; flashEffect.alpha = 0.7; tween(flashEffect, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { self.flashEnabled = true; } }); }; self.update = function () { if (self.shootCooldown > 0) { self.shootCooldown--; } }; return self; }); var ToiletMonster = Container.expand(function () { var self = Container.call(this); // Toilet body var body = self.attachAsset('toiletBody', { anchorX: 0.5, anchorY: 0.5 }); // Toilet seat var seat = self.attachAsset('toiletSeat', { anchorX: 0.5, anchorY: 0.5, y: -30 }); // Human head var head = self.attachAsset('humanHead', { anchorX: 0.5, anchorY: 0.5, y: -70 }); // Public properties self.speed = 3; self.health = 1; self.points = 100; self.direction = { x: 0, y: 0 }; // Set target position to move towards self.setTarget = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.direction.x = dx / dist; self.direction.y = dy / dist; } }; // Take damage self.takeDamage = function () { self.health--; // Flash white tween(self, { alpha: 0.2 }, { duration: 100, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 100 }); } }); return self.health <= 0; }; self.update = function () { self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; // Wobble animation seat.rotation = Math.sin(LK.ticks / 10) * 0.1; head.rotation = Math.sin(LK.ticks / 15 + 1) * 0.05; }; return self; }); var BossToiletMonster = ToiletMonster.expand(function () { var self = ToiletMonster.call(this); // Make it bigger self.scale.set(1.5); // Override properties self.health = 3; self.speed = 2; self.points = 300; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x33aa88 }); /**** * Game Code ****/ // Game state variables var player; var bullets = []; var toilets = []; var score = 0; var spawnCooldown = 0; var gameLevel = 1; var enemiesKilled = 0; // UI elements var scoreTxt; var levelTxt; // Initialize game function initGame() { // Create player player = new CameraHead(); player.x = 2048 / 2; // Center horizontally player.y = 2732 / 2; // Center vertically game.addChild(player); // Create score text scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); // Create level text levelTxt = new Text2('Level: 1', { size: 80, fill: 0xFFFFFF }); levelTxt.anchor.set(1, 0); LK.gui.topLeft.addChild(levelTxt); levelTxt.x = 200; // Move away from very top left corner // Update score updateScore(0); // Play background music LK.playMusic('gameMusic'); } // Update score display function updateScore(points) { score += points; LK.setScore(score); scoreTxt.setText('Score: ' + score); } // Spawn a toilet monster function spawnToilet() { var toilet; // Spawn boss every 10 kills if (enemiesKilled > 0 && enemiesKilled % 10 === 0) { toilet = new BossToiletMonster(); } else { toilet = new ToiletMonster(); } // Adjust difficulty based on level toilet.speed += (gameLevel - 1) * 0.5; // Position toilet at random edge of screen var edge = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left switch (edge) { case 0: // Top toilet.x = Math.random() * 2048; toilet.y = -100; break; case 1: // Right toilet.x = 2048 + 100; toilet.y = Math.random() * 2732; break; case 2: // Bottom toilet.x = Math.random() * 2048; toilet.y = 2732 + 100; break; case 3: // Left toilet.x = -100; toilet.y = Math.random() * 2732; break; } // Set target to player toilet.setTarget(player.x, player.y); // Add to game toilets.push(toilet); game.addChild(toilet); } // Fire a bullet function fireBullet(targetX, targetY) { if (player.shootCooldown > 0) return; // Create bullet var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y - 50; // Calculate direction to target var dx = targetX - bullet.x; var dy = targetY - bullet.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { bullet.direction.x = dx / dist; bullet.direction.y = dy / dist; } // Add to game bullets.push(bullet); game.addChild(bullet); // Flash camera player.flash(); // Play sound LK.getSound('shoot').play(); // Set cooldown player.shootCooldown = 10; } // Main game update game.update = function () { // Update player player.update(); // Spawn toilets if (spawnCooldown <= 0) { spawnToilet(); spawnCooldown = Math.max(30, 120 - gameLevel * 10); // Spawn faster as level increases } else { spawnCooldown--; } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; bullet.update(); // Check if bullet is off screen if (bullet.x < -100 || bullet.x > 2148 || bullet.y < -100 || bullet.y > 2832) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check collision with toilets for (var j = toilets.length - 1; j >= 0; j--) { var toilet = toilets[j]; if (bullet.intersects(toilet)) { // Destroy bullet bullet.destroy(); bullets.splice(i, 1); // Damage toilet if (toilet.takeDamage()) { // If toilet is destroyed updateScore(toilet.points); LK.getSound('toiletDeath').play(); toilet.destroy(); toilets.splice(j, 1); enemiesKilled++; // Level up every 15 kills if (enemiesKilled % 15 === 0) { gameLevel++; levelTxt.setText('Level: ' + gameLevel); } } else { // Hit but not destroyed LK.getSound('hit').play(); } break; } } // Break loop if bullet was removed if (i >= bullets.length) { break; } } // Update toilets for (var i = toilets.length - 1; i >= 0; i--) { var toilet = toilets[i]; toilet.update(); // Check collision with player if (toilet.intersects(player)) { // Game over LK.getSound('playerDeath').play(); LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } // Periodically update target to follow player if (LK.ticks % 60 === 0) { toilet.setTarget(player.x, player.y); } } }; // Handle touch/mouse events var touchX = 0; var touchY = 0; var isDragging = false; game.down = function (x, y, obj) { touchX = x; touchY = y; // If clicked near player, start dragging var dx = x - player.x; var dy = y - player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 150) { isDragging = true; } else { // Fire bullet towards click position fireBullet(x, y); } }; game.move = function (x, y, obj) { touchX = x; touchY = y; // Move player if dragging if (isDragging) { player.x = x; // Restrict player to bottom third of screen player.y = Math.max(2732 / 3 * 2, Math.min(y, 2732 - 100)); } }; game.up = function (x, y, obj) { isDragging = false; }; // Initialize the game initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 20;
self.direction = {
x: 0,
y: -1
}; // Default direction is upward
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
};
return self;
});
var CameraHead = Container.expand(function () {
var self = Container.call(this);
// Main camera body
var body = self.attachAsset('cameraHead', {
anchorX: 0.5,
anchorY: 0.5
});
// Camera lens
var lens = self.attachAsset('cameraLens', {
anchorX: 0.5,
anchorY: 0.5,
y: -40
});
// Flash effect (initially invisible)
var flashEffect = self.attachAsset('flash', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
// Public properties
self.isShooting = false;
self.shootCooldown = 0;
self.flashEnabled = true;
// Activate flash effect
self.flash = function () {
if (!self.flashEnabled) return;
self.flashEnabled = false;
flashEffect.alpha = 0.7;
tween(flashEffect, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
self.flashEnabled = true;
}
});
};
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
return self;
});
var ToiletMonster = Container.expand(function () {
var self = Container.call(this);
// Toilet body
var body = self.attachAsset('toiletBody', {
anchorX: 0.5,
anchorY: 0.5
});
// Toilet seat
var seat = self.attachAsset('toiletSeat', {
anchorX: 0.5,
anchorY: 0.5,
y: -30
});
// Human head
var head = self.attachAsset('humanHead', {
anchorX: 0.5,
anchorY: 0.5,
y: -70
});
// Public properties
self.speed = 3;
self.health = 1;
self.points = 100;
self.direction = {
x: 0,
y: 0
};
// Set target position to move towards
self.setTarget = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.direction.x = dx / dist;
self.direction.y = dy / dist;
}
};
// Take damage
self.takeDamage = function () {
self.health--;
// Flash white
tween(self, {
alpha: 0.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
alpha: 1
}, {
duration: 100
});
}
});
return self.health <= 0;
};
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
// Wobble animation
seat.rotation = Math.sin(LK.ticks / 10) * 0.1;
head.rotation = Math.sin(LK.ticks / 15 + 1) * 0.05;
};
return self;
});
var BossToiletMonster = ToiletMonster.expand(function () {
var self = ToiletMonster.call(this);
// Make it bigger
self.scale.set(1.5);
// Override properties
self.health = 3;
self.speed = 2;
self.points = 300;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x33aa88
});
/****
* Game Code
****/
// Game state variables
var player;
var bullets = [];
var toilets = [];
var score = 0;
var spawnCooldown = 0;
var gameLevel = 1;
var enemiesKilled = 0;
// UI elements
var scoreTxt;
var levelTxt;
// Initialize game
function initGame() {
// Create player
player = new CameraHead();
player.x = 2048 / 2; // Center horizontally
player.y = 2732 / 2; // Center vertically
game.addChild(player);
// Create score text
scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
// Create level text
levelTxt = new Text2('Level: 1', {
size: 80,
fill: 0xFFFFFF
});
levelTxt.anchor.set(1, 0);
LK.gui.topLeft.addChild(levelTxt);
levelTxt.x = 200; // Move away from very top left corner
// Update score
updateScore(0);
// Play background music
LK.playMusic('gameMusic');
}
// Update score display
function updateScore(points) {
score += points;
LK.setScore(score);
scoreTxt.setText('Score: ' + score);
}
// Spawn a toilet monster
function spawnToilet() {
var toilet;
// Spawn boss every 10 kills
if (enemiesKilled > 0 && enemiesKilled % 10 === 0) {
toilet = new BossToiletMonster();
} else {
toilet = new ToiletMonster();
}
// Adjust difficulty based on level
toilet.speed += (gameLevel - 1) * 0.5;
// Position toilet at random edge of screen
var edge = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left
switch (edge) {
case 0:
// Top
toilet.x = Math.random() * 2048;
toilet.y = -100;
break;
case 1:
// Right
toilet.x = 2048 + 100;
toilet.y = Math.random() * 2732;
break;
case 2:
// Bottom
toilet.x = Math.random() * 2048;
toilet.y = 2732 + 100;
break;
case 3:
// Left
toilet.x = -100;
toilet.y = Math.random() * 2732;
break;
}
// Set target to player
toilet.setTarget(player.x, player.y);
// Add to game
toilets.push(toilet);
game.addChild(toilet);
}
// Fire a bullet
function fireBullet(targetX, targetY) {
if (player.shootCooldown > 0) return;
// Create bullet
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y - 50;
// Calculate direction to target
var dx = targetX - bullet.x;
var dy = targetY - bullet.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
bullet.direction.x = dx / dist;
bullet.direction.y = dy / dist;
}
// Add to game
bullets.push(bullet);
game.addChild(bullet);
// Flash camera
player.flash();
// Play sound
LK.getSound('shoot').play();
// Set cooldown
player.shootCooldown = 10;
}
// Main game update
game.update = function () {
// Update player
player.update();
// Spawn toilets
if (spawnCooldown <= 0) {
spawnToilet();
spawnCooldown = Math.max(30, 120 - gameLevel * 10); // Spawn faster as level increases
} else {
spawnCooldown--;
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Check if bullet is off screen
if (bullet.x < -100 || bullet.x > 2148 || bullet.y < -100 || bullet.y > 2832) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check collision with toilets
for (var j = toilets.length - 1; j >= 0; j--) {
var toilet = toilets[j];
if (bullet.intersects(toilet)) {
// Destroy bullet
bullet.destroy();
bullets.splice(i, 1);
// Damage toilet
if (toilet.takeDamage()) {
// If toilet is destroyed
updateScore(toilet.points);
LK.getSound('toiletDeath').play();
toilet.destroy();
toilets.splice(j, 1);
enemiesKilled++;
// Level up every 15 kills
if (enemiesKilled % 15 === 0) {
gameLevel++;
levelTxt.setText('Level: ' + gameLevel);
}
} else {
// Hit but not destroyed
LK.getSound('hit').play();
}
break;
}
}
// Break loop if bullet was removed
if (i >= bullets.length) {
break;
}
}
// Update toilets
for (var i = toilets.length - 1; i >= 0; i--) {
var toilet = toilets[i];
toilet.update();
// Check collision with player
if (toilet.intersects(player)) {
// Game over
LK.getSound('playerDeath').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
// Periodically update target to follow player
if (LK.ticks % 60 === 0) {
toilet.setTarget(player.x, player.y);
}
}
};
// Handle touch/mouse events
var touchX = 0;
var touchY = 0;
var isDragging = false;
game.down = function (x, y, obj) {
touchX = x;
touchY = y;
// If clicked near player, start dragging
var dx = x - player.x;
var dy = y - player.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 150) {
isDragging = true;
} else {
// Fire bullet towards click position
fireBullet(x, y);
}
};
game.move = function (x, y, obj) {
touchX = x;
touchY = y;
// Move player if dragging
if (isDragging) {
player.x = x;
// Restrict player to bottom third of screen
player.y = Math.max(2732 / 3 * 2, Math.min(y, 2732 - 100));
}
};
game.up = function (x, y, obj) {
isDragging = false;
};
// Initialize the game
initGame();
A head with hair. In-Game asset. 2d. High contrast. No shadows
A white toilet facing toward. In-Game asset. 2d. High contrast. No shadows
A camera headed person with a suit on. In-Game asset. 2d. High contrast. No shadows
Gun. In-Game asset. 2d. High contrast. No shadows
Bullet. In-Game asset. 2d. High contrast. No shadows