Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Too much values to unpack
#1
So I'm trying to do a Space Invader-ish game, and I can't figure this out.
Says "Too much values to unpack (expected 3)"

Here's the code:
import pygame
from pygame import mixer
import math

pygame.init()
mixer.init()

mixer.music.load("9mm-pistol-shot-6349.mp3")
mixer.music.set_volume(0.5)

BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
WHITE = (255, 255, 255)

pW = 30
pH = 30

soldier = pygame.Rect(300, 370, pW, pH)

enemy1 = pygame.Rect(300, 0, pW, pH)
enemy2 = pygame.Rect(250, 50, pW, pH)
enemy3 = pygame.Rect(200, 0, pW, pH)
enemy4 = pygame.Rect(150, 50, pW, pH)
enemy5 = pygame.Rect(100, 0, pW, pH)
enemy6 = pygame.Rect(350, 50, pW, pH)
enemy7 = pygame.Rect(400, 0, pW, pH)
enemy8 = pygame.Rect(450, 50, pW, pH)
enemy9 = pygame.Rect(500, 0, pW, pH)
enemy10 = pygame.Rect(50, 50, pW, pH)

enemies = [enemy1, enemy2, enemy3, enemy4, enemy5, enemy6, enemy7, enemy8, enemy9, enemy10]

eB1 = pygame.Rect(0, 0, 5, 5)
eB2 = pygame.Rect(0, 0, 5, 5)
eB3 = pygame.Rect(0, 0, 5, 5)
eB4 = pygame.Rect(0, 0, 5, 5)
eB5 = pygame.Rect(0, 0, 5, 5)
eB6 = pygame.Rect(0, 0, 5, 5)
eB7 = pygame.Rect(0, 0, 5, 5)
eB8 = pygame.Rect(0, 0, 5, 5)
eB9 = pygame.Rect(0, 0, 5, 5)
eB10 = pygame.Rect(0, 0, 5, 5)

bullets = [eB1, eB2, eB3, eB4, eB5, eB6, eB7, eB8, eB9, eB10]
bullet_speed = 1

bullet = pygame.Rect(0, 0, 5, 5)

windowHeight = 400
windowWidth = 600

screen = pygame.display.set_mode((windowWidth, windowHeight))

# Load font
font = pygame.font.Font(None, 36)  # Default system font with size 36

# Initialize score
score = 0

# Constants for soldier shooting
RELOAD_TIME = 2000  # 2 seconds
last_shot_time = 0

key = pygame.key.get_pressed()

enemy_move_delay = 1000
last_enemy_move = pygame.time.get_ticks()

bulletFired = False
enemyBulletFired = False
enemyBulletCooldown = 1000
lastShoot = pygame.time.get_ticks()
whichBullet = 1  # Initialize bullet type

def moveEnemies():
    global last_enemy_move

    current_time = pygame.time.get_ticks()
    if current_time - last_enemy_move >= enemy_move_delay:
        for enemy in enemies:
            enemy.move_ip(0, 2)
        last_enemy_move = current_time

def moveBullet():
    global bulletFired
    global score

    if bulletFired:
        bullet.move_ip(0, -1)

        for enemy in enemies[:]:
            if bullet.colliderect(enemy):
                enemies.remove(enemy)
                score += 1  # Increment score when an enemy is hit

        if bullet.y < 0:
            bulletFired = False

def moveEnemyBullet():
    global enemyBulletFired
    global lastShoot
    global enemyBulletCooldown
    global bullets

    currentTime = pygame.time.get_ticks()

    if currentTime - lastShoot >= enemyBulletCooldown:
        lastShoot = currentTime

        # Iterate over enemies and fire bullets
        for enemy in enemies:
            if enemyBulletFired:
                # Calculate the direction vector from enemy to player
                direction_x = soldier.centerx - enemy.centerx
                direction_y = soldier.centery - enemy.centery

                # Normalize the direction vector
                length = math.sqrt(direction_x ** 2 + direction_y ** 2)
                if length != 0:
                    direction_x /= length
                    direction_y /= length

                # Create a bullet with initial position at the enemy
                bullet = pygame.Rect(enemy.centerx, enemy.centery, 5, 5)
                bullets.append((bullet, direction_x, direction_y))

        # Toggle enemyBulletFired
        enemyBulletFired = not enemyBulletFired

    # Move bullets and remove if they reach the window boundaries
    for bullet in bullets[:]:
        bullet_rect, _, _ = bullet
        bullet_rect.x += direction_x * bullet_speed
        bullet_rect.y += direction_y * bullet_speed

        if bullet_rect.y > windowHeight or bullet_rect.colliderect(soldier):
            bullets.remove(bullet)


