/**
* Copyright Thy ( http://wonderfl.net/user/Thy )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/3Ko5
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.geom.ColorTransform;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
/**
* ...
* @author Thi
*/
public class Main extends Sprite
{
// usadas pra formar o texto
private var texto:String = "Thi"
private var TF:TextField = new TextField()
private var format:TextFormat = new TextFormat("Arial", 200)
private var tw:Number, th:Number
// usada pra armazenar o desenho do texto, ou da screen
private var TDATA:BitmapData
private var DATA:BitmapData
private var screen:Bitmap
// câmera
private var cam:Cam = new Cam()
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
// desenha o bitmap do texto
TF.defaultTextFormat = format
TF.autoSize = TextFieldAutoSize.LEFT
TF.text = texto
stage.addChild(TF)
// copia o desenho desse texto
tw = TF.width
th = TF.height
TDATA = new BitmapData(tw, th, false, 0xFFFFFF)
TDATA.draw(TF)
// lixo
stage.removeChild(TF)
format = null
TF = null
// inicia pontos
initPart()
// inicia variáveis da screen (a única coisa que é mostrada na tela)
DATA = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0)
screen = new Bitmap(DATA, "auto", true)
RECT = DATA.rect
stage.addChild(screen)
// listeners
stage.addEventListener(KeyboardEvent.KEY_DOWN, down)
stage.addEventListener(Event.ENTER_FRAME, ef)
}
// temp
private var i:uint, j:uint, part:Part, X:Number, Y:Number, Z:Number
// variáveis para partículas
private var num:uint = 2000
private var parts:Vector.<Part> = new Vector.<Part>(num)
// inicia pontos
private function initPart():void
{
// cria a primeira partícula
part = new Part()
parts[0] = part
while ( TDATA.getPixel( (X = Math.random()*tw), (Y = Math.random()*th) ) != 0 )
{
}
part.x = X
part.y = Y
part.z = 1
// agora cria as próximas partículas
i = 0
while (++i < num)
{
// cria partículas, e as variáveis necessárias
part = new Part()
parts[i] = part
parts[i - 1].next = part
part.prev = parts[i - 1]
// faz as posições serem aleatórias,e também serem de acordo com o desenho do texto
while ( TDATA.getPixel( (X = Math.random()*tw), (Y = Math.random()*th) ) != 0 )
{
}
part.x = X
part.y = Y
part.z = Math.random() * 50 + 50
}
// lixo
part = null
X = NaN
Y = NaN
}
// função onEnterFrame
private var loop:Number = 0, seno:Number
private function ef (e:Event = null):void
{
andarCam()
loop += .1
seno = Math.sin(loop)
DATA.lock()
render()
filtros()
DATA.unlock()
}
private function andarCam():void
{
cam.vx *= .9
cam.vz *= .9
cam.a += (mouseX - 232.5) * .0001
A = cam.a
cam.z += Math.cos(A) * cam.vz
cam.x += Math.sin(A) * cam.vz
A += Math.PI*.5 // aumenta o ângulo em 90°
cam.z += Math.cos(A) * cam.vx
cam.x += Math.sin(A) * cam.vx
}
private var A:Number, R:Number
private var perspectiva:Number = 300, focal:Number
private function render():void
{
part = parts[0]
// distância dos pontos
X = part.x - cam.x
Y = part.y - cam.y
Z = part.z - cam.z
// ângulo da câmera em relação ao ponto, em relação ao eixo Y
A = Math.atan2(Z, X)
// raio da distância do ponto com a câmera, sem contar a altura
R = Math.sqrt(X * X + Z * Z) // pitágoras ( r² = x² + z² )
// ajusta as posições X e Z, de acordo com os ângulos
X = Math.cos (A + cam.a) * R
Z = Math.sin (A + cam.a) * R
// calcula a focal (varia de 0 à 1)
focal = perspectiva / (perspectiva + Z)
// renderiza ponto
X *= focal
Y *= focal
DATA.setPixel(X + 235, Y, 0xFF0000)
// renderiza o resto das partículas
while ((part = part.next) != null)
{
X = part.x - cam.x
Y = part.y - cam.y
Z = part.z - cam.z
// ângulo da câmera em relação ao ponto, em relação ao eixo Y
A = Math.atan2(Z, X)
// raio da distância do ponto com a câmera, sem contar a altura
R = Math.sqrt(X * X + Z * Z) // pitágoras ( r² = x² + z² )
// ajusta as posições X e Z, de acordo com os ângulos
X = Math.cos (A + cam.a) * R
Z = Math.sin (A + cam.a) * R
// calcula a focal (varia de 0 à 1)
focal = perspectiva / (perspectiva + Z)
// renderiza ponto
X *= focal
Y *= focal
if (focal > 0)
{
DATA.setPixel(X+235, Y, 0xFFFFFF)
}
}
}
private var RECT:Rectangle
private var COL:ColorTransform = new ColorTransform(.9,.9,.9)
private function filtros():void
{
DATA.colorTransform(RECT, COL)
}
private var key:uint
// função KeyDown
private function down(e:KeyboardEvent):void
{
key = e.keyCode
if (key == 37)
{
// esquerda
cam.vx -= 1
} else if (key == 39)
{
// direita
cam.vx += 1
}
if (key == 38)
{
// cima
cam.vz += 1
} else if (key == 40)
{
// baixo
cam.vz -= 1
}
}
}
}
//package
//{
/**
* ...
* @author Thi
*/
/*public*/ class Cam
{
public var x:Number, y:Number, z:Number, a:Number, vx:Number, vy:Number, vz:Number
public function Cam(x:Number = 0, y:Number = 0, z:Number = 0, a:Number = 0, vx:Number = 0, vy:Number = 0, vz:Number = 0)
{
this.x = x
this.y = y
this.z = z
this.a = a
this.vx = vx
this.vy = vy
this.vz = vz
}
}
//}
//package
//{
/**
* ...
* @author Thi
*/
/*public*/ class Part
{
public var x:Number, y:Number, z:Number, vx:Number, vy:Number, vz:Number
public var prev:Part, next:Part
public function Part(x:Number = 0, y:Number = 0, z:Number = 0, vx:Number = 0, vy:Number = 0, vz:Number = 0)
{
this.x = x
this.y = y
this.z = z
this.vx = vx
this.vy = vy
this.vz = vz
}
}
//}