AS3-45度角坐标转换

(2012-01-31 09:52:06)

guan(我)的理解:


关于45度角地图中像素坐标和地图坐标之间的转换,网上有各种方法,其实坐标转换就是计算tite宽和tile高在像素坐标中的偏移值,本方法是针对 tite块原点坐标在菱形的顶点的位置的坐标转换,在45度角地图中,方块形状为菱形,你可以用flash cs工具或其他绘图工具很快的创建出这种菱形方块,按以下3个步骤就可以了:
1、 绘制一个任意大小的正方形;
2、 把这个正方形旋转45度;
3、 把旋转的正方形的高度缩放为原来的50%。
还有一点就是方块尺寸的问题,菱形方块的宽度是高度的2倍,其次方块尺寸比例应该是2:1。例如64像素X 32像素或100像素 X 50像素等,这样的尺寸刚好能使方块在地图铺设的时候很好地排列在屏幕上。
至于坐标间的转换其实大家看图就好理解了:

图中是一个以红色(0,0)位置为原点,红点每向地图坐标系M轴上移动一个单位,原点相对像素坐标系X中的偏移值为:方块宽度/2
菱形方块宽 var tileW :Number;
菱形方块高 var tileH :Number;
地图的行数 var row :int;
地图的列数 var col :int;
红色原点坐标(像素坐标系) var originP : Point;
那么红色的原点坐标在地图坐标系中的位置为:
originP.x = row * tileW /2;
originP.y = 0;
原点坐标出来了,那么其它点的坐标呢?
思路是先求出在地图坐标系下(M方向或N方向)每移动一个单位的像素坐标系X轴和像素坐标系Y轴的像素偏移值。
如红色原点移动到黑色点的位置:
M在像素坐标系X轴的偏移像素 = tileW /2;(向右偏移)
M在像素坐标系Y轴的偏移像素 = tileH /2; (向下偏移)
N在像素坐标系X轴的偏移像素 = - tileW /2;(向左偏移)
N在像素坐标系Y轴的偏移像素 = tileH /2; (向下偏移)
假如有个地图坐标点(M,N),那么它对应的像素坐标系的点为var p:Point
p.x = 原点坐标X + M在像素坐标系X轴的偏移像素 × M + N在像素坐标系X轴的偏移像素 × N = originP.x + tileW /2 × M + (-tileW/2) × N = originP.x + (M – N) × tileW/2;
p.y = 原点坐标Y + M在像素坐标系Y轴的偏移像素 × M + N在像素坐标系Y轴的偏移像素 × N = originP.y + tileH/2 × M + tileH/2 × N = originP.y + (M + N) × tileH/2;

-------------------------------------------------------------------------------------------
  最早的有很多的2D游戏,地图看起来就像是俯视图一样,地图整体形状是个矩形的,地图的每一格也是个矩形,很多早期的RPG游戏就是这样。这样的地图实现 起来很方便,地图的信息一般就存储在一个二维数组中,描画、定位也很方便。不过这样的缺点就是不太逼真,所以在3D技术出现之前(或者是因为出于效率的原 因只能使用2D的情况下)有人想出了用2D的方式来模拟视觉上3D的效果,就是使用斜角地图块拼出的地图,这个斜角地图块的形状一般都是一个菱形,拼出后 整块的地图也是个菱形,如下图:

然后地图上有放置物体,比如建筑啊,自然物体,人物走动啊之类的,不少的游戏就是使用的这样的方式,比如:帝国时代;

其实对于这样的斜角地图,地图网格数据依然是存储在一个二维数组之中的。仔细看这个地图其实就相当于把一块正放的图以左上角为圆星逆时针旋转了45度而已 (这只是一种理解方式,也可以认为是以左上角为圆心顺时针转了45度,区别在于写转换屏幕坐标和网格坐标的转换模块时不同)只不过描画时按照特定的方式来 描画,也就是给出地图的某一块格子,要知道这块画在屏幕上的坐标;反过来得到屏幕上的一个坐标点,如果这个坐标点正好位于地图之中,要知道这个点对应的是 二维数组中的哪块。解决了这个屏幕坐标到地图网格之间的映射关系的问题,实现一个2.5D斜角地图就变得相当容易了,噢,还有就是美工上的要求就是把原本 四方的地图单元格画成中间一个菱形其余部分为透明的四方的地图单元格^_^

