2016-11-24 8 views
-1

私は現在、Python 3.5.2を使用して単純なスペースインベーダーPythonゲームを作成しようとしています。現在はすべて動作しますが、弾丸が私のエイリアンの側面に当たったときは、プログラムはエラーを表示します。 これは、コードPygame 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]]) 

弾丸は、外国人の側に達すると、プログラムは停止し、次のエラーが表示されています。

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の時にこの主題について同様の質問がたくさんありますが、提案のどれも非常に任意の助けにされていません。あなたが必要とする情報が他にもあれば、私はコメントしてもらえます。前もって感謝します!リストからalienを削除するが、後であなたはまだ他のbulletsや他のbulletでこれalienをチェックするため

+0

「i」は以前の 'bulletpos'で削除されましたか? 'i'が削除されたときに' for j'ループを終了してください。または削除する前に 'i 'がまだalienposにあるかどうかをテストする – fredtantini

+0

PyGameには、' pygame.Rect() 'を使って衝突をチェックする特殊な関数があります。また、オブジェクトのグループを保持する 'pygame.sprite.Group()'を持ち、衝突をチェックして要素を自動的に削除することができます。 – furas

+0

Pythonでは、新しいリストを作成し、for-loopで、オリジンのリストから要素を削除するよりも、保持したい要素を追加するほうがいいです。 'for-loop'の後にoryginalリストの代わりに新しいリストを割り当てます。 – furas

答えて

0

問題がある。このalienと衝突し、もう一度同じalienを削除しようとするかもしれない - しかし、このalienはリスト上に存在しません。

forループとスキップチェックの衝突を他のbulletsのままにするには、breakを使用できます。


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 

ところで:
あなたがこの方法のコードを整理することができます:

は私が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()