前言
在pygame中一般刚入门书籍上的游戏项目玩家移动逻辑如下:
玩家坐标.x += 移动方向 * 速度
玩家坐标.y += 移动方向 * 速度
使用这种移动逻辑的缺点十分明显,就是玩家的移动速度会受到电脑性能的影响。主要体现在游戏运行时候帧率不一样,高性能的电脑帧率比较高,代码调用频率高,玩家移动的速度就会快。虽然可以通过设置固定频率,但是谁也不能保证每一台电脑都能够顶着游戏设置的帧率跑满吧。
解决方案
使用增量时间
增量时间概念
增量时间(Delta Time,通常简写为dt
)是用来衡量从上一帧到当前帧所经过的时间量(通常以秒为单位)。这是游戏开发中处理动画、物理模拟等时非常重要的一个概念,它允许游戏以独立于实际帧率的速度运行。
增量时间的使用及解释
使用增量时间后的玩家移动逻辑如下
玩家坐标.x += 移动方向 * 速度 * dt
玩家坐标.y += 移动方向 * 速度 * dt
很好理解帧率高的玩家dt比较小,虽然代码执行效率比较高但是我移动的距离短;帧率比较低的玩家虽然我代码执行效率低,但是每次dt大我移动的距离就大。当帧率高的玩家和帧率低的玩家同时按下移动键相同时间,dt之和基本相同,移动的距离也基本相同。
测试代码
大家可以使用下面代码进行测试,可以在设置玩家文件里面中的move函数中把增量时间dt给删除,然后在设置文件里面更改帧率FPS看看移动速率的变化。再对比之后加上增量时间后的玩家移动速度。
这里还有一个,大家在开发游戏的时候还是要组织好代码结构,不要放在一个文件中后面不好更改,也不好升级优化。
main.py(主函数)
import pygame, sys
from level import Level
from settings import *
class Game:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('测试') # 设置标题
self.clock = pygame.time.Clock() # 创建时钟对象
self.level = Level()
def run(self):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
dt = self.clock.tick(FPS) / 1000 # 计算自上次调用到现在经过的秒数
self.level.run(dt)
pygame.display.flip()
if __name__ == '__main__':
game = Game()
game.run()
player.py(玩家)
import pygame
from settings import *
class Player:
def __init__(self):
# 获取显示界面
self.display_surface = pygame.display.get_surface()
# 玩家设置
self.width, self.height = 20, 20
self.speed = 200 # 玩家速度
# 玩家移动方向
self.direction = pygame.math.Vector2()
# 绘制玩家
left = SCREEN_WIDTH / 2 - self.width / 2
top = SCREEN_HEIGHT / 2 - self.height / 2
self.player_rect = pygame.Rect(left, top, self.width, self.height)
def draw_player(self):
pygame.draw.rect(surface=self.display_surface, color='green', rect=self.player_rect)
def input(self):
"""获取键盘输入"""
keys = pygame.key.get_pressed()
# ↑ and ↓
if keys[pygame.K_UP] or keys[pygame.K_w]:
self.direction.y = -1
elif keys[pygame.K_DOWN] or keys[pygame.K_s]:
self.direction.y = 1
else:
self.direction.y = 0
# ← and →
if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
self.direction.x = 1
elif keys[pygame.K_LEFT] or keys[pygame.K_a]:
self.direction.x = -1
else:
self.direction.x = 0
def move(self, dt):
"""玩家移动"""
self.input()
# 不使用增量时间的可以把dt删除掉
self.player_rect.x += self.direction.x * self.speed * dt
self.player_rect.y += self.direction.y * self.speed * dt
self.draw_player()
level.py(游戏进度)
import pygame
from player import Player
class Level:
def __init__(self):
# 获取显示界面
self.display_surface = pygame.display.get_surface()
self.display_surface_rect = self.display_surface.get_rect()
self.player = Player()
def run(self, dt):
self.display_surface.fill('white') # 填充白色
self.player.move(dt)
settings.py(设置文件)
# 屏幕宽度、屏幕高度
SCREEN_WIDTH, SCREEN_HEIGHT = 1200, 800
# 帧率
FPS = 90
遗留问题
现在解决了玩家以独立于实际帧率的速度运行,但是这里又有一个新问题,大家阅读一下玩家移动的代码,想一下在斜着方向上的移动速率和水平方向的移动速率是一样的吗?
标签:self,玩家,pygame,dt,移动,display From: https://blog.csdn.net/weixin_60062799/article/details/140858888