Python 如何正确地将重力作用于自由漂浮的空间物体,并在向相反方向推进时产生某种摩擦
我试图对运动进行编程,基本上就像小行星一样,一旦按下“向上”按钮,你们就会加速到一定的速度,因为在太空中你们不会停止,只能通过向相反方向推进来减速。最重要的是,我希望重力将你拉向屏幕底部。我已经完成了大部分工作,但问题是:Python 如何正确地将重力作用于自由漂浮的空间物体,并在向相反方向推进时产生某种摩擦,python,pygame,move,gravity,Python,Pygame,Move,Gravity,我试图对运动进行编程,基本上就像小行星一样,一旦按下“向上”按钮,你们就会加速到一定的速度,因为在太空中你们不会停止,只能通过向相反方向推进来减速。最重要的是,我希望重力将你拉向屏幕底部。我已经完成了大部分工作,但问题是: 当我转身朝相反的方向推进时,它不会先向后减速,然后再开始向前移动,它只是全速朝相反的方向发射 对于如何处理这个问题,并使运动总体上更平稳,有什么建议吗 import pygame as pg import os vec = pg.math.Vector2 TITLE = &
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()
将pygame导入为pg
导入操作系统
向量=pg.math.Vector2
TITLE=“引力”
宽度=800
高度=600
FPS=60
灰色=(211211211211)
#玩家属性
ROCKET_SHIP='Images/ROCKET_SHIP.png'#
玩家_ACC=0.5
游戏者摩擦=-0.00
玩家_GRAV=0.1
玩家旋转速度=200
玩家速度=5
职业玩家(第三页精灵):
定义初始化(self,game,x,y):
精灵精灵。精灵。精灵初始(自我)
self.game=游戏
self.image=game.rocket\u飞船
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_密钥(自):
自旋转速度=0
self.acc=vec(0,玩家重力)
keys=pg.key.get_pressed()
如果键[pg.K_左]:
self.rot\u speed=玩家rot\u speed
如果键[pg.K_RIGHT]:
self.rot\u speed=-玩家rot\u speed
如果键[pg.K_UP]:
self.vel=vec(玩家速度,0)。旋转(-self.rot)
如果键[pg.K_空格]:
self.shoot()
self.acc+=self.vel*玩家摩擦
self.vel+=self.acc
如果self.vel[1]>=2:
自身水平[1]=2
self.pos+=self.vel+0.5*self.acc
def喷射(自):
通过
def更新(自我):
self.get_key()
self.rot=(self.rot+self.rot_speed*self.game.dt)%360
self.image=pg.transform.rotate(self.game.rocket\u ship,self.rot-90)
self.rect=self.image.get_rect()
self.rect.center=self.pos
self.pos+=self.vel*self.game.dt
如果self.pos.x>宽度:
self.pos.x=0
如果自身位置x<0:
self.pos.x=宽度
如果自身位置y>高度:
自身位置y=0
如果自身位置y<0:
self.pos.y=高度
班级游戏:
定义初始化(自):
#初始化pygame并创建窗口
第init页()
pg.mixer.init()
pg.key.set_重复(10,50)
操作系统环境['SDL_视频窗口位置]]=“568101”
self.screen=pg.display.set_模式((宽度、高度))
pg.display.set_标题(标题)
self.clock=pg.time.clock()
self.running=True
self.load_data()
def加载_数据(自身):
self.rocket\u ship=pg.image.load(rocket\u ship).convert\u alpha()
self.rocket_ship=pg.transform.scale(self.rocket_ship,(32,32))
def新(自我):
#开始新游戏
self.all_sprite=pg.sprite.Group()
self.player=player(self,宽度/2,高度/4)
self.all_精灵添加(self.player)
self.run()
def运行(自):
#游戏循环
自弹=真
自娱自乐时:
self.dt=self.clock.tick(FPS)/1000.0
self.events()
self.update()
self.draw()
def更新(自我):
#游戏循环更新
self.all_sprites.update()
def事件(自):
#循环赛项目
对于pg.event.get()中的事件:
如果event.type==pg.QUIT:
如果自己玩:
自我表现=错误
self.running=False
def牵引(自):
#循环平局
pg.display.set_caption(“{.2f}.”格式(self.clock.get_fps())
自我筛选。填充(灰色)
self.all_sprite.draw(self.screen)
#绘制完所有内容后,翻转显示
pg.display.flip()
def显示启动屏幕(自身):
通过
def show_go_屏幕(自身):
通过
g=游戏()
g、 显示启动屏幕()
g.运行时:
g、 新的()
g、 显示屏幕()
第页退出
按UP键时,不必更改速度,但必须设置加速度:
self.vel=vec(玩家速度,0)。旋转(-self.rot)
self.acc+=vec(玩家_acc,0)。旋转(-self.rot)
将加速度添加到速度:
self.vel+=self.acc
我建议限制最大值。但是,我建议对每个方向分别执行此操作:
max\u 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]))
将此应用于方法获取密钥
:
职业玩家(pg.sprite.sprite):
# [...]
def get_密钥(自):
自旋转速度=0
self.acc=vec(0,玩家重力)
keys=pg.key.get_pressed()
如果键[pg.K_左]:
self.rot\u speed=玩家rot\u speed
如果键[pg.K_RIGHT]:
self.rot\u speed=-玩家rot\u speed
如果键[pg.K_UP]:
self.acc+=vec(玩家_acc,0)。旋转(-self.rot)
如果键[pg.K_空格]:
self.shoot()
self.vel+=self.acc+self.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
rabbi76一如既往,感谢您的回复。我最初有self.acc+=vec(PLAYER_acc,0)。rotate(-self.rot),但没有在vec.y位置设置任何最大值。正如预期的那样,现在只需调整ACC、GRAV和mex__\n级别的数字,就可以得到我想要的感觉。