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('laser', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x000000
});
// Scale into a more bomb-like shape
bombGraphic.scale.set(0.2, 0.2);
// Add timer visual
var timerText = new Text2("1.5", {
size: 40,
fill: 0xFF0000
});
timerText.anchor.set(0.5, 0.5);
self.addChild(timerText);
// Bomb properties
self.active = true;
self.exploding = false;
self.explosionRadius = 150;
self.timer = 1.5; // seconds until explosion
self.lastIntersecting = false;
// Setup explosion visual (initially hidden)
var explosionGraphic = self.attachAsset('laser', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFF3300,
alpha: 0
});
explosionGraphic.scale.set(1.5, 1.5);
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 = 0.2 + Math.sin(LK.ticks / 5) * 0.03 * (1.5 - self.timer) / 1.5;
bombGraphic.scale.set(pulseScale, pulseScale);
// Start explosion when timer reaches 0
if (self.timer <= 0) {
self.startExplosion();
}
}
};
self.startExplosion = function () {
self.exploding = true;
timerText.setText("");
bombGraphic.alpha = 0;
// Show explosion
explosionGraphic.alpha = 1;
// Explosion animation
tween(explosionGraphic, {
alpha: 0,
scaleX: 3,
scaleY: 3
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
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 * 3; // Make lasers 3x faster
}
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);
if (bomb.exploding && !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 3x 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
@@ -5,8 +5,77 @@
/****
* Classes
****/
+var Bomb = Container.expand(function () {
+ var self = Container.call(this);
+ // Create bomb visual
+ var bombGraphic = self.attachAsset('laser', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ tint: 0x000000
+ });
+ // Scale into a more bomb-like shape
+ bombGraphic.scale.set(0.2, 0.2);
+ // Add timer visual
+ var timerText = new Text2("1.5", {
+ size: 40,
+ fill: 0xFF0000
+ });
+ timerText.anchor.set(0.5, 0.5);
+ self.addChild(timerText);
+ // Bomb properties
+ self.active = true;
+ self.exploding = false;
+ self.explosionRadius = 150;
+ self.timer = 1.5; // seconds until explosion
+ self.lastIntersecting = false;
+ // Setup explosion visual (initially hidden)
+ var explosionGraphic = self.attachAsset('laser', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ tint: 0xFF3300,
+ alpha: 0
+ });
+ explosionGraphic.scale.set(1.5, 1.5);
+ 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 = 0.2 + Math.sin(LK.ticks / 5) * 0.03 * (1.5 - self.timer) / 1.5;
+ bombGraphic.scale.set(pulseScale, pulseScale);
+ // Start explosion when timer reaches 0
+ if (self.timer <= 0) {
+ self.startExplosion();
+ }
+ }
+ };
+ self.startExplosion = function () {
+ self.exploding = true;
+ timerText.setText("");
+ bombGraphic.alpha = 0;
+ // Show explosion
+ explosionGraphic.alpha = 1;
+ // Explosion animation
+ tween(explosionGraphic, {
+ alpha: 0,
+ scaleX: 3,
+ scaleY: 3
+ }, {
+ duration: 500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ if (self && self.parent) {
+ self.destroy();
+ }
+ }
+ });
+ };
+ return self;
+});
var CubeRoom = Container.expand(function () {
var self = Container.call(this);
// Room properties
self.walls = [];
@@ -238,8 +307,20 @@
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;
@@ -396,11 +477,13 @@
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
@@ -478,34 +561,100 @@
if (speedBoostActive && skeleton.attackCooldown <= 0) {
// Make attack spawn 1.5x slower after 20 attacks avoided
skeleton.attackCooldown *= 1.5;
}
- var attack = skeleton.createAttack();
- if (attack && attack.type === 'laser') {
- // Add delay between warning and laser appearance
+ // 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 () {
- // 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 * 3; // Make lasers 3x faster
- }
- 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
+ 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 * 3; // Make lasers 3x faster
+ }
+ 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
});
- }, 1200); // 1.2 second delay between warning and laser
+ }
}
+ // 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);
+ if (bomb.exploding && !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();