/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var AdvancedObjectsMenu = Container.expand(function () { var self = Container.call(this); // Create button background var buttonBg = self.attachAsset('block', { anchorX: 0.5, anchorY: 0.5 }); buttonBg.tint = 0x4286f4; buttonBg.width = 250; buttonBg.height = 60; // Button label var label = new Text2("Advanced Objects", { size: 28, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); // Dropdown container (hidden initially) var dropdown = new Container(); dropdown.y = 70; dropdown.visible = false; self.addChild(dropdown); // Dropdown background var dropdownBg = LK.getAsset('block', { anchorX: 0.5, anchorY: 0 }); dropdownBg.tint = 0x333333; dropdownBg.width = 250; dropdownBg.height = 80; dropdown.addChild(dropdownBg); // Car option var carOption = new Container(); carOption.y = 15; dropdown.addChild(carOption); var carLabel = new Text2("Car", { size: 24, fill: 0xFFFFFF }); carLabel.anchor.set(0.5, 0.5); carOption.addChild(carLabel); // Draggable state self.isOpen = false; self.isDraggingCar = false; self.currentCar = null; // Toggle dropdown self.down = function (x, y, obj) { // Only toggle if clicking the main button (not the dropdown) if (!self.isOpen || y < self.y + buttonBg.height / 2) { self.isOpen = !self.isOpen; dropdown.visible = self.isOpen; // Visual feedback tween(buttonBg, { alpha: 0.8, scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); } }; self.up = function (x, y, obj) { // Visual feedback tween(buttonBg, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 100 }); }; // Car option interaction carOption.interactive = true; carOption.down = function (x, y, obj) { self.isDraggingCar = true; // Create a car object that follows the pointer self.currentCar = new Car(); // Get global position var globalPos = game.toLocal(self.parent.toGlobal({ x: x, y: y })); self.currentCar.x = globalPos.x; self.currentCar.y = globalPos.y; // Add to game game.addChild(self.currentCar); // Visual feedback tween(carLabel, { alpha: 0.7 }, { duration: 100 }); }; carOption.move = function (x, y, obj) { if (self.isDraggingCar && self.currentCar) { // Get global position var globalPos = game.toLocal(self.parent.toGlobal({ x: x, y: y })); self.currentCar.x = globalPos.x; self.currentCar.y = globalPos.y; } }; carOption.up = function (x, y, obj) { if (self.isDraggingCar && self.currentCar) { // Add physics to the car physicsObjects.push(self.currentCar); // Set initial velocity self.currentCar.velocityX = 0; self.currentCar.velocityY = 0; // Reset state self.isDraggingCar = false; self.currentCar = null; // Play sound LK.getSound('place').play(); } // Visual feedback tween(carLabel, { alpha: 1 }, { duration: 100 }); }; return self; }); var BlueScreenButton = Container.expand(function () { var self = Container.call(this); // Create button background var buttonBg = self.attachAsset('buttonBg', { anchorX: 0.5, anchorY: 0.5 }); buttonBg.tint = 0x4286f4; buttonBg.width = 300; buttonBg.height = 80; // Button label var label = new Text2("BLUE SCREEN OF DEATH", { size: 24, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); // Button interaction self.down = function (x, y, obj) { // Visual feedback tween(buttonBg, { alpha: 0.8, scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); // Show blue screen of death showBlueScreenOfDeath(); }; self.up = function (x, y, obj) { // Visual feedback tween(buttonBg, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 100 }); }; return self; }); var Car = Container.expand(function () { var self = Container.call(this); // Car-specific properties self.type = 'car'; self.width = 200; self.height = 100; self.mass = 2; self.friction = 0.2; self.restitution = 0.3; self.velocityX = 0; self.velocityY = 0; self.rotation = 0; self.angularVelocity = 0; self.isStatic = false; // Car body self.visual = self.attachAsset('rectangle', { anchorX: 0.5, anchorY: 0.5, width: 200, height: 100 }); self.visual.tint = 0xff4400; // Orange/red car // Add a roof/cabin var roof = LK.getAsset('rectangle', { anchorX: 0.5, anchorY: 0.5, width: 100, height: 50 }); roof.tint = 0xff7700; roof.y = -25; self.addChild(roof); // Add wheels var frontWheel = LK.getAsset('circle', { anchorX: 0.5, anchorY: 0.5, width: 50, height: 50 }); frontWheel.tint = 0x333333; frontWheel.x = 70; frontWheel.y = 40; self.addChild(frontWheel); var rearWheel = LK.getAsset('circle', { anchorX: 0.5, anchorY: 0.5, width: 50, height: 50 }); rearWheel.tint = 0x333333; rearWheel.x = -70; rearWheel.y = 40; self.addChild(rearWheel); // Add headlights var headlight1 = LK.getAsset('circle', { anchorX: 0.5, anchorY: 0.5, width: 20, height: 20 }); headlight1.tint = 0xffffcc; headlight1.x = 95; headlight1.y = -15; self.addChild(headlight1); var headlight2 = LK.getAsset('circle', { anchorX: 0.5, anchorY: 0.5, width: 20, height: 20 }); headlight2.tint = 0xffffcc; headlight2.x = 95; headlight2.y = 15; self.addChild(headlight2); // Update method to handle wheels rotation self.update = function () { // Rotate wheels based on horizontal velocity frontWheel.rotation += self.velocityX * 0.03; rearWheel.rotation += self.velocityX * 0.03; }; return self; }); var DraggableButton = Container.expand(function () { var self = Container.call(this); // Create visual representation var buttonVisual = self.attachAsset('circle', { anchorX: 0.5, anchorY: 0.5 }); // Add a label var label = new Text2("Create", { size: 24, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); // Track if we're currently creating an object self.isCreating = false; self.currentObject = null; self.objectType = 'circle'; // Default object type // Update the visual based on the selected object type self.updateVisual = function (type) { if (type) { self.objectType = type; } // Remove existing visual self.removeChild(buttonVisual); // Create new visual based on current object type buttonVisual = self.attachAsset(self.objectType, { anchorX: 0.5, anchorY: 0.5 }); // Adjust for triangle shape if (self.objectType === 'triangle') { buttonVisual.scaleY = 0.5; buttonVisual.y = buttonVisual.height / 4; } // Make sure label stays on top self.removeChild(label); self.addChild(label); }; // Handle touch/click down self.down = function (x, y, obj) { self.isCreating = true; // Create a new physics object that follows the pointer self.currentObject = new PhysicsObject(self.objectType, { mass: 1, restitution: 0.7, friction: 0.1 }); // Position at pointer self.currentObject.x = x; self.currentObject.y = y; // Add to game game.addChild(self.currentObject); // Visual feedback tween(buttonVisual, { alpha: 0.7, scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; // Handle movement self.move = function (x, y, obj) { if (self.isCreating && self.currentObject) { self.currentObject.x = x; self.currentObject.y = y; } }; // Handle release self.up = function (x, y, obj) { if (self.isCreating && self.currentObject) { // Add physics to the object physicsObjects.push(self.currentObject); // Set initial velocity based on recent movement if (chaosMode) { // More chaotic initial velocity in chaos mode self.currentObject.velocityX = Math.random() * 30 - 15; self.currentObject.velocityY = Math.random() * -20 - 5; self.currentObject.angularVelocity = Math.random() * 0.3 - 0.15; // Sometimes create multiple balls when in chaos mode if (Math.random() < 0.3) { for (var i = 0; i < 3; i++) { createPhysicsObject(x + Math.random() * 100 - 50, y + Math.random() * 100 - 50, self.objectType, { mass: 0.5 + Math.random(), restitution: 0.8, friction: 0.05 }); } } } else { // Normal initial velocity self.currentObject.velocityX = Math.random() * 10 - 5; self.currentObject.velocityY = -10; // Initial upward velocity } // Reset state self.isCreating = false; self.currentObject = null; // Play sound LK.getSound('place').play(); } // Visual feedback tween(buttonVisual, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 100 }); }; return self; }); var GlitchButton = Container.expand(function () { var self = Container.call(this); // Button properties self.width = 150; self.height = 150; self.isGlitching = false; self.particles = []; self.maxParticles = 20; self.glitchActivated = false; // Visual appearance var buttonVisual = self.attachAsset('circle', { anchorX: 0.5, anchorY: 0.5, width: self.width, height: self.height }); buttonVisual.tint = 0x00FFFF; // Cyan // Text label var label = new Text2("GLITCH", { size: 32, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); // Create particles for (var i = 0; i < self.maxParticles; i++) { createParticle(); } // Create a single particle function createParticle() { var particle = new GlitchParticle({ color: Math.random() < 0.5 ? 0x00FFFF : 0xFF00FF, size: 5 + Math.random() * 15, distance: 80 + Math.random() * 60, speed: 0.5 + Math.random() * 1.5, glitchRate: 0.1 + Math.random() * 0.2 }); // Position relative to button particle.setOrigin(0, 0); self.addChild(particle); self.particles.push(particle); } // Button interaction self.down = function (x, y, obj) { // Increment glitch counter glitchCounter++; // Trigger glitch effect self.glitchActivated = true; // Visual feedback tween(buttonVisual, { alpha: 0.8, scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); // Trigger chaos mode chaosMode = true; // Flash screen LK.effects.flashScreen(0x00FFFF, 500); // Visual glitch effect for all UI elements glitchUI(); // Check if we reached 50 glitches if (glitchCounter >= 50 && !cleaningMode) { // Activate cleaning mode cleaningMode = true; // Hide all UI elements hideAllUI(); // Start virus cleaning process startVirusCleaning(); } // Play sound LK.getSound('place').play(); }; self.up = function (x, y, obj) { // Visual feedback tween(buttonVisual, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 100 }); }; // Update particles self.update = function () { // Update each particle for (var i = 0; i < self.particles.length; i++) { self.particles[i].update(); } // Button glitch effect if (Math.random() < 0.1) { self.isGlitching = !self.isGlitching; if (self.isGlitching) { buttonVisual.tint = Math.random() < 0.5 ? 0xFF00FF : 0x00FFFF; label.position.x = Math.random() * 10 - 5; label.position.y = Math.random() * 10 - 5; // Sometimes change text if (Math.random() < 0.2) { label.setText(Math.random() < 0.5 ? "ERR0R" : "GL1TCH"); } } else { buttonVisual.tint = 0x00FFFF; label.position.x = 0; label.position.y = 0; label.setText("GLITCH"); } } }; return self; }); // Glitch UI elements function var GlitchParticle = Container.expand(function (options) { var self = Container.call(this); // Default options options = options || {}; self.size = options.size || Math.random() * 10 + 5; self.speed = options.speed || Math.random() * 2 + 1; self.distance = options.distance || 50 + Math.random() * 100; self.angle = options.angle || Math.random() * Math.PI * 2; self.rotation = Math.random() * Math.PI * 2; self.rotationSpeed = Math.random() * 0.2 - 0.1; self.alpha = 0.7 + Math.random() * 0.3; self.glitchRate = options.glitchRate || 0.2; // Visual appearance var visual = self.attachAsset('square', { anchorX: 0.5, anchorY: 0.5 }); visual.width = self.size; visual.height = self.size; visual.tint = options.color || 0x00FFFF; // Animation properties self.time = 0; self.originalX = 0; self.originalY = 0; self.offsetX = 0; self.offsetY = 0; // Update particle position self.update = function () { self.time += 0.05; // Orbital movement self.offsetX = Math.cos(self.angle + self.time * self.speed) * self.distance; self.offsetY = Math.sin(self.angle + self.time * self.speed) * self.distance; self.x = self.originalX + self.offsetX; self.y = self.originalY + self.offsetY; // Rotate visual.rotation += self.rotationSpeed; // Random glitch effect if (Math.random() < self.glitchRate) { visual.x = Math.random() * 10 - 5; visual.y = Math.random() * 10 - 5; visual.alpha = 0.5 + Math.random() * 0.5; visual.tint = Math.random() < 0.5 ? 0x00FFFF : 0xFF00FF; } else { visual.x = 0; visual.y = 0; visual.alpha = self.alpha; } }; // Set origin point self.setOrigin = function (x, y) { self.originalX = x; self.originalY = y; }; return self; }); var ObjectSelector = Container.expand(function () { var self = Container.call(this); // Create main container var buttonContainer = new Container(); self.addChild(buttonContainer); // Header text var headerText = new Text2("Objects", { size: 36, fill: 0xFFFFFF }); headerText.anchor.set(0.5, 0); headerText.y = -60; self.addChild(headerText); // Create object buttons var objectTypes = [{ type: 'circle', label: 'Circle', color: 0xe74c3c }, { type: 'square', label: 'Square', color: 0x3498db }, { type: 'rectangle', label: 'Rectangle', color: 0x2ecc71 }, { type: 'triangle', label: 'Triangle', color: 0x70ae6e }]; var buttonWidth = 150; var buttonHeight = 80; var buttonSpacing = 20; var buttonsPerRow = 2; for (var i = 0; i < objectTypes.length; i++) { var col = i % buttonsPerRow; var row = Math.floor(i / buttonsPerRow); var button = new UIButton(objectTypes[i].label, buttonWidth, buttonHeight, objectTypes[i].color); button.x = col * (buttonWidth + buttonSpacing) - (buttonsPerRow - 1) * (buttonWidth + buttonSpacing) / 2; button.y = row * (buttonHeight + buttonSpacing); button.objectType = objectTypes[i].type; button.onPress = function () { if (self.onSelectObject) { self.onSelectObject(this.objectType); } }; buttonContainer.addChild(button); } return self; }); var PhysicsObject = Container.expand(function (type, properties) { var self = Container.call(this); self.type = type || 'block'; // Default properties self.mass = (properties === null || properties === void 0 ? void 0 : properties.mass) || 1; self.friction = (properties === null || properties === void 0 ? void 0 : properties.friction) || 0.1; self.restitution = (properties === null || properties === void 0 ? void 0 : properties.restitution) || 0.5; self.isStatic = (properties === null || properties === void 0 ? void 0 : properties.isStatic) || false; // Physics variables self.velocityX = 0; self.velocityY = 0; self.rotation = 0; self.angularVelocity = 0; // Create visual representation var visual = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5 }); if (type === 'triangle') { // Make the triangle shape by scaling visual.scaleY = 0.5; visual.y = visual.height / 4; } self.visual = visual; // Visual feedback for static objects if (self.isStatic) { visual.alpha = 0.7; } // Modify the color based on mass var color = visual.tint; if (self.mass > 1) { // Darken for heavier objects visual.tint = darkenColor(color, 0.2 * (self.mass - 1)); } else if (self.mass < 1) { // Lighten for lighter objects visual.tint = lightenColor(color, 0.2 * (1 - self.mass)); } // Handle interaction self.down = function (x, y, obj) { // Only allow dragging if we're in edit mode if (currentMode === 'edit') { isDragging = true; draggedObject = self; // Store offset for dragging dragOffsetX = self.x - x; dragOffsetY = self.y - y; } }; return self; }); var UIButton = Container.expand(function (label, width, height, color) { var self = Container.call(this); // Create button background var background = self.attachAsset('block', { anchorX: 0.5, anchorY: 0.5 }); background.tint = color || 0x4d90ff; background.width = width || 150; background.height = height || 80; // Create button label var labelText = new Text2(label, { size: 30, fill: 0xFFFFFF }); labelText.anchor.set(0.5, 0.5); self.addChild(labelText); // Handle button press self.down = function (x, y, obj) { tween(background, { alpha: 0.7 }, { duration: 100 }); }; self.up = function (x, y, obj) { tween(background, { alpha: 1 }, { duration: 100 }); if (self.onPress) { self.onPress(); } }; return self; }); // Glitch UI elements function var VirusScanButton = Container.expand(function () { var self = Container.call(this); // Create button background var buttonBg = self.attachAsset('buttonBg', { anchorX: 0.5, anchorY: 0.5 }); buttonBg.tint = 0x4286f4; buttonBg.width = 300; buttonBg.height = 80; // Button label var label = new Text2("VIRUS SCAN AGAIN", { size: 30, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); // Button interaction self.down = function (x, y, obj) { // Visual feedback tween(buttonBg, { alpha: 0.8, scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); // Show blue screen of death showBlueScreenOfDeath(); }; self.up = function (x, y, obj) { // Visual feedback tween(buttonBg, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 100 }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB // Sky blue background }); /**** * Game Code ****/ // Function to hide all UI elements function hideAllUI() { // Set background to black game.setBackgroundColor(0x000000); // Remove all physics objects for (var i = physicsObjects.length - 1; i >= 0; i--) { game.removeChild(physicsObjects[i]); physicsObjects.splice(i, 1); } // Hide all GUI elements var uiElements = [title, instructions, ballCountText, easterEggHint, circleCreator, clearButton, objectSelectorButton, advancedObjects, glitchButton]; for (var i = 0; i < uiElements.length; i++) { if (uiElements[i] && uiElements[i].parent) { uiElements[i].parent.removeChild(uiElements[i]); } } // Clear any existing object selector if (objectSelector && objectSelector.parent) { objectSelector.parent.removeChild(objectSelector); objectSelector = null; } } // Function to start virus cleaning process function startVirusCleaning() { // Create cleaning text var cleaningText = new Text2("CLEANING ALL VIRUSES", { size: 60, fill: 0x00FF00 }); cleaningText.anchor.set(0.5, 0.5); cleaningText.x = 2048 / 2; cleaningText.y = 2732 / 2 - 100; LK.gui.addChild(cleaningText); // Create progress text var progressText = new Text2("0%", { size: 50, fill: 0x00FF00 }); progressText.anchor.set(0.5, 0.5); progressText.x = 2048 / 2; progressText.y = 2732 / 2; LK.gui.addChild(progressText); // Update progress var progressInterval = LK.setInterval(function () { cleanProgress += 1; progressText.setText(cleanProgress + "%"); // Check if cleaning is complete if (cleanProgress >= 100) { LK.clearInterval(progressInterval); // Remove cleaning texts LK.gui.removeChild(cleaningText); LK.gui.removeChild(progressText); // Show error message showErrorMessage(); } }, 100); } // Function to show error message function showErrorMessage() { // Create error text var errorText = new Text2("ERROR: PLEASE RESTART THE GAME", { size: 60, fill: 0xFF0000 }); errorText.anchor.set(0.5, 0.5); errorText.x = 2048 / 2; errorText.y = 2732 / 2; LK.gui.addChild(errorText); // Create blinking effect var blinkInterval = LK.setInterval(function () { errorText.visible = !errorText.visible; }, 500); // Automatically restart the game after a few seconds LK.setTimeout(function () { LK.clearInterval(blinkInterval); LK.showGameOver(); }, 5000); } // Function to show blue screen of death function showBlueScreenOfDeath() { // Hide all game elements hideAllUI(); // Clear all UI LK.gui.removeChildren(); // Set background to blue game.setBackgroundColor(0x0078D7); // Modern Windows BSOD blue // Create BSOD content - Windows 10 style var sadFaceText = new Text2(":(", { size: 180, fill: 0xFFFFFF }); sadFaceText.anchor.set(0, 0); sadFaceText.x = 400; sadFaceText.y = 300; LK.gui.addChild(sadFaceText); var bsodText = new Text2("Your PC ran into a problem and needs to restart.", { size: 50, fill: 0xFFFFFF }); bsodText.anchor.set(0, 0); bsodText.x = 400; bsodText.y = 550; LK.gui.addChild(bsodText); var collectingText = new Text2("We're just collecting some error info, and then we'll restart for you.", { size: 36, fill: 0xFFFFFF }); collectingText.anchor.set(0, 0); collectingText.x = 400; collectingText.y = 650; LK.gui.addChild(collectingText); // Progress counter that goes from 0% to 100% var progress = 0; var percentText = new Text2("0% complete", { size: 36, fill: 0xFFFFFF }); percentText.anchor.set(0, 0); percentText.x = 400; percentText.y = 800; LK.gui.addChild(percentText); // QR code representation (simplified as a white square) var qrCode = LK.getAsset('square', { anchorX: 0, anchorY: 0, width: 200, height: 200 }); qrCode.tint = 0xFFFFFF; qrCode.x = 400; qrCode.y = 900; LK.gui.addChild(qrCode); // Add QR code text indicating it leads to Roblox.com var qrCodeText = new Text2("Scan to go to: roblox.com", { size: 30, fill: 0xFFFFFF }); qrCodeText.anchor.set(0, 0); qrCodeText.x = 620; qrCodeText.y = 950; LK.gui.addChild(qrCodeText); var errorCodeText = new Text2("CRITICAL_PROCESS_DIED", { size: 40, fill: 0xFFFFFF }); errorCodeText.anchor.set(0, 0); errorCodeText.x = 400; errorCodeText.y = 1150; LK.gui.addChild(errorCodeText); var stopCodeText = new Text2("Stop Code: 01X10XX011X0ERROR", { size: 36, fill: 0xFFFFFF }); stopCodeText.anchor.set(0, 0); stopCodeText.x = 400; stopCodeText.y = 1200; LK.gui.addChild(stopCodeText); // Update progress and auto-restart when done var progressInterval = LK.setInterval(function () { progress += 1; percentText.setText(progress + "% complete"); // When reaches 100%, restart game if (progress >= 100) { LK.clearInterval(progressInterval); LK.setTimeout(function () { LK.showGameOver(); }, 2000); } }, 100); } // Glitch UI elements function var GRAVITY = 0.5; var DRAG = 0.02; var GROUND_Y = 2500; // Game state var physicsObjects = []; var isSimulating = true; var currentMode = 'edit'; // Define currentMode variable var isDragging = false; var draggedObject = null; var dragOffsetX = 0; var dragOffsetY = 0; var selectedObjectType = 'circle'; var objectSelector = null; var glitchCounter = 0; var cleaningMode = false; var cleanProgress = 0; // Create the ground var ground = new PhysicsObject('ground', { isStatic: true }); ground.x = 2048 / 2; ground.y = GROUND_Y; game.addChild(ground); physicsObjects.push(ground); // Create a draggable button that creates physics objects var circleCreator = new DraggableButton(); circleCreator.x = 200; circleCreator.y = 200; LK.gui.addChild(circleCreator); // Add the advanced objects dropdown var advancedObjects = new AdvancedObjectsMenu(); advancedObjects.x = 450; advancedObjects.y = 200; LK.gui.addChild(advancedObjects); // Create a title var title = new Text2("Physics Playground", { size: 50, fill: 0xFFFFFF }); title.anchor.set(0.5, 0); title.x = 2048 / 2; title.y = 50; LK.gui.addChild(title); // Instructions var instructions = new Text2("Drag from the circle to create\nobjects that bounce with physics", { size: 30, fill: 0xFFFFFF }); instructions.anchor.set(0.5, 0); instructions.x = 2048 / 2; instructions.y = 120; LK.gui.addChild(instructions); // Ball counter var ballCountText = new Text2("Balls: 0", { size: 30, fill: 0xFFFFFF }); ballCountText.anchor.set(0, 0); ballCountText.x = 50; ballCountText.y = 50; LK.gui.addChild(ballCountText); // Easter egg hint var easterEggHint = new Text2("What happens at 100?", { size: 20, fill: 0xCCCCCC }); easterEggHint.anchor.set(0, 0); easterEggHint.x = 50; easterEggHint.y = 90; easterEggHint.alpha = 0.7; LK.gui.addChild(easterEggHint); // Game area doesn't need specific event handlers since // the DraggableButton handles its own events game.down = function (x, y, obj) {}; game.move = function (x, y, obj) {}; game.up = function (x, y, obj) {}; // Track total balls spawned and chaos mode var totalBallsSpawned = 0; var chaosMode = false; // Update physics in the game loop game.update = function () { updatePhysics(); // Update glitch button if it exists if (glitchButton) { glitchButton.update(); } // Extra chaotic effects when in chaos mode if (chaosMode) { // Randomly glitch UI sometimes if (Math.random() < 0.005) { glitchUI(); } } }; // Create a new physics object at specified position function createPhysicsObject(x, y, type, properties) { var newObject = new PhysicsObject(type || 'circle', properties || { mass: 1, friction: 0.1, restitution: 0.7 }); newObject.x = x; newObject.y = y; game.addChild(newObject); physicsObjects.push(newObject); // Set appropriate physics properties based on shape if (type === 'square' || type === 'rectangle') { // Squares and rectangles have more friction newObject.friction = properties && properties.friction || 0.2; // Squares and rectangles bounce less newObject.restitution = properties && properties.restitution || 0.4; } else if (type === 'triangle') { // Triangles are lighter newObject.mass = properties && properties.mass || 0.8; // Triangles have less friction newObject.friction = properties && properties.friction || 0.05; // Triangles bounce more newObject.restitution = properties && properties.restitution || 0.8; } // Track ball count and trigger chaos mode at 100 if (type === 'circle' || !type) { totalBallsSpawned++; // Show count if (ballCountText) { ballCountText.setText("Balls: " + totalBallsSpawned); } // Check for chaos threshold if (totalBallsSpawned >= 100 && !chaosMode) { chaosMode = true; // Flash screen LK.effects.flashScreen(0xFF0000, 500); // Create visual ball explosion for (var i = 0; i < 20; i++) { var angle = Math.random() * Math.PI * 2; var speed = 20 + Math.random() * 20; var ball = new PhysicsObject('circle', { mass: 0.5 + Math.random(), restitution: 0.9, friction: 0.05 }); ball.x = x; ball.y = y; ball.velocityX = Math.cos(angle) * speed; ball.velocityY = Math.sin(angle) * speed; ball.angularVelocity = Math.random() * 0.2 - 0.1; game.addChild(ball); physicsObjects.push(ball); } } } // Play place sound LK.getSound('place').play(); return newObject; } // Update physics for all objects function updatePhysics() { for (var i = 0; i < physicsObjects.length; i++) { var obj = physicsObjects[i]; if (!obj.isStatic) { // Apply gravity obj.velocityY += GRAVITY * obj.mass; // Apply drag obj.velocityX *= 1 - DRAG; obj.velocityY *= 1 - DRAG; obj.angularVelocity *= 1 - DRAG; // Update position obj.x += obj.velocityX; obj.y += obj.velocityY; // In chaos mode, objects can sometimes teleport if (chaosMode && Math.random() < 0.01) { obj.x = Math.random() * 2048; obj.y = Math.random() * GROUND_Y * 0.7; obj.velocityX *= -1.5; obj.velocityY *= -1.5; obj.visual.alpha = 0.7; tween(obj.visual, { alpha: 1, scaleX: 1 + Math.random() * 0.5, scaleY: 1 + Math.random() * 0.5 }, { duration: 300, easing: tween.easeOutElastic }); } // Update rotation with extra spin in chaos mode obj.rotation += obj.angularVelocity * (chaosMode && Math.random() < 0.1 ? 3 : 1); obj.visual.rotation = obj.rotation; // Check boundaries checkBoundaries(obj); // Check collisions with other objects for (var j = 0; j < physicsObjects.length; j++) { if (i !== j) { checkCollision(obj, physicsObjects[j]); } } } } } // Check if an object is out of bounds function checkBoundaries(obj) { // Left boundary if (obj.x - obj.visual.width / 2 < 0) { obj.x = obj.visual.width / 2; obj.velocityX = -obj.velocityX * obj.restitution; } // Right boundary if (obj.x + obj.visual.width / 2 > 2048) { obj.x = 2048 - obj.visual.width / 2; obj.velocityX = -obj.velocityX * obj.restitution; } // Bottom boundary if (obj.y + obj.visual.height / 2 > GROUND_Y - ground.visual.height / 2) { obj.y = GROUND_Y - ground.visual.height / 2 - obj.visual.height / 2; obj.velocityY = -obj.velocityY * obj.restitution; // Apply friction obj.velocityX *= 1 - obj.friction; // Play bounce sound if the impact is significant if (Math.abs(obj.velocityY) > 3) { LK.getSound('bounce').play(); } } } // Simple collision detection and response function checkCollision(obj1, obj2) { if (obj1.intersects(obj2)) { // Only process if not already processed in reverse if (obj1.isStatic && obj2.isStatic) { return; // Two static objects don't interact } // Calculate collision vector var dx = obj2.x - obj1.x; var dy = obj2.y - obj1.y; var distance = Math.sqrt(dx * dx + dy * dy); // Normalize collision vector var nx = dx / distance; var ny = dy / distance; // Calculate minimum translation distance var obj1Width = obj1.type === 'car' ? obj1.width / 2 : obj1.visual.width / 2; var obj2Width = obj2.type === 'car' ? obj2.width / 2 : obj2.visual.width / 2; var minDist = obj1Width + obj2Width; var mtd = minDist - distance; // Resolve collision if (!obj1.isStatic && !obj2.isStatic) { // Both objects move var totalMass = obj1.mass + obj2.mass; var obj1Ratio = obj1.mass / totalMass; var obj2Ratio = obj2.mass / totalMass; obj1.x -= nx * mtd * obj2Ratio; obj1.y -= ny * mtd * obj2Ratio; obj2.x += nx * mtd * obj1Ratio; obj2.y += ny * mtd * obj1Ratio; // Calculate relative velocity var vrx = obj2.velocityX - obj1.velocityX; var vry = obj2.velocityY - obj1.velocityY; // Calculate impulse var impulse = -(1 + Math.min(obj1.restitution, obj2.restitution)) * (vrx * nx + vry * ny) / (1 / obj1.mass + 1 / obj2.mass); // Apply impulse obj1.velocityX -= impulse * nx / obj1.mass; obj1.velocityY -= impulse * ny / obj1.mass; obj2.velocityX += impulse * nx / obj2.mass; obj2.velocityY += impulse * ny / obj2.mass; // Add angular velocity based on off-center collision var impact = Math.abs(impulse); obj1.angularVelocity += impact * 0.01 * (Math.random() - 0.5); obj2.angularVelocity += impact * 0.01 * (Math.random() - 0.5); // Play bounce sound if the impact is significant if (impact > 3) { LK.getSound('bounce').play(); } } else { // One object is static var movingObj, staticObj; if (obj1.isStatic) { movingObj = obj2; staticObj = obj1; nx = -nx; ny = -ny; } else { movingObj = obj1; staticObj = obj2; } // Move the moving object movingObj.x += nx * mtd; movingObj.y += ny * mtd; // Calculate new velocity var dot = movingObj.velocityX * nx + movingObj.velocityY * ny; movingObj.velocityX -= (1 + movingObj.restitution) * dot * nx; movingObj.velocityY -= (1 + movingObj.restitution) * dot * ny; // Apply friction var tangentX = -ny; var tangentY = nx; var tangentDot = movingObj.velocityX * tangentX + movingObj.velocityY * tangentY; movingObj.velocityX -= tangentDot * tangentX * staticObj.friction; movingObj.velocityY -= tangentDot * tangentY * staticObj.friction; // Add angular velocity movingObj.angularVelocity += dot * 0.02 * (Math.random() - 0.5); // Play bounce sound if the impact is significant if (Math.abs(dot) > 3) { LK.getSound('bounce').play(); } } } } // Clear all objects except ground function clearAll() { for (var i = physicsObjects.length - 1; i >= 0; i--) { var obj = physicsObjects[i]; if (obj !== ground) { game.removeChild(obj); physicsObjects.splice(i, 1); } } LK.getSound('delete').play(); } // Add object selector button var objectSelectorButton = new UIButton("Objects", 150, 80, 0x27ae60); objectSelectorButton.x = 2048 - 300; objectSelectorButton.y = 300; objectSelectorButton.onPress = function () { if (!objectSelector) { // Create and show the object selector objectSelector = new ObjectSelector(); objectSelector.x = 2048 / 2; objectSelector.y = 2732 / 2; objectSelector.onSelectObject = function (type) { selectedObjectType = type; // Update draggable button appearance circleCreator.updateVisual(type); // Hide selector LK.gui.removeChild(objectSelector); objectSelector = null; }; LK.gui.addChild(objectSelector); } else { // Hide selector LK.gui.removeChild(objectSelector); objectSelector = null; } }; LK.gui.addChild(objectSelectorButton); // Add a clear button var clearButton = new UIButton("Clear", 150, 80, 0xdc3545); clearButton.x = 2048 - 100; clearButton.y = 300; clearButton.onPress = clearAll; LK.gui.addChild(clearButton); // Add the glitch button var glitchButton = new GlitchButton(); glitchButton.x = 150; glitchButton.y = 600; LK.gui.addChild(glitchButton); // Helper function to darken a color function darkenColor(color, percent) { var r = color >> 16 & 0xFF; var g = color >> 8 & 0xFF; var b = color & 0xFF; r = Math.floor(r * (1 - percent)); g = Math.floor(g * (1 - percent)); b = Math.floor(b * (1 - percent)); return r << 16 | g << 8 | b; } // Helper function to lighten a color function lightenColor(color, percent) { var r = color >> 16 & 0xFF; var g = color >> 8 & 0xFF; var b = color & 0xFF; r = Math.floor(r + (255 - r) * percent); g = Math.floor(g + (255 - g) * percent); b = Math.floor(b + (255 - b) * percent); return r << 16 | g << 8 | b; } // Update game physics and glitch effects game.update = function () { // Skip normal updates in cleaning mode if (cleaningMode) { return; } updatePhysics(); // Update glitch button if it exists if (glitchButton) { glitchButton.update(); } // Extra chaotic effects when in chaos mode if (chaosMode) { // Randomly glitch UI sometimes if (Math.random() < 0.005) { glitchUI(); } } }; // Glitch UI elements function function glitchUI() { // Elements to glitch var uiElements = [title, instructions, ballCountText, easterEggHint, circleCreator, clearButton, objectSelectorButton, advancedObjects]; // Apply random transformations to all UI elements for (var i = 0; i < uiElements.length; i++) { var element = uiElements[i]; var originalX = element.x; var originalY = element.y; var originalRotation = element.rotation || 0; // Random position and rotation tween(element, { x: originalX + Math.random() * 300 - 150, y: originalY + Math.random() * 300 - 150, rotation: originalRotation + Math.random() * 0.5 - 0.25 }, { duration: 300, easing: tween.easeOutElastic, onFinish: function (el, origX, origY, origRot) { return function () { // Return to original position with a new tween tween(el, { x: origX + (Math.random() * 40 - 20), y: origY + (Math.random() * 40 - 20), rotation: origRot + (Math.random() * 0.1 - 0.05) }, { duration: 500, easing: tween.easeOutElastic }); }; }(element, originalX, originalY, originalRotation) }); // Also apply scale and alpha glitching tween(element, { scaleX: 1 + Math.random() * 0.4 - 0.2, scaleY: 1 + Math.random() * 0.4 - 0.2, alpha: 0.7 + Math.random() * 0.3 }, { duration: 200, easing: tween.easeOutElastic, onFinish: function onFinish() { tween(this, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 300 }); } }); } // Create some temporary glitch particles in random positions for (var j = 0; j < 30; j++) { var glitchParticle = new GlitchParticle({ size: 10 + Math.random() * 30, glitchRate: 0.5 }); glitchParticle.x = Math.random() * 2048; glitchParticle.y = Math.random() * 1000; LK.gui.addChild(glitchParticle); // Remove after a short time LK.setTimeout(function (particle) { return function () { LK.gui.removeChild(particle); }; }(glitchParticle), 1000 + Math.random() * 2000); } } // Add blue screen of death button at the bottom of the screen var blueScreenButton = new BlueScreenButton(); blueScreenButton.x = 2048 / 2; blueScreenButton.y = 2732 - 100; LK.gui.addChild(blueScreenButton); // Play background music LK.playMusic('bgmusic');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var AdvancedObjectsMenu = Container.expand(function () {
var self = Container.call(this);
// Create button background
var buttonBg = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5
});
buttonBg.tint = 0x4286f4;
buttonBg.width = 250;
buttonBg.height = 60;
// Button label
var label = new Text2("Advanced Objects", {
size: 28,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
// Dropdown container (hidden initially)
var dropdown = new Container();
dropdown.y = 70;
dropdown.visible = false;
self.addChild(dropdown);
// Dropdown background
var dropdownBg = LK.getAsset('block', {
anchorX: 0.5,
anchorY: 0
});
dropdownBg.tint = 0x333333;
dropdownBg.width = 250;
dropdownBg.height = 80;
dropdown.addChild(dropdownBg);
// Car option
var carOption = new Container();
carOption.y = 15;
dropdown.addChild(carOption);
var carLabel = new Text2("Car", {
size: 24,
fill: 0xFFFFFF
});
carLabel.anchor.set(0.5, 0.5);
carOption.addChild(carLabel);
// Draggable state
self.isOpen = false;
self.isDraggingCar = false;
self.currentCar = null;
// Toggle dropdown
self.down = function (x, y, obj) {
// Only toggle if clicking the main button (not the dropdown)
if (!self.isOpen || y < self.y + buttonBg.height / 2) {
self.isOpen = !self.isOpen;
dropdown.visible = self.isOpen;
// Visual feedback
tween(buttonBg, {
alpha: 0.8,
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
}
};
self.up = function (x, y, obj) {
// Visual feedback
tween(buttonBg, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
};
// Car option interaction
carOption.interactive = true;
carOption.down = function (x, y, obj) {
self.isDraggingCar = true;
// Create a car object that follows the pointer
self.currentCar = new Car();
// Get global position
var globalPos = game.toLocal(self.parent.toGlobal({
x: x,
y: y
}));
self.currentCar.x = globalPos.x;
self.currentCar.y = globalPos.y;
// Add to game
game.addChild(self.currentCar);
// Visual feedback
tween(carLabel, {
alpha: 0.7
}, {
duration: 100
});
};
carOption.move = function (x, y, obj) {
if (self.isDraggingCar && self.currentCar) {
// Get global position
var globalPos = game.toLocal(self.parent.toGlobal({
x: x,
y: y
}));
self.currentCar.x = globalPos.x;
self.currentCar.y = globalPos.y;
}
};
carOption.up = function (x, y, obj) {
if (self.isDraggingCar && self.currentCar) {
// Add physics to the car
physicsObjects.push(self.currentCar);
// Set initial velocity
self.currentCar.velocityX = 0;
self.currentCar.velocityY = 0;
// Reset state
self.isDraggingCar = false;
self.currentCar = null;
// Play sound
LK.getSound('place').play();
}
// Visual feedback
tween(carLabel, {
alpha: 1
}, {
duration: 100
});
};
return self;
});
var BlueScreenButton = Container.expand(function () {
var self = Container.call(this);
// Create button background
var buttonBg = self.attachAsset('buttonBg', {
anchorX: 0.5,
anchorY: 0.5
});
buttonBg.tint = 0x4286f4;
buttonBg.width = 300;
buttonBg.height = 80;
// Button label
var label = new Text2("BLUE SCREEN OF DEATH", {
size: 24,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
// Button interaction
self.down = function (x, y, obj) {
// Visual feedback
tween(buttonBg, {
alpha: 0.8,
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
// Show blue screen of death
showBlueScreenOfDeath();
};
self.up = function (x, y, obj) {
// Visual feedback
tween(buttonBg, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
};
return self;
});
var Car = Container.expand(function () {
var self = Container.call(this);
// Car-specific properties
self.type = 'car';
self.width = 200;
self.height = 100;
self.mass = 2;
self.friction = 0.2;
self.restitution = 0.3;
self.velocityX = 0;
self.velocityY = 0;
self.rotation = 0;
self.angularVelocity = 0;
self.isStatic = false;
// Car body
self.visual = self.attachAsset('rectangle', {
anchorX: 0.5,
anchorY: 0.5,
width: 200,
height: 100
});
self.visual.tint = 0xff4400; // Orange/red car
// Add a roof/cabin
var roof = LK.getAsset('rectangle', {
anchorX: 0.5,
anchorY: 0.5,
width: 100,
height: 50
});
roof.tint = 0xff7700;
roof.y = -25;
self.addChild(roof);
// Add wheels
var frontWheel = LK.getAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
width: 50,
height: 50
});
frontWheel.tint = 0x333333;
frontWheel.x = 70;
frontWheel.y = 40;
self.addChild(frontWheel);
var rearWheel = LK.getAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
width: 50,
height: 50
});
rearWheel.tint = 0x333333;
rearWheel.x = -70;
rearWheel.y = 40;
self.addChild(rearWheel);
// Add headlights
var headlight1 = LK.getAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
width: 20,
height: 20
});
headlight1.tint = 0xffffcc;
headlight1.x = 95;
headlight1.y = -15;
self.addChild(headlight1);
var headlight2 = LK.getAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
width: 20,
height: 20
});
headlight2.tint = 0xffffcc;
headlight2.x = 95;
headlight2.y = 15;
self.addChild(headlight2);
// Update method to handle wheels rotation
self.update = function () {
// Rotate wheels based on horizontal velocity
frontWheel.rotation += self.velocityX * 0.03;
rearWheel.rotation += self.velocityX * 0.03;
};
return self;
});
var DraggableButton = Container.expand(function () {
var self = Container.call(this);
// Create visual representation
var buttonVisual = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5
});
// Add a label
var label = new Text2("Create", {
size: 24,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
// Track if we're currently creating an object
self.isCreating = false;
self.currentObject = null;
self.objectType = 'circle'; // Default object type
// Update the visual based on the selected object type
self.updateVisual = function (type) {
if (type) {
self.objectType = type;
}
// Remove existing visual
self.removeChild(buttonVisual);
// Create new visual based on current object type
buttonVisual = self.attachAsset(self.objectType, {
anchorX: 0.5,
anchorY: 0.5
});
// Adjust for triangle shape
if (self.objectType === 'triangle') {
buttonVisual.scaleY = 0.5;
buttonVisual.y = buttonVisual.height / 4;
}
// Make sure label stays on top
self.removeChild(label);
self.addChild(label);
};
// Handle touch/click down
self.down = function (x, y, obj) {
self.isCreating = true;
// Create a new physics object that follows the pointer
self.currentObject = new PhysicsObject(self.objectType, {
mass: 1,
restitution: 0.7,
friction: 0.1
});
// Position at pointer
self.currentObject.x = x;
self.currentObject.y = y;
// Add to game
game.addChild(self.currentObject);
// Visual feedback
tween(buttonVisual, {
alpha: 0.7,
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
// Handle movement
self.move = function (x, y, obj) {
if (self.isCreating && self.currentObject) {
self.currentObject.x = x;
self.currentObject.y = y;
}
};
// Handle release
self.up = function (x, y, obj) {
if (self.isCreating && self.currentObject) {
// Add physics to the object
physicsObjects.push(self.currentObject);
// Set initial velocity based on recent movement
if (chaosMode) {
// More chaotic initial velocity in chaos mode
self.currentObject.velocityX = Math.random() * 30 - 15;
self.currentObject.velocityY = Math.random() * -20 - 5;
self.currentObject.angularVelocity = Math.random() * 0.3 - 0.15;
// Sometimes create multiple balls when in chaos mode
if (Math.random() < 0.3) {
for (var i = 0; i < 3; i++) {
createPhysicsObject(x + Math.random() * 100 - 50, y + Math.random() * 100 - 50, self.objectType, {
mass: 0.5 + Math.random(),
restitution: 0.8,
friction: 0.05
});
}
}
} else {
// Normal initial velocity
self.currentObject.velocityX = Math.random() * 10 - 5;
self.currentObject.velocityY = -10; // Initial upward velocity
}
// Reset state
self.isCreating = false;
self.currentObject = null;
// Play sound
LK.getSound('place').play();
}
// Visual feedback
tween(buttonVisual, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
};
return self;
});
var GlitchButton = Container.expand(function () {
var self = Container.call(this);
// Button properties
self.width = 150;
self.height = 150;
self.isGlitching = false;
self.particles = [];
self.maxParticles = 20;
self.glitchActivated = false;
// Visual appearance
var buttonVisual = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
width: self.width,
height: self.height
});
buttonVisual.tint = 0x00FFFF; // Cyan
// Text label
var label = new Text2("GLITCH", {
size: 32,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
// Create particles
for (var i = 0; i < self.maxParticles; i++) {
createParticle();
}
// Create a single particle
function createParticle() {
var particle = new GlitchParticle({
color: Math.random() < 0.5 ? 0x00FFFF : 0xFF00FF,
size: 5 + Math.random() * 15,
distance: 80 + Math.random() * 60,
speed: 0.5 + Math.random() * 1.5,
glitchRate: 0.1 + Math.random() * 0.2
});
// Position relative to button
particle.setOrigin(0, 0);
self.addChild(particle);
self.particles.push(particle);
}
// Button interaction
self.down = function (x, y, obj) {
// Increment glitch counter
glitchCounter++;
// Trigger glitch effect
self.glitchActivated = true;
// Visual feedback
tween(buttonVisual, {
alpha: 0.8,
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
// Trigger chaos mode
chaosMode = true;
// Flash screen
LK.effects.flashScreen(0x00FFFF, 500);
// Visual glitch effect for all UI elements
glitchUI();
// Check if we reached 50 glitches
if (glitchCounter >= 50 && !cleaningMode) {
// Activate cleaning mode
cleaningMode = true;
// Hide all UI elements
hideAllUI();
// Start virus cleaning process
startVirusCleaning();
}
// Play sound
LK.getSound('place').play();
};
self.up = function (x, y, obj) {
// Visual feedback
tween(buttonVisual, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
};
// Update particles
self.update = function () {
// Update each particle
for (var i = 0; i < self.particles.length; i++) {
self.particles[i].update();
}
// Button glitch effect
if (Math.random() < 0.1) {
self.isGlitching = !self.isGlitching;
if (self.isGlitching) {
buttonVisual.tint = Math.random() < 0.5 ? 0xFF00FF : 0x00FFFF;
label.position.x = Math.random() * 10 - 5;
label.position.y = Math.random() * 10 - 5;
// Sometimes change text
if (Math.random() < 0.2) {
label.setText(Math.random() < 0.5 ? "ERR0R" : "GL1TCH");
}
} else {
buttonVisual.tint = 0x00FFFF;
label.position.x = 0;
label.position.y = 0;
label.setText("GLITCH");
}
}
};
return self;
});
// Glitch UI elements function
var GlitchParticle = Container.expand(function (options) {
var self = Container.call(this);
// Default options
options = options || {};
self.size = options.size || Math.random() * 10 + 5;
self.speed = options.speed || Math.random() * 2 + 1;
self.distance = options.distance || 50 + Math.random() * 100;
self.angle = options.angle || Math.random() * Math.PI * 2;
self.rotation = Math.random() * Math.PI * 2;
self.rotationSpeed = Math.random() * 0.2 - 0.1;
self.alpha = 0.7 + Math.random() * 0.3;
self.glitchRate = options.glitchRate || 0.2;
// Visual appearance
var visual = self.attachAsset('square', {
anchorX: 0.5,
anchorY: 0.5
});
visual.width = self.size;
visual.height = self.size;
visual.tint = options.color || 0x00FFFF;
// Animation properties
self.time = 0;
self.originalX = 0;
self.originalY = 0;
self.offsetX = 0;
self.offsetY = 0;
// Update particle position
self.update = function () {
self.time += 0.05;
// Orbital movement
self.offsetX = Math.cos(self.angle + self.time * self.speed) * self.distance;
self.offsetY = Math.sin(self.angle + self.time * self.speed) * self.distance;
self.x = self.originalX + self.offsetX;
self.y = self.originalY + self.offsetY;
// Rotate
visual.rotation += self.rotationSpeed;
// Random glitch effect
if (Math.random() < self.glitchRate) {
visual.x = Math.random() * 10 - 5;
visual.y = Math.random() * 10 - 5;
visual.alpha = 0.5 + Math.random() * 0.5;
visual.tint = Math.random() < 0.5 ? 0x00FFFF : 0xFF00FF;
} else {
visual.x = 0;
visual.y = 0;
visual.alpha = self.alpha;
}
};
// Set origin point
self.setOrigin = function (x, y) {
self.originalX = x;
self.originalY = y;
};
return self;
});
var ObjectSelector = Container.expand(function () {
var self = Container.call(this);
// Create main container
var buttonContainer = new Container();
self.addChild(buttonContainer);
// Header text
var headerText = new Text2("Objects", {
size: 36,
fill: 0xFFFFFF
});
headerText.anchor.set(0.5, 0);
headerText.y = -60;
self.addChild(headerText);
// Create object buttons
var objectTypes = [{
type: 'circle',
label: 'Circle',
color: 0xe74c3c
}, {
type: 'square',
label: 'Square',
color: 0x3498db
}, {
type: 'rectangle',
label: 'Rectangle',
color: 0x2ecc71
}, {
type: 'triangle',
label: 'Triangle',
color: 0x70ae6e
}];
var buttonWidth = 150;
var buttonHeight = 80;
var buttonSpacing = 20;
var buttonsPerRow = 2;
for (var i = 0; i < objectTypes.length; i++) {
var col = i % buttonsPerRow;
var row = Math.floor(i / buttonsPerRow);
var button = new UIButton(objectTypes[i].label, buttonWidth, buttonHeight, objectTypes[i].color);
button.x = col * (buttonWidth + buttonSpacing) - (buttonsPerRow - 1) * (buttonWidth + buttonSpacing) / 2;
button.y = row * (buttonHeight + buttonSpacing);
button.objectType = objectTypes[i].type;
button.onPress = function () {
if (self.onSelectObject) {
self.onSelectObject(this.objectType);
}
};
buttonContainer.addChild(button);
}
return self;
});
var PhysicsObject = Container.expand(function (type, properties) {
var self = Container.call(this);
self.type = type || 'block';
// Default properties
self.mass = (properties === null || properties === void 0 ? void 0 : properties.mass) || 1;
self.friction = (properties === null || properties === void 0 ? void 0 : properties.friction) || 0.1;
self.restitution = (properties === null || properties === void 0 ? void 0 : properties.restitution) || 0.5;
self.isStatic = (properties === null || properties === void 0 ? void 0 : properties.isStatic) || false;
// Physics variables
self.velocityX = 0;
self.velocityY = 0;
self.rotation = 0;
self.angularVelocity = 0;
// Create visual representation
var visual = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
if (type === 'triangle') {
// Make the triangle shape by scaling
visual.scaleY = 0.5;
visual.y = visual.height / 4;
}
self.visual = visual;
// Visual feedback for static objects
if (self.isStatic) {
visual.alpha = 0.7;
}
// Modify the color based on mass
var color = visual.tint;
if (self.mass > 1) {
// Darken for heavier objects
visual.tint = darkenColor(color, 0.2 * (self.mass - 1));
} else if (self.mass < 1) {
// Lighten for lighter objects
visual.tint = lightenColor(color, 0.2 * (1 - self.mass));
}
// Handle interaction
self.down = function (x, y, obj) {
// Only allow dragging if we're in edit mode
if (currentMode === 'edit') {
isDragging = true;
draggedObject = self;
// Store offset for dragging
dragOffsetX = self.x - x;
dragOffsetY = self.y - y;
}
};
return self;
});
var UIButton = Container.expand(function (label, width, height, color) {
var self = Container.call(this);
// Create button background
var background = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5
});
background.tint = color || 0x4d90ff;
background.width = width || 150;
background.height = height || 80;
// Create button label
var labelText = new Text2(label, {
size: 30,
fill: 0xFFFFFF
});
labelText.anchor.set(0.5, 0.5);
self.addChild(labelText);
// Handle button press
self.down = function (x, y, obj) {
tween(background, {
alpha: 0.7
}, {
duration: 100
});
};
self.up = function (x, y, obj) {
tween(background, {
alpha: 1
}, {
duration: 100
});
if (self.onPress) {
self.onPress();
}
};
return self;
});
// Glitch UI elements function
var VirusScanButton = Container.expand(function () {
var self = Container.call(this);
// Create button background
var buttonBg = self.attachAsset('buttonBg', {
anchorX: 0.5,
anchorY: 0.5
});
buttonBg.tint = 0x4286f4;
buttonBg.width = 300;
buttonBg.height = 80;
// Button label
var label = new Text2("VIRUS SCAN AGAIN", {
size: 30,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
// Button interaction
self.down = function (x, y, obj) {
// Visual feedback
tween(buttonBg, {
alpha: 0.8,
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
// Show blue screen of death
showBlueScreenOfDeath();
};
self.up = function (x, y, obj) {
// Visual feedback
tween(buttonBg, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue background
});
/****
* Game Code
****/
// Function to hide all UI elements
function hideAllUI() {
// Set background to black
game.setBackgroundColor(0x000000);
// Remove all physics objects
for (var i = physicsObjects.length - 1; i >= 0; i--) {
game.removeChild(physicsObjects[i]);
physicsObjects.splice(i, 1);
}
// Hide all GUI elements
var uiElements = [title, instructions, ballCountText, easterEggHint, circleCreator, clearButton, objectSelectorButton, advancedObjects, glitchButton];
for (var i = 0; i < uiElements.length; i++) {
if (uiElements[i] && uiElements[i].parent) {
uiElements[i].parent.removeChild(uiElements[i]);
}
}
// Clear any existing object selector
if (objectSelector && objectSelector.parent) {
objectSelector.parent.removeChild(objectSelector);
objectSelector = null;
}
}
// Function to start virus cleaning process
function startVirusCleaning() {
// Create cleaning text
var cleaningText = new Text2("CLEANING ALL VIRUSES", {
size: 60,
fill: 0x00FF00
});
cleaningText.anchor.set(0.5, 0.5);
cleaningText.x = 2048 / 2;
cleaningText.y = 2732 / 2 - 100;
LK.gui.addChild(cleaningText);
// Create progress text
var progressText = new Text2("0%", {
size: 50,
fill: 0x00FF00
});
progressText.anchor.set(0.5, 0.5);
progressText.x = 2048 / 2;
progressText.y = 2732 / 2;
LK.gui.addChild(progressText);
// Update progress
var progressInterval = LK.setInterval(function () {
cleanProgress += 1;
progressText.setText(cleanProgress + "%");
// Check if cleaning is complete
if (cleanProgress >= 100) {
LK.clearInterval(progressInterval);
// Remove cleaning texts
LK.gui.removeChild(cleaningText);
LK.gui.removeChild(progressText);
// Show error message
showErrorMessage();
}
}, 100);
}
// Function to show error message
function showErrorMessage() {
// Create error text
var errorText = new Text2("ERROR: PLEASE RESTART THE GAME", {
size: 60,
fill: 0xFF0000
});
errorText.anchor.set(0.5, 0.5);
errorText.x = 2048 / 2;
errorText.y = 2732 / 2;
LK.gui.addChild(errorText);
// Create blinking effect
var blinkInterval = LK.setInterval(function () {
errorText.visible = !errorText.visible;
}, 500);
// Automatically restart the game after a few seconds
LK.setTimeout(function () {
LK.clearInterval(blinkInterval);
LK.showGameOver();
}, 5000);
}
// Function to show blue screen of death
function showBlueScreenOfDeath() {
// Hide all game elements
hideAllUI();
// Clear all UI
LK.gui.removeChildren();
// Set background to blue
game.setBackgroundColor(0x0078D7); // Modern Windows BSOD blue
// Create BSOD content - Windows 10 style
var sadFaceText = new Text2(":(", {
size: 180,
fill: 0xFFFFFF
});
sadFaceText.anchor.set(0, 0);
sadFaceText.x = 400;
sadFaceText.y = 300;
LK.gui.addChild(sadFaceText);
var bsodText = new Text2("Your PC ran into a problem and needs to restart.", {
size: 50,
fill: 0xFFFFFF
});
bsodText.anchor.set(0, 0);
bsodText.x = 400;
bsodText.y = 550;
LK.gui.addChild(bsodText);
var collectingText = new Text2("We're just collecting some error info, and then we'll restart for you.", {
size: 36,
fill: 0xFFFFFF
});
collectingText.anchor.set(0, 0);
collectingText.x = 400;
collectingText.y = 650;
LK.gui.addChild(collectingText);
// Progress counter that goes from 0% to 100%
var progress = 0;
var percentText = new Text2("0% complete", {
size: 36,
fill: 0xFFFFFF
});
percentText.anchor.set(0, 0);
percentText.x = 400;
percentText.y = 800;
LK.gui.addChild(percentText);
// QR code representation (simplified as a white square)
var qrCode = LK.getAsset('square', {
anchorX: 0,
anchorY: 0,
width: 200,
height: 200
});
qrCode.tint = 0xFFFFFF;
qrCode.x = 400;
qrCode.y = 900;
LK.gui.addChild(qrCode);
// Add QR code text indicating it leads to Roblox.com
var qrCodeText = new Text2("Scan to go to: roblox.com", {
size: 30,
fill: 0xFFFFFF
});
qrCodeText.anchor.set(0, 0);
qrCodeText.x = 620;
qrCodeText.y = 950;
LK.gui.addChild(qrCodeText);
var errorCodeText = new Text2("CRITICAL_PROCESS_DIED", {
size: 40,
fill: 0xFFFFFF
});
errorCodeText.anchor.set(0, 0);
errorCodeText.x = 400;
errorCodeText.y = 1150;
LK.gui.addChild(errorCodeText);
var stopCodeText = new Text2("Stop Code: 01X10XX011X0ERROR", {
size: 36,
fill: 0xFFFFFF
});
stopCodeText.anchor.set(0, 0);
stopCodeText.x = 400;
stopCodeText.y = 1200;
LK.gui.addChild(stopCodeText);
// Update progress and auto-restart when done
var progressInterval = LK.setInterval(function () {
progress += 1;
percentText.setText(progress + "% complete");
// When reaches 100%, restart game
if (progress >= 100) {
LK.clearInterval(progressInterval);
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
}
}, 100);
}
// Glitch UI elements function
var GRAVITY = 0.5;
var DRAG = 0.02;
var GROUND_Y = 2500;
// Game state
var physicsObjects = [];
var isSimulating = true;
var currentMode = 'edit'; // Define currentMode variable
var isDragging = false;
var draggedObject = null;
var dragOffsetX = 0;
var dragOffsetY = 0;
var selectedObjectType = 'circle';
var objectSelector = null;
var glitchCounter = 0;
var cleaningMode = false;
var cleanProgress = 0;
// Create the ground
var ground = new PhysicsObject('ground', {
isStatic: true
});
ground.x = 2048 / 2;
ground.y = GROUND_Y;
game.addChild(ground);
physicsObjects.push(ground);
// Create a draggable button that creates physics objects
var circleCreator = new DraggableButton();
circleCreator.x = 200;
circleCreator.y = 200;
LK.gui.addChild(circleCreator);
// Add the advanced objects dropdown
var advancedObjects = new AdvancedObjectsMenu();
advancedObjects.x = 450;
advancedObjects.y = 200;
LK.gui.addChild(advancedObjects);
// Create a title
var title = new Text2("Physics Playground", {
size: 50,
fill: 0xFFFFFF
});
title.anchor.set(0.5, 0);
title.x = 2048 / 2;
title.y = 50;
LK.gui.addChild(title);
// Instructions
var instructions = new Text2("Drag from the circle to create\nobjects that bounce with physics", {
size: 30,
fill: 0xFFFFFF
});
instructions.anchor.set(0.5, 0);
instructions.x = 2048 / 2;
instructions.y = 120;
LK.gui.addChild(instructions);
// Ball counter
var ballCountText = new Text2("Balls: 0", {
size: 30,
fill: 0xFFFFFF
});
ballCountText.anchor.set(0, 0);
ballCountText.x = 50;
ballCountText.y = 50;
LK.gui.addChild(ballCountText);
// Easter egg hint
var easterEggHint = new Text2("What happens at 100?", {
size: 20,
fill: 0xCCCCCC
});
easterEggHint.anchor.set(0, 0);
easterEggHint.x = 50;
easterEggHint.y = 90;
easterEggHint.alpha = 0.7;
LK.gui.addChild(easterEggHint);
// Game area doesn't need specific event handlers since
// the DraggableButton handles its own events
game.down = function (x, y, obj) {};
game.move = function (x, y, obj) {};
game.up = function (x, y, obj) {};
// Track total balls spawned and chaos mode
var totalBallsSpawned = 0;
var chaosMode = false;
// Update physics in the game loop
game.update = function () {
updatePhysics();
// Update glitch button if it exists
if (glitchButton) {
glitchButton.update();
}
// Extra chaotic effects when in chaos mode
if (chaosMode) {
// Randomly glitch UI sometimes
if (Math.random() < 0.005) {
glitchUI();
}
}
};
// Create a new physics object at specified position
function createPhysicsObject(x, y, type, properties) {
var newObject = new PhysicsObject(type || 'circle', properties || {
mass: 1,
friction: 0.1,
restitution: 0.7
});
newObject.x = x;
newObject.y = y;
game.addChild(newObject);
physicsObjects.push(newObject);
// Set appropriate physics properties based on shape
if (type === 'square' || type === 'rectangle') {
// Squares and rectangles have more friction
newObject.friction = properties && properties.friction || 0.2;
// Squares and rectangles bounce less
newObject.restitution = properties && properties.restitution || 0.4;
} else if (type === 'triangle') {
// Triangles are lighter
newObject.mass = properties && properties.mass || 0.8;
// Triangles have less friction
newObject.friction = properties && properties.friction || 0.05;
// Triangles bounce more
newObject.restitution = properties && properties.restitution || 0.8;
}
// Track ball count and trigger chaos mode at 100
if (type === 'circle' || !type) {
totalBallsSpawned++;
// Show count
if (ballCountText) {
ballCountText.setText("Balls: " + totalBallsSpawned);
}
// Check for chaos threshold
if (totalBallsSpawned >= 100 && !chaosMode) {
chaosMode = true;
// Flash screen
LK.effects.flashScreen(0xFF0000, 500);
// Create visual ball explosion
for (var i = 0; i < 20; i++) {
var angle = Math.random() * Math.PI * 2;
var speed = 20 + Math.random() * 20;
var ball = new PhysicsObject('circle', {
mass: 0.5 + Math.random(),
restitution: 0.9,
friction: 0.05
});
ball.x = x;
ball.y = y;
ball.velocityX = Math.cos(angle) * speed;
ball.velocityY = Math.sin(angle) * speed;
ball.angularVelocity = Math.random() * 0.2 - 0.1;
game.addChild(ball);
physicsObjects.push(ball);
}
}
}
// Play place sound
LK.getSound('place').play();
return newObject;
}
// Update physics for all objects
function updatePhysics() {
for (var i = 0; i < physicsObjects.length; i++) {
var obj = physicsObjects[i];
if (!obj.isStatic) {
// Apply gravity
obj.velocityY += GRAVITY * obj.mass;
// Apply drag
obj.velocityX *= 1 - DRAG;
obj.velocityY *= 1 - DRAG;
obj.angularVelocity *= 1 - DRAG;
// Update position
obj.x += obj.velocityX;
obj.y += obj.velocityY;
// In chaos mode, objects can sometimes teleport
if (chaosMode && Math.random() < 0.01) {
obj.x = Math.random() * 2048;
obj.y = Math.random() * GROUND_Y * 0.7;
obj.velocityX *= -1.5;
obj.velocityY *= -1.5;
obj.visual.alpha = 0.7;
tween(obj.visual, {
alpha: 1,
scaleX: 1 + Math.random() * 0.5,
scaleY: 1 + Math.random() * 0.5
}, {
duration: 300,
easing: tween.easeOutElastic
});
}
// Update rotation with extra spin in chaos mode
obj.rotation += obj.angularVelocity * (chaosMode && Math.random() < 0.1 ? 3 : 1);
obj.visual.rotation = obj.rotation;
// Check boundaries
checkBoundaries(obj);
// Check collisions with other objects
for (var j = 0; j < physicsObjects.length; j++) {
if (i !== j) {
checkCollision(obj, physicsObjects[j]);
}
}
}
}
}
// Check if an object is out of bounds
function checkBoundaries(obj) {
// Left boundary
if (obj.x - obj.visual.width / 2 < 0) {
obj.x = obj.visual.width / 2;
obj.velocityX = -obj.velocityX * obj.restitution;
}
// Right boundary
if (obj.x + obj.visual.width / 2 > 2048) {
obj.x = 2048 - obj.visual.width / 2;
obj.velocityX = -obj.velocityX * obj.restitution;
}
// Bottom boundary
if (obj.y + obj.visual.height / 2 > GROUND_Y - ground.visual.height / 2) {
obj.y = GROUND_Y - ground.visual.height / 2 - obj.visual.height / 2;
obj.velocityY = -obj.velocityY * obj.restitution;
// Apply friction
obj.velocityX *= 1 - obj.friction;
// Play bounce sound if the impact is significant
if (Math.abs(obj.velocityY) > 3) {
LK.getSound('bounce').play();
}
}
}
// Simple collision detection and response
function checkCollision(obj1, obj2) {
if (obj1.intersects(obj2)) {
// Only process if not already processed in reverse
if (obj1.isStatic && obj2.isStatic) {
return; // Two static objects don't interact
}
// Calculate collision vector
var dx = obj2.x - obj1.x;
var dy = obj2.y - obj1.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize collision vector
var nx = dx / distance;
var ny = dy / distance;
// Calculate minimum translation distance
var obj1Width = obj1.type === 'car' ? obj1.width / 2 : obj1.visual.width / 2;
var obj2Width = obj2.type === 'car' ? obj2.width / 2 : obj2.visual.width / 2;
var minDist = obj1Width + obj2Width;
var mtd = minDist - distance;
// Resolve collision
if (!obj1.isStatic && !obj2.isStatic) {
// Both objects move
var totalMass = obj1.mass + obj2.mass;
var obj1Ratio = obj1.mass / totalMass;
var obj2Ratio = obj2.mass / totalMass;
obj1.x -= nx * mtd * obj2Ratio;
obj1.y -= ny * mtd * obj2Ratio;
obj2.x += nx * mtd * obj1Ratio;
obj2.y += ny * mtd * obj1Ratio;
// Calculate relative velocity
var vrx = obj2.velocityX - obj1.velocityX;
var vry = obj2.velocityY - obj1.velocityY;
// Calculate impulse
var impulse = -(1 + Math.min(obj1.restitution, obj2.restitution)) * (vrx * nx + vry * ny) / (1 / obj1.mass + 1 / obj2.mass);
// Apply impulse
obj1.velocityX -= impulse * nx / obj1.mass;
obj1.velocityY -= impulse * ny / obj1.mass;
obj2.velocityX += impulse * nx / obj2.mass;
obj2.velocityY += impulse * ny / obj2.mass;
// Add angular velocity based on off-center collision
var impact = Math.abs(impulse);
obj1.angularVelocity += impact * 0.01 * (Math.random() - 0.5);
obj2.angularVelocity += impact * 0.01 * (Math.random() - 0.5);
// Play bounce sound if the impact is significant
if (impact > 3) {
LK.getSound('bounce').play();
}
} else {
// One object is static
var movingObj, staticObj;
if (obj1.isStatic) {
movingObj = obj2;
staticObj = obj1;
nx = -nx;
ny = -ny;
} else {
movingObj = obj1;
staticObj = obj2;
}
// Move the moving object
movingObj.x += nx * mtd;
movingObj.y += ny * mtd;
// Calculate new velocity
var dot = movingObj.velocityX * nx + movingObj.velocityY * ny;
movingObj.velocityX -= (1 + movingObj.restitution) * dot * nx;
movingObj.velocityY -= (1 + movingObj.restitution) * dot * ny;
// Apply friction
var tangentX = -ny;
var tangentY = nx;
var tangentDot = movingObj.velocityX * tangentX + movingObj.velocityY * tangentY;
movingObj.velocityX -= tangentDot * tangentX * staticObj.friction;
movingObj.velocityY -= tangentDot * tangentY * staticObj.friction;
// Add angular velocity
movingObj.angularVelocity += dot * 0.02 * (Math.random() - 0.5);
// Play bounce sound if the impact is significant
if (Math.abs(dot) > 3) {
LK.getSound('bounce').play();
}
}
}
}
// Clear all objects except ground
function clearAll() {
for (var i = physicsObjects.length - 1; i >= 0; i--) {
var obj = physicsObjects[i];
if (obj !== ground) {
game.removeChild(obj);
physicsObjects.splice(i, 1);
}
}
LK.getSound('delete').play();
}
// Add object selector button
var objectSelectorButton = new UIButton("Objects", 150, 80, 0x27ae60);
objectSelectorButton.x = 2048 - 300;
objectSelectorButton.y = 300;
objectSelectorButton.onPress = function () {
if (!objectSelector) {
// Create and show the object selector
objectSelector = new ObjectSelector();
objectSelector.x = 2048 / 2;
objectSelector.y = 2732 / 2;
objectSelector.onSelectObject = function (type) {
selectedObjectType = type;
// Update draggable button appearance
circleCreator.updateVisual(type);
// Hide selector
LK.gui.removeChild(objectSelector);
objectSelector = null;
};
LK.gui.addChild(objectSelector);
} else {
// Hide selector
LK.gui.removeChild(objectSelector);
objectSelector = null;
}
};
LK.gui.addChild(objectSelectorButton);
// Add a clear button
var clearButton = new UIButton("Clear", 150, 80, 0xdc3545);
clearButton.x = 2048 - 100;
clearButton.y = 300;
clearButton.onPress = clearAll;
LK.gui.addChild(clearButton);
// Add the glitch button
var glitchButton = new GlitchButton();
glitchButton.x = 150;
glitchButton.y = 600;
LK.gui.addChild(glitchButton);
// Helper function to darken a color
function darkenColor(color, percent) {
var r = color >> 16 & 0xFF;
var g = color >> 8 & 0xFF;
var b = color & 0xFF;
r = Math.floor(r * (1 - percent));
g = Math.floor(g * (1 - percent));
b = Math.floor(b * (1 - percent));
return r << 16 | g << 8 | b;
}
// Helper function to lighten a color
function lightenColor(color, percent) {
var r = color >> 16 & 0xFF;
var g = color >> 8 & 0xFF;
var b = color & 0xFF;
r = Math.floor(r + (255 - r) * percent);
g = Math.floor(g + (255 - g) * percent);
b = Math.floor(b + (255 - b) * percent);
return r << 16 | g << 8 | b;
}
// Update game physics and glitch effects
game.update = function () {
// Skip normal updates in cleaning mode
if (cleaningMode) {
return;
}
updatePhysics();
// Update glitch button if it exists
if (glitchButton) {
glitchButton.update();
}
// Extra chaotic effects when in chaos mode
if (chaosMode) {
// Randomly glitch UI sometimes
if (Math.random() < 0.005) {
glitchUI();
}
}
};
// Glitch UI elements function
function glitchUI() {
// Elements to glitch
var uiElements = [title, instructions, ballCountText, easterEggHint, circleCreator, clearButton, objectSelectorButton, advancedObjects];
// Apply random transformations to all UI elements
for (var i = 0; i < uiElements.length; i++) {
var element = uiElements[i];
var originalX = element.x;
var originalY = element.y;
var originalRotation = element.rotation || 0;
// Random position and rotation
tween(element, {
x: originalX + Math.random() * 300 - 150,
y: originalY + Math.random() * 300 - 150,
rotation: originalRotation + Math.random() * 0.5 - 0.25
}, {
duration: 300,
easing: tween.easeOutElastic,
onFinish: function (el, origX, origY, origRot) {
return function () {
// Return to original position with a new tween
tween(el, {
x: origX + (Math.random() * 40 - 20),
y: origY + (Math.random() * 40 - 20),
rotation: origRot + (Math.random() * 0.1 - 0.05)
}, {
duration: 500,
easing: tween.easeOutElastic
});
};
}(element, originalX, originalY, originalRotation)
});
// Also apply scale and alpha glitching
tween(element, {
scaleX: 1 + Math.random() * 0.4 - 0.2,
scaleY: 1 + Math.random() * 0.4 - 0.2,
alpha: 0.7 + Math.random() * 0.3
}, {
duration: 200,
easing: tween.easeOutElastic,
onFinish: function onFinish() {
tween(this, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, {
duration: 300
});
}
});
}
// Create some temporary glitch particles in random positions
for (var j = 0; j < 30; j++) {
var glitchParticle = new GlitchParticle({
size: 10 + Math.random() * 30,
glitchRate: 0.5
});
glitchParticle.x = Math.random() * 2048;
glitchParticle.y = Math.random() * 1000;
LK.gui.addChild(glitchParticle);
// Remove after a short time
LK.setTimeout(function (particle) {
return function () {
LK.gui.removeChild(particle);
};
}(glitchParticle), 1000 + Math.random() * 2000);
}
}
// Add blue screen of death button at the bottom of the screen
var blueScreenButton = new BlueScreenButton();
blueScreenButton.x = 2048 / 2;
blueScreenButton.y = 2732 - 100;
LK.gui.addChild(blueScreenButton);
// Play background music
LK.playMusic('bgmusic');