(二)pygame保证玩家在各个方面移动速率相同

前言

在专栏pygame游戏开发中的第一篇文章中讲解了增量时间的利用,可以使玩家的移动速率不受帧率的影响。但是存在一个问题是玩家斜着移动的时候速率明显更快。

看一下玩家移动的逻辑

玩家坐标.x += 移动方向 * 速度 * dt
玩家坐标.y += 移动方向 * 速度 * dt

这里的移动方向如果是x或y轴正方向则为+1,负方向为-1,但是速度是矢量,当玩家坐标x和y同时更新的时候,斜着的移动速度就如下图所示。

解决方案

将玩家移动方向设置为方向向量,检测按键按下时候,给方向向量赋值,当方向向量长度大于0时将方向向量归一化处理(向量转换为一个新的向量,这个新向量的方向与原有方向向量相同,但长度(或模)被调整为1),这样等同于把速度给分解了。代码思路如下

# 玩家移动方向
self.direction = pygame.math.Vector2()

# 如果方向向量长度大于0才执行相关动作
if self.direction.magnitude() > 0:
    self.direction = self.direction.normalize()  # 归一化
    self.player_rect.x += self.direction.x * self.speed * dt
    self.player_rect.y += self.direction.y * self.speed * dt
    print(self.direction)

整体代码

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()

        # 如果方向向量长度大于0才执行相关动作
        if self.direction.magnitude() > 0:
            self.direction = self.direction.normalize()  # 归一化
            self.player_rect.x += self.direction.x * self.speed * dt
            self.player_rect.y += self.direction.y * self.speed * dt

        self.draw_player()

settings.py(设置文件)

# 屏幕宽度、屏幕高度
SCREEN_WIDTH, SCREEN_HEIGHT = 1200, 800

# 帧率
FPS = 90

levle.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)

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()

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值