Too much values to unpack - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Too much values to unpack (/thread-41576.html) |
Too much values to unpack - actualpy - Feb-10-2024 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. RE: Too much values to unpack - deanhystad - Feb-10-2024 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 bulletsYou only need to declare enemyBulletFired and lastShoot using global. The other variables are not assigned in the function. def moveEnemyBullet(): global enemyBulletFired, lastShoot RE: Too much values to unpack - actualpy - Feb-11-2024 Thanks! I'll add it on. RE: Too much values to unpack - deanhystad - Feb-11-2024 You should read about sprites. They make programming in pygame much easier.. Here's a fairly extensive tutorial for making a space invaders pygame. |