从零开始重写KOK1(万王之王1) —— (3)优化玩家移动与精确8方向朝向

原创 2011年01月20日 18:56:00

0. 回顾与分析

在第1篇文章中,我们是对移动目标与玩家坐标做差,然后按照各个方向的可能性进行if判断,来决定人物的方向,在第一篇的DEMO中,可以发现,只有当人物正好在正斜方(45度的4个斜方向,或者说是n*pi/4时),人物才会斜着站,否则都是上下左右4个方向的朝向。

 

对人物的移动方面,我们是x没达到目标则加上RunSpeed,y也如此。这样的结果是,人物斜着走将会非常快。

 

所以我们优化代码以达到两个目的:

(1)人物的朝向是将一个圆分成16份,每个方向占两份,使人物朝向正确的角度。

(2)人物的RunSpeed应当对应向量,让玩家在朝任意方向走时,移动速度是一致的。

 

首先是截图和下载地址,这个和上篇文章是相同的:

移动和方向优化

 

直接可运行版本下载:>>点击进入下载页<<

 

1. 优化玩家朝向

首先画个图,来想象一下,什么情况应该朝哪个方向:

方向示意

每个颜色代表一个方向,玩家在相同颜色的区域内应该朝向相应的方向。在这个图中轴x的正方向是0,从正方向延逆时针旋转到x轴的负方向的弧度为pi,从x轴的正方向延顺时针旋转到x轴的负方向的弧度为-pi。但要注意到,在游戏中,y轴的正方向是向下的,将y轴方向颠倒,把弧度注释在图上即如下图:

计算机方向

好了,那么如何在已知玩家当前坐标与目的坐标的情况下,求得玩家应该朝向哪呢?

 

我们首先要将我玩家至于上图直角坐标系的(0,0)坐标处,根据几何平移变换,假设玩家坐标为sx,sy,目的坐标为tx,ty,那么当玩家平移至(0,0)处时,目的坐标则为(tx-sx, ty-sy),我们简写为(dx, dy),如图:

目的点变换

我们把原点与目的点连上,则形成了一个直角三角形。这时应该可以恍然大悟了,我们现在已知dy和dx,即已知tan的值。那么我们就可以根据某个目标点求tan,根据其值来了解他们落在上面哪个颜色之中。

 

在高中,我们还需要查表才知道某个角度的tan,现在我们有calc(计算器),则可以直接求出上面这些关键角度的tan值,如下:

tan 0 = 0

tan pi/8 = 0.4142

tan pi/4 = 1

tan 3pi/8 = 2.4142

tan pi/2 = 无穷

tan 5pi/8 = -2.4142

tan 3pi/4 = -1

tan 7pi/8 = -0.4142

tan pi = 0

并且根据sin(a) = -sin(-a)和cos(a) = cos(-a)和tan(a) = sin(a) / cos(a),我们得知tan(a) = -tan(-a)。

所以在上面的表的相对的负弧度的值取相反数即可。

 

通过分析上面的值,可以发现一个有意思的事——同一个tan值对应两个角度。这两个角度关于原点对称。这虽然使问题稍微麻烦了点,但也不难解决,只需要在求得tan之后,再比较dx是大于0还是小于0,就可以最终确定方向了。

 

总结一些这些值,我们将它们按域划分,如图:

方向值划分

因此,方向计算完成,c++实现代码如下:

 

2. 优化移动速度

因为玩家的移动能力是一定的,为RunSpeed,那么反应在刚才的坐标变换图中可以画出在任意方向下的移动能力就是个圆,如下图:

移动范围

由此可知该圆的半径为RunSpeed,我们要求出图上的x和y,这个x和y就是玩家在本帧应当移动的距离,而不是第一篇文章我们写死的RunSpeed本身。求x和y的问题也可以转换成一个三角形问题,如下图:

移动偏移

转换成几何问题的说法就是:已知OC、CD、OB,求OA、AB。

我们可以使用毕达哥拉斯定理求出OD。

