Reputation: 21
Please help!!
I'm trying to make Space Invaders with Python following this tutorial: https://www.youtube.com/watch?v=FfWpgLFMI7w
I got suuper confused at the part when the guy starts to add for loops, as I'm horrible with them and I don't really understand them.
There need to be multiple enemies, so I make a for loop that iterates through lists of variables and draws enemies. The tutorial went very quickly, and I have no idea what I'm supposed to put "[i]" next to, and what not.
When I run my code (shown below) it says:
Traceback (most recent call last): File "C:/Users/geema/PycharmProjects/pythonpractice/Scripts/myfirstpygame.py", line 139, in <module> enemyX[i] += enemyX_change[i]
I could copy and paste the code, but the purpose of this project is to better understand Python. Please help, I desperately need to fix this. I've looked over every line of code and I can't find any errors.
Here is my code:
import pygame
import random
import math
# initializing pygame
pygame.init()
# creating screen
screen = pygame.display.set_mode((800, 600))
backgroundImg = pygame.image.load('galaxybackground.jpg')
# title
pygame.display.set_caption('Donnaven\'s Game')
# icon
icon = pygame.image.load('gameicon.png')
pygame.display.set_icon(icon)
# player setup
playerImg = pygame.image.load('player.png')
playerX = 370
playerY = 480
playerX_change = 0
PLAYER_SPEED = 0.185 # pixels / frame
def drawPlayer(x, y):
screen.blit(playerImg, (x, y))
# enemy setup
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
ENEMY_SPEED = []
enemy_count = 6
for i in range(enemy_count):
enemyImg.append(pygame.image.load('enemy.png'))
enemyX.append(random.randint(0, 735))
enemyY.append(random.randint(50, 150))
ENEMY_SPEED.append(0.075)
enemyX_change.append(ENEMY_SPEED)
enemyY_change.append(40)
def drawEnemy(x, y, i):
screen.blit(enemyImg[i], (x, y))
# bullet
bulletImg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
""" Bullet state: ready means that you can't
see the bullet on the screen, and if the user
presses space, it will fire. Fire means that
the bullet is currently being fired or moving."""
bullet_state = 'ready'
bulletY_change = 0.75
# scoring system
score = 0
def check_collision(x1, y1, x2, y2):
distance = math.sqrt((math.pow(x2 - x1, 2)) + (math.pow(y2 - y1, 2)))
if distance < 27:
return True
else:
return False
def fire_bullet(x, y):
global bullet_state
bullet_state = 'fire'
screen.blit(bulletImg, (x + 16, y + 10))
# gameloop
running = True
while running:
# drawing screen
screen.fill((93, 92, 99))
# adding background
screen.blit(backgroundImg, (0, 0))
# checking for any events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# checking if keystroke is pressed
if event.type == pygame.KEYDOWN:
# checking if its left or right
if event.key == pygame.K_LEFT:
playerX_change -= PLAYER_SPEED
if event.key == pygame.K_RIGHT:
playerX_change += PLAYER_SPEED
# seeing if space is pressed
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
# setting the x based on input
playerX += playerX_change
# making sure player doesnt go beyond boundaries
if playerX < 0:
playerX = 0
elif playerX >= 736:
playerX = 736
# enemy movement
for i in range(enemy_count):
enemyX[i] += enemyX_change[i]
if enemyX[i] < 0:
enemyX_change[i] = ENEMY_SPEED
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] = -ENEMY_SPEED
enemyY[i] += enemyY_change[i]
# check collision
collision = check_collision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
bulletY = 480
bullet_state = 'ready'
score += 100
# reset enemy position
enemyX[i] = random.randint(0, 736)
enemyY[i] = random.randint(50, 150)
drawEnemy(enemyX[i], enemyY[i], i)
enemyX[i] += enemyX_change
# enemy boundaries
""" also make sure that enemy goes downwards a bit
when it reaches the edge"""
# bullet movement
if bulletY <= 0:
bulletY = 480
bullet_state = 'ready'
if bullet_state == 'fire':
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
# drawing the player
drawPlayer(playerX, playerY)
# drawing the enemy
# update the screen every frame - must be done last
pygame.display.update()
Thank you so so much to anybody who tries to help.
Upvotes: 0
Views: 214
Reputation: 211135
The issue is caused by the line
enemyX_change.append(ENEMY_SPEED)
Since each enemy has its own speed, ENEMY_SPEED
is a list. Therefore, you need to get the speed of an enemy by subscription:
enemyX_change.append(ENEMY_SPEED[i])
However, in lines 153, 157 and 175 some [i]
are still missing:
while running:
# [...]
# enemy movement
for i in range(enemy_count):
enemyX[i] += enemyX_change[i]
if enemyX[i] < 0:
enemyX_change[i] = ENEMY_SPEED[i] # <---
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] = -ENEMY_SPEED[i] # <---
enemyY[i] += enemyY_change[i]
# [...]
enemyX[i] += enemyX_change[i] # <---
Upvotes: 1