【发布时间】:2014-01-08 03:53:45
【问题描述】:
我希望 player1 有一个恒定的向下加速度作用在他身上。我尝试了几种方法,但它并没有真正按照我想要的方式工作。当我给 player1 向上的速度时,他会越来越高。我尝试改变速度和重力值,它看起来好一点,但我不确定它是否正确。我也希望当玩家1在屏幕底部时有一个摩擦力作用在他身上,但是因为摩擦力取决于法向力,而法向力取决于重力(如果我错了,请纠正我),我真的不能那样做然而,所以我只是对 player1 产生了持续的摩擦,但这也有点“奇怪”。我希望它在速度达到 0 时停止 player1,而不是反转加速度。
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, velo, accel, gravity, friction):
self.surface = surface
self.velo = velo
self.accel = accel
self.gravity = gravity
self.friction = friction
self.timestep = 1/fps
self.vel = (0, 0)
self.pos = ((screen_width / 2), (screen_height / 2))
self.size = (10, 10)
def velocity_right(self):
self.pos = (self.pos[0] + self.velo, self.pos[1])
def velocity_left(self):
self.pos = (self.pos[0] - self.velo, self.pos[1])
def velocity_up(self):
self.pos = (self.pos[0], self.pos[1] - self.velo)
def velocity_down(self):
self.pos = (self.pos[0], self.pos[1] + self.velo)
def velocity(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_i]:
self.velocity_up()
if keys[pygame.K_j]:
self.velocity_left()
if keys[pygame.K_k]:
self.velocity_down()
if keys[pygame.K_l]:
self.velocity_right()
def accelerate_right(self):
self.vel = (self.vel[0] + self.accel, self.vel[1])
self.pos = (self.pos[0] + self.vel[0], self.pos[1])
def accelerate_left(self):
self.vel = (self.vel[0] - self.accel, self.vel[1])
self.pos = (self.pos[0] + self.vel[0], self.pos[1])
def accelerate_up(self):
self.vel = (self.vel[0], self.vel[1] - self.accel)
self.pos = (self.pos[0], self.pos[1] + self.vel[1])
def accelerate_down(self):
self.vel = (self.vel[0], self.vel[1] + self.accel)
self.pos = (self.pos[0], self.pos[1] + self.vel[1])
def accelerate(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
self.accelerate_up()
if keys[pygame.K_a]:
self.accelerate_left()
if keys[pygame.K_s]:
self.accelerate_down()
if keys[pygame.K_d]:
self.accelerate_right()
if self.pos[0] <= 0 or self.pos[0] >= screen_width:
self.vel = (self.vel[0] * -1, self.vel[1])
if self.pos[1] <= 0 or self.pos[1] >= screen_height:
self.vel = (self.vel[0], self.vel[1] * -1)
self.character = pygame.Rect((self.pos[0], self.pos[1]), 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, self.pos[1])
self.pos = (self.pos[0], y_pos)
self.vel = (0, 0)
def apply_gravity(self):
self.vel = (self.vel[0], self.vel[1] + self.accel)
self.pos = (self.pos[0], self.pos[1] + self.vel[1])
# self.vel = (self.vel[0], self.vel[1] + self.gravity * self.timestep)
# self.pos = (self.pos[0], self.pos[1] + self.vel[1] * self.timestep + 0.5 * self.gravity * self.timestep**2)
def apply_friction(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_w] or keys[pygame.K_i]:
self.vel = (self.vel[0], self.vel[1] + self.friction)
self.pos = (self.pos[0], self.pos[1] + self.vel[1])
if keys[pygame.K_a] or keys[pygame.K_j]:
self.vel = (self.vel[0] + self.friction, self.vel[1])
self.pos = (self.pos[0] + self.vel[0], self.pos[1])
if keys[pygame.K_s] or keys[pygame.K_k]:
self.vel = (self.vel[0], self.vel[1] - self.friction)
self.pos = (self.pos[0], self.pos[1] + self.vel[1])
if keys[pygame.K_d] or keys[pygame.K_l]:
self.vel = (self.vel[0] - self.friction, self.vel[1])
self.pos = (self.pos[0] + self.vel[0], self.pos[1])
def main():
player1 = Character(screen, 10, 1, .5, .4)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
player1.reset()
player1.apply_gravity()
player1.apply_friction()
player1.velocity()
player1.accelerate()
screen.fill((0, 0, 0))
player1.display()
pygame.display.update(screen_rect)
clock.tick(fps)
if __name__ == "__main__":
main()
【问题讨论】:
-
以一定速度向上移动的物体将以一定速度减速。例如,如果重力为 1 l/t^2,并且物体的向上速度为 1 l/t,则 1 l/t 除以 1 l/t^2 意味着在一个单位时间后,该物体的速度为0. 再过一个单位时间,物体将以 1 l/t 的速度下降。
-
重力、摩擦和移动按键应该只作用于速度。然后速度应该作用于位置。我认为你的循环应该是这样的: 1. VelY +=重力; 2. VelX /= 摩擦力; 3. VelX,VelY +=(按键结果); 4. PosX,PosY += VelX, VelY;在 Pos 处绘制自我。
-
通过迭代改进代码不断地向 SO 发送垃圾邮件并不是开发软件的合适方式。