Почему не работает обнаружение столкновений или падающих изображений? - PullRequest
0 голосов
/ 21 апреля 2019

Я недавно написал этот код, где фрукты и другие предметы падают с верхней части экрана, а лягушка внизу должна попытаться поймать их.Обнаружение столкновений не работает, а также падающие изображения, поскольку они, кажется, просто падают и застряли в верхней части экрана.Это большая часть моего кода, так как я не могу понять, в какой области находится фактическая ошибка:

import pygame, sys, time, random
from pygame.locals import *
######### constants ##########
jumpvel=20
fallingspeed=0.5
running= True
blue= [129,183 ,253]
pink=[255,174,201]
textcolour= [255,255,255]
x=700//2
y=1000//2

score=0

#### fruits and naughty ######
thingylist= ['fruit1.bmp','fruit2.bmp','fruit3.bmp','fruit4.bmp','fruit5.bmp','fruit1.bmp','fruit2.bmp','fruit3.bmp','fruit4.bmp','fruit5.bmp','naughty1.bmp','naughty2.bmp','naughty3.bmp',]
all_things=[]
for i in range (12):
    new_thing_image=pygame.image.load(thingylist[(random.randrange(0,12))])
    new_thing_image.set_colorkey(pink)
    new_thing_rect=new_thing_image.get_rect()
    new_thing_rect.x=random.randrange(0,950)
    new_thing_rect.y=-random.randrange(50,500)
    all_things.append([new_thing_image,new_thing_rect])


################collision###############
def checkCollision (frog_rect,all_things,score):
    collides_with=None
    for i in range (len(all_things)):
        thing_rect=all_things[i][1]
        if (frog_rect.colliderect(thing_rect)):
            score=score+100
    return collides_with



######## initialising screen#########        
pygame.init()
gamedisplay=pygame.display.set_mode((1000,600)) #making the screen
pygame.display.set_caption('frog')
clock=pygame.time.Clock()# frames per second
bg=pygame.image.load('actual clouds.bmp').convert()


############ initialising sprites##############
frog= pygame.image.load('actual frog.bmp')
frog.set_colorkey(blue)
frog_rect=frog.get_rect()
frog_rect.centerx=(x)
frog_rect.centery=(y)


####### score###########
pygame.font.init()
font= pygame.font.SysFont ('Dubai MS', 48)

##########drawing things#############
def drawThings (all_things):
    for item in all_things:
        new_thing_image, new_thing_rect= item
        gamedisplay.blit(new_thing_image, (new_thing_rect.x, new_thing_rect.y))



#########update display function###########
def update(x,y,all_things,score):
    gamedisplay.blit(bg,[0,0])
    gamedisplay.blit(frog,(x,y))
    for thing in range (len(all_things)):
        new_thing_rect=all_things[i][1]
        #thing_rect.y=thing_rect.y+fallingspeed
        new_thing_rect.y+= fallingspeed
    drawThings(all_things)
    label=font.render("score "+ str(score) ,1,textcolour)
    gamedisplay.blit(label,(750,10))
    pygame.display.update()
    pygame.time.delay(50)



#########main game loop ############
while running == True:
    gamedisplay.blit(bg,[0,0])
    gamedisplay.blit(frog,(x,y))
    drawThings(all_things)
    label=font.render("score "+ str(score) ,1,textcolour)
    gamedisplay.blit(label,(750,10))
    pygame.display.flip()
    pygame.event.pump()
    key=pygame.key.get_pressed()

    ########### escape ###########
    if key [pygame.K_ESCAPE]:
        sys.exit()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    ########### controls ##############        
    if key[pygame.K_LEFT]:
        x -=2

    elif key[pygame.K_RIGHT]:
        x +=2

    elif key[pygame.K_SPACE]or key[pygame.K_UP]:
        for i in range (5):
            y -= jumpvel
            update(x,y,all_things,score)
        for i in range (5):
            y += jumpvel
            update(x,y,all_things,score)
    ######## limits ####################
    if x < 10:
        x = 10
    elif (x > (900 - 2)):
        x= 900-2

    ######### falling###########

    for item in all_things:
        new_thing_image, new_thing_rect= item
        #new_thing_rect=all_things[i][1]
        #thing_rect.y=thing_rect.y+fallingspeed
        new_thing_rect.y+= fallingspeed

    ############collision detection##########
    detect=checkCollision (frog_rect, all_things,score)
    if (detect !=None):
        score=score+100

update(x,y,all_things,score)

«Вещи» должны упасть в нижнюю часть экрана, чтобы лягушка могла их поймать, новсе они кажутся застрявшими наверху.Когда я тестировал код для обнаружения столкновений, даже когда два изображения столкнулись, это не повлияло на оценку - это означает, что что-то не работает.

1 Ответ

0 голосов
/ 21 апреля 2019

Падающие изображения останавливаются из-за этого

fallingspeed = 0.5

rect использует целочисленные значения для сохранения позиции, поэтому он будет округлять 0.5 до целого числа - int(0.5) == 0.

Когда у вас есть y = 0 и вы добавляете 0.5 - так что вы можете ожидать y = 0.5 - оно округляется до y = 0. В следующем цикле вы снова добавите 0.5, и он снова округлит его до y = 0. Таким образом, он останавливается на y = 0

Если у вас есть то есть y = -5 и вы добавляете 0.5, тогда вы можете ожидать -4.5, но оно округляется до -4 (не -5), поэтому оно движется.

Использование

fallingspeed = 1

и он не остановится на y = 0


old_y = 0
new_y = int(old_y+0.5)
print(old_y, new_y) 

# 0 0

old_y = -5
new_y = int(old_y+0.5)
print(old_y, new_y) 

# -5 -4

Иногда в более сложном коде важно сохранять положение в значениях с плавающей запятой, и тогда вам придется использовать float переменные вместо rect, чтобы сохранить положение и копировать его в rect только тогда, когда вам нужно нарисовать или проверка столкновения


столкновения

Внутри checkCollision вы устанавливаете collides_with = None, но никогда не меняете его на `True

 def checkCollision (frog_rect,all_things, score):
     collides_with = None

     for i in range (len(all_things)):
         thing_rect = all_things[i][1]
         if (frog_rect.colliderect(thing_rect)):
              score=score+100
              collides_with = True

     return collides_with

Вы могли бы написать это короче

 def checkCollision(frog_rect,all_things, score):
     collides_with = None

     for thing_image, thing_rect in all_things:
         if frog_rect.colliderect(thing_rect):
              score = score+100
              collides_with = True

     return collides_with

Теперь он должен изменить score в строке

detect = checkCollision(frog_rect, all_things, score)
if detect:
    score = score+100

Но если вы хотите изменить его внутри checkCollision, вы должны вернуть значение score. Переменная score внутри checkCollision является локальной переменной и не меняет значения в глобальной переменной score

 def checkCollision(frog_rect,all_things, score):
     collides_with = None

     for thing_image, thing_rect in all_things:
         if frog_rect.colliderect(thing_rect):
              score = score+100
              collides_with = True

     return collides_with, score

и затем вы должны обратиться к глобальному score

detect, score = checkCollision(frog_rect, all_things, score)
...