当通过函数触发碰撞时,碰撞检测的速度重新分配是 none 响应的
velocity reassignment for collision detection is none-responsive when collision is triggered through a function
import pygame as pg
import sys
def main():
pg.init()
clock = pg.time.Clock()
fps = 60
bg = (255, 255, 255)
size = [400, 400]
this = pg.display.set_mode(size)
ay = .5
vy = 2
vx = 4
player = pg.Rect(100, 50, 20, 20)
platform = pg.Rect(0, size[1]-20, size[0], 20)
objs = [player, platform]
colors = [[255, 0, 0], [0, 255, 0]]
move = [pg.K_LEFT, pg.K_RIGHT]
def collide(player, platform, vy):
hit = player.colliderect(platform)
if hit:
if player.bottom >= platform.top:
player.bottom = platform.top
vy = 0
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
return False
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
vy -= 10
key = pg.key.get_pressed()
for i in range(2):
if key[move[i]]:
player.x += vx * [-1, 1][i]
this.fill(bg)
vy += ay
player.y += vy
collide(player, platform, vy)
for i, obj in enumerate(objs):
pg.draw.rect(this, colors[i], obj)
pg.display.update()
clock.tick(fps)
pg.quit()
sys.exit
if __name__ == '__main__':
main()
正如你从上面的代码中看到的那样,我试图通过 "rectcollide" 方法创建一个着陆程序,但由于某些未知原因,无论何时调用该函数,尽管检测到碰撞并且玩家的位置重新-assigned,玩家的速度无论如何都不会改变。奇怪的是,如果我不使用函数并直接在主游戏更新循环中执行条件,它就可以正常工作。所以问题出在我认为的函数行为上。解决此问题的任何帮助将不胜感激。提前致谢。
在你的内部函数中,vy
是一个局部变量(函数的参数)。更改其值不会更改外部函数中 vy
变量的值。您要么需要 return
新速度(并将调用该函数的代码更改为 vy = collide(player, platform, vy)
),要么改变您的设计,使速度成为其他某个对象的属性(可能 player
如果您将其更改为自定义实例 class).
如果您直接访问外部命名空间中的 vy
(不作为参数),您可以在内部函数中使用 nonlocal
语句让它写入外部函数的本地多变的。然而,让事情像这样在其他名称空间上涂鸦通常被认为是糟糕的设计。使用对象或 return 值通常更容易推理,并且在出现问题时更容易调试。
import pygame as pg
import sys
def main():
pg.init()
clock = pg.time.Clock()
fps = 60
bg = (255, 255, 255)
size = [400, 400]
this = pg.display.set_mode(size)
ay = .5
vy = 2
vx = 4
player = pg.Rect(100, 50, 20, 20)
platform = pg.Rect(0, size[1]-20, size[0], 20)
objs = [player, platform]
colors = [[255, 0, 0], [0, 255, 0]]
move = [pg.K_LEFT, pg.K_RIGHT]
def collide(player, platform, vy):
hit = player.colliderect(platform)
if hit:
if player.bottom >= platform.top:
player.bottom = platform.top
vy = 0
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
return False
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
vy -= 10
key = pg.key.get_pressed()
for i in range(2):
if key[move[i]]:
player.x += vx * [-1, 1][i]
this.fill(bg)
vy += ay
player.y += vy
collide(player, platform, vy)
for i, obj in enumerate(objs):
pg.draw.rect(this, colors[i], obj)
pg.display.update()
clock.tick(fps)
pg.quit()
sys.exit
if __name__ == '__main__':
main()
正如你从上面的代码中看到的那样,我试图通过 "rectcollide" 方法创建一个着陆程序,但由于某些未知原因,无论何时调用该函数,尽管检测到碰撞并且玩家的位置重新-assigned,玩家的速度无论如何都不会改变。奇怪的是,如果我不使用函数并直接在主游戏更新循环中执行条件,它就可以正常工作。所以问题出在我认为的函数行为上。解决此问题的任何帮助将不胜感激。提前致谢。
在你的内部函数中,vy
是一个局部变量(函数的参数)。更改其值不会更改外部函数中 vy
变量的值。您要么需要 return
新速度(并将调用该函数的代码更改为 vy = collide(player, platform, vy)
),要么改变您的设计,使速度成为其他某个对象的属性(可能 player
如果您将其更改为自定义实例 class).
如果您直接访问外部命名空间中的 vy
(不作为参数),您可以在内部函数中使用 nonlocal
语句让它写入外部函数的本地多变的。然而,让事情像这样在其他名称空间上涂鸦通常被认为是糟糕的设计。使用对象或 return 值通常更容易推理,并且在出现问题时更容易调试。