由于之前写的flash游戏里有遇到这方面的问题,所以特别花了点时间想了下,大多数情况下这种2.5D斜角地图应该都是菱形的,虽然不是菱形理论上也可以做到,但我写的这个转换类的还是基于菱形的,语言用的是AS3,代码如下:

public class SquintAngleTranslator
{
   private var m_mapWid:int = 0;
   private var m_mapHei:int = 0;
  
   private var m_orgX:Number = 0;
   private var m_orgY:Number = 0;
  
   private var m_xincX:Number = 0;
   private var m_xincY:Number = 0;
   private var m_yincX:Number = 0;
   private var m_yincY:Number = 0;
  
  
   //初始化,设置地图网格横向纵向的数量及显示时大地图的范围
   public function InitlalRhombusMap( mapWid:int, mapHei:int, mapRange:Rectangle ):void
   {
    m_mapWid = mapWid;
    m_mapHei = mapHei;
   
    var count:Number = mapWid + mapHei;
   
    m_orgX = mapRange.left + mapRange.width / count;
    m_orgY = mapRange.top + mapWid * mapRange.height / count;
   
    m_xincX = mapRange.width / count;
    m_xincY = - mapRange.height / count;
    m_yincX = mapRange.width / count;
    m_yincY = mapRange.height / count;
   
   }
  
   //重设地图原点位置的偏移(用于地图滑动)
   public function SetOrgin( xpos:Number, ypos:Number ):void
   {
    m_orgX = xpos;
    m_orgY = ypos;
   }
  
   //地图网格坐标转换到屏幕显示坐标(用于提供给描画用)
   public function GridToView( xpos:int, ypos:int ):Point
   {
    var pos:Point = new Point();
   
    pos.x = m_orgX + m_xincX * xpos + m_yincX * ypos;
    pos.y = m_orgY + m_xincY * xpos + m_yincY * ypos;
   
    return pos;
   }
  
   //屏幕坐标转换到地图网格坐标(比如在即时战略中用于确定鼠标点击的是哪一块)
   public function ViewToGrid( xpos:Number, ypos:Number ):Point
   {
    var pos:Point = new Point();
   
    var coordX:Number = xpos - m_orgX;
    var coordY:Number = ypos - m_orgY;
   
    pos.x = ( coordX * m_yincY - coordY * m_yincX ) / ( m_xincX * m_yincY - m_xincY * m_yincX );
    pos.y = ( coordX - m_xincX * pos.x ) / m_yincX;
  
    pos.x = Math.round( pos.x );
    pos.y = Math.round( pos.y );
   
    return pos;
   }
  
   //判断网格坐标是否在地图范围内
   public function LegalGridCoord( xpos:int, ypos:int ):Boolean
   {
    if ( xpos < 0 || ypos < 0 || xpos >= m_mapWid || ypos >= m_mapHei )
    {
     return false;
    }
   
    return true;
   }
  
   //判断屏幕坐标是否在地图范围内
   public function LegalViewCoord( xpos:Number, ypos:Number ):Boolean
   {
    var pos:Point = ViewToGrid( xpos, ypos );
   
    return LegalGridCoord( pos.x, pos.y );
   }
  
   //格式化屏幕坐标,即返回最接近该坐标的一个格子的标准屏幕坐标(通常用于在地图中拖动建筑物对齐网格用)
   public function FormatViewPos( xpos:Number, ypos:Number ):Point
   {
    var pos:Point = ViewToGrid( xpos, ypos );
   
    if ( LegalGridCoord( pos.x, pos.y ) )
    {
     pos = GridToView( pos.x, pos.y );
    }else
    {
     pos.x = xpos;
     pos.y = ypos;
    }
   
    return pos;
   }
  
}

