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


embed

FAVORITE BY
:
発泡スチロールを連想させるゲーム。楽しくて綺麗で軽快
:
:
ball blast, quite funny
:
:
:
:
:
gamenice game
:
gameNice Game
:
:
シンプルゲーム
:
gamesimple, addictive and fun :D
:
:
ゲーム
:
:
:
great, but hard to play, needs smaller circle :)
:
nice i got 336
:
:
:
:
:
:
:
:
gamesお気に入り第一号
:
Addictive :D
:
BallBlast
:
Cool
:
I love it!
:
おもろい
:
ABA
:
cool
:
ゲーム
:
gameおもしろい
:
相変わらずお美しい!
:
赤に触らないように白を消してくゲーム
:
568点..
FORKED
  1. // forked from ABA's BallBlast
  2. // BallBlast.as
  3. //  - Blast while balls.
  4. //  - When the red ball is blasted or the ball reaches the celling,
  5. //    the game is over.
  6. //  <Control>
  7. //   Mouse: Move the red ring.
  8. //   Click: Blast balls in the red ring.
  9. package
  10. {
  11.     import flash.display.Sprite;
  12.     import flash.events.Event;
  13.     [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  14.     public class BallBlast extends Sprite
  15.     {
  16.         public function BallBlast()
  17.         {
  18.             main = this;
  19.             initialize();
  20.             addEventListener(Event.ENTER_FRAME, update);
  21.         }
  22.     }
  23. }
  24. import flash.display.Sprite;
  25. import flash.display.Bitmap;
  26. import flash.display.BitmapData;
  27. import flash.geom.Rectangle;
  28. import flash.geom.Vector3D;
  29. import flash.text.TextField;
  30. import flash.text.TextFormat;
  31. import flash.text.TextFormatAlign;
  32. import flash.events.Event;
  33. import flash.events.MouseEvent;
  34. const SCREEN_WIDTH:int = 465;
  35. const SCREEN_HEIGHT:int = 465;
  36. var main:Sprite;
  37. var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  38. var isMouseClicked:Boolean;
  39. var mousePos:Vector3D = new Vector3D;
  40. var rect:Rectangle = new Rectangle;
  41. var offset:Vector3D = new Vector3D;
  42. var ticks:int;
  43. var scoreField:TextField = new TextField;
  44. var score:int;
  45. const GAME_OVER_DURATION:int = 150;
  46. const NO_START_DURATION:int = 30;
  47. var gameOverTicks:int;
  48. var lastBall:Ball;
  49. var messageField:TextField = new TextField;
  50. function initialize():void
  51. {
  52.     main.addChild(new Bitmap(buffer));
  53.     main.stage.addEventListener(MouseEvent.CLICK, function(e:Event):void { isMouseClicked = true; } );
  54.     Field.initialize();
  55.     initializeBlurs();
  56.     scoreField = createTextField(SCREEN_WIDTH - 100010024, 0xff6666, TextFormatAlign.RIGHT);
  57.     main.addChild(scoreField);
  58.     messageField = createTextField(SCREEN_WIDTH - 256025636, 0xff6666);
  59.     main.addChild(messageField);
  60.     startTitle();
  61. }
  62. function update(event:Event):void
  63. {
  64.     mousePos.x = main.stage.mouseX - SCREEN_WIDTH / 2;
  65.     mousePos.y = main.stage.mouseY - SCREEN_HEIGHT / 2;
  66.     if (isMouseClicked)
  67.     {
  68.         isMouseClicked = false;
  69.         if (gameOverTicks < 0) blastBalls(mousePos);
  70.         else if (gameOverTicks > NO_START_DURATION) startGame();
  71.     }
  72.     buffer.lock();
  73.     buffer.fillRect(buffer.rect, 0);
  74.     updateBlurs();
  75.     updateSparks();
  76.     var b:Ball;
  77.     for each (b in balls) b.update();
  78.     for each (b in balls) if (!b.isRed) b.draw();
  79.     for each (b in balls) if (b.isRed)  b.draw();
  80.     if (gameOverTicks < 0) drawBlastCircle();
  81.     buffer.unlock();
  82.     if (gameOverTicks < 0 || gameOverTicks > GAME_OVER_DURATION)
  83.     {
  84.         if (ticks % 5 == 0)    balls.push(new Ball(false));
  85.         if (ticks % 256 == 50) balls.push(new Ball(true));
  86.     }
  87.     ticks++;
  88.     if (gameOverTicks >= 0)
  89.     {
  90.         if (gameOverTicks == GAME_OVER_DURATION) startTitle();
  91.         gameOverTicks++;
  92.         if (lastBall != null) lastBall.draw();
  93.     }
  94. }
  95. function drawBlastCircle():void
  96. {
  97.     offset.x = 0; offset.y = BALL_BLAST_RADIUS;
  98.     rotation(offset, ticks * 0.05);
  99.     for (var i:int = 0; i < 16; i++)
  100.     {
  101.         drawBox(mousePos.x + offset.x, mousePos.y + offset.y, 7, 0xee0000,
  102.                 13200100100);
  103.         rotation(offset, Math.PI * 2 / 16);
  104.     }
  105. }
  106. function startTitle():void
  107. {
  108.     ticks = 0;
  109.     lastBall = null;
  110.     gameOverTicks = GAME_OVER_DURATION;
  111.     messageField.y = SCREEN_HEIGHT / 3;
  112.     messageField.text = "BallBlast";
  113. }
  114. function startGame():void
  115. {
  116.     blastAllBalls();
  117.     lastBall = null;
  118.     score = 0;
  119.     scoreField.text = String(score);
  120.     ticks = 0;
  121.     gameOverTicks = -1;
  122.     messageField.text = "";
  123. }
  124. function startGameOver():void
  125. {
  126.     blastAllBalls();
  127.     if (gameOverTicks >= 0return;
  128.     gameOverTicks = 0;
  129.     messageField.y = SCREEN_HEIGHT / 2;
  130.     messageField.text = "GAME OVER";
  131. }
  132. // Balls.
  133. const BALL_BLAST_RADIUS:Number = 64.0;
  134. var balls:Vector.<Ball> = new Vector.<Ball>;
  135. class Ball
  136. {
  137.     private const GRAVITY_FORCE:Number = 0.5;
  138.     private const MAX_VELOCITY_CHANGE:Number = 0.5;
  139.     public var pos:Vector3D = new Vector3D;
  140.     public var vel:Vector3D = new Vector3D;
  141.     public var radius:Number;
  142.     public var angle:Number, angleVel:Number;
  143.     public var isInAppearance:Boolean;
  144.     public var isRed:Boolean;
  145.     public function Ball(isRed:Boolean):void
  146.     {
  147.         if (!isRed)
  148.         {
  149.             radius = 20.0 + Math.random() * 20.0;
  150.             pos.x = (Math.random() * 2 - 1) * (Field.size.x - radius * 1.1);
  151.             pos.y = Field.size.y + radius * 1.1;
  152.             isInAppearance = true;
  153.         }
  154.         else
  155.         {
  156.             radius = 20.0;
  157.             pos.x = 0; pos.y = -Field.size.y * 0.8;
  158.             isInAppearance = false;
  159.         }
  160.         vel.x = vel.y = 0;
  161.         angle = Math.random() * Math.PI * 2;
  162.         angleVel = (Math.random() * 2 - 1) * 0.1;
  163.         this.isRed = isRed;
  164.     }
  165.     public function update():void
  166.     {
  167.         if (isInAppearance)
  168.         {
  169.             vel.y -= GRAVITY_FORCE * 2;
  170.             if (pos.y < Field.size.y - radius) isInAppearance = false;
  171.         }
  172.         else
  173.         {
  174.             if (pos.y > Field.size.y - radius) hit(pos.y - (Field.size.y - radius), 0);
  175.             vel.y += GRAVITY_FORCE;
  176.         }
  177.         vel.scaleBy(0.95);
  178.         pos.incrementBy(vel);
  179.         if (pos.y < -Field.size.y + radius)
  180.         {
  181.             if (gameOverTicks < 0) lastBall = this;
  182.             startGameOver();
  183.             return;
  184.         }
  185.         if (pos.x > Field.size.x - radius) hit(pos.x - (Field.size.x - radius), Math.PI / 2);
  186.         if (pos.x < -Field.size.x + radius) hit((-Field.size.y + radius) - pos.x, Math.PI / 2 * 3);
  187.         for each (var b:Ball in balls)
  188.         {
  189.             if (b == thiscontinue;
  190.             var d:Number = radius + b.radius - Vector3D.distance(pos, b.pos);
  191.             if (d > 0) hit(d, Math.atan2(b.pos.x - pos.x, b.pos.y - pos.y));
  192.         }
  193.         angle += angleVel; angleVel *= 0.95;
  194.     }
  195.     public function draw():void
  196.     {
  197.         offset.x = 0; offset.y = radius / 2;
  198.         rotation(offset, angle);
  199.         var color:int , r:int ,g:int, b:int;
  200.         if (!isRed)
  201.         {
  202.             color = 0xeeeeee; r = 200; g = 200; b = 200;
  203.         }
  204.         else
  205.         {
  206.             color = 0xff0000; r = 250; g = 200; b = 200;
  207.         }
  208.         for (var i:int = 0; i < 3; i++)
  209.         {
  210.             drawBox(pos.x + offset.x, pos.y + offset.y, radius, color, radius, r, g, b);
  211.             rotation(offset, Math.PI * 2 / 3);
  212.         }
  213.     }
  214.     private function hit(d:Number, a:Number):void
  215.     {
  216.         if (isInAppearance) return;
  217.         var sv:Number = Math.sin(a) * d, cv:Number = Math.cos(a) * d;
  218.         pos.x -= sv / 2; pos.y -= cv / 2;
  219.         angleVel += (-sv * 0.1 - angleVel) * 0.1;
  220.         sv *= 0.1 * vel.x; cv *= 0.1 * vel.y;
  221.         if (sv > MAX_VELOCITY_CHANGE) sv = MAX_VELOCITY_CHANGE;
  222.         if (sv < -MAX_VELOCITY_CHANGE) sv = -MAX_VELOCITY_CHANGE;
  223.         if (cv > MAX_VELOCITY_CHANGE) cv = MAX_VELOCITY_CHANGE;
  224.         if (cv < -MAX_VELOCITY_CHANGE) cv = -MAX_VELOCITY_CHANGE;
  225.         vel.x -= sv; vel.y -= cv;
  226.     }
  227. }
  228. function blastBalls(p:Vector3D):void
  229. {
  230.     var bc:int = 0;
  231.     var b:Ball;
  232.     for each (b in balls)
  233.     {
  234.         if (Vector3D.distance(b.pos, p) < BALL_BLAST_RADIUS + b.radius)
  235.         {
  236.             if (b.isRed)
  237.             {
  238.                 lastBall = b;
  239.                 startGameOver();
  240.                 return;
  241.             }
  242.             bc++;
  243.         }
  244.     }
  245.     score += bc;
  246.     scoreField.text = String(score);
  247.     for (var i:int = 0; i < balls.length; i++)
  248.     {
  249.         b = balls[i];
  250.         if (Vector3D.distance(b.pos, p) < BALL_BLAST_RADIUS + b.radius)
  251.         {
  252.             addSparks(10, b.pos, 20.020.0250250250);
  253.             balls.splice(i, 1); i--;
  254.         }
  255.     }
  256. }
  257. function blastAllBalls():void
  258. {
  259.     for each (var b:Ball in balls) addSparks(5, b.pos, 20.020.025000);
  260.     balls = new Vector.<Ball>;
  261. }
  262. // Sparks.
  263. var sparks:Vector.<Spark> = new Vector.<Spark>;
  264. class Spark
  265. {
  266.     public var pos:Vector3D = new Vector3D;
  267.     public var vel:Vector3D = new Vector3D;
  268.     public var size:Number;
  269.     public var r:int, g:int, b:int;
  270.     public var ticks:int;
  271.     public function update():Boolean
  272.     {
  273.         pos.incrementBy(vel);
  274.         vel.y += 0.5;
  275.         vel.scaleBy(0.99);
  276.         size *= 0.95;
  277.         r *= 0.98; g *= 0.98; b *= 0.98;
  278.         if (pos.x < -Field.size.x && vel.x < 0 ||
  279.             pos.x >  Field.size.x && vel.x > 0) vel.x *= -1;
  280.         if (pos.y < -Field.size.y && vel.y < 0 ||
  281.             pos.y >  Field.size.y && vel.y > 0) vel.y *= -1;
  282.         var cr:Number = Math.random();
  283.         drawBox(pos.x, pos.y, size, r * 0x10000 + g * 0x100 + b, size, r * cr, g * cr, b * cr);
  284.         ticks--;
  285.         return (ticks >= 0);
  286.     }
  287. }
  288. function addSparks(count:int, p:Vector3D, speed:Number, size:Number, r:int, g:int ,b:int):void
  289. {
  290.     for (var i:int = 0; i < count; i++)
  291.     {
  292.         var s:Spark = new Spark;
  293.         s.pos.x = p.x; s.pos.y = p.y;
  294.         var a:Number = Math.random() * Math.PI * 2;
  295.         var sp:Number = speed * (0.5 + Math.random());
  296.         s.vel.x = Math.sin(a) * sp; s.vel.y = Math.cos(a) * sp;
  297.         s.size = size;
  298.         s.r = r; s.g = g; s.b = b;
  299.         s.ticks = 15 + 15 * Math.random();
  300.         sparks.push(s);
  301.     }
  302. }
  303. function updateSparks():void
  304. {
  305.     for (var i:int = 0; i < sparks.length; i++)
  306.     {
  307.         if (!sparks[i].update())
  308.         {
  309.             sparks.splice(i, 1); i--;
  310.         }
  311.     }
  312. }
  313. // Game field.
  314. class Field
  315. {
  316.     public static var size:Vector3D = new Vector3D;
  317.     public static function initialize():void
  318.     {
  319.         size.x = SCREEN_WIDTH * 0.9 / 2; size.y = SCREEN_HEIGHT * 0.9 / 2;
  320.     }
  321.     public static function contains(p:Vector3D):Boolean
  322.     {
  323.         return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  324.     }
  325. }
  326. // Blur effect.
  327. const BLUR_MAX_COUNT:int = 512;
  328. const BLUR_HISTORY_COUNT:int = 6;
  329. var blurs:Vector.<Vector.<Blur>> = new Vector.<Vector.<Blur>>(BLUR_HISTORY_COUNT, true);
  330. var blurCounts:Vector.<int> = new Vector.<int>(BLUR_HISTORY_COUNT, true);
  331. var blurIndex:int;
  332. class Blur
  333. {
  334.     public var pos:Vector3D = new Vector3D;
  335.     public var width:Number, height:Number;
  336.     public var r:int, g:int, b:int;
  337.     public function update():void
  338.     {
  339.         rect.x = pos.x - width / 2;
  340.         rect.y = pos.y - height / 2;
  341.         rect.width = width; rect.height = height;
  342.         buffer.fillRect(rect, r * 0x10000 + g * 0x100 + b);
  343.         width *= 1.2; height *= 1.2;
  344.         var a:int = (r + g + b) / 3;
  345.         r += (a - r) * 0.25;
  346.         g += (a - g) * 0.25;
  347.         b += (a - b) * 0.25;
  348.         r *= 0.65; g *= 0.65; b *= 0.65;
  349.     }
  350. }
  351. function drawBox(x:Number, y:Number, size:int, color:int,
  352.                  bsize:int, br:int, bg:int, bb:int):void
  353. {
  354.     rect.x = x - size / 2 + SCREEN_WIDTH / 2;
  355.     rect.y = y - size / 2 + SCREEN_HEIGHT / 2;
  356.     rect.width = rect.height = size;
  357.     buffer.fillRect(rect, color);
  358.     addBlur(x, y, bsize, bsize, br, bg, bb);
  359. }
  360. function addBlur(x:Number, y:Number, w:Number, h:Number,
  361.                  r:int, g:int, b:int):void
  362. {
  363.     if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  364.     var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  365.     bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  366.     bl.width = w; bl.height = h;
  367.     bl.r = r; bl.g = g; bl.b = b;
  368.     blurCounts[blurIndex]++;
  369. }
  370. function updateBlurs():void
  371. {
  372.     var bi:int = blurIndex + 1;
  373.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  374.     {
  375.         if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  376.         for (var j:int = 0; j < blurCounts[bi]; j++) blurs[bi][j].update();
  377.         bi++;
  378.     }
  379.     blurIndex++;
  380.     if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  381.     blurCounts[blurIndex] = 0;
  382. }
  383. function initializeBlurs():void
  384. {
  385.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  386.     {
  387.         var bs:Vector.<Blur> = new Vector.<Blur>(BLUR_MAX_COUNT, true);
  388.         for (var j:int = 0; j < BLUR_MAX_COUNT; j++)
  389.         {
  390.             bs[j] = new Blur;
  391.         }
  392.         blurs[i] = bs;
  393.         blurCounts[i] = 0;
  394.     }
  395.     blurIndex = 0;
  396. }
  397. // Utility functions.
  398. function rotation(v:Vector3D, a:Number):void
  399. {
  400.     var sv:Number = Math.sin(a);
  401.     var cv:Number = Math.cos(a);
  402.     var rx:Number = cv * v.x - sv * v.y;
  403.     v.y = sv * v.x + cv * v.y;
  404.     v.x = rx;
  405. }
  406. function normalizeAngle(v:Number):Number
  407. {
  408.     if (v > Math.PI)       return v - Math.PI * 2;
  409.     else if (v < -Math.PI) return v + Math.PI * 2;
  410.     else                   return v;
  411. }
  412. function createTextField(x:int, y:int, width:int, size:int, color:int,
  413.                          align:String = TextFormatAlign.LEFT):TextField
  414. {
  415.     var fm:TextFormat = new TextFormat;
  416.     fm.font = "_typewriter"; fm.bold = true;
  417.     fm.size = size; fm.color = color;
  418.     fm.align = align;
  419.     var fi:TextField = new TextField;
  420.     fi.defaultTextFormat = fm;
  421.     fi.x = x; fi.y = y; fi.width = width;
  422.     fi.selectable = false;
  423.     return fi;
  424. }
noswf
  1. // forked from ABA's BallBlast
  2. // BallBlast.as
  3. //  - Blast while balls.
  4. //  - When the red ball is blasted or the ball reaches the celling,
  5. //    the game is over.
  6. //  <Control>
  7. //   Mouse: Move the red ring.
  8. //   Click: Blast balls in the red ring.
  9. package
  10. {
  11.     import flash.display.Sprite;
  12.     import flash.events.Event;
  13.     [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  14.     public class BallBlast extends Sprite
  15.     {
  16.         public function BallBlast()
  17.         {
  18.             main = this;
  19.             initialize();
  20.             addEventListener(Event.ENTER_FRAME, update);
  21.         }
  22.     }
  23. }
  24. import flash.display.Sprite;
  25. import flash.display.Bitmap;
  26. import flash.display.BitmapData;
  27. import flash.geom.Rectangle;
  28. import flash.geom.Vector3D;
  29. import flash.text.TextField;
  30. import flash.text.TextFormat;
  31. import flash.text.TextFormatAlign;
  32. import flash.events.Event;
  33. import flash.events.MouseEvent;
  34. const SCREEN_WIDTH:int = 465;
  35. const SCREEN_HEIGHT:int = 465;
  36. var main:Sprite;
  37. var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  38. var isMouseClicked:Boolean;
  39. var mousePos:Vector3D = new Vector3D;
  40. var rect:Rectangle = new Rectangle;
  41. var offset:Vector3D = new Vector3D;
  42. var ticks:int;
  43. var scoreField:TextField = new TextField;
  44. var score:int;
  45. const GAME_OVER_DURATION:int = 150;
  46. const NO_START_DURATION:int = 30;
  47. var gameOverTicks:int;
  48. var lastBall:Ball;
  49. var messageField:TextField = new TextField;
  50. function initialize():void
  51. {
  52.     main.addChild(new Bitmap(buffer));
  53.     main.stage.addEventListener(MouseEvent.CLICK, function(e:Event):void { isMouseClicked = true; } );
  54.     Field.initialize();
  55.     initializeBlurs();
  56.     scoreField = createTextField(SCREEN_WIDTH - 100010024, 0xff6666, TextFormatAlign.RIGHT);
  57.     main.addChild(scoreField);
  58.     messageField = createTextField(SCREEN_WIDTH - 256025636, 0xff6666);
  59.     main.addChild(messageField);
  60.     startTitle();
  61. }
  62. function update(event:Event):void
  63. {
  64.     mousePos.x = main.stage.mouseX - SCREEN_WIDTH / 2;
  65.     mousePos.y = main.stage.mouseY - SCREEN_HEIGHT / 2;
  66.     if (isMouseClicked)
  67.     {
  68.         isMouseClicked = false;
  69.         if (gameOverTicks < 0) blastBalls(mousePos);
  70.         else if (gameOverTicks > NO_START_DURATION) startGame();
  71.     }
  72.     buffer.lock();
  73.     buffer.fillRect(buffer.rect, 0);
  74.     updateBlurs();
  75.     updateSparks();
  76.     var b:Ball;
  77.     for each (b in balls) b.update();
  78.     for each (b in balls) if (!b.isRed) b.draw();
  79.     for each (b in balls) if (b.isRed)  b.draw();
  80.     if (gameOverTicks < 0) drawBlastCircle();
  81.     buffer.unlock();
  82.     if (gameOverTicks < 0 || gameOverTicks > GAME_OVER_DURATION)
  83.     {
  84.         if (ticks % 5 == 0)    balls.push(new Ball(false));
  85.         if (ticks % 256 == 50) balls.push(new Ball(true));
  86.     }
  87.     ticks++;
  88.     if (gameOverTicks >= 0)
  89.     {
  90.         if (gameOverTicks == GAME_OVER_DURATION) startTitle();
  91.         gameOverTicks++;
  92.         if (lastBall != null) lastBall.draw();
  93.     }
  94. }
  95. function drawBlastCircle():void
  96. {
  97.     offset.x = 0; offset.y = BALL_BLAST_RADIUS;
  98.     rotation(offset, ticks * 0.05);
  99.     for (var i:int = 0; i < 16; i++)
  100.     {
  101.         drawBox(mousePos.x + offset.x, mousePos.y + offset.y, 7, 0xee0000,
  102.                 13200100100);
  103.         rotation(offset, Math.PI * 2 / 16);
  104.     }
  105. }
  106. function startTitle():void
  107. {
  108.     ticks = 0;
  109.     lastBall = null;
  110.     gameOverTicks = GAME_OVER_DURATION;
  111.     messageField.y = SCREEN_HEIGHT / 3;
  112.     messageField.text = "BallBlast";
  113. }
  114. function startGame():void
  115. {
  116.     blastAllBalls();
  117.     lastBall = null;
  118.     score = 0;
  119.     scoreField.text = String(score);
  120.     ticks = 0;
  121.     gameOverTicks = -1;
  122.     messageField.text = "";
  123. }
  124. function startGameOver():void
  125. {
  126.     blastAllBalls();
  127.     if (gameOverTicks >= 0return;
  128.     gameOverTicks = 0;
  129.     messageField.y = SCREEN_HEIGHT / 2;
  130.     messageField.text = "GAME OVER";
  131. }
  132. // Balls.
  133. const BALL_BLAST_RADIUS:Number = 64.0;
  134. var balls:Vector.<Ball> = new Vector.<Ball>;
  135. class Ball
  136. {
  137.     private const GRAVITY_FORCE:Number = 0.5;
  138.     private const MAX_VELOCITY_CHANGE:Number = 0.5;
  139.     public var pos:Vector3D = new Vector3D;
  140.     public var vel:Vector3D = new Vector3D;
  141.     public var radius:Number;
  142.     public var angle:Number, angleVel:Number;
  143.     public var isInAppearance:Boolean;
  144.     public var isRed:Boolean;
  145.     public function Ball(isRed:Boolean):void
  146.     {
  147.         if (!isRed)
  148.         {
  149.             radius = 20.0 + Math.random() * 20.0;
  150.             pos.x = (Math.random() * 2 - 1) * (Field.size.x - radius * 1.1);
  151.             pos.y = Field.size.y + radius * 1.1;
  152.             isInAppearance = true;
  153.         }
  154.         else
  155.         {
  156.             radius = 20.0;
  157.             pos.x = 0; pos.y = -Field.size.y * 0.8;
  158.             isInAppearance = false;
  159.         }
  160.         vel.x = vel.y = 0;
  161.         angle = Math.random() * Math.PI * 2;
  162.         angleVel = (Math.random() * 2 - 1) * 0.1;
  163.         this.isRed = isRed;
  164.     }
  165.     public function update():void
  166.     {
  167.         if (isInAppearance)
  168.         {
  169.             vel.y -= GRAVITY_FORCE * 2;
  170.             if (pos.y < Field.size.y - radius) isInAppearance = false;
  171.         }
  172.         else
  173.         {
  174.             if (pos.y > Field.size.y - radius) hit(pos.y - (Field.size.y - radius), 0);
  175.             vel.y += GRAVITY_FORCE;
  176.         }
  177.         vel.scaleBy(0.95);
  178.         pos.incrementBy(vel);
  179.         if (pos.y < -Field.size.y + radius)
  180.         {
  181.             if (gameOverTicks < 0) lastBall = this;
  182.             startGameOver();
  183.             return;
  184.         }
  185.         if (pos.x > Field.size.x - radius) hit(pos.x - (Field.size.x - radius), Math.PI / 2);
  186.         if (pos.x < -Field.size.x + radius) hit((-Field.size.y + radius) - pos.x, Math.PI / 2 * 3);
  187.         for each (var b:Ball in balls)
  188.         {
  189.             if (b == thiscontinue;
  190.             var d:Number = radius + b.radius - Vector3D.distance(pos, b.pos);
  191.             if (d > 0) hit(d, Math.atan2(b.pos.x - pos.x, b.pos.y - pos.y));
  192.         }
  193.         angle += angleVel; angleVel *= 0.95;
  194.     }
  195.     public function draw():void
  196.     {
  197.         offset.x = 0; offset.y = radius / 2;
  198.         rotation(offset, angle);
  199.         var color:int , r:int ,g:int, b:int;
  200.         if (!isRed)
  201.         {
  202.             color = 0xeeeeee; r = 200; g = 200; b = 200;
  203.         }
  204.         else
  205.         {
  206.             color = 0xff0000; r = 250; g = 200; b = 200;
  207.         }
  208.         for (var i:int = 0; i < 3; i++)
  209.         {
  210.             drawBox(pos.x + offset.x, pos.y + offset.y, radius, color, radius, r, g, b);
  211.             rotation(offset, Math.PI * 2 / 3);
  212.         }
  213.     }
  214.     private function hit(d:Number, a:Number):void
  215.     {
  216.         if (isInAppearance) return;
  217.         var sv:Number = Math.sin(a) * d, cv:Number = Math.cos(a) * d;
  218.         pos.x -= sv / 2; pos.y -= cv / 2;
  219.         angleVel += (-sv * 0.1 - angleVel) * 0.1;
  220.         sv *= 0.1 * vel.x; cv *= 0.1 * vel.y;
  221.         if (sv > MAX_VELOCITY_CHANGE) sv = MAX_VELOCITY_CHANGE;
  222.         if (sv < -MAX_VELOCITY_CHANGE) sv = -MAX_VELOCITY_CHANGE;
  223.         if (cv > MAX_VELOCITY_CHANGE) cv = MAX_VELOCITY_CHANGE;
  224.         if (cv < -MAX_VELOCITY_CHANGE) cv = -MAX_VELOCITY_CHANGE;
  225.         vel.x -= sv; vel.y -= cv;
  226.     }
  227. }
  228. function blastBalls(p:Vector3D):void
  229. {
  230.     var bc:int = 0;
  231.     var b:Ball;
  232.     for each (b in balls)
  233.     {
  234.         if (Vector3D.distance(b.pos, p) < BALL_BLAST_RADIUS + b.radius)
  235.         {
  236.             if (b.isRed)
  237.             {
  238.                 lastBall = b;
  239.                 startGameOver();
  240.                 return;
  241.             }
  242.             bc++;
  243.         }
  244.     }
  245.     score += bc;
  246.     scoreField.text = String(score);
  247.     for (var i:int = 0; i < balls.length; i++)
  248.     {
  249.         b = balls[i];
  250.         if (Vector3D.distance(b.pos, p) < BALL_BLAST_RADIUS + b.radius)
  251.         {
  252.             addSparks(10, b.pos, 20.020.0250250250);
  253.             balls.splice(i, 1); i--;
  254.         }
  255.     }
  256. }
  257. function blastAllBalls():void
  258. {
  259.     for each (var b:Ball in balls) addSparks(5, b.pos, 20.020.025000);
  260.     balls = new Vector.<Ball>;
  261. }
  262. // Sparks.
  263. var sparks:Vector.<Spark> = new Vector.<Spark>;
  264. class Spark
  265. {
  266.     public var pos:Vector3D = new Vector3D;
  267.     public var vel:Vector3D = new Vector3D;
  268.     public var size:Number;
  269.     public var r:int, g:int, b:int;
  270.     public var ticks:int;
  271.     public function update():Boolean
  272.     {
  273.         pos.incrementBy(vel);
  274.         vel.y += 0.5;
  275.         vel.scaleBy(0.99);
  276.         size *= 0.95;
  277.         r *= 0.98; g *= 0.98; b *= 0.98;
  278.         if (pos.x < -Field.size.x && vel.x < 0 ||
  279.             pos.x >  Field.size.x && vel.x > 0) vel.x *= -1;
  280.         if (pos.y < -Field.size.y && vel.y < 0 ||
  281.             pos.y >  Field.size.y && vel.y > 0) vel.y *= -1;
  282.         var cr:Number = Math.random();
  283.         drawBox(pos.x, pos.y, size, r * 0x10000 + g * 0x100 + b, size, r * cr, g * cr, b * cr);
  284.         ticks--;
  285.         return (ticks >= 0);
  286.     }
  287. }
  288. function addSparks(count:int, p:Vector3D, speed:Number, size:Number, r:int, g:int ,b:int):void
  289. {
  290.     for (var i:int = 0; i < count; i++)
  291.     {
  292.         var s:Spark = new Spark;
  293.         s.pos.x = p.x; s.pos.y = p.y;
  294.         var a:Number = Math.random() * Math.PI * 2;
  295.         var sp:Number = speed * (0.5 + Math.random());
  296.         s.vel.x = Math.sin(a) * sp; s.vel.y = Math.cos(a) * sp;
  297.         s.size = size;
  298.         s.r = r; s.g = g; s.b = b;
  299.         s.ticks = 15 + 15 * Math.random();
  300.         sparks.push(s);
  301.     }
  302. }
  303. function updateSparks():void
  304. {
  305.     for (var i:int = 0; i < sparks.length; i++)
  306.     {
  307.         if (!sparks[i].update())
  308.         {
  309.             sparks.splice(i, 1); i--;
  310.         }
  311.     }
  312. }
  313. // Game field.
  314. class Field
  315. {
  316.     public static var size:Vector3D = new Vector3D;
  317.     public static function initialize():void
  318.     {
  319.         size.x = SCREEN_WIDTH * 0.9 / 2; size.y = SCREEN_HEIGHT * 0.9 / 2;
  320.     }
  321.     public static function contains(p:Vector3D):Boolean
  322.     {
  323.         return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  324.     }
  325. }
  326. // Blur effect.
  327. const BLUR_MAX_COUNT:int = 512;
  328. const BLUR_HISTORY_COUNT:int = 6;
  329. var blurs:Vector.<Vector.<Blur>> = new Vector.<Vector.<Blur>>(BLUR_HISTORY_COUNT, true);
  330. var blurCounts:Vector.<int> = new Vector.<int>(BLUR_HISTORY_COUNT, true);
  331. var blurIndex:int;
  332. class Blur
  333. {
  334.     public var pos:Vector3D = new Vector3D;
  335.     public var width:Number, height:Number;
  336.     public var r:int, g:int, b:int;
  337.     public function update():void
  338.     {
  339.         rect.x = pos.x - width / 2;
  340.         rect.y = pos.y - height / 2;
  341.         rect.width = width; rect.height = height;
  342.         buffer.fillRect(rect, r * 0x10000 + g * 0x100 + b);
  343.         width *= 1.2; height *= 1.2;
  344.         var a:int = (r + g + b) / 3;
  345.         r += (a - r) * 0.25;
  346.         g += (a - g) * 0.25;
  347.         b += (a - b) * 0.25;
  348.         r *= 0.65; g *= 0.65; b *= 0.65;
  349.     }
  350. }
  351. function drawBox(x:Number, y:Number, size:int, color:int,
  352.                  bsize:int, br:int, bg:int, bb:int):void
  353. {
  354.     rect.x = x - size / 2 + SCREEN_WIDTH / 2;
  355.     rect.y = y - size / 2 + SCREEN_HEIGHT / 2;
  356.     rect.width = rect.height = size;
  357.     buffer.fillRect(rect, color);
  358.     addBlur(x, y, bsize, bsize, br, bg, bb);
  359. }
  360. function addBlur(x:Number, y:Number, w:Number, h:Number,
  361.                  r:int, g:int, b:int):void
  362. {
  363.     if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  364.     var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  365.     bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  366.     bl.width = w; bl.height = h;
  367.     bl.r = r; bl.g = g; bl.b = b;
  368.     blurCounts[blurIndex]++;
  369. }
  370. function updateBlurs():void
  371. {
  372.     var bi:int = blurIndex + 1;
  373.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  374.     {
  375.         if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  376.         for (var j:int = 0; j < blurCounts[bi]; j++) blurs[bi][j].update();
  377.         bi++;
  378.     }
  379.     blurIndex++;
  380.     if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  381.     blurCounts[blurIndex] = 0;
  382. }
  383. function initializeBlurs():void
  384. {
  385.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  386.     {
  387.         var bs:Vector.<Blur> = new Vector.<Blur>(BLUR_MAX_COUNT, true);
  388.         for (var j:int = 0; j < BLUR_MAX_COUNT; j++)
  389.         {
  390.             bs[j] = new Blur;
  391.         }
  392.         blurs[i] = bs;
  393.         blurCounts[i] = 0;
  394.     }
  395.     blurIndex = 0;
  396. }
  397. // Utility functions.
  398. function rotation(v:Vector3D, a:Number):void
  399. {
  400.     var sv:Number = Math.sin(a);
  401.     var cv:Number = Math.cos(a);
  402.     var rx:Number = cv * v.x - sv * v.y;
  403.     v.y = sv * v.x + cv * v.y;
  404.     v.x = rx;
  405. }
  406. function normalizeAngle(v:Number):Number
  407. {
  408.     if (v > Math.PI)       return v - Math.PI * 2;
  409.     else if (v < -Math.PI) return v + Math.PI * 2;
  410.     else                   return v;
  411. }
  412. function createTextField(x:int, y:int, width:int, size:int, color:int,
  413.                          align:String = TextFormatAlign.LEFT):TextField
  414. {
  415.     var fm:TextFormat = new TextFormat;
  416.     fm.font = "_typewriter"; fm.bold = true;
  417.     fm.size = size; fm.color = color;
  418.     fm.align = align;
  419.     var fi:TextField = new TextField;
  420.     fi.defaultTextFormat = fm;
  421.     fi.x = x; fi.y = y; fi.width = width;
  422.     fi.selectable = false;
  423.     return fi;
  424. }
noswf
  1. // forked from ABA's BallBlast
  2. // BallBlast.as
  3. //  - Blast while balls.
  4. //  - When the red ball is blasted or the ball reaches the celling,
  5. //    the game is over.
  6. //  <Control>
  7. //   Mouse: Move the red ring.
  8. //   Click: Blast balls in the red ring.
  9. package
  10. {
  11.     import flash.display.Sprite;
  12.     import flash.events.Event;
  13.     [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  14.     public class BallBlast extends Sprite
  15.     {
  16.         public function BallBlast()
  17.         {
  18.             main = this;
  19.             initialize();
  20.             addEventListener(Event.ENTER_FRAME, update);
  21.         }
  22.     }
  23. }
  24. import flash.display.Sprite;
  25. import flash.display.Bitmap;
  26. import flash.display.BitmapData;
  27. import flash.geom.Rectangle;
  28. import flash.geom.Vector3D;
  29. import flash.text.TextField;
  30. import flash.text.TextFormat;
  31. import flash.text.TextFormatAlign;
  32. import flash.events.Event;
  33. import flash.events.MouseEvent;
  34. const SCREEN_WIDTH:int = 465;
  35. const SCREEN_HEIGHT:int = 465;
  36. var main:Sprite;
  37. var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  38. var isMouseClicked:Boolean;
  39. var mousePos:Vector3D = new Vector3D;
  40. var rect:Rectangle = new Rectangle;
  41. var offset:Vector3D = new Vector3D;
  42. var ticks:int;
  43. var scoreField:TextField = new TextField;
  44. var score:int;
  45. const GAME_OVER_DURATION:int = 150;
  46. const NO_START_DURATION:int = 30;
  47. var gameOverTicks:int;
  48. var lastBall:Ball;
  49. var messageField:TextField = new TextField;
  50. function initialize():void
  51. {
  52.     main.addChild(new Bitmap(buffer));
  53.     main.stage.addEventListener(MouseEvent.CLICK, function(e:Event):void { isMouseClicked = true; } );
  54.     Field.initialize();
  55.     initializeBlurs();
  56.     scoreField = createTextField(SCREEN_WIDTH - 100010024, 0xff6666, TextFormatAlign.RIGHT);
  57.     main.addChild(scoreField);
  58.     messageField = createTextField(SCREEN_WIDTH - 256025636, 0xff6666);
  59.     main.addChild(messageField);
  60.     startTitle();
  61. }
  62. function update(event:Event):void
  63. {
  64.     mousePos.x = main.stage.mouseX - SCREEN_WIDTH / 2;
  65.     mousePos.y = main.stage.mouseY - SCREEN_HEIGHT / 2;
  66.     if (isMouseClicked)
  67.     {
  68.         isMouseClicked = false;
  69.         if (gameOverTicks < 0) blastBalls(mousePos);
  70.         else if (gameOverTicks > NO_START_DURATION) startGame();
  71.     }
  72.     buffer.lock();
  73.     buffer.fillRect(buffer.rect, 0);
  74.     updateBlurs();
  75.     updateSparks();
  76.     var b:Ball;
  77.     for each (b in balls) b.update();
  78.     for each (b in balls) if (!b.isRed) b.draw();
  79.     for each (b in balls) if (b.isRed)  b.draw();
  80.     if (gameOverTicks < 0) drawBlastCircle();
  81.     buffer.unlock();
  82.     if (gameOverTicks < 0 || gameOverTicks > GAME_OVER_DURATION)
  83.     {
  84.         if (ticks % 5 == 0)    balls.push(new Ball(false));
  85.         if (ticks % 256 == 50) balls.push(new Ball(true));
  86.     }
  87.     ticks++;
  88.     if (gameOverTicks >= 0)
  89.     {
  90.         if (gameOverTicks == GAME_OVER_DURATION) startTitle();
  91.         gameOverTicks++;
  92.         if (lastBall != null) lastBall.draw();
  93.     }
  94. }
  95. function drawBlastCircle():void
  96. {
  97.     offset.x = 0; offset.y = BALL_BLAST_RADIUS;
  98.     rotation(offset, ticks * 0.05);
  99.     for (var i:int = 0; i < 16; i++)
  100.     {
  101.         drawBox(mousePos.x + offset.x, mousePos.y + offset.y, 7, 0xee0000,
  102.                 13200100100);
  103.         rotation(offset, Math.PI * 2 / 16);
  104.     }
  105. }
  106. function startTitle():void
  107. {
  108.     ticks = 0;
  109.     lastBall = null;
  110.     gameOverTicks = GAME_OVER_DURATION;
  111.     messageField.y = SCREEN_HEIGHT / 3;
  112.     messageField.text = "BallBlast";
  113. }
  114. function startGame():void
  115. {
  116.     blastAllBalls();
  117.     lastBall = null;
  118.     score = 0;
  119.     scoreField.text = String(score);
  120.     ticks = 0;
  121.     gameOverTicks = -1;
  122.     messageField.text = "";
  123. }
  124. function startGameOver():void
  125. {
  126.     blastAllBalls();
  127.     if (gameOverTicks >= 0return;
  128.     gameOverTicks = 0;
  129.     messageField.y = SCREEN_HEIGHT / 2;
  130.     messageField.text = "GAME OVER";
  131. }
  132. // Balls.
  133. const BALL_BLAST_RADIUS:Number = 64.0;
  134. var balls:Vector.<Ball> = new Vector.<Ball>;
  135. class Ball
  136. {
  137.     private const GRAVITY_FORCE:Number = 0.5;
  138.     private const MAX_VELOCITY_CHANGE:Number = 0.5;
  139.     public var pos:Vector3D = new Vector3D;
  140.     public var vel:Vector3D = new Vector3D;
  141.     public var radius:Number;
  142.     public var angle:Number, angleVel:Number;
  143.     public var isInAppearance:Boolean;
  144.     public var isRed:Boolean;
  145.     public function Ball(isRed:Boolean):void
  146.     {
  147.         if (!isRed)
  148.         {
  149.             radius = 20.0 + Math.random() * 20.0;
  150.             pos.x = (Math.random() * 2 - 1) * (Field.size.x - radius * 1.1);
  151.             pos.y = Field.size.y + radius * 1.1;
  152.             isInAppearance = true;
  153.         }
  154.         else
  155.         {
  156.             radius = 20.0;
  157.             pos.x = 0; pos.y = -Field.size.y * 0.8;
  158.             isInAppearance = false;
  159.         }
  160.         vel.x = vel.y = 0;
  161.         angle = Math.random() * Math.PI * 2;
  162.         angleVel = (Math.random() * 2 - 1) * 0.1;
  163.         this.isRed = isRed;
  164.     }
  165.     public function update():void
  166.     {
  167.         if (isInAppearance)
  168.         {
  169.             vel.y -= GRAVITY_FORCE * 2;
  170.             if (pos.y < Field.size.y - radius) isInAppearance = false;
  171.         }
  172.         else
  173.         {
  174.             if (pos.y > Field.size.y - radius) hit(pos.y - (Field.size.y - radius), 0);
  175.             vel.y += GRAVITY_FORCE;
  176.         }
  177.         vel.scaleBy(0.95);
  178.         pos.incrementBy(vel);
  179.         if (pos.y < -Field.size.y + radius)
  180.         {
  181.             if (gameOverTicks < 0) lastBall = this;
  182.             startGameOver();
  183.             return;
  184.         }
  185.         if (pos.x > Field.size.x - radius) hit(pos.x - (Field.size.x - radius), Math.PI / 2);
  186.         if (pos.x < -Field.size.x + radius) hit((-Field.size.y + radius) - pos.x, Math.PI / 2 * 3);
  187.         for each (var b:Ball in balls)
  188.         {
  189.             if (b == thiscontinue;
  190.             var d:Number = radius + b.radius - Vector3D.distance(pos, b.pos);
  191.             if (d > 0) hit(d, Math.atan2(b.pos.x - pos.x, b.pos.y - pos.y));
  192.         }
  193.         angle += angleVel; angleVel *= 0.95;
  194.     }
  195.     public function draw():void
  196.     {
  197.         offset.x = 0; offset.y = radius / 2;
  198.         rotation(offset, angle);
  199.         var color:int , r:int ,g:int, b:int;
  200.         if (!isRed)
  201.         {
  202.             color = 0xeeeeee; r = 200; g = 200; b = 200;
  203.         }
  204.         else
  205.         {
  206.             color = 0xff0000; r = 250; g = 200; b = 200;
  207.         }
  208.         for (var i:int = 0; i < 3; i++)
  209.         {
  210.             drawBox(pos.x + offset.x, pos.y + offset.y, radius, color, radius, r, g, b);
  211.             rotation(offset, Math.PI * 2 / 3);
  212.         }
  213.     }
  214.     private function hit(d:Number, a:Number):void
  215.     {
  216.         if (isInAppearance) return;
  217.         var sv:Number = Math.sin(a) * d, cv:Number = Math.cos(a) * d;
  218.         pos.x -= sv / 2; pos.y -= cv / 2;
  219.         angleVel += (-sv * 0.1 - angleVel) * 0.1;
  220.         sv *= 0.1 * vel.x; cv *= 0.1 * vel.y;
  221.         if (sv > MAX_VELOCITY_CHANGE) sv = MAX_VELOCITY_CHANGE;
  222.         if (sv < -MAX_VELOCITY_CHANGE) sv = -MAX_VELOCITY_CHANGE;
  223.         if (cv > MAX_VELOCITY_CHANGE) cv = MAX_VELOCITY_CHANGE;
  224.         if (cv < -MAX_VELOCITY_CHANGE) cv = -MAX_VELOCITY_CHANGE;
  225.         vel.x -= sv; vel.y -= cv;
  226.     }
  227. }
  228. function blastBalls(p:Vector3D):void
  229. {
  230.     var bc:int = 0;
  231.     var b:Ball;
  232.     for each (b in balls)
  233.     {
  234.         if (Vector3D.distance(b.pos, p) < BALL_BLAST_RADIUS + b.radius)
  235.         {
  236.             if (b.isRed)
  237.             {
  238.                 lastBall = b;
  239.                 startGameOver();
  240.                 return;
  241.             }
  242.             bc++;
  243.         }
  244.     }
  245.     score += bc;
  246.     scoreField.text = String(score);
  247.     for (var i:int = 0; i < balls.length; i++)
  248.     {
  249.         b = balls[i];
  250.         if (Vector3D.distance(b.pos, p) < BALL_BLAST_RADIUS + b.radius)
  251.         {
  252.             addSparks(10, b.pos, 20.020.0250250250);
  253.             balls.splice(i, 1); i--;
  254.         }
  255.     }
  256. }
  257. function blastAllBalls():void
  258. {
  259.     for each (var b:Ball in balls) addSparks(5, b.pos, 20.020.025000);
  260.     balls = new Vector.<Ball>;
  261. }
  262. // Sparks.
  263. var sparks:Vector.<Spark> = new Vector.<Spark>;
  264. class Spark
  265. {
  266.     public var pos:Vector3D = new Vector3D;
  267.     public var vel:Vector3D = new Vector3D;
  268.     public var size:Number;
  269.     public var r:int, g:int, b:int;
  270.     public var ticks:int;
  271.     public function update():Boolean
  272.     {
  273.         pos.incrementBy(vel);
  274.         vel.y += 0.5;
  275.         vel.scaleBy(0.99);
  276.         size *= 0.95;
  277.         r *= 0.98; g *= 0.98; b *= 0.98;
  278.         if (pos.x < -Field.size.x && vel.x < 0 ||
  279.             pos.x >  Field.size.x && vel.x > 0) vel.x *= -1;
  280.         if (pos.y < -Field.size.y && vel.y < 0 ||
  281.             pos.y >  Field.size.y && vel.y > 0) vel.y *= -1;
  282.         var cr:Number = Math.random();
  283.         drawBox(pos.x, pos.y, size, r * 0x10000 + g * 0x100 + b, size, r * cr, g * cr, b * cr);
  284.         ticks--;
  285.         return (ticks >= 0);
  286.     }
  287. }
  288. function addSparks(count:int, p:Vector3D, speed:Number, size:Number, r:int, g:int ,b:int):void
  289. {
  290.     for (var i:int = 0; i < count; i++)
  291.     {
  292.         var s:Spark = new Spark;
  293.         s.pos.x = p.x; s.pos.y = p.y;
  294.         var a:Number = Math.random() * Math.PI * 2;
  295.         var sp:Number = speed * (0.5 + Math.random());
  296.         s.vel.x = Math.sin(a) * sp; s.vel.y = Math.cos(a) * sp;
  297.         s.size = size;
  298.         s.r = r; s.g = g; s.b = b;
  299.         s.ticks = 15 + 15 * Math.random();
  300.         sparks.push(s);
  301.     }
  302. }
  303. function updateSparks():void
  304. {
  305.     for (var i:int = 0; i < sparks.length; i++)
  306.     {
  307.         if (!sparks[i].update())
  308.         {
  309.             sparks.splice(i, 1); i--;
  310.         }
  311.     }
  312. }
  313. // Game field.
  314. class Field
  315. {
  316.     public static var size:Vector3D = new Vector3D;
  317.     public static function initialize():void
  318.     {
  319.         size.x = SCREEN_WIDTH * 0.9 / 2; size.y = SCREEN_HEIGHT * 0.9 / 2;
  320.     }
  321.     public static function contains(p:Vector3D):Boolean
  322.     {
  323.         return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  324.     }
  325. }
  326. // Blur effect.
  327. const BLUR_MAX_COUNT:int = 512;
  328. const BLUR_HISTORY_COUNT:int = 6;
  329. var blurs:Vector.<Vector.<Blur>> = new Vector.<Vector.<Blur>>(BLUR_HISTORY_COUNT, true);
  330. var blurCounts:Vector.<int> = new Vector.<int>(BLUR_HISTORY_COUNT, true);
  331. var blurIndex:int;
  332. class Blur
  333. {
  334.     public var pos:Vector3D = new Vector3D;
  335.     public var width:Number, height:Number;
  336.     public var r:int, g:int, b:int;
  337.     public function update():void
  338.     {
  339.         rect.x = pos.x - width / 2;
  340.         rect.y = pos.y - height / 2;
  341.         rect.width = width; rect.height = height;
  342.         buffer.fillRect(rect, r * 0x10000 + g * 0x100 + b);
  343.         width *= 1.2; height *= 1.2;
  344.         var a:int = (r + g + b) / 3;
  345.         r += (a - r) * 0.25;
  346.         g += (a - g) * 0.25;
  347.         b += (a - b) * 0.25;
  348.         r *= 0.65; g *= 0.65; b *= 0.65;
  349.     }
  350. }
  351. function drawBox(x:Number, y:Number, size:int, color:int,
  352.                  bsize:int, br:int, bg:int, bb:int):void
  353. {
  354.     rect.x = x - size / 2 + SCREEN_WIDTH / 2;
  355.     rect.y = y - size / 2 + SCREEN_HEIGHT / 2;
  356.     rect.width = rect.height = size;
  357.     buffer.fillRect(rect, color);
  358.     addBlur(x, y, bsize, bsize, br, bg, bb);
  359. }
  360. function addBlur(x:Number, y:Number, w:Number, h:Number,
  361.                  r:int, g:int, b:int):void
  362. {
  363.     if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  364.     var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  365.     bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  366.     bl.width = w; bl.height = h;
  367.     bl.r = r; bl.g = g; bl.b = b;
  368.     blurCounts[blurIndex]++;
  369. }
  370. function updateBlurs():void
  371. {
  372.     var bi:int = blurIndex + 1;
  373.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  374.     {
  375.         if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  376.         for (var j:int = 0; j < blurCounts[bi]; j++) blurs[bi][j].update();
  377.         bi++;
  378.     }
  379.     blurIndex++;
  380.     if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  381.     blurCounts[blurIndex] = 0;
  382. }
  383. function initializeBlurs():void
  384. {
  385.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  386.     {
  387.         var bs:Vector.<Blur> = new Vector.<Blur>(BLUR_MAX_COUNT, true);
  388.         for (var j:int = 0; j < BLUR_MAX_COUNT; j++)
  389.         {
  390.             bs[j] = new Blur;
  391.         }
  392.         blurs[i] = bs;
  393.         blurCounts[i] = 0;
  394.     }
  395.     blurIndex = 0;
  396. }
  397. // Utility functions.
  398. function rotation(v:Vector3D, a:Number):void
  399. {
  400.     var sv:Number = Math.sin(a);
  401.     var cv:Number = Math.cos(a);
  402.     var rx:Number = cv * v.x - sv * v.y;
  403.     v.y = sv * v.x + cv * v.y;
  404.     v.x = rx;
  405. }
  406. function normalizeAngle(v:Number):Number
  407. {
  408.     if (v > Math.PI)       return v - Math.PI * 2;
  409.     else if (v < -Math.PI) return v + Math.PI * 2;
  410.     else                   return v;
  411. }
  412. function createTextField(x:int, y:int, width:int, size:int, color:int,
  413.                          align:String = TextFormatAlign.LEFT):TextField
  414. {
  415.     var fm:TextFormat = new TextFormat;
  416.     fm.font = "_typewriter"; fm.bold = true;
  417.     fm.size = size; fm.color = color;
  418.     fm.align = align;
  419.     var fi:TextField = new TextField;
  420.     fi.defaultTextFormat = fm;
  421.     fi.x = x; fi.y = y; fi.width = width;
  422.     fi.selectable = false;
  423.     return fi;
  424. }
noswf
  1. // forked from ABA's BallBlast
  2. // BallBlast.as
  3. //  - Blast while balls.
  4. //  - When the red ball is blasted or the ball reaches the celling,
  5. //    the game is over.
  6. //  <Control>
  7. //   Mouse: Move the red ring.
  8. //   Click: Blast balls in the red ring.
  9. package
  10. {
  11.     import flash.display.Sprite;
  12.     import flash.events.Event;
  13.     [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  14.     public class BallBlast extends Sprite
  15.     {
  16.         public function BallBlast()
  17.         {
  18.             main = this;
  19.             initialize();
  20.             addEventListener(Event.ENTER_FRAME, update);
  21.         }
  22.     }
  23. }
  24. import flash.display.Sprite;
  25. import flash.display.Bitmap;
  26. import flash.display.BitmapData;
  27. import flash.geom.Rectangle;
  28. import flash.geom.Vector3D;
  29. import flash.text.TextField;
  30. import flash.text.TextFormat;
  31. import flash.text.TextFormatAlign;
  32. import flash.events.Event;
  33. import flash.events.MouseEvent;
  34. const SCREEN_WIDTH:int = 465;
  35. const SCREEN_HEIGHT:int = 465;
  36. var main:Sprite;
  37. var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  38. var isMouseClicked:Boolean;
  39. var mousePos:Vector3D = new Vector3D;
  40. var rect:Rectangle = new Rectangle;
  41. var offset:Vector3D = new Vector3D;
  42. var ticks:int;
  43. var scoreField:TextField = new TextField;
  44. var score:int;
  45. const GAME_OVER_DURATION:int = 150;
  46. const NO_START_DURATION:int = 30;
  47. var gameOverTicks:int;
  48. var lastBall:Ball;
  49. var messageField:TextField = new TextField;
  50. function initialize():void
  51. {
  52.     main.addChild(new Bitmap(buffer));
  53.     main.stage.addEventListener(MouseEvent.CLICK, function(e:Event):void { isMouseClicked = true; } );
  54.     Field.initialize();
  55.     initializeBlurs();
  56.     scoreField = createTextField(SCREEN_WIDTH - 100010024, 0xff6666, TextFormatAlign.RIGHT);
  57.     main.addChild(scoreField);
  58.     messageField = createTextField(SCREEN_WIDTH - 256025636, 0xff6666);
  59.     main.addChild(messageField);
  60.     startTitle();
  61. }
  62. function update(event:Event):void
  63. {
  64.     mousePos.x = main.stage.mouseX - SCREEN_WIDTH / 2;
  65.     mousePos.y = main.stage.mouseY - SCREEN_HEIGHT / 2;
  66.     if (isMouseClicked)
  67.     {
  68.         isMouseClicked = false;
  69.         if (gameOverTicks < 0) blastBalls(mousePos);
  70.         else if (gameOverTicks > NO_START_DURATION) startGame();
  71.     }
  72.     buffer.lock();
  73.     buffer.fillRect(buffer.rect, 0);
  74.     updateBlurs();
  75.     updateSparks();
  76.     var b:Ball;
  77.     for each (b in balls) b.update();
  78.     for each (b in balls) if (!b.isRed) b.draw();
  79.     for each (b in balls) if (b.isRed)  b.draw();
  80.     if (gameOverTicks < 0) drawBlastCircle();
  81.     buffer.unlock();
  82.     if (gameOverTicks < 0 || gameOverTicks > GAME_OVER_DURATION)
  83.     {
  84.         if (ticks % 5 == 0)    balls.push(new Ball(false));
  85.         if (ticks % 256 == 50) balls.push(new Ball(true));
  86.     }
  87.     ticks++;
  88.     if (gameOverTicks >= 0)
  89.     {
  90.         if (gameOverTicks == GAME_OVER_DURATION) startTitle();
  91.         gameOverTicks++;
  92.         if (lastBall != null) lastBall.draw();
  93.     }
  94. }
  95. function drawBlastCircle():void
  96. {
  97.     offset.x = 0; offset.y = BALL_BLAST_RADIUS;
  98.     rotation(offset, ticks * 0.05);
  99.     for (var i:int = 0; i < 16; i++)
  100.     {
  101.         drawBox(mousePos.x + offset.x, mousePos.y + offset.y, 7, 0xee0000,
  102.                 13200100100);
  103.         rotation(offset, Math.PI * 2 / 16);
  104.     }
  105. }
  106. function startTitle():void
  107. {
  108.     ticks = 0;
  109.     lastBall = null;
  110.     gameOverTicks = GAME_OVER_DURATION;
  111.     messageField.y = SCREEN_HEIGHT / 3;
  112.     messageField.text = "BallBlast";
  113. }
  114. function startGame():void
  115. {
  116.     blastAllBalls();
  117.     lastBall = null;
  118.     score = 0;
  119.     scoreField.text = String(score);
  120.     ticks = 0;
  121.     gameOverTicks = -1;
  122.     messageField.text = "";
  123. }
  124. function startGameOver():void
  125. {
  126.     blastAllBalls();
  127.     if (gameOverTicks >= 0return;
  128.     gameOverTicks = 0;
  129.     messageField.y = SCREEN_HEIGHT / 2;
  130.     messageField.text = "GAME OVER";
  131. }
  132. // Balls.
  133. const BALL_BLAST_RADIUS:Number = 64.0;
  134. var balls:Vector.<Ball> = new Vector.<Ball>;
  135. class Ball
  136. {
  137.     private const GRAVITY_FORCE:Number = 0.5;
  138.     private const MAX_VELOCITY_CHANGE:Number = 0.5;
  139.     public var pos:Vector3D = new Vector3D;
  140.     public var vel:Vector3D = new Vector3D;
  141.     public var radius:Number;
  142.     public var angle:Number, angleVel:Number;
  143.     public var isInAppearance:Boolean;
  144.     public var isRed:Boolean;
  145.     public function Ball(isRed:Boolean):void
  146.     {
  147.         if (!isRed)
  148.         {
  149.             radius = 20.0 + Math.random() * 20.0;
  150.             pos.x = (Math.random() * 2 - 1) * (Field.size.x - radius * 1.1);
  151.             pos.y = Field.size.y + radius * 1.1;
  152.             isInAppearance = true;
  153.         }
  154.         else
  155.         {
  156.             radius = 20.0;
  157.             pos.x = 0; pos.y = -Field.size.y * 0.8;
  158.             isInAppearance = false;
  159.         }
  160.         vel.x = vel.y = 0;
  161.         angle = Math.random() * Math.PI * 2;
  162.         angleVel = (Math.random() * 2 - 1) * 0.1;
  163.         this.isRed = isRed;
  164.     }
  165.     public function update():void
  166.     {
  167.         if (isInAppearance)
  168.         {
  169.             vel.y -= GRAVITY_FORCE * 2;
  170.             if (pos.y < Field.size.y - radius) isInAppearance = false;
  171.         }
  172.         else
  173.         {
  174.             if (pos.y > Field.size.y - radius) hit(pos.y - (Field.size.y - radius), 0);
  175.             vel.y += GRAVITY_FORCE;
  176.         }
  177.         vel.scaleBy(0.95);
  178.         pos.incrementBy(vel);
  179.         if (pos.y < -Field.size.y + radius)
  180.         {
  181.             if (gameOverTicks < 0) lastBall = this;
  182.             startGameOver();
  183.             return;
  184.         }
  185.         if (pos.x > Field.size.x - radius) hit(pos.x - (Field.size.x - radius), Math.PI / 2);
  186.         if (pos.x < -Field.size.x + radius) hit((-Field.size.y + radius) - pos.x, Math.PI / 2 * 3);
  187.         for each (var b:Ball in balls)
  188.         {
  189.             if (b == thiscontinue;
  190.             var d:Number = radius + b.radius - Vector3D.distance(pos, b.pos);
  191.             if (d > 0) hit(d, Math.atan2(b.pos.x - pos.x, b.pos.y - pos.y));
  192.         }
  193.         angle += angleVel; angleVel *= 0.95;
  194.     }
  195.     public function draw():void
  196.     {
  197.         offset.x = 0; offset.y = radius / 2;
  198.         rotation(offset, angle);
  199.         var color:int , r:int ,g:int, b:int;
  200.         if (!isRed)
  201.         {
  202.             color = 0xeeeeee; r = 200; g = 200; b = 200;
  203.         }
  204.         else
  205.         {
  206.             color = 0xff0000; r = 250; g = 200; b = 200;
  207.         }
  208.         for (var i:int = 0; i < 3; i++)
  209.         {
  210.             drawBox(pos.x + offset.x, pos.y + offset.y, radius, color, radius, r, g, b);
  211.             rotation(offset, Math.PI * 2 / 3);
  212.         }
  213.     }
  214.     private function hit(d:Number, a:Number):void
  215.     {
  216.         if (isInAppearance) return;
  217.         var sv:Number = Math.sin(a) * d, cv:Number = Math.cos(a) * d;
  218.         pos.x -= sv / 2; pos.y -= cv / 2;
  219.         angleVel += (-sv * 0.1 - angleVel) * 0.1;
  220.         sv *= 0.1 * vel.x; cv *= 0.1 * vel.y;
  221.         if (sv > MAX_VELOCITY_CHANGE) sv = MAX_VELOCITY_CHANGE;
  222.         if (sv < -MAX_VELOCITY_CHANGE) sv = -MAX_VELOCITY_CHANGE;
  223.         if (cv > MAX_VELOCITY_CHANGE) cv = MAX_VELOCITY_CHANGE;
  224.         if (cv < -MAX_VELOCITY_CHANGE) cv = -MAX_VELOCITY_CHANGE;
  225.         vel.x -= sv; vel.y -= cv;
  226.     }
  227. }
  228. function blastBalls(p:Vector3D):void
  229. {
  230.     var bc:int = 0;
  231.     var b:Ball;
  232.     for each (b in balls)
  233.     {
  234.         if (Vector3D.distance(b.pos, p) < BALL_BLAST_RADIUS + b.radius)
  235.         {
  236.             if (b.isRed)
  237.             {
  238.                 lastBall = b;
  239.                 startGameOver();
  240.                 return;
  241.             }
  242.             bc++;
  243.         }
  244.     }
  245.     score += bc;
  246.     scoreField.text = String(score);
  247.     for (var i:int = 0; i < balls.length; i++)
  248.     {
  249.         b = balls[i];
  250.         if (Vector3D.distance(b.pos, p) < BALL_BLAST_RADIUS + b.radius)
  251.         {
  252.             addSparks(10, b.pos, 20.020.0250250250);
  253.             balls.splice(i, 1); i--;
  254.         }
  255.     }
  256. }
  257. function blastAllBalls():void
  258. {
  259.     for each (var b:Ball in balls) addSparks(5, b.pos, 20.020.025000);
  260.     balls = new Vector.<Ball>;
  261. }
  262. // Sparks.
  263. var sparks:Vector.<Spark> = new Vector.<Spark>;
  264. class Spark
  265. {
  266.     public var pos:Vector3D = new Vector3D;
  267.     public var vel:Vector3D = new Vector3D;
  268.     public var size:Number;
  269.     public var r:int, g:int, b:int;
  270.     public var ticks:int;
  271.     public function update():Boolean
  272.     {
  273.         pos.incrementBy(vel);
  274.         vel.y += 0.5;
  275.         vel.scaleBy(0.99);
  276.         size *= 0.95;
  277.         r *= 0.98; g *= 0.98; b *= 0.98;
  278.         if (pos.x < -Field.size.x && vel.x < 0 ||
  279.             pos.x >  Field.size.x && vel.x > 0) vel.x *= -1;
  280.         if (pos.y < -Field.size.y && vel.y < 0 ||
  281.             pos.y >  Field.size.y && vel.y > 0) vel.y *= -1;
  282.         var cr:Number = Math.random();
  283.         drawBox(pos.x, pos.y, size, r * 0x10000 + g * 0x100 + b, size, r * cr, g * cr, b * cr);
  284.         ticks--;
  285.         return (ticks >= 0);
  286.     }
  287. }
  288. function addSparks(count:int, p:Vector3D, speed:Number, size:Number, r:int, g:int ,b:int):void
  289. {
  290.     for (var i:int = 0; i < count; i++)
  291.     {
  292.         var s:Spark = new Spark;
  293.         s.pos.x = p.x; s.pos.y = p.y;
  294.         var a:Number = Math.random() * Math.PI * 2;
  295.         var sp:Number = speed * (0.5 + Math.random());
  296.         s.vel.x = Math.sin(a) * sp; s.vel.y = Math.cos(a) * sp;
  297.         s.size = size;
  298.         s.r = r; s.g = g; s.b = b;
  299.         s.ticks = 15 + 15 * Math.random();
  300.         sparks.push(s);
  301.     }
  302. }
  303. function updateSparks():void
  304. {
  305.     for (var i:int = 0; i < sparks.length; i++)
  306.     {
  307.         if (!sparks[i].update())
  308.         {
  309.             sparks.splice(i, 1); i--;
  310.         }
  311.     }
  312. }
  313. // Game field.
  314. class Field
  315. {
  316.     public static var size:Vector3D = new Vector3D;
  317.     public static function initialize():void
  318.     {
  319.         size.x = SCREEN_WIDTH * 0.9 / 2; size.y = SCREEN_HEIGHT * 0.9 / 2;
  320.     }
  321.     public static function contains(p:Vector3D):Boolean
  322.     {
  323.         return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  324.     }
  325. }
  326. // Blur effect.
  327. const BLUR_MAX_COUNT:int = 12;
  328. const BLUR_HISTORY_COUNT:int = 3;
  329. var blurs:Vector.<Vector.<Blur>> = new Vector.<Vector.<Blur>>(BLUR_HISTORY_COUNT, true);
  330. var blurCounts:Vector.<int> = new Vector.<int>(BLUR_HISTORY_COUNT, true);
  331. var blurIndex:int;
  332. class Blur
  333. {
  334.     public var pos:Vector3D = new Vector3D;
  335.     public var width:Number, height:Number;
  336.     public var r:int, g:int, b:int;
  337.     public function update():void
  338.     {
  339.         rect.x = pos.x - width / 2;
  340.         rect.y = pos.y - height / 2;
  341.         rect.width = width; rect.height = height;
  342.         buffer.fillRect(rect, r * 0x10000 + g * 0x100 + b);
  343.         width *= 1.2; height *= 1.2;
  344.         var a:int = (r + g + b) / 3;
  345.         r += (a - r) * 0.25;
  346.         g += (a - g) * 0.25;
  347.         b += (a - b) * 0.25;
  348.         r *= 0.65; g *= 0.65; b *= 0.65;
  349.     }
  350. }
  351. function drawBox(x:Number, y:Number, size:int, color:int,
  352.                  bsize:int, br:int, bg:int, bb:int):void
  353. {
  354.     rect.x = x - size / 2 + SCREEN_WIDTH / 2;
  355.     rect.y = y - size / 2 + SCREEN_HEIGHT / 2;
  356.     rect.width = rect.height = size;
  357.     buffer.fillRect(rect, color);
  358.     addBlur(x, y, bsize, bsize, br, bg, bb);
  359. }
  360. function addBlur(x:Number, y:Number, w:Number, h:Number,
  361.                  r:int, g:int, b:int):void
  362. {
  363.     if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  364.     var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  365.     bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  366.     bl.width = w; bl.height = h;
  367.     bl.r = r; bl.g = g; bl.b = b;
  368.     blurCounts[blurIndex]++;
  369. }
  370. function updateBlurs():void
  371. {
  372.     var bi:int = blurIndex + 1;
  373.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  374.     {
  375.         if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  376.         for (var j:int = 0; j < blurCounts[bi]; j++) blurs[bi][j].update();
  377.         bi++;
  378.     }
  379.     blurIndex++;
  380.     if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  381.     blurCounts[blurIndex] = 0;
  382. }
  383. function initializeBlurs():void
  384. {
  385.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  386.     {
  387.         var bs:Vector.<Blur> = new Vector.<Blur>(BLUR_MAX_COUNT, true);
  388.         for (var j:int = 0; j < BLUR_MAX_COUNT; j++)
  389.         {
  390.             bs[j] = new Blur;
  391.         }
  392.         blurs[i] = bs;
  393.         blurCounts[i] = 0;
  394.     }
  395.     blurIndex = 0;
  396. }
  397. // Utility functions.
  398. function rotation(v:Vector3D, a:Number):void
  399. {
  400.     var sv:Number = Math.sin(a);
  401.     var cv:Number = Math.cos(a);
  402.     var rx:Number = cv * v.x - sv * v.y;
  403.     v.y = sv * v.x + cv * v.y;
  404.     v.x = rx;
  405. }
  406. function normalizeAngle(v:Number):Number
  407. {
  408.     if (v > Math.PI)       return v - Math.PI * 2;
  409.     else if (v < -Math.PI) return v + Math.PI * 2;
  410.     else                   return v;
  411. }
  412. function createTextField(x:int, y:int, width:int, size:int, color:int,
  413.                          align:String = TextFormatAlign.LEFT):TextField
  414. {
  415.     var fm:TextFormat = new TextFormat;
  416.     fm.font = "_typewriter"; fm.bold = true;
  417.     fm.size = size; fm.color = color;
  418.     fm.align = align;
  419.     var fi:TextField = new TextField;
  420.     fi.defaultTextFormat = fm;
  421.     fi.x = x; fi.y = y; fi.width = width;
  422.     fi.selectable = false;
  423.     return fi;
  424. }
noswf
  1. // forked from ABA's BallBlast
  2. // BallBlast.as
  3. //  - Blast while balls.
  4. //  - When the red ball is blasted or the ball reaches the celling,
  5. //    the game is over.
  6. //  <Control>
  7. //   Mouse: Move the red ring.
  8. //   Click: Blast balls in the red ring.
  9. package
  10. {
  11.     import flash.display.Sprite;
  12.     import flash.events.Event;
  13.     [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  14.     public class BallBlast extends Sprite
  15.     {
  16.         public function BallBlast()
  17.         {
  18.             main = this;
  19.             initialize();
  20.             addEventListener(Event.ENTER_FRAME, update);
  21.         }
  22.     }
  23. }
  24. import flash.display.Sprite;
  25. import flash.display.Bitmap;
  26. import flash.display.BitmapData;
  27. import flash.geom.Rectangle;
  28. import flash.geom.Vector3D;
  29. import flash.text.TextField;
  30. import flash.text.TextFormat;
  31. import flash.text.TextFormatAlign;
  32. import flash.events.Event;
  33. import flash.events.MouseEvent;
  34. const SCREEN_WIDTH:int = 465;
  35. const SCREEN_HEIGHT:int = 465;
  36. var main:Sprite;
  37. var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  38. var isMouseClicked:Boolean;
  39. var mousePos:Vector3D = new Vector3D;
  40. var rect:Rectangle = new Rectangle;
  41. var offset:Vector3D = new Vector3D;
  42. var ticks:int;
  43. var scoreField:TextField = new TextField;
  44. var score:int;
  45. const GAME_OVER_DURATION:int = 150;
  46. const NO_START_DURATION:int = 30;
  47. var gameOverTicks:int;
  48. var lastBall:Ball;
  49. var messageField:TextField = new TextField;
  50. function initialize():void
  51. {
  52.     main.addChild(new Bitmap(buffer));
  53.     main.stage.addEventListener(MouseEvent.CLICK, function(e:Event):void { isMouseClicked = true; } );
  54.     Field.initialize();
  55.     initializeBlurs();
  56.     scoreField = createTextField(SCREEN_WIDTH - 100010024, 0xff6666, TextFormatAlign.RIGHT);
  57.     main.addChild(scoreField);
  58.     messageField = createTextField(SCREEN_WIDTH - 256025636, 0xff6666);
  59.     main.addChild(messageField);
  60.     startTitle();
  61. }
  62. function update(event:Event):void
  63. {
  64.     mousePos.x = main.stage.mouseX - SCREEN_WIDTH / 2;
  65.     mousePos.y = main.stage.mouseY - SCREEN_HEIGHT / 2;
  66.     if (isMouseClicked)
  67.     {
  68.         isMouseClicked = false;
  69.         if (gameOverTicks < 0) blastBalls(mousePos);
  70.         else if (gameOverTicks > NO_START_DURATION) startGame();
  71.     }
  72.     buffer.lock();
  73.     buffer.fillRect(buffer.rect, 0);
  74.     updateBlurs();
  75.     updateSparks();
  76.     var b:Ball;
  77.     for each (b in balls) b.update();
  78.     for each (b in balls) if (!b.isRed) b.draw();
  79.     for each (b in balls) if (b.isRed)  b.draw();
  80.     if (gameOverTicks < 0) drawBlastCircle();
  81.     buffer.unlock();
  82.     if (gameOverTicks < 0 || gameOverTicks > GAME_OVER_DURATION)
  83.     {
  84.         if (ticks % 5 == 0)    balls.push(new Ball(false));
  85.         if (ticks % 256 == 50) balls.push(new Ball(true));
  86.     }
  87.     ticks++;
  88.     if (gameOverTicks >= 0)
  89.     {
  90.         if (gameOverTicks == GAME_OVER_DURATION) startTitle();
  91.         gameOverTicks++;
  92.         if (lastBall != null) lastBall.draw();
  93.     }
  94. }
  95. function drawBlastCircle():void
  96. {
  97.     offset.x = 0; offset.y = BALL_BLAST_RADIUS;
  98.     rotation(offset, ticks * 0.05);
  99.     for (var i:int = 0; i < 16; i++)
  100.     {
  101.         drawBox(mousePos.x + offset.x, mousePos.y + offset.y, 7, 0xee0000,
  102.                 13200100100);
  103.         rotation(offset, Math.PI * 2 / 16);
  104.     }
  105. }
  106. function startTitle():void
  107. {
  108.     ticks = 0;
  109.     lastBall = null;
  110.     gameOverTicks = GAME_OVER_DURATION;
  111.     messageField.y = SCREEN_HEIGHT / 3;
  112.     messageField.text = "BallBlast";
  113. }
  114. function startGame():void
  115. {
  116.     blastAllBalls();
  117.     lastBall = null;
  118.     score = 0;
  119.     scoreField.text = String(score);
  120.     ticks = 0;
  121.     gameOverTicks = -1;
  122.     messageField.text = "";
  123. }
  124. function startGameOver():void
  125. {
  126.     blastAllBalls();
  127.     if (gameOverTicks >= 0return;
  128.     gameOverTicks = 0;
  129.     messageField.y = SCREEN_HEIGHT / 2;
  130.     messageField.text = "GAME OVER";
  131. }
  132. // Balls.
  133. const BALL_BLAST_RADIUS:Number = 64.0;
  134. var balls:Vector.<Ball> = new Vector.<Ball>;
  135. class Ball
  136. {
  137.     private const GRAVITY_FORCE:Number = 0.5;
  138.     private const MAX_VELOCITY_CHANGE:Number = 0.5;
  139.     public var pos:Vector3D = new Vector3D;
  140.     public var vel:Vector3D = new Vector3D;
  141.     public var radius:Number;
  142.     public var angle:Number, angleVel:Number;
  143.     public var isInAppearance:Boolean;
  144.     public var isRed:Boolean;
  145.     public function Ball(isRed:Boolean):void
  146.     {
  147.         if (!isRed)
  148.         {
  149.             radius = 20.0 + Math.random() * 20.0;
  150.             pos.x = (Math.random() * 2 - 1) * (Field.size.x - radius * 1.1);
  151.             pos.y = Field.size.y + radius * 1.1;
  152.             isInAppearance = true;
  153.         }
  154.         else
  155.         {
  156.             radius = 20.0;
  157.             pos.x = 0; pos.y = -Field.size.y * 0.8;
  158.             isInAppearance = false;
  159.         }
  160.         vel.x = vel.y = 0;
  161.         angle = Math.random() * Math.PI * 2;
  162.         angleVel = (Math.random() * 2 - 1) * 0.1;
  163.         this.isRed = isRed;
  164.     }
  165.     public function update():void
  166.     {
  167.         if (isInAppearance)
  168.         {
  169.             vel.y -= GRAVITY_FORCE * 2;
  170.             if (pos.y < Field.size.y - radius) isInAppearance = false;
  171.         }
  172.         else
  173.         {
  174.             if (pos.y > Field.size.y - radius) hit(pos.y - (Field.size.y - radius), 0);
  175.             vel.y += GRAVITY_FORCE;
  176.         }
  177.         vel.scaleBy(0.95);
  178.         pos.incrementBy(vel);
  179.         if (pos.y < -Field.size.y + radius)
  180.         {
  181.             if (gameOverTicks < 0) lastBall = this;
  182.             startGameOver();
  183.             return;
  184.         }
  185.         if (pos.x > Field.size.x - radius) hit(pos.x - (Field.size.x - radius), Math.PI / 2);
  186.         if (pos.x < -Field.size.x + radius) hit((-Field.size.y + radius) - pos.x, Math.PI / 2 * 3);
  187.         for each (var b:Ball in balls)
  188.         {
  189.             if (b == thiscontinue;
  190.             var d:Number = radius + b.radius - Vector3D.distance(pos, b.pos);
  191.             if (d > 0) hit(d, Math.atan2(b.pos.x - pos.x, b.pos.y - pos.y));
  192.         }
  193.         angle += angleVel; angleVel *= 0.95;
  194.     }
  195.     public function draw():void
  196.     {
  197.         offset.x = 0; offset.y = radius / 2;
  198.         rotation(offset, angle);
  199.         var color:int , r:int ,g:int, b:int;
  200.         if (!isRed)
  201.         {
  202.             color = 0xeeeeee; r = 200; g = 200; b = 200;
  203.         }
  204.         else
  205.         {
  206.             color = 0xff0000; r = 250; g = 200; b = 200;
  207.         }
  208.         for (var i:int = 0; i < 3; i++)
  209.         {
  210.             drawBox(pos.x + offset.x, pos.y + offset.y, radius, color, radius, r, g, b);
  211.             rotation(offset, Math.PI * 2 / 3);
  212.         }
  213.     }
  214.     private function hit(d:Number, a:Number):void
  215.     {
  216.         if (isInAppearance) return;
  217.         var sv:Number = Math.sin(a) * d, cv:Number = Math.cos(a) * d;
  218.         pos.x -= sv / 2; pos.y -= cv / 2;
  219.         angleVel += (-sv * 0.1 - angleVel) * 0.1;
  220.         sv *= 0.1 * vel.x; cv *= 0.1 * vel.y;
  221.         if (sv > MAX_VELOCITY_CHANGE) sv = MAX_VELOCITY_CHANGE;
  222.         if (sv < -MAX_VELOCITY_CHANGE) sv = -MAX_VELOCITY_CHANGE;
  223.         if (cv > MAX_VELOCITY_CHANGE) cv = MAX_VELOCITY_CHANGE;
  224.         if (cv < -MAX_VELOCITY_CHANGE) cv = -MAX_VELOCITY_CHANGE;
  225.         vel.x -= sv; vel.y -= cv;
  226.     }
  227. }
  228. function blastBalls(p:Vector3D):void
  229. {
  230.     var bc:int = 0;
  231.     var b:Ball;
  232.     for each (b in balls)
  233.     {
  234.         if (Vector3D.distance(b.pos, p) < BALL_BLAST_RADIUS + b.radius)
  235.         {
  236.             if (b.isRed)
  237.             {
  238.                 lastBall = b;
  239.                 startGameOver();
  240.                 return;
  241.             }
  242.             bc++;
  243.         }
  244.     }
  245.     score += bc;
  246.     scoreField.text = String(score);
  247.     for (var i:int = 0; i < balls.length; i++)
  248.     {
  249.         b = balls[i];
  250.         if (Vector3D.distance(b.pos, p) < BALL_BLAST_RADIUS + b.radius)
  251.         {
  252.             addSparks(10, b.pos, 20.020.0250250250);
  253.             balls.splice(i, 1); i--;
  254.         }
  255.     }
  256. }
  257. function blastAllBalls():void
  258. {
  259.     for each (var b:Ball in balls) addSparks(5, b.pos, 20.020.025000);
  260.     balls = new Vector.<Ball>;
  261. }
  262. // Sparks.
  263. var sparks:Vector.<Spark> = new Vector.<Spark>;
  264. class Spark
  265. {
  266.     public var pos:Vector3D = new Vector3D;
  267.     public var vel:Vector3D = new Vector3D;
  268.     public var size:Number;
  269.     public var r:int, g:int, b:int;
  270.     public var ticks:int;
  271.     public function update():Boolean
  272.     {
  273.         pos.incrementBy(vel);
  274.         vel.y += 0.5;
  275.         vel.scaleBy(0.99);
  276.         size *= 0.95;
  277.         r *= 0.98; g *= 0.98; b *= 0.98;
  278.         if (pos.x < -Field.size.x && vel.x < 0 ||
  279.             pos.x >  Field.size.x && vel.x > 0) vel.x *= -1;
  280.         if (pos.y < -Field.size.y && vel.y < 0 ||
  281.             pos.y >  Field.size.y && vel.y > 0) vel.y *= -1;
  282.         var cr:Number = Math.random();
  283.         drawBox(pos.x, pos.y, size, r * 0x10000 + g * 0x100 + b, size, r * cr, g * cr, b * cr);
  284.         ticks--;
  285.         return (ticks >= 0);
  286.     }
  287. }
  288. function addSparks(count:int, p:Vector3D, speed:Number, size:Number, r:int, g:int ,b:int):void
  289. {
  290.     for (var i:int = 0; i < count; i++)
  291.     {
  292.         var s:Spark = new Spark;
  293.         s.pos.x = p.x; s.pos.y = p.y;
  294.         var a:Number = Math.random() * Math.PI * 2;
  295.         var sp:Number = speed * (0.5 + Math.random());
  296.         s.vel.x = Math.sin(a) * sp; s.vel.y = Math.cos(a) * sp;
  297.         s.size = size;
  298.         s.r = r; s.g = g; s.b = b;
  299.         s.ticks = 15 + 15 * Math.random();
  300.         sparks.push(s);
  301.     }
  302. }
  303. function updateSparks():void
  304. {
  305.     for (var i:int = 0; i < sparks.length; i++)
  306.     {
  307.         if (!sparks[i].update())
  308.         {
  309.             sparks.splice(i, 1); i--;
  310.         }
  311.     }
  312. }
  313. // Game field.
  314. class Field
  315. {
  316.     public static var size:Vector3D = new Vector3D;
  317.     public static function initialize():void
  318.     {
  319.         size.x = SCREEN_WIDTH * 0.9 / 2; size.y = SCREEN_HEIGHT * 0.9 / 2;
  320.     }
  321.     public static function contains(p:Vector3D):Boolean
  322.     {
  323.         return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  324.     }
  325. }
  326. // Blur effect.
  327. const BLUR_MAX_COUNT:int = 512;
  328. const BLUR_HISTORY_COUNT:int = 6;
  329. var blurs:Vector.<Vector.<Blur>> = new Vector.<Vector.<Blur>>(BLUR_HISTORY_COUNT, true);
  330. var blurCounts:Vector.<int> = new Vector.<int>(BLUR_HISTORY_COUNT, true);
  331. var blurIndex:int;
  332. class Blur
  333. {
  334.     public var pos:Vector3D = new Vector3D;
  335.     public var width:Number, height:Number;
  336.     public var r:int, g:int, b:int;
  337.     public function update():void
  338.     {
  339.         rect.x = pos.x - width / 2;
  340.         rect.y = pos.y - height / 2;
  341.         rect.width = width; rect.height = height;
  342.         buffer.fillRect(rect, r * 0x10000 + g * 0x100 + b);
  343.         width *= 1.2; height *= 1.2;
  344.         var a:int = (r + g + b) / 3;
  345.         r += (a - r) * 0.25;
  346.         g += (a - g) * 0.25;
  347.         b += (a - b) * 0.25;
  348.         r *= 0.65; g *= 0.65; b *= 0.65;
  349.     }
  350. }
  351. function drawBox(x:Number, y:Number, size:int, color:int,
  352.                  bsize:int, br:int, bg:int, bb:int):void
  353. {
  354.     rect.x = x - size / 2 + SCREEN_WIDTH / 2;
  355.     rect.y = y - size / 2 + SCREEN_HEIGHT / 2;
  356.     rect.width = rect.height = size;
  357.     buffer.fillRect(rect, color);
  358.     addBlur(x, y, bsize, bsize, br, bg, bb);
  359. }
  360. function addBlur(x:Number, y:Number, w:Number, h:Number,
  361.                  r:int, g:int, b:int):void
  362. {
  363.     if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  364.     var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  365.     bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  366.     bl.width = w; bl.height = h;
  367.     bl.r = r; bl.g = g; bl.b = b;
  368.     blurCounts[blurIndex]++;
  369. }
  370. function updateBlurs():void
  371. {
  372.     var bi:int = blurIndex + 1;
  373.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  374.     {
  375.         if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  376.         for (var j:int = 0; j < blurCounts[bi]; j++) blurs[bi][j].update();
  377.         bi++;
  378.     }
  379.     blurIndex++;
  380.     if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  381.     blurCounts[blurIndex] = 0;
  382. }
  383. function initializeBlurs():void
  384. {
  385.     for (var i:int = 0; i < BLUR_HISTORY_COUNT; i++)
  386.     {
  387.         var bs:Vector.<Blur> = new Vector.<Blur>(BLUR_MAX_COUNT, true);
  388.         for (var j:int = 0; j < BLUR_MAX_COUNT; j++)
  389.         {
  390.             bs[j] = new Blur;
  391.         }
  392.         blurs[i] = bs;
  393.         blurCounts[i] = 0;
  394.     }
  395.     blurIndex = 0;
  396. }
  397. // Utility functions.
  398. function rotation(v:Vector3D, a:Number):void
  399. {
  400.     var sv:Number = Math.sin(a);
  401.     var cv:Number = Math.cos(a);
  402.     var rx:Number = cv * v.x - sv * v.y;
  403.     v.y = sv * v.x + cv * v.y;
  404.     v.x = rx;
  405. }
  406. function normalizeAngle(v:Number):Number
  407. {
  408.     if (v > Math.PI)       return v - Math.PI * 2;
  409.     else if (v < -Math.PI) return v + Math.PI * 2;
  410.     else                   return v;
  411. }
  412. function createTextField(x:int, y:int, width:int, size:int, color:int,
  413.                          align:String = TextFormatAlign.LEFT):TextField
  414. {
  415.     var fm:TextFormat = new TextFormat;
  416.     fm.font = "_typewriter"; fm.bold = true;
  417.     fm.size = size; fm.color = color;
  418.     fm.align = align;
  419.     var fi:TextField = new TextField;
  420.     fi.defaultTextFormat = fm;
  421.     fi.x = x; fi.y = y; fi.width = width;
  422.     fi.selectable = false;
  423.     return fi;
  424. }
noswf
Get Adobe Flash Player