※現在、「wonderfl build flash online」求人コンテンツ制作に関してのアンケートを実施中です!みなさまのお力添えを頂いて、続々とアンケート結果が集まっていますが、まだまだ募集しております。ご協力のほど、どうぞよろしくお願いいたします!
wonderfl運営事務局
→アンケートページ(※ログインしてからお答えいただけるようになっています。)
UpDownRoad forked from: UpDownRoad
- // forked from ABA's UpDownRoad
- // UpDownRoad.as
- // Display a 3d updown road with 3d particles.
- package
- {
- import flash.display.Sprite;
- import flash.display.BitmapData;
- import flash.display.Bitmap;
- import flash.geom.Rectangle;
- import flash.events.Event;
- [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
- public class UpDownRoad extends Sprite
- {
- private const SCREEN_WIDTH:int = 465;
- private const SCREEN_HEIGHT:int = 465;
- private const DRAWN_PARTICLES_MAX_COUNT:int = 2000;
- private const PROJECTION_RATIO:Number = 128;
- private const LOD_DISTANCE:Number = 200;
- private const MAX_DEPTH:Number = 500;
- private const ROAD_SPACING:Number = 5;
- private const ROAD_WIDTH:Number = 64;
- private const ROAD_HEIGHT:Number = 6;
- private const SIGHT_HEIGHT:Number = 30;
- private const BACKGROUND_BOX_SIZE:int = 16;
- private const BACKGROUND_R:int = 0x88;
- private const BACKGROUND_G:int = 0xcc;
- private const BACKGROUND_B:int = 0xff;
- private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
- private var rect:Rectangle = new Rectangle;
- private var roads:Vector.<Road> = new Vector.<Road>;
- private var particles:Vector.<Particle> = new Vector.<Particle>;
- private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
- private var dpIndex:int;
- private var viewpoint:Vector3 = new Vector3;
- private var yaw:Number, pitch:Number, roll:Number;
- private var offset:Vector3 = new Vector3;
- private var carPosIndex:Number;
- private var roadIndex:int;
- public function UpDownRoad()
- {
- addChild(new Bitmap(buffer));
- yaw = pitch = roll = 0;
- createRoad();
- for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
- drawnParticles.push(new DrawnParticle);
- carPosIndex = roads.length - 10;
- addEventListener(Event.ENTER_FRAME, onEnterFrame);
- }
- private function onEnterFrame(evt:Event):void
- {
- buffer.fillRect(buffer.rect, 0x99ffdd);
- carPosIndex += 1.7;
- if (carPosIndex >= roads.length)
- carPosIndex -= roads.length;
- var cpi:int = carPosIndex;
- var ncpi:int = carPosIndex + 1;
- if (ncpi >= roads.length)
- ncpi -= roads.length;
- var co:Number = carPosIndex - cpi;
- var rp:Vector3 = roads[cpi].pos;
- var nrp:Vector3 = roads[ncpi].pos;
- viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
- viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
- viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
- var oa:Number = roads[ncpi].angle - roads[cpi].angle;
- oa = normalizeAngle(oa);
- oa = roads[cpi].angle + oa * co - yaw;
- oa = normalizeAngle(oa);
- yaw += oa * 0.1;
- yaw = normalizeAngle(yaw);
- pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
- roll += (-oa * 0.7 - roll) * 0.1;
- drawBackground();
- dpIndex = 0;
- for each (var p:Particle in particles)
- drawParticle(p);
- drawnParticles.sort(sortOnZ);
- function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
- {
- if (v1.pos.z < v2.pos.z)
- return 1;
- else if (v1.pos.z > v2.pos.z)
- return -1;
- else
- return 0;
- }
- for (var i:int = 0; i < dpIndex; i++)
- {
- var dp:DrawnParticle = drawnParticles[i];
- rect.x = dp.pos.x - dp.width;
- rect.y = dp.pos.y - dp.height;
- rect.width = dp.width * 2;
- rect.height = dp.height * 2;
- buffer.fillRect(rect, dp.color);
- }
- }
- private function drawParticle(p:Particle):void
- {
- offset.x = p.pos.x - viewpoint.x;
- offset.y = p.pos.y - viewpoint.y;
- offset.z = p.pos.z - viewpoint.z;
- offset.rotationYaw(yaw);
- offset.rotationPitch(pitch);
- offset.rotationRoll(roll);
- if (offset.z < -10 || offset.z > MAX_DEPTH)
- return;
- if (p.detail != null && offset.length < LOD_DISTANCE)
- {
- for each (var pp:Particle in p.detail)
- drawParticle(pp);
- return;
- }
- if (offset.z < 1 || p.width <= 0)
- return;
- var ar:Number = 1.0 - offset.z / MAX_DEPTH;
- if (ar < 0)
- return;
- var dp:DrawnParticle = drawnParticles[dpIndex];
- var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
- dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
- dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
- dp.pos.z = offset.z;
- dp.width = p.width * zr;
- dp.height = p.height * zr;
- dp.color = createColor(p.r, p.g, p.b, 250 * ar);
- dpIndex++;
- }
- private function createColor(r:int, g:int, b:int, a:int):int
- {
- return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
- int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
- int((b * a + BACKGROUND_B * (256 - a)) / 256);
- }
- private function drawBackground():void
- {
- offset.x = 0;
- offset.y = 0;
- offset.z = 99999;
- offset.rotationPitch(pitch);
- var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
- var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
- var bx:Number, by:Number;
- var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
- var bh:Number, bby:Number;
- for (var j:int = 0; j < 3; j++)
- {
- switch (j)
- {
- case 0:
- {
- bh = 8;
- bby = 0;
- break;
- }
- case 1:
- {
- bh = 16;
- bby = 16;
- break;
- }
- case 2:
- {
- bh = SCREEN_HEIGHT / 3;
- bby = 48;
- break;
- }
- }
- bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
- by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
- rect.width = BACKGROUND_BOX_SIZE;
- rect.height = bh * 2;
- for (var i:int = 0; i < bc; i++)
- {
- rect.x = bx - BACKGROUND_BOX_SIZE / 2;
- rect.y = by - bh;
- buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
- bx += BACKGROUND_BOX_SIZE;
- by += vby;
- }
- }
- }
- private var roadPattern:Array = [20, 0, 0.2, 1, 16, 0, -3, 0, 16, 0, 3, 0, 80, 0.05, 0.05, 1, 90, 0, 0, 0, 80, -0.05, -1.0, 1, 20, 0, 1.75, 1];
- private function createRoad():void
- {
- var r:Road = new Road;
- var a:Number = 0;
- var ud:Number = roadPattern[2];
- r.angle = a;
- r.upDown = ud;
- var c:int;
- var ta:Number, tud:Number;
- var polePattern:int;
- var i:int;
- roadIndex = 0;
- for (i = 0; i < roadPattern.length; i += 4)
- {
- c = roadPattern[i];
- ta = roadPattern[i + 1];
- tud = roadPattern[i + 2];
- polePattern = roadPattern[i + 3];
- for (var j:int = 0; j < c; j++)
- {
- a += (ta - a) * 0.2;
- ud += (tud - ud) * 0.1;
- r.angle += a;
- r.angle = normalizeAngle(r.angle);
- r.upDown = ud;
- addRoadAndPole(r, polePattern);
- r = getNextRoad(r);
- }
- }
- c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
- var vrp:Vector3 = new Vector3;
- vrp.x = -r.pos.x / c;
- vrp.y = -r.pos.y / c;
- vrp.z = -r.pos.z / c;
- var va:Number = -r.angle / c;
- var vud:Number = -r.upDown / c;
- for (i = 0; i < c; i++)
- {
- addRoadAndPole(r, polePattern);
- var nr:Road = new Road;
- nr.pos.x = r.pos.x + vrp.x;
- nr.pos.y = r.pos.y + vrp.y;
- nr.pos.z = r.pos.z + vrp.z;
- nr.angle = r.angle + va;
- nr.upDown = r.upDown + vud;
- r = nr;
- }
- }
- private function addRoadAndPole(r:Road, polePattern:int):void
- {
- addRoadParticles(r);
- roads.push(r);
- if (polePattern > 0 && roadIndex % 7 == 0)
- {
- addPoleParticles(r);
- }
- roadIndex++;
- }
- private function getNextRoad(r:Road):Road
- {
- var nr:Road = new Road;
- nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
- nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
- nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
- nr.angle = r.angle;
- nr.upDown = r.upDown;
- return nr;
- }
- private function addRoadParticles(r:Road):void
- {
- for (var j:int = 0; j < 3; j++)
- {
- var p:Particle = new Particle;
- var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
- var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
- p.pos.x = r.pos.x + ox * (j - 1);
- p.pos.y = r.pos.y;
- p.pos.z = r.pos.z + oz * (j - 1);
- p.width = ROAD_WIDTH / 3 * 1.05;
- p.height = ROAD_HEIGHT;
- p.detail = new Vector.<Particle>;
- var pc:int = p.width / p.height + 2;
- ox = Math.cos(r.angle) * p.width / pc * 2;
- oz = -Math.sin(r.angle) * p.width / pc * 2;
- var c:int = 0;
- var i:int;
- var pp:Particle;
- for (i = 0; i < pc; i++)
- {
- pp = new Particle;
- pp.pos.x = p.pos.x + ox * (i - pc / 2);
- pp.pos.y = p.pos.y;
- pp.pos.z = p.pos.z + oz * (i - pc / 2);
- pp.width = pp.height = p.height;
- pp.r = pp.g = pp.b = 190 + Math.random() * 30;
- c += pp.r;
- pp.detail = null;
- p.detail.push(pp);
- }
- p.r = p.g = p.b = c / pc;
- particles.push(p);
- if (roadIndex % 3 == 0 && j != 1)
- {
- pp = new Particle;
- pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
- pp.pos.y = p.pos.y - p.height * 0.5;
- pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
- pp.width = p.height;
- pp.height = p.height * 0.6;
- pp.r = pp.g = pp.b = 32;
- pp.detail = null;
- particles.push(pp);
- }
- }
- }
- private function addPoleParticles(r:Road):void
- {
- for (var i:int = 0; i < 2; i++)
- {
- var p:Particle = new Particle;
- p.width = 4;
- p.height = 36;
- p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
- p.pos.y = r.pos.y - p.height / 2;
- p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
- p.r = 250; p.g = 60; p.b = 60;
- p.detail = new Vector.<Particle>;
- for (var j:int = 0; j < 8; j++)
- {
- var pp:Particle = new Particle;
- pp.pos.x = p.pos.x;
- pp.pos.y = p.pos.y - j * p.height / 8;
- pp.pos.z = p.pos.z;
- pp.width = p.width;
- pp.height = p.height / 8;
- pp.r = p.r;
- pp.g = p.g;
- pp.b = p.b;
- pp.detail = null;
- p.detail.push(pp);
- }
- particles.push(p);
- }
- }
- private function normalizeAngle(v:Number):Number {
- if (v > Math.PI)
- return v - Math.PI * 2;
- else if (v < -Math.PI)
- return v + Math.PI * 2;
- else
- return v;
- }
- }
- }
- class Road
- {
- public var pos:Vector3 = new Vector3;
- public var angle:Number, upDown:Number;
- }
- class Particle
- {
- public var pos:Vector3 = new Vector3;
- public var width:Number;
- public var height:Number;
- public var r:int, g:int, b:int;
- public var detail:Vector.<Particle>;
- }
- class DrawnParticle
- {
- public var pos:Vector3 = new Vector3;
- public var width:Number;
- public var height:Number;
- public var color:int;
- }
- class Vector3
- {
- public var x:Number = 0;
- public var y:Number = 0;
- public var z:Number = 0;
- public function rotationYaw(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var rx:Number = cv * x - sv * z;
- z = sv * x + cv * z;
- x = rx;
- }
- public function rotationPitch(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var ry:Number = cv * y - sv * z;
- z = sv * y + cv * z;
- y = ry;
- }
- public function rotationRoll(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var rx:Number = cv * x - sv * y;
- y = sv * x + cv * y;
- x = rx;
- }
- public function get length():Number
- {
- return Math.sqrt(x * x + y * y + z * z);
- }
- }
UpDownRoad forked from: UpDownRoad
- // forked from ABA's UpDownRoad
- // UpDownRoad.as
- // Display a 3d updown road with 3d particles.
- package
- {
- import flash.display.Sprite;
- import flash.display.BitmapData;
- import flash.display.Bitmap;
- import flash.geom.Rectangle;
- import flash.events.Event;
- [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
- public class UpDownRoad extends Sprite
- {
- private const SCREEN_WIDTH:int = 465;
- private const SCREEN_HEIGHT:int = 465;
- private const DRAWN_PARTICLES_MAX_COUNT:int = 2000;
- private const PROJECTION_RATIO:Number = 128;
- private const LOD_DISTANCE:Number = 200;
- private const MAX_DEPTH:Number = 500;
- private const ROAD_SPACING:Number = 5;
- private const ROAD_WIDTH:Number = 64;
- private const ROAD_HEIGHT:Number = 6;
- private const SIGHT_HEIGHT:Number = 30;
- private const BACKGROUND_BOX_SIZE:int = 16;
- private const BACKGROUND_R:int = 0x88;
- private const BACKGROUND_G:int = 0xcc;
- private const BACKGROUND_B:int = 0xff;
- private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
- private var rect:Rectangle = new Rectangle;
- private var roads:Vector.<Road> = new Vector.<Road>;
- private var particles:Vector.<Particle> = new Vector.<Particle>;
- private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
- private var dpIndex:int;
- private var viewpoint:Vector3 = new Vector3;
- private var yaw:Number, pitch:Number, roll:Number;
- private var offset:Vector3 = new Vector3;
- private var carPosIndex:Number;
- private var roadIndex:int;
- public function UpDownRoad()
- {
- addChild(new Bitmap(buffer));
- yaw = pitch = roll = 0;
- createRoad();
- for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
- drawnParticles.push(new DrawnParticle);
- carPosIndex = roads.length - 10;
- addEventListener(Event.ENTER_FRAME, onEnterFrame);
- }
- private function onEnterFrame(evt:Event):void
- {
- buffer.fillRect(buffer.rect, 0x99ffdd);
- carPosIndex += 1.7;
- if (carPosIndex >= roads.length)
- carPosIndex -= roads.length;
- var cpi:int = carPosIndex;
- var ncpi:int = carPosIndex + 1;
- if (ncpi >= roads.length)
- ncpi -= roads.length;
- var co:Number = carPosIndex - cpi;
- var rp:Vector3 = roads[cpi].pos;
- var nrp:Vector3 = roads[ncpi].pos;
- viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
- viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
- viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
- var oa:Number = roads[ncpi].angle - roads[cpi].angle;
- oa = normalizeAngle(oa);
- oa = roads[cpi].angle + oa * co - yaw;
- oa = normalizeAngle(oa);
- yaw += oa * 0.1;
- yaw = normalizeAngle(yaw);
- pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
- roll += (-oa * 0.7 - roll) * 0.1;
- drawBackground();
- dpIndex = 0;
- for each (var p:Particle in particles)
- drawParticle(p);
- drawnParticles.sort(sortOnZ);
- function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
- {
- if (v1.pos.z < v2.pos.z)
- return 1;
- else if (v1.pos.z > v2.pos.z)
- return -1;
- else
- return 0;
- }
- for (var i:int = 0; i < dpIndex; i++)
- {
- var dp:DrawnParticle = drawnParticles[i];
- rect.x = dp.pos.x - dp.width;
- rect.y = dp.pos.y - dp.height;
- rect.width = dp.width * 2;
- rect.height = dp.height * 2;
- buffer.fillRect(rect, dp.color);
- }
- }
- private function drawParticle(p:Particle):void
- {
- offset.x = p.pos.x - viewpoint.x;
- offset.y = p.pos.y - viewpoint.y;
- offset.z = p.pos.z - viewpoint.z;
- offset.rotationYaw(yaw);
- offset.rotationPitch(pitch);
- offset.rotationRoll(roll);
- if (offset.z < -10 || offset.z > MAX_DEPTH)
- return;
- if (p.detail != null && offset.length < LOD_DISTANCE)
- {
- for each (var pp:Particle in p.detail)
- drawParticle(pp);
- return;
- }
- if (offset.z < 1 || p.width <= 0)
- return;
- var ar:Number = 1.0 - offset.z / MAX_DEPTH;
- if (ar < 0)
- return;
- var dp:DrawnParticle = drawnParticles[dpIndex];
- var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
- dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
- dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
- dp.pos.z = offset.z;
- dp.width = p.width * zr;
- dp.height = p.height * zr;
- dp.color = createColor(p.r, p.g, p.b, 250 * ar);
- dpIndex++;
- }
- private function createColor(r:int, g:int, b:int, a:int):int
- {
- return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
- int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
- int((b * a + BACKGROUND_B * (256 - a)) / 256);
- }
- private function drawBackground():void
- {
- offset.x = 0;
- offset.y = 0;
- offset.z = 99999;
- offset.rotationPitch(pitch);
- var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
- var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
- var bx:Number, by:Number;
- var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
- var bh:Number, bby:Number;
- for (var j:int = 0; j < 3; j++)
- {
- switch (j)
- {
- case 0:
- {
- bh = 8;
- bby = 0;
- break;
- }
- case 1:
- {
- bh = 16;
- bby = 16;
- break;
- }
- case 2:
- {
- bh = SCREEN_HEIGHT / 3;
- bby = 48;
- break;
- }
- }
- bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
- by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
- rect.width = BACKGROUND_BOX_SIZE;
- rect.height = bh * 2;
- for (var i:int = 0; i < bc; i++)
- {
- rect.x = bx - BACKGROUND_BOX_SIZE / 2;
- rect.y = by - bh;
- buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
- bx += BACKGROUND_BOX_SIZE;
- by += vby;
- }
- }
- }
- private var roadPattern:Array = [20, 0, 0.2, 1, 16, 0, -3, 0, 16, 0, 3, 0, 80, 0.05, 0.05, 1, 90, 0, 0, 0, 80, -0.05, -1.0, 1, 20, 0, 1.75, 1];
- private function createRoad():void
- {
- var r:Road = new Road;
- var a:Number = 0;
- var ud:Number = roadPattern[2];
- r.angle = a;
- r.upDown = ud;
- var c:int;
- var ta:Number, tud:Number;
- var polePattern:int;
- var i:int;
- roadIndex = 0;
- for (i = 0; i < roadPattern.length; i += 4)
- {
- c = roadPattern[i];
- ta = roadPattern[i + 1];
- tud = roadPattern[i + 2];
- polePattern = roadPattern[i + 3];
- for (var j:int = 0; j < c; j++)
- {
- a += (ta - a) * 0.2;
- ud += (tud - ud) * 0.1;
- r.angle += a;
- r.angle = normalizeAngle(r.angle);
- r.upDown = ud;
- addRoadAndPole(r, polePattern);
- r = getNextRoad(r);
- }
- }
- c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
- var vrp:Vector3 = new Vector3;
- vrp.x = -r.pos.x / c;
- vrp.y = -r.pos.y / c;
- vrp.z = -r.pos.z / c;
- var va:Number = -r.angle / c;
- var vud:Number = -r.upDown / c;
- for (i = 0; i < c; i++)
- {
- addRoadAndPole(r, polePattern);
- var nr:Road = new Road;
- nr.pos.x = r.pos.x + vrp.x;
- nr.pos.y = r.pos.y + vrp.y;
- nr.pos.z = r.pos.z + vrp.z;
- nr.angle = r.angle + va;
- nr.upDown = r.upDown + vud;
- r = nr;
- }
- }
- private function addRoadAndPole(r:Road, polePattern:int):void
- {
- addRoadParticles(r);
- roads.push(r);
- if (polePattern > 0 && roadIndex % 7 == 0)
- {
- addPoleParticles(r);
- }
- roadIndex++;
- }
- private function getNextRoad(r:Road):Road
- {
- var nr:Road = new Road;
- nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
- nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
- nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
- nr.angle = r.angle;
- nr.upDown = r.upDown;
- return nr;
- }
- private function addRoadParticles(r:Road):void
- {
- for (var j:int = 0; j < 3; j++)
- {
- var p:Particle = new Particle;
- var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
- var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
- p.pos.x = r.pos.x + ox * (j - 1);
- p.pos.y = r.pos.y;
- p.pos.z = r.pos.z + oz * (j - 1);
- p.width = ROAD_WIDTH / 3 * 1.05;
- p.height = ROAD_HEIGHT;
- p.detail = new Vector.<Particle>;
- var pc:int = p.width / p.height + 2;
- ox = Math.cos(r.angle) * p.width / pc * 2;
- oz = -Math.sin(r.angle) * p.width / pc * 2;
- var c:int = 0;
- var i:int;
- var pp:Particle;
- for (i = 0; i < pc; i++)
- {
- pp = new Particle;
- pp.pos.x = p.pos.x + ox * (i - pc / 2);
- pp.pos.y = p.pos.y;
- pp.pos.z = p.pos.z + oz * (i - pc / 2);
- pp.width = pp.height = p.height;
- pp.r = pp.g = pp.b = 190 + Math.random() * 30;
- c += pp.r;
- pp.detail = null;
- p.detail.push(pp);
- }
- p.r = p.g = p.b = c / pc;
- particles.push(p);
- if (roadIndex % 3 == 0 && j != 1)
- {
- pp = new Particle;
- pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
- pp.pos.y = p.pos.y - p.height * 0.5;
- pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
- pp.width = p.height;
- pp.height = p.height * 0.6;
- pp.r = pp.g = pp.b = 32;
- pp.detail = null;
- particles.push(pp);
- }
- }
- }
- private function addPoleParticles(r:Road):void
- {
- for (var i:int = 0; i < 2; i++)
- {
- var p:Particle = new Particle;
- p.width = 4;
- p.height = 36;
- p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
- p.pos.y = r.pos.y - p.height / 2;
- p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
- p.r = 250; p.g = 60; p.b = 60;
- p.detail = new Vector.<Particle>;
- for (var j:int = 0; j < 8; j++)
- {
- var pp:Particle = new Particle;
- pp.pos.x = p.pos.x;
- pp.pos.y = p.pos.y - j * p.height / 8;
- pp.pos.z = p.pos.z;
- pp.width = p.width;
- pp.height = p.height / 8;
- pp.r = p.r;
- pp.g = p.g;
- pp.b = p.b;
- pp.detail = null;
- p.detail.push(pp);
- }
- particles.push(p);
- }
- }
- private function normalizeAngle(v:Number):Number {
- if (v > Math.PI)
- return v - Math.PI * 2;
- else if (v < -Math.PI)
- return v + Math.PI * 2;
- else
- return v;
- }
- }
- }
- class Road
- {
- public var pos:Vector3 = new Vector3;
- public var angle:Number, upDown:Number;
- }
- class Particle
- {
- public var pos:Vector3 = new Vector3;
- public var width:Number;
- public var height:Number;
- public var r:int, g:int, b:int;
- public var detail:Vector.<Particle>;
- }
- class DrawnParticle
- {
- public var pos:Vector3 = new Vector3;
- public var width:Number;
- public var height:Number;
- public var color:int;
- }
- class Vector3
- {
- public var x:Number = 0;
- public var y:Number = 0;
- public var z:Number = 0;
- public function rotationYaw(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var rx:Number = cv * x - sv * z;
- z = sv * x + cv * z;
- x = rx;
- }
- public function rotationPitch(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var ry:Number = cv * y - sv * z;
- z = sv * y + cv * z;
- y = ry;
- }
- public function rotationRoll(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var rx:Number = cv * x - sv * y;
- y = sv * x + cv * y;
- x = rx;
- }
- public function get length():Number
- {
- return Math.sqrt(x * x + y * y + z * z);
- }
- }
UpDownRoad forked from: UpDownRoad
- // forked from ABA's UpDownRoad
- // UpDownRoad.as
- // Display a 3d updown road with 3d particles.
- package
- {
- import flash.display.Sprite;
- import flash.display.BitmapData;
- import flash.display.Bitmap;
- import flash.geom.Rectangle;
- import flash.events.Event;
- [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
- public class UpDownRoad extends Sprite
- {
- private const SCREEN_WIDTH:int = 265;
- private const SCREEN_HEIGHT:int = 265;
- private const DRAWN_PARTICLES_MAX_COUNT:int = 5000;
- private const PROJECTION_RATIO:Number = 128;
- private const LOD_DISTANCE:Number = 200;
- private const MAX_DEPTH:Number = 500;
- private const ROAD_SPACING:Number = 3;
- private const ROAD_WIDTH:Number = 64;
- private const ROAD_HEIGHT:Number = 6;
- private const SIGHT_HEIGHT:Number = 30;
- private const BACKGROUND_BOX_SIZE:int = 16;
- private const BACKGROUND_R:int = 0x88;
- private const BACKGROUND_G:int = 0xcc;
- private const BACKGROUND_B:int = 0xff;
- private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
- private var rect:Rectangle = new Rectangle;
- private var roads:Vector.<Road> = new Vector.<Road>;
- private var particles:Vector.<Particle> = new Vector.<Particle>;
- private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
- private var dpIndex:int;
- private var viewpoint:Vector3 = new Vector3;
- private var yaw:Number, pitch:Number, roll:Number;
- private var offset:Vector3 = new Vector3;
- private var carPosIndex:Number;
- private var roadIndex:int;
- public function UpDownRoad()
- {
- addChild(new Bitmap(buffer));
- yaw = pitch = roll = 0;
- createRoad();
- for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
- drawnParticles.push(new DrawnParticle);
- carPosIndex = roads.length - 10;
- addEventListener(Event.ENTER_FRAME, onEnterFrame);
- }
- private function onEnterFrame(evt:Event):void
- {
- buffer.fillRect(buffer.rect, 0x99ffdd);
- carPosIndex += 1.7;
- if (carPosIndex >= roads.length)
- carPosIndex -= roads.length;
- var cpi:int = carPosIndex;
- var ncpi:int = carPosIndex + 1;
- if (ncpi >= roads.length)
- ncpi -= roads.length;
- var co:Number = carPosIndex - cpi;
- var rp:Vector3 = roads[cpi].pos;
- var nrp:Vector3 = roads[ncpi].pos;
- viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
- viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
- viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
- var oa:Number = roads[ncpi].angle - roads[cpi].angle;
- oa = normalizeAngle(oa);
- oa = roads[cpi].angle + oa * co - yaw;
- oa = normalizeAngle(oa);
- yaw += oa * 0.1;
- yaw = normalizeAngle(yaw);
- pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
- roll += (-oa * 0.7 - roll) * 0.1;
- drawBackground();
- dpIndex = 0;
- for each (var p:Particle in particles)
- drawParticle(p);
- drawnParticles.sort(sortOnZ);
- function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
- {
- if (v1.pos.z < v2.pos.z)
- return 1;
- else if (v1.pos.z > v2.pos.z)
- return -1;
- else
- return 0;
- }
- for (var i:int = 0; i < dpIndex; i++)
- {
- var dp:DrawnParticle = drawnParticles[i];
- rect.x = dp.pos.x - dp.width;
- rect.y = dp.pos.y - dp.height;
- rect.width = dp.width * 2;
- rect.height = dp.height * 2;
- buffer.fillRect(rect, dp.color);
- }
- }
- private function drawParticle(p:Particle):void
- {
- offset.x = p.pos.x - viewpoint.x;
- offset.y = p.pos.y - viewpoint.y;
- offset.z = p.pos.z - viewpoint.z;
- offset.rotationYaw(yaw);
- offset.rotationPitch(pitch);
- offset.rotationRoll(roll);
- if (offset.z < -10 || offset.z > MAX_DEPTH)
- return;
- if (p.detail != null && offset.length < LOD_DISTANCE)
- {
- for each (var pp:Particle in p.detail)
- drawParticle(pp);
- return;
- }
- if (offset.z < 1 || p.width <= 0)
- return;
- var ar:Number = 1.0 - offset.z / MAX_DEPTH;
- if (ar < 0)
- return;
- var dp:DrawnParticle = drawnParticles[dpIndex];
- var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
- dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
- dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
- dp.pos.z = offset.z;
- dp.width = p.width * zr;
- dp.height = p.height * zr;
- dp.color = createColor(p.r, p.g, p.b, 250 * ar);
- dpIndex++;
- }
- private function createColor(r:int, g:int, b:int, a:int):int
- {
- return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
- int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
- int((b * a + BACKGROUND_B * (256 - a)) / 256);
- }
- private function drawBackground():void
- {
- offset.x = 0;
- offset.y = 0;
- offset.z = 99999;
- offset.rotationPitch(pitch);
- var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
- var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
- var bx:Number, by:Number;
- var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
- var bh:Number, bby:Number;
- for (var j:int = 0; j < 3; j++)
- {
- switch (j)
- {
- case 0:
- {
- bh = 8;
- bby = 0;
- break;
- }
- case 1:
- {
- bh = 16;
- bby = 16;
- break;
- }
- case 2:
- {
- bh = SCREEN_HEIGHT / 3;
- bby = 48;
- break;
- }
- }
- bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
- by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
- rect.width = BACKGROUND_BOX_SIZE;
- rect.height = bh * 2;
- for (var i:int = 0; i < bc; i++)
- {
- rect.x = bx - BACKGROUND_BOX_SIZE / 2;
- rect.y = by - bh;
- buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
- bx += BACKGROUND_BOX_SIZE;
- by += vby;
- }
- }
- }
- private var roadPattern:Array = [20, 0, 0.2, 1, 16, 0, -3, 0, 16, 0, 3, 0, 80, 0.05, 0.05, 1, 90, 0, 0, 0, 80, -0.05, -1.0, 1, 20, 0, 1.75, 1];
- private function createRoad():void
- {
- var r:Road = new Road;
- var a:Number = 0;
- var ud:Number = roadPattern[2];
- r.angle = a;
- r.upDown = ud;
- var c:int;
- var ta:Number, tud:Number;
- var polePattern:int;
- var i:int;
- roadIndex = 0;
- for (i = 0; i < roadPattern.length; i += 4)
- {
- c = roadPattern[i];
- ta = roadPattern[i + 1];
- tud = roadPattern[i + 2];
- polePattern = roadPattern[i + 3];
- for (var j:int = 0; j < c; j++)
- {
- a += (ta - a) * 0.2;
- ud += (tud - ud) * 0.1;
- r.angle += a;
- r.angle = normalizeAngle(r.angle);
- r.upDown = ud;
- addRoadAndPole(r, polePattern);
- r = getNextRoad(r);
- }
- }
- c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
- var vrp:Vector3 = new Vector3;
- vrp.x = -r.pos.x / c;
- vrp.y = -r.pos.y / c;
- vrp.z = -r.pos.z / c;
- var va:Number = -r.angle / c;
- var vud:Number = -r.upDown / c;
- for (i = 0; i < c; i++)
- {
- addRoadAndPole(r, polePattern);
- var nr:Road = new Road;
- nr.pos.x = r.pos.x + vrp.x;
- nr.pos.y = r.pos.y + vrp.y;
- nr.pos.z = r.pos.z + vrp.z;
- nr.angle = r.angle + va;
- nr.upDown = r.upDown + vud;
- r = nr;
- }
- }
- private function addRoadAndPole(r:Road, polePattern:int):void
- {
- addRoadParticles(r);
- roads.push(r);
- if (polePattern > 0 && roadIndex % 7 == 0)
- {
- addPoleParticles(r);
- }
- roadIndex++;
- }
- private function getNextRoad(r:Road):Road
- {
- var nr:Road = new Road;
- nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
- nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
- nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
- nr.angle = r.angle;
- nr.upDown = r.upDown;
- return nr;
- }
- private function addRoadParticles(r:Road):void
- {
- for (var j:int = 0; j < 3; j++)
- {
- var p:Particle = new Particle;
- var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
- var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
- p.pos.x = r.pos.x + ox * (j - 1);
- p.pos.y = r.pos.y;
- p.pos.z = r.pos.z + oz * (j - 1);
- p.width = ROAD_WIDTH / 3 * 1.05;
- p.height = ROAD_HEIGHT;
- p.detail = new Vector.<Particle>;
- var pc:int = p.width / p.height + 2;
- ox = Math.cos(r.angle) * p.width / pc * 2;
- oz = -Math.sin(r.angle) * p.width / pc * 2;
- var c:int = 0;
- var i:int;
- var pp:Particle;
- for (i = 0; i < pc; i++)
- {
- pp = new Particle;
- pp.pos.x = p.pos.x + ox * (i - pc / 2);
- pp.pos.y = p.pos.y;
- pp.pos.z = p.pos.z + oz * (i - pc / 2);
- pp.width = pp.height = p.height;
- pp.r = pp.g = pp.b = 190 + Math.random() * 30;
- c += pp.r;
- pp.detail = null;
- p.detail.push(pp);
- }
- p.r = p.g = p.b = c / pc;
- particles.push(p);
- if (roadIndex % 3 == 0 && j != 1)
- {
- pp = new Particle;
- pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
- pp.pos.y = p.pos.y - p.height * 0.5;
- pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
- pp.width = p.height;
- pp.height = p.height * 0.6;
- pp.r = pp.g = pp.b = 32;
- pp.detail = null;
- particles.push(pp);
- }
- }
- }
- private function addPoleParticles(r:Road):void
- {
- for (var i:int = 0; i < 2; i++)
- {
- var p:Particle = new Particle;
- p.width = 4;
- p.height = 36;
- p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
- p.pos.y = r.pos.y - p.height / 2;
- p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
- p.r = 250; p.g = 60; p.b = 60;
- p.detail = new Vector.<Particle>;
- for (var j:int = 0; j < 8; j++)
- {
- var pp:Particle = new Particle;
- pp.pos.x = p.pos.x;
- pp.pos.y = p.pos.y - j * p.height / 8;
- pp.pos.z = p.pos.z;
- pp.width = p.width;
- pp.height = p.height / 8;
- pp.r = p.r;
- pp.g = p.g;
- pp.b = p.b;
- pp.detail = null;
- p.detail.push(pp);
- }
- particles.push(p);
- }
- }
- private function normalizeAngle(v:Number):Number {
- if (v > Math.PI)
- return v - Math.PI * 2;
- else if (v < -Math.PI)
- return v + Math.PI * 2;
- else
- return v;
- }
- }
- }
- class Road
- {
- public var pos:Vector3 = new Vector3;
- public var angle:Number, upDown:Number;
- }
- class Particle
- {
- public var pos:Vector3 = new Vector3;
- public var width:Number;
- public var height:Number;
- public var r:int, g:int, b:int;
- public var detail:Vector.<Particle>;
- }
- class DrawnParticle
- {
- public var pos:Vector3 = new Vector3;
- public var width:Number;
- public var height:Number;
- public var color:int;
- }
- class Vector3
- {
- public var x:Number = 0;
- public var y:Number = 0;
- public var z:Number = 0;
- public function rotationYaw(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var rx:Number = cv * x - sv * z;
- z = sv * x + cv * z;
- x = rx;
- }
- public function rotationPitch(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var ry:Number = cv * y - sv * z;
- z = sv * y + cv * z;
- y = ry;
- }
- public function rotationRoll(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var rx:Number = cv * x - sv * y;
- y = sv * x + cv * y;
- x = rx;
- }
- public function get length():Number
- {
- return Math.sqrt(x * x + y * y + z * z);
- }
- }
UpDownRoad forked from: UpDownRoad
- // forked from ABA's UpDownRoad
- // UpDownRoad.as
- // Display a 3d updown road with 3d particles.
- package
- {
- import flash.display.Sprite;
- import flash.display.BitmapData;
- import flash.display.Bitmap;
- import flash.geom.Rectangle;
- import flash.events.Event;
- [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
- public class UpDownRoad extends Sprite
- {
- private const SCREEN_WIDTH:int = 465;
- private const SCREEN_HEIGHT:int = 465;
- private const DRAWN_PARTICLES_MAX_COUNT:int = 2000;
- private const PROJECTION_RATIO:Number = 128;
- private const LOD_DISTANCE:Number = 200;
- private const MAX_DEPTH:Number = 500;
- private const ROAD_SPACING:Number = 5;
- private const ROAD_WIDTH:Number = 64;
- private const ROAD_HEIGHT:Number = 6;
- private const SIGHT_HEIGHT:Number = 30;
- private const BACKGROUND_BOX_SIZE:int = 16;
- private const BACKGROUND_R:int = 0x88;
- private const BACKGROUND_G:int = 0xcc;
- private const BACKGROUND_B:int = 0xff;
- private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
- private var rect:Rectangle = new Rectangle;
- private var roads:Vector.<Road> = new Vector.<Road>;
- private var particles:Vector.<Particle> = new Vector.<Particle>;
- private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
- private var dpIndex:int;
- private var viewpoint:Vector3 = new Vector3;
- private var yaw:Number, pitch:Number, roll:Number;
- private var offset:Vector3 = new Vector3;
- private var carPosIndex:Number;
- private var roadIndex:int;
- public function UpDownRoad()
- {
- addChild(new Bitmap(buffer));
- yaw = pitch = roll = 0;
- createRoad();
- for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
- drawnParticles.push(new DrawnParticle);
- carPosIndex = roads.length - 10;
- addEventListener(Event.ENTER_FRAME, onEnterFrame);
- }
- private function onEnterFrame(evt:Event):void
- {
- buffer.fillRect(buffer.rect, 0x99ffdd);
- carPosIndex += 1.7;
- if (carPosIndex >= roads.length)
- carPosIndex -= roads.length;
- var cpi:int = carPosIndex;
- var ncpi:int = carPosIndex + 1;
- if (ncpi >= roads.length)
- ncpi -= roads.length;
- var co:Number = carPosIndex - cpi;
- var rp:Vector3 = roads[cpi].pos;
- var nrp:Vector3 = roads[ncpi].pos;
- viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
- viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
- viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
- var oa:Number = roads[ncpi].angle - roads[cpi].angle;
- oa = normalizeAngle(oa);
- oa = roads[cpi].angle + oa * co - yaw;
- oa = normalizeAngle(oa);
- yaw += oa * 0.1;
- yaw = normalizeAngle(yaw);
- pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
- roll += (-oa * 0.7 - roll) * 0.1;
- drawBackground();
- dpIndex = 0;
- for each (var p:Particle in particles)
- drawParticle(p);
- drawnParticles.sort(sortOnZ);
- function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
- {
- if (v1.pos.z < v2.pos.z)
- return 1;
- else if (v1.pos.z > v2.pos.z)
- return -1;
- else
- return 0;
- }
- for (var i:int = 0; i < dpIndex; i++)
- {
- var dp:DrawnParticle = drawnParticles[i];
- rect.x = dp.pos.x - dp.width;
- rect.y = dp.pos.y - dp.height;
- rect.width = dp.width * 2;
- rect.height = dp.height * 2;
- buffer.fillRect(rect, dp.color);
- }
- }
- private function drawParticle(p:Particle):void
- {
- offset.x = p.pos.x - viewpoint.x;
- offset.y = p.pos.y - viewpoint.y;
- offset.z = p.pos.z - viewpoint.z;
- offset.rotationYaw(yaw);
- offset.rotationPitch(pitch);
- offset.rotationRoll(roll);
- if (offset.z < -10 || offset.z > MAX_DEPTH)
- return;
- if (p.detail != null && offset.length < LOD_DISTANCE)
- {
- for each (var pp:Particle in p.detail)
- drawParticle(pp);
- return;
- }
- if (offset.z < 1 || p.width <= 0)
- return;
- var ar:Number = 1.0 - offset.z / MAX_DEPTH;
- if (ar < 0)
- return;
- var dp:DrawnParticle = drawnParticles[dpIndex];
- var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
- dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
- dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
- dp.pos.z = offset.z;
- dp.width = p.width * zr;
- dp.height = p.height * zr;
- dp.color = createColor(p.r, p.g, p.b, 250 * ar);
- dpIndex++;
- }
- private function createColor(r:int, g:int, b:int, a:int):int
- {
- return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
- int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
- int((b * a + BACKGROUND_B * (256 - a)) / 256);
- }
- private function drawBackground():void
- {
- offset.x = 0;
- offset.y = 0;
- offset.z = 99999;
- offset.rotationPitch(pitch);
- var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
- var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
- var bx:Number, by:Number;
- var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
- var bh:Number, bby:Number;
- for (var j:int = 0; j < 3; j++)
- {
- switch (j)
- {
- case 0:
- {
- bh = 8;
- bby = 0;
- break;
- }
- case 1:
- {
- bh = 16;
- bby = 16;
- break;
- }
- case 2:
- {
- bh = SCREEN_HEIGHT / 3;
- bby = 48;
- break;
- }
- }
- bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
- by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
- rect.width = BACKGROUND_BOX_SIZE;
- rect.height = bh * 2;
- for (var i:int = 0; i < bc; i++)
- {
- rect.x = bx - BACKGROUND_BOX_SIZE / 2;
- rect.y = by - bh;
- buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
- bx += BACKGROUND_BOX_SIZE;
- by += vby;
- }
- }
- }
- private var roadPattern:Array = [2,0, 0.2, 1, 8, 0, -3, 0, 16, 0, 3, 0, 80, 0.05, 0.05, 1, 90, 0, 0, 0, 80, -0.05, -1.0, 1, 20, 0, 1.75, 1];
- private function createRoad():void
- {
- var r:Road = new Road;
- var a:Number = 0;
- var ud:Number = roadPattern[2];
- r.angle = a;
- r.upDown = ud;
- var c:int;
- var ta:Number, tud:Number;
- var polePattern:int;
- var i:int;
- roadIndex = 0;
- for (i = 0; i < roadPattern.length; i += 4)
- {
- c = roadPattern[i];
- ta = roadPattern[i + 1];
- tud = roadPattern[i + 2];
- polePattern = roadPattern[i + 3];
- for (var j:int = 0; j < c; j++)
- {
- a += (ta - a) * 0.2;
- ud += (tud - ud) * 0.1;
- r.angle += a;
- r.angle = normalizeAngle(r.angle);
- r.upDown = ud;
- addRoadAndPole(r, polePattern);
- r = getNextRoad(r);
- }
- }
- c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
- var vrp:Vector3 = new Vector3;
- vrp.x = -r.pos.x / c;
- vrp.y = -r.pos.y / c;
- vrp.z = -r.pos.z / c;
- var va:Number = -r.angle / c;
- var vud:Number = -r.upDown / c;
- for (i = 0; i < c; i++)
- {
- addRoadAndPole(r, polePattern);
- var nr:Road = new Road;
- nr.pos.x = r.pos.x + vrp.x;
- nr.pos.y = r.pos.y + vrp.y;
- nr.pos.z = r.pos.z + vrp.z;
- nr.angle = r.angle + va;
- nr.upDown = r.upDown + vud;
- r = nr;
- }
- }
- private function addRoadAndPole(r:Road, polePattern:int):void
- {
- addRoadParticles(r);
- roads.push(r);
- if (polePattern > 0 && roadIndex % 7 == 0)
- {
- addPoleParticles(r);
- }
- roadIndex++;
- }
- private function getNextRoad(r:Road):Road
- {
- var nr:Road = new Road;
- nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
- nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
- nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
- nr.angle = r.angle;
- nr.upDown = r.upDown;
- return nr;
- }
- private function addRoadParticles(r:Road):void
- {
- for (var j:int = 0; j < 3; j++)
- {
- var p:Particle = new Particle;
- var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
- var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
- p.pos.x = r.pos.x + ox * (j - 1);
- p.pos.y = r.pos.y;
- p.pos.z = r.pos.z + oz * (j - 1);
- p.width = ROAD_WIDTH / 3 * 1.05;
- p.height = ROAD_HEIGHT;
- p.detail = new Vector.<Particle>;
- var pc:int = p.width / p.height + 2;
- ox = Math.cos(r.angle) * p.width / pc * 2;
- oz = -Math.sin(r.angle) * p.width / pc * 2;
- var c:int = 0;
- var i:int;
- var pp:Particle;
- for (i = 0; i < pc; i++)
- {
- pp = new Particle;
- pp.pos.x = p.pos.x + ox * (i - pc / 2);
- pp.pos.y = p.pos.y;
- pp.pos.z = p.pos.z + oz * (i - pc / 2);
- pp.width = pp.height = p.height;
- pp.r = pp.g = pp.b = 190 + Math.random() * 30;
- c += pp.r;
- pp.detail = null;
- p.detail.push(pp);
- }
- p.r = p.g = p.b = c / pc;
- particles.push(p);
- if (roadIndex % 3 == 0 && j != 1)
- {
- pp = new Particle;
- pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
- pp.pos.y = p.pos.y - p.height * 0.5;
- pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
- pp.width = p.height;
- pp.height = p.height * 0.6;
- pp.r = pp.g = pp.b = 32;
- pp.detail = null;
- particles.push(pp);
- }
- }
- }
- private function addPoleParticles(r:Road):void
- {
- for (var i:int = 0; i < 2; i++)
- {
- var p:Particle = new Particle;
- p.width = 4;
- p.height = 36;
- p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
- p.pos.y = r.pos.y - p.height / 2;
- p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
- p.r = 250; p.g = 60; p.b = 60;
- p.detail = new Vector.<Particle>;
- for (var j:int = 0; j < 8; j++)
- {
- var pp:Particle = new Particle;
- pp.pos.x = p.pos.x;
- pp.pos.y = p.pos.y - j * p.height / 8;
- pp.pos.z = p.pos.z;
- pp.width = p.width;
- pp.height = p.height / 8;
- pp.r = p.r;
- pp.g = p.g;
- pp.b = p.b;
- pp.detail = null;
- p.detail.push(pp);
- }
- particles.push(p);
- }
- }
- private function normalizeAngle(v:Number):Number {
- if (v > Math.PI)
- return v - Math.PI * 2;
- else if (v < -Math.PI)
- return v + Math.PI * 2;
- else
- return v;
- }
- }
- }
- class Road
- {
- public var pos:Vector3 = new Vector3;
- public var angle:Number, upDown:Number;
- }
- class Particle
- {
- public var pos:Vector3 = new Vector3;
- public var width:Number;
- public var height:Number;
- public var r:int, g:int, b:int;
- public var detail:Vector.<Particle>;
- }
- class DrawnParticle
- {
- public var pos:Vector3 = new Vector3;
- public var width:Number;
- public var height:Number;
- public var color:int;
- }
- class Vector3
- {
- public var x:Number = 0;
- public var y:Number = 0;
- public var z:Number = 0;
- public function rotationYaw(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var rx:Number = cv * x - sv * z;
- z = sv * x + cv * z;
- x = rx;
- }
- public function rotationPitch(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var ry:Number = cv * y - sv * z;
- z = sv * y + cv * z;
- y = ry;
- }
- public function rotationRoll(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var rx:Number = cv * x - sv * y;
- y = sv * x + cv * y;
- x = rx;
- }
- public function get length():Number
- {
- return Math.sqrt(x * x + y * y + z * z);
- }
- }
UpDownRoad forked from: UpDownRoad
- // forked from ABA's UpDownRoad
- // UpDownRoad.as
- // Display a 3d updown road with 3d particles.
- package
- {
- import flash.display.Sprite;
- import flash.display.BitmapData;
- import flash.display.Bitmap;
- import flash.geom.Rectangle;
- import flash.events.Event;
- [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
- public class UpDownRoad extends Sprite
- {
- private const SCREEN_WIDTH:int = 465;
- private const SCREEN_HEIGHT:int = 465;
- private const DRAWN_PARTICLES_MAX_COUNT:int = 2000;
- private const PROJECTION_RATIO:Number = 128;
- private const LOD_DISTANCE:Number = 200;
- private const MAX_DEPTH:Number = 500;
- private const ROAD_SPACING:Number = 5;
- private const ROAD_WIDTH:Number = 64;
- private const ROAD_HEIGHT:Number = 6;
- private const SIGHT_HEIGHT:Number = 30;
- private const BACKGROUND_BOX_SIZE:int = 16;
- private const BACKGROUND_R:int = 0x88;
- private const BACKGROUND_G:int = 0xcc;
- private const BACKGROUND_B:int = 0xff;
- private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
- private var rect:Rectangle = new Rectangle;
- private var roads:Vector.<Road> = new Vector.<Road>;
- private var particles:Vector.<Particle> = new Vector.<Particle>;
- private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
- private var dpIndex:int;
- private var viewpoint:Vector3 = new Vector3;
- private var yaw:Number, pitch:Number, roll:Number;
- private var offset:Vector3 = new Vector3;
- private var carPosIndex:Number;
- private var roadIndex:int;
- public function UpDownRoad()
- {
- addChild(new Bitmap(buffer));
- yaw = pitch = roll = 0;
- createRoad();
- for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
- drawnParticles.push(new DrawnParticle);
- carPosIndex = roads.length - 10;
- addEventListener(Event.ENTER_FRAME, onEnterFrame);
- }
- private function onEnterFrame(evt:Event):void
- {
- buffer.fillRect(buffer.rect, 0x99ffdd);
- carPosIndex += 1.7;
- if (carPosIndex >= roads.length)
- carPosIndex -= roads.length;
- var cpi:int = carPosIndex;
- var ncpi:int = carPosIndex + 1;
- if (ncpi >= roads.length)
- ncpi -= roads.length;
- var co:Number = carPosIndex - cpi;
- var rp:Vector3 = roads[cpi].pos;
- var nrp:Vector3 = roads[ncpi].pos;
- viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
- viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
- viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
- var oa:Number = roads[ncpi].angle - roads[cpi].angle;
- oa = normalizeAngle(oa);
- oa = roads[cpi].angle + oa * co - yaw;
- oa = normalizeAngle(oa);
- yaw += oa * 0.1;
- yaw = normalizeAngle(yaw);
- pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
- roll += (-oa * 0.7 - roll) * 0.1;
- drawBackground();
- dpIndex = 0;
- for each (var p:Particle in particles)
- drawParticle(p);
- drawnParticles.sort(sortOnZ);
- function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
- {
- if (v1.pos.z < v2.pos.z)
- return 1;
- else if (v1.pos.z > v2.pos.z)
- return -1;
- else
- return 0;
- }
- for (var i:int = 0; i < dpIndex; i++)
- {
- var dp:DrawnParticle = drawnParticles[i];
- rect.x = dp.pos.x - dp.width;
- rect.y = dp.pos.y - dp.height;
- rect.width = dp.width * 2;
- rect.height = dp.height * 2;
- buffer.fillRect(rect, dp.color);
- }
- }
- private function drawParticle(p:Particle):void
- {
- offset.x = p.pos.x - viewpoint.x;
- offset.y = p.pos.y - viewpoint.y;
- offset.z = p.pos.z - viewpoint.z;
- offset.rotationYaw(yaw);
- offset.rotationPitch(pitch);
- offset.rotationRoll(roll);
- if (offset.z < -10 || offset.z > MAX_DEPTH)
- return;
- if (p.detail != null && offset.length < LOD_DISTANCE)
- {
- for each (var pp:Particle in p.detail)
- drawParticle(pp);
- return;
- }
- if (offset.z < 1 || p.width <= 0)
- return;
- var ar:Number = 1.0 - offset.z / MAX_DEPTH;
- if (ar < 0)
- return;
- var dp:DrawnParticle = drawnParticles[dpIndex];
- var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
- dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
- dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
- dp.pos.z = offset.z;
- dp.width = p.width * zr;
- dp.height = p.height * zr;
- dp.color = createColor(p.r, p.g, p.b, 250 * ar);
- dpIndex++;
- }
- private function createColor(r:int, g:int, b:int, a:int):int
- {
- return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
- int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
- int((b * a + BACKGROUND_B * (256 - a)) / 256);
- }
- private function drawBackground():void
- {
- offset.x = 0;
- offset.y = 0;
- offset.z = 99999;
- offset.rotationPitch(pitch);
- var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
- var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
- var bx:Number, by:Number;
- var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
- var bh:Number, bby:Number;
- for (var j:int = 0; j < 3; j++)
- {
- switch (j)
- {
- case 0:
- {
- bh = 8;
- bby = 0;
- break;
- }
- case 1:
- {
- bh = 16;
- bby = 16;
- break;
- }
- case 2:
- {
- bh = SCREEN_HEIGHT / 3;
- bby = 48;
- break;
- }
- }
- bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
- by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
- rect.width = BACKGROUND_BOX_SIZE;
- rect.height = bh * 2;
- for (var i:int = 0; i < bc; i++)
- {
- rect.x = bx - BACKGROUND_BOX_SIZE / 2;
- rect.y = by - bh;
- buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
- bx += BACKGROUND_BOX_SIZE;
- by += vby;
- }
- }
- }
- private var roadPattern:Array = [20, 0, 0.2, 1, 16, 0, -3, 0, 16, 0, 3, 0, 80, 0.05, 0.05, 1, 90, 0, 0, 0, 80, -0.05, -1.0, 1, 20, 0, 1.75, 1];
- private function createRoad():void
- {
- var r:Road = new Road;
- var a:Number = 0;
- var ud:Number = roadPattern[2];
- r.angle = a;
- r.upDown = ud;
- var c:int;
- var ta:Number, tud:Number;
- var polePattern:int;
- var i:int;
- roadIndex = 0;
- for (i = 0; i < roadPattern.length; i += 4)
- {
- c = roadPattern[i];
- ta = roadPattern[i + 1];
- tud = roadPattern[i + 2];
- polePattern = roadPattern[i + 3];
- for (var j:int = 0; j < c; j++)
- {
- a += (ta - a) * 0.2;
- ud += (tud - ud) * 0.1;
- r.angle += a;
- r.angle = normalizeAngle(r.angle);
- r.upDown = ud;
- addRoadAndPole(r, polePattern);
- r = getNextRoad(r);
- }
- }
- c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
- var vrp:Vector3 = new Vector3;
- vrp.x = -r.pos.x / c;
- vrp.y = -r.pos.y / c;
- vrp.z = -r.pos.z / c;
- var va:Number = -r.angle / c;
- var vud:Number = -r.upDown / c;
- for (i = 0; i < c; i++)
- {
- addRoadAndPole(r, polePattern);
- var nr:Road = new Road;
- nr.pos.x = r.pos.x + vrp.x;
- nr.pos.y = r.pos.y + vrp.y;
- nr.pos.z = r.pos.z + vrp.z;
- nr.angle = r.angle + va;
- nr.upDown = r.upDown + vud;
- r = nr;
- }
- }
- private function addRoadAndPole(r:Road, polePattern:int):void
- {
- addRoadParticles(r);
- roads.push(r);
- if (polePattern > 0 && roadIndex % 7 == 0)
- {
- addPoleParticles(r);
- }
- roadIndex++;
- }
- private function getNextRoad(r:Road):Road
- {
- var nr:Road = new Road;
- nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
- nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
- nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
- nr.angle = r.angle;
- nr.upDown = r.upDown;
- return nr;
- }
- private function addRoadParticles(r:Road):void
- {
- for (var j:int = 0; j < 3; j++)
- {
- var p:Particle = new Particle;
- var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
- var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
- p.pos.x = r.pos.x + ox * (j - 1);
- p.pos.y = r.pos.y;
- p.pos.z = r.pos.z + oz * (j - 1);
- p.width = ROAD_WIDTH / 3 * 1.05;
- p.height = ROAD_HEIGHT;
- p.detail = new Vector.<Particle>;
- var pc:int = p.width / p.height + 2;
- ox = Math.cos(r.angle) * p.width / pc * 2;
- oz = -Math.sin(r.angle) * p.width / pc * 2;
- var c:int = 0;
- var i:int;
- var pp:Particle;
- for (i = 0; i < pc; i++)
- {
- pp = new Particle;
- pp.pos.x = p.pos.x + ox * (i - pc / 2);
- pp.pos.y = p.pos.y;
- pp.pos.z = p.pos.z + oz * (i - pc / 2);
- pp.width = pp.height = p.height;
- pp.r = pp.g = pp.b = 190 + Math.random() * 30;
- c += pp.r;
- pp.detail = null;
- p.detail.push(pp);
- }
- p.r = p.g = p.b = c / pc;
- particles.push(p);
- if (roadIndex % 3 == 0 && j != 1)
- {
- pp = new Particle;
- pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
- pp.pos.y = p.pos.y - p.height * 0.5;
- pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
- pp.width = p.height;
- pp.height = p.height * 0.6;
- pp.r = pp.g = pp.b = 32;
- pp.detail = null;
- particles.push(pp);
- }
- }
- }
- private function addPoleParticles(r:Road):void
- {
- for (var i:int = 0; i < 2; i++)
- {
- var p:Particle = new Particle;
- p.width = 4;
- p.height = 36;
- p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
- p.pos.y = r.pos.y - p.height / 2;
- p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
- p.r = 250; p.g = 60; p.b = 60;
- p.detail = new Vector.<Particle>;
- for (var j:int = 0; j < 8; j++)
- {
- var pp:Particle = new Particle;
- pp.pos.x = p.pos.x;
- pp.pos.y = p.pos.y - j * p.height / 8;
- pp.pos.z = p.pos.z;
- pp.width = p.width;
- pp.height = p.height / 8;
- pp.r = p.r;
- pp.g = p.g;
- pp.b = p.b;
- pp.detail = null;
- p.detail.push(pp);
- }
- particles.push(p);
- }
- }
- private function normalizeAngle(v:Number):Number {
- if (v > Math.PI)
- return v - Math.PI * 2;
- else if (v < -Math.PI)
- return v + Math.PI * 2;
- else
- return v;
- }
- }
- }
- class Road
- {
- public var pos:Vector3 = new Vector3;
- public var angle:Number, upDown:Number;
- }
- class Particle
- {
- public var pos:Vector3 = new Vector3;
- public var width:Number;
- public var height:Number;
- public var r:int, g:int, b:int;
- public var detail:Vector.<Particle>;
- }
- class DrawnParticle
- {
- public var pos:Vector3 = new Vector3;
- public var width:Number;
- public var height:Number;
- public var color:int;
- }
- class Vector3
- {
- public var x:Number = 0;
- public var y:Number = 0;
- public var z:Number = 0;
- public function rotationYaw(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var rx:Number = cv * x - sv * z;
- z = sv * x + cv * z;
- x = rx;
- }
- public function rotationPitch(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var ry:Number = cv * y - sv * z;
- z = sv * y + cv * z;
- y = ry;
- }
- public function rotationRoll(v:Number):void
- {
- var sv:Number = Math.sin(v);
- var cv:Number = Math.cos(v);
- var rx:Number = cv * x - sv * y;
- y = sv * x + cv * y;
- x = rx;
- }
- public function get length():Number
- {
- return Math.sqrt(x * x + y * y + z * z);
- }
- }
notice: 



