ブロック崩し

by nan05aur
ttp://sakef.jp/blog/2010/09/breakout/
こちらを参照しました
♥0 | Line 178 | Modified 2011-11-19 09:38:55 | MIT License
play

ActionScript3 source code

/**
 * Copyright nan05aur ( http://wonderfl.net/user/nan05aur )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/oPIm
 */

package
{
   import flash.display.Bitmap;
   import flash.display.BitmapData;
   import flash.display.Graphics;
   import flash.display.Shape;
   import flash.display.Sprite;
   import flash.display.StageAlign;
   import flash.display.StageQuality;
   import flash.display.StageScaleMode;
   import flash.events.Event;
   import flash.events.MouseEvent;
   import flash.geom.Matrix;
   import flash.geom.Point;
   import flash.geom.Rectangle;
   import flash.text.TextField;
   import flash.text.TextFieldAutoSize;
      
   [SWF(width = 465, height = 465, frameRate = 60)]
 
   public class breakout extends Sprite
   {
      // 描写するキャンバスのサイズ
      private static const CANVAS_WIDTH:Number=480;
      private static const CANVAS_HEIGHT:Number=480;
 
      // ボールに関する定数(半径・直径・初期位置・初期移動速度・制限)
      private static const BALL_RADIUS:Number=5;
      private static const BALL_SIZE:Number = 10;
      private static const BALL_SPEED:Number=5;
      private static const BALL_LIMIT_X:Number=CANVAS_WIDTH - BALL_SIZE;
 
      // バーに関する定数(サイズ・yの位置・制限)
      private static const BAR_WIDTH:Number=100;
      private static const BAR_HEIGHT:Number=10;
      private static const BAR_Y:Number=410;
      private static const BAR_LIMIT_X:Number=CANVAS_WIDTH - BAR_WIDTH;
 
      // ブロックのサイズ
      private static const BLOCK_WIDTH:Number = 45;
      private static const BLOCK_HEIGHT:Number = 20;
      private static const BLOCK_NUM_W:int = 8;
      private static const BLOCK_NUM_H:int = 5;
      private static const BLOCK_START_X:int=42;
      private static const BLOCK_START_Y:int=70;
      private static const BLOCK_SPACE:int=5;
 
      // キャンバス
      private var canvas:BitmapData;
      private var canvas_bmp:Bitmap;
 
      // ボールを描写するBitmapData・位置・移動速度
      private var ball:BitmapData;
      private var ball_x:Number;
      private var ball_y:Number;
      private var ball_dx:Number;
      private var ball_dy:Number;
 
      // バーのy座標
      private var bar_x:Number;
 
      // ブロックを保存する配列
      private var container:Array;
 
      // コンストラクタ
      public function breakout()
      {
         // ステージの設定
         stage.scaleMode=StageScaleMode.NO_SCALE;
         stage.align=StageAlign.TOP_LEFT;
         stage.quality=StageQuality.HIGH;
         stage.frameRate=60;
 
         // 全体を描写するキャンバス
         canvas=new BitmapData(CANVAS_WIDTH, CANVAS_HEIGHT, false, 0x000000);
         canvas_bmp=addChild(new Bitmap(canvas)) as Bitmap;
         onResize();
 
         // ブロックの位置を計算
         container = [];
         for(var i:int=0 ; i<BLOCK_NUM_W ; i++)
         {
            for(var j:int=0 ; j<BLOCK_NUM_H ; j++)
            {
               var block:Block = new Block(BLOCK_START_X + i*(BLOCK_SPACE + BLOCK_WIDTH), BLOCK_START_Y + j*(BLOCK_SPACE + BLOCK_HEIGHT));
               container.push(block);
            }
         }
 
         // "Click here."を作成して、canvasに描写
         var tf:TextField = new TextField;
         tf.autoSize = TextFieldAutoSize.LEFT;
         tf.text = "Click."
         tf.textColor = 0xffffff;
         canvas.draw(tf, new Matrix(1,0,0,1,(CANVAS_WIDTH-tf.width)/2, (CANVAS_HEIGHT-tf.height)/2));
 
         // ボールを描いたBitmapDataを作成
         var tmp:Shape=new Shape;
         var g:Graphics=tmp.graphics;
         g.beginFill(0xffffff, 1);
         g.drawCircle(BALL_RADIUS, BALL_RADIUS, BALL_RADIUS);
         g.endFill();
         ball=new BitmapData(BALL_SIZE, BALL_SIZE, false, 0x000000);
         ball.draw(tmp);
 
         // イベント追加
         stage.addEventListener(MouseEvent.CLICK, onClick);
      }
 
      // クリック後に実行
      private function onClick(e:MouseEvent):void
      {
         // クリックイベントの削除
         canvas.fillRect(canvas.rect, 0x000000);
         stage.removeEventListener(MouseEvent.CLICK, onClick);
 
         // ボールの移動に関する変数の初期化
         ball_x= canvas_bmp.mouseX + BAR_WIDTH/2;
         ball_y=BAR_Y-BALL_SIZE;
         ball_dx = Math.cos(45*Math.PI/180)*BALL_SPEED;
         ball_dy = Math.sin(45*Math.PI/180)*BALL_SPEED;
 
         // イベントの追加
         addEventListener(Event.ENTER_FRAME, onFrame);
         stage.addEventListener(Event.RESIZE, onResize);
      }
 
      // 毎フレーム実行される関数
      private function onFrame(e:Event):void
      {
         canvas.fillRect(canvas.rect, 0x000000);
 
         // バーの位置を更新
         bar_x=canvas_bmp.mouseX;
         if (bar_x < 0) bar_x=0;
         if (bar_x > BAR_LIMIT_X) bar_x=BAR_LIMIT_X;
 
         // ボールと壁の当たり判定
         if (ball_x < 0)
         {
            ball_x=0;
            ball_dx*= -1;
         }
         if (ball_x > BALL_LIMIT_X)
         {
            ball_x=BALL_LIMIT_X;
            ball_dx*= -1;
         }
         if(ball_y < 0)
         {
            ball_y = 0;
            ball_dy*= -1;
         }
 
         // ボールとバーの衝突判定
         if(ball_y + BALL_SIZE < BAR_Y){
         }else if(ball_x + BALL_SIZE < bar_x){
         }else if(ball_x > bar_x + BAR_WIDTH){
         }else if(ball_y > BAR_Y + BAR_HEIGHT){
         }else
         {
            ball_y = BAR_Y - BALL_SIZE;
            ball_dy *= -1;
 
            // ボールの反射角度を計算
            var ball_centerX:Number = ball_x + BALL_RADIUS;
            var ball_centerY:Number = ball_y + BALL_RADIUS;
            var bar_centerX:Number = bar_x + BAR_WIDTH/2;
            var bar_centerY:Number = BAR_Y + BAR_HEIGHT/2;
            var rad:Number = Math.atan2(ball_centerY - bar_centerY, ball_centerX - bar_centerX);
            ball_dx = Math.cos(rad)*BALL_SPEED;
            ball_dy = Math.sin(rad)*BALL_SPEED;
         }
 
         // 描写開始
         canvas.lock();
 
         // Blockとの衝突判定&描写
         var len:int = container.length;
         while(len--)
         {
            var block:Block = container[len];
 
            if(ball_y > block.y + BLOCK_HEIGHT){
            }else if(ball_x + BALL_SIZE < block.x){
            }else if(ball_x > block.x + BLOCK_WIDTH){
            }else if(ball_y + BALL_SIZE < block.y){
            }else
            {
               if(ball_y >= block.y + BLOCK_HEIGHT - 5 || ball_y + BALL_SIZE <= block.y + 5) ball_dy *= -1;
               else if(ball_x + BALL_SIZE <= block.x + 3 || ball_x  >= block.x + BLOCK_WIDTH - 3) ball_dx *= -1;
 
               container.splice(len,1);
               continue;
            }
 
            canvas.fillRect(new Rectangle(block.x, block.y, BLOCK_WIDTH, BLOCK_HEIGHT), 0x0000ff);
         }
 
         // バーの描写
         canvas.fillRect(new Rectangle(bar_x, BAR_Y, BAR_WIDTH, BAR_HEIGHT), 0xff0000);
 
         // ボールの描写
         canvas.copyPixels(ball, ball.rect, new Point(ball_x, ball_y));
         canvas.unlock();
 
         // ボールが範囲の外 or ブロックを崩し終わったら終了
         len = container.length;
         if(ball_y > CANVAS_HEIGHT || len == 0)
         {
            canvas.fillRect(canvas.rect, 0x000000);
            var tf:TextField = new TextField;
            tf.autoSize = TextFieldAutoSize.LEFT;
            tf.text = "Game Over"
            tf.textColor = 0xffffff;
            canvas.draw(tf, new Matrix(1,0,0,1,(CANVAS_WIDTH-tf.width)/2, (CANVAS_HEIGHT-tf.height)/2));
            removeEventListener(Event.ENTER_FRAME, onFrame);
         }
 
         // ボールの位置を更新
         ball_x+=ball_dx;
         ball_y+=ball_dy;
      }
 
      // リサイズイベント
      private function onResize(e:Event=null):void
      {
         canvas_bmp.x = (stage.stageWidth - CANVAS_WIDTH) / 2;
         canvas_bmp.y = (stage.stageHeight - CANVAS_HEIGHT) / 2;
      }
   }
}
 
// ブロックを表すクラス
class Block
{
   public var x:Number;
   public var y:Number;
 
   public function Block(x:Number, y:Number)
   {
      this.x = x;
      this.y = y;
   }
}