如何在 pygame 中使重力起作用?

How to make gravity function in pygame?

无法在 pygame

中移动玩家 所以,我试图在 pygame 中创建一个简单的物理系统。我的主要目标是添加一个 Y 重力功能,激活后可以移动玩家。我已经尝试了几次让它工作,但我想我遗漏了一些东西。

这是代码:

class Physic:
    def __init__(self, color, master, type, sizeX, sizeY, pos=[0,0]):
        self.master = master
        self.color = color
        self.type = type
        self.sizeX = sizeX
        self.sizeY = sizeY
        self.x = pos[0]
        self.y = pos[1]

        self.moveX = 0
        self.moveY = 0

        self.create_Object()


    def create_Object(self):
        if self.type == 'rect':
            self.rect()

    def rect(self):
        return pygame.draw.rect(self.master, self.color, (self.x, self.y, self.sizeX, self.sizeY))

    def drag(self):
        for event in pygame.event.get():
            if event.type == pygame.mouse.get_pressed()[0]:
                self.x = pygame.mouse.get_pos()

    def add_gravity(self):
        self.moveY += 3.2
        self.update_pos()

    def update_pos(self):
        self.y += self.moveY
        self.x += self.moveX


在主脚本中我放了这个:

def game():
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()


        screen.fill(WHITE)

        player = object.Physic(BLUE, screen, 'rect', 50, 50, [POS[0], POS[1]])
        player.add_gravity()

        # platform = object.rect(screen, RED, [30, 30], 100, 30)


        # physics.add_collider(player, platform, POS[0])

        pygame.display.update()


game()

你知道我错过了什么吗?

你的大问题是你在主循环中的每一次传递都重新创建玩家,所以它看起来像是被冻结在原地。

您还需要对帧率进行限制,以便您控制游戏的速度,从而可以适当地设置每帧的加速度。

运行 还有其他一些小问题需要修复。我试图将最小可能更改为 运行 它,因为重点是修复错误而不是重写错误。显然我必须在它周围添加一些包装代码

试试这个稍微调整过的版本:

#!/usr/bin/env python

import traceback
import pygame
import sys

FRAME_RATE = 60
GRAVITY = 32

SCREEN_SIZE = (600, 800)

WHITE = pygame.Color("white")
BLUE = pygame.Color("blue")

POS = (100, 600)

class Physic:
    def __init__(self, color, master, type, sizeX, sizeY, pos=(0,0)):
        self.master = master
        self.color = color
        self.type = type
        self.sizeX = sizeX
        self.sizeY = sizeY
        self.x = pos[0]
        self.y = pos[1]

        self.moveX = 0
        self.moveY = 0

        self.create_Object()


    def create_Object(self):
        if self.type == 'rect':
            self.draw()

    def draw(self):
        return pygame.draw.rect(self.master, self.color, (self.x, self.y, self.sizeX, self.sizeY))

    def drag(self):
        for event in pygame.event.get():
            #if event.type == pygame.mouse.get_pressed()[0]:    <--- remove this
            if event.type == pygame.MOUSEBUTTONDOWN:
                self.x = pygame.mouse.get_pos()

    def add_gravity(self):
        self.moveY += GRAVITY / FRAME_RATE
        self.update_pos()

    def update_pos(self):
        self.y += self.moveY
        self.x += self.moveX

def game():
    
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE)

    clock = pygame.time.Clock()
    
    player = Physic(BLUE, screen, 'rect', 50, 50, POS)
    # I added this to illustrate the gravity better ... going up and down
    player.moveY = -25
    player.moveX = 2

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return


        screen.fill(WHITE)

        player.add_gravity()

        player.draw()

        # platform = object.rect(screen, RED, [30, 30], 100, 30)


        # physics.add_collider(player, platform, POS[0])

        pygame.display.update()

        clock.tick(FRAME_RATE)



def main():
    
    try:
        game()

    except Exception as ex:
        print(traceback.format_exc())
        raise

    finally:
        # game exit cleanup stuff
        pygame.quit()


if __name__ == '__main__':
    main()

我想指出的一个问题,虽然它不影响这里的代码。在方法中定义 optional/named 参数时,不应使用不可变对象(如列表)作为默认对象。 IE。在 Physic __init__() 中,我将 pos=[0,0] 更改为 pos=(0,0)。这里没什么大不了的,但是如果你已经将它分配给一个 var,然后试图改变它,可能会导致非常奇怪的错误。它会对对象的其他实例产生影响,因为它们实际上共享默认的初始化对象,如果它被其中之一修改,它会在所有实例中发生!