User prompt
player and enemi doubble health bar
User prompt
make enemy slow move
User prompt
make player and bos long health bar
User prompt
make player can shoot left direction
User prompt
double jump
Code edit (1 edits merged)
Please save this source code
User prompt
Epic Boss Rush
Initial prompt
boss fight side scrolling game
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Boss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 200; self.maxHealth = 200; self.attackPattern = 0; self.jumpCount = 0; // Initialize jump count self.attackCooldown = 3000; // ms self.canAttack = true; self.attackTimer = null; self.movementSpeed = 1.5; // Reduced speed for slower movement self.direction = 1; // 1 = right, -1 = left self.phaseChangeThreshold = 50; // Health threshold for phase change self.isPhaseTwo = false; self.update = function () { // Boss movement if (!self.isPhaseTwo) { // Phase 1 movement: back and forth self.x += self.movementSpeed * self.direction; if (self.x > 1800 || self.x < 600) { self.direction *= -1; } } else { // Phase 2 movement: predictive follow player // Maintain a safe distance from the hero var safeDistance = 200; var predictionFactor = 0.1; // Factor to predict hero's future position var predictedHeroX = hero.x + hero.speed * predictionFactor * (pressedRight ? 1 : pressedLeft ? -1 : 0); if (self.x < predictedHeroX - safeDistance) { self.x += self.movementSpeed * 0.5; } else if (self.x > predictedHeroX + safeDistance) { self.x -= self.movementSpeed * 0.5; } } // Always perform long jumps and attack if (self.isGrounded || self.jumpCount < 4) { self.velocityY = -30; // Increased jump force for long jumps self.isGrounded = false; self.jumpCount++; // Increment jump count self.attack(); // Attack during jump } self.velocityY += 0.7; // Gravity self.y += self.velocityY; if (self.y >= groundLevel - bossGraphics.height / 2) { self.y = groundLevel - bossGraphics.height / 2; self.velocityY = 0; self.isGrounded = true; self.jumpCount = 0; // Reset jump count when grounded } // Attack if possible if (self.canAttack) { self.attack(); } // Check for phase change if (!self.isPhaseTwo && self.health <= self.phaseChangeThreshold) { self.enterPhaseTwo(); } }; self.attack = function () { self.canAttack = false; // Different attack patterns if (self.isPhaseTwo) { // Phase 2 - more aggressive attacks switch (Math.floor(Math.random() * 3)) { case 0: self.spreadAttack(); break; case 1: self.targetedAttack(); break; } } else { // Phase 1 - basic attacks if (Math.random() > 0.5) { self.singleAttack(); } else { self.targetedAttack(); } } // Reset attack cooldown self.attackTimer = LK.setTimeout(function () { self.canAttack = true; }, self.attackCooldown); }; self.singleAttack = function () { var projectile = new BossProjectile(); projectile.x = self.x; projectile.y = self.y; game.addChild(projectile); bossProjectiles.push(projectile); }; self.spreadAttack = function () { for (var i = -2; i <= 2; i++) { var projectile = new BossProjectile(); projectile.x = self.x; projectile.y = self.y; projectile.velocityX = -5 + i * 2; projectile.velocityY = 5; game.addChild(projectile); bossProjectiles.push(projectile); } }; self.targetedAttack = function () { var projectile = new BossProjectile(); projectile.x = self.x; projectile.y = self.y; // Calculate direction toward player var dx = hero.x - self.x; var dy = hero.y - self.y; var angle = Math.atan2(dy, dx); projectile.velocityX = Math.cos(angle) * 8; projectile.velocityY = Math.sin(angle) * 8; game.addChild(projectile); bossProjectiles.push(projectile); }; self.takeDamage = function (damage) { self.health -= damage; // Flash boss red LK.effects.flashObject(self, 0xff0000, 300); if (self.health <= 0) { self.health = 0; self.onDefeat(); } updateBossHealthBar(); LK.getSound('hit').play(); }; self.enterPhaseTwo = function () { self.isPhaseTwo = true; self.attackCooldown = 1000; // Faster attacks in phase 2 self.movementSpeed = 4; // Faster movement // Flash the boss to indicate phase change LK.effects.flashObject(self, 0xffff00, 1000); // Clear any existing attack timer and reset if (self.attackTimer) { LK.clearTimeout(self.attackTimer); } self.canAttack = true; }; self.onDefeat = function () { LK.getSound('bossDeath').play(); LK.showYouWin(); }; return self; }); var BossProjectile = Container.expand(function () { var self = Container.call(this); var projectileGraphics = self.attachAsset('projectile', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = -8; // Normal speed for enemy bullets self.velocityY = 0; self.damage = 5; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; // Remove if off screen if (self.x < -projectileGraphics.width || self.x > 2048 + projectileGraphics.width || self.y < -projectileGraphics.height || self.y > 2732 + projectileGraphics.height) { self.destroy(); var index = bossProjectiles.indexOf(self); if (index !== -1) { bossProjectiles.splice(index, 1); } } }; return self; }); var Hero = Container.expand(function () { var self = Container.call(this); var heroGraphics = self.attachAsset('hero', { anchorX: 0.5, anchorY: 0.5 }); self.health = 300; self.maxHealth = 300; self.speed = 7; self.jumpForce = -15; self.gravity = 0.7; self.velocityY = 0; self.isJumping = false; self.jumpCount = 0; // Initialize jump count self.isGrounded = false; self.canShoot = true; self.shootCooldown = 500; // ms self.invulnerable = false; self.invulnerabilityTime = 1000; // ms self.update = function () { // Apply gravity self.velocityY += self.gravity; self.y += self.velocityY; // Check if hero is on ground if (self.y >= groundLevel - heroGraphics.height / 2) { self.y = groundLevel - heroGraphics.height / 2; self.velocityY = 0; self.isGrounded = true; self.isJumping = false; self.jumpCount = 0; // Reset jump count when grounded } else { self.isGrounded = false; } // Keep hero within game boundaries if (self.x < heroGraphics.width / 2) { self.x = heroGraphics.width / 2; } else if (self.x > 2048 - heroGraphics.width / 2) { self.x = 2048 - heroGraphics.width / 2; } }; self.jump = function () { if (self.isGrounded || self.jumpCount < 4) { // Allow triple jump self.velocityY = self.jumpForce; self.isJumping = true; self.isGrounded = false; self.jumpCount++; // Increment jump count } }; self.shoot = function () { if (!self.canShoot) { return; } var projectile = new HeroProjectile(); projectile.x = self.x + (pressedLeft ? -50 : 50); // Adjust position based on direction projectile.y = self.y; projectile.velocityX = pressedLeft ? -15 : 15; // Adjust velocity based on direction game.addChild(projectile); projectiles.push(projectile); LK.getSound('shoot').play(); self.canShoot = false; LK.setTimeout(function () { self.canShoot = true; }, self.shootCooldown); }; self.takeDamage = function (damage) { if (self.invulnerable) { return; } self.health -= damage; if (self.health <= 0) { self.health = 0; LK.showGameOver(); } LK.getSound('playerHit').play(); updateHealthBar(); // Flash hero and make invulnerable temporarily self.invulnerable = true; LK.effects.flashObject(self, 0xffffff, 1000); LK.setTimeout(function () { self.invulnerable = false; }, self.invulnerabilityTime); }; return self; }); var HeroProjectile = Container.expand(function () { var self = Container.call(this); var projectileGraphics = self.attachAsset('heroProjectile', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 10; // Increased bullet speed self.damage = 10; self.update = function () { self.x += self.velocityX; // Remove if off screen if (self.x > 2048 + projectileGraphics.width) { self.destroy(); var index = projectiles.indexOf(self); if (index !== -1) { projectiles.splice(index, 1); } } }; return self; }); var Platform = Container.expand(function () { var self = Container.call(this); var platformGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { // Store lastY for transition detection if (self.lastY === undefined) { self.lastY = self.y; } // Update lastY self.lastY = self.y; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x34495e }); /**** * Game Code ****/ // Game variables var hero; var boss; var platforms = []; var projectiles = []; var bossProjectiles = []; var groundLevel = 2400; var heroHealthBar; var heroHealthBarBg; var bossHealthBar; var bossHealthBarBg; var moveLeftBtn; var moveRightBtn; var jumpBtn; var shootBtn; var pressedLeft = false; var pressedRight = false; // Set up game environment function setupGame() { // Add background image var background = LK.getAsset('backgroundImage', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); game.addChild(background); // Create hero hero = new Hero(); hero.x = 400; hero.y = groundLevel - hero.height / 2; game.addChild(hero); // Create boss boss = new Boss(); boss.x = 1600; boss.y = groundLevel - boss.height / 2; game.addChild(boss); // Create platforms createPlatforms(); // Create UI createUI(); // Start background music LK.playMusic('battleMusic'); } function createPlatforms() { // Ground platform var ground = new Platform(); ground.x = 1024; ground.y = groundLevel + 20; ground.scaleX = 5.12; // Cover full width (2048 / 400) game.addChild(ground); platforms.push(ground); // Add some floating platforms var platformPositions = [{ x: 600, y: 2200 }, { x: 1200, y: 2100 }, { x: 1800, y: 2200 }, { x: 1000, y: 2000 }, { x: 1500, y: 1900 }]; for (var i = 0; i < platformPositions.length; i++) { var platform = new Platform(); platform.x = platformPositions[i].x; platform.y = platformPositions[i].y; game.addChild(platform); platforms.push(platform); } } function createUI() { // Create hero health bar background heroHealthBarBg = LK.getAsset('healthBarBackground', { anchorX: 0, anchorY: 0.5, x: 20, y: 50 }); LK.gui.topLeft.addChild(heroHealthBarBg); // Create hero health bar heroHealthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, x: 20, y: 50 }); LK.gui.topLeft.addChild(heroHealthBar); // Create hero secondary health bar heroSecondaryHealthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, x: 20, y: 90 }); LK.gui.topLeft.addChild(heroSecondaryHealthBar); // Create boss health bar background bossHealthBarBg = LK.getAsset('healthBarBackground', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 50 }); LK.gui.top.addChild(bossHealthBarBg); // Create boss health bar bossHealthBar = LK.getAsset('healthBar', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 50 }); LK.gui.top.addChild(bossHealthBar); // Create boss secondary health bar bossSecondaryHealthBar = LK.getAsset('healthBar', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 90 }); LK.gui.top.addChild(bossSecondaryHealthBar); // Create control buttons createControlButtons(); } function createControlButtons() { // Left movement button moveLeftBtn = LK.getAsset('platform', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, x: 150, y: -150 }); moveLeftBtn.width = 150; moveLeftBtn.height = 150; moveLeftBtn.tint = 0x3498db; LK.gui.bottomLeft.addChild(moveLeftBtn); // Right movement button moveRightBtn = LK.getAsset('platform', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, x: 320, y: -150 }); moveRightBtn.width = 150; moveRightBtn.height = 150; moveRightBtn.tint = 0x3498db; LK.gui.bottomLeft.addChild(moveRightBtn); // Jump button jumpBtn = LK.getAsset('platform', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, x: -150, y: -150 }); jumpBtn.width = 150; jumpBtn.height = 150; jumpBtn.tint = 0x2ecc71; LK.gui.bottomRight.addChild(jumpBtn); // Shoot button shootBtn = LK.getAsset('platform', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, x: -320, y: -150 }); shootBtn.width = 150; shootBtn.height = 150; shootBtn.tint = 0xe74c3c; LK.gui.bottomRight.addChild(shootBtn); // Add event handlers moveLeftBtn.interactive = true; moveRightBtn.interactive = true; jumpBtn.interactive = true; shootBtn.interactive = true; // Setup button events moveLeftBtn.down = function () { pressedLeft = true; }; moveLeftBtn.up = function () { pressedLeft = false; }; moveRightBtn.down = function () { pressedRight = true; }; moveRightBtn.up = function () { pressedRight = false; }; jumpBtn.down = function () { hero.jump(); }; shootBtn.down = function () { hero.shoot(); }; } function updateHealthBar() { var healthPercentage = hero.health / hero.maxHealth; heroHealthBar.scaleX = healthPercentage; // Update secondary health bar var secondaryHealthPercentage = Math.max(0, (hero.health - hero.maxHealth / 2) / (hero.maxHealth / 2)); heroSecondaryHealthBar.scaleX = secondaryHealthPercentage; } function updateBossHealthBar() { var healthPercentage = boss.health / boss.maxHealth; bossHealthBar.scaleX = healthPercentage; // Update secondary health bar var secondaryHealthPercentage = Math.max(0, (boss.health - boss.maxHealth / 2) / (boss.maxHealth / 2)); bossSecondaryHealthBar.scaleX = secondaryHealthPercentage; } function checkCollisions() { // Check hero-boss collision if (hero.intersects(boss) && !hero.invulnerable) { hero.takeDamage(20); // Knock hero back hero.velocityY = -10; if (hero.x < boss.x) { hero.x -= 100; } else { hero.x += 100; } } // Check platform collisions for hero for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; // Only check if hero is falling if (hero.velocityY > 0) { var heroPrevY = hero.y - hero.velocityY; // Check if hero was above platform in previous frame if (heroPrevY + hero.height / 2 <= platform.y - platform.height / 2) { // Check if hero is now colliding with platform if (hero.intersects(platform)) { hero.y = platform.y - platform.height / 2 - hero.height / 2; hero.velocityY = 0; hero.isGrounded = true; hero.isJumping = false; } } } } // Check hero projectile collisions with boss for (var j = projectiles.length - 1; j >= 0; j--) { var projectile = projectiles[j]; if (projectile.intersects(boss)) { boss.takeDamage(projectile.damage); // Remove projectile projectile.destroy(); projectiles.splice(j, 1); } } // Check boss projectile collisions with hero for (var k = bossProjectiles.length - 1; k >= 0; k--) { var bossProjectile = bossProjectiles[k]; if (bossProjectile.intersects(hero) && !hero.invulnerable) { hero.takeDamage(bossProjectile.damage); // Remove projectile bossProjectile.destroy(); bossProjectiles.splice(k, 1); } } } function handleGameInput() { // Handle movement based on button states if (pressedLeft) { hero.x -= hero.speed; } if (pressedRight) { hero.x += hero.speed; } } // Set up game setupGame(); boss.onDefeat = function () { LK.getSound('bossDeath').play(); LK.showYouWin(); }; // Game update loop game.update = function () { // Update hero hero.update(); // Update boss boss.update(); // Update platforms for (var i = 0; i < platforms.length; i++) { platforms[i].update(); } // Update projectiles for (var i = 0; i < projectiles.length; i++) { projectiles[i].update(); } for (var j = 0; j < bossProjectiles.length; j++) { bossProjectiles[j].update(); } // Handle input handleGameInput(); // Check collisions checkCollisions(); }; // Touch events for the game area game.down = function (x, y, obj) { // Check if touch was on control buttons var touchPoint = { x: x, y: y }; var moveLeftPos = moveLeftBtn.parent.toGlobal(moveLeftBtn.position); var moveRightPos = moveRightBtn.parent.toGlobal(moveRightBtn.position); var jumpPos = jumpBtn.parent.toGlobal(jumpBtn.position); var shootPos = shootBtn.parent.toGlobal(shootBtn.position); // Simple distance check for buttons if (distance(touchPoint, moveLeftPos) < 75) { pressedLeft = true; } else if (distance(touchPoint, moveRightPos) < 75) { pressedRight = true; } else if (distance(touchPoint, jumpPos) < 75) { hero.jump(); } else if (distance(touchPoint, shootPos) < 75) { hero.shoot(); } }; game.up = function (x, y, obj) { // Stop movement when touch is released pressedLeft = false; pressedRight = false; }; // Helper function to calculate distance between points function distance(p1, p2) { return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)); }
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 200;
self.maxHealth = 200;
self.attackPattern = 0;
self.jumpCount = 0; // Initialize jump count
self.attackCooldown = 3000; // ms
self.canAttack = true;
self.attackTimer = null;
self.movementSpeed = 1.5; // Reduced speed for slower movement
self.direction = 1; // 1 = right, -1 = left
self.phaseChangeThreshold = 50; // Health threshold for phase change
self.isPhaseTwo = false;
self.update = function () {
// Boss movement
if (!self.isPhaseTwo) {
// Phase 1 movement: back and forth
self.x += self.movementSpeed * self.direction;
if (self.x > 1800 || self.x < 600) {
self.direction *= -1;
}
} else {
// Phase 2 movement: predictive follow player
// Maintain a safe distance from the hero
var safeDistance = 200;
var predictionFactor = 0.1; // Factor to predict hero's future position
var predictedHeroX = hero.x + hero.speed * predictionFactor * (pressedRight ? 1 : pressedLeft ? -1 : 0);
if (self.x < predictedHeroX - safeDistance) {
self.x += self.movementSpeed * 0.5;
} else if (self.x > predictedHeroX + safeDistance) {
self.x -= self.movementSpeed * 0.5;
}
}
// Always perform long jumps and attack
if (self.isGrounded || self.jumpCount < 4) {
self.velocityY = -30; // Increased jump force for long jumps
self.isGrounded = false;
self.jumpCount++; // Increment jump count
self.attack(); // Attack during jump
}
self.velocityY += 0.7; // Gravity
self.y += self.velocityY;
if (self.y >= groundLevel - bossGraphics.height / 2) {
self.y = groundLevel - bossGraphics.height / 2;
self.velocityY = 0;
self.isGrounded = true;
self.jumpCount = 0; // Reset jump count when grounded
}
// Attack if possible
if (self.canAttack) {
self.attack();
}
// Check for phase change
if (!self.isPhaseTwo && self.health <= self.phaseChangeThreshold) {
self.enterPhaseTwo();
}
};
self.attack = function () {
self.canAttack = false;
// Different attack patterns
if (self.isPhaseTwo) {
// Phase 2 - more aggressive attacks
switch (Math.floor(Math.random() * 3)) {
case 0:
self.spreadAttack();
break;
case 1:
self.targetedAttack();
break;
}
} else {
// Phase 1 - basic attacks
if (Math.random() > 0.5) {
self.singleAttack();
} else {
self.targetedAttack();
}
}
// Reset attack cooldown
self.attackTimer = LK.setTimeout(function () {
self.canAttack = true;
}, self.attackCooldown);
};
self.singleAttack = function () {
var projectile = new BossProjectile();
projectile.x = self.x;
projectile.y = self.y;
game.addChild(projectile);
bossProjectiles.push(projectile);
};
self.spreadAttack = function () {
for (var i = -2; i <= 2; i++) {
var projectile = new BossProjectile();
projectile.x = self.x;
projectile.y = self.y;
projectile.velocityX = -5 + i * 2;
projectile.velocityY = 5;
game.addChild(projectile);
bossProjectiles.push(projectile);
}
};
self.targetedAttack = function () {
var projectile = new BossProjectile();
projectile.x = self.x;
projectile.y = self.y;
// Calculate direction toward player
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var angle = Math.atan2(dy, dx);
projectile.velocityX = Math.cos(angle) * 8;
projectile.velocityY = Math.sin(angle) * 8;
game.addChild(projectile);
bossProjectiles.push(projectile);
};
self.takeDamage = function (damage) {
self.health -= damage;
// Flash boss red
LK.effects.flashObject(self, 0xff0000, 300);
if (self.health <= 0) {
self.health = 0;
self.onDefeat();
}
updateBossHealthBar();
LK.getSound('hit').play();
};
self.enterPhaseTwo = function () {
self.isPhaseTwo = true;
self.attackCooldown = 1000; // Faster attacks in phase 2
self.movementSpeed = 4; // Faster movement
// Flash the boss to indicate phase change
LK.effects.flashObject(self, 0xffff00, 1000);
// Clear any existing attack timer and reset
if (self.attackTimer) {
LK.clearTimeout(self.attackTimer);
}
self.canAttack = true;
};
self.onDefeat = function () {
LK.getSound('bossDeath').play();
LK.showYouWin();
};
return self;
});
var BossProjectile = Container.expand(function () {
var self = Container.call(this);
var projectileGraphics = self.attachAsset('projectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = -8; // Normal speed for enemy bullets
self.velocityY = 0;
self.damage = 5;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
// Remove if off screen
if (self.x < -projectileGraphics.width || self.x > 2048 + projectileGraphics.width || self.y < -projectileGraphics.height || self.y > 2732 + projectileGraphics.height) {
self.destroy();
var index = bossProjectiles.indexOf(self);
if (index !== -1) {
bossProjectiles.splice(index, 1);
}
}
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 300;
self.maxHealth = 300;
self.speed = 7;
self.jumpForce = -15;
self.gravity = 0.7;
self.velocityY = 0;
self.isJumping = false;
self.jumpCount = 0; // Initialize jump count
self.isGrounded = false;
self.canShoot = true;
self.shootCooldown = 500; // ms
self.invulnerable = false;
self.invulnerabilityTime = 1000; // ms
self.update = function () {
// Apply gravity
self.velocityY += self.gravity;
self.y += self.velocityY;
// Check if hero is on ground
if (self.y >= groundLevel - heroGraphics.height / 2) {
self.y = groundLevel - heroGraphics.height / 2;
self.velocityY = 0;
self.isGrounded = true;
self.isJumping = false;
self.jumpCount = 0; // Reset jump count when grounded
} else {
self.isGrounded = false;
}
// Keep hero within game boundaries
if (self.x < heroGraphics.width / 2) {
self.x = heroGraphics.width / 2;
} else if (self.x > 2048 - heroGraphics.width / 2) {
self.x = 2048 - heroGraphics.width / 2;
}
};
self.jump = function () {
if (self.isGrounded || self.jumpCount < 4) {
// Allow triple jump
self.velocityY = self.jumpForce;
self.isJumping = true;
self.isGrounded = false;
self.jumpCount++; // Increment jump count
}
};
self.shoot = function () {
if (!self.canShoot) {
return;
}
var projectile = new HeroProjectile();
projectile.x = self.x + (pressedLeft ? -50 : 50); // Adjust position based on direction
projectile.y = self.y;
projectile.velocityX = pressedLeft ? -15 : 15; // Adjust velocity based on direction
game.addChild(projectile);
projectiles.push(projectile);
LK.getSound('shoot').play();
self.canShoot = false;
LK.setTimeout(function () {
self.canShoot = true;
}, self.shootCooldown);
};
self.takeDamage = function (damage) {
if (self.invulnerable) {
return;
}
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
LK.showGameOver();
}
LK.getSound('playerHit').play();
updateHealthBar();
// Flash hero and make invulnerable temporarily
self.invulnerable = true;
LK.effects.flashObject(self, 0xffffff, 1000);
LK.setTimeout(function () {
self.invulnerable = false;
}, self.invulnerabilityTime);
};
return self;
});
var HeroProjectile = Container.expand(function () {
var self = Container.call(this);
var projectileGraphics = self.attachAsset('heroProjectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 10; // Increased bullet speed
self.damage = 10;
self.update = function () {
self.x += self.velocityX;
// Remove if off screen
if (self.x > 2048 + projectileGraphics.width) {
self.destroy();
var index = projectiles.indexOf(self);
if (index !== -1) {
projectiles.splice(index, 1);
}
}
};
return self;
});
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Store lastY for transition detection
if (self.lastY === undefined) {
self.lastY = self.y;
}
// Update lastY
self.lastY = self.y;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x34495e
});
/****
* Game Code
****/
// Game variables
var hero;
var boss;
var platforms = [];
var projectiles = [];
var bossProjectiles = [];
var groundLevel = 2400;
var heroHealthBar;
var heroHealthBarBg;
var bossHealthBar;
var bossHealthBarBg;
var moveLeftBtn;
var moveRightBtn;
var jumpBtn;
var shootBtn;
var pressedLeft = false;
var pressedRight = false;
// Set up game environment
function setupGame() {
// Add background image
var background = LK.getAsset('backgroundImage', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
game.addChild(background);
// Create hero
hero = new Hero();
hero.x = 400;
hero.y = groundLevel - hero.height / 2;
game.addChild(hero);
// Create boss
boss = new Boss();
boss.x = 1600;
boss.y = groundLevel - boss.height / 2;
game.addChild(boss);
// Create platforms
createPlatforms();
// Create UI
createUI();
// Start background music
LK.playMusic('battleMusic');
}
function createPlatforms() {
// Ground platform
var ground = new Platform();
ground.x = 1024;
ground.y = groundLevel + 20;
ground.scaleX = 5.12; // Cover full width (2048 / 400)
game.addChild(ground);
platforms.push(ground);
// Add some floating platforms
var platformPositions = [{
x: 600,
y: 2200
}, {
x: 1200,
y: 2100
}, {
x: 1800,
y: 2200
}, {
x: 1000,
y: 2000
}, {
x: 1500,
y: 1900
}];
for (var i = 0; i < platformPositions.length; i++) {
var platform = new Platform();
platform.x = platformPositions[i].x;
platform.y = platformPositions[i].y;
game.addChild(platform);
platforms.push(platform);
}
}
function createUI() {
// Create hero health bar background
heroHealthBarBg = LK.getAsset('healthBarBackground', {
anchorX: 0,
anchorY: 0.5,
x: 20,
y: 50
});
LK.gui.topLeft.addChild(heroHealthBarBg);
// Create hero health bar
heroHealthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
x: 20,
y: 50
});
LK.gui.topLeft.addChild(heroHealthBar);
// Create hero secondary health bar
heroSecondaryHealthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
x: 20,
y: 90
});
LK.gui.topLeft.addChild(heroSecondaryHealthBar);
// Create boss health bar background
bossHealthBarBg = LK.getAsset('healthBarBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 50
});
LK.gui.top.addChild(bossHealthBarBg);
// Create boss health bar
bossHealthBar = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 50
});
LK.gui.top.addChild(bossHealthBar);
// Create boss secondary health bar
bossSecondaryHealthBar = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 90
});
LK.gui.top.addChild(bossSecondaryHealthBar);
// Create control buttons
createControlButtons();
}
function createControlButtons() {
// Left movement button
moveLeftBtn = LK.getAsset('platform', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
x: 150,
y: -150
});
moveLeftBtn.width = 150;
moveLeftBtn.height = 150;
moveLeftBtn.tint = 0x3498db;
LK.gui.bottomLeft.addChild(moveLeftBtn);
// Right movement button
moveRightBtn = LK.getAsset('platform', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
x: 320,
y: -150
});
moveRightBtn.width = 150;
moveRightBtn.height = 150;
moveRightBtn.tint = 0x3498db;
LK.gui.bottomLeft.addChild(moveRightBtn);
// Jump button
jumpBtn = LK.getAsset('platform', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
x: -150,
y: -150
});
jumpBtn.width = 150;
jumpBtn.height = 150;
jumpBtn.tint = 0x2ecc71;
LK.gui.bottomRight.addChild(jumpBtn);
// Shoot button
shootBtn = LK.getAsset('platform', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
x: -320,
y: -150
});
shootBtn.width = 150;
shootBtn.height = 150;
shootBtn.tint = 0xe74c3c;
LK.gui.bottomRight.addChild(shootBtn);
// Add event handlers
moveLeftBtn.interactive = true;
moveRightBtn.interactive = true;
jumpBtn.interactive = true;
shootBtn.interactive = true;
// Setup button events
moveLeftBtn.down = function () {
pressedLeft = true;
};
moveLeftBtn.up = function () {
pressedLeft = false;
};
moveRightBtn.down = function () {
pressedRight = true;
};
moveRightBtn.up = function () {
pressedRight = false;
};
jumpBtn.down = function () {
hero.jump();
};
shootBtn.down = function () {
hero.shoot();
};
}
function updateHealthBar() {
var healthPercentage = hero.health / hero.maxHealth;
heroHealthBar.scaleX = healthPercentage;
// Update secondary health bar
var secondaryHealthPercentage = Math.max(0, (hero.health - hero.maxHealth / 2) / (hero.maxHealth / 2));
heroSecondaryHealthBar.scaleX = secondaryHealthPercentage;
}
function updateBossHealthBar() {
var healthPercentage = boss.health / boss.maxHealth;
bossHealthBar.scaleX = healthPercentage;
// Update secondary health bar
var secondaryHealthPercentage = Math.max(0, (boss.health - boss.maxHealth / 2) / (boss.maxHealth / 2));
bossSecondaryHealthBar.scaleX = secondaryHealthPercentage;
}
function checkCollisions() {
// Check hero-boss collision
if (hero.intersects(boss) && !hero.invulnerable) {
hero.takeDamage(20);
// Knock hero back
hero.velocityY = -10;
if (hero.x < boss.x) {
hero.x -= 100;
} else {
hero.x += 100;
}
}
// Check platform collisions for hero
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
// Only check if hero is falling
if (hero.velocityY > 0) {
var heroPrevY = hero.y - hero.velocityY;
// Check if hero was above platform in previous frame
if (heroPrevY + hero.height / 2 <= platform.y - platform.height / 2) {
// Check if hero is now colliding with platform
if (hero.intersects(platform)) {
hero.y = platform.y - platform.height / 2 - hero.height / 2;
hero.velocityY = 0;
hero.isGrounded = true;
hero.isJumping = false;
}
}
}
}
// Check hero projectile collisions with boss
for (var j = projectiles.length - 1; j >= 0; j--) {
var projectile = projectiles[j];
if (projectile.intersects(boss)) {
boss.takeDamage(projectile.damage);
// Remove projectile
projectile.destroy();
projectiles.splice(j, 1);
}
}
// Check boss projectile collisions with hero
for (var k = bossProjectiles.length - 1; k >= 0; k--) {
var bossProjectile = bossProjectiles[k];
if (bossProjectile.intersects(hero) && !hero.invulnerable) {
hero.takeDamage(bossProjectile.damage);
// Remove projectile
bossProjectile.destroy();
bossProjectiles.splice(k, 1);
}
}
}
function handleGameInput() {
// Handle movement based on button states
if (pressedLeft) {
hero.x -= hero.speed;
}
if (pressedRight) {
hero.x += hero.speed;
}
}
// Set up game
setupGame();
boss.onDefeat = function () {
LK.getSound('bossDeath').play();
LK.showYouWin();
};
// Game update loop
game.update = function () {
// Update hero
hero.update();
// Update boss
boss.update();
// Update platforms
for (var i = 0; i < platforms.length; i++) {
platforms[i].update();
}
// Update projectiles
for (var i = 0; i < projectiles.length; i++) {
projectiles[i].update();
}
for (var j = 0; j < bossProjectiles.length; j++) {
bossProjectiles[j].update();
}
// Handle input
handleGameInput();
// Check collisions
checkCollisions();
};
// Touch events for the game area
game.down = function (x, y, obj) {
// Check if touch was on control buttons
var touchPoint = {
x: x,
y: y
};
var moveLeftPos = moveLeftBtn.parent.toGlobal(moveLeftBtn.position);
var moveRightPos = moveRightBtn.parent.toGlobal(moveRightBtn.position);
var jumpPos = jumpBtn.parent.toGlobal(jumpBtn.position);
var shootPos = shootBtn.parent.toGlobal(shootBtn.position);
// Simple distance check for buttons
if (distance(touchPoint, moveLeftPos) < 75) {
pressedLeft = true;
} else if (distance(touchPoint, moveRightPos) < 75) {
pressedRight = true;
} else if (distance(touchPoint, jumpPos) < 75) {
hero.jump();
} else if (distance(touchPoint, shootPos) < 75) {
hero.shoot();
}
};
game.up = function (x, y, obj) {
// Stop movement when touch is released
pressedLeft = false;
pressedRight = false;
};
// Helper function to calculate distance between points
function distance(p1, p2) {
return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
}
chibi mario bross stand fight Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
chibi fat bowser left pose. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
rock pattern. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
chibi fire ball. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
8 bit image dark castle corridor cartoon style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows