2010-05-22 19 views
3

我想用as3创建一个honeycomb但我在定位单元时遇到了一些问题。用as3绘制一个蜂巢

我已经创建了单元格(不是代码),并且它们是for cycled,它们发送给funcion,并发送了我认为需要的参数(蜂窝单元已准备好放在舞台中心的精灵容器中)。

看到循环的结构和哪些参数传递,请参阅下面的例子中,在placeCell我计算的唯一事情是我应该直接获得内部THA称为function

alt text http://img293.imageshack.us/img293/1064/honeycomb.png

角度注意:角度是相反的,但并不重要,并且颜色在仅用于视觉划分案例的示例中是有用的。

我给循环调用placeCell并传递cellcurrent_casecounter(索引)和蜂窝cell_lv(细胞水平)。

我认为这是我需要的,但我不擅长几何和三角学,所以我不知道如何正确地定位细胞:

import flash.display.Sprite; 
stage.align = StageAlign.TOP_LEFT; 
stage.scaleMode = StageScaleMode.NO_SCALE; 

function createHoneycomb (cells:int):void { 

    var honeycomb:Sprite = new Sprite(); 
    addChild (honeycomb); 

    var cell_lv:int = 1; 
    var increment:int = 6; 
    var tot_cur_cells:int = 1; 

    var current_case:int = 0; 
    var case_counter:int = 1; 
    var case_length:int = 1; 
    var max_cases:int = 6; 

    var nucleus:Sprite = new cell(); // hexagon from library 
    honeycomb.addChild (nucleus); 

    for (var i:int = 1; i <= cells; i ++) { 

     if (case_counter < case_length) { 
      case_counter ++; 
     } else { 
      current_case ++; 
      if (current_case > max_cases) current_case = 1; 
      case_counter = 1; 
     } 

     if (i == tot_cur_cells) { // if i reach the current level 
      if (i > 1) cell_lv ++; 
      case_length = cell_lv; 
      tot_cur_cells += (increment * cell_lv); 
     } 

     var current_cell:Sprite = new cell(); // hexagon from library 
     honeycomb.addChild (current_cell); 

     placeCell (current_cell, case_counter, current_case, cell_lv); 

    } 
    function centerHoneycomb (e:Event):void { 
     honeycomb.x = stage.stageWidth/2 
     honeycomb.y = Math.round (stage.stageHeight/2); 
    } 

    stage.addEventListener (Event.RESIZE, centerHoneycomb) 
    stage.dispatchEvent (new Event (Event.RESIZE)); 
} 

function placeCell (cell:Sprite, counter:int, current_case:int, cell_lv:int):void { 
    var margin:int = 2; 

    // THIS IS MY PROBLEM 
    var start_degree:Number = (360/(cell_lv * 6)); 
    var angle:Number = (start_degree * ((current_case - 1) + counter) - start_degree); 
    var radius:Number = (cell.width + margin) * cell_lv; 

    cell.x = radius * Math.cos (angle); 
    cell.y = radius * Math.sin (angle); 
    // end of the problem 

    if (angle != 0) trace ("LV " + cell_lv + " current_case " + current_case + " counter " + counter + " angle " + angle + " radius " + radius); 
    else trace ("LV " + cell_lv + " current_case " + current_case + " counter " + counter + " angle " + angle + "  radius " + radius); 
} 

createHoneycomb (64); 

如果您复制并粘贴此代码,it works你需要创建一个六边形,并在动作库中调用它作为单元格

我该怎么做才能解决它?

我也想过用与案件开关对准它,但我认为这是一个有点马车这样

+0

