/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ //Classes can only be defined here. You cannot create inline classes in the games code. var Fox = Container.expand(function () { var self = Container.call(this); //Create and attach asset. This is the same as calling var xxx = self.addChild(LK.getAsset(...)) var foxGraphics = self.attachAsset('fox', { anchorX: 0.5, anchorY: 0.5 }); //Set fox speed self.speed = 3.5; // Increased initial fox speed self.scoreValue = 50; // Points gained for scaring a fox self.lastY = 0; self.lastWasIntersecting = false; self.lastBelowToilet = false; // Removed hasNormalcat property as Normalcat will spawn independently //If this instance of bullet is attached, this method will be called every tick by the LK engine automatically. //To not manually call .updated methods. If you want to manually call a method every tick on a class, use a different name than update. //As .update is called from the LK engine directly, .update cannot have method arguments. self.update = function () { // Move the fox towards bottom of screen (simpler vertical fall) self.y += self.speed; // Initialize lastY and lastWasIntersecting if they are not defined if (self.lastY === undefined) { self.lastY = self.y; } if (self.lastWasIntersecting === undefined) { self.lastWasIntersecting = self.intersects(toilet); } // Check if fox falls below the toilet var isBelowToilet = self.y > toilet.y && (self.x < toilet.x - toilet.width / 2 || self.x > toilet.x + toilet.width / 2); // Only track if fox is below toilet, don't end game here self.lastBelowToilet = isBelowToilet; }; return self; //You must return self if you want other classes to be able to inherit from this class }); var Normalcat = Container.expand(function () { var self = Container.call(this); var catGraphics = self.attachAsset('Normalcat', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ // Import tween plugin var game = new LK.Game({ backgroundColor: 0xFFC0CB // Init game with pink background }); /**** * Game Code ****/ // Import tween plugin // Add bathroom background var background = LK.getAsset('bathroom', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(background); var scoreTxt = new Text2('0', { size: 150, fill: 0xFFFFFF //Optional (this is the default string) //font: "'GillSans-Bold',Impact,'Arial Black',Tahoma", //Optional (this is the default string) }); // Update and display the score in the game. scoreTxt.setText(LK.getScore()); // LK.getScore is initialized to zero at game start. // Center the score text horizontally, anchor point set at the middle of its top edge. scoreTxt.anchor.set(0.5, 0); // Sets anchor to the center of the top edge of the text. // Define valid targets for positioning GUI elements: // gui.topLeft: Position at top-left corner (x=0, y=0). // gui.top: Position at top-center (x=width/2, y=0). // gui.topRight: Position at top-right corner (x=width, y=0). // gui.left: Position at middle-left (x=0, y=height/2). // gui.center: Position at center (x=width/2, y=height/2). // gui.right: Position at middle-right (x=width, y=height/2). // gui.bottomLeft: Position at bottom-left corner (x=0, y=height). // gui.bottom: Position at bottom-center (x=width/2, y=height). // gui.bottomRight: Position at bottom-right corner (x=width, y=height). // Add the score text to the GUI overlay. // The score text is attached to the top-center of the screen. // Use LK.gui for overlaying interface elements that should be on top of the game scene. // LK.gui does not have the same resolution as Game to allow for dynamically scaled GUI. Therefore take care to position elements relative to the core GUI targets. LK.gui.top.addChild(scoreTxt); // Create the toilet object and position it at the bottom center var toilet = LK.getAsset('toilet', { anchorX: 0.5, anchorY: 1.0, x: 2048 / 2, y: 2732 - 50 // Position slightly above the bottom }); game.addChild(toilet); // Set up toilet dragging var isDraggingToilet = false; var minX = toilet.width / 2; var maxX = 2048 - toilet.width / 2; var dragOffset = { x: 0 }; game.down = function (x, y, obj) { // Always start dragging the toilet regardless of where the tap is isDraggingToilet = true; dragOffset.x = toilet.x - x; }; game.move = function (x, y, obj) { // Make toilet follow finger directly toilet.x = Math.max(minX, Math.min(maxX, x)); }; game.up = function (x, y, obj) { isDraggingToilet = false; // Check if tap was on toilet and there are flushed cats to fling out var toiletBounds = toilet.getBounds(); if (x >= toiletBounds.x && x <= toiletBounds.x + toiletBounds.width && y >= toiletBounds.y && y <= toiletBounds.y + toiletBounds.height && flushedCats.length > 0) { // Fling out the oldest flushed cat var catToFling = flushedCats.shift(); // Make cat appear and teleport to toilet position instantly catToFling.x = toilet.x; catToFling.y = toilet.y - 100; // Position above toilet catToFling.alpha = 1; catToFling.scaleX = 1; catToFling.scaleY = 1; catToFling.rotation = 0; // Reset rotation // Calculate random fling direction to ensure cat flies completely off screen var flingDirection = Math.random() < 0.5 ? -1 : 1; // Random left or right var targetX = flingDirection > 0 ? 2048 + 300 : -300; // Fly completely off screen horizontally var targetY = Math.random() * 800 - 400; // Random height, can go above or below screen // Small delay to show the cat at toilet position before flinging LK.setTimeout(function () { // Animate cat flinging out completely off screen tween(catToFling, { x: targetX, y: targetY, rotation: Math.random() * Math.PI * 8, // More spinning scaleX: 0.3, scaleY: 0.3 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { // Cat has flown off screen, destroy it catToFling.destroy(); } }); }, 100); // 100ms delay to show cat at toilet before flinging } }; //Keep track of similar elements using arrays in the main 'Game' class var foxes = []; var normalcats = []; var flushedCats = []; // Track cats that have been flushed but not yet flung out // Timer to spawn foxes var foxSpawnTimer = LK.setInterval(function () { // Spawn a new fox from a random position at the top of the screen var newFox = new Fox(); newFox.x = Math.random() * 2048; newFox.y = -100; // Start above the screen // Normalcat now spawns independently, removed from fox spawn foxes.push(newFox); game.addChild(newFox); }, 1000); // Spawn a fox every second // Timer to spawn Normalcats independently var normalcatSpawnTimer = LK.setInterval(function () { if (Math.random() < 0.051) { // 5.1% chance to spawn a Normalcat var newCat = new Normalcat(); // Find a position away from existing foxes var attempts = 0; var validPosition = false; var catX, catY; while (!validPosition && attempts < 50) { catX = Math.random() * 2048; catY = -100; validPosition = true; // Check distance from all existing foxes for (var j = 0; j < foxes.length; j++) { var fox = foxes[j]; var distance = Math.sqrt(Math.pow(catX - fox.x, 2) + Math.pow(catY - fox.y, 2)); if (distance < 150) { // Minimum distance of 150 pixels from foxes validPosition = false; break; } } attempts++; } // Position cat in random radius of 5 pixels around chosen position var angle = Math.random() * Math.PI * 2; // Random angle var radius = Math.random() * 5; // Random radius up to 5 pixels newCat.x = catX + Math.cos(angle) * radius; newCat.y = catY + Math.sin(angle) * radius; normalcats.push(newCat); game.addChild(newCat); } }, 1000); // Check for Normalcat spawn every second // Ask LK engine to update game every game tick game.update = function () { // Always call move and tick methods from the main tick method in the 'Game' class. for (var i = foxes.length - 1; i >= 0; i--) { var fox = foxes[i]; // We always track last and current positions of properties which will trigger events. // This way, we can understand when the state changes (for example, going out the screen or intersecting when it was not last frame) // Check if fox reached the toilet based on state transition var currentIntersecting = fox.intersects(toilet); if (!fox.lastWasIntersecting && currentIntersecting) { // Fox reached the toilet - score points LK.setScore(LK.getScore() + fox.scoreValue); scoreTxt.setText(LK.getScore()); // Play flushing sound LK.getSound('flush').play(); // Create a different effect for fox (no rotation) tween(fox, { alpha: 0, scaleX: 0.2, scaleY: 0.2 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { fox.destroy(); } }); // Remove fox from array foxes.splice(i, 1); continue; } // Check if fox goes out of frame (below screen) if (fox.y > 2732 + 100) { // Add some buffer below screen height // Fox went out of frame - game over LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); break; } // Update last known states fox.lastY = fox.y; fox.lastWasIntersecting = currentIntersecting; // Check if fox is below toilet position var isBelowToilet = fox.y > toilet.y && (fox.x < toilet.x - toilet.width / 2 || fox.x > toilet.x + toilet.width / 2); fox.lastBelowToilet = isBelowToilet; } // Update Normalcats for (var j = normalcats.length - 1; j >= 0; j--) { var cat = normalcats[j]; // Make Normalcat fall like foxes cat.y += 3.5; // Check if Normalcat reached the toilet var catIntersecting = cat.intersects(toilet); if (catIntersecting) { // Normalcat reached the toilet - lose 100 points LK.setScore(LK.getScore() - 100); scoreTxt.setText(LK.getScore()); // Play flushing sound LK.getSound('flush').play(); // Add cat to flushed cats array and hide it temporarily cat.alpha = 0; cat.x = toilet.x; cat.y = toilet.y - 50; // Position slightly above toilet flushedCats.push(cat); // Remove cat from normal cats array normalcats.splice(j, 1); continue; } // Let Normalcat fall infinitely - remove from array when far below screen if (cat.y > 2732 + 500) { // Remove cat from array when far below screen (no game over) cat.destroy(); normalcats.splice(j, 1); continue; } } // Increase difficulty over time if (LK.ticks % 600 === 0 && LK.ticks > 0) { // Every 10 seconds // Increase fox spawn rate by reducing the interval time LK.clearInterval(foxSpawnTimer); var spawnRate = Math.max(300, 1000 - Math.floor(LK.ticks / 600) * 100); // Minimum 300ms foxSpawnTimer = LK.setInterval(function () { var newFox = new Fox(); newFox.x = Math.random() * (2048 - 200) + 100; // Keep foxes away from edges newFox.y = -100; newFox.speed = 3.5 + Math.floor(LK.ticks / 1200) * 0.8; // Increased speed and scaling over time // Normalcat now spawns independently, removed from fox spawn foxes.push(newFox); game.addChild(newFox); }, spawnRate); } }; // Play music track with these musicOptions: /* * loop: (optional) a boolean which indicates if to loop the music track. Default is true and doesn't need to be passed if the track should be looping. * fade: (optional) an object {fade: start: Number Volume to fade from (0.0 to 1.0), end: Number Volume to fade to (0.0 to 1.0), duration: number in miliseconds to fade} } */ // LK.playMusic('bgmusic'); // Assuming you have a 'bgmusic' asset initialized
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
//Classes can only be defined here. You cannot create inline classes in the games code.
var Fox = Container.expand(function () {
var self = Container.call(this);
//Create and attach asset. This is the same as calling var xxx = self.addChild(LK.getAsset(...))
var foxGraphics = self.attachAsset('fox', {
anchorX: 0.5,
anchorY: 0.5
});
//Set fox speed
self.speed = 3.5; // Increased initial fox speed
self.scoreValue = 50; // Points gained for scaring a fox
self.lastY = 0;
self.lastWasIntersecting = false;
self.lastBelowToilet = false;
// Removed hasNormalcat property as Normalcat will spawn independently
//If this instance of bullet is attached, this method will be called every tick by the LK engine automatically.
//To not manually call .updated methods. If you want to manually call a method every tick on a class, use a different name than update.
//As .update is called from the LK engine directly, .update cannot have method arguments.
self.update = function () {
// Move the fox towards bottom of screen (simpler vertical fall)
self.y += self.speed;
// Initialize lastY and lastWasIntersecting if they are not defined
if (self.lastY === undefined) {
self.lastY = self.y;
}
if (self.lastWasIntersecting === undefined) {
self.lastWasIntersecting = self.intersects(toilet);
}
// Check if fox falls below the toilet
var isBelowToilet = self.y > toilet.y && (self.x < toilet.x - toilet.width / 2 || self.x > toilet.x + toilet.width / 2);
// Only track if fox is below toilet, don't end game here
self.lastBelowToilet = isBelowToilet;
};
return self; //You must return self if you want other classes to be able to inherit from this class
});
var Normalcat = Container.expand(function () {
var self = Container.call(this);
var catGraphics = self.attachAsset('Normalcat', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
// Import tween plugin
var game = new LK.Game({
backgroundColor: 0xFFC0CB // Init game with pink background
});
/****
* Game Code
****/
// Import tween plugin
// Add bathroom background
var background = LK.getAsset('bathroom', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(background);
var scoreTxt = new Text2('0', {
size: 150,
fill: 0xFFFFFF //Optional (this is the default string)
//font: "'GillSans-Bold',Impact,'Arial Black',Tahoma", //Optional (this is the default string)
});
// Update and display the score in the game.
scoreTxt.setText(LK.getScore()); // LK.getScore is initialized to zero at game start.
// Center the score text horizontally, anchor point set at the middle of its top edge.
scoreTxt.anchor.set(0.5, 0); // Sets anchor to the center of the top edge of the text.
// Define valid targets for positioning GUI elements:
// gui.topLeft: Position at top-left corner (x=0, y=0).
// gui.top: Position at top-center (x=width/2, y=0).
// gui.topRight: Position at top-right corner (x=width, y=0).
// gui.left: Position at middle-left (x=0, y=height/2).
// gui.center: Position at center (x=width/2, y=height/2).
// gui.right: Position at middle-right (x=width, y=height/2).
// gui.bottomLeft: Position at bottom-left corner (x=0, y=height).
// gui.bottom: Position at bottom-center (x=width/2, y=height).
// gui.bottomRight: Position at bottom-right corner (x=width, y=height).
// Add the score text to the GUI overlay.
// The score text is attached to the top-center of the screen.
// Use LK.gui for overlaying interface elements that should be on top of the game scene.
// LK.gui does not have the same resolution as Game to allow for dynamically scaled GUI. Therefore take care to position elements relative to the core GUI targets.
LK.gui.top.addChild(scoreTxt);
// Create the toilet object and position it at the bottom center
var toilet = LK.getAsset('toilet', {
anchorX: 0.5,
anchorY: 1.0,
x: 2048 / 2,
y: 2732 - 50 // Position slightly above the bottom
});
game.addChild(toilet);
// Set up toilet dragging
var isDraggingToilet = false;
var minX = toilet.width / 2;
var maxX = 2048 - toilet.width / 2;
var dragOffset = {
x: 0
};
game.down = function (x, y, obj) {
// Always start dragging the toilet regardless of where the tap is
isDraggingToilet = true;
dragOffset.x = toilet.x - x;
};
game.move = function (x, y, obj) {
// Make toilet follow finger directly
toilet.x = Math.max(minX, Math.min(maxX, x));
};
game.up = function (x, y, obj) {
isDraggingToilet = false;
// Check if tap was on toilet and there are flushed cats to fling out
var toiletBounds = toilet.getBounds();
if (x >= toiletBounds.x && x <= toiletBounds.x + toiletBounds.width && y >= toiletBounds.y && y <= toiletBounds.y + toiletBounds.height && flushedCats.length > 0) {
// Fling out the oldest flushed cat
var catToFling = flushedCats.shift();
// Make cat appear and teleport to toilet position instantly
catToFling.x = toilet.x;
catToFling.y = toilet.y - 100; // Position above toilet
catToFling.alpha = 1;
catToFling.scaleX = 1;
catToFling.scaleY = 1;
catToFling.rotation = 0; // Reset rotation
// Calculate random fling direction to ensure cat flies completely off screen
var flingDirection = Math.random() < 0.5 ? -1 : 1; // Random left or right
var targetX = flingDirection > 0 ? 2048 + 300 : -300; // Fly completely off screen horizontally
var targetY = Math.random() * 800 - 400; // Random height, can go above or below screen
// Small delay to show the cat at toilet position before flinging
LK.setTimeout(function () {
// Animate cat flinging out completely off screen
tween(catToFling, {
x: targetX,
y: targetY,
rotation: Math.random() * Math.PI * 8,
// More spinning
scaleX: 0.3,
scaleY: 0.3
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Cat has flown off screen, destroy it
catToFling.destroy();
}
});
}, 100); // 100ms delay to show cat at toilet before flinging
}
};
//Keep track of similar elements using arrays in the main 'Game' class
var foxes = [];
var normalcats = [];
var flushedCats = []; // Track cats that have been flushed but not yet flung out
// Timer to spawn foxes
var foxSpawnTimer = LK.setInterval(function () {
// Spawn a new fox from a random position at the top of the screen
var newFox = new Fox();
newFox.x = Math.random() * 2048;
newFox.y = -100; // Start above the screen
// Normalcat now spawns independently, removed from fox spawn
foxes.push(newFox);
game.addChild(newFox);
}, 1000); // Spawn a fox every second
// Timer to spawn Normalcats independently
var normalcatSpawnTimer = LK.setInterval(function () {
if (Math.random() < 0.051) {
// 5.1% chance to spawn a Normalcat
var newCat = new Normalcat();
// Find a position away from existing foxes
var attempts = 0;
var validPosition = false;
var catX, catY;
while (!validPosition && attempts < 50) {
catX = Math.random() * 2048;
catY = -100;
validPosition = true;
// Check distance from all existing foxes
for (var j = 0; j < foxes.length; j++) {
var fox = foxes[j];
var distance = Math.sqrt(Math.pow(catX - fox.x, 2) + Math.pow(catY - fox.y, 2));
if (distance < 150) {
// Minimum distance of 150 pixels from foxes
validPosition = false;
break;
}
}
attempts++;
}
// Position cat in random radius of 5 pixels around chosen position
var angle = Math.random() * Math.PI * 2; // Random angle
var radius = Math.random() * 5; // Random radius up to 5 pixels
newCat.x = catX + Math.cos(angle) * radius;
newCat.y = catY + Math.sin(angle) * radius;
normalcats.push(newCat);
game.addChild(newCat);
}
}, 1000); // Check for Normalcat spawn every second
// Ask LK engine to update game every game tick
game.update = function () {
// Always call move and tick methods from the main tick method in the 'Game' class.
for (var i = foxes.length - 1; i >= 0; i--) {
var fox = foxes[i];
// We always track last and current positions of properties which will trigger events.
// This way, we can understand when the state changes (for example, going out the screen or intersecting when it was not last frame)
// Check if fox reached the toilet based on state transition
var currentIntersecting = fox.intersects(toilet);
if (!fox.lastWasIntersecting && currentIntersecting) {
// Fox reached the toilet - score points
LK.setScore(LK.getScore() + fox.scoreValue);
scoreTxt.setText(LK.getScore());
// Play flushing sound
LK.getSound('flush').play();
// Create a different effect for fox (no rotation)
tween(fox, {
alpha: 0,
scaleX: 0.2,
scaleY: 0.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
fox.destroy();
}
});
// Remove fox from array
foxes.splice(i, 1);
continue;
}
// Check if fox goes out of frame (below screen)
if (fox.y > 2732 + 100) {
// Add some buffer below screen height
// Fox went out of frame - game over
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
break;
}
// Update last known states
fox.lastY = fox.y;
fox.lastWasIntersecting = currentIntersecting;
// Check if fox is below toilet position
var isBelowToilet = fox.y > toilet.y && (fox.x < toilet.x - toilet.width / 2 || fox.x > toilet.x + toilet.width / 2);
fox.lastBelowToilet = isBelowToilet;
}
// Update Normalcats
for (var j = normalcats.length - 1; j >= 0; j--) {
var cat = normalcats[j];
// Make Normalcat fall like foxes
cat.y += 3.5;
// Check if Normalcat reached the toilet
var catIntersecting = cat.intersects(toilet);
if (catIntersecting) {
// Normalcat reached the toilet - lose 100 points
LK.setScore(LK.getScore() - 100);
scoreTxt.setText(LK.getScore());
// Play flushing sound
LK.getSound('flush').play();
// Add cat to flushed cats array and hide it temporarily
cat.alpha = 0;
cat.x = toilet.x;
cat.y = toilet.y - 50; // Position slightly above toilet
flushedCats.push(cat);
// Remove cat from normal cats array
normalcats.splice(j, 1);
continue;
}
// Let Normalcat fall infinitely - remove from array when far below screen
if (cat.y > 2732 + 500) {
// Remove cat from array when far below screen (no game over)
cat.destroy();
normalcats.splice(j, 1);
continue;
}
}
// Increase difficulty over time
if (LK.ticks % 600 === 0 && LK.ticks > 0) {
// Every 10 seconds
// Increase fox spawn rate by reducing the interval time
LK.clearInterval(foxSpawnTimer);
var spawnRate = Math.max(300, 1000 - Math.floor(LK.ticks / 600) * 100); // Minimum 300ms
foxSpawnTimer = LK.setInterval(function () {
var newFox = new Fox();
newFox.x = Math.random() * (2048 - 200) + 100; // Keep foxes away from edges
newFox.y = -100;
newFox.speed = 3.5 + Math.floor(LK.ticks / 1200) * 0.8; // Increased speed and scaling over time
// Normalcat now spawns independently, removed from fox spawn
foxes.push(newFox);
game.addChild(newFox);
}, spawnRate);
}
};
// Play music track with these musicOptions:
/*
* loop: (optional) a boolean which indicates if to loop the music track. Default is true and doesn't need to be passed if the track should be looping.
* fade: (optional) an object {fade: start: Number Volume to fade from (0.0 to 1.0), end: Number Volume to fade to (0.0 to 1.0), duration: number in miliseconds to fade} }
*/
// LK.playMusic('bgmusic'); // Assuming you have a 'bgmusic' asset initialized
A bathroom with a pink toilet. In-Game asset. 2d. High contrast. No shadows
Make a toilet with a small bit of water leaking of the side. In-Game asset. 2d. High contrast. No shadows. Realistic
Make a realistic fox that is sooooo cute. In-Game asset. 2d. High contrast. No shadows. Realistic
Add a Minecraft emerald sword.