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

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

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


FAVORITE BY
:
ShmupBullet-HellGameKill Evil Circles
:
118712  面白い!
:
すごいなー
:
あそべるー
FORKED
  1. // forked from ABA's CircleCycle
  2. // CircleCycle.as
  3. //  Destroy circles and avoid incoming bullets.
  4. //  <Control>
  5. //   Movement: Arrow or [WASD] keys.
  6. //   Fire:    [Z], [X], [.] or [/] key.
  7. package
  8. {
  9.     import flash.display.Sprite;
  10.     [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  11.     public class CircleCycle extends Sprite
  12.     {
  13.         public function CircleCycle()
  14.         {
  15.             main = this;
  16.             initialize();
  17.         }
  18.     }
  19. }
  20. import flash.display.Sprite;
  21. import flash.display.Bitmap;
  22. import flash.display.BitmapData;
  23. import flash.display.Graphics;
  24. import flash.geom.Rectangle;
  25. import flash.geom.Vector3D;
  26. import flash.text.TextField;
  27. import flash.text.TextFormat;
  28. import flash.text.TextFormatAlign;
  29. import flash.events.Event;
  30. import flash.events.KeyboardEvent;
  31. const SCREEN_WIDTH:int = 465, SCREEN_HEIGHT:int = 465;
  32. const TITLE:int = 0, GAME:int = 1, GAME_OVER:int = 2;
  33. const GAME_OVER_DURATION:int = 150, BLOCK_GAME_START_DURATION:int = 30;
  34. const BACKGROUND_BRIGHTNESS:int = 200;
  35. const BACKGROUND_COLOR:int = BACKGROUND_BRIGHTNESS * 0x10000 + BACKGROUND_BRIGHTNESS * 0x100 + BACKGROUND_BRIGHTNESS;
  36. var main:Sprite;
  37. var screen:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  38. var scoreField:TextField = new TextField;
  39. var timeField:TextField = new TextField;
  40. var messageField:TextField = new TextField;
  41. var score:int, time:int, stage:int, gameOverTicks:int;
  42. var rect:Rectangle = new Rectangle;
  43. var pos:Vector3D = new Vector3D, offset:Vector3D = new Vector3D;
  44. var rand:Function = Math.random, abs:Function = Math.abs;
  45. var sin:Function = Math.sin, cos:Function = Math.cos, atan2:Function = Math.atan2;
  46. var PI:Number = Math.PI;
  47. function initialize():void
  48. {
  49.     main.addChild(new Bitmap(screen));
  50.     main.stage.addEventListener(KeyboardEvent.KEY_DOWN, Key.onKeyDown);
  51.     main.stage.addEventListener(KeyboardEvent.KEY_UP,   Key.onKeyUp);
  52.     Field.initialize();
  53.     initializeBlurs();
  54.     player.initialize();
  55.     scoreField = createTextField(SCREEN_WIDTH - 100010024, 0xff6666, TextFormatAlign.RIGHT);
  56.     timeField = createTextField(SCREEN_WIDTH / 2 - 100, SCREEN_HEIGHT - 4820048, 0xff6666, TextFormatAlign.RIGHT);
  57.     messageField = createTextField(SCREEN_WIDTH - 256025636, 0xff6666);
  58.     main.addChild(scoreField); main.addChild(timeField); main.addChild(messageField);
  59.     start(TITLE);
  60.     main.addEventListener(Event.ENTER_FRAME, update);
  61. }
  62. function update(event:Event):void
  63. {
  64.     if (circles.length <= 0) goToNextStage();
  65.     screen.lock();
  66.     screen.fillRect(screen.rect, BACKGROUND_COLOR);
  67.     updateBlurs();
  68.     var i:int;
  69.     for (i = 0; i < sparks.length; i++)  if (!sparks[i].update())  { sparks.splice(i, 1); i--; }
  70.     for (i = 0; i < shots.length; i++)   if (!shots[i].update())   { shots.splice(i, 1);  i--; }
  71.     for each (var c:Circle in circles) c.update();
  72.     for (i = 0; i < circles.length; i++) if (!circles[i].exists)   { circles.splice(i, 1); i--; }
  73.     if (gameOverTicks < 0) player.update();
  74.     for (i = 0; i < bullets.length; i++) if (!bullets[i].update()) { bullets.splice(i, 1); i--; }
  75.     Field.drawSideBoard();
  76.     screen.unlock();
  77.     if (gameOverTicks < 0)
  78.     {
  79.         var msStr:String = String(time % 1000);
  80.         while (msStr.length < 3) msStr = "0" + msStr;
  81.         timeField.text = String(int(time / 1000)) + "\"" + msStr;
  82.         if (time <= 0) start(GAME_OVER);
  83.         time -= 33;
  84.     }
  85.     else
  86.     {
  87.         gameOverTicks++;
  88.         if (gameOverTicks == GAME_OVER_DURATION) start(TITLE);
  89.         if (Key.button1 && gameOverTicks > BLOCK_GAME_START_DURATION) start(GAME);
  90.     }
  91. }
  92. function goToNextStage():void
  93. {
  94.     if (gameOverTicks < 0 && stage > 0) score += time;
  95.     scoreField.text = String(score);
  96.     stage++;
  97.     time = 5000;
  98.     addCircles((rand() - 0.5) * Field.size.x, 250.0 / (20.0 + stage), 5.0 + rand() * 2.0 + rand() * 2.0);
  99. }
  100. function start(mode:int):void
  101. {
  102.     switch (mode)
  103.     {
  104.         case TITLE:
  105.         {
  106.             clearActors();
  107.             player.hide();
  108.             gameOverTicks = GAME_OVER_DURATION;
  109.             messageField.y = SCREEN_HEIGHT / 3 * 2; messageField.text = "CircleCycle";
  110.             break;
  111.         }
  112.         case GAME:
  113.         {
  114.             clearActors();
  115.             player.start();
  116.             gameOverTicks = -1;
  117.             messageField.text = "";
  118.             score = 0; stage = 0;
  119.             break;
  120.         }
  121.         case GAME_OVER:
  122.         {
  123.             player.hide();
  124.             gameOverTicks = 0;
  125.             messageField.y = SCREEN_HEIGHT / 2; messageField.text = "GAME OVER";
  126.             timeField.text = "";
  127.             break;
  128.         }
  129.     }
  130. }
  131. function clearActors():void
  132. {
  133.     shots = null; bullets = null; sparks = null;
  134.     shots = new Vector.<Shot>; bullets = new Vector.<Bullet>; sparks = new Vector.<Spark>;
  135.     for each (var c:Circle in circles) c.remove();
  136.     circles = null; circles = new Vector.<Circle>;
  137. }
  138. // Game actor base class.
  139. class Actor
  140. {
  141.     public var pos:Vector3D = new Vector3D;
  142. }
  143. class VelocityActor extends Actor
  144. {
  145.     public var vel:Vector3D = new Vector3D;
  146.     public var ticks:int;
  147.     public function update():Boolean
  148.     {
  149.         pos.incrementBy(vel);
  150.         ticks++;
  151.         if (!Field.contains(pos) || ticks > 300return false;
  152.         return true;
  153.     }
  154. }
  155. // Player.
  156. var player:Player = new Player;
  157. class Player extends Actor
  158. {
  159.     private const INVINCIBLE_DURATION:int = 90;
  160.     private const COLLISION_SIZE:Number = 5.0;
  161.     private const SPEED:Number = 9.0;
  162.     private var vel:Vector3D = new Vector3D;
  163.     private var fireTicks:int;
  164.     private var sprite:Sprite = new Sprite;
  165.     public function initialize():void
  166.     {
  167.         var g:Graphics = sprite.graphics;
  168.         g.lineStyle(5, 0x008800);
  169.         g.moveTo(0, -10); g.lineTo(-10,10); g.lineTo(1010); g.lineTo(0, -10);
  170.         main.addChild(sprite);
  171.     }
  172.     public function start():void
  173.     {
  174.         pos.x = 0; pos.y = Field.size.y * 0.5;
  175.         vel.y = -5.0;
  176.     }
  177.     public function hide():void
  178.     {
  179.         sprite.x = sprite.y = 99999;
  180.     }
  181.     public function update():void
  182.     {
  183.         offset.x = offset.y = 0;
  184.         if (Key.left)  offset.x = -1;
  185.         if (Key.right) offset.x = 1;
  186.         if (Key.up)    offset.y = -1;
  187.         if (Key.down)  offset.y = 1;
  188.         if (offset.x != 0 && offset.y != 0) offset.scaleBy(0.7);
  189.         offset.scaleBy(SPEED); pos.incrementBy(offset);
  190.         pos.incrementBy(vel); vel.scaleBy(0.9);
  191.         if (pos.x < -SCREEN_WIDTH  / 2) pos.x = -SCREEN_WIDTH / 2;
  192.         if (pos.x >  SCREEN_WIDTH  / 2) pos.x =  SCREEN_WIDTH / 2;
  193.         if (pos.y < -SCREEN_HEIGHT / 2) pos.y = -SCREEN_HEIGHT / 2;
  194.         if (pos.y >  SCREEN_HEIGHT / 2) pos.y =  SCREEN_HEIGHT / 2;
  195.         Field.offsetX = pos.x * 0.33;
  196.         sprite.x = pos.x + SCREEN_WIDTH / 2 - Field.offsetX;
  197.         sprite.y = pos.y + SCREEN_WIDTH / 2;
  198.         var bc:int = time * 150 / 5000;
  199.         addBlur(pos.x, pos.y - 777250 - bc, 50 + bc, 100);
  200.         addBlur(pos.x, pos.y + 31515250 - bc, 50 + bc, 100);
  201.         drawBox(pos.x + time * 0.02 / 2, pos.y + 15, time * 0.0210,
  202.                 (150 - bc) * 0x10000 + bc * 0x100, 0000);
  203.         var i:int;
  204.         if (fireTicks <= 0 && shots.length <= 7 && abs(vel.y) < 1.0 && Key.button1)
  205.         {
  206.             fireTicks = 2;
  207.             var s:Shot;
  208.             for (i = 0; i < 7; i++)
  209.             {
  210.                 s = new Shot;
  211.                 s.pos.x = pos.x; s.pos.y = pos.y;
  212.                 var d:Number = (i - 3) * 0.1;
  213.                 s.vel.x = sin(d) * 24.0; s.vel.y = -cos(d) * 24.0;
  214.                 shots.push(s);
  215.             }
  216.         }
  217.         fireTicks--;
  218.         i = 0;
  219.         for each (var b:Bullet in bullets)
  220.         {
  221.             if (Vector3D.distance(pos, b.pos) <= COLLISION_SIZE)
  222.             {
  223.                 if (vel.y < 1.0)
  224.                 {
  225.                     vel.y += 20.0;
  226.                     addSparks(50, pos.x, pos.y, 30.015.0200200100);
  227.                     time /= 2;
  228.                 }
  229.                 else
  230.                 {
  231.                     bullets.splice(i, 1); i--;
  232.                 }
  233.             }
  234.             i++;
  235.         }
  236.     }
  237. }
  238. // Player's shots.
  239. var shots:Vector.<Shot> = new Vector.<Shot>;
  240. class Shot extends VelocityActor
  241. {
  242.     override public function update():Boolean
  243.     {
  244.         for each (var c:Circle in circles) if (checkHit(c)) return false;
  245.         addBlur(pos.x, pos.y, 201550150100);
  246.         return super.update();
  247.     }
  248.     private function checkHit(c:Circle):Boolean
  249.     {
  250.         for each (var cc:Circle in c.children) if (cc.exists && checkHit(cc)) return true;
  251.         if (c.exists && c.hasCollision && Vector3D.distance(pos, c.pos) < c.spec.spriteRadius + 20.0)
  252.         {
  253.             addSparks(1, pos.x, pos.y, 20.05.050150100);
  254.             c.damage(); return true;
  255.         }
  256.         return false;
  257.     }
  258. }
  259. // Circles' bullets.
  260. var bullets:Vector.<Bullet>;
  261. class Bullet extends VelocityActor
  262. {
  263.     public var baseVel:Vector3D = new Vector3D;
  264.     public var color:int, br:int, bg:int, bb:int, size:int;
  265.     override public function update():Boolean
  266.     {
  267.         var sz:Number = 1.5 + Math.sin(ticks * 0.2) * 0.4;
  268.         var a:Number = 0.8 + Math.sin(ticks * 0.45) * 0.2;
  269.         drawBox(pos.x, pos.y, size, size, color, sz, br * a, bg * a, bb * a);
  270.         if (ticks <= 15)
  271.         {
  272.             vel.x = baseVel.x * (ticks + 15) / 30.0; vel.y = baseVel.y * (ticks + 15) / 30.0;
  273.         }
  274.         return super.update();
  275.     }
  276. }
  277. // Circles.
  278. var circles:Vector.<Circle> = new Vector.<Circle>;
  279. class Circle extends Actor
  280. {
  281.     public var children:Vector.<Circle> = new Vector.<Circle>;
  282.     public var isTop:Boolean, exists:Boolean = true;
  283.     public var spec:CircleSpec;
  284.     public var bulletSpeedRatio:Number = 1.0;
  285.     public var rollAngle:Number, fireAngle:Number, fireSpeed:Number, angleInterval:Number;
  286.     public var baseAngle:Number;
  287.     public var ticks:int, shield:int;
  288.     public var hasCollision:Boolean;
  289.     public var isDamaged:Boolean;
  290.     public var sprite:Sprite = new Sprite;
  291.     public function start():void
  292.     {
  293.         var g:Graphics = sprite.graphics;
  294.         g.clear();
  295.         g.lineStyle(5, (int)(spec.r / 2) * 0x10000 + int(spec.g / 2) * 0x100 + int(spec.b / 2));
  296.         g.drawCircle(00, spec.spriteRadius);
  297.         main.addChild(sprite);
  298.         baseAngle = rollAngle = fireAngle = 0;
  299.         shield = spec.shield;
  300.     }
  301.     public function update():void
  302.     {
  303.         sprite.x = pos.x + SCREEN_WIDTH / 2 - Field.offsetX;
  304.         sprite.y = pos.y + SCREEN_HEIGHT / 2;
  305.         var i:int;
  306.         if (isDamaged)
  307.         {
  308.             isDamaged = false;
  309.             var da:Number = ticks * 0.1, sr:Number = spec.spriteRadius, bc:int = sr * 0.5;
  310.             for (i = 0; i < bc; i++)
  311.             {
  312.                 addBlur(pos.x + sr * sin(da), pos.y + sr * cos(da),
  313.                         9 + rand() * 79 + rand() * 7, rand() * 128 + 127, rand() * 1280);
  314.                 da += PI * 2 / bc;
  315.             }
  316.         }
  317.         if (spec.fireInterval > 0 && ticks % spec.fireInterval == 0 && pos.y < 0)
  318.         {
  319.             if (spec.isAimingBaseAngle) baseAngle = atan2(player.pos.x - pos.x, player.pos.y - pos.y);
  320.             var ba:Number = baseAngle + rollAngle + fireAngle;
  321.             var srv:Number = -spec.bulletSpeedWhipVel * 2/ spec.bulletCount;
  322.             for (i = 0; i < spec.bulletCount; i++) fire(ba, 1.0 + spec.bulletSpeedWhipVel + srv * i);
  323.         }
  324.         ticks++;
  325.         if (spec.childrenCount <= 0return;
  326.         rollAngle = spec.rollAngle.getValue(ticks);
  327.         fireAngle = spec.fireAngle.getValue(ticks);
  328.         fireSpeed = spec.fireSpeed.getValue(ticks);
  329.         angleInterval = spec.angleInterval.getValue(ticks);
  330.         if (spec.isAimingRollAngle) rollAngle += atan2(player.pos.x - pos.x, player.pos.y - pos.y);
  331.         var a:Number = rollAngle - angleInterval * (children.length - 1) / 2 - angleInterval;
  332.         for each (var c:Circle in children)
  333.         {
  334.             a += angleInterval;
  335.             if (!c.exists) continue;
  336.             c.pos.x = pos.x + sin(a) * spec.radius;
  337.             c.pos.y = pos.y + cos(a) * spec.radius;
  338.             c.baseAngle = a + fireAngle;
  339.             c.update();
  340.         }
  341.         if (isTop && pos.y < -Field.size.y * 0.5) pos.y += 7.0;
  342.     }
  343.     private function fire(a:Number, sr:Number):void
  344.     {
  345.         var b:Bullet = new Bullet;
  346.         b.pos.x = pos.x; b.pos.y = pos.y;
  347.         var bs:Number = spec.bulletSpeed * bulletSpeedRatio * sr;
  348.         b.baseVel.x = sin(a) * bs; b.baseVel.y = cos(a) * bs;
  349.         b.size = spec.bulletSize;
  350.         b.br = spec.r; b.bg = spec.g; b.bb = spec.b;
  351.         b.color = int(b.br / 4) * 0x10000 + int(b.bg / 4) * 0x100 + int(b.bb / 4);
  352.         bullets.push(b);
  353.     }
  354.     public function damage():void
  355.     {
  356.         isDamaged = true;
  357.         shield--;
  358.         if (shield <= 0) remove(true);
  359.     }
  360.     public function remove(isDestroyed:Boolean = false):void
  361.     {
  362.         main.removeChild(sprite);
  363.         for each (var c:Circle in children) if (c.exists) c.remove();
  364.         exists = false;
  365.         if (!isDestroyed) return;
  366.         var ba:Number = ticks * 0.1, sr:Number = spec.spriteRadius, bc:int = sr * 0.5;
  367.         for (var i:int = 0; i < bc; i++)
  368.         {
  369.             addSparks(1, pos.x + sr * sin(ba), pos.y + sr * cos(ba), 10.010.0, spec.r, spec.g, spec.b);
  370.             ba += PI * 2 / bc;
  371.         }
  372.     }
  373. }
  374. class CircleSpec
  375. {
  376.     public static const FIX:int = 0, WEDGE:int = 1;
  377.     public var radius:Number, spriteRadius:Number;
  378.     public var isRound:Boolean;
  379.     public var rollAngle:Waveform = new Waveform;
  380.     public var isAimingRollAngle:Boolean, isAimingBaseAngle:Boolean;
  381.     public var fireAngle:Waveform = new Waveform, fireSpeed:Waveform = new Waveform;
  382.     public var fireInterval:int = -1;
  383.     public var angleInterval:Waveform = new Waveform;
  384.     public var bulletSpeed:Number = 7.0, bulletSize:Number = 15.0;
  385.     public var bulletSpeedFanType:int, bulletSpeedFanVel:Number = 0;
  386.     public var fireDelayType:int, fireDelayVel:Number = 0;
  387.     public var bulletCount:int = 1, bulletSpeedWhipVel:Number = 0;
  388.     public var r:int, g:int, b:int;
  389.     public var childrenCount:int;
  390.     public var shield:int;
  391.     public function set(childrenCount:int, radius:Number, childRadius:Number):void
  392.     {
  393.         this.childrenCount = childrenCount;
  394.         this.radius = radius; spriteRadius = radius + childRadius;
  395.         shield = radius * 0.7;
  396.         rollAngle.width = (0.5 + rand() * 0.5) * ((int)(rand() * 2) * 2 - 1);
  397.         isRound = (rand() < 0.25);
  398.         if (isRound) {
  399.             rollAngle.type = Waveform.MONOTONE;
  400.             rollAngle.interval = 60 + rand() * 60;
  401.             if (rand() < 0.4) fireAngle.type = Waveform.MONOTONE;
  402.             fireAngle.width = (2.0 + rand() * 2.0) * ((int)(rand() * 2) * 2 - 1);
  403.             fireAngle.interval = 90 + rand() * 90;
  404.             if (rand() < 0.3) fireAngle.center = rand() * PI * 2;
  405.             angleInterval.center = PI * 2 / childrenCount;
  406.         }
  407.         else
  408.         {
  409.             isAimingRollAngle = true;
  410.             if (rand() < 0.3) rollAngle.type = Waveform.SIN;
  411.             rollAngle.interval = 120 + rand() * 90;
  412.             if (rand() < 0.3) angleInterval.type = Waveform.SIN;
  413.             angleInterval.center = ((2.0 + rand() * 2.0) / childrenCount) * ((int)(rand() * 2) * 2 - 1);
  414.             angleInterval.width = angleInterval.center * (0.3 + rand() * 0.3);
  415.             angleInterval.interval = 60 + rand() * 60;
  416.         }
  417.         if (rand() < 0.5) bulletSpeedFanType = WEDGE;
  418.         if (rand() < 0.5) bulletSpeedFanVel = (0.3 + rand() * 0.2) * ((int)(rand() * 2) * 2 - 1);
  419.         if (rand() < 0.5) fireDelayType = WEDGE;
  420.         if (rand() < 0.5) fireDelayVel = (8.0 + rand() * 6.0) * ((int)(rand() * 2) * 2 - 1);
  421.     }
  422. }
  423. class Waveform
  424. {
  425.     public static const FIX:int = 0, MONOTONE:int = 1, SIN:int = 2;
  426.     public var type:int = FIX, center:Number = 0, width:Number = 0, interval:int = 1;
  427.     public function getValue(ticks:int):Number
  428.     {
  429.         switch (type)
  430.         {
  431.             case FIX:      return center;
  432.             case MONOTONE: return center + width * ticks * 2 / interval;
  433.             case SIN:      return center + width * sin(PI * 2 * ticks / interval);
  434.         }
  435.         return 0;
  436.     }
  437. }
  438. function addCircles(x:Number, depth:int, fireIntervalRatio:Number, bulletSpeed:Number):void
  439. {
  440.     var radius:Number = (20 + rand() * 20) * depth;
  441.     var c:Circle = new Circle;
  442.     c.pos.x = x; c.pos.y = -Field.size.y - radius;
  443.     c.isTop = true; c.hasCollision = true;
  444.     var r:int, g:int, b:int;
  445.     r = 127 + rand() * 128; g = 127 + rand() * 128; b = 127 + rand() * 128;
  446.     var sps:Vector.<CircleSpec> = new Vector.<CircleSpec>;
  447.     var turretCount:int = createCircleSpecs(sps, radius, depth, r, g, b);
  448.     var sp:CircleSpec;
  449.     for each (sp in sps) if (sp.isRound) turretCount *= 0.75;
  450.     sp = sps[0];
  451.     sp.fireInterval = turretCount * fireIntervalRatio + 1;
  452.     sp.bulletSpeed = bulletSpeed; sp.bulletSize = 10.0 + depth * 3;
  453.     addCircleChildren(c, sps.length - 1, sps, 1.00);
  454.     circles.push(c);
  455. }
  456. function createCircleSpecs(sps:Vector.<CircleSpec>, radius:Number, depth:int, r:int, g:int, b:int):int
  457. {
  458.     var sp:CircleSpec = new CircleSpec;
  459.     sp.r = r; sp.g = g; sp.b = b;
  460.     var turretCount:int;
  461.     if (depth == 0)
  462.     {
  463.         sp.radius = 0; sp.spriteRadius = radius; sp.childrenCount = 0;
  464.         if (rand() < 0.3)
  465.         {
  466.             sp.bulletCount = 2 + rand() * 5;
  467.             sp.bulletSpeedWhipVel = 0.2 + rand() * 0.2;
  468.             turretCount = sp.bulletCount * 0.75;
  469.         }
  470.         else turretCount = 1;
  471.     }
  472.     else
  473.     {
  474.         sp.childrenCount = 1 + rand() * 7;
  475.         var cr:Number = radius * (0.33 + rand() * 0.1);
  476.         sp.set(sp.childrenCount, radius, cr);
  477.         turretCount = createCircleSpecs(sps, cr, depth - 1, r, g, b) * sp.childrenCount;
  478.     }
  479.     sps.push(sp);
  480.     return turretCount;
  481. }
  482. function addCircleChildren(c:Circle, index:int, sps:Vector.<CircleSpec>,
  483.                            bulletSpeedRatio:Number, fireDelay:Number):void
  484. {
  485.     var sp:CircleSpec = sps[index];
  486.     var bsv:Number = -sp.bulletSpeedFanVel * 2 / sp.childrenCount;
  487.     var fdv:Number = -sp.fireDelayVel * 2 / sp.childrenCount;
  488.     if (sp.bulletSpeedFanType == CircleSpec.WEDGE) bsv *= 2;
  489.     if (sp.fireDelayType == CircleSpec.WEDGE) fdv *= 2;
  490.     for (var i:int = 0; i < sp.childrenCount; i++)
  491.     {
  492.         var cc:Circle = new Circle;
  493.         var bsr:Number;
  494.         if (sp.bulletSpeedFanType == CircleSpec.FIX || i < sp.childrenCount / 2) bsr = 1.0 + sp.bulletSpeedFanVel + bsv * i;
  495.         else bsr = 1.0 + sp.bulletSpeedFanVel + bsv * (sp.childrenCount - 1 - i);
  496.         var fd:Number;
  497.         if (sp.fireDelayType == CircleSpec.FIX || i < sp.childrenCount / 2) fd = sp.fireDelayVel + fdv * i;
  498.         else fd = sp.fireDelayVel + fdv * (sp.childrenCount - 1 - i);
  499.         addCircleChildren(cc, index - 1, sps, bsr * bulletSpeedRatio, fireDelay + fd);
  500.         c.children.push(cc);
  501.     }
  502.     c.bulletSpeedRatio = bulletSpeedRatio;
  503.     c.ticks = fireDelay;
  504.     c.spec = sp; c.start();
  505. }
  506. // Sparks.
  507. var sparks:Vector.<Spark>;
  508. class Spark extends VelocityActor
  509. {
  510.     public var size:Number;
  511.     public var r:int, g:int, b:int;
  512.     override public function update():Boolean
  513.     {
  514.         vel.scaleBy(0.99);
  515.         size *= 0.95;
  516.         r += (BACKGROUND_BRIGHTNESS - r) * 0.1;
  517.         g += (BACKGROUND_BRIGHTNESS - g) * 0.1;
  518.         b += (BACKGROUND_BRIGHTNESS - b) * 0.1;
  519.         var cr:Number = rand() + 0.5;
  520.         var br:int = r * cr, bg:int = g * cr, bb:int = b * cr;
  521.         if (br > 255) br = 255;
  522.         if (bg > 255) bg = 255;
  523.         if (bb > 255) bb = 255;
  524.         drawBox(pos.x, pos.y, size, size, r * 0x10000 + g * 0x100 + b, 1.5, br, bg, bb);
  525.         return super.update();
  526.     }
  527. }
  528. function addSparks(count:int, x:Number, y:Number, speed:Number, size:Number, r:int, g:int ,b:int):void
  529. {
  530.     for (var i:int = 0; i < count; i++)
  531.     {
  532.         var s:Spark = new Spark;
  533.         s.pos.x = x; s.pos.y = y;
  534.         var a:Number = rand() * PI * 2, sp:Number = speed * (0.5 + rand());
  535.         s.vel.x = Math.sin(a) * sp; s.vel.y = Math.cos(a) * sp;
  536.         s.size = size;
  537.         s.r = r; s.g = g; s.b = b;
  538.         s.ticks = 15 + 15 * rand();
  539.         sparks.push(s);
  540.     }
  541. }
  542. // Game field.
  543. class Field
  544. {
  545.     public static const SIDE_BOARD_WIDTH:Number = SCREEN_WIDTH / 6;
  546.     public static var size:Vector3D = new Vector3D;
  547.     public static var offsetX:Number = 0;
  548.     public static function initialize():void
  549.     {
  550.         size.x = SCREEN_WIDTH * 1.1 / 2; size.y = SCREEN_HEIGHT * 1.1 / 2;
  551.     }
  552.     public static function drawSideBoard():void
  553.     {
  554.         rect.width = SIDE_BOARD_WIDTH; rect.height = SCREEN_HEIGHT; rect.y = 0;
  555.         rect.x = 0;                         screen.fillRect(rect, BACKGROUND_COLOR);
  556.         rect.x = SCREEN_WIDTH - rect.width; screen.fillRect(rect, BACKGROUND_COLOR);
  557.     }
  558.     public static function contains(p:Vector3D):Boolean
  559.     {
  560.         return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  561.     }
  562. }
  563. // Blur effect.
  564. const BLUR_MAX_COUNT:int = 512, BLUR_HISTORY_COUNT:int = 6;
  565. var blurs:Vector.<Vector.<Blur>> = new Vector.<Vector.<Blur>>(BLUR_HISTORY_COUNT, true);
  566. var blurCounts:Vector.<int> = new Vector.<int>(BLUR_HISTORY_COUNT, true);
  567. var blurIndex:int;
  568. class Blur
  569. {
  570.     public var pos:Vector3D = new Vector3D;
  571.     public var width:Number, height:Number;
  572.     public var r:int, g:int, b:int;
  573.     public function update():void
  574.     {
  575.         rect.x = pos.x - width  / 2 - Field.offsetX; rect.width = width;
  576.         rect.y = pos.y - height / 2; rect.height = height;
  577.         screen.fillRect(rect, r * 0x10000 + g * 0x100 + b);
  578.         width *= 1.2; height *= 1.2;
  579.         r += (BACKGROUND_BRIGHTNESS - r) * 0.2;
  580.         g += (BACKGROUND_BRIGHTNESS - g) * 0.2;
  581.         b += (BACKGROUND_BRIGHTNESS - b) * 0.2;
  582.     }
  583. }
  584. function drawBox(x:Number, y:Number, w:int, h:int, color:int,
  585.                  blurSizeRatio:Number, br:int, bg:int, bb:int):void
  586. {
  587.     rect.x = x - w / 2 + SCREEN_WIDTH / 2 - Field.offsetX;
  588.     rect.y = y - h / 2 + SCREEN_HEIGHT / 2;
  589.     rect.width = w; rect.height = h;
  590.     screen.fillRect(rect, color);
  591.     if (blurSizeRatio > 0) addBlur(x, y, w * blurSizeRatio, h * blurSizeRatio, br, bg, bb);
  592. }
  593. function addBlur(x:Number, y:Number, w:Number, h:Number, r:int, g:int, b:int):void
  594. {
  595.     if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  596.     var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  597.     bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  598.     bl.width = w; bl.height = h;
  599.     bl.r = r; bl.g = g; bl.b = b;
  600.     blurCounts[blurIndex]++;
  601. }
  602. function updateBlurs():void
  603. {
  604.     var bi:int = blurIndex + 1;
  605.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  606.     {
  607.         if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  608.         for (var j:int = 0; j < blurCounts[bi]; j++) blurs[bi][j].update();
  609.         bi++;
  610.     }
  611.     blurIndex++;
  612.     if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  613.     blurCounts[blurIndex] = 0;
  614. }
  615. function initializeBlurs():void
  616. {
  617.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  618.     {
  619.         var bs:Vector.<Blur> = new Vector.<Blur>(BLUR_MAX_COUNT, true);
  620.         for (var j:int = 0; j < BLUR_MAX_COUNT; j++) bs[j] = new Blur;
  621.         blurs[i] = bs; blurCounts[i] = 0;
  622.     }
  623.     blurIndex = 0;
  624. }
  625. // Utility classes and functions.
  626. class Key
  627. {
  628.     public static var left:Boolean, up:Boolean, right:Boolean, down:Boolean;
  629.     public static var button1:Boolean;
  630.     public static function onKeyDown(event:KeyboardEvent):void
  631.     {
  632.         switch (event.keyCode)
  633.         {
  634.             case 0x25:case 0x41: left =    truebreak;
  635.             case 0x26:case 0x57: up =      truebreak;
  636.             case 0x27:case 0x44: right =   truebreak;
  637.             case 0x28:case 0x53: down =    truebreak;
  638.             case 0x5a:case 0xbf:
  639.             case 0x58:case 0xbe: button1 = truebreak;
  640.         }
  641.     }
  642.     public static function onKeyUp(event:KeyboardEvent):void
  643.     {
  644.         switch (event.keyCode)
  645.         {
  646.             case 0x25:case 0x41: left =    falsebreak;
  647.             case 0x26:case 0x57: up =      falsebreak;
  648.             case 0x27:case 0x44: right =   falsebreak;
  649.             case 0x28:case 0x53: down =    falsebreak;
  650.             case 0x5a:case 0xbf:
  651.             case 0x58:case 0xbe: button1 = falsebreak;
  652.         }
  653.     }
  654. }
  655. function createTextField(x:int, y:int, width:int, size:int, color:int,
  656.                          align:String = TextFormatAlign.LEFT):TextField
  657. {
  658.     var fm:TextFormat = new TextFormat;
  659.     fm.font = "_typewriter"; fm.bold = true;
  660.     fm.size = size; fm.color = color; fm.align = align;
  661.     var fi:TextField = new TextField;
  662.     fi.defaultTextFormat = fm;
  663.     fi.x = x; fi.y = y; fi.width = width; fi.selectable = false;
  664.     return fi;
  665. }
noswf
  1. // forked from ABA's CircleCycle
  2. // CircleCycle.as
  3. //  Destroy circles and avoid incoming bullets.
  4. //  <Control>
  5. //   Movement: Arrow or [WASD] keys.
  6. //   Fire:    [Z], [X], [.] or [/] key.
  7. package
  8. {
  9.     import flash.display.Sprite;
  10.     [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  11.     public class CircleCycle extends Sprite
  12.     {
  13.         public function CircleCycle()
  14.         {
  15.             main = this;
  16.             initialize();
  17.         }
  18.     }
  19. }
  20. import flash.display.Sprite;
  21. import flash.display.Bitmap;
  22. import flash.display.BitmapData;
  23. import flash.display.Graphics;
  24. import flash.geom.Rectangle;
  25. import flash.geom.Vector3D;
  26. import flash.text.TextField;
  27. import flash.text.TextFormat;
  28. import flash.text.TextFormatAlign;
  29. import flash.events.Event;
  30. import flash.events.KeyboardEvent;
  31. const SCREEN_WIDTH:int = 465, SCREEN_HEIGHT:int = 465;
  32. const TITLE:int = 0, GAME:int = 1, GAME_OVER:int = 2;
  33. const GAME_OVER_DURATION:int = 150, BLOCK_GAME_START_DURATION:int = 30;
  34. const BACKGROUND_BRIGHTNESS:int = 200;
  35. const BACKGROUND_COLOR:int = BACKGROUND_BRIGHTNESS * 0x10000 + BACKGROUND_BRIGHTNESS * 0x100 + BACKGROUND_BRIGHTNESS;
  36. var main:Sprite;
  37. var screen:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  38. var scoreField:TextField = new TextField;
  39. var timeField:TextField = new TextField;
  40. var messageField:TextField = new TextField;
  41. var score:int, time:int, stage:int, gameOverTicks:int;
  42. var rect:Rectangle = new Rectangle;
  43. var pos:Vector3D = new Vector3D, offset:Vector3D = new Vector3D;
  44. var rand:Function = Math.random, abs:Function = Math.abs;
  45. var sin:Function = Math.sin, cos:Function = Math.cos, atan2:Function = Math.atan2;
  46. var PI:Number = Math.PI;
  47. function initialize():void
  48. {
  49.     main.addChild(new Bitmap(screen));
  50.     main.stage.addEventListener(KeyboardEvent.KEY_DOWN, Key.onKeyDown);
  51.     main.stage.addEventListener(KeyboardEvent.KEY_UP,   Key.onKeyUp);
  52.     Field.initialize();
  53.     initializeBlurs();
  54.     player.initialize();
  55.     scoreField = createTextField(SCREEN_WIDTH - 100010024, 0xff6666, TextFormatAlign.RIGHT);
  56.     timeField = createTextField(SCREEN_WIDTH / 2 - 100, SCREEN_HEIGHT - 4820048, 0xff6666, TextFormatAlign.RIGHT);
  57.     messageField = createTextField(SCREEN_WIDTH - 256025636, 0xff6666);
  58.     main.addChild(scoreField); main.addChild(timeField); main.addChild(messageField);
  59.     start(TITLE);
  60.     main.addEventListener(Event.ENTER_FRAME, update);
  61. }
  62. function update(event:Event):void
  63. {
  64.     if (circles.length <= 0) goToNextStage();
  65.     screen.lock();
  66.     screen.fillRect(screen.rect, BACKGROUND_COLOR);
  67.     updateBlurs();
  68.     var i:int;
  69.     for (i = 0; i < sparks.length; i++)  if (!sparks[i].update())  { sparks.splice(i, 1); i--; }
  70.     for (i = 0; i < shots.length; i++)   if (!shots[i].update())   { shots.splice(i, 1);  i--; }
  71.     for each (var c:Circle in circles) c.update();
  72.     for (i = 0; i < circles.length; i++) if (!circles[i].exists)   { circles.splice(i, 1); i--; }
  73.     if (gameOverTicks < 0) player.update();
  74.     for (i = 0; i < bullets.length; i++) if (!bullets[i].update()) { bullets.splice(i, 1); i--; }
  75.     Field.drawSideBoard();
  76.     screen.unlock();
  77.     if (gameOverTicks < 0)
  78.     {
  79.         var msStr:String = String(time % 1000);
  80.         while (msStr.length < 3) msStr = "0" + msStr;
  81.         timeField.text = String(int(time / 1000)) + "\"" + msStr;
  82.         if (time <= 0) start(GAME_OVER);
  83.         time -= 33;
  84.     }
  85.     else
  86.     {
  87.         gameOverTicks++;
  88.         if (gameOverTicks == GAME_OVER_DURATION) start(TITLE);
  89.         if (Key.button1 && gameOverTicks > BLOCK_GAME_START_DURATION) start(GAME);
  90.     }
  91. }
  92. function goToNextStage():void
  93. {
  94.     if (gameOverTicks < 0 && stage > 0) score += time;
  95.     scoreField.text = String(score);
  96.     stage++;
  97.     time = 5000;
  98.     addCircles((rand() - 0.5) * Field.size.x, 250.0 / (20.0 + stage), 5.0 + rand() * 2.0 + rand() * 2.0);
  99. }
  100. function start(mode:int):void
  101. {
  102.     switch (mode)
  103.     {
  104.         case TITLE:
  105.         {
  106.             clearActors();
  107.             player.hide();
  108.             gameOverTicks = GAME_OVER_DURATION;
  109.             messageField.y = SCREEN_HEIGHT / 3 * 2; messageField.text = "CircleCycle";
  110.             break;
  111.         }
  112.         case GAME:
  113.         {
  114.             clearActors();
  115.             player.start();
  116.             gameOverTicks = -1;
  117.             messageField.text = "";
  118.             score = 0; stage = 0;
  119.             break;
  120.         }
  121.         case GAME_OVER:
  122.         {
  123.             player.hide();
  124.             gameOverTicks = 0;
  125.             messageField.y = SCREEN_HEIGHT / 2; messageField.text = "GAME OVER";
  126.             timeField.text = "";
  127.             break;
  128.         }
  129.     }
  130. }
  131. function clearActors():void
  132. {
  133.     shots = null; bullets = null; sparks = null;
  134.     shots = new Vector.<Shot>; bullets = new Vector.<Bullet>; sparks = new Vector.<Spark>;
  135.     for each (var c:Circle in circles) c.remove();
  136.     circles = null; circles = new Vector.<Circle>;
  137. }
  138. // Game actor base class.
  139. class Actor
  140. {
  141.     public var pos:Vector3D = new Vector3D;
  142. }
  143. class VelocityActor extends Actor
  144. {
  145.     public var vel:Vector3D = new Vector3D;
  146.     public var ticks:int;
  147.     public function update():Boolean
  148.     {
  149.         pos.incrementBy(vel);
  150.         ticks++;
  151.         if (!Field.contains(pos) || ticks > 300return false;
  152.         return true;
  153.     }
  154. }
  155. // Player.
  156. var player:Player = new Player;
  157. class Player extends Actor
  158. {
  159.     private const INVINCIBLE_DURATION:int = 90;
  160.     private const COLLISION_SIZE:Number = 5.0;
  161.     private const SPEED:Number = 9.0;
  162.     private var vel:Vector3D = new Vector3D;
  163.     private var fireTicks:int;
  164.     private var sprite:Sprite = new Sprite;
  165.     public function initialize():void
  166.     {
  167.         var g:Graphics = sprite.graphics;
  168.         g.lineStyle(5, 0x008800);
  169.         g.moveTo(0, -10); g.lineTo(-10,10); g.lineTo(1010); g.lineTo(0, -10);
  170.         main.addChild(sprite);
  171.     }
  172.     public function start():void
  173.     {
  174.         pos.x = 0; pos.y = Field.size.y * 0.5;
  175.         vel.y = -5.0;
  176.     }
  177.     public function hide():void
  178.     {
  179.         sprite.x = sprite.y = 99999;
  180.     }
  181.     public function update():void
  182.     {
  183.         offset.x = offset.y = 0;
  184.         if (Key.left)  offset.x = -1;
  185.         if (Key.right) offset.x = 1;
  186.         if (Key.up)    offset.y = -1;
  187.         if (Key.down)  offset.y = 1;
  188.         if (offset.x != 0 && offset.y != 0) offset.scaleBy(0.7);
  189.         offset.scaleBy(SPEED); pos.incrementBy(offset);
  190.         pos.incrementBy(vel); vel.scaleBy(0.9);
  191.         if (pos.x < -SCREEN_WIDTH  / 2) pos.x = -SCREEN_WIDTH / 2;
  192.         if (pos.x >  SCREEN_WIDTH  / 2) pos.x =  SCREEN_WIDTH / 2;
  193.         if (pos.y < -SCREEN_HEIGHT / 2) pos.y = -SCREEN_HEIGHT / 2;
  194.         if (pos.y >  SCREEN_HEIGHT / 2) pos.y =  SCREEN_HEIGHT / 2;
  195.         Field.offsetX = pos.x * 0.33;
  196.         sprite.x = pos.x + SCREEN_WIDTH / 2 - Field.offsetX;
  197.         sprite.y = pos.y + SCREEN_WIDTH / 2;
  198.         var bc:int = time * 150 / 5000;
  199.         addBlur(pos.x, pos.y - 777250 - bc, 50 + bc, 100);
  200.         addBlur(pos.x, pos.y + 31515250 - bc, 50 + bc, 100);
  201.         drawBox(pos.x + time * 0.02 / 2, pos.y + 15, time * 0.0210,
  202.                 (150 - bc) * 0x10000 + bc * 0x100, 0000);
  203.         var i:int;
  204.         if (fireTicks <= 0 && shots.length <= 7 && abs(vel.y) < 1.0 && Key.button1)
  205.         {
  206.             fireTicks = 2;
  207.             var s:Shot;
  208.             for (i = 0; i < 7; i++)
  209.             {
  210.                 s = new Shot;
  211.                 s.pos.x = pos.x; s.pos.y = pos.y;
  212.                 var d:Number = (i - 3) * 0.1;
  213.                 s.vel.x = sin(d) * 24.0; s.vel.y = -cos(d) * 24.0;
  214.                 shots.push(s);
  215.             }
  216.         }
  217.         fireTicks--;
  218.         i = 0;
  219.         for each (var b:Bullet in bullets)
  220.         {
  221.             if (Vector3D.distance(pos, b.pos) <= COLLISION_SIZE)
  222.             {
  223.                 if (vel.y < 1.0)
  224.                 {
  225.                     vel.y += 20.0;
  226.                     addSparks(50, pos.x, pos.y, 30.015.0200200100);
  227.                     time /= 2;
  228.                 }
  229.                 else
  230.                 {
  231.                     bullets.splice(i, 1); i--;
  232.                 }
  233.             }
  234.             i++;
  235.         }
  236.     }
  237. }
  238. // Player's shots.
  239. var shots:Vector.<Shot> = new Vector.<Shot>;
  240. class Shot extends VelocityActor
  241. {
  242.     override public function update():Boolean
  243.     {
  244.         for each (var c:Circle in circles) if (checkHit(c)) return false;
  245.         addBlur(pos.x, pos.y, 201550150100);
  246.         return super.update();
  247.     }
  248.     private function checkHit(c:Circle):Boolean
  249.     {
  250.         for each (var cc:Circle in c.children) if (cc.exists && checkHit(cc)) return true;
  251.         if (c.exists && c.hasCollision && Vector3D.distance(pos, c.pos) < c.spec.spriteRadius + 20.0)
  252.         {
  253.             addSparks(1, pos.x, pos.y, 20.05.050150100);
  254.             c.damage(); return true;
  255.         }
  256.         return false;
  257.     }
  258. }
  259. // Circles' bullets.
  260. var bullets:Vector.<Bullet>;
  261. class Bullet extends VelocityActor
  262. {
  263.     public var baseVel:Vector3D = new Vector3D;
  264.     public var color:int, br:int, bg:int, bb:int, size:int;
  265.     override public function update():Boolean
  266.     {
  267.         var sz:Number = 1.5 + Math.sin(ticks * 0.2) * 0.4;
  268.         var a:Number = 0.8 + Math.sin(ticks * 0.45) * 0.2;
  269.         drawBox(pos.x, pos.y, size, size, color, sz, br * a, bg * a, bb * a);
  270.         if (ticks <= 15)
  271.         {
  272.             vel.x = baseVel.x * (ticks + 15) / 30.0; vel.y = baseVel.y * (ticks + 15) / 30.0;
  273.         }
  274.         return super.update();
  275.     }
  276. }
  277. // Circles.
  278. var circles:Vector.<Circle> = new Vector.<Circle>;
  279. class Circle extends Actor
  280. {
  281.     public var children:Vector.<Circle> = new Vector.<Circle>;
  282.     public var isTop:Boolean, exists:Boolean = true;
  283.     public var spec:CircleSpec;
  284.     public var bulletSpeedRatio:Number = 1.0;
  285.     public var rollAngle:Number, fireAngle:Number, fireSpeed:Number, angleInterval:Number;
  286.     public var baseAngle:Number;
  287.     public var ticks:int, shield:int;
  288.     public var hasCollision:Boolean;
  289.     public var isDamaged:Boolean;
  290.     public var sprite:Sprite = new Sprite;
  291.     public function start():void
  292.     {
  293.         var g:Graphics = sprite.graphics;
  294.         g.clear();
  295.         g.lineStyle(5, (int)(spec.r / 2) * 0x10000 + int(spec.g / 2) * 0x100 + int(spec.b / 2));
  296.         g.drawCircle(00, spec.spriteRadius);
  297.         main.addChild(sprite);
  298.         baseAngle = rollAngle = fireAngle = 0;
  299.         shield = spec.shield;
  300.     }
  301.     public function update():void
  302.     {
  303.         sprite.x = pos.x + SCREEN_WIDTH / 2 - Field.offsetX;
  304.         sprite.y = pos.y + SCREEN_HEIGHT / 2;
  305.         var i:int;
  306.         if (isDamaged)
  307.         {
  308.             isDamaged = false;
  309.             var da:Number = ticks * 0.1, sr:Number = spec.spriteRadius, bc:int = sr * 0.5;
  310.             for (i = 0; i < bc; i++)
  311.             {
  312.                 addBlur(pos.x + sr * sin(da), pos.y + sr * cos(da),
  313.                         9 + rand() * 79 + rand() * 7, rand() * 128 + 127, rand() * 1280);
  314.                 da += PI * 2 / bc;
  315.             }
  316.         }
  317.         if (spec.fireInterval > 0 && ticks % spec.fireInterval == 0 && pos.y < 0)
  318.         {
  319.             if (spec.isAimingBaseAngle) baseAngle = atan2(player.pos.x - pos.x, player.pos.y - pos.y);
  320.             var ba:Number = baseAngle + rollAngle + fireAngle;
  321.             var srv:Number = -spec.bulletSpeedWhipVel * 2/ spec.bulletCount;
  322.             for (i = 0; i < spec.bulletCount; i++) fire(ba, 1.0 + spec.bulletSpeedWhipVel + srv * i);
  323.         }
  324.         ticks++;
  325.         if (spec.childrenCount <= 0return;
  326.         rollAngle = spec.rollAngle.getValue(ticks);
  327.         fireAngle = spec.fireAngle.getValue(ticks);
  328.         fireSpeed = spec.fireSpeed.getValue(ticks);
  329.         angleInterval = spec.angleInterval.getValue(ticks);
  330.         if (spec.isAimingRollAngle) rollAngle += atan2(player.pos.x - pos.x, player.pos.y - pos.y);
  331.         var a:Number = rollAngle - angleInterval * (children.length - 1) / 2 - angleInterval;
  332.         for each (var c:Circle in children)
  333.         {
  334.             a += angleInterval;
  335.             if (!c.exists) continue;
  336.             c.pos.x = pos.x + sin(a) * spec.radius;
  337.             c.pos.y = pos.y + cos(a) * spec.radius;
  338.             c.baseAngle = a + fireAngle;
  339.             c.update();
  340.         }
  341.         if (isTop && pos.y < -Field.size.y * 0.5) pos.y += 7.0;
  342.     }
  343.     private function fire(a:Number, sr:Number):void
  344.     {
  345.         var b:Bullet = new Bullet;
  346.         b.pos.x = pos.x; b.pos.y = pos.y;
  347.         var bs:Number = spec.bulletSpeed * bulletSpeedRatio * sr;
  348.         b.baseVel.x = sin(a) * bs; b.baseVel.y = cos(a) * bs;
  349.         b.size = spec.bulletSize;
  350.         b.br = spec.r; b.bg = spec.g; b.bb = spec.b;
  351.         b.color = int(b.br / 4) * 0x10000 + int(b.bg / 4) * 0x100 + int(b.bb / 4);
  352.         bullets.push(b);
  353.     }
  354.     public function damage():void
  355.     {
  356.         isDamaged = true;
  357.         shield--;
  358.         if (shield <= 0) remove(true);
  359.     }
  360.     public function remove(isDestroyed:Boolean = false):void
  361.     {
  362.         main.removeChild(sprite);
  363.         for each (var c:Circle in children) if (c.exists) c.remove();
  364.         exists = false;
  365.         if (!isDestroyed) return;
  366.         var ba:Number = ticks * 0.1, sr:Number = spec.spriteRadius, bc:int = sr * 0.5;
  367.         for (var i:int = 0; i < bc; i++)
  368.         {
  369.             addSparks(1, pos.x + sr * sin(ba), pos.y + sr * cos(ba), 10.010.0, spec.r, spec.g, spec.b);
  370.             ba += PI * 2 / bc;
  371.         }
  372.     }
  373. }
  374. class CircleSpec
  375. {
  376.     public static const FIX:int = 0, WEDGE:int = 1;
  377.     public var radius:Number, spriteRadius:Number;
  378.     public var isRound:Boolean;
  379.     public var rollAngle:Waveform = new Waveform;
  380.     public var isAimingRollAngle:Boolean, isAimingBaseAngle:Boolean;
  381.     public var fireAngle:Waveform = new Waveform, fireSpeed:Waveform = new Waveform;
  382.     public var fireInterval:int = -1;
  383.     public var angleInterval:Waveform = new Waveform;
  384.     public var bulletSpeed:Number = 7.0, bulletSize:Number = 15.0;
  385.     public var bulletSpeedFanType:int, bulletSpeedFanVel:Number = 0;
  386.     public var fireDelayType:int, fireDelayVel:Number = 0;
  387.     public var bulletCount:int = 1, bulletSpeedWhipVel:Number = 0;
  388.     public var r:int, g:int, b:int;
  389.     public var childrenCount:int;
  390.     public var shield:int;
  391.     public function set(childrenCount:int, radius:Number, childRadius:Number):void
  392.     {
  393.         this.childrenCount = childrenCount;
  394.         this.radius = radius; spriteRadius = radius + childRadius;
  395.         shield = radius * 0.7;
  396.         rollAngle.width = (0.5 + rand() * 0.5) * ((int)(rand() * 2) * 2 - 1);
  397.         isRound = (rand() < 0.25);
  398.         if (isRound) {
  399.             rollAngle.type = Waveform.MONOTONE;
  400.             rollAngle.interval = 60 + rand() * 60;
  401.             if (rand() < 0.4) fireAngle.type = Waveform.MONOTONE;
  402.             fireAngle.width = (2.0 + rand() * 2.0) * ((int)(rand() * 2) * 2 - 1);
  403.             fireAngle.interval = 90 + rand() * 90;
  404.             if (rand() < 0.3) fireAngle.center = rand() * PI * 2;
  405.             angleInterval.center = PI * 2 / childrenCount;
  406.         }
  407.         else
  408.         {
  409.             isAimingRollAngle = true;
  410.             if (rand() < 0.3) rollAngle.type = Waveform.SIN;
  411.             rollAngle.interval = 120 + rand() * 90;
  412.             if (rand() < 0.3) angleInterval.type = Waveform.SIN;
  413.             angleInterval.center = ((2.0 + rand() * 2.0) / childrenCount) * ((int)(rand() * 2) * 2 - 1);
  414.             angleInterval.width = angleInterval.center * (0.3 + rand() * 0.3);
  415.             angleInterval.interval = 60 + rand() * 60;
  416.         }
  417.         if (rand() < 0.5) bulletSpeedFanType = WEDGE;
  418.         if (rand() < 0.5) bulletSpeedFanVel = (0.3 + rand() * 0.2) * ((int)(rand() * 2) * 2 - 1);
  419.         if (rand() < 0.5) fireDelayType = WEDGE;
  420.         if (rand() < 0.5) fireDelayVel = (8.0 + rand() * 6.0) * ((int)(rand() * 2) * 2 - 1);
  421.     }
  422. }
  423. class Waveform
  424. {
  425.     public static const FIX:int = 0, MONOTONE:int = 1, SIN:int = 2;
  426.     public var type:int = FIX, center:Number = 0, width:Number = 0, interval:int = 1;
  427.     public function getValue(ticks:int):Number
  428.     {
  429.         switch (type)
  430.         {
  431.             case FIX:      return center;
  432.             case MONOTONE: return center + width * ticks * 2 / interval;
  433.             case SIN:      return center + width * sin(PI * 2 * ticks / interval);
  434.         }
  435.         return 0;
  436.     }
  437. }
  438. function addCircles(x:Number, depth:int, fireIntervalRatio:Number, bulletSpeed:Number):void
  439. {
  440.     var radius:Number = (20 + rand() * 20) * depth;
  441.     var c:Circle = new Circle;
  442.     c.pos.x = x; c.pos.y = -Field.size.y - radius;
  443.     c.isTop = true; c.hasCollision = true;
  444.     var r:int, g:int, b:int;
  445.     r = 127 + rand() * 128; g = 127 + rand() * 128; b = 127 + rand() * 128;
  446.     var sps:Vector.<CircleSpec> = new Vector.<CircleSpec>;
  447.     var turretCount:int = createCircleSpecs(sps, radius, depth, r, g, b);
  448.     var sp:CircleSpec;
  449.     for each (sp in sps) if (sp.isRound) turretCount *= 0.75;
  450.     sp = sps[0];
  451.     sp.fireInterval = turretCount * fireIntervalRatio + 1;
  452.     sp.bulletSpeed = bulletSpeed; sp.bulletSize = 10.0 + depth * 3;
  453.     addCircleChildren(c, sps.length - 1, sps, 1.00);
  454.     circles.push(c);
  455. }
  456. function createCircleSpecs(sps:Vector.<CircleSpec>, radius:Number, depth:int, r:int, g:int, b:int):int
  457. {
  458.     var sp:CircleSpec = new CircleSpec;
  459.     sp.r = r; sp.g = g; sp.b = b;
  460.     var turretCount:int;
  461.     if (depth == 0)
  462.     {
  463.         sp.radius = 0; sp.spriteRadius = radius; sp.childrenCount = 0;
  464.         if (rand() < 0.3)
  465.         {
  466.             sp.bulletCount = 2 + rand() * 5;
  467.             sp.bulletSpeedWhipVel = 0.2 + rand() * 0.2;
  468.             turretCount = sp.bulletCount * 0.75;
  469.         }
  470.         else turretCount = 1;
  471.     }
  472.     else
  473.     {
  474.         sp.childrenCount = 1 + rand() * 7;
  475.         var cr:Number = radius * (0.33 + rand() * 0.1);
  476.         sp.set(sp.childrenCount, radius, cr);
  477.         turretCount = createCircleSpecs(sps, cr, depth - 1, r, g, b) * sp.childrenCount;
  478.     }
  479.     sps.push(sp);
  480.     return turretCount;
  481. }
  482. function addCircleChildren(c:Circle, index:int, sps:Vector.<CircleSpec>,
  483.                            bulletSpeedRatio:Number, fireDelay:Number):void
  484. {
  485.     var sp:CircleSpec = sps[index];
  486.     var bsv:Number = -sp.bulletSpeedFanVel * 2 / sp.childrenCount;
  487.     var fdv:Number = -sp.fireDelayVel * 2 / sp.childrenCount;
  488.     if (sp.bulletSpeedFanType == CircleSpec.WEDGE) bsv *= 2;
  489.     if (sp.fireDelayType == CircleSpec.WEDGE) fdv *= 2;
  490.     for (var i:int = 0; i < sp.childrenCount; i++)
  491.     {
  492.         var cc:Circle = new Circle;
  493.         var bsr:Number;
  494.         if (sp.bulletSpeedFanType == CircleSpec.FIX || i < sp.childrenCount / 2) bsr = 1.0 + sp.bulletSpeedFanVel + bsv * i;
  495.         else bsr = 1.0 + sp.bulletSpeedFanVel + bsv * (sp.childrenCount - 1 - i);
  496.         var fd:Number;
  497.         if (sp.fireDelayType == CircleSpec.FIX || i < sp.childrenCount / 2) fd = sp.fireDelayVel + fdv * i;
  498.         else fd = sp.fireDelayVel + fdv * (sp.childrenCount - 1 - i);
  499.         addCircleChildren(cc, index - 1, sps, bsr * bulletSpeedRatio, fireDelay + fd);
  500.         c.children.push(cc);
  501.     }
  502.     c.bulletSpeedRatio = bulletSpeedRatio;
  503.     c.ticks = fireDelay;
  504.     c.spec = sp; c.start();
  505. }
  506. // Sparks.
  507. var sparks:Vector.<Spark>;
  508. class Spark extends VelocityActor
  509. {
  510.     public var size:Number;
  511.     public var r:int, g:int, b:int;
  512.     override public function update():Boolean
  513.     {
  514.         vel.scaleBy(0.99);
  515.         size *= 0.95;
  516.         r += (BACKGROUND_BRIGHTNESS - r) * 0.1;
  517.         g += (BACKGROUND_BRIGHTNESS - g) * 0.1;
  518.         b += (BACKGROUND_BRIGHTNESS - b) * 0.1;
  519.         var cr:Number = rand() + 0.5;
  520.         var br:int = r * cr, bg:int = g * cr, bb:int = b * cr;
  521.         if (br > 255) br = 255;
  522.         if (bg > 255) bg = 255;
  523.         if (bb > 255) bb = 255;
  524.         drawBox(pos.x, pos.y, size, size, r * 0x10000 + g * 0x100 + b, 1.5, br, bg, bb);
  525.         return super.update();
  526.     }
  527. }
  528. function addSparks(count:int, x:Number, y:Number, speed:Number, size:Number, r:int, g:int ,b:int):void
  529. {
  530.     for (var i:int = 0; i < count; i++)
  531.     {
  532.         var s:Spark = new Spark;
  533.         s.pos.x = x; s.pos.y = y;
  534.         var a:Number = rand() * PI * 2, sp:Number = speed * (0.5 + rand());
  535.         s.vel.x = Math.sin(a) * sp; s.vel.y = Math.cos(a) * sp;
  536.         s.size = size;
  537.         s.r = r; s.g = g; s.b = b;
  538.         s.ticks = 15 + 15 * rand();
  539.         sparks.push(s);
  540.     }
  541. }
  542. // Game field.
  543. class Field
  544. {
  545.     public static const SIDE_BOARD_WIDTH:Number = SCREEN_WIDTH / 6;
  546.     public static var size:Vector3D = new Vector3D;
  547.     public static var offsetX:Number = 0;
  548.     public static function initialize():void
  549.     {
  550.         size.x = SCREEN_WIDTH * 1.1 / 2; size.y = SCREEN_HEIGHT * 1.1 / 2;
  551.     }
  552.     public static function drawSideBoard():void
  553.     {
  554.         rect.width = SIDE_BOARD_WIDTH; rect.height = SCREEN_HEIGHT; rect.y = 0;
  555.         rect.x = 0;                         screen.fillRect(rect, BACKGROUND_COLOR);
  556.         rect.x = SCREEN_WIDTH - rect.width; screen.fillRect(rect, BACKGROUND_COLOR);
  557.     }
  558.     public static function contains(p:Vector3D):Boolean
  559.     {
  560.         return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  561.     }
  562. }
  563. // Blur effect.
  564. const BLUR_MAX_COUNT:int = 512, BLUR_HISTORY_COUNT:int = 6;
  565. var blurs:Vector.<Vector.<Blur>> = new Vector.<Vector.<Blur>>(BLUR_HISTORY_COUNT, true);
  566. var blurCounts:Vector.<int> = new Vector.<int>(BLUR_HISTORY_COUNT, true);
  567. var blurIndex:int;
  568. class Blur
  569. {
  570.     public var pos:Vector3D = new Vector3D;
  571.     public var width:Number, height:Number;
  572.     public var r:int, g:int, b:int;
  573.     public function update():void
  574.     {
  575.         rect.x = pos.x - width  / 2 - Field.offsetX; rect.width = width;
  576.         rect.y = pos.y - height / 2; rect.height = height;
  577.         screen.fillRect(rect, r * 0x10000 + g * 0x100 + b);
  578.         width *= 1.2; height *= 1.2;
  579.         r += (BACKGROUND_BRIGHTNESS - r) * 0.2;
  580.         g += (BACKGROUND_BRIGHTNESS - g) * 0.2;
  581.         b += (BACKGROUND_BRIGHTNESS - b) * 0.2;
  582.     }
  583. }
  584. function drawBox(x:Number, y:Number, w:int, h:int, color:int,
  585.                  blurSizeRatio:Number, br:int, bg:int, bb:int):void
  586. {
  587.     rect.x = x - w / 2 + SCREEN_WIDTH / 2 - Field.offsetX;
  588.     rect.y = y - h / 2 + SCREEN_HEIGHT / 2;
  589.     rect.width = w; rect.height = h;
  590.     screen.fillRect(rect, color);
  591.     if (blurSizeRatio > 0) addBlur(x, y, w * blurSizeRatio, h * blurSizeRatio, br, bg, bb);
  592. }
  593. function addBlur(x:Number, y:Number, w:Number, h:Number, r:int, g:int, b:int):void
  594. {
  595.     if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  596.     var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  597.     bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  598.     bl.width = w; bl.height = h;
  599.     bl.r = r; bl.g = g; bl.b = b;
  600.     blurCounts[blurIndex]++;
  601. }
  602. function updateBlurs():void
  603. {
  604.     var bi:int = blurIndex + 1;
  605.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  606.     {
  607.         if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  608.         for (var j:int = 0; j < blurCounts[bi]; j++) blurs[bi][j].update();
  609.         bi++;
  610.     }
  611.     blurIndex++;
  612.     if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  613.     blurCounts[blurIndex] = 0;
  614. }
  615. function initializeBlurs():void
  616. {
  617.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  618.     {
  619.         var bs:Vector.<Blur> = new Vector.<Blur>(BLUR_MAX_COUNT, true);
  620.         for (var j:int = 0; j < BLUR_MAX_COUNT; j++) bs[j] = new Blur;
  621.         blurs[i] = bs; blurCounts[i] = 0;
  622.     }
  623.     blurIndex = 0;
  624. }
  625. // Utility classes and functions.
  626. class Key
  627. {
  628.     public static var left:Boolean, up:Boolean, right:Boolean, down:Boolean;
  629.     public static var button1:Boolean;
  630.     public static function onKeyDown(event:KeyboardEvent):void
  631.     {
  632.         switch (event.keyCode)
  633.         {
  634.             case 0x25:case 0x41: left =    truebreak;
  635.             case 0x26:case 0x57: up =      truebreak;
  636.             case 0x27:case 0x44: right =   truebreak;
  637.             case 0x28:case 0x53: down =    truebreak;
  638.             case 0x5a:case 0xbf:
  639.             case 0x58:case 0xbe: button1 = truebreak;
  640.         }
  641.     }
  642.     public static function onKeyUp(event:KeyboardEvent):void
  643.     {
  644.         switch (event.keyCode)
  645.         {
  646.             case 0x25:case 0x41: left =    falsebreak;
  647.             case 0x26:case 0x57: up =      falsebreak;
  648.             case 0x27:case 0x44: right =   falsebreak;
  649.             case 0x28:case 0x53: down =    falsebreak;
  650.             case 0x5a:case 0xbf:
  651.             case 0x58:case 0xbe: button1 = falsebreak;
  652.         }
  653.     }
  654. }
  655. function createTextField(x:int, y:int, width:int, size:int, color:int,
  656.                          align:String = TextFormatAlign.LEFT):TextField
  657. {
  658.     var fm:TextFormat = new TextFormat;
  659.     fm.font = "_typewriter"; fm.bold = true;
  660.     fm.size = size; fm.color = color; fm.align = align;
  661.     var fi:TextField = new TextField;
  662.     fi.defaultTextFormat = fm;
  663.     fi.x = x; fi.y = y; fi.width = width; fi.selectable = false;
  664.     return fi;
  665. }
noswf
  1. // forked from ABA's CircleCycle
  2. // CircleCycle.as
  3. //  Destroy circles and avoid incoming bullets.
  4. //  <Control>
  5. //   Movement: Arrow or [WASD] keys.
  6. //   Fire:    [Z] or [/] key.
  7. //   Slow:    [X] or [.] key.
  8. package
  9. {
  10.     import flash.display.Sprite;
  11.     [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  12.     public class CircleCycle extends Sprite
  13.     {
  14.         public function CircleCycle()
  15.         {
  16.             main = this;
  17.             initialize();
  18.         }
  19.     }
  20. }
  21. import flash.display.Sprite;
  22. import flash.display.Bitmap;
  23. import flash.display.BitmapData;
  24. import flash.geom.Rectangle;
  25. import flash.geom.Vector3D;
  26. import flash.text.TextField;
  27. import flash.text.TextFormat;
  28. import flash.text.TextFormatAlign;
  29. import flash.events.Event;
  30. import flash.events.KeyboardEvent;
  31. const SCREEN_WIDTH:int = 465, SCREEN_HEIGHT:int = 465;
  32. const BACKGROUND_BRIGHTNESS:int = 200;
  33. const BACKGROUND_COLOR:int = BACKGROUND_BRIGHTNESS * 0x10000 + BACKGROUND_BRIGHTNESS * 0x100 + BACKGROUND_BRIGHTNESS;
  34. const GAME_OVER_DURATION:int = 150, BLOCK_GAME_START_DURATION:int = 30;
  35. var main:Sprite;
  36. var screen:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  37. var scoreField:TextField = new TextField, timeField:TextField = new TextField, messageField:TextField = new TextField;
  38. var gameOverTicks:int, score:int, stage:int, targetCircleCount:int, ticks:int, time:int;
  39. function initialize():void
  40. {
  41.     main.addChild(new Bitmap(screen));
  42.     main.stage.addEventListener(KeyboardEvent.KEY_DOWN, Key.onKeyDown);
  43.     main.stage.addEventListener(KeyboardEvent.KEY_UP,   Key.onKeyUp);
  44.     Field.initialize();
  45.     initializeBlurs();
  46.     scoreField = createTextField(SCREEN_WIDTH - 100010024, 0xff6666, TextFormatAlign.RIGHT);
  47.     timeField = createTextField(SCREEN_WIDTH / 2 - 120, SCREEN_HEIGHT - 4020040, 0xff6666, TextFormatAlign.RIGHT);
  48.     messageField = createTextField(SCREEN_WIDTH - 256025636, 0xff6666);
  49.     main.addChild(scoreField); main.addChild(timeField); main.addChild(messageField);
  50.     startTitle();
  51.     main.addEventListener(Event.ENTER_FRAME, update);
  52. }
  53. function update(event:Event):void
  54. {
  55.     screen.lock();
  56.     screen.fillRect(screen.rect, BACKGROUND_COLOR);
  57.     updateBlurs();
  58.     var i:int;
  59.     for (i = 0; i < sparks.length; i++)  if (!sparks[i].update())  { sparks.splice(i, 1);  i--; }
  60.     for (i = 0; i < shots.length; i++)   if (!shots[i].update())   { shots.splice(i, 1);   i--; }
  61.     for (i = 0; i < bonuses.length; i++) if (!bonuses[i].update()) { bonuses.splice(i, 1); i--; }
  62.     if (targetCircleCount <= 0) goToNextStage();
  63.     if (ticks % 50 == 0) addBackgroundCircles((rand() - 0.5) * Field.size.x * 1.5,
  64.                                               200.0 / (20.0 + stage), 5.0 + rand() * 2.0 + rand() * 2.0);
  65.     ticks++;
  66.     targetCircleCount = 0;
  67.     for each (var c:Circle in circles) c.update();
  68.     for (i = 0; i < circles.length; i++) if (!circles[i].exists)   { circles.splice(i, 1); i--; }
  69.     if (gameOverTicks < 0) Player.update();
  70.     for (i = 0; i < bullets.length; i++) if (!bullets[i].update()) { bullets.splice(i, 1); i--; }
  71.     Field.drawSideBoard();
  72.     screen.unlock();
  73.     if (gameOverTicks < 0)
  74.     {
  75.         time -= 33;
  76.         if (Key.button2) time -= 33;
  77.         if (time <= 0)
  78.         {
  79.             time = 0; startGameClear();
  80.         }
  81.         var msStr:String = String(time % 1000);
  82.         while (msStr.length < 3) msStr = "0" + msStr;
  83.         timeField.text = String(int(time / 1000)) + "\"" + msStr;
  84.     }
  85.     else
  86.     {
  87.         gameOverTicks++;
  88.         if (gameOverTicks == GAME_OVER_DURATION) startTitle();
  89.         if (Key.button1 && gameOverTicks > BLOCK_GAME_START_DURATION) startGame();
  90.     }
  91. }
  92. function goToNextStage():void
  93. {
  94.     if (rand() < 0.5) addTargetCircles((rand() - 0.5) * Field.size.x, 2,
  95.                                        200.0 / (20.0 + stage), 5.0 + rand() * 2.0 + rand() * 2.0false);
  96.     else              addTargetCircles((rand() - 0.5) * Field.size.x * 0.71,
  97.                                        400.0 / (20.0 + stage), 5.0 + rand() * 2.0 + rand() * 2.0true);
  98.     stage += 15;
  99. }
  100. function startTitle():void
  101. {
  102.     clearActors();
  103.     gameOverTicks = GAME_OVER_DURATION;
  104.     messageField.y = SCREEN_HEIGHT / 3 * 2; messageField.text = "CircleCycle";
  105. }
  106. function startGame():void
  107. {
  108.     clearActors();
  109.     Player.start();
  110.     gameOverTicks = -1;
  111.     messageField.text = "";
  112.     score = 0; scoreField.text = "0"; stage = 0; time = 60000;
  113. }
  114. function startGameOver():void
  115. {
  116.     gameOverTicks = 0;
  117.     messageField.y = SCREEN_HEIGHT / 2; messageField.text = "GAME OVER";
  118. }
  119. function startGameClear():void
  120. {
  121.     gameOverTicks = 0;
  122.     messageField.y = SCREEN_HEIGHT / 2; messageField.text = "COMPLETE!";
  123. }
  124. function clearActors():void
  125. {
  126.     shots = null; bullets = null; sparks = null; bonuses = null; circles = null;
  127.     shots = new Vector.<Shot>; bullets = new Vector.<Bullet>; sparks = new Vector.<Spark>; bonuses = new Vector.<Bonus>;
  128.     circles = new Vector.<Circle>; targetCircleCount = 0;
  129. }
  130. // Game actor base class.
  131. class Actor
  132. {
  133.     public var pos:Vector3D = new Vector3D;
  134. }
  135. class VelocityActor extends Actor
  136. {
  137.     public var vel:Vector3D = new Vector3D;
  138.     public var ticks:int, disappearTicks:int = 300;
  139.     public function update():Boolean
  140.     {
  141.         pos.incrementBy(vel);
  142.         ticks++;
  143.         if (!Field.contains(pos) || ticks > disappearTicks) return false;
  144.         return true;
  145.     }
  146. }
  147. // Player.
  148. class Player
  149. {
  150.     private static const COLLISION_SIZE:Number = 5.0;
  151.     private static const SPEED:Number = 9.0;
  152.     public static var pos:Vector3D = new Vector3D;
  153.     private static var fireTicks:int;
  154.     public static function start():void
  155.     {
  156.         pos.x = 0; pos.y = Field.size.y * 0.5;
  157.     }
  158.     public static function update():void
  159.     {
  160.         offset.x = offset.y = 0;
  161.         if (Key.left)  offset.x = -1;
  162.         if (Key.right) offset.x = 1;
  163.         if (Key.up)    offset.y = -1;
  164.         if (Key.down)  offset.y = 1;
  165.         if (offset.x != 0 && offset.y != 0) offset.scaleBy(0.7);
  166.         if (Key.button2) offset.scaleBy(0.5);
  167.         offset.scaleBy(SPEED); pos.incrementBy(offset);
  168.         if (pos.x < -SCREEN_WIDTH  / 2) pos.x = -SCREEN_WIDTH / 2;
  169.         if (pos.x >  SCREEN_WIDTH  / 2) pos.x =  SCREEN_WIDTH / 2;
  170.         if (pos.y < -SCREEN_HEIGHT / 2) pos.y = -SCREEN_HEIGHT / 2;
  171.         if (pos.y >  SCREEN_HEIGHT / 2) pos.y =  SCREEN_HEIGHT / 2;
  172.         Field.offsetX = pos.x * 0.33;
  173.         drawCircle(pos, 157, 0x008800, 0.5);
  174.         addBlur(pos.x, pos.y, 2020100200100);
  175.         if (fireTicks <= 0 && shots.length <= 14 && Key.button1)
  176.         {
  177.             fireTicks = 2;
  178.             var s:Shot;
  179.             for (var i:int = 0; i < 7; i++)
  180.             {
  181.                 s = new Shot;
  182.                 s.pos.x = pos.x; s.pos.y = pos.y;
  183.                 var a:Number = (i - 3) * 0.1;
  184.                 s.vel.x = sin(a) * 24.0; s.vel.y = -cos(a) * 24.0;
  185.                 shots.push(s);
  186.             }
  187.         }
  188.         fireTicks--;
  189.         for each (var b:Bullet in bullets)
  190.         {
  191.             if (Vector3D.distance(pos, b.pos) <= COLLISION_SIZE)
  192.             {
  193.                 addSparks(100, Player.pos.x, Player.pos.y, 30.015.0200100100);
  194.                 startGameOver(); break;
  195.             }
  196.         }
  197.     }
  198. }
  199. // Player's shots.
  200. var shots:Vector.<Shot>;
  201. class Shot extends VelocityActor
  202. {
  203.     override public function update():Boolean
  204.     {
  205.         for each (var c:Circle in circles) if (checkHit(c)) return false;
  206.         addBlur(pos.x, pos.y, 201550150100);
  207.         return super.update();
  208.     }
  209.     private function checkHit(c:Circle):Boolean
  210.     {
  211.         for each (var cc:Circle in c.children) if (cc.exists && checkHit(cc)) return true;
  212.         if (c.exists && c.hasCollision && Vector3D.distance(pos, c.pos) < c.spec.visualRadius + 20.0)
  213.         {
  214.             addSparks(1, pos.x, pos.y, 20.05.050150100);
  215.             c.damage(); return true;
  216.         }
  217.         return false;
  218.     }
  219. }
  220. // Circles' bullets.
  221. var bullets:Vector.<Bullet>;
  222. class Bullet extends VelocityActor
  223. {
  224.     public var baseVel:Vector3D = new Vector3D;
  225.     public var color:int, br:int, bg:int, bb:int, size:int;
  226.     override public function update():Boolean
  227.     {
  228.         var sz:Number = 1.5 + Math.sin(ticks * 0.2) * 0.4;
  229.         var a:Number = 0.8 + Math.sin(ticks * 0.45) * 0.2;
  230.         drawBox(pos.x, pos.y, size, size, color, sz, br * a, bg * a, bb * a);
  231.         if (ticks <= 15)
  232.         {
  233.             vel.x = baseVel.x * (ticks + 15) / 30.0; vel.y = baseVel.y * (ticks + 15) / 30.0;
  234.         }
  235.         else
  236.         {
  237.             vel.x = baseVel.x; vel.y = baseVel.y;
  238.         }
  239.         if (Key.button2) vel.scaleBy(0.5);
  240.         return super.update();
  241.     }
  242. }
  243. // Circles.
  244. var circles:Vector.<Circle>;
  245. class Circle extends Actor
  246. {
  247.     public var children:Vector.<Circle> = null;
  248.     public var isTop:Boolean, exists:Boolean = true;
  249.     public var spec:CircleSpec;
  250.     public var bulletSpeedRatio:Number = 1.0;
  251.     public var rollAngle:Number = 0, fireAngle:Number = 0, fireSpeed:Number, angleInterval:Number;
  252.     public var baseAngle:Number = 0;
  253.     public var ticks:int, shield:int;
  254.     public var hasCollision:Boolean, isTarget:Boolean, isDamaged:Boolean;
  255.     public var xReverse:Number = 1.0;
  256.     public var circleWidth:Number = 5.0;
  257.     public var color:int;
  258.     public function start():void
  259.     {
  260.         color = (int)(spec.r / 2) * 0x10000 + int(spec.g / 2) * 0x100 + int(spec.b / 2);
  261.         shield = spec.shield;
  262.     }
  263.     public function update():void
  264.     {
  265.         var vr:Number = spec.visualRadius;
  266.         if (spec.fireInterval > 0) vr *= ((ticks % spec.fireInterval) / spec.fireInterval * 0.5 + 1.0);
  267.         drawCircle(pos, vr, circleWidth, color);
  268.         var i:int;
  269.         if (isDamaged)
  270.         {
  271.             isDamaged = false;
  272.             var da:Number = ticks * 0.1, sr:Number = spec.visualRadius, bc:int = sr * 0.5;
  273.             for (i = 0; i < bc; i++)
  274.             {
  275.                 addBlur(pos.x + sr * sin(da), pos.y + sr * cos(da),
  276.                         9 + rand() * 79 + rand() * 7, rand() * 128 + 64, rand() * 128 + 12764);
  277.                 da += PI * 2 / bc;
  278.             }
  279.         }
  280.         if (spec.fireInterval > 0 && ticks % spec.fireInterval == 0 && pos.y < 0 &&
  281.             pos.x - Field.offsetX > -Field.size.x + Field.SIDE_BOARD_WIDTH &&
  282.             pos.x - Field.offsetX <  Field.size.x - Field.SIDE_BOARD_WIDTH &&
  283.             (!spec.isAimingBaseAngle || Vector3D.distance(pos, Player.pos) > 120))
  284.          {
  285.             var ba:Number;
  286.             if (spec.isAimingBaseAngle) ba = atan2(Player.pos.x - pos.x, Player.pos.y - pos.y);
  287.             else ba = baseAngle * xReverse;
  288.             ba += rollAngle + fireAngle;
  289.             var srv:Number = -spec.bulletSpeedWhipVel * 2 / spec.bulletCount;
  290.             for (i = 0; i < spec.bulletCount; i++) fire(ba, 1.0 + spec.bulletSpeedWhipVel + srv * i);
  291.         }
  292.         ticks++;
  293.         if (isTop && isTarget && pos.y < -Field.size.y * 0.5) pos.y += 7.0;
  294.         if (isTop && !isTarget)
  295.         {
  296.             pos.y += 3.0;
  297.             if (pos.y > Field.size.y + spec.radius) remove();
  298.         }
  299.         if (isTarget) targetCircleCount++;
  300.         if (children == nullreturn;
  301.         rollAngle = spec.rollAngle.getValue(ticks);
  302.         fireAngle = spec.fireAngle.getValue(ticks);
  303.         fireSpeed = spec.fireSpeed.getValue(ticks);
  304.         angleInterval = spec.angleInterval.getValue(ticks);
  305.         if (spec.isAimingRollAngle) rollAngle += atan2(Player.pos.x - pos.x, Player.pos.y - pos.y) * xReverse;
  306.         var a:Number = rollAngle - angleInterval * (children.length - 1) / 2 - angleInterval;
  307.         for each (var c:Circle in children)
  308.         {
  309.             a += angleInterval;
  310.             if (!c.exists) continue;
  311.             c.pos.x = pos.x + sin(a) * spec.radius * xReverse;
  312.             c.pos.y = pos.y + cos(a) * spec.radius;
  313.             c.baseAngle = a + fireAngle;
  314.             c.update();
  315.         }
  316.     }
  317.     private function fire(a:Number, sr:Number):void
  318.     {
  319.         var b:Bullet = new Bullet;
  320.         b.pos.x = pos.x; b.pos.y = pos.y;
  321.         var bs:Number = spec.bulletSpeed * bulletSpeedRatio * sr;
  322.         b.baseVel.x = sin(a) * bs; b.baseVel.y = cos(a) * bs;
  323.         b.size = spec.bulletSize;
  324.         b.br = spec.r; b.bg = spec.g; b.bb = spec.b;
  325.         b.color = int(b.br / 4) * 0x10000 + int(b.bg / 4) * 0x100 + int(b.bb / 4);
  326.         bullets.push(b);
  327.     }
  328.     public function damage():void
  329.     {
  330.         isDamaged = true;
  331.         shield--;
  332.         if (shield <= 0) remove(true);
  333.     }
  334.     public function remove(isDestroyed:Boolean = false):void
  335.     {
  336.         for each (var c:Circle in children) if (c.exists) c.remove();
  337.         children = null;
  338.         exists = false;
  339.         if (!isDestroyed) return;
  340.         var sa:Number = ticks * 0.1, sr:Number = spec.visualRadius, sc:int = sr * 0.5, i:int;
  341.         for (i = 0; i < sc; i++)
  342.         {
  343.             addSparks(1, pos.x + sr * sin(sa), pos.y + sr * cos(sa), 10.010.0, spec.r, spec.g, spec.b);
  344.             sa += PI * 2 / sc;
  345.         }
  346.         addBonuses(sr * sr * 2 / (abs(pos.y - Player.pos.y) + 30.0), pos.x, pos.y, 10.0);
  347.     }
  348.     public function setXReverse():void
  349.     {
  350.         xReverse = -1.0;
  351.         for each (var c:Circle in children) c.setXReverse();
  352.     }
  353. }
  354. class CircleSpec
  355. {
  356.     public static const FIX:int = 0, WEDGE:int = 1;
  357.     public var radius:Number, visualRadius:Number;
  358.     public var isRound:Boolean;
  359.     public var rollAngle:Waveform = new Waveform;
  360.     public var isAimingRollAngle:Boolean, isAimingBaseAngle:Boolean;
  361.     public var fireAngle:Waveform = new Waveform, fireSpeed:Waveform = new Waveform;
  362.     public var fireInterval:int = -1;
  363.     public var angleInterval:Waveform = new Waveform;
  364.     public var bulletSpeed:Number = 7.0, bulletSize:Number = 15.0;
  365.     public var bulletSpeedFanType:int, bulletSpeedFanVel:Number = 0;
  366.     public var fireDelayType:int, fireDelayVel:Number = 0;
  367.     public var bulletCount:int = 1, bulletSpeedWhipVel:Number = 0;
  368.     public var r:int, g:int, b:int;
  369.     public var childrenCount:int;
  370.     public var shield:int;
  371.     public function set(childrenCount:int, radius:Number, childRadius:Number):void
  372.     {
  373.         this.childrenCount = childrenCount;
  374.         this.radius = radius; visualRadius = radius + childRadius;
  375.         shield = radius;
  376.         rollAngle.width = (0.5 + rand() * 0.5) * ((int)(rand() * 2) * 2 - 1);
  377.         isRound = (rand() < 0.25);
  378.         if (isRound) {
  379.             rollAngle.type = Waveform.MONOTONE;
  380.             rollAngle.interval = 60 + rand() * 60;
  381.             if (rand() < 0.4) fireAngle.type = Waveform.MONOTONE;
  382.             fireAngle.width = (2.0 + rand() * 2.0) * ((int)(rand() * 2) * 2 - 1);
  383.             fireAngle.interval = 90 + rand() * 90;
  384.             if (rand() < 0.3) fireAngle.center = rand() * PI * 2;
  385.             angleInterval.center = PI * 2 / childrenCount;
  386.         }
  387.         else
  388.         {
  389.             isAimingRollAngle = true;
  390.             if (rand() < 0.3) rollAngle.type = Waveform.SIN;
  391.             rollAngle.interval = 120 + rand() * 90;
  392.             if (rand() < 0.3) angleInterval.type = Waveform.SIN;
  393.             angleInterval.center = ((2.0 + rand() * 2.0) / childrenCount) * ((int)(rand() * 2) * 2 - 1);
  394.             angleInterval.width = angleInterval.center * (0.3 + rand() * 0.3);
  395.             angleInterval.interval = 60 + rand() * 60;
  396.         }
  397.         if (rand() < 0.5) bulletSpeedFanType = WEDGE;
  398.         if (rand() < 0.5) bulletSpeedFanVel = (0.3 + rand() * 0.2) * ((int)(rand() * 2) * 2 - 1);
  399.         if (rand() < 0.5) fireDelayType = WEDGE;
  400.         if (rand() < 0.5) fireDelayVel = (8.0 + rand() * 6.0) * ((int)(rand() * 2) * 2 - 1);
  401.     }
  402. }
  403. class Waveform
  404. {
  405.     public static const FIX:int = 0, MONOTONE:int = 1, SIN:int = 2;
  406.     public var type:int = FIX, center:Number = 0, width:Number = 0, interval:int = 1;
  407.     public function getValue(ticks:int):Number
  408.     {
  409.         switch (type)
  410.         {
  411.             case FIX:      return center;
  412.             case MONOTONE: return center + width * ticks * 2 / interval;
  413.             case SIN:      return center + width * sin(PI * 2 * ticks / interval);
  414.         }
  415.         return 0;
  416.     }
  417. }
  418. function addTargetCircles(x:Number, depth:int, fireIntervalRatio:Number, bulletSpeed:Number, hasReversed:Boolean):void
  419. {
  420.     var radius:Number = (20 + rand() * 20) * depth;
  421.     var c:Circle = new Circle;
  422.     var rw:Number = 0;
  423.     if (hasReversed) rw = (rand() * 0.1 + 0.1) * Field.size.x;
  424.     var cy:Number = -Field.size.y * (1.0 + rand() * 2.0) - radius;
  425.     c.pos.x = x - rw; c.pos.y = cy;
  426.     c.isTop = true; c.hasCollision = true; c.isTarget = true;
  427.     var r:int, g:int, b:int;
  428.     r = 127 + rand() * 128; g = 127 + rand() * 128; b = 127 + rand() * 128;
  429.     var sps:Vector.<CircleSpec> = new Vector.<CircleSpec>;
  430.     var turretCount:int = createCircleSpecs(sps, radius, depth, r, g, b);
  431.     var sp:CircleSpec;
  432.     for each (sp in sps) if (sp.isRound) turretCount *= 0.75;
  433.     sp = sps[0];
  434.     sp.fireInterval = turretCount * fireIntervalRatio + 1;
  435.     sp.bulletSpeed = bulletSpeed; sp.bulletSize = 12.0 + depth * 2;
  436.     addCircleChildren(c, sps.length - 1, sps, 1.00);
  437.     circles.push(c);
  438.     if (hasReversed)
  439.     {
  440.         c = new Circle;
  441.         c.pos.x = x + rw; c.pos.y = cy;
  442.         c.isTop = true; c.hasCollision = true; c.isTarget = true;
  443.         addCircleChildren(c, sps.length - 1, sps, 1.00);
  444.         c.setXReverse();
  445.         circles.push(c);
  446.     }
  447. }
  448. function addBackgroundCircles(x:Number, fireIntervalRatio:Number, bulletSpeed:Number):void
  449. {
  450.     var radius:Number = (60 + rand() * 60);
  451.     var c:Circle = new Circle;
  452.     c.pos.x = x; c.pos.y = -Field.size.y - radius;
  453.     c.isTop = true;
  454.     c.circleWidth = 3.0;
  455.     var csp:CircleSpec = new CircleSpec;
  456.     csp.radius = 0; csp.visualRadius = 15.0; csp.childrenCount = 0;
  457.     csp.shield = 3;
  458.     csp.isAimingBaseAngle = true;
  459.     csp.bulletSpeed = bulletSpeed;
  460.     csp.r = csp.g = csp.b = 200;
  461.     var sp:CircleSpec = new CircleSpec;
  462.     sp.childrenCount = 3 + rand() * 7;
  463.     csp.fireInterval = sp.childrenCount * fireIntervalRatio + 1;
  464.     sp.radius = radius; sp.visualRadius = radius - csp.visualRadius;
  465.     sp.rollAngle.width = (0.5 + rand() * 0.5) * ((int)(rand() * 2) * 2 - 1);
  466.     sp.rollAngle.type = Waveform.MONOTONE;
  467.     sp.rollAngle.interval = 60 + rand() * 60;
  468.     sp.angleInterval.center = ((2.0 + rand() * 2.0) / sp.childrenCount);
  469.     if (rand() < 0.5) sp.fireDelayVel = (8.0 + rand() * 6.0) * ((int)(rand() * 2) * 2 - 1);
  470.     sp.r = sp.g = sp.b = 300;
  471.     c.children = new Vector.<Circle>;
  472.     var cct:int = 0;
  473.     for (var i:int = 0; i < sp.childrenCount; i++)
  474.     {
  475.         var cc:Circle = new Circle;
  476.         cc.hasCollision = true;
  477.         cc.spec = csp; cc.start();
  478.         cc.ticks = cct; cct += sp.fireDelayVel;
  479.         c.children.push(cc);
  480.     }
  481.     c.spec = sp; c.start();
  482.     circles.push(c);
  483. }
  484. function createCircleSpecs(sps:Vector.<CircleSpec>, radius:Number, depth:int, r:int, g:int, b:int):int
  485. {
  486.     var sp:CircleSpec = new CircleSpec;
  487.     sp.r = r; sp.g = g; sp.b = b;
  488.     var turretCount:int;
  489.     if (depth == 0)
  490.     {
  491.         sp.radius = 0; sp.visualRadius = radius; sp.childrenCount = 0;
  492.         if (rand() < 0.3)
  493.         {
  494.             sp.bulletCount = 2 + rand() * 5;
  495.             sp.bulletSpeedWhipVel = 0.2 + rand() * 0.2;
  496.             turretCount = sp.bulletCount * 0.75;
  497.         }
  498.         else turretCount = 1;
  499.     }
  500.     else
  501.     {
  502.         sp.childrenCount = 1 + rand() * 7;
  503.         var cr:Number = radius * (0.33 + rand() * 0.1);
  504.         sp.set(sp.childrenCount, radius, cr);
  505.         turretCount = createCircleSpecs(sps, cr, depth - 1, r, g, b) * sp.childrenCount;
  506.     }
  507.     sps.push(sp);
  508.     return turretCount;
  509. }
  510. function addCircleChildren(c:Circle, index:int, sps:Vector.<CircleSpec>,
  511.                            bulletSpeedRatio:Number, fireDelay:Number):void
  512. {
  513.     var sp:CircleSpec = sps[index];
  514.     var bsv:Number = -sp.bulletSpeedFanVel * 2 / sp.childrenCount;
  515.     var fdv:Number = -sp.fireDelayVel * 2 / sp.childrenCount;
  516.     if (sp.bulletSpeedFanType == CircleSpec.WEDGE) bsv *= 2;
  517.     if (sp.fireDelayType == CircleSpec.WEDGE) fdv *= 2;
  518.     if (sp.childrenCount > 0) c.children = new Vector.<Circle>;
  519.     for (var i:int = 0; i < sp.childrenCount; i++)
  520.     {
  521.         var cc:Circle = new Circle;
  522.         var bsr:Number;
  523.         if (sp.bulletSpeedFanType == CircleSpec.FIX || i < sp.childrenCount / 2) bsr = 1.0 + sp.bulletSpeedFanVel + bsv * i;
  524.         else bsr = 1.0 + sp.bulletSpeedFanVel + bsv * (sp.childrenCount - 1 - i);
  525.         var fd:Number;
  526.         if (sp.fireDelayType == CircleSpec.FIX || i < sp.childrenCount / 2) fd = sp.fireDelayVel + fdv * i;
  527.         else fd = sp.fireDelayVel + fdv * (sp.childrenCount - 1 - i);
  528.         addCircleChildren(cc, index - 1, sps, bsr * bulletSpeedRatio, fireDelay + fd);
  529.         c.children.push(cc);
  530.     }
  531.     c.bulletSpeedRatio = bulletSpeedRatio;
  532.     c.ticks = fireDelay;
  533.     c.spec = sp; c.start();
  534. }
  535. // Sparks.
  536. var sparks:Vector.<Spark>;
  537. class Spark extends VelocityActor
  538. {
  539.     public var size:Number;
  540.     public var r:int, g:int, b:int;
  541.     override public function update():Boolean
  542.     {
  543.         vel.scaleBy(0.99);
  544.         size *= 0.95;
  545.         r += (BACKGROUND_BRIGHTNESS - r) * 0.1;
  546.         g += (BACKGROUND_BRIGHTNESS - g) * 0.1;
  547.         b += (BACKGROUND_BRIGHTNESS - b) * 0.1;
  548.         var cr:Number = rand() + 0.5;
  549.         var br:int = r * cr, bg:int = g * cr, bb:int = b * cr;
  550.         if (br > 255) br = 255;
  551.         if (bg > 255) bg = 255;
  552.         if (bb > 255) bb = 255;
  553.         drawBox(pos.x, pos.y, size, size, r * 0x10000 + g * 0x100 + b, 1.5, br, bg, bb);
  554.         return super.update();
  555.     }
  556. }
  557. function addSparks(count:int, x:Number, y:Number, speed:Number, size:Number, r:int, g:int, b:int):void
  558. {
  559.     for (var i:int = 0; i < count; i++)
  560.     {
  561.         var s:Spark = new Spark;
  562.         s.pos.x = x; s.pos.y = y;
  563.         var a:Number = rand() * PI * 2, sp:Number = speed * (0.5 + rand());
  564.         s.vel.x = Math.sin(a) * sp; s.vel.y = Math.cos(a) * sp;
  565.         s.size = size;
  566.         s.r = r; s.g = g; s.b = b;
  567.         s.disappearTicks = 15 + 15 * rand();
  568.         sparks.push(s);
  569.     }
  570. }
  571. // Bonus items.
  572. var bonuses:Vector.<Bonus>;
  573. class Bonus extends VelocityActor
  574. {
  575.     public var isInhaled:Boolean;
  576.     override public function update():Boolean
  577.     {
  578.         var a:Number = ticks * 0.1;
  579.         for (var i:int = 0; i < 4; i++)
  580.         {
  581.             drawBox(pos.x + sin(a) * 10 - 5, pos.y + cos(a) * 10 - 588, 0x6688aa, 1.0150200150);
  582.             a += PI / 2;
  583.         }
  584.         if (isInhaled && gameOverTicks < 0)
  585.         {
  586.             vel.x += (Player.pos.x - pos.x) * 0.05; vel.y += (Player.pos.y - pos.y) * 0.05;
  587.         }
  588.         else vel.y += 0.5;
  589.         vel.scaleBy(0.9);
  590.         var d:Number = Vector3D.distance(pos, Player.pos);
  591.         if (isInhaled && d < 40.0 && gameOverTicks < 0)
  592.         {
  593.             score++; scoreField.text = String(score); return false;
  594.         }
  595.         else if (d < 120.0 && vel.length < 5.0) isInhaled = true;
  596.         return super.update();
  597.     }
  598. }
  599. function addBonuses(count:int, x:Number, y:Number, speed:Number):void
  600. {
  601.     for (var i:int = 0; i < count; i++)
  602.     {
  603.         var b:Bonus = new Bonus;
  604.         b.pos.x = x; b.pos.y = y;
  605.         var a:Number = rand() * PI * 2, sp:Number = speed * (0.5 + rand());
  606.         b.vel.x = Math.sin(a) * sp; b.vel.y = Math.cos(a) * sp;
  607.         bonuses.push(b);
  608.     }
  609. }
  610. // Game field.
  611. class Field
  612. {
  613.     public static const SIDE_BOARD_WIDTH:Number = SCREEN_WIDTH / 6;
  614.     public static var size:Vector3D = new Vector3D;
  615.     public static var offsetX:Number = 0;
  616.     public static function initialize():void
  617.     {
  618.         size.x = SCREEN_WIDTH * 1.1 / 2; size.y = SCREEN_HEIGHT * 1.1 / 2;
  619.     }
  620.     public static function drawSideBoard():void
  621.     {
  622.         rect.width = SIDE_BOARD_WIDTH; rect.height = SCREEN_HEIGHT; rect.y = 0;
  623.         rect.x = 0;                         screen.fillRect(rect, BACKGROUND_COLOR);
  624.         rect.x = SCREEN_WIDTH - rect.width; screen.fillRect(rect, BACKGROUND_COLOR);
  625.     }
  626.     public static function contains(p:Vector3D):Boolean
  627.     {
  628.         return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  629.     }
  630. }
  631. // Blur effect.
  632. const BLUR_MAX_COUNT:int = 512, BLUR_HISTORY_COUNT:int = 6;
  633. var blurs:Vector.<Vector.<Blur>> = new Vector.<Vector.<Blur>>(BLUR_HISTORY_COUNT, true);
  634. var blurCounts:Vector.<int> = new Vector.<int>(BLUR_HISTORY_COUNT, true);
  635. var blurIndex:int;
  636. class Blur
  637. {
  638.     public var pos:Vector3D = new Vector3D;
  639.     public var width:Number, height:Number;
  640.     public var r:int, g:int, b:int;
  641.     public function update():void
  642.     {
  643.         rect.x = pos.x - width  / 2 - Field.offsetX; rect.width = width;
  644.         rect.y = pos.y - height / 2; rect.height = height;
  645.         screen.fillRect(rect, r * 0x10000 + g * 0x100 + b);
  646.         width *= 1.2; height *= 1.2;
  647.         r += (BACKGROUND_BRIGHTNESS - r) * 0.2;
  648.         g += (BACKGROUND_BRIGHTNESS - g) * 0.2;
  649.         b += (BACKGROUND_BRIGHTNESS - b) * 0.2;
  650.     }
  651. }
  652. function drawBox(x:Number, y:Number, w:int, h:int, color:int,
  653.                  blurSizeRatio:Number, br:int, bg:int, bb:int):void
  654. {
  655.     rect.x = x - w / 2 + SCREEN_WIDTH / 2 - Field.offsetX;
  656.     rect.y = y - h / 2 + SCREEN_HEIGHT / 2;
  657.     rect.width = w; rect.height = h;
  658.     screen.fillRect(rect, color);
  659.     if (blurSizeRatio > 0) addBlur(x, y, w * blurSizeRatio, h * blurSizeRatio, br, bg, bb);
  660. }
  661. function addBlur(x:Number, y:Number, w:Number, h:Number, r:int, g:int, b:int):void
  662. {
  663.     if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  664.     var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  665.     bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  666.     bl.width = w; bl.height = h;
  667.     bl.r = r; bl.g = g; bl.b = b;
  668.     blurCounts[blurIndex]++;
  669. }
  670. function updateBlurs():void
  671. {
  672.     var bi:int = blurIndex + 1;
  673.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  674.     {
  675.         if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  676.         for (var j:int = 0; j < blurCounts[bi]; j++) blurs[bi][j].update();
  677.         bi++;
  678.     }
  679.     blurIndex++;
  680.     if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  681.     blurCounts[blurIndex] = 0;
  682. }
  683. function initializeBlurs():void
  684. {
  685.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  686.     {
  687.         var bs:Vector.<Blur> = new Vector.<Blur>(BLUR_MAX_COUNT, true);
  688.         for (var j:int = 0; j < BLUR_MAX_COUNT; j++) bs[j] = new Blur;
  689.         blurs[i] = bs; blurCounts[i] = 0;
  690.     }
  691.     blurIndex = 0;
  692. }
  693. // Utility classes, functions and variables.
  694. var pos:Vector3D = new Vector3D, offset:Vector3D = new Vector3D;
  695. var rect:Rectangle = new Rectangle;
  696. var rand:Function = Math.random, abs:Function = Math.abs;
  697. var sin:Function = Math.sin, cos:Function = Math.cos, atan2:Function = Math.atan2;
  698. var PI:Number = Math.PI;
  699. class Key
  700. {
  701.     public static var left:Boolean, up:Boolean, right:Boolean, down:Boolean;
  702.     public static var button1:Boolean, button2:Boolean;
  703.     public static function onKeyDown(event:KeyboardEvent):void
  704.     {
  705.         switch (event.keyCode)
  706.         {
  707.             case 0x25:case 0x41: left =    truebreak;
  708.             case 0x26:case 0x57: up =      truebreak;
  709.             case 0x27:case 0x44: right =   truebreak;
  710.             case 0x28:case 0x53: down =    truebreak;
  711.             case 0x5a:case 0xbf: button1 = truebreak;
  712.             case 0x58:case 0xbe: button2 = truebreak;
  713.         }
  714.     }
  715.     public static function onKeyUp(event:KeyboardEvent):void
  716.     {
  717.         switch (event.keyCode)
  718.         {
  719.             case 0x25:case 0x41: left =    falsebreak;
  720.             case 0x26:case 0x57: up =      falsebreak;
  721.             case 0x27:case 0x44: right =   falsebreak;
  722.             case 0x28:case 0x53: down =    falsebreak;
  723.             case 0x5a:case 0xbf: button1 = falsebreak;
  724.             case 0x58:case 0xbe: button2 = falsebreak;
  725.         }
  726.     }
  727. }
  728. function createTextField(x:int, y:int, width:int, size:int, color:int,
  729.                          align:String = TextFormatAlign.LEFT):TextField
  730. {
  731.     var fm:TextFormat = new TextFormat;
  732.     fm.font = "_typewriter"; fm.bold = true;
  733.     fm.size = size; fm.color = color; fm.align = align;
  734.     var fi:TextField = new TextField;
  735.     fi.defaultTextFormat = fm;
  736.     fi.x = x; fi.y = y; fi.width = width; fi.selectable = false;
  737.     return fi;
  738. }
  739. function drawCircle(p:Vector3D, radius:Number, width:Number, color:int, xRatio:Number = 1.0):void
  740. {
  741.     pos.x = p.x + SCREEN_WIDTH / 2 - Field.offsetX;
  742.     pos.y = p.y + SCREEN_HEIGHT / 2;
  743.     var c:int = radius * 1.5;
  744.     var a:Number = 0, oa:Number = PI * 2 / c;
  745.     rect.width = rect.height = width;
  746.     for (var i:int = 0; i < c; i++)
  747.     {
  748.         rect.x = pos.x + sin(a) * radius * xRatio - width / 2;
  749.         rect.y = pos.y + cos(a) * radius - width / 2;
  750.         screen.fillRect(rect, color);
  751.         a += oa;
  752.     }
  753. }
noswf
  1. // 全画面でプレイしたくなった
  2. // 赤い四角クリックすると全画面に
  3. // forked from ABA's CircleCycle
  4. // CircleCycle.as
  5. //  Destroy circles and avoid incoming bullets.
  6. //  <Control>
  7. //   Movement: Arrow or [WASD] keys.
  8. //   Fire:    [Z], [X], [.] or [/] key.
  9. package
  10. {
  11.     import flash.display.Sprite;
  12.     [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  13.     public class CircleCycle extends Sprite
  14.     {
  15.         public function CircleCycle()
  16.         {
  17.             main = this;
  18.             initialize();
  19.             addChild( new ClickFullScreener );
  20.         }
  21.     }
  22. }
  23. import flash.events.MouseEvent;
  24. class ClickFullScreener extends Sprite {
  25.     public function ClickFullScreener() {
  26.             var btn :Sprite = new Sprite;
  27.             addChild( btn );
  28.             btn.graphics.beginFill(0xFF0000);
  29.             btn.graphics.drawRect(0,0,100,100);
  30.             btn.buttonMode = true;
  31.             btn.addEventListener( MouseEvent.CLICK, onclick );
  32.     }
  33.         private function onclick( e :MouseEvent ) :void {
  34.             switch(stage.displayState) {
  35.                 case "normal":
  36.                     stage.displayState = "fullScreen";
  37.                     break;
  38.                 case "fullScreen":
  39.                 default:
  40.                     stage.displayState = "normal";
  41.                     break;
  42.             }
  43.             e.target.visible = false;
  44.         }
  45. }
  46. import flash.display.Sprite;
  47. import flash.display.Bitmap;
  48. import flash.display.BitmapData;
  49. import flash.display.Graphics;
  50. import flash.geom.Rectangle;
  51. import flash.geom.Vector3D;
  52. import flash.text.TextField;
  53. import flash.text.TextFormat;
  54. import flash.text.TextFormatAlign;
  55. import flash.events.Event;
  56. import flash.events.KeyboardEvent;
  57. const SCREEN_WIDTH:int = 465, SCREEN_HEIGHT:int = 465;
  58. const TITLE:int = 0, GAME:int = 1, GAME_OVER:int = 2;
  59. const GAME_OVER_DURATION:int = 150, BLOCK_GAME_START_DURATION:int = 30;
  60. const BACKGROUND_BRIGHTNESS:int = 200;
  61. const BACKGROUND_COLOR:int = BACKGROUND_BRIGHTNESS * 0x10000 + BACKGROUND_BRIGHTNESS * 0x100 + BACKGROUND_BRIGHTNESS;
  62. var main:Sprite;
  63. var screen:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  64. var scoreField:TextField = new TextField;
  65. var timeField:TextField = new TextField;
  66. var messageField:TextField = new TextField;
  67. var score:int, time:int, stage:int, gameOverTicks:int;
  68. var rect:Rectangle = new Rectangle;
  69. var pos:Vector3D = new Vector3D, offset:Vector3D = new Vector3D;
  70. var rand:Function = Math.random, abs:Function = Math.abs;
  71. var sin:Function = Math.sin, cos:Function = Math.cos, atan2:Function = Math.atan2;
  72. var PI:Number = Math.PI;
  73. function initialize():void
  74. {
  75.     main.addChild(new Bitmap(screen));
  76.     main.stage.addEventListener(KeyboardEvent.KEY_DOWN, Key.onKeyDown);
  77.     main.stage.addEventListener(KeyboardEvent.KEY_UP,   Key.onKeyUp);
  78.     Field.initialize();
  79.     initializeBlurs();
  80.     player.initialize();
  81.     scoreField = createTextField(SCREEN_WIDTH - 100010024, 0xff6666, TextFormatAlign.RIGHT);
  82.     timeField = createTextField(SCREEN_WIDTH / 2 - 100, SCREEN_HEIGHT - 4820048, 0xff6666, TextFormatAlign.RIGHT);
  83.     messageField = createTextField(SCREEN_WIDTH - 256025636, 0xff6666);
  84.     main.addChild(scoreField); main.addChild(timeField); main.addChild(messageField);
  85.     start(TITLE);
  86.     main.addEventListener(Event.ENTER_FRAME, update);
  87. }
  88. function update(event:Event):void
  89. {
  90.     if (circles.length <= 0) goToNextStage();
  91.     screen.lock();
  92.     screen.fillRect(screen.rect, BACKGROUND_COLOR);
  93.     updateBlurs();
  94.     var i:int;
  95.     for (i = 0; i < sparks.length; i++)  if (!sparks[i].update())  { sparks.splice(i, 1); i--; }
  96.     for (i = 0; i < shots.length; i++)   if (!shots[i].update())   { shots.splice(i, 1);  i--; }
  97.     for each (var c:Circle in circles) c.update();
  98.     for (i = 0; i < circles.length; i++) if (!circles[i].exists)   { circles.splice(i, 1); i--; }
  99.     if (gameOverTicks < 0) player.update();
  100.     for (i = 0; i < bullets.length; i++) if (!bullets[i].update()) { bullets.splice(i, 1); i--; }
  101.     Field.drawSideBoard();
  102.     screen.unlock();
  103.     if (gameOverTicks < 0)
  104.     {
  105.         var msStr:String = String(time % 1000);
  106.         while (msStr.length < 3) msStr = "0" + msStr;
  107.         timeField.text = String(int(time / 1000)) + "\"" + msStr;
  108.         if (time <= 0) start(GAME_OVER);
  109.         time -= 33;
  110.     }
  111.     else
  112.     {
  113.         gameOverTicks++;
  114.         if (gameOverTicks == GAME_OVER_DURATION) start(TITLE);
  115.         if (Key.button1 && gameOverTicks > BLOCK_GAME_START_DURATION) start(GAME);
  116.     }
  117. }
  118. function goToNextStage():void
  119. {
  120.     if (gameOverTicks < 0 && stage > 0) score += time;
  121.     scoreField.text = String(score);
  122.     stage++;
  123.     time = 5000;
  124.     addCircles((rand() - 0.5) * Field.size.x, 250.0 / (20.0 + stage), 5.0 + rand() * 2.0 + rand() * 2.0);
  125. }
  126. function start(mode:int):void
  127. {
  128.     switch (mode)
  129.     {
  130.         case TITLE:
  131.         {
  132.             clearActors();
  133.             player.hide();
  134.             gameOverTicks = GAME_OVER_DURATION;
  135.             messageField.y = SCREEN_HEIGHT / 3 * 2; messageField.text = "CircleCycle";
  136.             break;
  137.         }
  138.         case GAME:
  139.         {
  140.             clearActors();
  141.             player.start();
  142.             gameOverTicks = -1;
  143.             messageField.text = "";
  144.             score = 0; stage = 0;
  145.             break;
  146.         }
  147.         case GAME_OVER:
  148.         {
  149.             player.hide();
  150.             gameOverTicks = 0;
  151.             messageField.y = SCREEN_HEIGHT / 2; messageField.text = "GAME OVER";
  152.             timeField.text = "";
  153.             break;
  154.         }
  155.     }
  156. }
  157. function clearActors():void
  158. {
  159.     shots = null; bullets = null; sparks = null;
  160.     shots = new Vector.<Shot>; bullets = new Vector.<Bullet>; sparks = new Vector.<Spark>;
  161.     for each (var c:Circle in circles) c.remove();
  162.     circles = null; circles = new Vector.<Circle>;
  163. }
  164. // Game actor base class.
  165. class Actor
  166. {
  167.     public var pos:Vector3D = new Vector3D;
  168. }
  169. class VelocityActor extends Actor
  170. {
  171.     public var vel:Vector3D = new Vector3D;
  172.     public var ticks:int;
  173.     public function update():Boolean
  174.     {
  175.         pos.incrementBy(vel);
  176.         ticks++;
  177.         if (!Field.contains(pos) || ticks > 300return false;
  178.         return true;
  179.     }
  180. }
  181. // Player.
  182. var player:Player = new Player;
  183. class Player extends Actor
  184. {
  185.     private const INVINCIBLE_DURATION:int = 90;
  186.     private const COLLISION_SIZE:Number = 5.0;
  187.     private const SPEED:Number = 9.0;
  188.     private var vel:Vector3D = new Vector3D;
  189.     private var fireTicks:int;
  190.     private var sprite:Sprite = new Sprite;
  191.     public function initialize():void
  192.     {
  193.         var g:Graphics = sprite.graphics;
  194.         g.lineStyle(5, 0x008800);
  195.         g.moveTo(0, -10); g.lineTo(-10,10); g.lineTo(1010); g.lineTo(0, -10);
  196.         main.addChild(sprite);
  197.     }
  198.     public function start():void
  199.     {
  200.         pos.x = 0; pos.y = Field.size.y * 0.5;
  201.         vel.y = -5.0;
  202.     }
  203.     public function hide():void
  204.     {
  205.         sprite.x = sprite.y = 99999;
  206.     }
  207.     public function update():void
  208.     {
  209.         offset.x = offset.y = 0;
  210.         if (Key.left)  offset.x = -1;
  211.         if (Key.right) offset.x = 1;
  212.         if (Key.up)    offset.y = -1;
  213.         if (Key.down)  offset.y = 1;
  214.         if (offset.x != 0 && offset.y != 0) offset.scaleBy(0.7);
  215.         offset.scaleBy(SPEED); pos.incrementBy(offset);
  216.         pos.incrementBy(vel); vel.scaleBy(0.9);
  217.         if (pos.x < -SCREEN_WIDTH  / 2) pos.x = -SCREEN_WIDTH / 2;
  218.         if (pos.x >  SCREEN_WIDTH  / 2) pos.x =  SCREEN_WIDTH / 2;
  219.         if (pos.y < -SCREEN_HEIGHT / 2) pos.y = -SCREEN_HEIGHT / 2;
  220.         if (pos.y >  SCREEN_HEIGHT / 2) pos.y =  SCREEN_HEIGHT / 2;
  221.         Field.offsetX = pos.x * 0.33;
  222.         sprite.x = pos.x + SCREEN_WIDTH / 2 - Field.offsetX;
  223.         sprite.y = pos.y + SCREEN_WIDTH / 2;
  224.         var bc:int = time * 150 / 5000;
  225.         addBlur(pos.x, pos.y - 777250 - bc, 50 + bc, 100);
  226.         addBlur(pos.x, pos.y + 31515250 - bc, 50 + bc, 100);
  227.         drawBox(pos.x + time * 0.02 / 2, pos.y + 15, time * 0.0210,
  228.                 (150 - bc) * 0x10000 + bc * 0x100, 0000);
  229.         var i:int;
  230.         if (fireTicks <= 0 && shots.length <= 7 && abs(vel.y) < 1.0 && Key.button1)
  231.         {
  232.             fireTicks = 2;
  233.             var s:Shot;
  234.             for (i = 0; i < 7; i++)
  235.             {
  236.                 s = new Shot;
  237.                 s.pos.x = pos.x; s.pos.y = pos.y;
  238.                 var d:Number = (i - 3) * 0.1;
  239.                 s.vel.x = sin(d) * 24.0; s.vel.y = -cos(d) * 24.0;
  240.                 shots.push(s);
  241.             }
  242.         }
  243.         fireTicks--;
  244.         i = 0;
  245.         for each (var b:Bullet in bullets)
  246.         {
  247.             if (Vector3D.distance(pos, b.pos) <= COLLISION_SIZE)
  248.             {
  249.                 if (vel.y < 1.0)
  250.                 {
  251.                     vel.y += 20.0;
  252.                     addSparks(50, pos.x, pos.y, 30.015.0200200100);
  253.                     time /= 2;
  254.                 }
  255.                 else
  256.                 {
  257.                     bullets.splice(i, 1); i--;
  258.                 }
  259.             }
  260.             i++;
  261.         }
  262.     }
  263. }
  264. // Player's shots.
  265. var shots:Vector.<Shot> = new Vector.<Shot>;
  266. class Shot extends VelocityActor
  267. {
  268.     override public function update():Boolean
  269.     {
  270.         for each (var c:Circle in circles) if (checkHit(c)) return false;
  271.         addBlur(pos.x, pos.y, 201550150100);
  272.         return super.update();
  273.     }
  274.     private function checkHit(c:Circle):Boolean
  275.     {
  276.         for each (var cc:Circle in c.children) if (cc.exists && checkHit(cc)) return true;
  277.         if (c.exists && c.hasCollision && Vector3D.distance(pos, c.pos) < c.spec.spriteRadius + 20.0)
  278.         {
  279.             addSparks(1, pos.x, pos.y, 20.05.050150100);
  280.             c.damage(); return true;
  281.         }
  282.         return false;
  283.     }
  284. }
  285. // Circles' bullets.
  286. var bullets:Vector.<Bullet>;
  287. class Bullet extends VelocityActor
  288. {
  289.     public var baseVel:Vector3D = new Vector3D;
  290.     public var color:int, br:int, bg:int, bb:int, size:int;
  291.     override public function update():Boolean
  292.     {
  293.         var sz:Number = 1.5 + Math.sin(ticks * 0.2) * 0.4;
  294.         var a:Number = 0.8 + Math.sin(ticks * 0.45) * 0.2;
  295.         drawBox(pos.x, pos.y, size, size, color, sz, br * a, bg * a, bb * a);
  296.         if (ticks <= 15)
  297.         {
  298.             vel.x = baseVel.x * (ticks + 15) / 30.0; vel.y = baseVel.y * (ticks + 15) / 30.0;
  299.         }
  300.         return super.update();
  301.     }
  302. }
  303. // Circles.
  304. var circles:Vector.<Circle> = new Vector.<Circle>;
  305. class Circle extends Actor
  306. {
  307.     public var children:Vector.<Circle> = new Vector.<Circle>;
  308.     public var isTop:Boolean, exists:Boolean = true;
  309.     public var spec:CircleSpec;
  310.     public var bulletSpeedRatio:Number = 1.0;
  311.     public var rollAngle:Number, fireAngle:Number, fireSpeed:Number, angleInterval:Number;
  312.     public var baseAngle:Number;
  313.     public var ticks:int, shield:int;
  314.     public var hasCollision:Boolean;
  315.     public var isDamaged:Boolean;
  316.     public var sprite:Sprite = new Sprite;
  317.     public function start():void
  318.     {
  319.         var g:Graphics = sprite.graphics;
  320.         g.clear();
  321.         g.lineStyle(5, (int)(spec.r / 2) * 0x10000 + int(spec.g / 2) * 0x100 + int(spec.b / 2));
  322.         g.drawCircle(00, spec.spriteRadius);
  323.         main.addChild(sprite);
  324.         baseAngle = rollAngle = fireAngle = 0;
  325.         shield = spec.shield;
  326.     }
  327.     public function update():void
  328.     {
  329.         sprite.x = pos.x + SCREEN_WIDTH / 2 - Field.offsetX;
  330.         sprite.y = pos.y + SCREEN_HEIGHT / 2;
  331.         var i:int;
  332.         if (isDamaged)
  333.         {
  334.             isDamaged = false;
  335.             var da:Number = ticks * 0.1, sr:Number = spec.spriteRadius, bc:int = sr * 0.5;
  336.             for (i = 0; i < bc; i++)
  337.             {
  338.                 addBlur(pos.x + sr * sin(da), pos.y + sr * cos(da),
  339.                         9 + rand() * 79 + rand() * 7, rand() * 128 + 127, rand() * 1280);
  340.                 da += PI * 2 / bc;
  341.             }
  342.         }
  343.         if (spec.fireInterval > 0 && ticks % spec.fireInterval == 0 && pos.y < 0)
  344.         {
  345.             if (spec.isAimingBaseAngle) baseAngle = atan2(player.pos.x - pos.x, player.pos.y - pos.y);
  346.             var ba:Number = baseAngle + rollAngle + fireAngle;
  347.             var srv:Number = -spec.bulletSpeedWhipVel * 2/ spec.bulletCount;
  348.             for (i = 0; i < spec.bulletCount; i++) fire(ba, 1.0 + spec.bulletSpeedWhipVel + srv * i);
  349.         }
  350.         ticks++;
  351.         if (spec.childrenCount <= 0return;
  352.         rollAngle = spec.rollAngle.getValue(ticks);
  353.         fireAngle = spec.fireAngle.getValue(ticks);
  354.         fireSpeed = spec.fireSpeed.getValue(ticks);
  355.         angleInterval = spec.angleInterval.getValue(ticks);
  356.         if (spec.isAimingRollAngle) rollAngle += atan2(player.pos.x - pos.x, player.pos.y - pos.y);
  357.         var a:Number = rollAngle - angleInterval * (children.length - 1) / 2 - angleInterval;
  358.         for each (var c:Circle in children)
  359.         {
  360.             a += angleInterval;
  361.             if (!c.exists) continue;
  362.             c.pos.x = pos.x + sin(a) * spec.radius;
  363.             c.pos.y = pos.y + cos(a) * spec.radius;
  364.             c.baseAngle = a + fireAngle;
  365.             c.update();
  366.         }
  367.         if (isTop && pos.y < -Field.size.y * 0.5) pos.y += 7.0;
  368.     }
  369.     private function fire(a:Number, sr:Number):void
  370.     {
  371.         var b:Bullet = new Bullet;
  372.         b.pos.x = pos.x; b.pos.y = pos.y;
  373.         var bs:Number = spec.bulletSpeed * bulletSpeedRatio * sr;
  374.         b.baseVel.x = sin(a) * bs; b.baseVel.y = cos(a) * bs;
  375.         b.size = spec.bulletSize;
  376.         b.br = spec.r; b.bg = spec.g; b.bb = spec.b;
  377.         b.color = int(b.br / 4) * 0x10000 + int(b.bg / 4) * 0x100 + int(b.bb / 4);
  378.         bullets.push(b);
  379.     }
  380.     public function damage():void
  381.     {
  382.         isDamaged = true;
  383.         shield--;
  384.         if (shield <= 0) remove(true);
  385.     }
  386.     public function remove(isDestroyed:Boolean = false):void
  387.     {
  388.         main.removeChild(sprite);
  389.         for each (var c:Circle in children) if (c.exists) c.remove();
  390.         exists = false;
  391.         if (!isDestroyed) return;
  392.         var ba:Number = ticks * 0.1, sr:Number = spec.spriteRadius, bc:int = sr * 0.5;
  393.         for (var i:int = 0; i < bc; i++)
  394.         {
  395.             addSparks(1, pos.x + sr * sin(ba), pos.y + sr * cos(ba), 10.010.0, spec.r, spec.g, spec.b);
  396.             ba += PI * 2 / bc;
  397.         }
  398.     }
  399. }
  400. class CircleSpec
  401. {
  402.     public static const FIX:int = 0, WEDGE:int = 1;
  403.     public var radius:Number, spriteRadius:Number;
  404.     public var isRound:Boolean;
  405.     public var rollAngle:Waveform = new Waveform;
  406.     public var isAimingRollAngle:Boolean, isAimingBaseAngle:Boolean;
  407.     public var fireAngle:Waveform = new Waveform, fireSpeed:Waveform = new Waveform;
  408.     public var fireInterval:int = -1;
  409.     public var angleInterval:Waveform = new Waveform;
  410.     public var bulletSpeed:Number = 7.0, bulletSize:Number = 15.0;
  411.     public var bulletSpeedFanType:int, bulletSpeedFanVel:Number = 0;
  412.     public var fireDelayType:int, fireDelayVel:Number = 0;
  413.     public var bulletCount:int = 1, bulletSpeedWhipVel:Number = 0;
  414.     public var r:int, g:int, b:int;
  415.     public var childrenCount:int;
  416.     public var shield:int;
  417.     public function set(childrenCount:int, radius:Number, childRadius:Number):void
  418.     {
  419.         this.childrenCount = childrenCount;
  420.         this.radius = radius; spriteRadius = radius + childRadius;
  421.         shield = radius * 0.7;
  422.         rollAngle.width = (0.5 + rand() * 0.5) * ((int)(rand() * 2) * 2 - 1);
  423.         isRound = (rand() < 0.25);
  424.         if (isRound) {
  425.             rollAngle.type = Waveform.MONOTONE;
  426.             rollAngle.interval = 60 + rand() * 60;
  427.             if (rand() < 0.4) fireAngle.type = Waveform.MONOTONE;
  428.             fireAngle.width = (2.0 + rand() * 2.0) * ((int)(rand() * 2) * 2 - 1);
  429.             fireAngle.interval = 90 + rand() * 90;
  430.             if (rand() < 0.3) fireAngle.center = rand() * PI * 2;
  431.             angleInterval.center = PI * 2 / childrenCount;
  432.         }
  433.         else
  434.         {
  435.             isAimingRollAngle = true;
  436.             if (rand() < 0.3) rollAngle.type = Waveform.SIN;
  437.             rollAngle.interval = 120 + rand() * 90;
  438.             if (rand() < 0.3) angleInterval.type = Waveform.SIN;
  439.             angleInterval.center = ((2.0 + rand() * 2.0) / childrenCount) * ((int)(rand() * 2) * 2 - 1);
  440.             angleInterval.width = angleInterval.center * (0.3 + rand() * 0.3);
  441.             angleInterval.interval = 60 + rand() * 60;
  442.         }
  443.         if (rand() < 0.5) bulletSpeedFanType = WEDGE;
  444.         if (rand() < 0.5) bulletSpeedFanVel = (0.3 + rand() * 0.2) * ((int)(rand() * 2) * 2 - 1);
  445.         if (rand() < 0.5) fireDelayType = WEDGE;
  446.         if (rand() < 0.5) fireDelayVel = (8.0 + rand() * 6.0) * ((int)(rand() * 2) * 2 - 1);
  447.     }
  448. }
  449. class Waveform
  450. {
  451.     public static const FIX:int = 0, MONOTONE:int = 1, SIN:int = 2;
  452.     public var type:int = FIX, center:Number = 0, width:Number = 0, interval:int = 1;
  453.     public function getValue(ticks:int):Number
  454.     {
  455.         switch (type)
  456.         {
  457.             case FIX:      return center;
  458.             case MONOTONE: return center + width * ticks * 2 / interval;
  459.             case SIN:      return center + width * sin(PI * 2 * ticks / interval);
  460.         }
  461.         return 0;
  462.     }
  463. }
  464. function addCircles(x:Number, depth:int, fireIntervalRatio:Number, bulletSpeed:Number):void
  465. {
  466.     var radius:Number = (20 + rand() * 20) * depth;
  467.     var c:Circle = new Circle;
  468.     c.pos.x = x; c.pos.y = -Field.size.y - radius;
  469.     c.isTop = true; c.hasCollision = true;
  470.     var r:int, g:int, b:int;
  471.     r = 127 + rand() * 128; g = 127 + rand() * 128; b = 127 + rand() * 128;
  472.     var sps:Vector.<CircleSpec> = new Vector.<CircleSpec>;
  473.     var turretCount:int = createCircleSpecs(sps, radius, depth, r, g, b);
  474.     var sp:CircleSpec;
  475.     for each (sp in sps) if (sp.isRound) turretCount *= 0.75;
  476.     sp = sps[0];
  477.     sp.fireInterval = turretCount * fireIntervalRatio + 1;
  478.     sp.bulletSpeed = bulletSpeed; sp.bulletSize = 10.0 + depth * 3;
  479.     addCircleChildren(c, sps.length - 1, sps, 1.00);
  480.     circles.push(c);
  481. }
  482. function createCircleSpecs(sps:Vector.<CircleSpec>, radius:Number, depth:int, r:int, g:int, b:int):int
  483. {
  484.     var sp:CircleSpec = new CircleSpec;
  485.     sp.r = r; sp.g = g; sp.b = b;
  486.     var turretCount:int;
  487.     if (depth == 0)
  488.     {
  489.         sp.radius = 0; sp.spriteRadius = radius; sp.childrenCount = 0;
  490.         if (rand() < 0.3)
  491.         {
  492.             sp.bulletCount = 2 + rand() * 5;
  493.             sp.bulletSpeedWhipVel = 0.2 + rand() * 0.2;
  494.             turretCount = sp.bulletCount * 0.75;
  495.         }
  496.         else turretCount = 1;
  497.     }
  498.     else
  499.     {
  500.         sp.childrenCount = 1 + rand() * 7;
  501.         var cr:Number = radius * (0.33 + rand() * 0.1);
  502.         sp.set(sp.childrenCount, radius, cr);
  503.         turretCount = createCircleSpecs(sps, cr, depth - 1, r, g, b) * sp.childrenCount;
  504.     }
  505.     sps.push(sp);
  506.     return turretCount;
  507. }
  508. function addCircleChildren(c:Circle, index:int, sps:Vector.<CircleSpec>,
  509.                            bulletSpeedRatio:Number, fireDelay:Number):void
  510. {
  511.     var sp:CircleSpec = sps[index];
  512.     var bsv:Number = -sp.bulletSpeedFanVel * 2 / sp.childrenCount;
  513.     var fdv:Number = -sp.fireDelayVel * 2 / sp.childrenCount;
  514.     if (sp.bulletSpeedFanType == CircleSpec.WEDGE) bsv *= 2;
  515.     if (sp.fireDelayType == CircleSpec.WEDGE) fdv *= 2;
  516.     for (var i:int = 0; i < sp.childrenCount; i++)
  517.     {
  518.         var cc:Circle = new Circle;
  519.         var bsr:Number;
  520.         if (sp.bulletSpeedFanType == CircleSpec.FIX || i < sp.childrenCount / 2) bsr = 1.0 + sp.bulletSpeedFanVel + bsv * i;
  521.         else bsr = 1.0 + sp.bulletSpeedFanVel + bsv * (sp.childrenCount - 1 - i);
  522.         var fd:Number;
  523.         if (sp.fireDelayType == CircleSpec.FIX || i < sp.childrenCount / 2) fd = sp.fireDelayVel + fdv * i;
  524.         else fd = sp.fireDelayVel + fdv * (sp.childrenCount - 1 - i);
  525.         addCircleChildren(cc, index - 1, sps, bsr * bulletSpeedRatio, fireDelay + fd);
  526.         c.children.push(cc);
  527.     }
  528.     c.bulletSpeedRatio = bulletSpeedRatio;
  529.     c.ticks = fireDelay;
  530.     c.spec = sp; c.start();
  531. }
  532. // Sparks.
  533. var sparks:Vector.<Spark>;
  534. class Spark extends VelocityActor
  535. {
  536.     public var size:Number;
  537.     public var r:int, g:int, b:int;
  538.     override public function update():Boolean
  539.     {
  540.         vel.scaleBy(0.99);
  541.         size *= 0.95;
  542.         r += (BACKGROUND_BRIGHTNESS - r) * 0.1;
  543.         g += (BACKGROUND_BRIGHTNESS - g) * 0.1;
  544.         b += (BACKGROUND_BRIGHTNESS - b) * 0.1;
  545.         var cr:Number = rand() + 0.5;
  546.         var br:int = r * cr, bg:int = g * cr, bb:int = b * cr;
  547.         if (br > 255) br = 255;
  548.         if (bg > 255) bg = 255;
  549.         if (bb > 255) bb = 255;
  550.         drawBox(pos.x, pos.y, size, size, r * 0x10000 + g * 0x100 + b, 1.5, br, bg, bb);
  551.         return super.update();
  552.     }
  553. }
  554. function addSparks(count:int, x:Number, y:Number, speed:Number, size:Number, r:int, g:int ,b:int):void
  555. {
  556.     for (var i:int = 0; i < count; i++)
  557.     {
  558.         var s:Spark = new Spark;
  559.         s.pos.x = x; s.pos.y = y;
  560.         var a:Number = rand() * PI * 2, sp:Number = speed * (0.5 + rand());
  561.         s.vel.x = Math.sin(a) * sp; s.vel.y = Math.cos(a) * sp;
  562.         s.size = size;
  563.         s.r = r; s.g = g; s.b = b;
  564.         s.ticks = 15 + 15 * rand();
  565.         sparks.push(s);
  566.     }
  567. }
  568. // Game field.
  569. class Field
  570. {
  571.     public static const SIDE_BOARD_WIDTH:Number = SCREEN_WIDTH / 6;
  572.     public static var size:Vector3D = new Vector3D;
  573.     public static var offsetX:Number = 0;
  574.     public static function initialize():void
  575.     {
  576.         size.x = SCREEN_WIDTH * 1.1 / 2; size.y = SCREEN_HEIGHT * 1.1 / 2;
  577.     }
  578.     public static function drawSideBoard():void
  579.     {
  580.         rect.width = SIDE_BOARD_WIDTH; rect.height = SCREEN_HEIGHT; rect.y = 0;
  581.         rect.x = 0;                         screen.fillRect(rect, BACKGROUND_COLOR);
  582.         rect.x = SCREEN_WIDTH - rect.width; screen.fillRect(rect, BACKGROUND_COLOR);
  583.     }
  584.     public static function contains(p:Vector3D):Boolean
  585.     {
  586.         return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  587.     }
  588. }
  589. // Blur effect.
  590. const BLUR_MAX_COUNT:int = 512, BLUR_HISTORY_COUNT:int = 6;
  591. var blurs:Vector.<Vector.<Blur>> = new Vector.<Vector.<Blur>>(BLUR_HISTORY_COUNT, true);
  592. var blurCounts:Vector.<int> = new Vector.<int>(BLUR_HISTORY_COUNT, true);
  593. var blurIndex:int;
  594. class Blur
  595. {
  596.     public var pos:Vector3D = new Vector3D;
  597.     public var width:Number, height:Number;
  598.     public var r:int, g:int, b:int;
  599.     public function update():void
  600.     {
  601.         rect.x = pos.x - width  / 2 - Field.offsetX; rect.width = width;
  602.         rect.y = pos.y - height / 2; rect.height = height;
  603.         screen.fillRect(rect, r * 0x10000 + g * 0x100 + b);
  604.         width *= 1.2; height *= 1.2;
  605.         r += (BACKGROUND_BRIGHTNESS - r) * 0.2;
  606.         g += (BACKGROUND_BRIGHTNESS - g) * 0.2;
  607.         b += (BACKGROUND_BRIGHTNESS - b) * 0.2;
  608.     }
  609. }
  610. function drawBox(x:Number, y:Number, w:int, h:int, color:int,
  611.                  blurSizeRatio:Number, br:int, bg:int, bb:int):void
  612. {
  613.     rect.x = x - w / 2 + SCREEN_WIDTH / 2 - Field.offsetX;
  614.     rect.y = y - h / 2 + SCREEN_HEIGHT / 2;
  615.     rect.width = w; rect.height = h;
  616.     screen.fillRect(rect, color);
  617.     if (blurSizeRatio > 0) addBlur(x, y, w * blurSizeRatio, h * blurSizeRatio, br, bg, bb);
  618. }
  619. function addBlur(x:Number, y:Number, w:Number, h:Number, r:int, g:int, b:int):void
  620. {
  621.     if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  622.     var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  623.     bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  624.     bl.width = w; bl.height = h;
  625.     bl.r = r; bl.g = g; bl.b = b;
  626.     blurCounts[blurIndex]++;
  627. }
  628. function updateBlurs():void
  629. {
  630.     var bi:int = blurIndex + 1;
  631.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  632.     {
  633.         if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  634.         for (var j:int = 0; j < blurCounts[bi]; j++) blurs[bi][j].update();
  635.         bi++;
  636.     }
  637.     blurIndex++;
  638.     if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  639.     blurCounts[blurIndex] = 0;
  640. }
  641. function initializeBlurs():void
  642. {
  643.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  644.     {
  645.         var bs:Vector.<Blur> = new Vector.<Blur>(BLUR_MAX_COUNT, true);
  646.         for (var j:int = 0; j < BLUR_MAX_COUNT; j++) bs[j] = new Blur;
  647.         blurs[i] = bs; blurCounts[i] = 0;
  648.     }
  649.     blurIndex = 0;
  650. }
  651. // Utility classes and functions.
  652. class Key
  653. {
  654.     public static var left:Boolean, up:Boolean, right:Boolean, down:Boolean;
  655.     public static var button1:Boolean;
  656.     public static function onKeyDown(event:KeyboardEvent):void
  657.     {
  658.         switch (event.keyCode)
  659.         {
  660.             case 0x25:case 0x41: left =    truebreak;
  661.             case 0x26:case 0x57: up =      truebreak;
  662.             case 0x27:case 0x44: right =   truebreak;
  663.             case 0x28:case 0x53: down =    truebreak;
  664.             case 0x5a:case 0xbf:
  665.             case 0x58:case 0xbe: button1 = truebreak;
  666.         }
  667.     }
  668.     public static function onKeyUp(event:KeyboardEvent):void
  669.     {
  670.         switch (event.keyCode)
  671.         {
  672.             case 0x25:case 0x41: left =    falsebreak;
  673.             case 0x26:case 0x57: up =      falsebreak;
  674.             case 0x27:case 0x44: right =   falsebreak;
  675.             case 0x28:case 0x53: down =    falsebreak;
  676.             case 0x5a:case 0xbf:
  677.             case 0x58:case 0xbe: button1 = falsebreak;
  678.         }
  679.     }
  680. }
  681. function createTextField(x:int, y:int, width:int, size:int, color:int,
  682.                          align:String = TextFormatAlign.LEFT):TextField
  683. {
  684.     var fm:TextFormat = new TextFormat;
  685.     fm.font = "_typewriter"; fm.bold = true;
  686.     fm.size = size; fm.color = color; fm.align = align;
  687.     var fi:TextField = new TextField;
  688.     fi.defaultTextFormat = fm;
  689.     fi.x = x; fi.y = y; fi.width = width; fi.selectable = false;
  690.     return fi;
  691. }
noswf
  1. // forked from ABA's CircleCycle
  2. // CircleCycle.as
  3. //  Destroy circles and avoid incoming bullets.
  4. //  <Control>
  5. //   Movement: Arrow or [WASD] keys.
  6. //   Fire:    [Z], [X], [.] or [/] key.
  7. package
  8. {
  9.     import flash.display.Sprite;
  10.     [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  11.     public class CircleCycle extends Sprite
  12.     {
  13.         public function CircleCycle()
  14.         {
  15.             main = this;
  16.             initialize();
  17.         }
  18.     }
  19. }
  20. import flash.display.Sprite;
  21. import flash.display.Bitmap;
  22. import flash.display.BitmapData;
  23. import flash.display.Graphics;
  24. import flash.geom.Rectangle;
  25. import flash.geom.Vector3D;
  26. import flash.text.TextField;
  27. import flash.text.TextFormat;
  28. import flash.text.TextFormatAlign;
  29. import flash.events.Event;
  30. import flash.events.KeyboardEvent;
  31. const SCREEN_WIDTH:int = 465, SCREEN_HEIGHT:int = 465;
  32. const TITLE:int = 0, GAME:int = 1, GAME_OVER:int = 2;
  33. const GAME_OVER_DURATION:int = 150, BLOCK_GAME_START_DURATION:int = 30;
  34. const BACKGROUND_BRIGHTNESS:int = 200;
  35. const BACKGROUND_COLOR:int = BACKGROUND_BRIGHTNESS * 0x10000 + BACKGROUND_BRIGHTNESS * 0x100 + BACKGROUND_BRIGHTNESS;
  36. var main:Sprite;
  37. var screen:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  38. var scoreField:TextField = new TextField;
  39. var timeField:TextField = new TextField;
  40. var messageField:TextField = new TextField;
  41. var score:int, time:int, stage:int, gameOverTicks:int;
  42. var rect:Rectangle = new Rectangle;
  43. var pos:Vector3D = new Vector3D, offset:Vector3D = new Vector3D;
  44. var rand:Function = Math.random, abs:Function = Math.abs;
  45. var sin:Function = Math.sin, cos:Function = Math.cos, atan2:Function = Math.atan2;
  46. var PI:Number = Math.PI;
  47. function initialize():void
  48. {
  49.     main.addChild(new Bitmap(screen));
  50.     main.stage.addEventListener(KeyboardEvent.KEY_DOWN, Key.onKeyDown);
  51.     main.stage.addEventListener(KeyboardEvent.KEY_UP,   Key.onKeyUp);
  52.     Field.initialize();
  53.     initializeBlurs();
  54.     player.initialize();
  55.     scoreField = createTextField(SCREEN_WIDTH - 100010024, 0xff6666, TextFormatAlign.RIGHT);
  56.     timeField = createTextField(SCREEN_WIDTH / 2 - 100, SCREEN_HEIGHT - 4820048, 0xff6666, TextFormatAlign.RIGHT);
  57.     messageField = createTextField(SCREEN_WIDTH - 256025636, 0xff6666);
  58.     main.addChild(scoreField); main.addChild(timeField); main.addChild(messageField);
  59.     start(TITLE);
  60.     main.addEventListener(Event.ENTER_FRAME, update);
  61. }
  62. function update(event:Event):void
  63. {
  64.     if (circles.length <= 0) goToNextStage();
  65.     screen.lock();
  66.     screen.fillRect(screen.rect, BACKGROUND_COLOR);
  67.     updateBlurs();
  68.     var i:int;
  69.     for (i = 0; i < sparks.length; i++)  if (!sparks[i].update())  { sparks.splice(i, 1); i--; }
  70.     for (i = 0; i < shots.length; i++)   if (!shots[i].update())   { shots.splice(i, 1);  i--; }
  71.     for each (var c:Circle in circles) c.update();
  72.     for (i = 0; i < circles.length; i++) if (!circles[i].exists)   { circles.splice(i, 1); i--; }
  73.     if (gameOverTicks < 0) player.update();
  74.     for (i = 0; i < bullets.length; i++) if (!bullets[i].update()) { bullets.splice(i, 1); i--; }
  75.     Field.drawSideBoard();
  76.     screen.unlock();
  77.     if (gameOverTicks < 0)
  78.     {
  79.         var msStr:String = String(time % 1000);
  80.         for (i = 0; i < 3 - msStr.length; i++) msStr = "0" + msStr;
  81.         timeField.text = String(int(time / 1000)) + "\"" + msStr;
  82.         if (time <= 0) start(GAME_OVER);
  83.         time -= 33;
  84.     }
  85.     else
  86.     {
  87.         gameOverTicks++;
  88.         if (gameOverTicks == GAME_OVER_DURATION) start(TITLE);
  89.         if (Key.button1 && gameOverTicks > BLOCK_GAME_START_DURATION) start(GAME);
  90.     }
  91. }
  92. function goToNextStage():void
  93. {
  94.     if (gameOverTicks < 0 && stage > 0) score += time;
  95.     scoreField.text = String(score);
  96.     stage++;
  97.     time = 5000;
  98.     addCircles((rand() - 0.5) * Field.size.x, 250.0 / (20.0 + stage), 5.0 + rand() * 2.0 + rand() * 2.0);
  99. }
  100. function start(mode:int):void
  101. {
  102.     switch (mode)
  103.     {
  104.         case TITLE:
  105.         {
  106.             clearActors();
  107.             player.hide();
  108.             gameOverTicks = GAME_OVER_DURATION;
  109.             messageField.y = SCREEN_HEIGHT / 3 * 2; messageField.text = "CircleCycle";
  110.             break;
  111.         }
  112.         case GAME:
  113.         {
  114.             clearActors();
  115.             player.start();
  116.             gameOverTicks = -1;
  117.             messageField.text = "";
  118.             score = 0; stage = 0;
  119.             break;
  120.         }
  121.         case GAME_OVER:
  122.         {
  123.             player.hide();
  124.             gameOverTicks = 0;
  125.             messageField.y = SCREEN_HEIGHT / 2; messageField.text = "GAME OVER";
  126.             timeField.text = "";
  127.             break;
  128.         }
  129.     }
  130. }
  131. function clearActors():void
  132. {
  133.     shots = null; bullets = null; sparks = null;
  134.     shots = new Vector.<Shot>; bullets = new Vector.<Bullet>; sparks = new Vector.<Spark>;
  135.     for each (var c:Circle in circles) c.remove();
  136.     circles = null; circles = new Vector.<Circle>;
  137. }
  138. // Game actor base class.
  139. class Actor
  140. {
  141.     public var pos:Vector3D = new Vector3D;
  142. }
  143. class VelocityActor extends Actor
  144. {
  145.     public var vel:Vector3D = new Vector3D;
  146.     public var ticks:int;
  147.     public function update():Boolean
  148.     {
  149.         pos.incrementBy(vel);
  150.         ticks++;
  151.         if (!Field.contains(pos) || ticks > 300return false;
  152.         return true;
  153.     }
  154. }
  155. // Player.
  156. var player:Player = new Player;
  157. class Player extends Actor
  158. {
  159.     private const INVINCIBLE_DURATION:int = 90;
  160.     private const COLLISION_SIZE:Number = 5.0;
  161.     private const SPEED:Number = 9.0;
  162.     private var vel:Vector3D = new Vector3D;
  163.     private var fireTicks:int;
  164.     private var sprite:Sprite = new Sprite;
  165.     public function initialize():void
  166.     {
  167.         var g:Graphics = sprite.graphics;
  168.         g.lineStyle(5, 0x008800);
  169.         g.moveTo(0, -10); g.lineTo(-10,10); g.lineTo(1010); g.lineTo(0, -10);
  170.         main.addChild(sprite);
  171.     }
  172.     public function start():void
  173.     {
  174.         pos.x = 0; pos.y = Field.size.y * 0.5;
  175.         vel.y = -5.0;
  176.     }
  177.     public function hide():void
  178.     {
  179.         sprite.x = sprite.y = 99999;
  180.     }
  181.     public function update():void
  182.     {
  183.         offset.x = offset.y = 0;
  184.         if (Key.left)  offset.x = -1;
  185.         if (Key.right) offset.x = 1;
  186.         if (Key.up)    offset.y = -1;
  187.         if (Key.down)  offset.y = 1;
  188.         if (offset.x != 0 && offset.y != 0) offset.scaleBy(0.7);
  189.         offset.scaleBy(SPEED); pos.incrementBy(offset);
  190.         pos.incrementBy(vel); vel.scaleBy(0.9);
  191.         if (pos.x < -SCREEN_WIDTH  / 2) pos.x = -SCREEN_WIDTH / 2;
  192.         if (pos.x >  SCREEN_WIDTH  / 2) pos.x =  SCREEN_WIDTH / 2;
  193.         if (pos.y < -SCREEN_HEIGHT / 2) pos.y = -SCREEN_HEIGHT / 2;
  194.         if (pos.y >  SCREEN_HEIGHT / 2) pos.y =  SCREEN_HEIGHT / 2;
  195.         Field.offsetX = pos.x * 0.33;
  196.         sprite.x = pos.x + SCREEN_WIDTH / 2 - Field.offsetX;
  197.         sprite.y = pos.y + SCREEN_WIDTH / 2;
  198.         var bc:int = time * 150 / 5000;
  199.         addBlur(pos.x, pos.y - 777250 - bc, 50 + bc, 100);
  200.         addBlur(pos.x, pos.y + 31515250 - bc, 50 + bc, 100);
  201.         drawBox(pos.x + time * 0.02 / 2, pos.y + 15, time * 0.0210,
  202.                 (150 - bc) * 0x10000 + bc * 0x100, 0000);
  203.         var i:int;
  204.         if (fireTicks <= 0 && shots.length <= 7 && abs(vel.y) < 1.0 && Key.button1)
  205.         {
  206.             fireTicks = 2;
  207.             var s:Shot;
  208.             for (i = 0; i < 7; i++)
  209.             {
  210.                 s = new Shot;
  211.                 s.pos.x = pos.x; s.pos.y = pos.y;
  212.                 var d:Number = (i - 3) * 0.1;
  213.                 s.vel.x = sin(d) * 24.0; s.vel.y = -cos(d) * 24.0;
  214.                 shots.push(s);
  215.             }
  216.         }
  217.         fireTicks--;
  218.         i = 0;
  219.         for each (var b:Bullet in bullets)
  220.         {
  221.             if (Vector3D.distance(pos, b.pos) <= COLLISION_SIZE)
  222.             {
  223.                 if (vel.y < 1.0)
  224.                 {
  225.                     vel.y += 20.0;
  226.                     addSparks(50, pos.x, pos.y, 30.015.0200200100);
  227.                     time /= 2;
  228.                 }
  229.                 else
  230.                 {
  231.                     bullets.splice(i, 1); i--;
  232.                 }
  233.             }
  234.             i++;
  235.         }
  236.     }
  237. }
  238. // Player's shots.
  239. var shots:Vector.<Shot> = new Vector.<Shot>;
  240. class Shot extends VelocityActor
  241. {
  242.     override public function update():Boolean
  243.     {
  244.         for each (var c:Circle in circles) if (checkHit(c)) return false;
  245.         addBlur(pos.x, pos.y, 201550150100);
  246.         return super.update();
  247.     }