地方细胞)的代码(也有趣的问题,并想帮助你... – Ladislav 2010-05-22 16:17:29

+0

“我已创建的细胞(不是代码)”。他创造了它作为库中的资产,可能使用多边形工具。 – poke 2010-05-22 16:40:43

回答

4

好吧,我真的很喜欢这个问题。这很有趣,也很有挑战性,我得到了一个工作成果。虽然我没有使用任何代码作为基础,但是从头开始,所以根据最终用途,您可能需要稍微修改一下。

但是,我确实创建了类似的变量与你的单元格内的相似变量(图中)。对于每个单元有以下特性:

  • 的迭代变量i同样你手机号码
  • 半径r等于你水平,并表示从该中心的距离(以0为中心)
  • 位置p表示当前半径的位置
  • 部门s等于你情况下,但与零
  • p % r等于你指数开始

我没有一个角度,只是因为我不各六角形定位使用一个角度。相反,我将六边形的(固定)位置的位置设为半径1,并计算其间的缺失位置。

下面的代码显示了我的实现61(60 +中心,但它是可配置的)。您也可以通过查看Wonderfl的行动代码。

package 
{ 
    import flash.display.Sprite; 

    public class Comb extends Sprite 
    { 
     public function Comb() 
     { 
      Hexagon.scale = 0.5; 
      this.x = stage.stageWidth/2; 
      this.y = stage.stageHeight/2; 

      // draw honeycomb with 60 cells 
      drawComb(60); 
     } 

     private function drawComb (n:uint):void 
     { 
      var colors:Array = new Array(0x33CC33, 0x006699, 0xCC3300, 0x663399, 0xFF9900, 0x336666); 
      var sectors:Array = new Array(
       new Array(2, 0), 
       new Array(1, 1), 
       new Array(-1, 1), 
       new Array(-2, 0), 
       new Array(-1, -1), 
       new Array(1, -1)); 

      var w:Number = 0.50 * Hexagon.hxWidth; 
      var h:Number = 0.75 * Hexagon.hxHeight; 
      var r:uint, p:uint, s:uint; 
      var hx:Hexagon; 

      for (var i:uint = 0; i <= n; i++) 
      { 
       r = getRadius(i); 
       p = getPosition(i, r); 
       s = getSector(i, r, p); 

       // create hexagon 
       if (r == 0) 
        hx = new Hexagon(0xCCCCCC); 
       else 
        hx = new Hexagon(colors[s]); 

       hx.x = w * (r * sectors[s][0] - (p % r) * (sectors[s][0] - sectors[ (s + 1) % 6 ][0])); 
       hx.y = h * (r * sectors[s][1] - (p % r) * (sectors[s][1] - sectors[ (s + 1) % 6 ][1])); 
       addChild(hx); 
      } 
     } 

     private function getRadius (i:uint):uint 
     { 
      var r:uint = 0; 
      while (i > r * 6) 
       i -= r++ * 6; 
      return r; 
     } 

     private function getPosition (i:uint, r:uint):uint 
     { 
      if (r == 0) 
       return i; 
      while (r-- > 0) 
       i -= r * 6; 
      return i - 1; 
     } 

     private function getSector (i:uint, r:uint, s:uint):uint 
     { 
      return Math.floor(s/r); 
     } 
    } 
} 

import flash.display.Shape; 

class Hexagon extends Shape 
{ 
    public static var hxWidth:Number = 90; 
    public static var hxHeight:Number = 100; 

    private static var _scale:Number = 1; 

    public function Hexagon (color:uint) 
    { 
     graphics.beginFill(color); 
     graphics.lineStyle(3, 0xFFFFFF); 
     graphics.moveTo( 0, -50); 
     graphics.lineTo( 45, -25); 
     graphics.lineTo( 45, 25); 
     graphics.lineTo( 0, 50), 
     graphics.lineTo(-45, 25); 
     graphics.lineTo(-45, -25); 
     graphics.lineTo( 0, -50); 

     this.scaleX = this.scaleY = _scale; 
    } 

    public static function set scale (value:Number):void 
    { 
     _scale = value; 
     hxWidth = value * 90; 
     hxHeight = value * 100; 
    } 

    public static function get scale():Number 
    { 
     return _scale; 
    } 
} 
+0

你做到了!你的代码很棒!非常感谢你所做的一切,我会为我所需要的改变一下,但它非常完美! – vitto 2010-05-22 17:25:33

+0

非常好:)工作很好 – Ladislav 2010-05-24 06:44:19