почему этот код регистрирует только определенные коллизии, а не все? - PullRequest
0 голосов
/ 23 апреля 2019

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

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

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

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

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

##########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))
    gamedisplay.blit(heart1,(750,50))
    gamedisplay.blit(heart2,(850,50))
    gamedisplay.blit(heart2,(800,50))
    pygame.display.update()
    pygame.time.delay(50)

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()
    for item in all_things:
        new_thing_image, new_thing_rect= item
        new_thing_rect.y+= fallingspeed
        if new_thing_rect.y >450:
            new_thing_rect.x=random.randrange(0,950)
            new_thing_rect.y=-random.randrange(50,500)
    ############collision detection##########
    detect,score =checkCollision (frog_rect, all_things,score)

    update(x,y,all_things,score)

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

1 Ответ

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

Основываясь на фрагменте кода - который не включает код обновления позиции лягушки, я бы предположил, что проблемы:

  • Оценка случайно увеличивается
  • Столкновения не всегда работают

Вызывается тем, что прямоугольник столкновения определяется один раз для начальной позиции лягушки, но затем никогда не обновляется при изменении положения лягушки.

############ initialising sprites##############
frog= pygame.image.load('actual frog.bmp')
frog.set_colorkey(blue)
frog_rect=frog.get_rect()
frog_rect.centerx=(x)       # <-- rect only ever updated here!
frog_rect.centery=(y)

Это могло бы привести к описанным симптомам, так как подсвечивающие объекты (фрукты?), Падающие через прямоугольник столкновения, добавляли бы к счету (на первый взгляд случайным образом), и когда лягушка все еще находилась в исходном положении, столкновение работало бы отлично. Если бы лягушка была частично над прямоугольником, она бы сработала, и совсем не так, как только лягушка отодвинулась от этого прямоугольника начальной позиции.

Решение проблемы заключается в обновлении координат прямоугольника frog_rect всякий раз, когда x & y позиции лягушки обновляется. Это может быть достигнуто установкой frog_rect.centerx и frog_rect.centery внутри функции update():

def update(x, y, all_things, score ):
    frog_rect.x = x
    frog_rect.y = y

Прямоугольник лягушки инициализируется координатами .centerx, .centery, но лягушка рисуется в x,y, поэтому прямоугольник столкновения также начинается немного смещенным от центра. Таким образом, было бы лучше также обновить функцию инициализации:

frog_rect=frog.get_rect()
frog_rect.x = x
frog_rect.y = y
...