然后根据某定理(实在忘了名称了),可知OA:OC = OB:OD = AB:CD,可以求出OA和AB。

c++代码如下:

 

到此对玩家移动和方向的优化就完成了。

 

项目代码下载地址:>>点击进入下载页<<

Caffe使用——01 简言

Caffe 作为一个老牌的最早在工业上应用并效率较好的深度学习框架,在使用时可以非常简单。Caffe提供了命令行接口、C++接口、python接口等。可以在几乎不编写任何代码的情况下,完成数据转换、神...
  • sdlypyzq
  • sdlypyzq
  • 2018年01月15日 15:00
  • 39

从零开始重写KOK1(万王之王1) —— (4)遮挡、阻挡与寻路

0. 上篇文章,人物已经可以正确的朝向和移动了,这次我们要添加几个石头,并且达到以下效果1) 人物和石头根据站位可以正确产生遮挡效果2) 人物被石头阻挡住,即不能穿过石头3) 当鼠标点击石头后面时,人...
  • cppyin
  • cppyin
  • 2011年02月01日 14:25
  • 7025

从零开始重写KOK1(万王之王1) —— (1)让人物可在地图上使用鼠标跑动

从飞信裸辞已经2个月了,因为对游戏的爱,和做出好玩的游戏这个梦想。《Windows游戏编程大师技巧》(以下简称《大师》)这书已经读完,DEMO也都搞清楚了,为了确实的掌握2D游戏的技术,决定完成一个完...
  • cppyin
  • cppyin
  • 2011年01月11日 11:49
  • 6850

从零开始重写KOK1(万王之王1) —— (2)优化地图加载

本来想在第2篇说明物体遮挡与寻路的开发过程,但是因为我把这问题想简单了,现在已经完成了遮挡与寻路,但是中间的过程非常多,第一篇文章的系统结构需要做一些修改才可以,这里先说一下地图加载的相关问题。首先是...
  • cppyin
  • cppyin
  • 2011年01月20日 14:48
  • 6664

【Unity学习笔记】NPC朝向玩家的代码实现

using System.Collections; using System.Collections.Generic; using UnityEngine; public class LookAt :...
  • bouquet12138
  • bouquet12138
  • 2017年02月14日 20:27
  • 426

Unity教程之-让物体朝摄像机Camera观察方向移动(一)

http://www.unity.5helpyou.com/3206.html
  • u012322480
  • u012322480
  • 2016年03月15日 17:08
  • 1514

7-2 列车厢调度(25 point(s))(栈的经典题目)

7-2 列车厢调度(25 point(s)) 1 ====== 移动方向 大家或许在某些数据结构教材上见到过“列车厢调度问题”(当然没见过也不要紧)。今天,我们...
  • codeswarrior
  • codeswarrior
  • 2017年11月10日 21:39
  • 195

Unity 获取物体朝向一个目标点时的旋转值

在Unity中,要使得物体朝向一个目标向量可以直接用transform.LookAt()实现。  那么有没有什么办法可以在不使用 transform.LookAt() 的前提下,直接计算出物体在调用...
  • yyq9111
  • yyq9111
  • 2016年11月08日 14:33
  • 5450

5-2 列车厢调度 (25分)

5-2 列车厢调度 (25分) 1 ====== 移动方向 大家或许在某些数据结构教材上见到过“列车厢调度问题”(当然没见过也不要紧)。今天,我们就来实际操作一下列车厢的...
  • chan_yeol
  • chan_yeol
  • 2016年03月27日 11:24
  • 1305

Unity 移动设备面朝方向

Input.deviceOrientation : (例子:if (Input.deviceOrientation == DeviceOrientation.FaceDown)) Unkno...
  • he_wen_jian
  • he_wen_jian
  • 2014年04月24日 17:52
  • 2761
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:从零开始重写KOK1(万王之王1) —— (3)优化玩家移动与精确8方向朝向
举报原因:
原因补充:

(最多只允许输入30个字)