[AS3] 水ぼうそう

2009/12/8

こんにちは。きんくまです。

子供が水ぼうそうにかかり、保育園をお休みしております。
小さい子はかかるのも早いのですが、直るのも早いですね。大人だとこうはいきません。

spred_fig

というわけで、病気の広がりをイメージしてみました。
画面をクリックすると広がります。

 
以下ソース

package
{
  import com.kuma_de.ColorUtil;
  import flash.display.Bitmap;
  import flash.display.BitmapData;
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.geom.Point;

  /**
   * ...
   * @author KinkumaDesign
   */
  public class Main extends Sprite
  {
    private var _tmpPt:Point;
    private var _alphaBmd:BitmapData;
    private var _lastBmd:BitmapData;
    private var _canvasBmd:BitmapData;
    private var _canvas:Bitmap;
    private var _balls:Array;

    private var _h:int;
    private var _s:int;
    private var _v:int;

    public function Main():void
    {
      if (stage) init();
      else addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(e:Event = null):void
    {
      removeEventListener(Event.ADDED_TO_STAGE, init);

      var vc:Vector.<int> = ColorUtil.RGBtoHSV(255, 0, 0);
      _h = vc[0];
      _s = vc[1];
      _v = vc[2];

      _balls = [];
      initCanvas();
      addEventListener(Event.ENTER_FRAME, update);
      stage.addEventListener(MouseEvent.MOUSE_DOWN, stageDownHD);
    }

    private function stageDownHD(e:MouseEvent):void
    {
      var ball:Ball;
      var i:int;
      for (i = 0; i < 50; i++) {
        _h += 2;
        if (_h > 3066) {
          _h -= 3066;
        }
        var rgb:Vector.<int> = ColorUtil.HSVtoRGB(_h, _s, _v);
        var color:int = ColorUtil.RGBtoHex(rgb[0], rgb[1], rgb[2]);
        ball = new Ball(stage.mouseX, stage.mouseY, color);
        _balls.push(ball);
      }
    }

    private function getRandomPos(range:Number):Number
    {
      return (Math.random() < 0.5 ? -1 : 1) * Math.random() * range;
    }

    private function initCanvas():void
    {
      _canvasBmd = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xff000000);
      _canvas = new Bitmap(_canvasBmd);
      addChild(_canvas);
      _lastBmd = _canvasBmd.clone();
      _alphaBmd = new BitmapData(_canvasBmd.width, _canvasBmd.height, true, 0xf5000000);
      _tmpPt = new Point();
    }

    private function update(e:Event):void
    {
      draw();
    }

    private function draw():void
    {
      _canvasBmd.lock();
      _canvasBmd.fillRect(_canvasBmd.rect, 0xff000000);
      _canvasBmd.copyPixels(_lastBmd, _canvasBmd.rect, _tmpPt, _alphaBmd, _tmpPt, true);
      var i:int;
      var len:int = _balls.length;
      var ball:Ball;
      var isAlive:Boolean;
      for (i = len -1; i > 0; i--) {
        ball = _balls[i];
        isAlive = ball.update();
        if (isAlive) {
          _canvasBmd.draw(ball);
        }else {
          _balls.splice(i, 1);
        }
      }

      _canvasBmd.unlock();
      _lastBmd = _canvasBmd.clone();
    }
  }

}
package
{
  import flash.display.Graphics;
  import flash.display.Sprite;
  /**
   * ...
   * @author KinkumaDesign
   */
  public class Ball extends Sprite
  {
    private var _circle:Sprite;
    private var _accel:Number = 0.01;
    private var _velocity:Number = 0;
    private var _vX:Number;
    private var _vY:Number;
    private var _gravity:Number = 0.5;

    public function Ball(X:Number, Y:Number, color:int)
    {
      _circle = new Sprite();
      addChild(_circle);
      var g:Graphics = _circle.graphics;
      g.beginFill(color, 0.7);
      g.drawCircle(0, 0, 3);
      g.endFill();
      _circle.x = X;
      _circle.y = Y;
      _vX = (Math.random() < 0.5 ? -1 : 1) * Math.random() * 15;
      _vY = Math.random() * -20;
    }

    public function update():Boolean
    {
      _velocity += _accel;
      _circle.scaleX += _velocity;
      _circle.scaleY += _velocity;
      _circle.x += _vX;
      _vY += _gravity;
      _circle.y += _vY;
      if (_circle.y > 450 + _circle.height) {
        return false;
      }else {
        return true;
      }
    }
  }

}
/*
 * Cの書籍からの移植
 * 詳解 画像処理プログラミング / 昌達 慶仁 著 / ソフトバンククリエイティブ
 * http://www.sbcr.jp/books/products/detail.asp?sku=4797344370
 */