def moveSoldier():
    global bulletFired
    global last_shot_time

    key = pygame.key.get_pressed()

    if key[pygame.K_d]:
        soldier.move_ip(1, 0)
    if key[pygame.K_a]:
        soldier.move_ip(-1, 0)

    # Check for shooting
    if key[pygame.K_SPACE] and pygame.time.get_ticks() - last_shot_time >= RELOAD_TIME:
        bulletFired = True
        last_shot_time = pygame.time.get_ticks()  # Update the last shot time
        bullet.x = soldier.x + soldier.width // 2 - bullet.width // 2  
        bullet.y = soldier.y
        mixer.music.play()

run = True

while run:
    screen.fill(BLACK)


    pygame.draw.rect(screen, GREEN, soldier)
    pygame.draw.rect(screen, WHITE, bullet)

    for enemy in enemies:
        pygame.draw.rect(screen, GREEN, enemy)

    # Draw enemy bullets
    
    for bullet in bullets:
        pygame.draw.rect(screen, GREEN, bullet)



    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    text_surface = font.render(f'Score: {score}', True, WHITE)  # Render score text
    text_rect = text_surface.get_rect()
    text_rect.topleft = (10, 10)  # Position of the text

    text_surface2 = font.render('You Won, GG', True, WHITE)  # Render text
    text_rect2 = text_surface2.get_rect()
    text_rect2.midright = (320, 170)  # Position of the text

    # Blit the text onto the screen
    screen.blit(text_surface, text_rect)

    moveSoldier()
    moveEnemies()
    moveBullet()
    moveEnemyBullet()

    if score == 10:
        screen.fill(BLACK)
        screen.blit(text_surface2, text_rect2)
    

    pygame.display.update()

pygame.quit()
Here's the error: ValueError: too many values to unpack (expected 3) (on line 132)
Thanks in advance.
Gribouillis write Feb-10-2024, 10:11 AM:
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Reply
#2
You need to be consistent. Initially you define bullets to be a list of rectangles.
eB1 = pygame.Rect(0, 0, 5, 5)
eB2 = pygame.Rect(0, 0, 5, 5)
eB3 = pygame.Rect(0, 0, 5, 5)
eB4 = pygame.Rect(0, 0, 5, 5)
eB5 = pygame.Rect(0, 0, 5, 5)
eB6 = pygame.Rect(0, 0, 5, 5)
eB7 = pygame.Rect(0, 0, 5, 5)
eB8 = pygame.Rect(0, 0, 5, 5)
eB9 = pygame.Rect(0, 0, 5, 5)
eB10 = pygame.Rect(0, 0, 5, 5)
 
bullets = [eB1, eB2, eB3, eB4, eB5, eB6, eB7, eB8, eB9, eB10]
Later on you add tuples to bullets:
                bullets.append((bullet, direction_x, direction_y))
This causes a problem when unpacking because somethmes bullets[x] will be just a rectangle, and other times it will be a rectangle and a direction (direction_x, direction_y).

You have a lot of problems in your code that are associated with bullets.

You only need to declare a variable as global when doing an assignment. You don't have to use global for accessing the variable. In this function:
def moveEnemyBullet():
    global enemyBulletFired
    global lastShoot
    global enemyBulletCooldown
    global bullets
You only need to declare enemyBulletFired and lastShoot using global. The other variables are not assigned in the function.
def moveEnemyBullet():
    global enemyBulletFired, lastShoot
actualpy likes this post
Reply
#3
Thanks! I'll add it on.
Reply
#4
You should read about sprites. They make programming in pygame much easier..

Here's a fairly extensive tutorial for making a space invaders pygame.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  unpack dict menator01 1 1,200 Apr-09-2022, 03:10 PM
Last Post: menator01
  ValueError: not enough values to unpack (expected 4, got 1) vlearner 2 6,340 Jan-28-2022, 06:36 PM
Last Post: deanhystad
  [SOLVED] [geopy] "ValueError: too many values to unpack (expected 2)" Winfried 2 2,875 Mar-30-2021, 07:01 PM
Last Post: Winfried
  Cannot unpack non-iterable NoneType object, i would like to ask for help on this. Jadiac 3 8,934 Oct-18-2020, 02:11 PM
Last Post: Jadiac
  subprogram issues: cannot unpack non-iterable function object error djwilson0495 13 6,017 Aug-20-2020, 05:53 PM
Last Post: deanhystad
  struct.unpack failed Roro 2 3,366 Jun-13-2020, 05:28 PM
Last Post: DreamingInsanity
  Can't unpack values of dictionary with ** Snake 3 3,574 Mar-11-2020, 11:17 AM
Last Post: Snake
  Error: too many values to unpack Mike 1 5,143 Oct-30-2019, 03:07 PM
Last Post: buran
  How to unpack tuples in if statements saurkkum 1 5,185 May-05-2019, 09:43 AM
Last Post: Gribouillis
  too many values to unpack error fyec 1 8,068 Jun-28-2018, 01:48 AM
Last Post: ichabod801

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020