Reputation: 141
After finally beeing able to make multiple enemies in the game I confronted myself with the most annoying bug ever. I have multiple enemies, a space ship and I can even shoot bullets, but right after I added the enemies to the game and followed the exact same steps as show in this video, the background is gone for some reason, what made the speed of the player character, of the enemies and the bullet went like crazy. Plus, the sprites are duplicating themselves and wont go away, and the only think that I can think is "What the hell am I doing wrong??" because I feel like I can't even follow the steps and copy the code from a video (btw I'm not receiving any error messages). Anyways, here's the full game code.
import pygame
import random
import math
# Initiate pygame
pygame.init()
# Display the game window
screen = pygame.display.set_mode((800, 600))
# Title and Icon
pygame.display.set_caption('Space Invaders')
icon = pygame.image.load('icon.png')
pygame.display.set_icon(icon)
# Background
background = pygame.image.load('background.png')
# Player
playerSprite = pygame.image.load('player.png')
playerX = 370
playerY = 480
playerX_change = 0
# Enemies
enemySprite = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 6
for i in range(num_of_enemies):
enemySprite.append(pygame.image.load('enemy.png'))
enemyX.append(random.randint(0, 736))
enemyY.append(random.randint(50, 150))
enemyX_change.append(4)
enemyY_change.append(40)
# Bullet
bulletSprite = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
bulletY_change = 10
# When bullet_state = 'ready', you can't see the bullet on the screen
# When bullet_state = 'fire', the bullet is currently moving
bullet_state = 'ready'
score = 0
def player(x, y):
screen.blit(playerSprite, (x, y))
def enemy(x, y, i):
screen.blit(enemySprite[i], (x, y))
def fire_bullet(x, y):
global bullet_state
bullet_state = 'fire'
screen.blit(bulletSprite, (x + 16, y + 10))
def isCollision(enemyX, enemyY, bulletX, bulletY):
distance = math.sqrt((math.pow(enemyX - bulletX, 2)) + (math.pow(enemyY - bulletY, 2)))
if distance < 27:
return True
else:
return False
# Game Loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# If a key is pressed, check if it's the right or left arrow key
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -5
if event.key == pygame.K_RIGHT:
playerX_change = 5
if event.key == pygame.K_SPACE:
if bullet_state == 'ready':
bulletX = playerX
fire_bullet(playerX, bulletY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# Player movement
playerX += playerX_change
# Prevents the player from going off the border
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
# Enemies movement
for i in range(num_of_enemies):
enemyX[i] += enemyX_change[i]
if enemyX[i] <= 0:
enemyX_change[i] = 4
enemyY[i] += enemyX_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] = -4
enemyY[i] += enemyY_change[i]
# Collision
collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
bulletY = 480
bullet_state = 'ready'
score += 1
print(score)
enemyX[i] = random.randint(0, 736)
enemyY[i] = random.randint(50, 150)
enemy(enemyX[i], enemyY[i], i)
# Bullet movement
if bulletY <= 0:
bulletY = 480
bullet_state = 'ready'
if bullet_state == 'fire':
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
player(playerX, playerY)
pygame.display.update()
Upvotes: 2
Views: 232
Reputation: 211135
the background is gone for some reason
Of course, because the background
is never blit
to screen
.
the sprites are duplicating themselves and wont go away,
That's because you don't draw the background.
blit
the background
in the main application loop, before the objects of the scene are drawn:
while running:
# [...]
screen.blit(background, (0, 0))
# Enemies movement
for i in range(num_of_enemies):
# [...]
the speed of the player character, of the enemies and the bullet went like crazy.
Use pygame.time.Clock()
to control the frames per second.
clock = pygame.time.Clock()
running = True
while running:
clock.tick(60)
# [...]
Another (less sophisticated) possibility, which is probably use in the tutorial is to use pygame.time.delay()
:
running = True
while running:
pygame.time.delay(10)
# [...]
Upvotes: 2