如何在Pygame太空街机游戏中实现多子弹连发功能?
Fixing Multi-Bullet Fire & Obstacle Collision in Your Pygame Space Game
Hey there! Let's tackle two key issues here: letting you fire multiple bullets without waiting for the first to leave the screen, and making those bullets actually interact with obstacles. Here's how we'll adjust your code:
Modified Full Code
import random import pygame pygame.init() screen = pygame.display.set_mode((800, 600)) pygame.display.set_caption("Space Invader") icon = pygame.image.load("space-invaders.png") pygame.display.set_icon(icon) background = pygame.image.load("background.png") # Player setup player_image = pygame.image.load("space-invaders.png") playerX = 370 playerY = 480 playerX_change = 0 playerY_change = 0 def player(x, y): screen.blit(player_image, (x, y)) # Obstacle setup obs_image = pygame.image.load("cave-painting (1).png") obsX = random.randint(0, 800) obsY = random.randint(0, 100) obsX_change = 2 obsY_change = 0.3 def obstacle(x, y): screen.blit(obs_image, (x, y)) # Bullet setup - now using a list to track multiple bullets bullet_image = pygame.image.load("bullet.png") bulletY_change = 10 # Speed of bullets bullets = [] # Each entry stores a bullet's (x, y) position def fire_bullet(x, y): screen.blit(bullet_image, (x + 16, y + 10)) # Offset to center bullet on player running = True while running: screen.fill((0, 0, 0)) screen.blit(background, (0, 0)) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # Keydown events if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: playerX_change = -4 if event.key == pygame.K_RIGHT: playerX_change = 4 if event.key == pygame.K_UP: playerY_change = -4 if event.key == pygame.K_DOWN: playerY_change = 4 if event.key == pygame.K_SPACE: # Add a new bullet every time space is pressed (no waiting!) bullets.append((playerX + 16, playerY + 10)) # Center bullet on player # Keyup events if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: playerX_change = 0 if event.key == pygame.K_UP or event.key == pygame.K_DOWN: playerY_change = 0 # Update player position & boundaries playerX += playerX_change playerY += playerY_change if playerX <= 0: playerX = 0 elif playerX >= 765: playerX = 765 if playerY <= 200: playerY = 200 elif playerY >= 480: playerY = 480 # Update obstacle position & boundaries obsX += obsX_change obsY += obsY_change if obsX <= 0: obsX_change = 3 obsY += obsY_change elif obsX >= 736: obsX_change = -3 obsY += obsY_change # Handle all active bullets for bullet in bullets.copy(): bullet_x, bullet_y = bullet # Move bullet upward new_bullet_y = bullet_y - bulletY_change # Draw updated bullet position fire_bullet(bullet_x, new_bullet_y) # Update bullet's position in the list bullets[bullets.index(bullet)] = (bullet_x, new_bullet_y) # Remove bullet if it flies off-screen if new_bullet_y <= 0: bullets.remove(bullet) # Check collision with obstacle (adjust hitbox values for your images!) if (obsX < bullet_x < obsX + 64) and (obsY < new_bullet_y < obsY + 64): # Reset obstacle to random position on hit obsX = random.randint(0, 800) obsY = random.randint(0, 100) # Remove the bullet that hit the obstacle bullets.remove(bullet) # Draw player and obstacle last to keep them on top player(playerX, playerY) obstacle(obsX, obsY) pygame.display.update()
Key Changes Explained
- Multi-bullet support: Replaced single bullet variables with a
bulletslist. Now every space press adds a new bullet to the list, so you can fire continuously without waiting for previous bullets to leave the screen. - Bullet management: We loop through a copy of the bullets list to safely update positions, draw bullets, and remove ones that go off-screen.
- Collision detection: Added basic hitbox checks to make bullets interact with obstacles. When a hit is detected, the obstacle resets to a random position and the bullet is removed. Adjust the
64values in the collision check to match your actual image sizes. - Centered bullet spawn: Added small offsets when firing bullets so they spawn from the center of your player ship instead of the top-left corner, which feels more natural.
Quick Notes
- If you want to limit the maximum number of bullets on screen (to prevent performance issues), add a check before appending to the
bulletslist:if len(bullets) < 5:(replace 5 with your preferred limit). - Double-check the boundary values (like
765for player X) to match your actual image dimensions.
内容的提问来源于stack exchange,提问作者user12211053
相关产品推荐
相关产品推荐

