• 3D 服务器端以向量计算为主的角色位置的算法


    把我以前学习过的一个东西拿出来分享下~

    3D服务器端玩家行走处理是服务器端根据客户端行走路径、玩家行走时间以及速度(包括变化速度)计算得出玩家的当前位置。

    由于客户端行走是一条路径,不使用2D中的格子计算算法,未能高效的获取角色的当前位置,运用玩家行走路径,行走速度,行走时间这些已量,进行计算玩家的当前精确位置。由于3D游戏中的点为xyz的空间点,所以牵连的计算为3维向量计算。

    空间两点距离计算公式为:

    玩家在某条线段上的坐标x:

    玩家在某条线段上的坐标y:

    玩家在某条线段上的坐标z:

    角色当前位置计算原理分析:

    角色行走是一条路径,这条路径使用点序列表示,角色开始行走记录当前时间TimeStart,获取觉得当前位置的计算,首先获取当前时间TimeNow,根据TimeNow-TimeStart的时间差与角色的行走速度,获取角色已经行走过的距离distance,计算每两点的距离,判定角色当前时间所处在哪一条路径上,及角色在哪两点之间。然后使用向量计算公式计算当前角色处于的坐标点位置。

    角色位置位置计算的类封装实现代码:

      1 #pragma once
      2 
      3 class CCoordinatePath
      4 {
      5 public:
      6     CCoordinatePath(void);
      7     ~CCoordinatePath(void);
      8 
      9 public:
     10     // 更新行走路径
     11     void UpdatePath(COORDINATE_3D stopCoordinate3D);
     12     void UpdatePath(vector<COORDINATE_3DPATH> vtPath, COORDINATE_3D stopCoordinate3D, float nCompletePath = 0);
     13     // 开始行走(移动计算)
     14     void StartMove(DWORD dwStartTime);
     15     // 获取当前空间位置
     16     COORDINATE_3D GetCoordinate(DWORD dwNowTime);
     17     // 获取行走路径
     18     const vector<COORDINATE_3DPATH>* GetPath();
     19     // 获取停止位置
     20     COORDINATE_3D GetStopCoordinate();
     21     // 获取移动总距离(从开始行走到现在的行走总距离)
     22     float GetCompletePath(DWORD dwNowTime);
     23     // 更新玩家速度
     24     void UpdateSpeed(unsigned short wSpeed, DWORD dwNowTime);
     25     // 获取当前速度
     26     unsigned short GetSpeed();
     27     // 玩家是否正在移动
     28     bool IsMoving(DWORD dwNowTime);
     29 
     30 private:
     31     // 行走路径
     32     vector<COORDINATE_3DPATH> m_vtPath;
     33     // 停止点
     34     COORDINATE_3D m_stopCoordinate3D;
     35 
     36     // 已完成路径
     37     float m_nCompletePath;
     38     // 玩家当前速度
     39     unsigned short m_wCurSpeed;
     40     // 行走路径开始时间
     41     DWORD m_dwStartMoveTime;
     42     
     43 };
     44  
     45 #include "StdAfx.h"
     46 #include "CoordinatePath.h"
     47 
     48 CCoordinatePath::CCoordinatePath(void)
     49 {
     50     m_wCurSpeed = 4;
     51 }
     52 
     53 CCoordinatePath::~CCoordinatePath(void)
     54 {
     55 }
     56 
     57 void CCoordinatePath::UpdatePath( COORDINATE_3D stopCoordinate3D )
     58 {
     59     m_vtPath.clear();
     60     m_stopCoordinate3D = stopCoordinate3D;
     61     m_nCompletePath = 0;
     62 }
     63 
     64 void CCoordinatePath::UpdatePath( vector<COORDINATE_3DPATH> vtPath, COORDINATE_3D stopCoordinate3D, float nCompletePath /*= 0*/ )
     65 {
     66     m_vtPath = vtPath;
     67     m_stopCoordinate3D = stopCoordinate3D;
     68     m_nCompletePath = nCompletePath;
     69 }
     70 
     71 void CCoordinatePath::StartMove( DWORD dwStartTime )
     72 {
     73     m_dwStartMoveTime = dwStartTime;
     74 }
     75 
     76 COORDINATE_3D CCoordinatePath::GetCoordinate(DWORD dwNowTime)
     77 {
     78     if (m_vtPath.size() == 0)
     79     {
     80         return m_stopCoordinate3D;
     81     }
     82 
     83     float nTotalDistance = GetCompletePath(dwNowTime);
     84 
     85     if (nTotalDistance < 0)
     86     {
     87         cout << "计算玩家移动距离错误" << endl;
     88         return m_stopCoordinate3D;
     89     }
     90 
     91     // ceshi
     92     //cout << "距离:" << nTotalDistance << "时间" << (dwNowTime-m_dwStartMoveTime) << endl;
     93 
     94     COORDINATE_3D coordinate3D;
     95 
     96     // 上面已经计算出玩家行走总距离,计算玩家位置
     97     vector<COORDINATE_3DPATH>::iterator itPath = m_vtPath.begin();
     98     for (; itPath!=m_vtPath.end(); ++itPath)
     99     {
    100         if (itPath->allDistance > nTotalDistance)
    101         {
    102             // 角色当前位置在当前path中,计算当前位置
    103             float nCurDistance = nTotalDistance - (itPath->allDistance - itPath->curDistance);
    104 
    105             if (nCurDistance < 0)
    106             {
    107                 cout << "[严重错误]获取坐标" << endl;
    108                 return m_stopCoordinate3D;
    109             }
    110 
    111             coordinate3D.x = itPath->x + itPath->dFormula*itPath->xDistance*nCurDistance;
    112             coordinate3D.y = itPath->y + itPath->dFormula*itPath->yDistance*nCurDistance;
    113             coordinate3D.z = itPath->z + itPath->dFormula*itPath->zDistance*nCurDistance;
    114             coordinate3D.dir = itPath->dir;
    115 
    116             if (coordinate3D.x ==1 && coordinate3D.y==1 && coordinate3D.z == 1)
    117             {
    118                 int i = 0;
    119             }
    120             ///yang
    121             //cout << "当前移动坐标:x:" << coordinate3D.x << ",y:" << coordinate3D.y << ",z:" << coordinate3D.z << endl;
    122             ///yang
    123             return coordinate3D;
    124         }
    125     }
    126 
    127     // 到达目标点做先前点路径的清理工作
    128     m_vtPath.clear();
    129 
    130     return m_stopCoordinate3D;
    131 }
    132 
    133 const vector<COORDINATE_3DPATH>* CCoordinatePath::GetPath()
    134 {
    135     return &m_vtPath;
    136 }
    137 
    138 COORDINATE_3D CCoordinatePath::GetStopCoordinate()
    139 {
    140     return m_stopCoordinate3D;
    141 }
    142 
    143 float CCoordinatePath::GetCompletePath( DWORD dwNowTime )
    144 {
    145     // 无变速的移动距离计算
    146     DWORD dwMoveTime = dwNowTime-m_dwStartMoveTime;
    147 
    148     return (m_nCompletePath + m_wCurSpeed*dwMoveTime/1000.0f);
    149 }
    150 
    151 void CCoordinatePath::UpdateSpeed( unsigned short wSpeed, DWORD dwNowTime )
    152 {
    153     // 计算已经完成路径
    154     m_nCompletePath += GetCompletePath(dwNowTime);
    155     m_dwStartMoveTime = dwNowTime;
    156 
    157     m_wCurSpeed = wSpeed;    //当前速度
    158 }
    159 
    160 unsigned short CCoordinatePath::GetSpeed()
    161 {
    162     return m_wCurSpeed;
    163 }
    164 
    165 bool CCoordinatePath::IsMoving( DWORD dwNowTime )
    166 {
    167     GetCoordinate(dwNowTime);
    168 
    169     if (m_vtPath.size() > 0)
    170     {
    171         return true;
    172     }
    173     else
    174     {
    175         return false;
    176     }
    177 }
  • 相关阅读:
    IBM X3650 M4服务器安装centos找不到硬盘的解决方法
    页面头部title、description、keywords标签的优化
    SEO优化之Title 和 Meta 标签
    WPA字典锦集
    PIN码计算锦集
    神经网络入门 第6章 识别手写字体
    神经网络入门 第5章 实现多层神经网络BP算法
    神经网络入门 第4章 神经网络可以模拟任意函数
    神经网络入门 第3章 S函数
    神经网络入门 第2章 编写第一个神经元
  • 原文地址:https://www.cnblogs.com/Mushrooms/p/3141819.html
Copyright © 2020-2023  润新知