python - 为什么这种碰撞检测不适用于之前创建的对象?
问题描述
经过数小时的搜索,我仍然无法弄清楚为什么只有最近生成的圆圈会受到碰撞检测的影响。我注释掉了有问题的代码。我尝试了精灵,这可能是答案,但我仍然得到相同的结果。
import pygame,random
pygame.init()
width,height,radius = 1280,720,20
class Ball():
def __init__(self):
self.x = 0
self.y = 0
self.vx = 0
self.vy = 0
def make_ball():
ball = Ball()
ball.x = random.randrange(radius, width - radius)
ball.y = random.randrange(radius, 100)
ball.vx = random.randint(1,2)
ball.vy = 0
return ball
def main():
rect_x = 60
display = pygame.display.set_mode((width,height))
pygame.display.set_caption("BOUNCE")
running = True
ball_list = []
ball = make_ball()
ball_list.append(ball)
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
ball = make_ball()
ball_list.append(ball)
for ball in ball_list:
ball.x += ball.vx
ball.vy += 0.02
ball.y += ball.vy
if ball.y >= height - radius:
ball.vy *= -1
if ball.x >= width - radius or ball.x <= radius:
ball.vx *= -1
display.fill((0,0,0))
for ball in ball_list:
random_color = (random.randint(1,255),random.randint(1,255),random.randint(1,255))
circle = pygame.draw.circle(display,random_color,(int(ball.x), int(ball.y)),radius)
rectangle = pygame.draw.rect(display,(255,255,255),(int(rect_x),660,60,60))
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT and rect_x > 0:
rect_x -= 2
if event.key == pygame.K_RIGHT and rect_x < width - 60:
rect_x += 2
'''if pygame.Rect(circle).colliderect(rectangle) == True: ###THIS IS THE BAD CODE!
print('Your Score:',pygame.time.get_ticks())
running = False'''
text = pygame.font.Font(None,120).render(str(pygame.time.get_ticks()),True,(255,255,255))
display.blit(text,(50,50))
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
main()
解决方案
缩进和代码组织是其中的关键。违规部分是(已删除评论):
for ball in ball_list:
random_color = (random.randint(1,255),random.randint(1,255),random.randint(1,255))
circle = pygame.draw.circle(display,random_color,(int(ball.x), int(ball.y)),radius)
rectangle = pygame.draw.rect(display,(255,255,255),(int(rect_x),660,60,60))
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT and rect_x > 0:
rect_x -= 2
if event.key == pygame.K_RIGHT and rect_x < width - 60:
rect_x += 2
if pygame.Rect(circle).colliderect(rectangle) == True:
print('Your Score:',pygame.time.get_ticks())
running = False
您拥有所有正确的部分,但是您执行它们的顺序以及缩进都已关闭:
for ball in ball_list:
random_color = (random.randint(1,255),random.randint(1,255),random.randint(1,255))
circle = pygame.draw.circle(display,random_color,(int(ball.x), int(ball.y)),radius)
rectangle = pygame.draw.rect(display,(255,255,255),(int(rect_x),660,60,60))
if pygame.Rect(circle).colliderect(rectangle):
print('Your Score:',pygame.time.get_ticks())
running = False
现在这将遍历列表中的每个球并检查每个球是否发生碰撞。注意 colliderect if 语句缩进到 for 循环中。另请注意,我从中间删除了 KEYDOWN 检查
说到这一点,我建议使用:
pressed = pygame.key.get_pressed()
if pressed[pygame.K_LEFT] and rect_x > 0:
rect_x -= 2
if pressed[pygame.K_RIGHT] and rect_x < width - 60:
rect_x += 2
for ball in ball_list:
# for loop from above
而不是你所拥有的。当您想要允许按住一个键时,这最有效。pygame.key.get_pressed() 始终获取所有键的状态,而不仅仅是在事件发生时
推荐阅读
- c# - MsiExec.exe 产品 ID 卸载
- spring - @autowired MessageSource 在自定义异常中始终为空
- svg-edit - 如何在 svg-edit 中更改渐变颜色?
- spring-boot - Feign.RetryableException:读取执行 POST [URL] 超时
- php - 如何根据父下拉选择动态选择子下拉列表
- elasticsearch - ELK 部署;CPU、内存、磁盘
- javascript - 复选框未设置在 jquery 中选中 onclick
- java - CSS - 圆形边框看起来像两个重叠的按钮
- rx-java - 如何为 RxAndroidBle 实现同步任务队列
- java - 带有两个表和集合的 HIbernate 标准