2016-11-24 129 views
-1

我目前正在尝试使用Python 3.5.2创建一个简单的空间入侵者Python游戏。目前一切正常,但每当子弹击中我的外星人的一面程序显示错误。 这是代码Pygame碰撞错误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]]) 

当子弹击中了外来的一侧,该程序停止,并出现以下错误。

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

有很多关于在StackOverflow上这个问题类似的问题,但没有的建议一直是任何帮助很大。如果有任何更多的信息,你都需要我会很乐意发表评论。提前致谢!

+0

我以前的'bulletpos'可以删除'我'吗?尝试:当'i'被移除时退出'for j'循环;或者在删除之前测试'i'是否仍在'alienpos'中 – fredtantini

+0

PyGame有特殊的功能来检查使用'pygame.Rect()'的冲突。它有'pygame.sprite.Group()'保留了一组对象,它可以检查冲突并自动删除元素。 – furas

+0

在Python中,最好创建新列表并在for循环中添加要保留的元素,而不是从oryginal列表中删除元素。在'for-loop'之后,你指定了一个新的列表来取代oryginal列表。 – furas

回答

0

问题是因为你从列表中删除alien但后来你还检查了这alien与其他bulletsbullet可能与此alien碰撞并尝试再次同alien删除 - 但这alien不存在于名单。

您可以使用break离开for-loop并跳过检查与其他bullets的碰撞。

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:你能组织这样的代码:

我用pygame.Rect().get_rect()),以保持对象的位置,然后我可以使用pygame的功能来检查碰撞。

pygame.Rect()具有性能leftrighttopbottomcenter等,所以它更容易比较的位置 - 在屏幕上即player_rect.right == screen_rect.right,或把中心player_rect.center = screen_rect.center

Pygame的具有功能pygame.key.get_pressed()和你没有创建自己的列表keys

我只使用事件来发射子弹,因为pygame.key.get_pressed()当我按住按钮时会发射子弹。但是当我一直按下时,我只想射击一次。

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()