/**
* Copyright Cheshir ( http://wonderfl.net/user/Cheshir )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/njIQ
*/
/* first try make simple paralax */
package {
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.geom.Point;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.events.Event;
import flash.display.Sprite;
public class FlashTest extends Sprite {
private var tf:TextField = new TextField();
private var moveSpeed:Number = 2;
private var cameraView:Sprite;
private var camera:MyCamera;
public function FlashTest() {
// Итак... эффект паралакса есть...
Point3D.centerX = stage.stageWidth/2;
Point3D.centerY = stage.stageHeight/2;
addChild(tf);
cameraView = new Sprite();
cameraView.graphics.beginFill(0);
cameraView.graphics.drawRect(0,0,stage.stageWidth/2,stage.stageHeight/2);
cameraView.x = stage.stageWidth/2;
cameraView.y = stage.stageHeight/2;
addChild(cameraView);
addEventListener(Event.ENTER_FRAME, update);
stage.addEventListener(MouseEvent.CLICK, stopMove);
stage.addEventListener(MouseEvent.MOUSE_DOWN, startMove);
/* Теперь... предположим, я хочу накидать 2д сетку... уходящую к горизонту...
for(var tz:int=0; tz<20; tz++){
for(var tx:int=0; tx<18; tx++){
points.push(new Point3D(tx*30, stage.stageHeight*Math.random(), tz*30));
}
} //*/
// Теперь давай создадим то, что станет камерой...
camera = new MyCamera(150,20,20, cameraView); // Сейчас камера ближе... кубики начинаются с Z=100;
for(var tx:int=0; tx<12; tx+=2){
boxes.push(new Box(Math.random()*3,Math.random()*3,Math.random()*3));
}
camera.viewBoxes = boxes;
tf.text = 'boxes:'+camera.viewBoxes.length;
}
private var boxes:Array = [];
private var points:Array = [];
private function update(e:Event):void{
this.graphics.clear();
this.graphics.lineStyle(0.5);
this.graphics.beginFill(0xccffcc);
this.graphics.drawCircle(Point3D.centerX, Point3D.centerY, 3);
for(var i:int=0; i<boxes.length; i++){
// points[i].z += 2;
// this.graphics.moveTo(points[i].x, points[i].y);
// camera.y += 2; // Падение камеры... вобщем то, я хочу чтобы у нее был собственный бокс, который бы следил за ней...
// camera.cameraBox.drawBoxOn(this,0xffcc00,0xffffff); // У камеры есть собственный бокс
camera.calculateBox(); // В принципе.. его наверное можно использовать для проверки столкновений...
camera.render();
boxes[i].drawBoxOn(this);
}
this.graphics.beginFill(0xff0000);
this.graphics.drawCircle(camera.realX, camera.realY, 5-camera.z/500);
if(cameraMove){
//Point3D.centerX = mouseX; Point3D.centerY = mouseY;
selectBoxOnView();
// Нужно рассчитать поворот камеры в зависимости от положения мыши...
//camera.move(); // Нужно подвинуть камеру, в том направлении, в котором она повернута...
}
}
private function stopMove(e:MouseEvent):void {
cameraMove = false;
}
private var cameraMove:Boolean = false;
private function startMove(e:MouseEvent):void {
cameraMove = true;
}
private function selectBoxOnView():void{
// Так... попроубем найти бокс по которому попала мышь...
//boxes[0].drawBoxOn(this, 1, 0xff0000);
camera.x = mouseX; camera.y = mouseY;
camera.calculateBox();
camera.cameraBox.drawBoxOn(this, 1, 0xff0000);
// Нужно провести луч от экрана к горизонту...
var p:Point3D = new Point3D(mouseX, mouseY, 0);
var horisont:Point3D = new Point3D(Point3D.centerX, Point3D.centerY, Point3D.maxFar);
this.graphics.lineStyle(1, 0xffff00);
this.graphics.moveTo(p.realX, p.realY);
this.graphics.lineTo(horisont.realX, horisont.realY);
}
}
}
import flash.display.Sprite;
import flash.geom.Point;
Class {
class Box { // Пусть бокс будет в простых величинах
private var _x:int;
private var _y:int;
private var _z:int;
public static var BoxSize:Number = 100;
private var boxPoints:Array;
private var planes:Array = [0,1,3,2, 4,5,7,6, 0,4,5,1, 1,3,7,5, 0,2,6,4, 3,2,6,7]; // all 6 faces...
public function Box(x:int,y:int,z:int) {
// вообще бокс должен состоять из 6 сторон, однако, мы же никогда не увидим больше 3-х верно?
_x = x; _y = y; _z = z;
test = new Point3D(x*BoxSize,y*BoxSize,z*BoxSize);
// все же коробке нужны все 8 точек, а вот рендер уже можно будет сделать умнее...
boxPoints = [new Point3D(x*BoxSize,y*BoxSize,z*BoxSize),
new Point3D(x*BoxSize+BoxSize,y*BoxSize,z*BoxSize),
new Point3D(x*BoxSize,y*BoxSize+BoxSize,z*BoxSize),
new Point3D(x*BoxSize+BoxSize,y*BoxSize+BoxSize,z*BoxSize),
new Point3D(x*BoxSize,y*BoxSize,z*BoxSize+BoxSize),
new Point3D(x*BoxSize+BoxSize,y*BoxSize,z*BoxSize+BoxSize),
new Point3D(x*BoxSize,y*BoxSize+BoxSize,z*BoxSize+BoxSize),
new Point3D(x*BoxSize+BoxSize,y*BoxSize+BoxSize,z*BoxSize+BoxSize)];
}
private function recalculateBoxPoints():void {
boxPoints[0].x = _x*BoxSize; boxPoints[0].y = _y*BoxSize; boxPoints[0].z = _z*BoxSize;
boxPoints[1].x = _x*BoxSize+BoxSize; boxPoints[1].y = _y*BoxSize; boxPoints[1].z = _z*BoxSize;
boxPoints[2].x = _x*BoxSize; boxPoints[2].y = _y*BoxSize+BoxSize; boxPoints[2].z = _z*BoxSize;
boxPoints[3].x = _x*BoxSize+BoxSize; boxPoints[3].y = _y*BoxSize+BoxSize; boxPoints[3].z = _z*BoxSize;
boxPoints[4].x = _x*BoxSize; boxPoints[4].y = _y*BoxSize; boxPoints[4].z = _z*BoxSize+BoxSize;
boxPoints[5].x = _x*BoxSize+BoxSize; boxPoints[5].y = _y*BoxSize; boxPoints[5].z = _z*BoxSize+BoxSize;
boxPoints[6].x = _x*BoxSize; boxPoints[6].y = _y*BoxSize+BoxSize; boxPoints[6].z = _z*BoxSize+BoxSize;
boxPoints[7].x = _x*BoxSize+BoxSize; boxPoints[7].y = _y*BoxSize+BoxSize; boxPoints[7].z = _z*BoxSize+BoxSize;
}
public function set z(val:int):void { _z = val; this.recalculateBoxPoints(); }
public function get z():int {return _z;}
public function set x(val:int):void { _x = val; this.recalculateBoxPoints();}
public function get x():int {return _x;}
public function set y(val:int):void { _y = val; this.recalculateBoxPoints();}
public function get y():int {return _y;}
public function getPoints():Array{
return boxPoints;
}
private var test:Point3D;
public function drawBoxOn(canvas:Sprite, stroke:uint=0, fill:uint=0xcccccc):void {
for(var i:int=0; i<planes.length; i+=4){
canvas.graphics.lineStyle(1,stroke);
canvas.graphics.beginFill(fill,0.5);
canvas.graphics.moveTo(boxPoints[planes[i]].realX,boxPoints[planes[i]].realY);
canvas.graphics.lineTo(boxPoints[planes[i+1]].realX,boxPoints[planes[i+1]].realY);
canvas.graphics.lineTo(boxPoints[planes[i+2]].realX,boxPoints[planes[i+2]].realY);
canvas.graphics.lineTo(boxPoints[planes[i+3]].realX,boxPoints[planes[i+3]].realY);
}
canvas.graphics.moveTo(boxPoints[0].realX,boxPoints[0].realY);
}
}
}
Class {
class Point3D extends Point {
public static var centerX:Number = 200;
public static var centerY:Number = 200;
public static var maxFar:Number = 2000;
public var z:Number;
public function Point3D(x:Number=0, y:Number=0, z:Number=0):void{
super(x,y);
this.z = z;
}
private var centerDirect:Number = 0;
private var distanceDirect:Number = 0;
public function get realX():Number {
if(this.z>=maxFar)
return centerX;
var dx:Number = centerX-this.x;
var dy:Number = centerY-this.y;
centerDirect = Math.atan2(dy, dx);
distanceDirect = Math.sqrt(dx*dx+dy*dy);
var rX:Number = this.x + Math.cos(centerDirect)*Math.sqrt(this.z/maxFar)*distanceDirect;
return rX;
}
public function get realY():Number {
// Окей обратная перспектива все еще существует, но это уже не так важно...
// Теперь ее можно просто обезать...
if(this.z>=maxFar)
return centerY;
var dx:Number = centerX-this.x;
var dy:Number = centerY-this.y;
centerDirect = Math.atan2(dy, dx);
distanceDirect = Math.sqrt(dx*dx+dy*dy);
var rY:Number = this.y + Math.sin(centerDirect)*Math.sqrt(this.z/maxFar)*distanceDirect;
return rY;
}
}
}
Class {
class MyCamera extends Point3D { // I think that can be only one camera in this implementaion of Point3D paralax
public var cameraBox:Box;
public var viewBoxes:Array = []; // Сюда мы положим объекты которые будут отобраны для рендера...
public var viewPoints:Array = []; // давай ка соберем точки с коробок
public var rotationY:Number = 90; // Поворот относительно вертикальной оси, по умолчанию... 90... тоесть, от экрана...
private var view:Sprite;
private var viewH:Number;
private var viewW:Number;
public function MyCamera(x:Number, y:Number, z:Number, view:Sprite){
super(x,y,z);
this.view = view;
this.viewH = view.width;
this.viewW = view.height;
Point3D.centerX = view.width/2;
Point3D.centerY = view.width/2;
cameraBox = new Box(x/Box.BoxSize, y/Box.BoxSize, z/Box.BoxSize);
}
public function calculateBox():void {
cameraBox.x = x/Box.BoxSize;
cameraBox.y = y/Box.BoxSize;
cameraBox.z = z/Box.BoxSize;
}
// Считаю, что пора наладить рендер... так...
public function render():void {
view.graphics.clear(); // очищаем экран...
view.graphics.beginFill(0);
view.graphics.drawRect(0,0,viewW, viewH); // рисуем фон...
for(var i:int=0; i<viewBoxes.length; i++){ // Рисуем бокс для всез в массиве отображения...
viewBoxes[i].drawBoxOn(view,0xffffff,0xffffff);
}
}
}
}