AS3-45度角坐标转换相关推荐

  1. allegro 16.6或者17.0把45度线转换成圆弧

    allegro 高速线绕等长时,把45度角转换成圆弧,先走成下图中下边45度线的形式,然后点菜单栏Route->Unsurpported Prototypes->Auto-interact ...

  2. 什么是倾斜45度的火山图?

    今天是转录组培训最后一天,剩下一点时间自由探索.朋友们来自山南海北,还是北京的最多. 一位老师聊起火山图(Volcano plot | 别再问我这为什么是火山图 (在线轻松绘制)),说见过倾斜45度的 ...

  3. Java中2.5D游戏(斜45度角)的设计与实现(1)

    通常的概念中,2D也就是所谓的二维,也就是平面图形--即由X与Y坐标构成的图形,其内容由水平的X轴向与垂直的Y轴描绘确定,也就是由长和高的形成所谓的二维平面. 而所谓3D,也称之为三维.其图形内容除了 ...

  4. 如何用通达信编写均线斜率大于45度的公式

    今天介绍两个与角度.斜率相关的通达信函数ATAN.SLOPE,并探讨编写均线斜率大于45度的通达信指标公式.这里说的均线斜率,实际上是均线的角度. 一.ATAN函数 含义:求反正切值 使用方法:ATA ...

  5. COCOS2D-X中45度地图通过位置获得对应行列数中的三角变换理解

    晚上看COCOS2d-X的瓦片地图集这块,发现有2种地图,普通的和45度视角的.普通的通过位置获取所在行列数比较简单,大概就是具体的位置除以图素的宽高,而45度脚的方法则能够实现2.5D的效果,理解起 ...

  6. 编写简易斜45度地图编辑器

    最近在研究cocos2dx的地图,最开始使用的是Tiled,这个编辑器做比较小的地图还是比较强大的,不过做大地图的时候,有一些功能不太方便并且有缺陷(包括刷图繁琐以及坐标体系过于复杂,导致寻路比较看起 ...

  7. 45度斜角地图菱形坐标转换

    !!! 此文章内容为转载,没有真实实践,只给需要的朋友提供思路,具体详细算法需要自己根据项目需求变动 !!! 我们要做一个45度游戏地图中,那么如何判断鼠标点中了哪一个碎片呢??如图:   也许你想到 ...

  8. 让Tiled成为一个强有力的45度菱形Staggered打点器(地图编辑器)

    让Tiled成为一个强有力的45度菱形Staggered打点器(地图编辑器) 分类: cocos2dx2013-08-05 23:09 1601人阅读 评论(1) 收藏 举报 Tiled的确强大,处理 ...

  9. 改进的负载线移相器设计与仿真(适用于45度以内移相)

    根据文档资料可知,改进型的负载线移相器比普通的负载线移相器有如下有点:插损低, 回损好,但占用空间会较大. 普通的负载线移相器是直接在微带线上加电感或电容去进行移相 , 而改进型负载线移相器则是在90 ...

最新文章

  1. 响应式编程入门:实现电梯调度模拟器
  2. VC++使用Soap ToolKit3.0调用WebService接口
  3. linux 用户态 spinlock,spinlock作用
  4. 快速排序以及基于快排思想的找前k个最大数
  5. 欢迎您参加_ADT技术培训营
  6. socket与文件描述符
  7. php 字符串比较的规则,PHP字符串比较函数strcmp()与strcasecmp()的用法介绍
  8. 【Swin Transformer】W-MSA与MSA时间复杂度的理解
  9. 好用的Typecho系统后台模板
  10. 输出滑动窗口最大值(双端队列)
  11. 树莓派4B使用移远EC20带GPS 4G模块ppp拨号上网
  12. MFC之学习绘制矩形、画刷使用
  13. 图像知识 太经典 膜拜
  14. mysql数据库学习(基础篇)
  15. 彻底搞懂CSS层叠上下文、层叠等级、层叠顺序、z-index
  16. WPS word文档插入图片显示不全
  17. 山药搭配什么吃最有营养?
  18. Android 免费短信验证码--Mob.com
  19. 虚拟机桥接模式无法联网
  20. MySQL中间件Atlas

热门文章

  1. 什么是生产历史追溯系统
  2. Android 天气APP(三十二)快捷切换常用城市
  3. 全球及中国知识付费行业商业模式与发展盈利分析报告2022版
  4. 全网最全的BigDecimal的newScale(保留小数位)和roundingMode(舍入模式),详细介绍roundingMode(重点)
  5. 益圆木门 | 门墙同色,营造高级艺术范儿!
  6. Wikibon:英伟达如何通过人工智能抢夺数据中心市场?
  7. NC、NC57、NC65、NCC、U8C移动审批
  8. 一篇文章让你入门【MySQL】
  9. 商用密码算法知识点总结
  10. 一台计算机可作为另一台主机,电脑能给另一台电脑装系统吗