游戏开发论坛

 找回密码
 立即注册
搜索
查看: 9243|回复: 1

游戏编程实用技能:2D游戏中坐标转换

[复制链接]

1万

主题

1万

帖子

3万

积分

论坛元老

Rank: 8Rank: 8

积分
36572
发表于 2016-3-21 10:45:14 | 显示全部楼层 |阅读模式
QQ截图20160321103747.png

  GameRes游资网授权发布 文/肥宝传说之路

  游戏里面经常用到坐标转换,例如地图、战斗技能等。

  一、直角坐标和极坐标的转换

  前提条件:

  1、两坐标系原点重合

  2、两坐标系x轴正半轴重合

  3、两坐标系单位长度相同

  变量关系:

20160310222701307.jpg

  如上图,M的直角坐标为(x,y),极坐标(ρ,Θ)。

  由图中关系可以得出

  ρ^2 = x^2 + y^2 (勾股定理)

  tanΘ = y/x

  x = ρ*cosΘ

  y = ρ*sinΘ

  其他象限的就不证明了,这里不是讲数学的。知道是一样就行了。

  代码如下:

  1. #include <math>  
  2. //把直角坐标转换成极坐标  
  3. void changeXYToPolarCoordinate(int x, int y, int& r, int& angle)  
  4. {  
  5.     if (x == 0)  
  6.     {  
  7.         r = abs( y);//x轴为0,r等于y的绝对值  
  8.         if ( y < 0)//y小于0是270°  
  9.         {  
  10.             angle = 270;  
  11.         }  
  12.         else if ( y > 0)//y大于0是90°  
  13.         {  
  14.             angle = 90;  
  15.         }  
  16.         else//原点  
  17.         {  
  18.             angle = 0;  
  19.         }  
  20.     }  
  21.     else  
  22.     {  
  23.         r = sqrt( x* x + y* y);  //与原点的距离  
  24.         angle = asin( y / r);<span style="white-space:pre">   </span>//反正弦函数  
  25.     }  
  26.       
  27. }  
  28. //把极坐标转换成直角坐标  
  29. void changePolarCoordinateToXY(int& r, int& angle, int& x, int& y)  
  30. {  
  31.      x = r * cos(angle);  
  32.      y = r * sin(angle);  
  33. }  
复制代码

  二、绝对坐标和相对坐标的转换

20160311123458339.jpg

  如图中坐标系O和坐标系A,原点分别是O(0,0),A(xa,ya).这个相对坐标系A的x轴和y轴是跟坐标系O的x轴和y轴分别平行的。

  对于B(xb,yb)的相对坐标是(xb-xa,yb-ya)</p><p>就这么简单。

  但是,如果A的坐标轴跟O的不平行呢?看下图

  说一下运用的背景,例如怪物A身上有个喷火技能,释放技能的时候,喷出一条火线,在火线上的的玩家都会受到伤害。犹豫在计算机上,直线的范围太小。如果我们只用直线来计算。很可能站在附近便宜一个像素的角色B就逃过的攻击。可以说,这种技能基本上攻击不了其他角色,除了特意攻击的那个。

  下图中O为原点。怪物A,角色B/C/D三个,ABCD的绝对坐标都是知道的。怪物A锁定B,向B喷火。(图画得有点不好,大家不要介意)。以喷火路线为相对坐标系的x轴。火线长为L,宽为W。一般来说,B是必然中招的(这都不中招就是有bug了)。相对坐标的x轴,就是向量AB的方向。Y轴垂直于向量AB

  这个时候要判断C和D是否也被击中了。

20160311123647135.jpg

  我们先看C的相对坐标。AC是点的距离,再求角CAB就可以得到极坐标,然后用极坐标转换成直角坐标就可以了,

  根据余弦定理  BC^2 = AC^2 + AB^2 - 2*AB*BC*cos(角CAB)。

  所以cos(角CAB) =  (AC^2 + AB^2 - BC^2)/ 2*AB*BC

  然后根据上面一提到的极坐标和直角坐标的转换。得出相对坐标xr = AC * cos(角CAB); yr ^2 = AC ^2 + yr ^ 2  ;

  (xr,yr)就是相对坐标了。记得BC等于零的时候是不行的。(都重合了还需要计算么?)

  再看看实现代码吧:

  1. </pre><pre code_snippet_id="1605923" snippet_file_name="blog_20160311_2_6232871" name="code" class="cpp">class CPoint  
  2. {  
  3. public:  
  4.     double x;  
  5.     double y;  
  6. }  
  7. double computeDistance(CPoint from, CPoint to)  
  8. {  
  9.     return sqrt(pow(to.x - from.x, 2) + pow(to.y - from.y, 2));  
  10. }  
  11. CPoint Common::changeAbsolute2Relative(CPoint originPoint, CPoint directionPoint, CPoint changePoint)  
  12. {  
  13.     CPoint rePoint;  
  14.     if (originPoint == directionPoint)  
  15.     {  
  16.         rePoint.x = changePoint.x - originPoint.x;  
  17.         rePoint.y = changePoint.y - originPoint.y;  
  18.     }  
  19.     else  
  20.     {   
  21.         double a = computeDistance(changePoint, originPoint);  
  22.         double b = computeDistance(directionPoint, originPoint);  
  23.         double c = computeDistance(directionPoint, changePoint);  
  24.         double cosa = (b*b + c*c - a*a) / 2 * b*c;//余弦定理  
  25.         rePoint.x = a * cosa ;  
  26.         rePoint.y = sqrt(a*a - rePoint.x*rePoint.x);  
  27.     }  
  28.     return rePoint;  
  29. }  
复制代码

  相关阅读开放世界游戏中的大地图的实现——程序技术篇

1

主题

2

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2016-3-23 13:46:56 | 显示全部楼层
大神的 帖子都是干货啊~~   今天才看见。。。 全部收藏去。。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-25 09:13

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表