Python 在pygame中添加重力
我希望在player1上有一个恒定的向下加速度。我所评论的一切都是我创造引力的尝试。我在最后一次尝试中离开了,因为它看起来非常接近,但仍然不对 另外,我如何使它在释放键时,player1将继续移动,但停止加速?我尝试了一个Python 在pygame中添加重力,python,pygame,Python,Pygame,我希望在player1上有一个恒定的向下加速度。我所评论的一切都是我创造引力的尝试。我在最后一次尝试中离开了,因为它看起来非常接近,但仍然不对 另外,我如何使它在释放键时,player1将继续移动,但停止加速?我尝试了一个if语句,检查没有按下任何键,但是我不知道如何使player1以恒定的速度朝着它前进的方向移动,所以我就把它拿了出来 还有,为什么player1有时会“卡在”屏幕边缘?我对这一点的最佳猜测是,它与pygame本身有关 import sys import pygame pyga
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()
导入系统
导入pygame
pygame.init()
屏幕宽度=640
屏幕高度=480
screen=pygame.display.set_模式((屏幕宽度、屏幕高度))
screen\u rect=screen.get\u rect()
clock=pygame.time.clock()
fps=30
类字符(对象):
定义初始(自身、表面、加速度、重力):
self.surface=曲面
自加速=加速
重力
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_水平”:
{“y_-mag”:self.y_-mag,“y_-dir”:self.y_-dir}
self.x_pos=(屏幕宽度/2)
self.y\u pos=(屏幕高度/2)
self.pos={“x_pos”:self.x_pos,“y_pos”:self.y_pos}
self.size=(10,10)
def向右移动(自身):
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向左移动(自身):
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上移(自):
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向下移动(自):
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移动(自我):
keys=pygame.key.get_pressed()
如果键[pygame.K_w]:
self.move_up()
如果键[pygame.K_a]:
self.move_left()
如果键[pygame.K_s]:
self.move_down()
如果键[pygame.K_d]:
self.move_right()
如果self.pos[“x_pos”]=屏幕宽度:
self.vel[“x_vel”][“x_mag”]*=-1
self.vel[“x_vel”][“x_dir”]=0
如果self.pos[“y_pos”]=屏幕高度:
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.climp\u ip(屏幕显示)
def显示(自):
pygame.draw.rect(self.surface,(255,255,255),self.character)
def重置(自):
(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
#级别(字符):
#定义初始值(自、加速到期至重力):
#self.accel_due_to_grav=加速度_due_to_grav
#
#def激活(自):
#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=字符(屏幕,.5,.5)
尽管如此:
对于pygame.event.get()中的事件:
如果event.type==pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type==pygame.MOUSEBUTTONDOWN:
player1.reset()
#grav01=重力(.01)
#grav01.active()
player1.move()
屏幕填充((0,0,0))
player1.display()
pygame.display.update(屏幕显示)
时钟滴答声(fps)
如果名称=“\uuuuu main\uuuuuuuu”:
main()
动机
不要让你厌烦太多的物理:对于恒定加速度(如地球表面的重力),我们有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=xuOld+v*t+0.5*a*t²
,他的速度将是v=vuOld+a*t
(这当然只是一个近似值,但对于游戏来说已经足够好了)
你的代码 重力类就快到了。至少在y方向。你可以用同样的方式计算x方向的位移,但是ofc没有重力。用你在评论中提供的重新编写的代码,我会尝试将这个函数添加到
类字符中
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