ActionScript3构建基本菱形网格地图

文介绍使用Flash ActionScript3构建由菱形网格组成的2.5D游戏地图。

 

实现的基本需求有以下几点:
1、        绘制宽高比2:1的菱形
2、        由菱形平铺10*10的区域组成地图
3、        不同的地图数据点变更颜色以区分,表示阻挡区块等
4、        通过鼠标位置x、y计算鼠标位置所属菱形,以高亮表示

为什么要选择菱形?
菱形具有四边相等,和对角线互相垂直的特点。拼接的时候不再需要其他变形操作,也方便美术资源按照区块形状剪裁或绘制。另外请参考等距视图相关知识。

为什么要宽高比是2:1?
1)        顶角角度接近于360度的1/3,即接近3D坐标系
2)        整数比在资源绘制和拼接时不易出现裂缝等问题
3)        大多数的绘图计算等对2的n次方进行过优化,对性能有一定提升,所以在2:1的基础上还要尽量选择2的n次方的长度值,比如64:32,32:16等。

类及功能说明:
MapProject.as   主类,仅用于显示map于此
map/Map.as   地图绘制类,有drawMap()等方法
map/Tile.as   网格类,用于绘制菱形网格
map/MapUtils.as   地图工具类,可以由坐标值获取坐标位置网格,或通过网格获取坐标

Tile.as类
绘制网格的函数:
  1. private function draw():void
  2.                 {
  3.                         _graphic.graphics.clear();
  4.                         _graphic.graphics.lineStyle(1);
  5.                         _graphic.graphics.beginFill(_fillColor);
  6.                         _graphic.graphics.moveTo(0, 0);
  7.                         _graphic.graphics.lineTo(_width/2, -_height/2);
  8.                         _graphic.graphics.lineTo(_width, 0);
  9.                         _graphic.graphics.lineTo(_width/2, _height/2);
  10.                         _graphic.graphics.lineTo(0, 0);
  11.                         _graphic.graphics.endFill();
  12.                         this.addChild(_graphic);
  13.                 }
复制代码
其中的_fillColor可以通过public方法设置,表示网格填充颜色
  1. public function set fillColor(_para:uint):void
  2.                 {
  3.                         this._fillColor =_para;
  4.                 }
复制代码
这里仅需要注意,菱形的原点取的是菱形最左边的角的顶点,以方便后面MapUtil类坐标转化的计算。

Map.as类
首先有一个地图数据,0代表可通行区域,1代表不可通行区域(规则可自定)。
  1. private var _mapArr:Array = [[0,0,0,0,0,0,0,0,0,0],
  2.                         [0,0,0,0,0,0,0,0,0,0],
  3.                         [0,0,1,0,0,0,0,0,0,0],
  4.                         [0,0,0,0,0,0,0,0,0,0],
  5.                         [0,0,0,0,0,0,0,0,0,0],
  6.                         [0,0,0,0,0,0,0,0,1,0],
  7.                         [0,0,0,0,0,0,0,0,0,0],
  8.                         [0,0,0,0,0,1,0,0,0,0],
  9.                         [0,0,0,0,0,0,0,0,0,0],
  10.                         [0,0,0,0,0,0,0,0,0,0]];
复制代码
地图数据也可随机生成。
在构造函数中初始化了MapUtils类,用于地图中的坐标转化:
_mapUtil = new MapUtil();

Map类中最重要的是drawMap方法,用于绘制地图:
  1. public function drawMap():void
  2.                 {
  3.                         var cols:int;  //lie
  4.                         var rows:int; //hang
  5.                         _gridArr = [];
  6.                         var _ind:int = 0;
  7.                         
  8.                         for(var i:int = 0; i <_mapArr.length; i++){
  9.                                 var _rowsArr:Array = _mapArr[i];
  10.                                 _gridArr[i] = [];
  11.                                 for(var j:int = 0; j <_rowsArr.length;  j++){
  12.                                         var _tile:Tile = new Tile();
  13.                                         _tile.x = j * _tile.thisWidth/2 - i * _tile.thisWidth/2;
  14.                                         _tile.y = j * _tile.thisHeight/2 + i* _tile.thisHeight/2;
  15.                                         if(_mapArr[i][j] != 0){
  16.                                                 _tile.fillColor = 0xff0000;
  17.                                                 _tile.reDraw();
  18.                                         }
  19.                                         _gridArr[i][j] = _tile;
  20.                                         
  21.                                         //添加一个文本显示网格索引
  22.                                         var _t:TextField = this.getText(String(_ind));
  23.                                         _t.x = 26;
  24.                                         _t.y = -10;
  25.                                         _tile.addChild(_t);
  26.                                         
  27.                                         _ind++;                                        
  28.                                         _gridLayer.addChild(_tile);
  29.                                 }
  30.                         }
  31.                         this._mapUtil.tileArr = _gridArr;
  32.                 }
复制代码
drawMap()函数主要就是按照地图数据数组初始化每个网格,并排列网格,因为地图数据数组是2维数组,这里使用了嵌套for循环,下面两行代码用来布局网格:
  1. _tile.x = j * _tile.thisWidth/2 - i * _tile.thisWidth/2;
  2. _tile.y = j * _tile.thisHeight/2 + i* _tile.thisHeight/2;
复制代码
另外Map.as类中为地图层添加了MouseMove和MouseClick事件,用于检测鼠标经过或点击位置所属的网格。


MapUtils.as类
主要是用来做坐标转换使用,其中有一个set方法用于赋值网格数组,这个赋值在Map.as中绘制完地图会进行:
  1. public function set tileArr(_arr:Array):void
  2.                 {
  3.                         this._tileArr = _arr;        
  4.                 }
复制代码
根据Map中坐标值来获得所属区块是通过数学计算来获得的:
  1. public function getTileByPoint(_x:Number, _y:Number):Tile
  2.                 {
  3.                         var _tile:Tile = new Tile;
  4.                         var _xp:int = 0;
  5.                         var _yp:int = 0;
  6.                         
  7.                         _yp = Math.floor( (_x/(_tile.thisWidth/2) + _y/(_tile.thisHeight/2) ) /2   );
  8.                         _xp = Math.floor( _x/(_tile.thisWidth/2) - ( (_x/(_tile.thisWidth/2) + _y/(_tile.thisHeight/2) ) /2 )  );
  9.                         _xp = Math.abs(_xp);
  10.                         _yp = Math.abs(_yp);
  11.                                                 
  12.                         if(_tileArr[_xp] !=null  && _tileArr[_xp][_yp] != null){
  13.                                 return _tileArr[_xp][_yp];
  14.                         }
  15.                         return null;
  16.                 }
复制代码
注意_xp,_yp的计算方程:
  1. _yp = Math.floor( (_x/(_tile.thisWidth/2) + _y/(_tile.thisHeight/2) ) /2   );
  2. _xp = Math.floor( _x/(_tile.thisWidth/2) - ( (_x/(_tile.thisWidth/2) + _y/(_tile.thisHeight/2) ) /2 )  );
复制代码
这两个方程可以由Map类中平铺网格时的方程(可参考上文),逆推而来:
  1. _tile.x = j * _tile.thisWidth/2 - i * _tile.thisWidth/2;
  2. _tile.y = j * _tile.thisHeight/2 + i* _tile.thisHeight/2;
复制代码
(本文完)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值