User prompt
Please fix the bug: 'ReferenceError: background is not defined' in or related to this line: 'if (background && background2) {' Line Number: 409
User prompt
make background image animate
User prompt
Please fix the bug: 'TypeError: tween.add is not a function' in or related to this line: 'tween.add({' Line Number: 70 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
enenmy explode after lose
User prompt
control from bottom
User prompt
make smooth control ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add background
User prompt
reduce enemy multiple bullet
Code edit (1 edits merged)
Please save this source code
User prompt
Boss Battle Blitz
Initial prompt
import pygame import random import sys # Inisialisasi Pygame pygame.init() # Ukuran layar WIDTH = 480 HEIGHT = 600 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Vertical Shooter: Boss Battle") # Warna BLACK = (0, 0, 0) WHITE = (255, 255, 255) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) # Clock untuk mengatur FPS clock = pygame.time.Clock() FPS = 60 # Kelas Player class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((50, 40)) self.image.fill(GREEN) self.rect = self.image.get_rect() self.rect.centerx = WIDTH // 2 self.rect.bottom = HEIGHT - 10 self.speed_x = 0 self.health = 100 self.shoot_delay = 250 # delay tembakan dalam ms self.last_shot = pygame.time.get_ticks() def update(self): # Gerakan player self.speed_x = 0 keystate = pygame.key.get_pressed() if keystate[pygame.K_LEFT]: self.speed_x = -5 if keystate[pygame.K_RIGHT]: self.speed_x = 5 self.rect.x += self.speed_x # Batasi player agar tidak keluar layar if self.rect.right > WIDTH: self.rect.right = WIDTH if self.rect.left < 0: self.rect.left = 0 def shoot(self): now = pygame.time.get_ticks() if now - self.last_shot > self.shoot_delay: self.last_shot = now bullet = Bullet(self.rect.centerx, self.rect.top) all_sprites.add(bullet) bullets.add(bullet) # Kelas Bullet class Bullet(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.image = pygame.Surface((5, 10)) self.image.fill(BLUE) self.rect = self.image.get_rect() self.rect.centerx = x self.rect.bottom = y self.speedy = -10 def update(self): self.rect.y += self.speedy # Hapus bullet jika keluar layar if self.rect.bottom < 0: self.kill() # Kelas Boss class Boss(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((100, 80)) self.image.fill(RED) self.rect = self.image.get_rect() self.rect.centerx = WIDTH // 2 self.rect.y = 50 self.speed_x = 3 self.health = 200 self.shoot_delay = 1000 self.last_shot = pygame.time.get_ticks() self.pattern_timer = pygame.time.get_ticks() self.pattern_duration = 3000 # 3 detik self.movement_pattern = 0 def update(self): # Ganti pola gerakan setiap beberapa detik now = pygame.time.get_ticks() if now - self.pattern_timer > self.pattern_duration: self.pattern_timer = now self.movement_pattern = random.randint(0, 2) # Pola gerakan boss if self.movement_pattern == 0: # Diam self.speed_x = 0 elif self.movement_pattern == 1: # Gerak kiri-kanan self.speed_x = 3 elif self.movement_pattern == 2: # Gerak lebih cepat self.speed_x = 5 self.rect.x += self.speed_x # Pantulan jika mencapai tepi layar if self.rect.right > WIDTH or self.rect.left < 0: self.speed_x *= -1 def shoot(self): now = pygame.time.get_ticks() if now - self.last_shot > self.shoot_delay: self.last_shot = now # Tembakan boss (3 arah) bullet1 = EnemyBullet(self.rect.left + 20, self.rect.bottom) bullet2 = EnemyBullet(self.rect.centerx, self.rect.bottom) bullet3 = EnemyBullet(self.rect.right - 20, self.rect.bottom) all_sprites.add(bullet1, bullet2, bullet3) enemy_bullets.add(bullet1, bullet2, bullet3) # Kelas Enemy Bullet class EnemyBullet(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.image = pygame.Surface((8, 15)) self.image.fill(RED) self.rect = self.image.get_rect() self.rect.centerx = x self.rect.top = y self.speedy = 7 def update(self): self.rect.y += self.speedy # Hapus bullet jika keluar layar if self.rect.top > HEIGHT: self.kill() # Kelas Explosion class Explosion(pygame.sprite.Sprite): def __init__(self, center, size): super().__init__() self.size = size self.image = pygame.Surface((size, size)) self.image.fill(RED) self.rect = self.image.get_rect() self.rect.center = center self.frame = 0 self.last_update = pygame.time.get_ticks() self.frame_rate = 50 # ms def update(self): now = pygame.time.get_ticks() if now - self.last_update > self.frame_rate: self.last_update = now self.frame += 1 if self.frame == 8: # Jumlah frame animasi self.kill() else: # Ubah warna untuk efek animasi sederhana if self.frame % 2 == 0: self.image.fill(WHITE) else: self.image.fill(RED) # Fungsi untuk menggambar health bar def draw_health_bar(surface, x, y, health, max_health): BAR_LENGTH = 100 BAR_HEIGHT = 10 fill = (health / max_health) * BAR_LENGTH outline_rect = pygame.Rect(x, y, BAR_LENGTH, BAR_HEIGHT) fill_rect = pygame.Rect(x, y, fill, BAR_HEIGHT) pygame.draw.rect(surface, GREEN, fill_rect) pygame.draw.rect(surface, WHITE, outline_rect, 2) # Fungsi untuk menampilkan teks di layar def draw_text(surface, text, size, x, y): font = pygame.font.SysFont("arial", size) text_surface = font.render(text, True, WHITE) text_rect = text_surface.get_rect() text_rect.midtop = (x, y) surface.blit(text_surface, text_rect) # Membuat sprite groups all_sprites = pygame.sprite.Group() bullets = pygame.sprite.Group() enemy_bullets = pygame.sprite.Group() # Membuat player player = Player() all_sprites.add(player) # Membuat boss boss = Boss() all_sprites.add(boss) # Game loop running = True game_over = False score = 0 while running: # Mengatur kecepatan game clock.tick(FPS) # Process input (events) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: player.shoot() if event.key == pygame.K_r and game_over: # Reset game game_over = False all_sprites = pygame.sprite.Group() bullets = pygame.sprite.Group() enemy_bullets = pygame.sprite.Group() player = Player() all_sprites.add(player) boss = Boss() all_sprites.add(boss) score = 0 if not game_over: # Update all_sprites.update() # Boss shoot boss.shoot() # Cek collision bullet player dengan boss hits = pygame.sprite.spritecollide(boss, bullets, True) for hit in hits: boss.health -= 10 score += 10 if boss.health <= 0: explosion = Explosion(boss.rect.center, 80) all_sprites.add(explosion) boss.kill() game_over = True draw_text(screen, "YOU WIN!", 50, WIDTH // 2, HEIGHT // 2) draw_text(screen, "Press R to restart", 30, WIDTH // 2, HEIGHT // 2 + 60) # Cek collision bullet boss dengan player hits = pygame.sprite.spritecollide(player, enemy_bullets, True) for hit in hits: player.health -= 20 if player.health <= 0: explosion = Explosion(player.rect.center, 50) all_sprites.add(explosion) player.kill() game_over = True draw_text(screen, "GAME OVER", 50, WIDTH // 2, HEIGHT // 2) draw_text(screen, "Press R to restart", 30, WIDTH // 2, HEIGHT // 2 + 60) # Render screen.fill(BLACK) all_sprites.draw(screen) # Gambar health bar dan score draw_health_bar(screen, 5, 5, player.health, 100) draw_text(screen, f"Player HP: {player.health}", 18, 60, 5) draw_health_bar(screen, WIDTH - 105, 5, boss.health, 200) draw_text(screen, f"Boss HP: {boss.health}", 18, WIDTH - 40, 5) draw_text(screen, f"Score: {score}", 18, WIDTH // 2, 5) # Jika game over, tampilkan pesan if game_over: draw_text(screen, "Press R to restart", 30, WIDTH // 2, HEIGHT // 2 + 60) # Flip the display pygame.display.flip() pygame.quit() sys.exit()
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Boss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 1000; self.health = self.maxHealth; self.shootCooldown = 60; self.shootPattern = 0; self.patternTime = 0; self.moveDirection = 1; self.moveSpeed = 3; self.phaseThresholds = [0.7, 0.4, 0.1]; self.currentPhase = 0; self.takeDamage = function (amount) { self.health -= amount; self.health = Math.max(0, self.health); LK.getSound('hit').play(); LK.effects.flashObject(self, 0xffffff, 200); updateHealthBars(); // Check for phase transitions var healthPercentage = self.health / self.maxHealth; if (self.currentPhase < self.phaseThresholds.length && healthPercentage <= self.phaseThresholds[self.currentPhase]) { self.transitionPhase(); } if (self.health <= 0) { var explodeBoss = function explodeBoss() { // Create multiple explosion particles for (var i = 0; i < 20; i++) { var particle = new Container(); var size = 30 + Math.random() * 70; var explosionGraphic = particle.attachAsset('bossBullet', { anchorX: 0.5, anchorY: 0.5 }); // Randomize size and position explosionGraphic.width = explosionGraphic.height = size; explosionGraphic.tint = 0xFF4500; // Orange-red color // Position particles randomly around boss center particle.x = self.x + (Math.random() - 0.5) * 200; particle.y = self.y + (Math.random() - 0.5) * 200; game.addChild(particle); // Animate expansion and fade out tween(explosionGraphic, { alpha: 0, width: size * 3, height: size * 3 }, { duration: 800 + Math.random() * 700, easing: tween.easeOut, onFinish: function onFinish() { particle.destroy(); } }); } // Hide the boss graphic self.alpha = 0; // Show win screen after explosion animation LK.setTimeout(function () { LK.effects.flashScreen(0xffffff, 1000); LK.showYouWin(); }, 1200); }; LK.getSound('bossDeath').play(); // Create explosion animation on boss explodeBoss(); } }; self.transitionPhase = function () { self.currentPhase++; self.moveSpeed += 1; self.patternTime = 0; // Increase shoot cooldown with each phase to reduce bullet frequency self.shootCooldown = 120; // Give player a breather when phase changes // Flash the boss to indicate phase change LK.effects.flashObject(self, 0xff00ff, 500); if (self.currentPhase === 1) { // Phase 2: Boss moves faster and changes shoot pattern self.shootPattern = 1; } else if (self.currentPhase === 2) { // Phase 3: Boss moves even faster and uses spiral pattern self.shootPattern = 2; } else if (self.currentPhase === 3) { // Final phase: Boss goes berserk with all patterns self.shootPattern = 3; } }; self.shootBullet = function (angle) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y + 100; // Reduce bullet speed to give player more time to dodge bullet.init(3 + self.currentPhase, angle); game.addChild(bullet); bossBullets.push(bullet); }; self.update = function () { // Movement patterns self.patternTime++; // Basic side-to-side movement self.x += self.moveSpeed * self.moveDirection; // Change direction when hitting screen bounds if (self.x > 1800) { self.moveDirection = -1; } else if (self.x < 248) { self.moveDirection = 1; } // Additional vertical movement in later phases if (self.currentPhase >= 1) { self.y += Math.sin(self.patternTime * 0.02) * 2; } // Shooting logic self.shootCooldown--; if (self.shootCooldown <= 0) { LK.getSound('bossShoot').play(); // Different shooting patterns based on current phase - simplified to reduce bullet count switch (self.shootPattern) { case 0: // Basic straight shots - unchanged self.shootBullet(0); self.shootCooldown = 90; //{y} // Increased cooldown break; case 1: // Reduced three-way to two-way spread self.shootBullet(-0.2); self.shootBullet(0.2); self.shootCooldown = 80; //{B} // Increased cooldown break; case 2: // Reduced spiral pattern from 5 to 3 bullets var angleOffset = self.patternTime * 0.1 % (Math.PI * 2); for (var i = 0; i < 3; i++) { // Reduced from 5 to 3 var angle = angleOffset + i * Math.PI * 2 / 3; // Adjusted spacing self.shootBullet(angle); } self.shootCooldown = 100; //{G} // Increased cooldown break; case 3: // Simplified berserk mode if (self.patternTime % 180 < 90) { // Single straight shot instead of triple self.shootBullet(0); self.shootCooldown = 40; // Increased cooldown } else { // Reduced spiral pattern var angleOffset = self.patternTime * 0.15 % (Math.PI * 2); for (var i = 0; i < 4; i++) { // Reduced from 8 to 4 var angle = angleOffset + i * Math.PI * 2 / 4; // Adjusted spacing self.shootBullet(angle); } self.shootCooldown = 90; //{M} // Increased cooldown } break; } } }; return self; }); var BossBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bossBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.angle = 0; self.speedX = 0; self.init = function (speed, angle) { self.speed = speed || 8; self.angle = angle || 0; self.speedX = Math.sin(self.angle) * self.speed; self.speedY = Math.cos(self.angle) * self.speed; }; self.update = function () { self.y += self.speedY; self.x += self.speedX; }; return self; }); var HealthBar = Container.expand(function () { var self = Container.call(this); var background = self.attachAsset('healthBarBg', { anchorX: 0, anchorY: 0 }); var bar = self.attachAsset('healthBar', { anchorX: 0, anchorY: 0 }); self.setPercentage = function (percentage) { bar.scale.x = Math.max(0, Math.min(1, percentage)); }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 100; self.health = self.maxHealth; self.shootCooldown = 0; self.shootCooldownMax = 15; self.invulnerable = false; self.invulnerableTime = 0; self.shoot = function () { if (self.shootCooldown <= 0) { var bullet = new PlayerBullet(); bullet.x = self.x; bullet.y = self.y - 60; game.addChild(bullet); playerBullets.push(bullet); self.shootCooldown = self.shootCooldownMax; LK.getSound('playerShoot').play(); } }; self.takeDamage = function (amount) { if (!self.invulnerable) { self.health -= amount; self.health = Math.max(0, self.health); LK.getSound('playerHit').play(); LK.effects.flashObject(self, 0xff0000, 500); updateHealthBars(); self.invulnerable = true; self.invulnerableTime = 60; if (self.health <= 0) { LK.showGameOver(); } } }; self.update = function () { if (self.shootCooldown > 0) { self.shootCooldown--; } if (self.invulnerable) { self.invulnerableTime--; shipGraphics.alpha = Math.sin(LK.ticks * 0.5) * 0.5 + 0.5; if (self.invulnerableTime <= 0) { self.invulnerable = false; shipGraphics.alpha = 1; } } }; return self; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -15; self.damage = 10; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000022 }); /**** * Game Code ****/ // Game variables var player; var boss; var playerBullets = []; var bossBullets = []; var playerHealthBar; var bossHealthBar; var scoreText; var score = 0; var isShooting = false; var dragTarget = null; var background; var background2; // Initialize the game function initializeGame() { // Add background var background = game.addChild(LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 })); // Create a second background for seamless scrolling var background2 = game.addChild(LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 2732 // Position it above the first background })); // Setup player player = new Player(); player.x = 2048 / 2; player.y = 2732 - 200; game.addChild(player); // Setup boss boss = new Boss(); boss.x = 2048 / 2; boss.y = 400; game.addChild(boss); // Initialize bullet arrays playerBullets = []; bossBullets = []; // Setup UI setupUI(); // Play background music LK.playMusic('battleMusic'); // Reset score score = 0; LK.setScore(score); updateScoreText(); } function setupUI() { // Player health bar (bottom left) playerHealthBar = new HealthBar(); playerHealthBar.x = 50; playerHealthBar.y = 2732 - 80; LK.gui.addChild(playerHealthBar); // Boss health bar (top center) bossHealthBar = new HealthBar(); bossHealthBar.x = (2048 - 400) / 2; bossHealthBar.y = 50; LK.gui.addChild(bossHealthBar); // Score text scoreText = new Text2('Score: 0', { size: 50, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); scoreText.x = 2048 - 50; scoreText.y = 50; LK.gui.addChild(scoreText); updateHealthBars(); } function updateHealthBars() { if (player && playerHealthBar) { playerHealthBar.setPercentage(player.health / player.maxHealth); } if (boss && bossHealthBar) { bossHealthBar.setPercentage(boss.health / boss.maxHealth); } } function updateScoreText() { if (scoreText) { scoreText.setText('Score: ' + score); } } function addScore(points) { score += points; LK.setScore(score); updateScoreText(); } // Game events game.down = function (x, y, obj) { isShooting = true; dragTarget = player; handleMove(x, y, obj); }; game.up = function (x, y, obj) { isShooting = false; dragTarget = null; }; function handleMove(x, y, obj) { if (dragTarget === player) { // Keep player within screen bounds, but fixed at bottom player.x = Math.max(50, Math.min(2048 - 50, x)); player.y = 2732 - 200; // Fixed position at bottom of screen } } game.move = handleMove; // Main game update loop game.update = function () { // Animate background scrolling if (background && background2) { // Move backgrounds down background.y += 1; background2.y += 1; // Reset position when background goes off screen if (background.y - background.height / 2 > 2732) { background.y = background2.y - background.height; } if (background2.y - background2.height / 2 > 2732) { background2.y = background.y - background2.height; } } // Update player if (player) { player.update(); // Auto shooting if (isShooting) { player.shoot(); } } // Update boss if (boss) { boss.update(); } // Update player bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; // Check if bullet is offscreen if (bullet.y < -50) { bullet.destroy(); playerBullets.splice(i, 1); continue; } // Check for collision with boss if (boss && bullet.intersects(boss)) { boss.takeDamage(bullet.damage); addScore(10); bullet.destroy(); playerBullets.splice(i, 1); } } // Update boss bullets for (var j = bossBullets.length - 1; j >= 0; j--) { var bossBullet = bossBullets[j]; // Check if bullet is offscreen if (bossBullet.y > 2732 + 50 || bossBullet.x < -50 || bossBullet.x > 2048 + 50) { bossBullet.destroy(); bossBullets.splice(j, 1); continue; } // Check for collision with player if (player && !player.invulnerable && bossBullet.intersects(player)) { player.takeDamage(10); bossBullet.destroy(); bossBullets.splice(j, 1); } } }; // Initialize the game initializeGame();
===================================================================
--- original.js
+++ change.js
@@ -289,8 +289,10 @@
var scoreText;
var score = 0;
var isShooting = false;
var dragTarget = null;
+var background;
+var background2;
// Initialize the game
function initializeGame() {
// Add background
var background = game.addChild(LK.getAsset('background', {
16 bit image style top down ufo. In-Game asset. 2d. High contrast. No shadows
16 bit top down flyin war drone. In-Game asset. 2d. High contrast. No shadows
red oval fire ball. In-Game asset. 2d. High contrast. No shadows
top down cloud and blue sky disney style image. In-Game asset. 2d. High contrast. No shadows