我的代码中的碰撞检测问题(python)

时间:2018-01-11 22:20:38

标签: python pygame collision-detection

我试图用python制作一个游戏,其中一个角色射击敌人的入射波。我有一个子弹列表,一个敌人列表'尸体,以及他们的头脑清单。出于某种原因,当我射击并且子弹与敌人发生碰撞时,有两种结果之一。我得到一个错误:"列表索引超出范围"或者被删除后产生的所有敌人,最终我得到同样的错误。我该如何解决?此外,我每次拍子弹时都试图让图像出现(枪口闪光灯),而且我遇到了麻烦。任何人都可以帮忙

from pygame import *
import random
import math
import os #Displays the pygame window at the top left of the screen
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" %(0,25)

init() #Starts pygame
font.init()
myfont = font.SysFont("arial", 18)
#clock = time.Clock()
LENGTH = 1000 #Creates Screen that is 1000 X 700
WIDTH = 700
SIZE = (LENGTH, WIDTH)
Screen = display.set_mode(SIZE)
lastTime = time.get_ticks()
lastTime2 = time.get_ticks()
lastTime3 = time.get_ticks()

ShotCooldown = 300
GBSpawn_Rate = 1500
MuzzleFl_Length = 100


MuzzleFlash = image.load("MuzzleFlash.png")
ForestBg = image.load('ForestBackground.jpg')
RowOfBushes = image.load('Row of Bushes.png')


#Defines colours
BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0)
GREEN = (0,255,0)
YELLOW = (253,228,74)
PATH = (232,224,136)
GRASS = (112,200,160)
CASTLE= (212,211,209)
SKIN = (222,174,150)
BULLET = (147,105,68)
GRASS2 = (180,221,160)
ROBOT = (150,150,150)

myClock = time.Clock()
running = True
CaptainY = 500
Key = 0
BulletX = 900
BulletY = 0
RidgeY = 130
Shooting = False
Shots = []
Flashes = []
Flashes_T = []
Gigabits = []
Gigabits_Heads = []
Gigabit_Health = []
Health = 100
Collided_bullet = 0
MoveUp = False
MoveDown = False 

