我目前有一个对象,该对象具有代码以使其围绕其中心旋转并向周围移动(通过改变其pos值)。
但是我想这样做,以便如果按下向上箭头,它将朝着其面对的方向加速,并且当其释放时,它将再次减速回到0。在代码中,我使用dt
值表示时间的变化。
我尝试计时按下和释放按钮的时间,并将其用作dt
值,使用此方法,dT
值可以为负。我还认为这是行不通的,因为这样火箭将收到dT
值为1秒的值,并且将其速度更新为非常快,而不是进行平滑的加速/减速。
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()
答案 0 :(得分:1)
我认为您对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)
对于某些增加了火箭加速度的新ChangeCurrentAcceleration()
函数,您可以更改update()
来假定它已经具有适当的推力加速度,并据此计算新的速度和位置(可能会添加0.95 *乘数来加速,因此自然会放慢速度。)
答案 1 :(得分:0)
我不认为测量按钮按下的时间是正确的方法。主循环的每次迭代对应于固定的时间量,并且要生成动画,您希望在每次迭代时以固定的时间量移动火箭。因此,您无需按照自己的方式计算dt
。您已经拥有它,它等于1/FPS
。
通常要做的是为火箭设置一些速度/加速度。现在它们全为0,但是您应该设置一个固定值,而不是零:按下键按钮时,希望它快多少,或者希望它快多少。
然后,当按下相应的按键时,调用update
方法以根据该速度/加速度计算新的位置/角度,然后再考虑到经过的时间为1/FPS
,重新绘制火箭。>
您还需要两种方法分别更新线性运动和旋转。现在的方式是,您无法根据不同的键来分开运动。
答案 2 :(得分:0)
感谢大家的帮助,我没有意识到这部分:D 但是,我想为以后稍后访问此页面的人回答我自己的问题。
一种更好的方法是获取软件遍历每个迭代所花费的时间,并将其用作dT。它看起来像如下:B在主循环之前:fpsClock = pygame.time.Clock()
主循环:
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)