Python Pygame-移动漂移

Python Pygame-移动漂移,python,pygame,Python,Pygame,我现在有一个对象,它有代码围绕其中心旋转并移动它(通过改变其pos值) 然而,我想这样做,如果按下向上箭头,它将在其面对的方向上加速,当它被释放时,它将再次减速回到0。在代码中,我使用dt值表示时间变化 我尝试记录按下和松开按钮的时间,并将其用作dt值,使用此方法,dt值可以为负值。我还认为这是行不通的,因为这样火箭会收到一个1秒的dT值,并更新它的速度,使其非常快,而不是平稳加速/减速 class Rocket: def __init__(self, image, pos, angle

我现在有一个对象,它有代码围绕其中心旋转并移动它(通过改变其pos值)

然而,我想这样做,如果按下向上箭头,它将在其面对的方向上加速,当它被释放时,它将再次减速回到0。在代码中,我使用
dt
值表示时间变化

我尝试记录按下和松开按钮的时间,并将其用作
dt
值,使用此方法,
dt
值可以为负值。我还认为这是行不通的,因为这样火箭会收到一个1秒的
dT
值,并更新它的速度,使其非常快,而不是平稳加速/减速

class Rocket:
    def __init__(self, image, pos, angle):
        self.image = pygame.image.load(image)
        self.imageDimensions = self.image.get_rect()
        self.angle = angle
        self.pos = pos
        self.center = (self.pos[0], self.pos[1])

        self.velocity = [0, 0]

        self.acceleration = [0, 0]
        self.angularVelocity = 0
        self.angularAcceleration = 0

        self.isAccelerating = False
        self.thrust = 50

    def draw(self, surface):
        rotatedImg = pygame.transform.rotate(self.image, self.angle)
        rotatedImgDimensions = rotatedImg.get_rect()

        #display image
        surface.blit(rotatedImg, (self.pos[0] - rotatedImgDimensions.center[0], self.pos[1] - rotatedImgDimensions.center[1]))

    def update(self, dt):
        #update angle
        self.angularVelocity += self.angularAcceleration * dt
        self.angle += self.angularVelocity * dt

        #if accelerating update the acceleration
        if self.isAccelerating:
            self.acceleration[0] -= self.thrust * math.sin(math.radians(self.angle))
            self.acceleration[1] -= self.thrust * math.sin(math.radians(self.angle))

        #update velocity
        self.velocity[0] += self.acceleration[0] * dt
        self.velocity[1] += self.acceleration[1] * dt

        #update position
        self.pos[0] += self.velocity[0] * dt
        self.pos[1] += self.velocity[1] * dt
简而言之,当我按下向上箭头时,火箭会加速前进;当我按下向下箭头时,火箭会加速到0;当按下向左和向右箭头时,火箭会向左和向右旋转

请注意,上面的类位于另一个名为
Objects.py的文件中

谢谢

以下是代码的其余部分:

import pygame
from pygame.locals import *
import math
import Objects

#colors
WHITE = (255,255,255)
BLACK = (0,0,0)
TRANSPARENT = (0,0,0,0)

#size window
Width, Height = (1280,720)

#Main menu
def game_intro():
    intro = True

    while intro:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    intro = False
        screen.fill(BLACK)


FPS = 30

#initialise pygame
pygame.init()
fpsClock = pygame.time.Clock()

screen = pygame.display.set_mode((Width, Height))
pygame.display.set_caption("Rockets and Missiles")

#Add players
Rocket1 = Objects.Rocket("rocket.png", [100, 100], 0)    #start at pos 50,50

#run main menu first
game_intro()
run = True
while run:

    screen.fill(BLACK)

    Rocket1.draw(screen)

    #event handler

    pressed = pygame.key.get_pressed() #list with all pressed keys
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            Time0 = pygame.time.get_ticks()
        if event.type == pygame.KEYUP:
            Time1 = pygame.time.get_ticks()

    if pressed[pygame.K_UP]:
        dT = Time1 - Time0
        print(dT)
        Rocket1.update(dT)

    pygame.display.update()
    fpsClock.tick(FPS)

pygame.quit()
quit()

我认为你对
dT
没有一个非常有用的定义。据我所知,只有在按下一个键时才调用
Rocket.update()
,如果你想要平滑运动,火箭需要用小的
dT
更新每一帧。如果不在火箭类中更一致地调用
update()
,您将无法获得所需的良好运动

对于主循环,我建议如下:

dT = 1/FPS
while run:

    screen.fill(BLACK)

    Rocket1.draw(screen)

    #event handler

    pressed = pygame.key.get_pressed() #list with all pressed keys
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    if pressed[pygame.K_UP]:
        Rocket1.ChangeCurrentAcceleration()
    Rocket1.update()
    pygame.display.update()
    fpsClock.tick(FPS)
while run:

    screen.fill(BLACK)

    Rocket1.draw(screen)

    #draw missiles
    for missile in Missiles:
        missile.draw(screen)

    #event handler

    pressed = pygame.key.get_pressed() #list with all pressed keys
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    if pressed[K_UP]:
        Rocket1.acceleration = [0, -100]
    if pressed[K_DOWN]:
        Rocket1.acceleration = [0, 100]
    if pressed[K_RCTRL]:
        Missiles.append(Objects.Missile("missile.png", Rocket1.pos, Rocket1.angle))

    dT = fpsClock.get_time()

    Rocket1.update(dT/1000)

    pygame.display.update()
    fpsClock.tick(FPS)

对于增加火箭加速度的一些新的
ChangeCurrentAcceleration()
函数,您可以更改
update()
,以假设火箭已经具有来自推力的适当加速度,并从中计算新的速度和位置(可能为加速度添加一个0.95*乘数,使其自然减速).

我认为测量按下按钮的时间不是正确的方法。主循环的每次迭代对应于固定的时间量,要生成动画,您需要在每次迭代中以固定的时间量移动火箭。因此,无需按您现在的方式计算a
dt
。您已经有了它,它等于
1/FPS

你通常要做的是为你的火箭设定一些速度/加速度。现在它们都是0,但您应该设置一个不同于零的固定值:当按下按键时,您希望它加快多少,或者您希望它加快多少。
当按下相应的按键时,调用
update
方法,根据该速度/加速度计算新的位置/角度,然后重新绘制火箭,考虑到所经过的时间为
1/FPS


另外,还需要两种方法分别更新线性运动和旋转。现在的方法是,你不能根据不同的键来区分动作。

谢谢大家的帮助,我没有意识到这一部分:D 不过,我想为稍后访问此页面的人回答我自己的问题

一种更好的方法可能是获得软件在每次迭代中花费的时间,并将其用作dT。它将如下所示:b在主循环前面:
fpscall=pygame.time.Clock()

主回路:

dT = 1/FPS
while run:

    screen.fill(BLACK)

    Rocket1.draw(screen)

    #event handler

    pressed = pygame.key.get_pressed() #list with all pressed keys
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    if pressed[pygame.K_UP]:
        Rocket1.ChangeCurrentAcceleration()
    Rocket1.update()
    pygame.display.update()
    fpsClock.tick(FPS)
while run:

    screen.fill(BLACK)

    Rocket1.draw(screen)

    #draw missiles
    for missile in Missiles:
        missile.draw(screen)

    #event handler

    pressed = pygame.key.get_pressed() #list with all pressed keys
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    if pressed[K_UP]:
        Rocket1.acceleration = [0, -100]
    if pressed[K_DOWN]:
        Rocket1.acceleration = [0, 100]
    if pressed[K_RCTRL]:
        Missiles.append(Objects.Missile("missile.png", Rocket1.pos, Rocket1.angle))

    dT = fpsClock.get_time()

    Rocket1.update(dT/1000)

    pygame.display.update()
    fpsClock.tick(FPS)