2016-11-24 7 views
-1

Ich versuche derzeit, ein einfaches Space Invaders Python-Spiel mit Python 3.5.2 zu erstellen. Momentan läuft alles, aber wenn das Geschoss auf die Seite meines Aliens trifft, zeigt das Programm einen Fehler an. Dies ist der CodePygame Collision Error Python 3

import pygame 
from pygame.locals import * 

pygame.init() 

width, height = 640, 480 

keys=[False, False, False, False] 
playerpos=[290,400] 
alienpos=[] 
bulletpos=[] 
for i in range(100, 600, 100): 
    for j in range(0, 150, 50): 
     alienpos.append([i, j]) 

screen = pygame.display.set_mode((width, height)) 
space = pygame.image.load("space.jpg") 
alien = pygame.image.load("alien.png") 
bullet = pygame.image.load("bullet.png") 
space = pygame.transform.scale(space,(width,height)) 

player = pygame.image.load("spacecraft.png") 
flag1 = 0 
flag2 = 0 
switch = True 


while 1: 
    screen.fill(0) 
    screen.blit(space,(0,0)) 

    for i in alienpos: 

     for j in bulletpos: 
      if i[1]<=j[1] and i[1]+28 >= j[1] and i[0]<=j[0] and i[0]+28 >= j[0]: 
       alienpos.remove(i) 

     screen.blit(alien, i) 

     if (i[0] + 1) > 600: 
      flag1 = 1 
     elif (i[0] - 1) < 1: 
      flag1 = 0 
     if flag1 == 0: 
      i[0] += 1 
     elif flag1 == 1: 
      i[0] -= 1  

    if not len(bulletpos)==0: 
     for pos in bulletpos: 
      if pos[1] > 0: 
       screen.blit(bullet, pos) 
       pos[1] -= 1 
       pos=([playerpos[0], playerpos[1]]) 


    screen.blit(player, playerpos) 


    pygame.display.flip() 

    for event in pygame.event.get(): 
     if event.type == pygame.KEYDOWN: 
      if event.key==K_w: 
       keys[0]=True 
      elif event.key==K_a: 
       keys[1]=True 
      elif event.key==K_s: 
       keys[2]=True 
      elif event.key==K_d: 
       keys[3]=True 
     if event.type == pygame.KEYUP: 
      if event.key==pygame.K_w: 
       keys[0]=False 
      elif event.key==pygame.K_a: 
       keys[1]=False 
      elif event.key==pygame.K_s: 
       keys[2]=False 
      elif event.key==pygame.K_d: 
       keys[3]=False 

     if event.type == pygame.QUIT: 
      pygame.quit() 
      exit(0) 

    if keys[1]: 
     playerpos[0]-=5 
    elif keys[3]: 
     playerpos[0]+=5 
    elif keys[0]: 
     bulletpos.append([playerpos[0], playerpos[1]]) 

Wenn die Kugel auf der Seite der Ausländer trifft, stoppt das Programm und die folgende Fehlermeldung angezeigt.

Traceback (most recent call last): 
    File "Python35\game.py", line 36, in <module> 
    alienpos.remove(i) 
ValueError: list.remove(x): x not in list 

Es gibt viele ähnliche Fragen zu diesem Thema bei Stackoverflow, aber keiner der Vorschläge haben keine Hilfe viel gewesen. Wenn es weitere Informationen gibt, die Sie alle benötigen, würde ich mich freuen, Sie zu kommentieren. Danke im Voraus!

+0

Konnte 'i' durch einen vorherigen' bulletpos' entfernt werden? Versuchen Sie Folgendes: Beenden Sie die 'for j'-Schleife, wenn' i' entfernt wurde; oder testen, ob "i" immer noch in "alienpos" vor dem Entfernen – fredtantini

+0

PyGame hat spezielle Funktionen, um Kollisionen mit 'pygame.Rect()' zu überprüfen. Und es hat 'pygame.sprite.Group()', die eine Gruppe von Objekten enthält und Kollisionen überprüfen und Elemente automatisch entfernen kann. – furas

+0

In Python besser neue Liste erstellen und in for-Schleife Elemente hinzufügen, die Sie behalten möchten, als Elemente aus oryginal Liste zu entfernen. Und nach 'for-loop' ordnen Sie eine neue Liste anstelle einer origine-Liste zu. – furas

