WireFrame SpaceShip
wire frame test
/**
* Copyright whirlpower ( http://wonderfl.net/user/whirlpower )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/lVW5
*/
/*
* wire frame test
*/
package {
import flash.display.Sprite;
[SWF(width=465, height=465, backgroundColor = 0x000000, frameRate = 60)]
public class FlashTest extends Sprite {
public function FlashTest() {
// write as3 code here..
new SpaceField( stage );
graphics.beginFill( 0x000000, 1 );
graphics.drawRect(0,0,465,465);
graphics.endFill();
}
}
}
import flash.display.*;
import flash.events.*;
internal class SpaceField extends Sprite
{
private var particles :Array = new Array();
private var spaceShip :SpaceShip;
private var renderer :Renderer;
private var pars :PerspectiveCalculater;
private var container :DisplayObjectContainer;
public function SpaceField( container:DisplayObjectContainer ):void
{
this.container = container;
pars = new PerspectiveCalculater( 0, 0, 250 );
renderer = new Renderer( 500, 500 );
spaceShip = new SpaceShip();
onEnterFrame( null );
container.addChild( renderer );
container.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
container.addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
addEventListener(Event.ENTER_FRAME, onEnterFrame );
}
private function mouseDownHandler( e:MouseEvent ):void
{
mouseDown = true;
}
private function mouseUpHandler( e:MouseEvent ):void
{
mouseDown = false;
}
private var vx :Number = 2;
private var vy :Number = 2;
private var lx :Number = 0;
private var ly :Number = 0;
private var friction :Number = 0.999;
private var mouseDown :Boolean = false;
/**
* enter frame
* @param evt
*/
private function onEnterFrame( evt:Event ):void
{
// 横回転
if ( mouseDown )
vx = lx - container.mouseX;
else
vx *= friction;
if( Math.abs( vx ) <= 0.1 ) vx = 0;
lx = container.mouseX;
// 縦回転
if( mouseDown )
vy = ly - container.mouseY;
else
vy *= friction;
if( Math.abs( vy ) <= 0.1 ) vy = 0;
ly = container.mouseY;
// 座標回転
for each( var v:Vertex in spaceShip.vertices )
{
localRotate( v, "z", "y", vy );
localRotate( v, "x", "z", -vx );
pars.to2D( v );
}
renderer.draw( spaceShip.edges, spaceShip.vertices );
}
private function localRotate( vertex:Vertex, a:String, b:String, v:Number ):void
{
var cos :Number;
var sin :Number;
var posA:Number;
var posB:Number;
var rad :Number = Math.PI / 360;
cos = Math.cos( v * rad );
sin = Math.sin( v * rad );
posA = vertex[a];
posB = vertex[b];
vertex[a] = posA * cos - posB * sin;
vertex[b] = posB * cos + posA * sin;
}
}
/**
* vertex
*/
internal class Vertex
{
public var x :Number = 0;
public var y :Number = 0;
public var z :Number = 0;
public var vx :Number = 0;
public var vy :Number = 0;
public var vz :Number = 0;
public var drawX:Number = 0;
public var drawY:Number = 0;
public var scale:Number = 1;
public var color:uint = 0xFFFFFF;
public function Vertex():void{}
}
/**
* edge
*/
internal class Edge
{
public var vertex1 :Vertex;
public var vertex2 :Vertex;
public var color :uint = 0xFFFFFF;
public function Edge( vertex1:Vertex, vertex2:Vertex, color:uint ):void
{
this.vertex1 = vertex1;
this.vertex2 = vertex2;
this.color = color;
}
}
/**
* renderer
*/
internal class Renderer extends Bitmap
{
private var w :int;
private var h :int;
private var centerX :int;
private var centerY :int;
public function Renderer( _w:int, _h:int ):void
{
this.w = _w;
this.h = _h;
centerX = int( w / 2 );
centerY = int( h / 2 );
bitmapData = new BitmapData( w, h, true, 0x00 );
}
public function draw( edges:Array, vertices:Array ):void
{
var scale :Number;
bitmapData.lock();
bitmapData.fillRect( bitmapData.rect, 0x00 );
// vartexsのレンダリング
for each( var p:Vertex in vertices )
{
bitmapData.setPixel32( centerX+p.drawX, centerY+p.drawY, p.color );
}
//edgeのレンダリング
for each( var e:Edge in edges )
{
var shape :Shape = new Shape();
var g :Graphics = shape.graphics;
g.lineStyle( 1, e.color );
g.moveTo( centerX+e.vertex1.drawX, centerY+e.vertex1.drawY );
g.lineTo( centerX+e.vertex2.drawX, centerY+e.vertex2.drawY );
bitmapData.draw( shape );
}
bitmapData.unlock();
}
}
/**
* 3D座標を2D座標に変換します。
*/
internal class PerspectiveCalculater
{
private var vpX :int; // 消失点
private var vpY :int; // 消失点
private var fl :int; // 画角
public function PerspectiveCalculater( vpX:int, vpY:int, fl:int = 500 )
{
this.vpX = vpX;
this.vpY = vpY;
this.fl = fl;
}
/*
* 3D座標の2D変換
*/
public function to2D( v:Vertex ):void
{
var scale:Number = fl / ( fl + v.z );
v.drawX = vpX + v.x * scale;
v.drawY = vpY + v.y * scale;
v.scale = scale;
}
}
/**
* 宇宙船データ
*/
internal class SpaceShip extends Vertex
{
public var vertices :Array;
public var edges :Array;
// Shipを構成するVartex座標
private var shipData :Array = [
-14.5, 0.0, 0.4,
14.5, 0.0, 0.4,
0.0, 22.0, 4.2,
0.0, 0.0, 69.0,
0.0, 12.0, -32.4,
25.5, 3.6, -17.1,
86.0, -16.7, -16.8,
-25.5, 3.6, -17.1,
-86.0, -16.7, -16.8,
26.5, 23.3, -10.2,
36.1, 35.2, -44.7,
-26.5, 23.3, -10.2,
-36.1, 35.2, -44.7,
];
// edgeの組み合わせ
private var shipEage :Array = [
0,3, 1,3, 2,3, 0,4, 1,4, 2,4, 0,1, 1,2, 0,2,
1,6, 5,6, 1,5, 9,10, 1,10, 1,9,
0,8, 7,8, 0,7, 0,12, 11,12, 0,11
];
public function SpaceShip():void
{
vertices = [];
edges = [];
createShip();
}
/**
* Shipのデータを作成する。
*/
private function createShip():void
{
var v :Vertex;
var leng:int = shipData.length;
var i :int = 0;
for ( i = 0; i < leng; i += 3 )
{
v = new Vertex();
v.x = shipData[i];
v.y = shipData[i+1];
v.z = shipData[i+2];
v.scale = 1;
v.color = 0xFFFFFFFF;
vertices.push( v );
}
leng = shipEage.length;
for ( i = 0; i < leng; i+=2)
{
edges.push( new Edge( vertices[shipEage[i]], vertices[shipEage[i+1]], color ) );
}
}
}