※現在、「wonderfl build flash online」求人コンテンツ制作に関してのアンケートを実施中です!みなさまのお力添えを頂いて、続々とアンケート結果が集まっていますが、まだまだ募集しております。ご協力のほど、どうぞよろしくお願いいたします!

wonderfl運営事務局
→アンケートページ(※ログインしてからお答えいただけるようになっています。)

 notice: Flash editor updated! Join the development! Thanks to MiniBuilder


FAVORITE BY
:
RollerCoaster
:
3D track
:
コースエディタを誰かたのむ
:
全部fillRectで疑似3D。カッコイイ!
FORKED
  1. // forked from ABA's UpDownRoad
  2. // UpDownRoad.as
  3. //  Display a 3d updown road with 3d particles.
  4. package
  5. {
  6.   import flash.display.Sprite;
  7.   import flash.display.BitmapData;
  8.   import flash.display.Bitmap;
  9.   import flash.geom.Rectangle;
  10.   import flash.events.Event;
  11.   [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  12.   public class UpDownRoad extends Sprite
  13.   {
  14.     private const SCREEN_WIDTH:int = 465;
  15.     private const SCREEN_HEIGHT:int = 465;
  16.     private const DRAWN_PARTICLES_MAX_COUNT:int = 2000;
  17.     private const PROJECTION_RATIO:Number = 128;
  18.     private const LOD_DISTANCE:Number = 200;
  19.     private const MAX_DEPTH:Number = 500;
  20.     private const ROAD_SPACING:Number = 5;
  21.     private const ROAD_WIDTH:Number = 64;
  22.     private const ROAD_HEIGHT:Number = 6;
  23.     private const SIGHT_HEIGHT:Number = 30;
  24.     private const BACKGROUND_BOX_SIZE:int = 16;
  25.     private const BACKGROUND_R:int = 0x88;
  26.     private const BACKGROUND_G:int = 0xcc;
  27.     private const BACKGROUND_B:int = 0xff;
  28.     private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  29.     private var rect:Rectangle = new Rectangle;
  30.     private var roads:Vector.<Road> = new Vector.<Road>;
  31.     private var particles:Vector.<Particle> = new Vector.<Particle>;
  32.     private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
  33.     private var dpIndex:int;
  34.     private var viewpoint:Vector3 = new Vector3;
  35.     private var yaw:Number, pitch:Number, roll:Number;
  36.     private var offset:Vector3 = new Vector3;
  37.     private var carPosIndex:Number;
  38.     private var roadIndex:int;
  39.     public function UpDownRoad()
  40.     {
  41.       addChild(new Bitmap(buffer));
  42.       yaw = pitch = roll = 0;
  43.       createRoad();
  44.       for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
  45.         drawnParticles.push(new DrawnParticle);
  46.       carPosIndex = roads.length - 10;
  47.       addEventListener(Event.ENTER_FRAME, onEnterFrame);
  48.     }
  49.     private function onEnterFrame(evt:Event):void
  50.     {
  51.       buffer.fillRect(buffer.rect, 0x99ffdd);
  52.       carPosIndex += 1.7;
  53.       if (carPosIndex >= roads.length)
  54.         carPosIndex -= roads.length;
  55.       var cpi:int = carPosIndex;
  56.       var ncpi:int = carPosIndex + 1;
  57.       if (ncpi >= roads.length)
  58.         ncpi -= roads.length;
  59.       var co:Number = carPosIndex - cpi;
  60.       var rp:Vector3 = roads[cpi].pos;
  61.       var nrp:Vector3 = roads[ncpi].pos;
  62.       viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
  63.       viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
  64.       viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
  65.       var oa:Number = roads[ncpi].angle - roads[cpi].angle;
  66.       oa = normalizeAngle(oa);
  67.       oa = roads[cpi].angle + oa * co - yaw;
  68.       oa = normalizeAngle(oa);
  69.       yaw += oa * 0.1;
  70.       yaw = normalizeAngle(yaw);
  71.       pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
  72.       roll += (-oa * 0.7 - roll) * 0.1;
  73.       drawBackground();
  74.       dpIndex = 0;
  75.       for each (var p:Particle in particles)
  76.         drawParticle(p);
  77.       drawnParticles.sort(sortOnZ);
  78.       function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
  79.       {
  80.         if (v1.pos.z < v2.pos.z)
  81.           return 1;
  82.         else if (v1.pos.z > v2.pos.z)
  83.           return -1;
  84.         else
  85.           return 0;
  86.       }
  87.       for (var i:int = 0; i < dpIndex; i++)
  88.       {
  89.         var dp:DrawnParticle = drawnParticles[i];
  90.         rect.x = dp.pos.x - dp.width;
  91.         rect.y = dp.pos.y - dp.height;
  92.         rect.width = dp.width * 2;
  93.         rect.height = dp.height * 2;
  94.         buffer.fillRect(rect, dp.color);
  95.       }
  96.     }
  97.     private function drawParticle(p:Particle):void
  98.     {
  99.       offset.x = p.pos.x - viewpoint.x;
  100.       offset.y = p.pos.y - viewpoint.y;
  101.       offset.z = p.pos.z - viewpoint.z;
  102.       offset.rotationYaw(yaw);
  103.       offset.rotationPitch(pitch);
  104.       offset.rotationRoll(roll);
  105.       if (offset.z < -10 || offset.z > MAX_DEPTH)
  106.         return;
  107.       if (p.detail != null && offset.length < LOD_DISTANCE)
  108.       {
  109.         for each (var pp:Particle in p.detail)
  110.           drawParticle(pp);
  111.         return;
  112.       }
  113.       if (offset.z < 1 || p.width <= 0)
  114.         return;
  115.       var ar:Number = 1.0 - offset.z / MAX_DEPTH;
  116.       if (ar < 0)
  117.         return;
  118.       var dp:DrawnParticle = drawnParticles[dpIndex];
  119.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  120.       dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
  121.       dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
  122.       dp.pos.z = offset.z;
  123.       dp.width = p.width * zr;
  124.       dp.height = p.height * zr;
  125.       dp.color = createColor(p.r, p.g, p.b, 250 * ar);
  126.       dpIndex++;
  127.     }
  128.     private function createColor(r:int, g:int, b:int, a:int):int
  129.     {
  130.       return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
  131.              int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
  132.              int((b * a + BACKGROUND_B * (256 - a)) / 256);
  133.     }
  134.     private function drawBackground():void
  135.     {
  136.       offset.x = 0;
  137.       offset.y = 0;
  138.       offset.z = 99999;
  139.       offset.rotationPitch(pitch);
  140.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  141.       var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
  142.       var bx:Number, by:Number;
  143.       var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
  144.       var bh:Number, bby:Number;
  145.       for (var j:int = 0; j < 3; j++)
  146.       {
  147.         switch (j)
  148.         {
  149.           case 0:
  150.           {
  151.             bh = 8;
  152.             bby = 0;
  153.             break;
  154.           }
  155.           case 1:
  156.           {
  157.             bh = 16;
  158.             bby = 16;
  159.             break;
  160.           }
  161.           case 2:
  162.           {
  163.             bh = SCREEN_HEIGHT / 3;
  164.             bby = 48;
  165.             break;
  166.           }
  167.         }
  168.         bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
  169.         by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
  170.         rect.width = BACKGROUND_BOX_SIZE;
  171.         rect.height = bh * 2;
  172.         for (var i:int = 0; i < bc; i++)
  173.         {
  174.           rect.x = bx - BACKGROUND_BOX_SIZE / 2;
  175.           rect.y = by - bh;
  176.           buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
  177.           bx += BACKGROUND_BOX_SIZE;
  178.           by += vby;
  179.         }
  180.       }
  181.     }
  182.     private var roadPattern:Array = [2000.21160, -3016030800.050.0519000080, -0.05, -1.012001.751];
  183.     private function createRoad():void
  184.     {
  185.       var r:Road = new Road;
  186.       var a:Number = 0;
  187.       var ud:Number = roadPattern[2];
  188.       r.angle = a;
  189.       r.upDown = ud;
  190.       var c:int;
  191.       var ta:Number, tud:Number;
  192.       var polePattern:int;
  193.       var i:int;
  194.       roadIndex = 0;
  195.       for (i = 0; i < roadPattern.length; i += 4)
  196.       {
  197.         c = roadPattern[i];
  198.         ta = roadPattern[i + 1];
  199.         tud = roadPattern[i + 2];
  200.         polePattern = roadPattern[i + 3];
  201.         for (var j:int = 0; j < c; j++)
  202.         {
  203.           a += (ta - a) * 0.2;
  204.           ud += (tud - ud) * 0.1;
  205.           r.angle += a;
  206.           r.angle = normalizeAngle(r.angle);
  207.           r.upDown = ud;
  208.           addRoadAndPole(r, polePattern);
  209.           r = getNextRoad(r);
  210.         }
  211.       }
  212.       c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
  213.       var vrp:Vector3 = new Vector3;
  214.       vrp.x = -r.pos.x / c;
  215.       vrp.y = -r.pos.y / c;
  216.       vrp.z = -r.pos.z / c;
  217.       var va:Number = -r.angle / c;
  218.       var vud:Number = -r.upDown / c;
  219.       for (i = 0; i < c; i++)
  220.       {
  221.         addRoadAndPole(r, polePattern);
  222.         var nr:Road = new Road;
  223.         nr.pos.x = r.pos.x + vrp.x;
  224.         nr.pos.y = r.pos.y + vrp.y;
  225.         nr.pos.z = r.pos.z + vrp.z;
  226.         nr.angle = r.angle + va;
  227.         nr.upDown = r.upDown + vud;
  228.         r = nr;
  229.       }
  230.     }
  231.     private function addRoadAndPole(r:Road, polePattern:int):void
  232.     {
  233.       addRoadParticles(r);
  234.       roads.push(r);
  235.       if (polePattern > 0 && roadIndex % 7 == 0)
  236.       {
  237.         addPoleParticles(r);
  238.       }
  239.       roadIndex++;
  240.     }
  241.     private function getNextRoad(r:Road):Road
  242.     {
  243.       var nr:Road = new Road;
  244.       nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
  245.       nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
  246.       nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
  247.       nr.angle = r.angle;
  248.       nr.upDown = r.upDown;
  249.       return nr;
  250.     }
  251.     private function addRoadParticles(r:Road):void
  252.     {
  253.       for (var j:int = 0; j < 3; j++)
  254.       {
  255.         var p:Particle = new Particle;
  256.         var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
  257.         var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
  258.         p.pos.x = r.pos.x + ox * (j - 1);
  259.         p.pos.y = r.pos.y;
  260.         p.pos.z = r.pos.z + oz * (j - 1);
  261.         p.width = ROAD_WIDTH / 3 * 1.05;
  262.         p.height = ROAD_HEIGHT;
  263.         p.detail = new Vector.<Particle>;
  264.         var pc:int = p.width / p.height + 2;
  265.         ox = Math.cos(r.angle) * p.width / pc * 2;
  266.         oz = -Math.sin(r.angle) * p.width / pc * 2;
  267.         var c:int = 0;
  268.         var i:int;
  269.         var pp:Particle;
  270.         for (i = 0; i < pc; i++)
  271.         {
  272.           pp = new Particle;
  273.           pp.pos.x = p.pos.x + ox * (i - pc / 2);
  274.           pp.pos.y = p.pos.y;
  275.           pp.pos.z = p.pos.z + oz * (i - pc / 2);
  276.           pp.width = pp.height = p.height;
  277.           pp.r = pp.g = pp.b = 190 + Math.random() * 30;
  278.           c += pp.r;
  279.           pp.detail = null;
  280.           p.detail.push(pp);
  281.         }
  282.         p.r = p.g = p.b = c / pc;
  283.         particles.push(p);
  284.         if (roadIndex % 3 == 0 && j != 1)
  285.         {
  286.           pp = new Particle;
  287.           pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
  288.           pp.pos.y = p.pos.y - p.height * 0.5;
  289.           pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
  290.           pp.width = p.height;
  291.           pp.height = p.height * 0.6;
  292.           pp.r = pp.g = pp.b = 32;
  293.           pp.detail = null;
  294.           particles.push(pp);
  295.         }
  296.       }
  297.     }
  298.     private function addPoleParticles(r:Road):void
  299.     {
  300.       for (var i:int = 0; i < 2; i++)
  301.       {
  302.         var p:Particle = new Particle;
  303.         p.width = 4;
  304.         p.height = 36;
  305.         p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  306.         p.pos.y = r.pos.y - p.height / 2;
  307.         p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  308.         p.r = 250; p.g = 60; p.b = 60;
  309.         p.detail = new Vector.<Particle>;
  310.         for (var j:int = 0; j < 8; j++)
  311.         {
  312.           var pp:Particle = new Particle;
  313.           pp.pos.x = p.pos.x;
  314.           pp.pos.y = p.pos.y - j * p.height / 8;
  315.           pp.pos.z = p.pos.z;
  316.           pp.width = p.width;
  317.           pp.height = p.height / 8;
  318.           pp.r = p.r;
  319.           pp.g = p.g;
  320.           pp.b = p.b;
  321.           pp.detail = null;
  322.           p.detail.push(pp);
  323.         }
  324.         particles.push(p);
  325.       }
  326.     }
  327.     private function normalizeAngle(v:Number):Number {
  328.       if (v > Math.PI)
  329.         return v - Math.PI * 2;
  330.       else if (v < -Math.PI)
  331.         return v + Math.PI * 2;
  332.       else
  333.         return v;
  334.     }
  335.   }
  336. }
  337. class Road
  338. {
  339.   public var pos:Vector3 = new Vector3;
  340.   public var angle:Number, upDown:Number;
  341. }
  342. class Particle
  343. {
  344.   public var pos:Vector3 = new Vector3;
  345.   public var width:Number;
  346.   public var height:Number;
  347.   public var r:int, g:int, b:int;
  348.   public var detail:Vector.<Particle>;
  349. }
  350. class DrawnParticle
  351. {
  352.   public var pos:Vector3 = new Vector3;
  353.   public var width:Number;
  354.   public var height:Number;
  355.   public var color:int;
  356. }
  357. class Vector3
  358. {
  359.   public var x:Number = 0;
  360.   public var y:Number = 0;
  361.   public var z:Number = 0;
  362.   public function rotationYaw(v:Number):void
  363.   {
  364.     var sv:Number = Math.sin(v);
  365.     var cv:Number = Math.cos(v);
  366.     var rx:Number = cv * x - sv * z;
  367.     z = sv * x + cv * z;
  368.     x = rx;
  369.   }
  370.   public function rotationPitch(v:Number):void
  371.   {
  372.     var sv:Number = Math.sin(v);
  373.     var cv:Number = Math.cos(v);
  374.     var ry:Number = cv * y - sv * z;
  375.     z = sv * y + cv * z;
  376.     y = ry;
  377.   }
  378.   public function rotationRoll(v:Number):void
  379.   {
  380.     var sv:Number = Math.sin(v);
  381.     var cv:Number = Math.cos(v);
  382.     var rx:Number = cv * x - sv * y;
  383.     y = sv * x + cv * y;
  384.     x = rx;
  385.   }
  386.   public function get length():Number
  387.   {
  388.     return Math.sqrt(x * x + y * y + z * z);
  389.   }
  390. }
noswf
  1. // forked from ABA's UpDownRoad
  2. // UpDownRoad.as
  3. //  Display a 3d updown road with 3d particles.
  4. package
  5. {
  6.   import flash.display.Sprite;
  7.   import flash.display.BitmapData;
  8.   import flash.display.Bitmap;
  9.   import flash.geom.Rectangle;
  10.   import flash.events.Event;
  11.   [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  12.   public class UpDownRoad extends Sprite
  13.   {
  14.     private const SCREEN_WIDTH:int = 465;
  15.     private const SCREEN_HEIGHT:int = 465;
  16.     private const DRAWN_PARTICLES_MAX_COUNT:int = 2000;
  17.     private const PROJECTION_RATIO:Number = 128;
  18.     private const LOD_DISTANCE:Number = 200;
  19.     private const MAX_DEPTH:Number = 500;
  20.     private const ROAD_SPACING:Number = 5;
  21.     private const ROAD_WIDTH:Number = 64;
  22.     private const ROAD_HEIGHT:Number = 6;
  23.     private const SIGHT_HEIGHT:Number = 30;
  24.     private const BACKGROUND_BOX_SIZE:int = 16;
  25.     private const BACKGROUND_R:int = 0x88;
  26.     private const BACKGROUND_G:int = 0xcc;
  27.     private const BACKGROUND_B:int = 0xff;
  28.     private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  29.     private var rect:Rectangle = new Rectangle;
  30.     private var roads:Vector.<Road> = new Vector.<Road>;
  31.     private var particles:Vector.<Particle> = new Vector.<Particle>;
  32.     private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
  33.     private var dpIndex:int;
  34.     private var viewpoint:Vector3 = new Vector3;
  35.     private var yaw:Number, pitch:Number, roll:Number;
  36.     private var offset:Vector3 = new Vector3;
  37.     private var carPosIndex:Number;
  38.     private var roadIndex:int;
  39.     public function UpDownRoad()
  40.     {
  41.       addChild(new Bitmap(buffer));
  42.       yaw = pitch = roll = 0;
  43.       createRoad();
  44.       for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
  45.         drawnParticles.push(new DrawnParticle);
  46.       carPosIndex = roads.length - 10;
  47.       addEventListener(Event.ENTER_FRAME, onEnterFrame);
  48.     }
  49.     private function onEnterFrame(evt:Event):void
  50.     {
  51.       buffer.fillRect(buffer.rect, 0x99ffdd);
  52.       carPosIndex += 1.7;
  53.       if (carPosIndex >= roads.length)
  54.         carPosIndex -= roads.length;
  55.       var cpi:int = carPosIndex;
  56.       var ncpi:int = carPosIndex + 1;
  57.       if (ncpi >= roads.length)
  58.         ncpi -= roads.length;
  59.       var co:Number = carPosIndex - cpi;
  60.       var rp:Vector3 = roads[cpi].pos;
  61.       var nrp:Vector3 = roads[ncpi].pos;
  62.       viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
  63.       viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
  64.       viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
  65.       var oa:Number = roads[ncpi].angle - roads[cpi].angle;
  66.       oa = normalizeAngle(oa);
  67.       oa = roads[cpi].angle + oa * co - yaw;
  68.       oa = normalizeAngle(oa);
  69.       yaw += oa * 0.1;
  70.       yaw = normalizeAngle(yaw);
  71.       pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
  72.       roll += (-oa * 0.7 - roll) * 0.1;
  73.       drawBackground();
  74.       dpIndex = 0;
  75.       for each (var p:Particle in particles)
  76.         drawParticle(p);
  77.       drawnParticles.sort(sortOnZ);
  78.       function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
  79.       {
  80.         if (v1.pos.z < v2.pos.z)
  81.           return 1;
  82.         else if (v1.pos.z > v2.pos.z)
  83.           return -1;
  84.         else
  85.           return 0;
  86.       }
  87.       for (var i:int = 0; i < dpIndex; i++)
  88.       {
  89.         var dp:DrawnParticle = drawnParticles[i];
  90.         rect.x = dp.pos.x - dp.width;
  91.         rect.y = dp.pos.y - dp.height;
  92.         rect.width = dp.width * 2;
  93.         rect.height = dp.height * 2;
  94.         buffer.fillRect(rect, dp.color);
  95.       }
  96.     }
  97.     private function drawParticle(p:Particle):void
  98.     {
  99.       offset.x = p.pos.x - viewpoint.x;
  100.       offset.y = p.pos.y - viewpoint.y;
  101.       offset.z = p.pos.z - viewpoint.z;
  102.       offset.rotationYaw(yaw);
  103.       offset.rotationPitch(pitch);
  104.       offset.rotationRoll(roll);
  105.       if (offset.z < -10 || offset.z > MAX_DEPTH)
  106.         return;
  107.       if (p.detail != null && offset.length < LOD_DISTANCE)
  108.       {
  109.         for each (var pp:Particle in p.detail)
  110.           drawParticle(pp);
  111.         return;
  112.       }
  113.       if (offset.z < 1 || p.width <= 0)
  114.         return;
  115.       var ar:Number = 1.0 - offset.z / MAX_DEPTH;
  116.       if (ar < 0)
  117.         return;
  118.       var dp:DrawnParticle = drawnParticles[dpIndex];
  119.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  120.       dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
  121.       dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
  122.       dp.pos.z = offset.z;
  123.       dp.width = p.width * zr;
  124.       dp.height = p.height * zr;
  125.       dp.color = createColor(p.r, p.g, p.b, 250 * ar);
  126.       dpIndex++;
  127.     }
  128.     private function createColor(r:int, g:int, b:int, a:int):int
  129.     {
  130.       return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
  131.              int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
  132.              int((b * a + BACKGROUND_B * (256 - a)) / 256);
  133.     }
  134.     private function drawBackground():void
  135.     {
  136.       offset.x = 0;
  137.       offset.y = 0;
  138.       offset.z = 99999;
  139.       offset.rotationPitch(pitch);
  140.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  141.       var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
  142.       var bx:Number, by:Number;
  143.       var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
  144.       var bh:Number, bby:Number;
  145.       for (var j:int = 0; j < 3; j++)
  146.       {
  147.         switch (j)
  148.         {
  149.           case 0:
  150.           {
  151.             bh = 8;
  152.             bby = 0;
  153.             break;
  154.           }
  155.           case 1:
  156.           {
  157.             bh = 16;
  158.             bby = 16;
  159.             break;
  160.           }
  161.           case 2:
  162.           {
  163.             bh = SCREEN_HEIGHT / 3;
  164.             bby = 48;
  165.             break;
  166.           }
  167.         }
  168.         bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
  169.         by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
  170.         rect.width = BACKGROUND_BOX_SIZE;
  171.         rect.height = bh * 2;
  172.         for (var i:int = 0; i < bc; i++)
  173.         {
  174.           rect.x = bx - BACKGROUND_BOX_SIZE / 2;
  175.           rect.y = by - bh;
  176.           buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
  177.           bx += BACKGROUND_BOX_SIZE;
  178.           by += vby;
  179.         }
  180.       }
  181.     }
  182.     private var roadPattern:Array = [2000.21160, -3016030800.050.0519000080, -0.05, -1.012001.751];
  183.     private function createRoad():void
  184.     {
  185.       var r:Road = new Road;
  186.       var a:Number = 0;
  187.       var ud:Number = roadPattern[2];
  188.       r.angle = a;
  189.       r.upDown = ud;
  190.       var c:int;
  191.       var ta:Number, tud:Number;
  192.       var polePattern:int;
  193.       var i:int;
  194.       roadIndex = 0;
  195.       for (i = 0; i < roadPattern.length; i += 4)
  196.       {
  197.         c = roadPattern[i];
  198.         ta = roadPattern[i + 1];
  199.         tud = roadPattern[i + 2];
  200.         polePattern = roadPattern[i + 3];
  201.         for (var j:int = 0; j < c; j++)
  202.         {
  203.           a += (ta - a) * 0.2;
  204.           ud += (tud - ud) * 0.1;
  205.           r.angle += a;
  206.           r.angle = normalizeAngle(r.angle);
  207.           r.upDown = ud;
  208.           addRoadAndPole(r, polePattern);
  209.           r = getNextRoad(r);
  210.         }
  211.       }
  212.       c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
  213.       var vrp:Vector3 = new Vector3;
  214.       vrp.x = -r.pos.x / c;
  215.       vrp.y = -r.pos.y / c;
  216.       vrp.z = -r.pos.z / c;
  217.       var va:Number = -r.angle / c;
  218.       var vud:Number = -r.upDown / c;
  219.       for (i = 0; i < c; i++)
  220.       {
  221.         addRoadAndPole(r, polePattern);
  222.         var nr:Road = new Road;
  223.         nr.pos.x = r.pos.x + vrp.x;
  224.         nr.pos.y = r.pos.y + vrp.y;
  225.         nr.pos.z = r.pos.z + vrp.z;
  226.         nr.angle = r.angle + va;
  227.         nr.upDown = r.upDown + vud;
  228.         r = nr;
  229.       }
  230.     }
  231.     private function addRoadAndPole(r:Road, polePattern:int):void
  232.     {
  233.       addRoadParticles(r);
  234.       roads.push(r);
  235.       if (polePattern > 0 && roadIndex % 7 == 0)
  236.       {
  237.         addPoleParticles(r);
  238.       }
  239.       roadIndex++;
  240.     }
  241.     private function getNextRoad(r:Road):Road
  242.     {
  243.       var nr:Road = new Road;
  244.       nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
  245.       nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
  246.       nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
  247.       nr.angle = r.angle;
  248.       nr.upDown = r.upDown;
  249.       return nr;
  250.     }
  251.     private function addRoadParticles(r:Road):void
  252.     {
  253.       for (var j:int = 0; j < 3; j++)
  254.       {
  255.         var p:Particle = new Particle;
  256.         var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
  257.         var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
  258.         p.pos.x = r.pos.x + ox * (j - 1);
  259.         p.pos.y = r.pos.y;
  260.         p.pos.z = r.pos.z + oz * (j - 1);
  261.         p.width = ROAD_WIDTH / 3 * 1.05;
  262.         p.height = ROAD_HEIGHT;
  263.         p.detail = new Vector.<Particle>;
  264.         var pc:int = p.width / p.height + 2;
  265.         ox = Math.cos(r.angle) * p.width / pc * 2;
  266.         oz = -Math.sin(r.angle) * p.width / pc * 2;
  267.         var c:int = 0;
  268.         var i:int;
  269.         var pp:Particle;
  270.         for (i = 0; i < pc; i++)
  271.         {
  272.           pp = new Particle;
  273.           pp.pos.x = p.pos.x + ox * (i - pc / 2);
  274.           pp.pos.y = p.pos.y;
  275.           pp.pos.z = p.pos.z + oz * (i - pc / 2);
  276.           pp.width = pp.height = p.height;
  277.           pp.r = pp.g = pp.b = 190 + Math.random() * 30;
  278.           c += pp.r;
  279.           pp.detail = null;
  280.           p.detail.push(pp);
  281.         }
  282.         p.r = p.g = p.b = c / pc;
  283.         particles.push(p);
  284.         if (roadIndex % 3 == 0 && j != 1)
  285.         {
  286.           pp = new Particle;
  287.           pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
  288.           pp.pos.y = p.pos.y - p.height * 0.5;
  289.           pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
  290.           pp.width = p.height;
  291.           pp.height = p.height * 0.6;
  292.           pp.r = pp.g = pp.b = 32;
  293.           pp.detail = null;
  294.           particles.push(pp);
  295.         }
  296.       }
  297.     }
  298.     private function addPoleParticles(r:Road):void
  299.     {
  300.       for (var i:int = 0; i < 2; i++)
  301.       {
  302.         var p:Particle = new Particle;
  303.         p.width = 4;
  304.         p.height = 36;
  305.         p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  306.         p.pos.y = r.pos.y - p.height / 2;
  307.         p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  308.         p.r = 250; p.g = 60; p.b = 60;
  309.         p.detail = new Vector.<Particle>;
  310.         for (var j:int = 0; j < 8; j++)
  311.         {
  312.           var pp:Particle = new Particle;
  313.           pp.pos.x = p.pos.x;
  314.           pp.pos.y = p.pos.y - j * p.height / 8;
  315.           pp.pos.z = p.pos.z;
  316.           pp.width = p.width;
  317.           pp.height = p.height / 8;
  318.           pp.r = p.r;
  319.           pp.g = p.g;
  320.           pp.b = p.b;
  321.           pp.detail = null;
  322.           p.detail.push(pp);
  323.         }
  324.         particles.push(p);
  325.       }
  326.     }
  327.     private function normalizeAngle(v:Number):Number {
  328.       if (v > Math.PI)
  329.         return v - Math.PI * 2;
  330.       else if (v < -Math.PI)
  331.         return v + Math.PI * 2;
  332.       else
  333.         return v;
  334.     }
  335.   }
  336. }
  337. class Road
  338. {
  339.   public var pos:Vector3 = new Vector3;
  340.   public var angle:Number, upDown:Number;
  341. }
  342. class Particle
  343. {
  344.   public var pos:Vector3 = new Vector3;
  345.   public var width:Number;
  346.   public var height:Number;
  347.   public var r:int, g:int, b:int;
  348.   public var detail:Vector.<Particle>;
  349. }
  350. class DrawnParticle
  351. {
  352.   public var pos:Vector3 = new Vector3;
  353.   public var width:Number;
  354.   public var height:Number;
  355.   public var color:int;
  356. }
  357. class Vector3
  358. {
  359.   public var x:Number = 0;
  360.   public var y:Number = 0;
  361.   public var z:Number = 0;
  362.   public function rotationYaw(v:Number):void
  363.   {
  364.     var sv:Number = Math.sin(v);
  365.     var cv:Number = Math.cos(v);
  366.     var rx:Number = cv * x - sv * z;
  367.     z = sv * x + cv * z;
  368.     x = rx;
  369.   }
  370.   public function rotationPitch(v:Number):void
  371.   {
  372.     var sv:Number = Math.sin(v);
  373.     var cv:Number = Math.cos(v);
  374.     var ry:Number = cv * y - sv * z;
  375.     z = sv * y + cv * z;
  376.     y = ry;
  377.   }
  378.   public function rotationRoll(v:Number):void
  379.   {
  380.     var sv:Number = Math.sin(v);
  381.     var cv:Number = Math.cos(v);
  382.     var rx:Number = cv * x - sv * y;
  383.     y = sv * x + cv * y;
  384.     x = rx;
  385.   }
  386.   public function get length():Number
  387.   {
  388.     return Math.sqrt(x * x + y * y + z * z);
  389.   }
  390. }
noswf
  1. // forked from ABA's UpDownRoad
  2. // UpDownRoad.as
  3. //  Display a 3d updown road with 3d particles.
  4. package
  5. {
  6.   import flash.display.Sprite;
  7.   import flash.display.BitmapData;
  8.   import flash.display.Bitmap;
  9.   import flash.geom.Rectangle;
  10.   import flash.events.Event;
  11.   [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  12.   public class UpDownRoad extends Sprite
  13.   {
  14.     private const SCREEN_WIDTH:int = 265;
  15.     private const SCREEN_HEIGHT:int = 265;
  16.     private const DRAWN_PARTICLES_MAX_COUNT:int = 5000;
  17.     private const PROJECTION_RATIO:Number = 128;
  18.     private const LOD_DISTANCE:Number = 200;
  19.     private const MAX_DEPTH:Number = 500;
  20.     private const ROAD_SPACING:Number = 3;
  21.     private const ROAD_WIDTH:Number = 64;
  22.     private const ROAD_HEIGHT:Number = 6;
  23.     private const SIGHT_HEIGHT:Number = 30;
  24.     private const BACKGROUND_BOX_SIZE:int = 16;
  25.     private const BACKGROUND_R:int = 0x88;
  26.     private const BACKGROUND_G:int = 0xcc;
  27.     private const BACKGROUND_B:int = 0xff;
  28.     private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  29.     private var rect:Rectangle = new Rectangle;
  30.     private var roads:Vector.<Road> = new Vector.<Road>;
  31.     private var particles:Vector.<Particle> = new Vector.<Particle>;
  32.     private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
  33.     private var dpIndex:int;
  34.     private var viewpoint:Vector3 = new Vector3;
  35.     private var yaw:Number, pitch:Number, roll:Number;
  36.     private var offset:Vector3 = new Vector3;
  37.     private var carPosIndex:Number;
  38.     private var roadIndex:int;
  39.     public function UpDownRoad()
  40.     {
  41.       addChild(new Bitmap(buffer));
  42.       yaw = pitch = roll = 0;
  43.       createRoad();
  44.       for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
  45.         drawnParticles.push(new DrawnParticle);
  46.       carPosIndex = roads.length - 10;
  47.       addEventListener(Event.ENTER_FRAME, onEnterFrame);
  48.     }
  49.     private function onEnterFrame(evt:Event):void
  50.     {
  51.       buffer.fillRect(buffer.rect, 0x99ffdd);
  52.       carPosIndex += 1.7;
  53.       if (carPosIndex >= roads.length)
  54.         carPosIndex -= roads.length;
  55.       var cpi:int = carPosIndex;
  56.       var ncpi:int = carPosIndex + 1;
  57.       if (ncpi >= roads.length)
  58.         ncpi -= roads.length;
  59.       var co:Number = carPosIndex - cpi;
  60.       var rp:Vector3 = roads[cpi].pos;
  61.       var nrp:Vector3 = roads[ncpi].pos;
  62.       viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
  63.       viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
  64.       viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
  65.       var oa:Number = roads[ncpi].angle - roads[cpi].angle;
  66.       oa = normalizeAngle(oa);
  67.       oa = roads[cpi].angle + oa * co - yaw;
  68.       oa = normalizeAngle(oa);
  69.       yaw += oa * 0.1;
  70.       yaw = normalizeAngle(yaw);
  71.       pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
  72.       roll += (-oa * 0.7 - roll) * 0.1;
  73.       drawBackground();
  74.       dpIndex = 0;
  75.       for each (var p:Particle in particles)
  76.         drawParticle(p);
  77.       drawnParticles.sort(sortOnZ);
  78.       function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
  79.       {
  80.         if (v1.pos.z < v2.pos.z)
  81.           return 1;
  82.         else if (v1.pos.z > v2.pos.z)
  83.           return -1;
  84.         else
  85.           return 0;
  86.       }
  87.       for (var i:int = 0; i < dpIndex; i++)
  88.       {
  89.         var dp:DrawnParticle = drawnParticles[i];
  90.         rect.x = dp.pos.x - dp.width;
  91.         rect.y = dp.pos.y - dp.height;
  92.         rect.width = dp.width * 2;
  93.         rect.height = dp.height * 2;
  94.         buffer.fillRect(rect, dp.color);
  95.       }
  96.     }
  97.     private function drawParticle(p:Particle):void
  98.     {
  99.       offset.x = p.pos.x - viewpoint.x;
  100.       offset.y = p.pos.y - viewpoint.y;
  101.       offset.z = p.pos.z - viewpoint.z;
  102.       offset.rotationYaw(yaw);
  103.       offset.rotationPitch(pitch);
  104.       offset.rotationRoll(roll);
  105.       if (offset.z < -10 || offset.z > MAX_DEPTH)
  106.         return;
  107.       if (p.detail != null && offset.length < LOD_DISTANCE)
  108.       {
  109.         for each (var pp:Particle in p.detail)
  110.           drawParticle(pp);
  111.         return;
  112.       }
  113.       if (offset.z < 1 || p.width <= 0)
  114.         return;
  115.       var ar:Number = 1.0 - offset.z / MAX_DEPTH;
  116.       if (ar < 0)
  117.         return;
  118.       var dp:DrawnParticle = drawnParticles[dpIndex];
  119.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  120.       dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
  121.       dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
  122.       dp.pos.z = offset.z;
  123.       dp.width = p.width * zr;
  124.       dp.height = p.height * zr;
  125.       dp.color = createColor(p.r, p.g, p.b, 250 * ar);
  126.       dpIndex++;
  127.     }
  128.     private function createColor(r:int, g:int, b:int, a:int):int
  129.     {
  130.       return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
  131.              int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
  132.              int((b * a + BACKGROUND_B * (256 - a)) / 256);
  133.     }
  134.     private function drawBackground():void
  135.     {
  136.       offset.x = 0;
  137.       offset.y = 0;
  138.       offset.z = 99999;
  139.       offset.rotationPitch(pitch);
  140.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  141.       var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
  142.       var bx:Number, by:Number;
  143.       var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
  144.       var bh:Number, bby:Number;
  145.       for (var j:int = 0; j < 3; j++)
  146.       {
  147.         switch (j)
  148.         {
  149.           case 0:
  150.           {
  151.             bh = 8;
  152.             bby = 0;
  153.             break;
  154.           }
  155.           case 1:
  156.           {
  157.             bh = 16;
  158.             bby = 16;
  159.             break;
  160.           }
  161.           case 2:
  162.           {
  163.             bh = SCREEN_HEIGHT / 3;
  164.             bby = 48;
  165.             break;
  166.           }
  167.         }
  168.         bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
  169.         by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
  170.         rect.width = BACKGROUND_BOX_SIZE;
  171.         rect.height = bh * 2;
  172.         for (var i:int = 0; i < bc; i++)
  173.         {
  174.           rect.x = bx - BACKGROUND_BOX_SIZE / 2;
  175.           rect.y = by - bh;
  176.           buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
  177.           bx += BACKGROUND_BOX_SIZE;
  178.           by += vby;
  179.         }
  180.       }
  181.     }
  182.     private var roadPattern:Array = [2000.21160, -3016030800.050.0519000080, -0.05, -1.012001.751];
  183.     private function createRoad():void
  184.     {
  185.       var r:Road = new Road;
  186.       var a:Number = 0;
  187.       var ud:Number = roadPattern[2];
  188.       r.angle = a;
  189.       r.upDown = ud;
  190.       var c:int;
  191.       var ta:Number, tud:Number;
  192.       var polePattern:int;
  193.       var i:int;
  194.       roadIndex = 0;
  195.       for (i = 0; i < roadPattern.length; i += 4)
  196.       {
  197.         c = roadPattern[i];
  198.         ta = roadPattern[i + 1];
  199.         tud = roadPattern[i + 2];
  200.         polePattern = roadPattern[i + 3];
  201.         for (var j:int = 0; j < c; j++)
  202.         {
  203.           a += (ta - a) * 0.2;
  204.           ud += (tud - ud) * 0.1;
  205.           r.angle += a;
  206.           r.angle = normalizeAngle(r.angle);
  207.           r.upDown = ud;
  208.           addRoadAndPole(r, polePattern);
  209.           r = getNextRoad(r);
  210.         }
  211.       }
  212.       c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
  213.       var vrp:Vector3 = new Vector3;
  214.       vrp.x = -r.pos.x / c;
  215.       vrp.y = -r.pos.y / c;
  216.       vrp.z = -r.pos.z / c;
  217.       var va:Number = -r.angle / c;
  218.       var vud:Number = -r.upDown / c;
  219.       for (i = 0; i < c; i++)
  220.       {
  221.         addRoadAndPole(r, polePattern);
  222.         var nr:Road = new Road;
  223.         nr.pos.x = r.pos.x + vrp.x;
  224.         nr.pos.y = r.pos.y + vrp.y;
  225.         nr.pos.z = r.pos.z + vrp.z;
  226.         nr.angle = r.angle + va;
  227.         nr.upDown = r.upDown + vud;
  228.         r = nr;
  229.       }
  230.     }
  231.     private function addRoadAndPole(r:Road, polePattern:int):void
  232.     {
  233.       addRoadParticles(r);
  234.       roads.push(r);
  235.       if (polePattern > 0 && roadIndex % 7 == 0)
  236.       {
  237.         addPoleParticles(r);
  238.       }
  239.       roadIndex++;
  240.     }
  241.     private function getNextRoad(r:Road):Road
  242.     {
  243.       var nr:Road = new Road;
  244.       nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
  245.       nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
  246.       nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
  247.       nr.angle = r.angle;
  248.       nr.upDown = r.upDown;
  249.       return nr;
  250.     }
  251.     private function addRoadParticles(r:Road):void
  252.     {
  253.       for (var j:int = 0; j < 3; j++)
  254.       {
  255.         var p:Particle = new Particle;
  256.         var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
  257.         var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
  258.         p.pos.x = r.pos.x + ox * (j - 1);
  259.         p.pos.y = r.pos.y;
  260.         p.pos.z = r.pos.z + oz * (j - 1);
  261.         p.width = ROAD_WIDTH / 3 * 1.05;
  262.         p.height = ROAD_HEIGHT;
  263.         p.detail = new Vector.<Particle>;
  264.         var pc:int = p.width / p.height + 2;
  265.         ox = Math.cos(r.angle) * p.width / pc * 2;
  266.         oz = -Math.sin(r.angle) * p.width / pc * 2;
  267.         var c:int = 0;
  268.         var i:int;
  269.         var pp:Particle;
  270.         for (i = 0; i < pc; i++)
  271.         {
  272.           pp = new Particle;
  273.           pp.pos.x = p.pos.x + ox * (i - pc / 2);
  274.           pp.pos.y = p.pos.y;
  275.           pp.pos.z = p.pos.z + oz * (i - pc / 2);
  276.           pp.width = pp.height = p.height;
  277.           pp.r = pp.g = pp.b = 190 + Math.random() * 30;
  278.           c += pp.r;
  279.           pp.detail = null;
  280.           p.detail.push(pp);
  281.         }
  282.         p.r = p.g = p.b = c / pc;
  283.         particles.push(p);
  284.         if (roadIndex % 3 == 0 && j != 1)
  285.         {
  286.           pp = new Particle;
  287.           pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
  288.           pp.pos.y = p.pos.y - p.height * 0.5;
  289.           pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
  290.           pp.width = p.height;
  291.           pp.height = p.height * 0.6;
  292.           pp.r = pp.g = pp.b = 32;
  293.           pp.detail = null;
  294.           particles.push(pp);
  295.         }
  296.       }
  297.     }
  298.     private function addPoleParticles(r:Road):void
  299.     {
  300.       for (var i:int = 0; i < 2; i++)
  301.       {
  302.         var p:Particle = new Particle;
  303.         p.width = 4;
  304.         p.height = 36;
  305.         p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  306.         p.pos.y = r.pos.y - p.height / 2;
  307.         p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  308.         p.r = 250; p.g = 60; p.b = 60;
  309.         p.detail = new Vector.<Particle>;
  310.         for (var j:int = 0; j < 8; j++)
  311.         {
  312.           var pp:Particle = new Particle;
  313.           pp.pos.x = p.pos.x;
  314.           pp.pos.y = p.pos.y - j * p.height / 8;
  315.           pp.pos.z = p.pos.z;
  316.           pp.width = p.width;
  317.           pp.height = p.height / 8;
  318.           pp.r = p.r;
  319.           pp.g = p.g;
  320.           pp.b = p.b;
  321.           pp.detail = null;
  322.           p.detail.push(pp);
  323.         }
  324.         particles.push(p);
  325.       }
  326.     }
  327.     private function normalizeAngle(v:Number):Number {
  328.       if (v > Math.PI)
  329.         return v - Math.PI * 2;
  330.       else if (v < -Math.PI)
  331.         return v + Math.PI * 2;
  332.       else
  333.         return v;
  334.     }
  335.   }
  336. }
  337. class Road
  338. {
  339.   public var pos:Vector3 = new Vector3;
  340.   public var angle:Number, upDown:Number;
  341. }
  342. class Particle
  343. {
  344.   public var pos:Vector3 = new Vector3;
  345.   public var width:Number;
  346.   public var height:Number;
  347.   public var r:int, g:int, b:int;
  348.   public var detail:Vector.<Particle>;
  349. }
  350. class DrawnParticle
  351. {
  352.   public var pos:Vector3 = new Vector3;
  353.   public var width:Number;
  354.   public var height:Number;
  355.   public var color:int;
  356. }
  357. class Vector3
  358. {
  359.   public var x:Number = 0;
  360.   public var y:Number = 0;
  361.   public var z:Number = 0;
  362.   public function rotationYaw(v:Number):void
  363.   {
  364.     var sv:Number = Math.sin(v);
  365.     var cv:Number = Math.cos(v);
  366.     var rx:Number = cv * x - sv * z;
  367.     z = sv * x + cv * z;
  368.     x = rx;
  369.   }
  370.   public function rotationPitch(v:Number):void
  371.   {
  372.     var sv:Number = Math.sin(v);
  373.     var cv:Number = Math.cos(v);
  374.     var ry:Number = cv * y - sv * z;
  375.     z = sv * y + cv * z;
  376.     y = ry;
  377.   }
  378.   public function rotationRoll(v:Number):void
  379.   {
  380.     var sv:Number = Math.sin(v);
  381.     var cv:Number = Math.cos(v);
  382.     var rx:Number = cv * x - sv * y;
  383.     y = sv * x + cv * y;
  384.     x = rx;
  385.   }
  386.   public function get length():Number
  387.   {
  388.     return Math.sqrt(x * x + y * y + z * z);
  389.   }
  390. }
noswf
  1. // forked from ABA's UpDownRoad
  2. // UpDownRoad.as
  3. //  Display a 3d updown road with 3d particles.
  4. package
  5. {
  6.   import flash.display.Sprite;
  7.   import flash.display.BitmapData;
  8.   import flash.display.Bitmap;
  9.   import flash.geom.Rectangle;
  10.   import flash.events.Event;
  11.   [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  12.   public class UpDownRoad extends Sprite
  13.   {
  14.     private const SCREEN_WIDTH:int = 465;
  15.     private const SCREEN_HEIGHT:int = 465;
  16.     private const DRAWN_PARTICLES_MAX_COUNT:int = 2000;
  17.     private const PROJECTION_RATIO:Number = 128;
  18.     private const LOD_DISTANCE:Number = 200;
  19.     private const MAX_DEPTH:Number = 500;
  20.     private const ROAD_SPACING:Number = 5;
  21.     private const ROAD_WIDTH:Number = 64;
  22.     private const ROAD_HEIGHT:Number = 6;
  23.     private const SIGHT_HEIGHT:Number = 30;
  24.     private const BACKGROUND_BOX_SIZE:int = 16;
  25.     private const BACKGROUND_R:int = 0x88;
  26.     private const BACKGROUND_G:int = 0xcc;
  27.     private const BACKGROUND_B:int = 0xff;
  28.     private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  29.     private var rect:Rectangle = new Rectangle;
  30.     private var roads:Vector.<Road> = new Vector.<Road>;
  31.     private var particles:Vector.<Particle> = new Vector.<Particle>;
  32.     private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
  33.     private var dpIndex:int;
  34.     private var viewpoint:Vector3 = new Vector3;
  35.     private var yaw:Number, pitch:Number, roll:Number;
  36.     private var offset:Vector3 = new Vector3;
  37.     private var carPosIndex:Number;
  38.     private var roadIndex:int;
  39.     public function UpDownRoad()
  40.     {
  41.       addChild(new Bitmap(buffer));
  42.       yaw = pitch = roll = 0;
  43.       createRoad();
  44.       for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
  45.         drawnParticles.push(new DrawnParticle);
  46.       carPosIndex = roads.length - 10;
  47.       addEventListener(Event.ENTER_FRAME, onEnterFrame);
  48.     }
  49.     private function onEnterFrame(evt:Event):void
  50.     {
  51.       buffer.fillRect(buffer.rect, 0x99ffdd);
  52.       carPosIndex += 1.7;
  53.       if (carPosIndex >= roads.length)
  54.         carPosIndex -= roads.length;
  55.       var cpi:int = carPosIndex;
  56.       var ncpi:int = carPosIndex + 1;
  57.       if (ncpi >= roads.length)
  58.         ncpi -= roads.length;
  59.       var co:Number = carPosIndex - cpi;
  60.       var rp:Vector3 = roads[cpi].pos;
  61.       var nrp:Vector3 = roads[ncpi].pos;
  62.       viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
  63.       viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
  64.       viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
  65.       var oa:Number = roads[ncpi].angle - roads[cpi].angle;
  66.       oa = normalizeAngle(oa);
  67.       oa = roads[cpi].angle + oa * co - yaw;
  68.       oa = normalizeAngle(oa);
  69.       yaw += oa * 0.1;
  70.       yaw = normalizeAngle(yaw);
  71.       pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
  72.       roll += (-oa * 0.7 - roll) * 0.1;
  73.       drawBackground();
  74.       dpIndex = 0;
  75.       for each (var p:Particle in particles)
  76.         drawParticle(p);
  77.       drawnParticles.sort(sortOnZ);
  78.       function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
  79.       {
  80.         if (v1.pos.z < v2.pos.z)
  81.           return 1;
  82.         else if (v1.pos.z > v2.pos.z)
  83.           return -1;
  84.         else
  85.           return 0;
  86.       }
  87.       for (var i:int = 0; i < dpIndex; i++)
  88.       {
  89.         var dp:DrawnParticle = drawnParticles[i];
  90.         rect.x = dp.pos.x - dp.width;
  91.         rect.y = dp.pos.y - dp.height;
  92.         rect.width = dp.width * 2;
  93.         rect.height = dp.height * 2;
  94.         buffer.fillRect(rect, dp.color);
  95.       }
  96.     }
  97.     private function drawParticle(p:Particle):void
  98.     {
  99.       offset.x = p.pos.x - viewpoint.x;
  100.       offset.y = p.pos.y - viewpoint.y;
  101.       offset.z = p.pos.z - viewpoint.z;
  102.       offset.rotationYaw(yaw);
  103.       offset.rotationPitch(pitch);
  104.       offset.rotationRoll(roll);
  105.       if (offset.z < -10 || offset.z > MAX_DEPTH)
  106.         return;
  107.       if (p.detail != null && offset.length < LOD_DISTANCE)
  108.       {
  109.         for each (var pp:Particle in p.detail)
  110.           drawParticle(pp);
  111.         return;
  112.       }
  113.       if (offset.z < 1 || p.width <= 0)
  114.         return;
  115.       var ar:Number = 1.0 - offset.z / MAX_DEPTH;
  116.       if (ar < 0)
  117.         return;
  118.       var dp:DrawnParticle = drawnParticles[dpIndex];
  119.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  120.       dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
  121.       dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
  122.       dp.pos.z = offset.z;
  123.       dp.width = p.width * zr;
  124.       dp.height = p.height * zr;
  125.       dp.color = createColor(p.r, p.g, p.b, 250 * ar);
  126.       dpIndex++;
  127.     }
  128.     private function createColor(r:int, g:int, b:int, a:int):int
  129.     {
  130.       return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
  131.              int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
  132.              int((b * a + BACKGROUND_B * (256 - a)) / 256);
  133.     }
  134.     private function drawBackground():void
  135.     {
  136.       offset.x = 0;
  137.       offset.y = 0;
  138.       offset.z = 99999;
  139.       offset.rotationPitch(pitch);
  140.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  141.       var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
  142.       var bx:Number, by:Number;
  143.       var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
  144.       var bh:Number, bby:Number;
  145.       for (var j:int = 0; j < 3; j++)
  146.       {
  147.         switch (j)
  148.         {
  149.           case 0:
  150.           {
  151.             bh = 8;
  152.             bby = 0;
  153.             break;
  154.           }
  155.           case 1:
  156.           {
  157.             bh = 16;
  158.             bby = 16;
  159.             break;
  160.           }
  161.           case 2:
  162.           {
  163.             bh = SCREEN_HEIGHT / 3;
  164.             bby = 48;
  165.             break;
  166.           }
  167.         }
  168.         bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
  169.         by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
  170.         rect.width = BACKGROUND_BOX_SIZE;
  171.         rect.height = bh * 2;
  172.         for (var i:int = 0; i < bc; i++)
  173.         {
  174.           rect.x = bx - BACKGROUND_BOX_SIZE / 2;
  175.           rect.y = by - bh;
  176.           buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
  177.           bx += BACKGROUND_BOX_SIZE;
  178.           by += vby;
  179.         }
  180.       }
  181.     }
  182.     private var roadPattern:Array = [2,00.2180, -3016030800.050.0519000080, -0.05, -1.012001.751];
  183.     private function createRoad():void
  184.     {
  185.       var r:Road = new Road;
  186.       var a:Number = 0;
  187.       var ud:Number = roadPattern[2];
  188.       r.angle = a;
  189.       r.upDown = ud;
  190.       var c:int;
  191.       var ta:Number, tud:Number;
  192.       var polePattern:int;
  193.       var i:int;
  194.       roadIndex = 0;
  195.       for (i = 0; i < roadPattern.length; i += 4)
  196.       {
  197.         c = roadPattern[i];
  198.         ta = roadPattern[i + 1];
  199.         tud = roadPattern[i + 2];
  200.         polePattern = roadPattern[i + 3];
  201.         for (var j:int = 0; j < c; j++)
  202.         {
  203.           a += (ta - a) * 0.2;
  204.           ud += (tud - ud) * 0.1;
  205.           r.angle += a;
  206.           r.angle = normalizeAngle(r.angle);
  207.           r.upDown = ud;
  208.           addRoadAndPole(r, polePattern);
  209.           r = getNextRoad(r);
  210.         }
  211.       }
  212.       c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
  213.       var vrp:Vector3 = new Vector3;
  214.       vrp.x = -r.pos.x / c;
  215.       vrp.y = -r.pos.y / c;
  216.       vrp.z = -r.pos.z / c;
  217.       var va:Number = -r.angle / c;
  218.       var vud:Number = -r.upDown / c;
  219.       for (i = 0; i < c; i++)
  220.       {
  221.         addRoadAndPole(r, polePattern);
  222.         var nr:Road = new Road;
  223.         nr.pos.x = r.pos.x + vrp.x;
  224.         nr.pos.y = r.pos.y + vrp.y;
  225.         nr.pos.z = r.pos.z + vrp.z;
  226.         nr.angle = r.angle + va;
  227.         nr.upDown = r.upDown + vud;
  228.         r = nr;
  229.       }
  230.     }
  231.     private function addRoadAndPole(r:Road, polePattern:int):void
  232.     {
  233.       addRoadParticles(r);
  234.       roads.push(r);
  235.       if (polePattern > 0 && roadIndex % 7 == 0)
  236.       {
  237.         addPoleParticles(r);
  238.       }
  239.       roadIndex++;
  240.     }
  241.     private function getNextRoad(r:Road):Road
  242.     {
  243.       var nr:Road = new Road;
  244.       nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
  245.       nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
  246.       nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
  247.       nr.angle = r.angle;
  248.       nr.upDown = r.upDown;
  249.       return nr;
  250.     }
  251.     private function addRoadParticles(r:Road):void
  252.     {
  253.       for (var j:int = 0; j < 3; j++)
  254.       {
  255.         var p:Particle = new Particle;
  256.         var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
  257.         var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
  258.         p.pos.x = r.pos.x + ox * (j - 1);
  259.         p.pos.y = r.pos.y;
  260.         p.pos.z = r.pos.z + oz * (j - 1);
  261.         p.width = ROAD_WIDTH / 3 * 1.05;
  262.         p.height = ROAD_HEIGHT;
  263.         p.detail = new Vector.<Particle>;
  264.         var pc:int = p.width / p.height + 2;
  265.         ox = Math.cos(r.angle) * p.width / pc * 2;
  266.         oz = -Math.sin(r.angle) * p.width / pc * 2;
  267.         var c:int = 0;
  268.         var i:int;
  269.         var pp:Particle;
  270.         for (i = 0; i < pc; i++)
  271.         {
  272.           pp = new Particle;
  273.           pp.pos.x = p.pos.x + ox * (i - pc / 2);
  274.           pp.pos.y = p.pos.y;
  275.           pp.pos.z = p.pos.z + oz * (i - pc / 2);
  276.           pp.width = pp.height = p.height;
  277.           pp.r = pp.g = pp.b = 190 + Math.random() * 30;
  278.           c += pp.r;
  279.           pp.detail = null;
  280.           p.detail.push(pp);
  281.         }
  282.         p.r = p.g = p.b = c / pc;
  283.         particles.push(p);
  284.         if (roadIndex % 3 == 0 && j != 1)
  285.         {
  286.           pp = new Particle;
  287.           pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
  288.           pp.pos.y = p.pos.y - p.height * 0.5;
  289.           pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
  290.           pp.width = p.height;
  291.           pp.height = p.height * 0.6;
  292.           pp.r = pp.g = pp.b = 32;
  293.           pp.detail = null;
  294.           particles.push(pp);
  295.         }
  296.       }
  297.     }
  298.     private function addPoleParticles(r:Road):void
  299.     {
  300.       for (var i:int = 0; i < 2; i++)
  301.       {
  302.         var p:Particle = new Particle;
  303.         p.width = 4;
  304.         p.height = 36;
  305.         p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  306.         p.pos.y = r.pos.y - p.height / 2;
  307.         p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  308.         p.r = 250; p.g = 60; p.b = 60;
  309.         p.detail = new Vector.<Particle>;
  310.         for (var j:int = 0; j < 8; j++)
  311.         {
  312.           var pp:Particle = new Particle;
  313.           pp.pos.x = p.pos.x;
  314.           pp.pos.y = p.pos.y - j * p.height / 8;
  315.           pp.pos.z = p.pos.z;
  316.           pp.width = p.width;
  317.           pp.height = p.height / 8;
  318.           pp.r = p.r;
  319.           pp.g = p.g;
  320.           pp.b = p.b;
  321.           pp.detail = null;
  322.           p.detail.push(pp);
  323.         }
  324.         particles.push(p);
  325.       }
  326.     }
  327.     private function normalizeAngle(v:Number):Number {
  328.       if (v > Math.PI)
  329.         return v - Math.PI * 2;
  330.       else if (v < -Math.PI)
  331.         return v + Math.PI * 2;
  332.       else
  333.         return v;
  334.     }
  335.   }
  336. }
  337. class Road
  338. {
  339.   public var pos:Vector3 = new Vector3;
  340.   public var angle:Number, upDown:Number;
  341. }
  342. class Particle
  343. {
  344.   public var pos:Vector3 = new Vector3;
  345.   public var width:Number;
  346.   public var height:Number;
  347.   public var r:int, g:int, b:int;
  348.   public var detail:Vector.<Particle>;
  349. }
  350. class DrawnParticle
  351. {
  352.   public var pos:Vector3 = new Vector3;
  353.   public var width:Number;
  354.   public var height:Number;
  355.   public var color:int;
  356. }
  357. class Vector3
  358. {
  359.   public var x:Number = 0;
  360.   public var y:Number = 0;
  361.   public var z:Number = 0;
  362.   public function rotationYaw(v:Number):void
  363.   {
  364.     var sv:Number = Math.sin(v);
  365.     var cv:Number = Math.cos(v);
  366.     var rx:Number = cv * x - sv * z;
  367.     z = sv * x + cv * z;
  368.     x = rx;
  369.   }
  370.   public function rotationPitch(v:Number):void
  371.   {
  372.     var sv:Number = Math.sin(v);
  373.     var cv:Number = Math.cos(v);
  374.     var ry:Number = cv * y - sv * z;
  375.     z = sv * y + cv * z;
  376.     y = ry;
  377.   }
  378.   public function rotationRoll(v:Number):void
  379.   {
  380.     var sv:Number = Math.sin(v);
  381.     var cv:Number = Math.cos(v);
  382.     var rx:Number = cv * x - sv * y;
  383.     y = sv * x + cv * y;
  384.     x = rx;
  385.   }
  386.   public function get length():Number
  387.   {
  388.     return Math.sqrt(x * x + y * y + z * z);
  389.   }
  390. }
noswf
  1. // forked from ABA's UpDownRoad
  2. // UpDownRoad.as
  3. //  Display a 3d updown road with 3d particles.
  4. package
  5. {
  6.   import flash.display.Sprite;
  7.   import flash.display.BitmapData;
  8.   import flash.display.Bitmap;
  9.   import flash.geom.Rectangle;
  10.   import flash.events.Event;
  11.   [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  12.   public class UpDownRoad extends Sprite
  13.   {
  14.     private const SCREEN_WIDTH:int = 465;
  15.     private const SCREEN_HEIGHT:int = 465;
  16.     private const DRAWN_PARTICLES_MAX_COUNT:int = 2000;
  17.     private const PROJECTION_RATIO:Number = 128;
  18.     private const LOD_DISTANCE:Number = 200;
  19.     private const MAX_DEPTH:Number = 500;
  20.     private const ROAD_SPACING:Number = 5;
  21.     private const ROAD_WIDTH:Number = 64;
  22.     private const ROAD_HEIGHT:Number = 6;
  23.     private const SIGHT_HEIGHT:Number = 30;
  24.     private const BACKGROUND_BOX_SIZE:int = 16;
  25.     private const BACKGROUND_R:int = 0x88;
  26.     private const BACKGROUND_G:int = 0xcc;
  27.     private const BACKGROUND_B:int = 0xff;
  28.     private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  29.     private var rect:Rectangle = new Rectangle;
  30.     private var roads:Vector.<Road> = new Vector.<Road>;
  31.     private var particles:Vector.<Particle> = new Vector.<Particle>;
  32.     private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
  33.     private var dpIndex:int;
  34.     private var viewpoint:Vector3 = new Vector3;
  35.     private var yaw:Number, pitch:Number, roll:Number;
  36.     private var offset:Vector3 = new Vector3;
  37.     private var carPosIndex:Number;
  38.     private var roadIndex:int;
  39.     public function UpDownRoad()
  40.     {
  41.       addChild(new Bitmap(buffer));
  42.       yaw = pitch = roll = 0;
  43.       createRoad();
  44.       for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
  45.         drawnParticles.push(new DrawnParticle);
  46.       carPosIndex = roads.length - 10;
  47.       addEventListener(Event.ENTER_FRAME, onEnterFrame);
  48.     }
  49.     private function onEnterFrame(evt:Event):void
  50.     {
  51.       buffer.fillRect(buffer.rect, 0x99ffdd);
  52.       carPosIndex += 1.7;
  53.       if (carPosIndex >= roads.length)
  54.         carPosIndex -= roads.length;
  55.       var cpi:int = carPosIndex;
  56.       var ncpi:int = carPosIndex + 1;
  57.       if (ncpi >= roads.length)
  58.         ncpi -= roads.length;
  59.       var co:Number = carPosIndex - cpi;
  60.       var rp:Vector3 = roads[cpi].pos;
  61.       var nrp:Vector3 = roads[ncpi].pos;
  62.       viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
  63.       viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
  64.       viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
  65.       var oa:Number = roads[ncpi].angle - roads[cpi].angle;
  66.       oa = normalizeAngle(oa);
  67.       oa = roads[cpi].angle + oa * co - yaw;
  68.       oa = normalizeAngle(oa);
  69.       yaw += oa * 0.1;
  70.       yaw = normalizeAngle(yaw);
  71.       pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
  72.       roll += (-oa * 0.7 - roll) * 0.1;
  73.       drawBackground();
  74.       dpIndex = 0;
  75.       for each (var p:Particle in particles)
  76.         drawParticle(p);
  77.       drawnParticles.sort(sortOnZ);
  78.       function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
  79.       {
  80.         if (v1.pos.z < v2.pos.z)
  81.           return 1;
  82.         else if (v1.pos.z > v2.pos.z)
  83.           return -1;
  84.         else
  85.           return 0;
  86.       }
  87.       for (var i:int = 0; i < dpIndex; i++)
  88.       {
  89.         var dp:DrawnParticle = drawnParticles[i];
  90.         rect.x = dp.pos.x - dp.width;
  91.         rect.y = dp.pos.y - dp.height;
  92.         rect.width = dp.width * 2;
  93.         rect.height = dp.height * 2;
  94.         buffer.fillRect(rect, dp.color);
  95.       }
  96.     }
  97.     private function drawParticle(p:Particle):void
  98.     {
  99.       offset.x = p.pos.x - viewpoint.x;
  100.       offset.y = p.pos.y - viewpoint.y;
  101.       offset.z = p.pos.z - viewpoint.z;
  102.       offset.rotationYaw(yaw);
  103.       offset.rotationPitch(pitch);
  104.       offset.rotationRoll(roll);
  105.       if (offset.z < -10 || offset.z > MAX_DEPTH)
  106.         return;
  107.       if (p.detail != null && offset.length < LOD_DISTANCE)
  108.       {
  109.         for each (var pp:Particle in p.detail)
  110.           drawParticle(pp);
  111.         return;
  112.       }
  113.       if (offset.z < 1 || p.width <= 0)
  114.         return;
  115.       var ar:Number = 1.0 - offset.z / MAX_DEPTH;
  116.       if (ar < 0)
  117.         return;
  118.       var dp:DrawnParticle = drawnParticles[dpIndex];
  119.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  120.       dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
  121.       dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
  122.       dp.pos.z = offset.z;
  123.       dp.width = p.width * zr;
  124.       dp.height = p.height * zr;
  125.       dp.color = createColor(p.r, p.g, p.b, 250 * ar);
  126.       dpIndex++;
  127.     }
  128.     private function createColor(r:int, g:int, b:int, a:int):int
  129.     {
  130.       return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
  131.              int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
  132.              int((b * a + BACKGROUND_B * (256 - a)) / 256);
  133.     }
  134.     private function drawBackground():void
  135.     {
  136.       offset.x = 0;
  137.       offset.y = 0;
  138.       offset.z = 99999;
  139.       offset.rotationPitch(pitch);
  140.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  141.       var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
  142.       var bx:Number, by:Number;
  143.       var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
  144.       var bh:Number, bby:Number;
  145.       for (var j:int = 0; j < 3; j++)
  146.       {
  147.         switch (j)
  148.         {
  149.           case 0:
  150.           {
  151.             bh = 8;
  152.             bby = 0;
  153.             break;
  154.           }
  155.           case 1:
  156.           {
  157.             bh = 16;
  158.             bby = 16;
  159.             break;
  160.           }
  161.           case 2:
  162.           {
  163.             bh = SCREEN_HEIGHT / 3;
  164.             bby = 48;
  165.             break;
  166.           }
  167.         }
  168.         bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
  169.         by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
  170.         rect.width = BACKGROUND_BOX_SIZE;
  171.         rect.height = bh * 2;
  172.         for (var i:int = 0; i < bc; i++)
  173.         {
  174.           rect.x = bx - BACKGROUND_BOX_SIZE / 2;
  175.           rect.y = by - bh;
  176.           buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
  177.           bx += BACKGROUND_BOX_SIZE;
  178.           by += vby;
  179.         }
  180.       }
  181.     }
  182.     private var roadPattern:Array = [2000.21160, -3016030800.050.0519000080, -0.05, -1.012001.751];
  183.     private function createRoad():void
  184.     {
  185.       var r:Road = new Road;
  186.       var a:Number = 0;
  187.       var ud:Number = roadPattern[2];
  188.       r.angle = a;
  189.       r.upDown = ud;
  190.       var c:int;
  191.       var ta:Number, tud:Number;
  192.       var polePattern:int;
  193.       var i:int;
  194.       roadIndex = 0;
  195.       for (i = 0; i < roadPattern.length; i += 4)
  196.       {
  197.         c = roadPattern[i];
  198.         ta = roadPattern[i + 1];
  199.         tud = roadPattern[i + 2];
  200.         polePattern = roadPattern[i + 3];
  201.         for (var j:int = 0; j < c; j++)
  202.         {
  203.           a += (ta - a) * 0.2;
  204.           ud += (tud - ud) * 0.1;
  205.           r.angle += a;
  206.           r.angle = normalizeAngle(r.angle);
  207.           r.upDown = ud;
  208.           addRoadAndPole(r, polePattern);
  209.           r = getNextRoad(r);
  210.         }
  211.       }
  212.       c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
  213.       var vrp:Vector3 = new Vector3;
  214.       vrp.x = -r.pos.x / c;
  215.       vrp.y = -r.pos.y / c;
  216.       vrp.z = -r.pos.z / c;
  217.       var va:Number = -r.angle / c;
  218.       var vud:Number = -r.upDown / c;
  219.       for (i = 0; i < c; i++)
  220.       {
  221.         addRoadAndPole(r, polePattern);
  222.         var nr:Road = new Road;
  223.         nr.pos.x = r.pos.x + vrp.x;
  224.         nr.pos.y = r.pos.y + vrp.y;
  225.         nr.pos.z = r.pos.z + vrp.z;
  226.         nr.angle = r.angle + va;
  227.         nr.upDown = r.upDown + vud;
  228.         r = nr;
  229.       }
  230.     }
  231.     private function addRoadAndPole(r:Road, polePattern:int):void
  232.     {
  233.       addRoadParticles(r);
  234.       roads.push(r);
  235.       if (polePattern > 0 && roadIndex % 7 == 0)
  236.       {
  237.         addPoleParticles(r);
  238.       }
  239.       roadIndex++;
  240.     }
  241.     private function getNextRoad(r:Road):Road
  242.     {
  243.       var nr:Road = new Road;
  244.       nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
  245.       nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
  246.       nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
  247.       nr.angle = r.angle;
  248.       nr.upDown = r.upDown;
  249.       return nr;
  250.     }
  251.     private function addRoadParticles(r:Road):void
  252.     {
  253.       for (var j:int = 0; j < 3; j++)
  254.       {
  255.         var p:Particle = new Particle;
  256.         var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
  257.         var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
  258.         p.pos.x = r.pos.x + ox * (j - 1);
  259.         p.pos.y = r.pos.y;
  260.         p.pos.z = r.pos.z + oz * (j - 1);
  261.         p.width = ROAD_WIDTH / 3 * 1.05;
  262.         p.height = ROAD_HEIGHT;
  263.         p.detail = new Vector.<Particle>;
  264.         var pc:int = p.width / p.height + 2;
  265.         ox = Math.cos(r.angle) * p.width / pc * 2;
  266.         oz = -Math.sin(r.angle) * p.width / pc * 2;
  267.         var c:int = 0;
  268.         var i:int;
  269.         var pp:Particle;
  270.         for (i = 0; i < pc; i++)
  271.         {
  272.           pp = new Particle;
  273.           pp.pos.x = p.pos.x + ox * (i - pc / 2);
  274.           pp.pos.y = p.pos.y;
  275.           pp.pos.z = p.pos.z + oz * (i - pc / 2);
  276.           pp.width = pp.height = p.height;
  277.           pp.r = pp.g = pp.b = 190 + Math.random() * 30;
  278.           c += pp.r;
  279.           pp.detail = null;
  280.           p.detail.push(pp);
  281.         }
  282.         p.r = p.g = p.b = c / pc;
  283.         particles.push(p);
  284.         if (roadIndex % 3 == 0 && j != 1)
  285.         {
  286.           pp = new Particle;
  287.           pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
  288.           pp.pos.y = p.pos.y - p.height * 0.5;
  289.           pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
  290.           pp.width = p.height;
  291.           pp.height = p.height * 0.6;
  292.           pp.r = pp.g = pp.b = 32;
  293.           pp.detail = null;
  294.           particles.push(pp);
  295.         }
  296.       }
  297.     }
  298.     private function addPoleParticles(r:Road):void
  299.     {
  300.       for (var i:int = 0; i < 2; i++)
  301.       {
  302.         var p:Particle = new Particle;
  303.         p.width = 4;
  304.         p.height = 36;
  305.         p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  306.         p.pos.y = r.pos.y - p.height / 2;
  307.         p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  308.         p.r = 250; p.g = 60; p.b = 60;
  309.         p.detail = new Vector.<Particle>;
  310.         for (var j:int = 0; j < 8; j++)
  311.         {
  312.           var pp:Particle = new Particle;
  313.           pp.pos.x = p.pos.x;
  314.           pp.pos.y = p.pos.y - j * p.height / 8;
  315.           pp.pos.z = p.pos.z;
  316.           pp.width = p.width;
  317.           pp.height = p.height / 8;
  318.           pp.r = p.r;
  319.           pp.g = p.g;
  320.           pp.b = p.b;
  321.           pp.detail = null;
  322.           p.detail.push(pp);
  323.         }
  324.         particles.push(p);
  325.       }
  326.     }
  327.     private function normalizeAngle(v:Number):Number {
  328.       if (v > Math.PI)
  329.         return v - Math.PI * 2;
  330.       else if (v < -Math.PI)
  331.         return v + Math.PI * 2;
  332.       else
  333.         return v;
  334.     }
  335.   }
  336. }
  337. class Road
  338. {
  339.   public var pos:Vector3 = new Vector3;
  340.   public var angle:Number, upDown:Number;
  341. }
  342. class Particle
  343. {
  344.   public var pos:Vector3 = new Vector3;
  345.   public var width:Number;
  346.   public var height:Number;
  347.   public var r:int, g:int, b:int;
  348.   public var detail:Vector.<Particle>;
  349. }
  350. class DrawnParticle
  351. {
  352.   public var pos:Vector3 = new Vector3;
  353.   public var width:Number;
  354.   public var height:Number;
  355.   public var color:int;
  356. }
  357. class Vector3
  358. {
  359.   public var x:Number = 0;
  360.   public var y:Number = 0;
  361.   public var z:Number = 0;
  362.   public function rotationYaw(v:Number):void
  363.   {
  364.     var sv:Number = Math.sin(v);
  365.     var cv:Number = Math.cos(v);
  366.     var rx:Number = cv * x - sv * z;
  367.     z = sv * x + cv * z;
  368.     x = rx;
  369.   }
  370.   public function rotationPitch(v:Number):void
  371.   {
  372.     var sv:Number = Math.sin(v);
  373.     var cv:Number = Math.cos(v);
  374.     var ry:Number = cv * y - sv * z;
  375.     z = sv * y + cv * z;
  376.     y = ry;
  377.   }
  378.   public function rotationRoll(v:Number):void
  379.   {
  380.     var sv:Number = Math.sin(v);
  381.     var cv:Number = Math.cos(v);
  382.     var rx:Number = cv * x - sv * y;
  383.     y = sv * x + cv * y;
  384.     x = rx;
  385.   }
  386.   public function get length():Number
  387.   {
  388.     return Math.sqrt(x * x + y * y + z * z);
  389.   }
  390. }
noswf
Get Adobe Flash Player