我希望玩家1持续向下加速。我注意到的一切都是我创造引力的尝试。我离开了我的最后一次尝试,因为它看起来非常接近,但它仍然不对。
另外,我怎么做到这样当钥匙被释放时,player1会继续移动,但是会停止加速?我尝试了一个if
语句,我检查了没有键被按下,但后来我不知道怎么让player1以恒定的速度向它移动的方向移动,所以我就把它取出来了。
另外,为什么player1有时会“卡在”屏幕边缘?我对这个问题的最好猜测是它与pygame本身有关。
import sys
import pygame
pygame.init()
screen_width = 640
screen_height = 480
screen = pygame.display.set_mode((screen_width, screen_height))
screen_rect = screen.get_rect()
clock = pygame.time.Clock()
fps = 30
class Character(object):
def __init__(self, surface, accel, gravity):
self.surface = surface
self.accel = accel
self.gravity = gravity
self.x_mag = 0
self.y_mag = 0
self.x_dir = 0
self.y_dir = 0
self.vel = {"x_vel":
{"x_mag": self.x_mag, "x_dir": self.x_dir},
"y_vel":
{"y_mag": self.y_mag, "y_dir": self.y_dir}}
self.x_pos = (screen_width / 2)
self.y_pos = (screen_height / 2)
self.pos = {"x_pos": self.x_pos, "y_pos": self.y_pos}
self.size = (10, 10)
def move_right(self):
self.vel["x_vel"]["x_dir"] = 1
self.vel["y_vel"]["y_dir"] = 0
self.vel["x_vel"]["x_mag"] += self.accel
self.pos["x_pos"] += (self.vel["x_vel"]["x_mag"] * self.vel["x_vel"]["x_dir"])
def move_left(self):
self.vel["x_vel"]["x_dir"] = 1
self.vel["y_vel"]["y_dir"] = 0
self.vel["x_vel"]["x_mag"] -= self.accel
self.pos["x_pos"] += (self.vel["x_vel"]["x_mag"] * self.vel["x_vel"]["x_dir"])
def move_up(self):
self.vel["x_vel"]["x_dir"] = 0
self.vel["y_vel"]["y_dir"] = 1
self.vel["y_vel"]["y_mag"] -= self.accel
self.pos["y_pos"] += (self.vel["y_vel"]["y_mag"] * self.vel["y_vel"]["y_dir"])
def move_down(self):
self.vel["x_vel"]["x_dir"] = 0
self.vel["y_vel"]["y_dir"] = 1
self.vel["y_vel"]["y_mag"] += self.accel
self.pos["y_pos"] += (self.vel["y_vel"]["y_mag"] * self.vel["y_vel"]["y_dir"])
def move(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
self.move_up()
if keys[pygame.K_a]:
self.move_left()
if keys[pygame.K_s]:
self.move_down()
if keys[pygame.K_d]:
self.move_right()
if self.pos["x_pos"] <= 0 or self.pos["x_pos"] >= screen_width:
self.vel["x_vel"]["x_mag"] *= -1
self.vel["x_vel"]["x_dir"] = 0
if self.pos["y_pos"] <= 0 or self.pos["y_pos"] >= screen_height:
self.vel["y_vel"]["y_mag"] *= -1
self.vel["y_vel"]["y_dir"] = 0
#self.vel["y_vel"]["y_mag"] += self.gravity
#self.pos["y_pos"] += (self.vel["y_vel"]["y_mag"] * self.vel["y_vel"]["y_dir"])
self.pos["y_pos"] *= self.gravity
self.character = pygame.Rect((self.pos["x_pos"], self.pos["y_pos"]), self.size)
self.character.clamp_ip(screen_rect)
def display(self):
pygame.draw.rect(self.surface, (255, 255, 255), self.character)
def reset(self):
(x_pos, y_pos) = pygame.mouse.get_pos()
self.pos["x_pos"] = x_pos
self.pos["y_pos"] = y_pos
self.vel["x_vel"]["x_mag"] = 0
self.vel["y_vel"]["y_mag"] = 0
# class Gravity(Character):
# def __init__(self, accel_due_to_grav):
# self.accel_due_to_grav = accel_due_to_grav
#
# def active(self):
# self.vel["y_vel"]["y_mag"] += self.accel_due_to_grav
# self.pos["y_pos"] += (self.vel["y_vel"]["y_mag"] * self.vel["y_vel"]["y_dir"])
def main():
player1 = Character(screen, .5, .5)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
player1.reset()
# grav01 = Gravity(.01)
# grav01.active()
player1.move()
screen.fill((0, 0, 0))
player1.display()
pygame.display.update(screen_rect)
clock.tick(fps)
if __name__ == "__main__":
main()
答案 0 :(得分:2)
没有太多的物理学让你烦恼:对于恒定的加速度(例如地球表面的重力),我们得到v = v_0 + a*t
(其中v_0
是你在重力作用于你之前的速度(例如,在你跳下之前站在塔上 - 不推荐)
对于恒定速度(这意味着没有加速度 - 例如:滑冰),您的位置会随x = x_0 + v*t
变化。
如果您想知道在应用某些加速度并具有一定速度时位置如何变化:x = x_0 + v_0*t + 0.5*a*t²
如果你在游戏中有一个速度和一个加速度,你想知道你的角色的位置需要如何改变,你可以设置t = 1/30
(例如,如果你为每一帧计算它)和知道在下一帧中你的角色将位于x = x_old + v*t + 0.5*a*t²
位置并且他的速度将是v = v_old + a*t
(这当然只是一个近似值,但对游戏而言足够好)
Gravity课几乎就在那里。至少对于y方向。您可以以相同的方式计算x方向上的位移,但是在没有重力的情况下计算。使用您在评论中提供的重新编写的代码,我会尝试将此函数添加到class Character(object)
定义,并在调用display之前在main()
中调用它。
def apply_gravity(self):
timestep = 1./30 # or something else to your liking
self.vel["y_vel"]["y_mag"] += self.accel_due_to_grav * timestep
self.pos["y_pos"] += (self.vel["y_vel"]["y_mag"] * self.vel["y_vel"]["y_dir"]) * timestep
self.pos["y_pos"] += 0.5* self.accel_due_to_grav * timestep**2
另外,如果你不希望机芯看起来像是滑冰的那个,你可能会引入摩擦(在速度的相反方向上的小加速度)或潮湿速度(在每个时间步长乘以0.9这样的东西)