如何在pygame中制作重力函数?

问题描述 投票:0回答:1

我试图在 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()

你知道我错过了什么吗?

python pygame gravity
1个回答
1
投票

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

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

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

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

#!/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()

我想指出的一个问题,虽然它不影响这里的代码。在方法中定义可选/命名参数时,不应使用不可变对象(如列表)作为默认值。 IE。在

Physic
__init__()
我将
pos=[0,0]
更改为
pos=(0,0)
。这里没什么大不了的,但如果你把它分配给一个 var,然后试图改变它,可能会导致非常奇怪的错误。它会对对象的其他实例产生影响,因为它们实际上共享默认的初始化对象,并且如果它被其中一个实例修改,则会在所有实例中发生!

© www.soinside.com 2019 - 2024. All rights reserved.