#17 Hanabi ( flash on 2009-9-5 )
#17 Hanabi
*
* BitmapData#fillRectではなくBitmapData#colorTransformを用いる実験。
* 作っているうちにHANABIぽくなくなってしまったけれど、綺麗なのでよしとします。
*
* 操作:
* ・クリック: クリック位置に点を生成
*
* 参考:
* ・HANABI
* http://wonderfl.net/code/13dbc50eb48b0bfd6920540c228e8ba9ae75b601
*
* @author krogue
/**
* Copyright krogue ( http://wonderfl.net/user/krogue )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/sFKK
*/
/**
* #17 Hanabi
*
* BitmapData#fillRectではなくBitmapData#colorTransformを用いる実験。
* 作っているうちにHANABIぽくなくなってしまったけれど、綺麗なのでよしとします。
*
* 操作:
* ・クリック: クリック位置に点を生成
*
* 参考:
* ・HANABI
* http://wonderfl.net/code/13dbc50eb48b0bfd6920540c228e8ba9ae75b601
*
* @author krogue
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
[SWF(width="465", height="465", backgroundColor="0", frameRate="60")]
public class Main extends Sprite
{
private var frame:int = 0;
private var hanabi:Hanabi;
private var isMouseDown:Boolean;
public function Main()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
initialize();
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler(event:Event):void
{
update();
}
private function initialize():void
{
// addChild(new Stats());
hanabi = addChild(new Hanabi()) as Hanabi;
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
private function update():void
{
if (isMouseDown)
hanabi.shoot(mouseX, mouseY);
hanabi.update();
frame = (frame + 1 == 60 ? 0 : frame + 1);
}
private function mouseDownHandler(event:MouseEvent):void
{
isMouseDown = true;
}
private function mouseUpHandler(event:MouseEvent):void
{
isMouseDown = false;
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.Sprite;
import flash.geom.ColorTransform;
import flash.geom.Point;
class Hanabi extends Sprite
{
private static const ACCELERATION:Number = 0.01;
private static const ANGULAR_VELOCITY:Number = 0.02;
private static const MAX_SPEED:Number = 2; // 初期速度の最高値
private static const MIN_SPEED:Number = 0.5; // 初期速度の最低値
private static const NUM_SHOOT:int = 8; // shoot一回で生成される点の数
private const bitmap:Bitmap = addChild(new Bitmap()) as Bitmap;
private const colorTransform:ColorTransform =
new ColorTransform(0.8, 0.9, 0.8); // 尾の長さに影響
private const pixels:Array /* of Pixel */ = [];
public function Hanabi()
{
bitmap.bitmapData = new BitmapData(465, 465, false, 0x000000);
}
public function update():void
{
const bmd:BitmapData = bitmap.bitmapData;
bmd.lock();
// Array#spliceの都合で逆向きに走査
for (var i:int = pixels.length - 1; i >= 0; i--)
{
var pixel:Pixel = pixels[i];
pixel.angle += ANGULAR_VELOCITY;
pixel.speed *= 1 + ACCELERATION;
pixel.x += Math.cos(pixel.angle) * pixel.speed;
pixel.y += Math.sin(pixel.angle) * pixel.speed;
bmd.setPixel(pixel.x, pixel.y, 0xFFFFFF);
if (!bmd.rect.contains(pixel.x, pixel.y))
pixels.splice(i, 1);
}
bmd.colorTransform(bmd.rect, colorTransform);
bmd.unlock();
}
public function shoot(x:Number, y:Number):void
{
const n:int = NUM_SHOOT;
for (var i:int = 0; i < n; i++)
{
var pixel:Pixel = new Pixel();
pixel.x = x;
pixel.y = y;
pixel.angle = Math.random() * Math.PI * 2;
// intの場合はfloor(rand * (max - min + 1)) + min
pixel.speed = Math.random() * (MAX_SPEED - MIN_SPEED) + MIN_SPEED;
pixels.push(pixel);
}
}
}
class Pixel
{
public var x:Number;
public var y:Number;
public var angle:Number;
public var speed:Number;
}