package com.kuma_de
{
  public class ColorUtil
  {
    private static const SCALE:Number = 255;
    private static const hSCALE:Number = 256;
    private static const GETA:Number = 2;
    private static const hGETA:Number = 2;

    /**
     * RGBからHSVを得る
     *
     * @param r Red 0~255
     * @param g Green 0~255
     * @param b Blue 0~255
     * @return Vector.<int> H:0~3066, S:0~511, V:0~511
     */
    public static function RGBtoHSV(r:int, g:int, b:int):Vector.<int>
    {
      var rr:Number, gg:Number, bb:Number;
      var hh:Number, ss:Number, vv:Number;
      var cmax:Number, cmin:Number, cdes:Number;

      rr = Number(r);
      gg = Number(g);
      bb = Number(b);

      cmax = (rr > gg) ? rr : gg;
      if (bb > cmax) {
        cmax = bb;
      }

      cmin = (rr < gg) ? rr : gg;
      if (bb < cmin) {
        cmin = bb;
      }

      cdes = cmax - cmin;
      vv = cmax;
      if (cdes != 0) {
        ss = cdes * SCALE / cmax;
        if (cmax == rr) {
          hh = (gg - bb) * SCALE / cdes;
        }else if (cmax == gg) {
          hh = (bb - rr) * SCALE / cdes + 2 * hSCALE;
        }else {
          hh = (rr - gg) * SCALE / cdes + 4 * hSCALE;
        }
      }else if (cmax != 0) {
        ss = cdes * SCALE / cmax;
        hh = 0;
      }else {
        ss = 0;
        hh = 0;
      }
      if (hh < 0) {
        hh += 6 * hSCALE;
      }

      return Vector.<int>([int(hh * hGETA), int(ss * hGETA), int(vv * hGETA)]);
    }

    /**
     * RGBからHSVを得る
     *
     * @param h Hue 0~3066
     * @param s Saturation 0~511
     * @param v Value 0~511
     * @return Vector.<int> R:0~255, G:0~255, B:0~255
     */
    public static function HSVtoRGB(h:int, s:int, v:int):Vector.<int>
    {
      var rr:Number, gg:Number, bb:Number;
      var hh:Number, ss:Number, vv:Number;
      var r:Number, g:Number, b:Number;

      if (h == 6 * hGETA * hSCALE) {
        h = 0;
      }
      hh = Number(h / hGETA);
      ss = Number(s / GETA);
      vv = Number(v / GETA);

      switch(int(hh / hSCALE)) {
      case 0:
        rr = SCALE;
        gg = hh;
        bb = 0;
        break;
      case 1:
        rr = 2 * hSCALE - hh;
        gg = SCALE;
        bb = 0;
        break;
      case 2:
        rr = 0;
        gg = SCALE;
        bb = hh - 2 * hSCALE;
        break;
      case 3:
        rr = 0;
        gg = 4 * hSCALE - hh;
        bb = SCALE;
        break;
      case 4:
        rr = hh - 4 * hSCALE;
        gg = 0;
        bb = SCALE;
        break;
      case 5:
        rr = SCALE;
        gg = 0;
        bb = 6 * hSCALE - hh;
        break;
      }

      rr = (rr + (SCALE - rr) * (SCALE - ss) / SCALE) * vv / SCALE;
      gg = (gg + (SCALE - gg) * (SCALE - ss) / SCALE) * vv / SCALE;
      bb = (bb + (SCALE - bb) * (SCALE - ss) / SCALE) * vv / SCALE;

      r = int(rr);
      g = int(gg);
      b = int(bb);
      if (r > 255) { r = 255 }
      if (g > 255) { g = 255 }
      if (b > 255) { b = 255 }
      return Vector.<int>([r, g, b]);
    }

    private static function sgn(x:Number):Number
    {
      return (x < 0) ? -1 : 1;
    }

    private static function CINT(x:Number):int
    {
      return int(x + sgn(x) * 0.5);
    }

    private static var FL:Number;

    /**
     * RGBから16進数を得る
     *
     * @param r Red 0~255
     * @param g Green 0~255
     * @param b Blue 0~255
     * @return int 0~0xffffff
     */
    public static function RGBtoHex(r:int, g:int, b:int):int
    {
      return r << 16 | g << 8 | b;
    }

    /**
     * ARGBから16進数を得る
     *
     * @param a Alpha 0~255
     * @param r Red 0~255
     * @param g Green 0~255
     * @param b Blue 0~255
     * @return int 0~0xffffffff
     */
    public static function ARGBtoHex(a:int, r:int, g:int, b:int):int
    {
      return a << 24 | r << 16 | g << 8 | b;
    }

    /**
     * 16進数からRGBを得る
     *
     * @param hex 16進数
     * @return Vector.<int> R:0~255, G:0~255, B:0~255
     */
    public static function HextoRGB(hex:int):Vector.<int>
    {
      var r:int = hex >> 16;
      var g:int = hex >> 8 & 0xff;
      var b:int = hex & 0xff;
      return Vector.<int>([r, g, b]);
    }

    /**
     * 16進数からRGBを得る
     *
     * @param hex 16進数
     * @return Vector.<int> A:0~255, R:0~255, G:0~255, B:0~255
     */
    public static function HextoARGB(hex:int):Vector.<int>
    {
      var a:int = hex >> 24;
      var r:int = hex >> 16 & 0xff;
      var g:int = hex >> 8 & 0xff;
      var b:int = hex & 0xff;
      return Vector.<int>([a, r, g, b]);
    }
  }
}

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

ページトップへ戻る