我正在尝试使用 as3
创建一个 honeycomb
但我在单元格定位方面遇到了一些问题。
我已经创建了单元格(不使用代码)并将它们用于循环
到函数
并向它发送我认为需要的参数(蜂窝单元已经在舞台中央的 Sprite 容器上了)。
要查看循环的结构和传递的参数,请参阅下面的示例,我在 placeCell
中计算的唯一内容是我应该直接在调用的 函数中获取的角度
alt text http://img293.imageshack.us/img293/1064/honeycomb.png
注意:角度是反的,但并不重要,颜色仅在视觉划分的情况下在示例中有用。
我的 for 循环调用 placeCell
并传递 cell
、current_case
、counter
(index) 和 honeycomb 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);
如果您复制并粘贴此代码,它可以工作
,但您需要创建一个六边形并将其作为单元格在 actionscript 库中调用
我该如何解决?
我也想过用一个开关来对齐它,但我认为这样做有点问题
最佳答案
好吧,我真的很喜欢这个问题。这很有趣,也很有挑战性,我得到了一个有效的结果。我没有使用您的任何代码作为基础,而是从头开始,因此根据您的最终用途,您可能需要进行一些更改。
然而,我确实创建了与您的单元格内的变量类似的变量(在图片中)。对于每个单元格,您具有以下属性:
- 迭代变量
i
等于您的单元格编号 - 半径
r
等于您的等级,表示距中心的距离(0
是中心) - position
p
表示当前半径内的位置 - 扇区
等于您的案例,但从零开始
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;
}
}
关于actionscript-3 - 用as3画一个 hive ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2887725/