Databas3
Databas3

Reputation: 21

TypeError: unsupported operand type(s) for +=: 'int' and 'list' with Pygame

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

Answers (1)

Rabbid76
Rabbid76

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

Related Questions