问题描述
我正在尝试编写基本上像小行星一样的运动,一旦按下向上按钮,你就会加速到一定的速度,然后因为在太空中你不会停下来,只能通过向相反的方向推动来减慢速度.最重要的是,我希望重力将您拉向屏幕底部.我已经完成了大部分工作,但我遇到的问题是:
I am trying to program movement that is basically like Asteroids where once UP button is pressed you accelerate to a certain speed and then because in space you don't stop and can only slow down by thrusting in opposite direction. On top of that, I would like gravity to be pulling you towards the bottom of the screen. I have this accomplished for the most part but the issue I have is:
- 当我转身向相反方向推时,它不会先向后减速,然后再开始向前移动,而是全速向相反方向发射
关于如何处理这个问题并使运动总体上更顺畅的任何建议?
Any suggestions of how to handle this and make movement smoother in general?
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()
推荐答案
当你按下时,你不必改变速度,但你必须设置加速度:
When you press you don't have to change the speed, but you have to set the acceleration:
self.acc += vec(PLAYER_ACC, 0).rotate(-self.rot)
将加速度与速度相加:
self.vel += self.acc
我建议限制最大值.但是,我建议对每个方向分别执行此操作:
I recommend limiting the maximum. However, I recommend doing this separately for each direction:
max_vel = 2
self.vel[0] = max(-max_vel, min(max_vel, self.vel[0]))
self.vel[1] = max(-max_vel, min(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, min(max_vel, self.vel[0]))
self.vel[1] = max(-max_vel, min(max_vel, self.vel[1]))
self.pos += self.vel
这篇关于当向相反方向推力时,如何正确地对自由漂浮的太空物体施加重力和某种摩擦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!