Penrose Stairs Complex
あ…ありのまま今起こった事を話すぜ!
「おれは奴の前で階段を登っていたと思ったらいつのまにか降りていた」
な…何を言ってるのかわからねーと思うので、
こちらにその図を用意しました。御覧下さい。
/**
* Copyright o8que ( http://wonderfl.net/user/o8que )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/z1Fp
*/
/* ------------------------------------------------------------------------------------------------
* [階段シリーズ]
* http://wonderfl.net/c/zQW4 hiyoko vs. unko (HVU)
* http://wonderfl.net/c/2epI A
* http://wonderfl.net/c/z1Fp Penrose Stairs Complex
* http://wonderfl.net/c/lVRx Penrose Stairs Fractal
* http://wonderfl.net/c/atBv Complementary Penrose Stairs Fractal
* ------------------------------------------------------------------------------------------------
*/
package {
import flash.display.Sprite;
import flash.events.Event;
[SWF(width="465",height="465",frameRate="60")]
public class Main extends Sprite {
private var _segments:Vector.<IsoObject>;
private var _count:int;
private var _diffY:Number;
private static const BOX_SIZE:int = 50;
private static const RISER:Number = BOX_SIZE / 6;
private static const SEGMENT_INTERVAL:Number = BOX_SIZE * 2 + RISER * 4;
public function Main() {
_segments = new Vector.<IsoObject>();
_count = 0;
_diffY = 0;
var i:int;
for (i = 0; i < 6; i++) { _segments.push(createSegment()); }
for (i = 0; i < 6; i++) { shiftSegment(); }
x = BOX_SIZE * 3.5 + 7.5;
y = 900;
addEventListener(Event.ENTER_FRAME, update);
}
private function createSegment():IsoObject {
var segment:IsoObject = new IsoObject();
var step:Array = [0,1,10,9,6,2,8,5,4,3,4,5,6,7];
var boxX:Array = [2,2,5,6,0,2,6,0,1,2,3,4,5,6];
var boxZ:Array = [0,1,1,1,2,2,2,3,3,3,3,3,3,3];
for (var i:int = 0; i < 14; i++) {
var box:IsoBox = new IsoBox(BOX_SIZE, 500);
box.wx = BOX_SIZE * boxX[i];
box.wy = -RISER * step[i];
box.wz = -BOX_SIZE * boxZ[i];
segment.addChild(box);
}
return segment;
}
private function shiftSegment():void {
var segment:IsoObject = _segments.shift();
segment.wx = -_count * BOX_SIZE * 4;
segment.wy = _count * RISER * 8;
segment.wz = _count * BOX_SIZE * 4;
addChildAt(segment, 0);
_segments.push(segment);
_count++;
}
private function update(event:Event):void {
var increment:Number = 1;
y += increment;
_diffY += increment;
if (_diffY > SEGMENT_INTERVAL) {
_diffY -= SEGMENT_INTERVAL;
shiftSegment();
}
}
}
}
/* ------------------------------------------------------------------------------------------------
* IsoObject
* ------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Sprite;
import flash.geom.Point;
import flash.geom.Vector3D;
//public
class IsoObject extends Sprite {
private var _world:Vector3D;
private var _screen:Point;
public function IsoObject() {
_world = new Vector3D(0, 0, 0);
_screen = new Point(0, 0);
}
public function update():void {
x = _screen.x;
y = _screen.y;
}
public function get wx():Number { return _world.x; }
public function set wx(value:Number):void { _world.x = value; IsoUtils.isoToScreen(_world, _screen); update(); }
public function get wy():Number { return _world.y; }
public function set wy(value:Number):void { _world.y = value; IsoUtils.isoToScreen(_world, _screen); update(); }
public function get wz():Number { return _world.z; }
public function set wz(value:Number):void { _world.z = value; IsoUtils.isoToScreen(_world, _screen); update(); }
}
//}
/* ------------------------------------------------------------------------------------------------
* IsoBox
* ------------------------------------------------------------------------------------------------
*/
//package {
//public
class IsoBox extends IsoObject {
private var _size:Number;
private var _height:Number;
public function IsoBox(size:Number, height:Number) {
super();
_size = size;
_height = height;
draw();
}
private function draw():void {
var halfSize:Number = _size / 2;
graphics.clear();
graphics.moveTo(0, halfSize - _height);
drawTopFace();
drawLeftFace();
drawRightFace();
function drawTopFace():void {
graphics.lineStyle(0, 0xC0C0C0);
graphics.beginFill(0xFFFFFF);
graphics.lineTo( -_size, -_height);
graphics.lineTo(0, -halfSize - _height);
graphics.lineTo(_size, -_height);
graphics.lineTo(0, halfSize - _height);
graphics.endFill();
}
function drawLeftFace():void {
graphics.lineStyle();
graphics.beginFill(0xC0C0C0);
graphics.lineTo(0, halfSize);
graphics.lineTo( -_size, 0);
graphics.lineTo( -_size, -_height);
graphics.lineTo(0, halfSize - _height);
graphics.endFill();
}
function drawRightFace():void {
graphics.lineStyle();
graphics.beginFill(0x808080);
graphics.lineTo(0, halfSize);
graphics.lineTo(_size, 0);
graphics.lineTo(_size, -_height);
graphics.lineTo(0, halfSize - _height);
graphics.endFill();
}
}
override public function get height():Number { return _height; }
override public function set height(value:Number):void { _height = value; draw(); }
}
//}
/* ------------------------------------------------------------------------------------------------
* IsoUtils
* ------------------------------------------------------------------------------------------------
*/
//package {
import flash.geom.Point;
import flash.geom.Vector3D;
//public
class IsoUtils {
public static const TRUE_SCALE:Number = Math.cos( -30 * Math.PI / 180) * Math.SQRT2;
public static function isoToScreen(iso:Vector3D, out:Point = null):Point {
out ||= new Point(0, 0);
out.x = iso.x + iso.z;
out.y = (iso.x - iso.z) / 2 + iso.y;
return out;
}
public static function screenToIso(screen:Point, out:Vector3D = null):Vector3D {
out ||= new Vector3D(0, 0, 0);
out.x = (screen.x / 2 + screen.y) - out.y;
out.z = (screen.x / 2 - screen.y) + out.y;
return out;
}
public static function compareDepth(a:Vector3D, b:Vector3D):Number {
return (a.x - a.y - a.z) - (b.x - b.y - b.z);
}
}
//}