如何解决当向相反方向推力时,如何正确地对自由漂浮的太空物体施加重力和某种摩擦
我正在尝试编写基本上像小行星一样的运动,一旦按下向上按钮,你就会加速到一定的速度,然后因为在太空中你不会停下来,只能通过向相反的方向推动来减慢速度。最重要的是,我希望重力将您拉向屏幕底部。我已经完成了大部分工作,但我遇到的问题是:
- 当我转身向相反方向推时,它不会先向后减速,然后再开始向前移动,而是全速向相反方向发射
关于如何处理这个问题并使运动总体上更顺畅的任何建议?
import pygame as pg
import os
vec = pg.math.Vector2
TITLE = "GraviTAR"
WIDTH = 800
HEIGHT = 600
FPS = 60
GREY = (211,211,211)
# Player properties
ROCKET_SHIP = 'Images/Rocket_Ship.png' # <a href='https://pngtree.com/so/spaceship-clipart'>spaceship
# clipart png from pngtree.com</a>
PLAYER_ACC = 0.5
PLAYER_FRICTION = -0.00
PLAYER_GRAV = 0.1
PLAYER_ROT_SPEED = 200
PLAYER_SPEED = 5
class Player(pg.sprite.Sprite):
def __init__(self,game,x,y):
pg.sprite.Sprite.__init__(self)
self.game = game
self.image = game.rocket_ship
self.rect = self.image.get_rect()
self.rect.center = (x,y)
self.vel = vec(0,0)
self.pos = vec(x,y)
self.rot = 0
def get_keys(self):
self.rot_speed = 0
self.acc = vec(0,PLAYER_GRAV)
keys = pg.key.get_pressed()
if keys[pg.K_LEFT]:
self.rot_speed = PLAYER_ROT_SPEED
if keys[pg.K_RIGHT]:
self.rot_speed = -PLAYER_ROT_SPEED
if keys[pg.K_UP]:
self.vel = vec(PLAYER_SPEED,0).rotate(-self.rot)
if keys[pg.K_SPACE]:
self.shoot()
self.acc += self.vel * PLAYER_FRICTION
self.vel += self.acc
if self.vel[1] >= 2:
self.vel[1] = 2
self.pos += self.vel + 0.5 * self.acc
def shoot(self):
pass
def update(self):
self.get_keys()
self.rot = (self.rot + self.rot_speed * self.game.dt) % 360
self.image = pg.transform.rotate(self.game.rocket_ship,self.rot - 90)
self.rect = self.image.get_rect()
self.rect.center = self.pos
self.pos += self.vel * self.game.dt
if self.pos.x > WIDTH:
self.pos.x = 0
if self.pos.x < 0:
self.pos.x = WIDTH
if self.pos.y > HEIGHT:
self.pos.y = 0
if self.pos.y < 0:
self.pos.y = HEIGHT
class Game:
def __init__(self):
# Initialize pygame and create window
pg.init()
pg.mixer.init()
pg.key.set_repeat(10,50)
os.environ['SDL_VIDEO_WINDOW_POS'] = '568,101'
self.screen = pg.display.set_mode((WIDTH,HEIGHT))
pg.display.set_caption(TITLE)
self.clock = pg.time.Clock()
self.running = True
self.load_data()
def load_data(self):
self.rocket_ship = pg.image.load(ROCKET_SHIP).convert_alpha()
self.rocket_ship = pg.transform.scale(self.rocket_ship,(32,32))
def new(self):
# Start a new game
self.all_sprites = pg.sprite.Group()
self.player = Player(self,WIDTH / 2,HEIGHT / 4)
self.all_sprites.add(self.player)
self.run()
def run(self):
# Game loop
self.playing = True
while self.playing:
self.dt = self.clock.tick(FPS) / 1000.0
self.events()
self.update()
self.draw()
def update(self):
# Game loop update
self.all_sprites.update()
def events(self):
# Game loop events
for event in pg.event.get():
if event.type == pg.QUIT:
if self.playing:
self.playing = False
self.running = False
def draw(self):
# Game loop draw
pg.display.set_caption("{:.2f}".format(self.clock.get_fps()))
self.screen.fill(GREY)
self.all_sprites.draw(self.screen)
# After drawing everything,flip display
pg.display.flip()
def show_start_screen(self):
pass
def show_go_screen(self):
pass
g = Game()
g.show_start_screen()
while g.running:
g.new()
g.show_go_screen()
pg.quit()
解决方法
当你按下UP时,你不必改变速度,但你必须设置加速度:
self.vel = vec(PLAYER_SPEED,0).rotate(-self.rot)
self.acc += vec(PLAYER_ACC,0).rotate(-self.rot)
将加速度与速度相加:
self.vel += self.acc
我建议限制最大值。但是,我建议对每个方向分别执行此操作:
max_vel = 2
self.vel[0] = max(-max_vel,min(max_vel,self.vel[0]))
self.vel[1] = max(-max_vel,self.vel[1]))
将此应用于方法 get_keys
:
class Player(pg.sprite.Sprite):
# [...]
def get_keys(self):
self.rot_speed = 0
self.acc = vec(0,PLAYER_GRAV)
keys = pg.key.get_pressed()
if keys[pg.K_LEFT]:
self.rot_speed = PLAYER_ROT_SPEED
if keys[pg.K_RIGHT]:
self.rot_speed = -PLAYER_ROT_SPEED
if keys[pg.K_UP]:
self.acc += vec(PLAYER_ACC,0).rotate(-self.rot)
if keys[pg.K_SPACE]:
self.shoot()
self.vel += self.acc + self.vel * PLAYER_FRICTION
max_vel = 2
self.vel[0] = max(-max_vel,self.vel[0]))
self.vel[1] = max(-max_vel,self.vel[1]))
self.pos += self.vel
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。