Antwort

0

Problem ist, weil Sie alien aus der Liste entfernen, aber später überprüfen Sie immer noch diese alien mit anderen bullets und andere bullet mit diesem alien kollidieren können und Sie versuchen, erneut die gleiche alien zu entfernen - aber das alien existiert nicht in der Liste.

Sie können break verwenden, um for-loop zu verlassen und die Kollisionsprüfung mit anderen bullets zu überspringen.

for j in bulletpos: 
     if i[1]<=j[1] and i[1]+28 >= j[1] and i[0]<=j[0] and i[0]+28 >= j[0]: 
      alienpos.remove(i) 
      break 

BTW: Sie Code auf diese Weise organisieren könnten:

Ich benutze pygame.Rect() (.get_rect()) Objekte Position zu halten, und dann kann ich pygame Funktionen verwenden, um Kollisionen zu überprüfen.

pygame.Rect() hat Eigenschaften left, right, top, bottom, center, etc., so ist es einfacher, Positionen zu vergleichen - das heißt player_rect.right == screen_rect.right, oder setzen Zentrum auf dem Bildschirm player_rect.center = screen_rect.center

Pygame hat Funktion pygame.key.get_pressed() und Sie haben nicht um eigene Liste zu erstellen keys

Ich benutze Ereignis nur, um Kugel zu schießen, weil pygame.key.get_pressed() Kugeln feuert, wenn ich Knopf gedrückt halte. Aber ich will nur einmal schießen, wenn ich gedrückt halte.

import pygame 

# --- constants --- (UPPER_CASE names) 

WIDTH = 640 
HEIGHT = 480 

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

# --- main --- (lower_case names) 

# - init - 

pygame.init() 
screen = pygame.display.set_mode((WIDTH, HEIGHT)) 
screen_rect = screen.get_rect() 

# - objects - 

background = pygame.image.load("space.jpg") 
background = pygame.transform.scale(background, (WIDTH, HEIGHT)) 

alien = pygame.image.load("alien.png") 
bullet = pygame.image.load("bullet.png") 

aliens = [] 
bullets = [] 

for x in range(100, 600, 100): 
    for y in range(0, 150, 50): 
     aliens.append(alien.get_rect(x=x, y=y)) 

player = pygame.image.load("spacecraft.png") 
player_rect = player.get_rect(x=290, y=400) 

# - other - 

move_right = True 

# - mainloop - 

while True: 

    # - events - 

    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      pygame.quit() 
      #exit(0) 
     elif event.type == pygame.KEYDOWN: 
      if event.key in (pygame.K_SPACE, pygame.K_w): 
       # add bullet 
       bullets.append(bullet.get_rect(center=player_rect.center)) 

    # - updates (without draws) - 

    keys = pygame.key.get_pressed() 

    # move player 

    if keys[pygame.K_a] or keys[pygame.K_LEFT]: 
     player_rect.x -= 5 
     if player_rect.left < screen_rect.left: 
      player_rect.left = screen_rect.left 
    elif keys[pygame.K_d] or keys[pygame.K_RIGHT]: 
     player_rect.x += 5 
     if player_rect.right > screen_rect.right: 
      player_rect.right = screen_rect.right 

    # move bullets 

    for b in bullets: 
     if b.bottom > screen_rect.top: 
      b.y -= 1 

    # move aliens 

    switch_direction = False 

    for a in aliens: 
     if move_right: 
      a.x += 1 
      if a.right >= screen_rect.right: 
       switch_direction = True 
     else: 
      a.x -= 1 
      if a.left <= screen_rect.left: 
       switch_direction = True 

    if switch_direction: 
     move_right = not move_right 
     for a in aliens: 
      a.y += 5 

    # check collisions 

    temp_aliens = [] 

    for a in aliens: 
     for b in bullets: 
      if b.colliderect(a): 
       bullets.remove(b) 
       break 
     else: 
      temp_aliens.append(a) 

    aliens = temp_aliens 

    # - draws (without updates) - 

    #screen.fill(BLACK) 
    screen.blit(background, (0,0)) 

    for a in aliens: 
     screen.blit(alien, a) 

    for b in bullets: 
     screen.blit(bullet, b) 

    screen.blit(player, player_rect) 
    pygame.display.flip()