与墙壁的碰撞不会阻止物体的速度
Collision with wall doesn't stop object's velocity
我正在开发一款游戏,在该游戏中,每当玩家的 x >= 屏幕宽度时,我希望玩家的 x 速度 = 0。但是当我尝试时,它不起作用。碰撞代码对我来说看起来不错,我认为我调用 player.collision()
.
时存在一些问题
PS。当对象 x <= 0 时,对象的速度等于 0,但当 x >= displayW
时,速度不等于 0.
问题在#collision to walls
下
PYTHON
# IMPORTS
import pygame, random;
# GLOBALS
global screen, displayW, displayH;
global clock, FPS;
global end, food, player;
# SETGLOBALVALUES
def setGlobalValues():
global screen, displayW, displayH;
global clock, FPS;
global end, food, player;
displayW = 800;
displayH = 600;
screen = pygame.display.set_mode((displayW, displayH));
clock = pygame.time.Clock();
FPS = 60;
end = False;
food = Food();
player = Player();
# MAIN
def main():
pygame.init();
setGlobalValues();
setup();
gameLoop();
quitGame();
# GAMELOOP
def gameLoop():
global end, player;
while(not end):
for event in pygame.event.get():
# ONCLICK QUIT
if(event.type == pygame.QUIT):
end = True;
# KEYDOWN
if(event.type == pygame.KEYDOWN):
if(event.key == pygame.K_LEFT):
player.velX -= 1;
if(event.key == pygame.K_RIGHT):
player.velX += 1;
# KEYUP
if(event.type == pygame.KEYUP):
if(event.key == pygame.K_LEFT):
player.velX = 0;
if(event.key == pygame.K_RIGHT):
player.velX = 0;
draw();
animate();
collision();
# DRAW
def draw():
global screen, food, player;
# fill background
screen.fill((255, 255, 255));
player.draw();
# update
pygame.display.update();
# ANIMATE
def animate():
global food, player;
food.animate();
player.animate();
# COLLISION
def collision():
player.collision();
# CLASSES
class Food():
def __init__(self, x=0, y=0, w=0, h=0, velY=0, color=()):
global displayW;
self.x = random.randrange(0, displayW);
self.y = -100;
self.w = 20;
self.h = 20;
self.velY = 0.7;
self.color = (255, 0, 0);
def draw(self):
global screen;
pygame.draw.rect(screen, self.color, (self.x, self.y, self.w, self.h));
def animate(self):
self.y += self.velY;
def collision(self):
global displayW, displayH;
pass;
class Player():
def __init__(self, x=0, y=0, velX=0, velY=0, w=0, h=0, color=()):
global displayW, displayH;
self.w = 20;
self.h = 20;
self.x = displayW / 2 - self.w / 2;
self.y = displayH - 100;
self.velX = 0;
self.velY = 0;
self.color = (0, 0, 0);
def draw(self):
global screen;
pygame.draw.ellipse(screen, self.color, (self.x, self.y, self.w, self.h));
def animate(self):
self.x += self.velX;
self.y += self.velY;
def collision(self):
global displayW;
# collision to walls
if(self.x <= 0):
self.velX = 0;
elif(self.x >= displayW):
self.velX = 0;
# SETUP
def setup():
pygame.display.set_caption("Food Catcher");
# QUIT GAME
def quitGame():
pygame.quit();
quit();
# CALL MAIN
if(__name__ == "__main__"):
main();
逻辑是正确的 - 但它允许玩家在两侧慢慢 "sleep by"。您认为它在左侧工作,而玩家在右侧消失的原因是您确实将屏幕宽度与玩家的 left 角坐标进行了比较。当它为零时,播放器在屏幕上。但是当 player.x == 屏幕宽度时,玩家已经离开了屏幕。
将您的条件更改为:
elif(self.x + self.h) >= displayW:
逻辑是正确的 - 但你在那里没有延迟,这意味着你的更新速度与计算机重新绘制屏幕的速度一样快 - 而且,新毒药 (player.animate) 的计算发生在之后由于按键,你更新了速度 (velX),在你检查是否有碰撞,并将速度降低到 0。
所以,玩家的速度实际上没有变化,即使碰撞检测将它降低到零 - 在下一帧,它会通过连续按键再次增加。我只是不确定为什么它不会在 left-hand 端消失。
无论如何,只需将对 "collision" 的调用更改为在调用动画之前进行。
更多pygame技巧:在你的while循环中包含几十微秒的延迟。这样,游戏就不会耗尽您的 CPU 的 100%。只需调用 pygame.time.delay(20)
即可。此外,您会注意到一次移动 1 或 2 像素可能会很慢 - 因此,请将速度调整为 5 或 10 像素的倍数。
并且,在 "collision" 方法上。不仅改变速度,还改变位置,让玩家在屏幕上。
更多Python技巧: 与其他语言的一大堆不同,Python 不是 C 语法的直接修改:不需要 ;
在每一行,并且不需要 ( )
围绕 if 表达式(无论如何它们由 :
分隔)。此外,如果您仅使用全局变量进行读取,或调用存储在全局变量中的对象中的方法,则无需声明它 - 实际上您需要 none 个 global
声明,但在 setGlobalValues
函数上。
我正在开发一款游戏,在该游戏中,每当玩家的 x >= 屏幕宽度时,我希望玩家的 x 速度 = 0。但是当我尝试时,它不起作用。碰撞代码对我来说看起来不错,我认为我调用 player.collision()
.
PS。当对象 x <= 0 时,对象的速度等于 0,但当 x >= displayW
时,速度不等于 0.
问题在#collision to walls
PYTHON
# IMPORTS
import pygame, random;
# GLOBALS
global screen, displayW, displayH;
global clock, FPS;
global end, food, player;
# SETGLOBALVALUES
def setGlobalValues():
global screen, displayW, displayH;
global clock, FPS;
global end, food, player;
displayW = 800;
displayH = 600;
screen = pygame.display.set_mode((displayW, displayH));
clock = pygame.time.Clock();
FPS = 60;
end = False;
food = Food();
player = Player();
# MAIN
def main():
pygame.init();
setGlobalValues();
setup();
gameLoop();
quitGame();
# GAMELOOP
def gameLoop():
global end, player;
while(not end):
for event in pygame.event.get():
# ONCLICK QUIT
if(event.type == pygame.QUIT):
end = True;
# KEYDOWN
if(event.type == pygame.KEYDOWN):
if(event.key == pygame.K_LEFT):
player.velX -= 1;
if(event.key == pygame.K_RIGHT):
player.velX += 1;
# KEYUP
if(event.type == pygame.KEYUP):
if(event.key == pygame.K_LEFT):
player.velX = 0;
if(event.key == pygame.K_RIGHT):
player.velX = 0;
draw();
animate();
collision();
# DRAW
def draw():
global screen, food, player;
# fill background
screen.fill((255, 255, 255));
player.draw();
# update
pygame.display.update();
# ANIMATE
def animate():
global food, player;
food.animate();
player.animate();
# COLLISION
def collision():
player.collision();
# CLASSES
class Food():
def __init__(self, x=0, y=0, w=0, h=0, velY=0, color=()):
global displayW;
self.x = random.randrange(0, displayW);
self.y = -100;
self.w = 20;
self.h = 20;
self.velY = 0.7;
self.color = (255, 0, 0);
def draw(self):
global screen;
pygame.draw.rect(screen, self.color, (self.x, self.y, self.w, self.h));
def animate(self):
self.y += self.velY;
def collision(self):
global displayW, displayH;
pass;
class Player():
def __init__(self, x=0, y=0, velX=0, velY=0, w=0, h=0, color=()):
global displayW, displayH;
self.w = 20;
self.h = 20;
self.x = displayW / 2 - self.w / 2;
self.y = displayH - 100;
self.velX = 0;
self.velY = 0;
self.color = (0, 0, 0);
def draw(self):
global screen;
pygame.draw.ellipse(screen, self.color, (self.x, self.y, self.w, self.h));
def animate(self):
self.x += self.velX;
self.y += self.velY;
def collision(self):
global displayW;
# collision to walls
if(self.x <= 0):
self.velX = 0;
elif(self.x >= displayW):
self.velX = 0;
# SETUP
def setup():
pygame.display.set_caption("Food Catcher");
# QUIT GAME
def quitGame():
pygame.quit();
quit();
# CALL MAIN
if(__name__ == "__main__"):
main();
逻辑是正确的 - 但它允许玩家在两侧慢慢 "sleep by"。您认为它在左侧工作,而玩家在右侧消失的原因是您确实将屏幕宽度与玩家的 left 角坐标进行了比较。当它为零时,播放器在屏幕上。但是当 player.x == 屏幕宽度时,玩家已经离开了屏幕。
将您的条件更改为:
elif(self.x + self.h) >= displayW:
逻辑是正确的 - 但你在那里没有延迟,这意味着你的更新速度与计算机重新绘制屏幕的速度一样快 - 而且,新毒药 (player.animate) 的计算发生在之后由于按键,你更新了速度 (velX),在你检查是否有碰撞,并将速度降低到 0。
所以,玩家的速度实际上没有变化,即使碰撞检测将它降低到零 - 在下一帧,它会通过连续按键再次增加。我只是不确定为什么它不会在 left-hand 端消失。
无论如何,只需将对 "collision" 的调用更改为在调用动画之前进行。
更多pygame技巧:在你的while循环中包含几十微秒的延迟。这样,游戏就不会耗尽您的 CPU 的 100%。只需调用 pygame.time.delay(20)
即可。此外,您会注意到一次移动 1 或 2 像素可能会很慢 - 因此,请将速度调整为 5 或 10 像素的倍数。
并且,在 "collision" 方法上。不仅改变速度,还改变位置,让玩家在屏幕上。
更多Python技巧: 与其他语言的一大堆不同,Python 不是 C 语法的直接修改:不需要 ;
在每一行,并且不需要 ( )
围绕 if 表达式(无论如何它们由 :
分隔)。此外,如果您仅使用全局变量进行读取,或调用存储在全局变量中的对象中的方法,则无需声明它 - 实际上您需要 none 个 global
声明,但在 setGlobalValues
函数上。