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

时间:2017-02-04 03:12:20

标签: python pygame collision-detection collision

我正在开发一款游戏,并且在该游戏中,只要玩家的x是> =屏幕的宽度,我就希望玩家的x速度为= 0.但是当我尝试时,它不起作用。碰撞代码对我来说很好,我认为当我调用player.collision()时存在一些问题。

PS。当对象x <&lt; = 0时,对象的速度等于0,但当x>&gt; = 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();

1 个答案:

答案 0 :(得分:2)

逻辑是正确的 - 但它允许玩家在两边慢慢“睡觉”。您认为它在左侧工作的原因,以及在严谨方面消失的玩家是您将屏幕的宽度与播放器的角坐标进行比较。当它为零时,播放器在屏幕上。但是当player.x ==屏幕宽度时,播放器已经从屏幕上拉出。

将您的条件更改为:

elif(self.x  + self.h) >= displayW:

逻辑是正确的 - 但是你没有延迟,这意味着你可以像计算机重新绘制屏幕一样快地获取更新 - 并且,在你更新了之后,新的poision(player.animate)的计算就会发生。由于按键的速度(velX),之前检查是否存在切割,并将速度降低到0。

因此,即使碰撞检测将其降低到零,玩家的速度实际上也没有变化 - 在下一帧,它将通过连续按键再次增加。我只是不确定为什么它不会在左侧消失。

无论如何,只需在调用动画之前将呼叫更改为“碰撞”即可。

更多pygame提示:在while循环中包含几十微秒的延迟。这样,游戏不会占用100%的CPU。只需拨打pygame.time.delay(20)即可。此外,您会注意到每次移动1或2px可能会很慢 - 因此,请以5或10px的倍数调整速度。

并且,在“碰撞”方法上。不仅改变速度,还改变位置,以便玩家在屏幕上。

更多Python提示:与其他语言的gazzilion不同,Python不是C sytax的直接修改:不需要每行;,也不需要{{1如果表达式(它们由( )分隔)。此外,如果您只使用全局变量进行读取,或者调用存储在全局变量中的对象中的方法,则无需声明它 - 实际上您不需要那些:声明,而是在global功能。