• 用 python 写一个模拟玩家移动的示例


    实例:二维矢量模拟玩家移动

    在游戏中,一般使用二维矢量保存玩家的位置,使用矢量计算可以计算出玩家移动的位置,下面的 demo 中,首先实现二维矢量对象,接着构造玩家对象,最后使用矢量对象和玩家对象共同模拟玩家移动的过程

    1)实现二维矢量结构

    矢量是数据中的概念,二维矢量拥有两个方向的信息,同时可以进行加、减、乘(缩放)、距离、单位化等计算

    在计算机中,使用拥有 x 和 y 两个分量的 Vecor2 结构体实现数学中二维向量的概念,如下:

    # coding=utf-8
    import math
    import time
    
    
    # 坐标类
    class Vector(object):
        def __init__(self, x=0, y=0):
            self.x = x
            self.y = y
        
        # 相加
        def add(self, vector):
            self.x += vector.x
            self.y += vector.y
        
        # 相减
        def sub(self, vector):
            x = self.x - vector.x
            y = self.y - vector.y
            return Vector(x, y)
    
        # 相乘
        def multi(self, speed):
            self.x *= speed
            self.y *= speed
            return self
    
        # 计算距离
        def distance(self, vector):
            dx = self.x - vector.x
            dy = self.y - vector.y
            return math.sqrt(dx ** 2 + dy ** 2)
    
        # 矢量单位化
        def normalize(self):
            mag = self.x ** 2 + self.y ** 2
            if mag > 0:
                one_over_mag = 1 / math.sqrt(mag)
                vector = Vector(x=self.x * one_over_mag, y=self.y * one_over_mag)
            else:
                vector = Vector()
            return vector
    

    2)实现玩家对象

    玩家对象负责存储玩家的当前位置、目标位置和移动速度,使用 moveTo() 为玩家设定目的地坐标,使用 update() 更新玩家坐标

    # 玩家类
    class Player(object):
        def __init__(self, current_vector=None, target_vector=None, speed=0):
            self.current_vector = current_vector
            self.target_vector = target_vector
            self.speed = speed
    
        # 获取玩家坐标
        def get_current_vector(self):
            return self.current_vector
    
        # 判断是否到达终点
        def is_arrived(self):
            return self.current_vector.distance(self.target_vector) < self.speed
    
        # 更新玩家位置
        def update_vector(self):
            # 获取方向矢量(固定值)
            direction_vector = self.target_vector.sub(self.current_vector)
            # 矢量单位化(固定值)
            normalize_vector = direction_vector.normalize()
            # 根据速度计算 x, y 方向上前进的长度
            ongoing_vector = normalize_vector.multi(self.speed)
            # 更新位置
            self.current_vector.add(ongoing_vector)

    更新坐标稍微复杂一些,需要通过矢量计算获得玩家移动后的新位置,步骤如下:

    1. 使用矢量减法,将目标位置(targetPos)减去当前位置(currPos)即可计算出位于两个位置之间的新矢量
    2. 使用 normalize() 方法将方向矢量变为模为 1 的单位化矢量
    3. 然后用单位化矢量乘以玩家的速度,就能得到玩家每次分别在 x, y 方向上移动的长度
    4. 将目标当前位置的坐标与移动的坐标相加,得到新位置的坐标,并做修改

    3)主程序

    玩家移动是一个不断更新位置的循环过程,每次检测玩家是否靠近目标点附近,如果还没有到达,则不断地更新位置,并打印出玩家的当前位置,直到玩家到达终点

    if __name__ == '__main__':
        p = Player()
        p.current_vector = Vector(0, 0)
        p.target_vector = Vector(2, 2)
        p.speed = 0.2
    
        while not p.is_arrived():
            p.update_vector()
            print(f"({p.current_vector.x}, {p.current_vector.y})")
            time.sleep(1)
    
        print("arrive at the destination")
    1. 将 Player 实例化,设定玩家终点坐标,当前坐标
    2. 更新玩家位置
    3. 每次移动后,打印玩家的位置坐标
    4. 延时 1 秒(便于观察效果)

     

    ending~

    每天都要遇到更好的自己.
  • 相关阅读:
    软件设计师 -算法设计与分析
    windows下git使用
    SourceTree免注册并连码云
    软件设计师-软件工程基础知识
    基本约瑟夫环问题详解
    SGU180(树状数组,逆序对,离散)
    POJ(1195)(单点修改,区间查询)(二维)
    C++ bitset
    冯志远0920
    怎样学好哲学(lucas+费马小定理)
  • 原文地址:https://www.cnblogs.com/kaichenkai/p/10976692.html
Copyright © 2020-2023  润新知