forked1:カーナビのあれっぽいのforked from: PS2 Firework
yにも変化つけてみた
package {
import __AS3__.vec.Vector;
import flash.display.BitmapData;
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Utils3D;
import flash.geom.Vector3D;
import flash.utils.getTimer;
[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="40")]
/**
* yにも変化つけてみた
*
*/
public class mapLine extends Sprite
{
private var baseField:Sprite = new Sprite();
private var sprite:Sprite = new Sprite();
private var perspective:PerspectiveProjection = new PerspectiveProjection();
private var projectionMatrix:Matrix3D = new Matrix3D();
private const CENTER_X:Number = stage.stageWidth / 2;
private const CENTER_Y:Number = stage.stageHeight * 0.65;
private const FLOOR_SIZE:Number = 300;
private const FLOOR_HALFSIZE:Number = FLOOR_SIZE / 2;
private var FLOOR_VERTICES:Vector.<Number> = Vector.<Number>([
FLOOR_HALFSIZE, 0, FLOOR_HALFSIZE,
-FLOOR_HALFSIZE, 0, FLOOR_HALFSIZE,
-FLOOR_HALFSIZE, 0, -FLOOR_HALFSIZE,
FLOOR_HALFSIZE, 0, -FLOOR_HALFSIZE,
FLOOR_HALFSIZE, 0, 0,
-FLOOR_HALFSIZE, 0, 0,
0, 0, FLOOR_HALFSIZE,
0, 0, -FLOOR_HALFSIZE,
]);
private var floorUvts:Vector.<Number> = Vector.<Number>([
1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]);
private var floorUvts2:Vector.<Number> = Vector.<Number>([
1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]);
private const FLOOR_VERTEX_NUMBER:int = FLOOR_VERTICES.length / 3;
private var floorProjectedVertices:Vector.<Number> = new Vector.<Number>();
private var floorIndices:Vector.<int> = Vector.<int>([
0, 1, 2, 2, 3, 0
]);
private var viewRotationY:Number = 0;
private var viewRotationX:Number = 25;
private const TEXTURE_SIZE:int = 150;
private var floorTexture:BitmapData = new BitmapData(TEXTURE_SIZE, TEXTURE_SIZE, false, 0x000000);
// 照り返し
private var reflectionBitmapData:BitmapData;
private const REFLECTION_COLOR:uint = 0x555566;
private const REFLECTION_RADIUS:Number = 16;
//Line
private var lineSprite:Sprite = new Sprite();
private var lineNum:uint = 30;
private var LineArray:Vector.<linePos> = new Vector.<linePos>(lineNum);
public function mapLine()
{
setBaseField();
addEventListener(Event.ENTER_FRAME, handleEnterFrame);
}
private var WIREFRAME_COLOR:uint = 0xFFFFFF;
private function setBaseField():void {
addChild(sprite);
addChild(lineSprite);
for(var i:uint=0; i<lineNum; i++) {
LineArray[i] = new linePos();
}
var shape:Shape = new Shape();
var g:Graphics = shape.graphics;
reflectionBitmapData = new BitmapData(REFLECTION_RADIUS * 2, REFLECTION_RADIUS * 2, true, 0);
g.clear();
var matrix:Matrix = new Matrix();
matrix.createGradientBox(REFLECTION_RADIUS * 2, REFLECTION_RADIUS * 2, 0, 0, 0);
g.beginGradientFill(GradientType.RADIAL, [ REFLECTION_COLOR, REFLECTION_COLOR ], [ 1, 0 ], [ 0, 255 ], matrix);
g.drawCircle(REFLECTION_RADIUS, REFLECTION_RADIUS, REFLECTION_RADIUS*0.1);
g.endFill();
reflectionBitmapData.draw(shape);
}
private function handleEnterFrame(e:Event):void
{
const FACTOR:Number = 0.06;
viewRotationY += (getTimer() * 0.01 + (-(CENTER_X - mouseX) * 0.4) - viewRotationY) * FACTOR;
viewRotationX += ((27 + (CENTER_Y - mouseY) * 0.15) - viewRotationX) * FACTOR;
_render();
setupProjectionMatrix();
}
private function renderFloor(nx:Number, nz:Number):void
{
var matrix:Matrix = new Matrix();
var colorTransform:ColorTransform = new ColorTransform();
matrix.translate(FLOOR_HALFSIZE + nx - REFLECTION_RADIUS * 1, FLOOR_HALFSIZE - nz - REFLECTION_RADIUS * 1);
matrix.scale(TEXTURE_SIZE / FLOOR_SIZE, TEXTURE_SIZE / FLOOR_SIZE);
floorTexture.draw(reflectionBitmapData, matrix, colorTransform);
}
private function _render():void
{
Utils3D.projectVectors(projectionMatrix, FLOOR_VERTICES, floorProjectedVertices, floorUvts);
for (var i:uint = 0; i < FLOOR_VERTEX_NUMBER; i++) {
floorProjectedVertices[(i << 1) ] += CENTER_X;
floorProjectedVertices[(i << 1) + 1] += CENTER_Y;
}
var g:Graphics = sprite.graphics;
g.clear();
g.beginBitmapFill(floorTexture);
g.drawTriangles(floorProjectedVertices, floorIndices, floorUvts);
g.endFill();
g.lineStyle(1, WIREFRAME_COLOR);
g.moveTo(floorProjectedVertices[0], floorProjectedVertices[1]);
g.lineTo(floorProjectedVertices[2], floorProjectedVertices[3]);
g.lineTo(floorProjectedVertices[4], floorProjectedVertices[5]);
g.lineTo(floorProjectedVertices[6], floorProjectedVertices[7]);
g.lineTo(floorProjectedVertices[0], floorProjectedVertices[1]);
// LINE
var g2:Graphics = lineSprite.graphics;
g2.clear();
g2.lineStyle(1, WIREFRAME_COLOR);
for(var il:uint=0; il<lineNum; il++) {
var lPos:linePos = LineArray[il];
Utils3D.projectVectors(projectionMatrix, lPos.LINE_VERTICES, lPos.lineProjectedVertices, floorUvts2);
var LINE_V_NUM:int = lPos.LINE_VERTEX_NUMBER;
for (i = 0; i <LINE_V_NUM; i++) {
lPos.lineProjectedVertices[(i << 1) ] += CENTER_X;
lPos.lineProjectedVertices[(i << 1) + 1] += CENTER_Y;
}
g2.moveTo(lPos.lineProjectedVertices[0], lPos.lineProjectedVertices[1]);
var lineArNum:Number = lPos.lineProjectedVertices.length / 2;
for(i=1; i<lineArNum; i++) {
g2.lineTo(lPos.lineProjectedVertices[i*2], lPos.lineProjectedVertices[i*2+1]);
}
lPos.handleEnterFrame();
var px:Number = lPos.LINE_VERTICES[0] +( lPos.vecX*Math.random() )*20;
var py:Number = lPos.LINE_VERTICES[2] +( lPos.vecZ*Math.random() )*20;
renderFloor(px, py);
}
}
private function setupProjectionMatrix():void
{
perspective.fieldOfView = 60;
projectionMatrix.identity();
projectionMatrix.appendRotation(viewRotationY, Vector3D.Y_AXIS);
projectionMatrix.appendRotation(viewRotationX, Vector3D.X_AXIS);
projectionMatrix.appendTranslation(0, 0, perspective.focalLength);
projectionMatrix.append(perspective.toMatrix3D());
correctMatrix3DMultiplyBug(projectionMatrix);
}
private function correctMatrix3DMultiplyBug(matrix:Matrix3D):void
{
var m1:Matrix3D = new Matrix3D(Vector.<Number>([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 ]));
var m2:Matrix3D = new Matrix3D(Vector.<Number>([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ]));
m1.append(m2);
if (m1.rawData[15] == 20) {
// バグ持ち!
var rawData:Vector.<Number> = matrix.rawData;
rawData[15] /= 20;
matrix.rawData = rawData;
}
}
}
}
class linePos {
public var LINE_VERTICES:Vector.<Number> = Vector.<Number>([
0, -50, 0,
0, -50, 0,
0, -50, 0,
0, -50, 0,
0, -50, 0,
0, -50, 0,
0, -50, 0,
0, -50, 0
]);
public var lineProjectedVertices:Vector.<Number> = new Vector.<Number>();
public const LINE_VERTEX_NUMBER:int = LINE_VERTICES.length / 3;
public var cnt:uint=0;
public var vecX:Number = -1;
public var vecZ:Number = 2;
private const FLOOR_SIZE:Number = 300;
private const FLOOR_HALFSIZE:Number = FLOOR_SIZE / 2;
private var delay:uint;
private var delaycnt:uint = 0;
private var R:Number = 30 * Math.random(); //y値の波形半径
//コンストラクタ
public function linePos()
{
delay = Math.round( 20 * Math.random() );
}
public function handleEnterFrame():void {
if(delaycnt>delay) {
update();
} else {
delaycnt++;
}
}
private function update():void
{
var leng:uint = LINE_VERTICES.length/3;
var t:uint
for(var i:uint=1; i<leng; i++) {
t = leng-1-i;
LINE_VERTICES[(t+1)*3+2] = LINE_VERTICES[t*3+2];
LINE_VERTICES[(t+1)*3+1] = LINE_VERTICES[t*3+1];
LINE_VERTICES[(t+1)*3] = LINE_VERTICES[t*3];
}
if(cnt==15) {
var ram:Number = Math.random();
//開始点にポイントを戻す。4方向のどこを開始点にするかはランダム
var startX:Number;
var startZ:Number;
if(ram < 0.25) {
startX = -FLOOR_HALFSIZE+FLOOR_SIZE*Math.random();
startZ = -FLOOR_HALFSIZE;
vecX = -1 + 2 * Math.random();
vecZ = 2;
}else if(ram<0.5) {
startX = -FLOOR_HALFSIZE+FLOOR_SIZE*Math.random();
startZ = FLOOR_HALFSIZE;
vecX = -1 + 2 * Math.random();;
vecZ = -2;
}else if(ram<0.75) {
startX = -FLOOR_HALFSIZE;
startZ = -FLOOR_HALFSIZE+FLOOR_SIZE*Math.random();
vecX = 2;
vecZ = -1 + 2 * Math.random();;
}else {
startX = FLOOR_HALFSIZE;
startZ = -FLOOR_HALFSIZE+FLOOR_SIZE*Math.random();
vecX = -2;
vecZ = -1 + 2 * Math.random();
}
//3次元座標のリセット。
LINE_VERTICES = Vector.<Number>([
startX, -50, startZ,
startX, -50, startZ,
startX, -50, startZ,
startX, -50, startZ,
startX, -50, startZ,
startX, -50, startZ,
startX, -50, startZ,
startX, -50, startZ
]);
cnt = 0;
} else {
//通常は単に座標を更新する
var px:Number = LINE_VERTICES[0] +( vecX*Math.random() )*10;
var py:Number = LINE_VERTICES[2] +( vecZ*Math.random() )*10;
LINE_VERTICES[0] = px;
LINE_VERTICES[1] = -50 + R * Math.sin(cnt);
LINE_VERTICES[2] = py;
cnt++;
}
}
}