while running:
    for evnt in event.get(): # checks all events that happen
        if evnt.type == QUIT: # if event type is quit the program stops running
            running = False
        if evnt.type == KEYDOWN:
            Key = evnt.key

            if Key == K_UP:
                MoveUp = True

            if Key == K_DOWN:
                MoveDown = True

            if Key == K_SPACE:
                Shooting = True  

        if evnt.type == KEYUP:
            Key = evnt.key

            if Key == K_UP:
                MoveUp = False

            if Key == K_DOWN:
                MoveDown = False

            if Key == K_SPACE:
                Shooting = False
                Key != K_SPACE

    draw.rect(Screen, GRASS, (0,0, LENGTH, WIDTH))


    #Draws Trees in the backgroung
    for X in range(4):
        Screen.blit(ForestBg,(X*305,-50))

    #Draws Bushes in the front
    for X in range(4):
        Screen.blit(RowOfBushes,(X*290,625))

    #draws Paths    
    draw.rect(Screen, PATH, (0,150, 1000, 75))

    draw.rect(Screen, PATH, (0,275, 1000, 75))

    draw.rect(Screen, PATH, (0,400, 1000, 75))

    draw.rect(Screen, PATH, (0,525, 1000, 75))

    #Draws castle
    draw.rect(Screen, CASTLE, (900, 125, 100, 500))
    draw.rect(Screen, BLACK, (900, 125, 100, 500),5)

    RidgeY = 130
    for X in range(10):
        draw.rect(Screen, CASTLE, (910, RidgeY, 10, 30))
        draw.rect(Screen, BLACK, (910, RidgeY, 10, 30),2)
        RidgeY += 50

    RidgeY = 130
    for X in range(10):
        draw.rect(Screen, CASTLE, (980, RidgeY, 10, 30))
        draw.rect(Screen, BLACK, (980, RidgeY, 10, 30),2)
        RidgeY += 50  

    draw.rect(Screen, CASTLE, (900,625, 100,25))
    draw.rect(Screen, BLACK, (900,625, 100,25),5)

    #Draws captain antivirus

    #Body
    draw.rect(Screen, RED, (942, CaptainY, 15, 30))
    draw.rect(Screen, BLACK, (942, CaptainY, 15, 30),1)

    #Legs 
    draw.rect(Screen, BLACK, (942, CaptainY+30, 15, 25))
    draw.rect(Screen, BLACK, (942, CaptainY+30, 15, 25),1)

    #Arm
    draw.rect(Screen, RED, (930, CaptainY+5, 20, 5))
    draw.rect(Screen, BLACK, (930, CaptainY+5, 20, 5), 1)

    #Head
    draw.circle(Screen, SKIN, (950, CaptainY-7), 10)
    draw.circle(Screen, BLACK, (950, CaptainY-7), 10,1)

    #Gun
    draw.rect(Screen, BLACK, (920, CaptainY+3, 10, 3))
    draw.rect(Screen, BLACK, (927, CaptainY+3, 3, 5))

    #Hand
    draw.circle(Screen, SKIN, (931, CaptainY+7), 3)

    draw.rect(Screen, BLACK, (935, CaptainY+55, 22, 5))

    if len(Gigabits) < 20: 
        if time.get_ticks() - lastTime2 >= GBSpawn_Rate:
            GBit_X = 0
            GBit_Y = random.choice([148, 273, 398, 523])
            Gigabit = Rect(GBit_X, GBit_Y, 15, 40)
            Gigabit_H = Rect(GBit_X, GBit_Y -20, 15, 15)
            Gigabits_Heads.append(Gigabit_H)
            Gigabits.append(Gigabit)
            Gigabit_Health.append(1)
            lastTime2 = time.get_ticks()

    #Draws enemy bodies      
    for X in Gigabits:
        draw.rect(Screen, ROBOT, X)
        draw.rect(Screen, BLACK, X, 2)

    #Draws Enemy heads
    for X in Gigabits_Heads:
        draw.rect(Screen, ROBOT, X)
        draw.rect(Screen, BLACK, X, 2)    

    #Moves Enemy body    
    for X in range(len(Gigabits)-1,-1,-1):
        if Gigabits[X][0] < 885:
            Gigabits[X][0] += 1
        else:
            del Gigabits[X]

    #moves enemy heads        
    for X in range(len(Gigabits_Heads)-1,-1,-1):
        if Gigabits_Heads[X][0] < 885:
            Gigabits_Heads[X][0] += 1
        else:
            del Gigabits_Heads[X]
            Health -= 5


    #Draws Healthbar
    if 50 < Health >= 75:
        draw.rect(Screen, WHITE, (850,40, 100,25))
        draw.rect(Screen, GREEN, (850, 40, Health, 25))
        draw.rect(Screen, BLACK, (850, 40, 100, 25),5)

    elif  25< Health >= 50: 
        draw.rect(Screen, WHITE, (850,40, 100,25))        
        draw.rect(Screen, YELLOW, (850, 40, Health, 25))
        draw.rect(Screen, BLACK, (850, 40, 100, 25),5)

    elif 0 < Health >= 25:
        draw.rect(Screen, WHITE, (850,40, 100,25))        
        draw.rect(Screen, RED, (850, 40, Health, 25))
        draw.rect(Screen, BLACK, (850, 40, 100, 25),5)

    else:
        Health = 0

    HealthTXT = myfont.render("HEALTH: " + str(Health) , 1, (0,0,0))
    Screen.blit (HealthTXT, (857,42))

    #Moves character  
    if MoveUp == True:
        CaptainY -= 5
    if MoveDown == True:
        CaptainY += 5

    if CaptainY + 60 <= 125:
        CaptainY = 70
    elif CaptainY + 60 >= 625:
        CaptainY = 565

    #Creates Shot   
    if Shooting == True:
        if time.get_ticks() - lastTime >= ShotCooldown:
            BulletY = CaptainY+3
            Bullet = Rect(BulletX, BulletY, 25, 3)
            Shots.append(Bullet)
            Flash = MuzzleFlash, (890, CaptainY)
            Flashtime = time.get_ticks()
            Flashes_T.append(Flashtime)
            Shooting = False
            lastTime = time.get_ticks()


    #Draws Shot   
    for X in Shots:
        draw.rect(Screen, BULLET, X)

    #for X in Flashes:
        ##Spot = Flashes.index(X)
        ##if time.get_ticks - Flashes_T[Spot]  <= Flash_Length:
            ##Screen.blit(X)
            ##lastTime3 = time.get_ticks()
        ##else:
            ##del X

    #if Shooting == True:
        #if time.get_ticks() - lastTime3 >= MuzzleFl_Length:
        #Screen.blit(MuzzleFlash, (890, CaptainY-3))
            #lastTime3 = time.get_ticks()

    for X in range(len(Shots)-1, -1,-1):
            if Shots[X][0] > 0:
                Shots[X][0] -= 20
            else:
                del Shots[X]

    for X in Gigabits:
        for Y in Shots:
            if X.colliderect(Y) == True:
                Spot = Gigabits.index(X)
                Gigabit_Health[Spot] -= 1
                del Y

    for X in Gigabits_Heads:
        for Y in Shots:
            if X.colliderect(Y) == True:
                Spot = Gigabits_Heads.index(X)
                Gigabit_Health[Spot] -= 1
                del Y

    if len(Gigabits) > 0:
        for X in Gigabit_Health:
            if X == 0:
                Spot = Gigabit_Health.index(X)
                del Gigabits[Spot]
                del Gigabits_Heads[Spot]
                del [X]




    myClock.tick(60)   
    display.flip()

quit()

1 个答案:

答案 0 :(得分:1)

您正在迭代列表中的元素。这是不允许的,因为您正在减少列表的长度,同时尝试访问不再有效的索引处的列表元素。因此你得到IndexError

请查看此问题Remove items from a list while iterating。如果此修复程序没有解决此问题,您应该修复代码,并针对其他问题使用最小的正确工作示例提出新问题。