与墙壁的碰撞不会阻止物体的速度

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 函数上。