当向相反方向推力时

当向相反方向推力时

本文介绍了当向相反方向推力时,如何正确地对自由漂浮的太空物体施加重力和某种摩擦的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写基本上像小行星一样的运动,一旦按下向上按钮,你就会加速到一定的速度,然后因为在太空中你不会停下来,只能通过向相反的方向推动来减慢速度.最重要的是,我希望重力将您拉向屏幕底部.我已经完成了大部分工作,但我遇到的问题是:

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:

  1. 当我转身向相反方向推时,它不会先向后减速,然后再开始向前移动,而是全速向相反方向发射

关于如何处理这个问题并使运动总体上更顺畅的任何建议?

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

这篇关于当向相反方向推力时,如何正确地对自由漂浮的太空物体施加重力和某种摩擦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 09:59