User prompt
make the lasers a little bit smaller
User prompt
make bombs explosion area smaller and when the bomb exploded it is still can kill us fix this problems
User prompt
when a bomb spawns make it doesnt kill the player after 1.6 seconds
User prompt
after the bomb exploded its killing area is still active make it dissapear after the bomb exploded and when we avoided from 20 attacks lasers are 3x faster make it 2x
User prompt
i want the bomb to be image like our character
User prompt
when we avoided from 10 attacks make a new attack type it creates a random bomb into the cube room and it will explode after 1.5 second the explotions area will be same as the bombs area and when it explodes another one will be spawn and if the player touches it while it exploiding player will die ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make warnings visible before the laser
User prompt
when we avoided from 20 attacks make lasers spawn time 1.5x slower and make a warning about where the next laser will come from
User prompt
make the lasers 3x faster when we avoided from 20 attacks
User prompt
make skeletons health 300
User prompt
make skeletons health 30
User prompt
make lasers acceleration faster and when we avoid from each attack skeleton should get damage
User prompt
make lasers slower from start and they will slowly be faster but it will stay in the same speed when it is 4 times faster from start ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make the room smaller and make lasers smaller too
User prompt
make us in a cube room and we cant get out
User prompt
ok now when we get hit from his attacks make it kill us
User prompt
rewrite the source code
User prompt
Heart Escape: Skeleton Showdown
Initial prompt
make me a game we will be a heart that is our main character and our enemy is a skeleton with a jacket and he will tryna kill us with his skills utils like one of them is a lasers coming to us and we need to escape from them and everytime when we escape from his utils the enemy will get damage a little bit and when we escape enough of his utils he will die and we will win
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bomb = Container.expand(function () { var self = Container.call(this); // Create bomb visual var bombGraphic = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5 }); // Use the dedicated bomb asset instead of repurposed laser // Create eyes for character-like appearance var leftEye = new Container(); var leftEyeWhite = LK.getAsset('bomb', { anchorX: 0.5, anchorY: 0.5, tint: 0xFFFFFF, scaleX: 0.2, scaleY: 0.2 }); var leftEyePupil = LK.getAsset('bomb', { anchorX: 0.5, anchorY: 0.5, tint: 0x0000FF, scaleX: 0.1, scaleY: 0.1 }); leftEye.addChild(leftEyeWhite); leftEye.addChild(leftEyePupil); leftEye.x = -20; leftEye.y = -15; var rightEye = new Container(); var rightEyeWhite = LK.getAsset('bomb', { anchorX: 0.5, anchorY: 0.5, tint: 0xFFFFFF, scaleX: 0.2, scaleY: 0.2 }); var rightEyePupil = LK.getAsset('bomb', { anchorX: 0.5, anchorY: 0.5, tint: 0x0000FF, scaleX: 0.1, scaleY: 0.1 }); rightEye.addChild(rightEyeWhite); rightEye.addChild(rightEyePupil); rightEye.x = 20; rightEye.y = -15; // Create a mouth that looks worried var mouth = LK.getAsset('bomb', { anchorX: 0.5, anchorY: 0.5, tint: 0xFF0000, scaleX: 0.4, scaleY: 0.1 }); mouth.y = 20; self.addChild(leftEye); self.addChild(rightEye); self.addChild(mouth); // Add timer visual var timerText = new Text2("1.5", { size: 40, fill: 0xFF0000 }); timerText.anchor.set(0.5, 0.5); timerText.y = -40; // Position above the bomb self.addChild(timerText); // Bomb properties self.active = true; self.exploding = false; self.explosionRadius = 100; // Smaller explosion radius (was 150) self.timer = 1.5; // seconds until explosion self.lastIntersecting = false; // Setup explosion visual (initially hidden) var explosionGraphic = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5, alpha: 0, scaleX: 0.7, // Scale down explosion graphic (70% of original size) scaleY: 0.7 // Scale down explosion graphic (70% of original size) }); self.update = function () { if (!self.active) return; if (!self.exploding) { // Update timer self.timer -= 1 / 60; // 60fps timerText.setText(Math.max(0, self.timer).toFixed(1)); // Pulse effect as timer gets lower var pulseScale = 1.0 + Math.sin(LK.ticks / 5) * 0.1 * (1.5 - self.timer) / 1.5; bombGraphic.scale.set(pulseScale, pulseScale); // Make eyes look more panicked as timer decreases var eyeScale = 0.2 + (1.5 - self.timer) * 0.1; leftEyeWhite.scale.set(eyeScale, eyeScale); rightEyeWhite.scale.set(eyeScale, eyeScale); // Make mouth more worried mouth.scaleX = 0.4 + (1.5 - self.timer) * 0.2; // Start explosion when timer reaches 0 if (self.timer <= 0) { self.startExplosion(); } } }; self.startExplosion = function () { self.exploding = true; timerText.setText(""); bombGraphic.alpha = 0; leftEye.alpha = 0; rightEye.alpha = 0; mouth.alpha = 0; // Show explosion explosionGraphic.alpha = 1; // Immediately set active to false // This prevents collision detection from triggering after explosion is complete self.active = false; // Explosion animation tween(explosionGraphic, { alpha: 0, scaleX: 1.4, // Smaller expansion (was 2) scaleY: 1.4 // Smaller expansion (was 2) }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Make sure explosion is completely inactive after animation finishes self.exploding = false; if (self && self.parent) { self.destroy(); } } }); }; return self; }); var CubeRoom = Container.expand(function () { var self = Container.call(this); // Room properties self.walls = []; self.wallThickness = 50; self.roomWidth = 1600; self.roomHeight = 1600; self.roomX = 0; self.roomY = 0; self.init = function (x, y, width, height) { self.roomX = x || (2048 - self.roomWidth) / 2; self.roomY = y || 800; self.roomWidth = width || 1200; // Smaller default room width self.roomHeight = height || 1200; // Smaller default room height // Create walls self.createWalls(); }; self.createWalls = function () { // Top wall var topWall = new Wall(); topWall.init(self.roomWidth, self.wallThickness, 0x555555); topWall.x = self.roomX; topWall.y = self.roomY; self.addChild(topWall); self.walls.push(topWall); // Bottom wall var bottomWall = new Wall(); bottomWall.init(self.roomWidth, self.wallThickness, 0x555555); bottomWall.x = self.roomX; bottomWall.y = self.roomY + self.roomHeight - self.wallThickness; self.addChild(bottomWall); self.walls.push(bottomWall); // Left wall var leftWall = new Wall(); leftWall.init(self.wallThickness, self.roomHeight, 0x444444); leftWall.x = self.roomX; leftWall.y = self.roomY; self.addChild(leftWall); self.walls.push(leftWall); // Right wall var rightWall = new Wall(); rightWall.init(self.wallThickness, self.roomHeight, 0x444444); rightWall.x = self.roomX + self.roomWidth - self.wallThickness; rightWall.y = self.roomY; self.addChild(rightWall); self.walls.push(rightWall); }; self.getWalls = function () { return self.walls; }; self.getInnerBounds = function () { return { x: self.roomX + self.wallThickness, y: self.roomY + self.wallThickness, width: self.roomWidth - self.wallThickness * 2, height: self.roomHeight - self.wallThickness * 2 }; }; return self; }); var HealthBar = Container.expand(function () { var self = Container.call(this); var background = self.attachAsset('healthBarBg', { anchorX: 0, anchorY: 0 }); var foreground = self.attachAsset('healthBarFg', { anchorX: 0, anchorY: 0 }); self.setHealth = function (percent) { foreground.scale.x = Math.max(0, Math.min(1, percent)); }; return self; }); var Heart = Container.expand(function () { var self = Container.call(this); var heartGraphic = self.attachAsset('heart', { anchorX: 0.5, anchorY: 0.5 }); self.health = 3; self.invulnerable = false; self.lastX = 0; self.lastY = 0; self.down = function (x, y, obj) { self.dragging = true; }; self.up = function (x, y, obj) { self.dragging = false; }; self.takeDamage = function () { if (self.invulnerable) return; // Set health to 0 directly to kill player immediately self.health = 0; LK.getSound('hit').play(); // Flash red when taking damage LK.effects.flashObject(self, 0xff0000, 500); // No need for invulnerability since player dies immediately LK.getSound('gameOver').play(); LK.showGameOver(); }; self.update = function () { self.lastX = self.x; self.lastY = self.y; }; return self; }); var Laser = Container.expand(function () { var self = Container.call(this); var laserGraphic = self.attachAsset('laser', { anchorX: 0.5, anchorY: 0.5 }); self.active = true; self.direction = 1; // 1: vertical, 2: diagonal left, 3: diagonal right self.speed = 15; self.initialSpeed = 0; // Store initial speed for acceleration calculation self.maxSpeed = 0; // Will be set to 4x initial speed self.lastY = 0; self.lastIntersecting = false; self.setup = function (direction, speed) { self.direction = direction || 1; self.initialSpeed = speed ? speed / 4 : 3.75; // Start at 1/4 of the target speed self.speed = self.initialSpeed; self.maxSpeed = self.initialSpeed * 4; // Max speed is 4x the initial speed if (self.direction === 1) { // Vertical laser laserGraphic.rotation = 0; } else if (self.direction === 2) { // Diagonal left laserGraphic.rotation = Math.PI / 4; } else if (self.direction === 3) { // Diagonal right laserGraphic.rotation = -Math.PI / 4; } // Start accelerating the laser using tween with faster acceleration tween(self, { speed: self.maxSpeed }, { duration: 1000, // Accelerate over 1 second instead of 2 easing: tween.easeInQuad // More aggressive acceleration curve }); }; self.update = function () { self.lastY = self.y; if (self.direction === 1) { self.y += self.speed; } else if (self.direction === 2) { self.y += self.speed; self.x -= self.speed * 0.8; } else if (self.direction === 3) { self.y += self.speed; self.x += self.speed * 0.8; } }; return self; }); var PlayerHealthDisplay = Container.expand(function () { var self = Container.call(this); var heartsContainer = new Container(); self.addChild(heartsContainer); self.updateHealth = function (health) { heartsContainer.removeChildren(); for (var i = 0; i < health; i++) { var heartIcon = LK.getAsset('heart', { anchorX: 0.5, anchorY: 0.5, scale: 0.3 }); heartIcon.x = i * 70; heartsContainer.addChild(heartIcon); } }; return self; }); var Skeleton = Container.expand(function () { var self = Container.call(this); // Create skeleton body var skeletonGraphic = self.attachAsset('skeleton', { anchorX: 0.5, anchorY: 0.5 }); // Add jacket on top var jacketGraphic = self.attachAsset('jacket', { anchorX: 0.5, anchorY: 0.5, y: -20 }); self.maxHealth = 300; self.health = self.maxHealth; self.attackCooldown = 0; self.attackPattern = 1; self.lastAttackTime = 0; self.warningIndicator = null; self.nextAttackPosition = null; self.takeDamage = function (amount) { self.health -= amount; // Flash red when taking damage LK.effects.flashObject(self, 0xff0000, 300); if (self.health <= 0) { LK.getSound('victory').play(); LK.showYouWin(); } // Increase difficulty as health decreases if (self.health < self.maxHealth * 0.7 && self.attackPattern === 1) { self.attackPattern = 2; // More frequent attacks } else if (self.health < self.maxHealth * 0.4 && self.attackPattern === 2) { self.attackPattern = 3; // Even more frequent and complex attacks } }; self.update = function () { self.attackCooldown--; // Subtle movement self.x += Math.sin(LK.ticks / 20) * 2; // Update warning indicator position if it exists if (self.warningIndicator && self.warningIndicator.parent) { if (self.nextAttackPosition) { self.warningIndicator.x = self.nextAttackPosition; } // Add subtle animation to make warning more noticeable self.warningIndicator.y += Math.sin(LK.ticks / 10) * 0.7; } }; // Create attack based on current pattern self.createAttack = function () { if (self.attackCooldown > 0) return null; var attack; var now = Date.now(); // Ensure minimum time between attacks if (now - self.lastAttackTime < 800) return null; self.lastAttackTime = now; // Check if we should create a bomb attack (if available and bombs are active) if (bombAttackActive && Math.random() < 0.3) { self.attackCooldown = 100; // Longer cooldown for bomb attacks attack = { type: 'bomb', position: { x: roomBounds.x + Math.random() * (roomBounds.width - 100) + 50, y: roomBounds.y + Math.random() * (roomBounds.height - 100) + 50 } }; return attack; } // Different attack patterns based on skeleton's health if (self.attackPattern === 1) { // Basic pattern: vertical lasers self.attackCooldown = 60; attack = { type: 'laser', direction: 1, speed: 15, // This will be scaled in Laser.setup to start slower position: { x: 1024 + Math.random() * 600 - 300 // Reduced position range for smaller room } }; } else if (self.attackPattern === 2) { // Medium pattern: vertical and diagonal lasers self.attackCooldown = 45; var dir = Math.floor(Math.random() * 3) + 1; attack = { type: 'laser', direction: dir, speed: 18, // This will be scaled in Laser.setup to start slower position: { x: 1024 + Math.random() * 700 - 350 // Reduced position range for smaller room } }; } else { // Hard pattern: faster and more varied attacks self.attackCooldown = 30; var dir = Math.floor(Math.random() * 3) + 1; attack = { type: 'laser', direction: dir, speed: 22, // This will be scaled in Laser.setup to start slower position: { x: 1024 + Math.random() * 800 - 400 // Reduced position range for smaller room } }; } // Show warning for where the attack will come from if (attack) { // Remove any existing warning indicator if (self.warningIndicator && self.warningIndicator.parent) { self.warningIndicator.parent.removeChild(self.warningIndicator); } // Create a new warning indicator with enhanced visibility self.warningIndicator = new Container(); var warningLine = LK.getAsset('laser', { anchorX: 0.5, anchorY: 0.5, tint: 0xFF0000, // Red warning color for better visibility scaleY: 2, // Make it thicker alpha: 0.8 // More visible alpha }); // Create a background glow effect var warningGlow = LK.getAsset('laser', { anchorX: 0.5, anchorY: 0.5, tint: 0xFFFF00, // Yellow glow scaleY: 3, // Even thicker for the glow alpha: 0.4 }); // Position the warning indicator at the attack position self.warningIndicator.x = attack.position.x; self.warningIndicator.y = self.y + 150; self.nextAttackPosition = attack.position.x; // Adjust rotation based on attack direction if (attack.direction === 1) { warningLine.rotation = 0; warningGlow.rotation = 0; } else if (attack.direction === 2) { warningLine.rotation = Math.PI / 4; warningGlow.rotation = Math.PI / 4; } else if (attack.direction === 3) { warningLine.rotation = -Math.PI / 4; warningGlow.rotation = -Math.PI / 4; } // Add the glow behind the warning line self.warningIndicator.addChild(warningGlow); self.warningIndicator.addChild(warningLine); // Add text warning var warningText = new Text2("!", { size: 100, fill: 0xFF0000 }); warningText.anchor.set(0.5, 0.5); warningText.y = -warningLine.height * 0.6; self.warningIndicator.addChild(warningText); // Add warning to game immediately and make it visible longer if (game) { game.addChild(self.warningIndicator); // Make the warning flash more dramatically tween(warningLine, { alpha: 0.3 }, { duration: 300, repeat: 6, yoyo: true }); // Pulse the glow tween(warningGlow, { scaleY: 4, alpha: 0.2 }, { duration: 500, repeat: 4, yoyo: true, onComplete: function onComplete() { if (self.warningIndicator && self.warningIndicator.parent) { self.warningIndicator.parent.removeChild(self.warningIndicator); } } }); } } return attack; }; return self; }); var Wall = Container.expand(function () { var self = Container.call(this); var wallGraphic; self.init = function (width, height, color) { // Create a custom wall shape wallGraphic = self.attachAsset('healthBarBg', { anchorX: 0, anchorY: 0 }); // Set size and color wallGraphic.width = width; wallGraphic.height = height; wallGraphic.tint = color || 0x888888; }; return self; }); /**** * Initialize Game ****/ // Game variables var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game variables var heart; var skeleton; var healthBar; var playerHealth; var lasers = []; var bombs = []; var score = 0; var attacksAvoided = 0; var speedBoostActive = false; var bombAttackActive = false; var dragging = false; var cubeRoom; var wallCollisions = []; // Set background color game.setBackgroundColor(0x222222); // Create cube room cubeRoom = game.addChild(new CubeRoom()); cubeRoom.init((2048 - 1200) / 2, 700, 1200, 1200); // Smaller room size var roomBounds = cubeRoom.getInnerBounds(); // Create player heart heart = game.addChild(new Heart()); heart.x = 1024; heart.y = roomBounds.y + roomBounds.height / 2; // Create skeleton enemy skeleton = game.addChild(new Skeleton()); skeleton.x = 1024; skeleton.y = 400; // Create health bar for skeleton healthBar = game.addChild(new HealthBar()); healthBar.x = (2048 - 800) / 2; healthBar.y = 200; // Create player health display playerHealth = game.addChild(new PlayerHealthDisplay()); playerHealth.x = 150; playerHealth.y = 2600; playerHealth.updateHealth(heart.health); // Score text var scoreTxt = new Text2('Attacks Avoided: 0', { size: 70, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.x = 1024; scoreTxt.y = 100; game.addChild(scoreTxt); // Instructions text var instructionsTxt = new Text2('You are trapped in a cube room! Avoid attacks!', { size: 50, fill: 0xFFFFFF }); instructionsTxt.anchor.set(0.5, 0); instructionsTxt.x = 1024; instructionsTxt.y = 2500; game.addChild(instructionsTxt); // Game movement handlers game.move = function (x, y, obj) { if (dragging) { // Move heart to cursor position heart.x = x; heart.y = y; // Keep heart within cube room bounds var roomBounds = cubeRoom.getInnerBounds(); var halfHeartWidth = heart.width / 2; var halfHeartHeight = heart.height / 2; // Constrain movement to inside the room heart.x = Math.max(roomBounds.x + halfHeartWidth, Math.min(heart.x, roomBounds.x + roomBounds.width - halfHeartWidth)); heart.y = Math.max(roomBounds.y + halfHeartHeight, Math.min(heart.y, roomBounds.y + roomBounds.height - halfHeartHeight)); } }; game.down = function (x, y, obj) { dragging = true; }; game.up = function (x, y, obj) { dragging = false; }; // Main game update loop game.update = function () { // Update heart heart.update(); // Get room walls for collision checking var walls = cubeRoom.getWalls(); var roomBounds = cubeRoom.getInnerBounds(); // Update skeleton and create new attacks skeleton.update(); // Adjust attack cooldown based on number of avoided attacks if (speedBoostActive && skeleton.attackCooldown <= 0) { // Make attack spawn 1.5x slower after 20 attacks avoided skeleton.attackCooldown *= 1.5; } // Check if we should activate bomb attacks at 10 avoided attacks if (attacksAvoided >= 10 && !bombAttackActive) { bombAttackActive = true; // Display message about the new bomb attack var bombTxt = new Text2('NEW ATTACK: BOMBS will appear in the room!', { size: 70, fill: 0xFF0000 }); bombTxt.anchor.set(0.5, 0.5); bombTxt.x = 1024; bombTxt.y = 1366; game.addChild(bombTxt); // Remove the message after 3 seconds LK.setTimeout(function () { bombTxt.destroy(); }, 3000); } var attack = skeleton.createAttack(); if (attack) { if (attack.type === 'laser') { // Add delay between warning and laser appearance LK.setTimeout(function () { // Only proceed if game is still active if (!game) return; var laser = new Laser(); // Position lasers to appear from within the cube room laser.x = Math.max(roomBounds.x + 100, Math.min(attack.position.x, roomBounds.x + roomBounds.width - 100)); laser.y = skeleton.y + 200; // Apply speed boost if 20 attacks have been avoided var laserSpeed = attack.speed; if (speedBoostActive) { laserSpeed = attack.speed * 2; // Make lasers 2x faster instead of 3x } laser.setup(attack.direction, laserSpeed); laser.lastY = laser.y; laser.lastIntersecting = laser.intersects(heart); lasers.push(laser); game.addChild(laser); // Play a sound when laser appears LK.getSound('hit').play({ volume: 0.3 }); }, 1200); // 1.2 second delay between warning and laser } else if (attack.type === 'bomb') { // Create a new bomb var bomb = new Bomb(); bomb.x = attack.position.x; bomb.y = attack.position.y; bomb.lastIntersecting = bomb.intersects(heart); bombs.push(bomb); game.addChild(bomb); // Play a sound when bomb appears LK.getSound('hit').play({ volume: 0.3 }); } } // Update bombs for (var i = bombs.length - 1; i >= 0; i--) { var bomb = bombs[i]; bomb.update(); // Check for collision with heart during explosion var currentIntersecting = bomb.intersects(heart); // Only check collision if the bomb is exploding AND still active if (bomb.exploding && bomb.active && !bomb.lastIntersecting && currentIntersecting) { // Heart was hit by explosion heart.takeDamage(); playerHealth.updateHealth(heart.health); } // Remove bombs that have finished exploding if (bomb.exploding && bomb.alpha <= 0) { // After bomb explodes, create a new one LK.setTimeout(function () { if (!game) return; var newAttack = { type: 'bomb', position: { x: roomBounds.x + Math.random() * (roomBounds.width - 100) + 50, y: roomBounds.y + Math.random() * (roomBounds.height - 100) + 50 } }; var newBomb = new Bomb(); newBomb.x = newAttack.position.x; newBomb.y = newAttack.position.y; newBomb.lastIntersecting = newBomb.intersects(heart); bombs.push(newBomb); game.addChild(newBomb); }, 500); bomb.destroy(); bombs.splice(i, 1); } bomb.lastIntersecting = currentIntersecting; } // Update lasers for (var i = lasers.length - 1; i >= 0; i--) { var laser = lasers[i]; laser.update(); // Check for collisions with heart var currentIntersecting = laser.intersects(heart); if (!laser.lastIntersecting && currentIntersecting) { // Heart was hit by laser heart.takeDamage(); playerHealth.updateHealth(heart.health); } // Remove lasers that go off screen if (laser.lastY < 2800 && laser.y > 2800 || laser.x < -200 || laser.x > 2248) { // If we successfully avoided the laser, damage the skeleton if (!currentIntersecting && laser.active) { score++; attacksAvoided++; scoreTxt.setText('Attacks Avoided: ' + score); skeleton.takeDamage(10); // Increased damage to the skeleton when avoiding an attack healthBar.setHealth(skeleton.health / skeleton.maxHealth); laser.active = false; // Mark as processed LK.getSound('avoid').play(); // Flash the skeleton green to indicate they're taking damage LK.effects.flashObject(skeleton, 0x00ff00, 300); // Check if we've avoided 20 attacks and haven't activated the speed boost yet if (attacksAvoided >= 20 && !speedBoostActive) { speedBoostActive = true; // Display message about the speed boost and slower spawn rate var boostTxt = new Text2('DANGER! Lasers 2x FASTER but SPAWN 1.5x SLOWER!', { size: 70, fill: 0xFF0000 }); boostTxt.anchor.set(0.5, 0.5); boostTxt.x = 1024; boostTxt.y = 1366; game.addChild(boostTxt); // Remove the message after 3 seconds LK.setTimeout(function () { boostTxt.destroy(); }, 3000); } } // Remove laser laser.destroy(); lasers.splice(i, 1); } laser.lastIntersecting = currentIntersecting; } };
===================================================================
--- original.js
+++ change.js