吹き出るワンコ
いつもより多く吹き出ております
操作: マウス押しっぱなし
※前に同じネタ見た気がするのでもしかぶってたらごめんなさい
/**
* Copyright beinteractive ( http://wonderfl.net/user/beinteractive )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/m0pv
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
[SWF(width = 456, height = 456, frameRate = 30, bakcgroundColor = 0xffffff)]
public class WondeflFukideruWanco extends Sprite
{
// ウンコSWF URL
protected static const UNKO_URL:String = 'http://swf.wonderfl.net/static/assets/checkmate05/wancoProfessional.swf';
// テクスチャ幅
protected static const TEXTURE_W:Number = 32;
// テクスチャ高
protected static const TEXTURE_H:Number = 32;
// テクスチャを何度ずつ生成するか
protected static const TEXTURE_R:Number = Math.PI / 30;
// キャンバスクリア時の ColorTransform
protected static const CLEAR_TRANSFORM:ColorTransform = new ColorTransform(1.0, 1.0, 1.0, 0.15);
public function WondeflFukideruWanco()
{
// 設定
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.quality = StageQuality.MEDIUM;
// ウンコロード
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadCompleteHandler);
loader.load(new URLRequest(UNKO_URL));
}
/**
* テクスチャ.
*/
protected var texture:BitmapData;
/**
* キャンバス.
*/
protected var canvas:BitmapData;
/**
* パーティクル群への参照.
*/
protected var particles:UnkoParticle;
/**
* マウスが押されているか?
*/
protected var isPressed:Boolean;
/**
* ウンコロード完了.
*/
protected function loadCompleteHandler(e:Event):void
{
// 後始末
var loaderInfo:LoaderInfo = e.target as LoaderInfo;
loaderInfo.removeEventListener(Event.COMPLETE, loadCompleteHandler);
// ウンコクラス取り出し
var unkoClass:Class = loaderInfo.applicationDomain.getDefinition('WakeMotion') as Class;
// テクスチャ生成
texture = makeTexture(new unkoClass(), 0, -40, 90);
// ヒットエリア
var s:Sprite = new Sprite();
s.graphics.beginFill(0xffffff);
s.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
s.graphics.endFill();
// 指カーソル他ボタン設定
s.buttonMode = true;
s.useHandCursor = true;
s.mouseChildren = false;
addChild(s);
// キャンバス
canvas = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x00000000);
addChild(new Bitmap(canvas));
// マウスイベント
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
// フレームイベント
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
/**
* <code>image</code> を元に生成したテクスチャ.
*
* @param image 元画像
* @param x 中心X
* @param y 中心Y
* @param size 画像サイズ
* @return 生成されたテクスチャ
*/
protected function makeTexture(image:DisplayObject, x:int, y:int, size:Number):BitmapData
{
// 32x32 サイズで 6 度ずつ回しながら 360 度分
var width:Number = TEXTURE_W;
var height:Number = TEXTURE_H;
var step:Number = TEXTURE_R;
var n:uint = (Math.PI * 2) / step;
var texture:BitmapData = new BitmapData(width * n, height, true, 0x00000000);
var m:Matrix = new Matrix();
for (var i:uint = 0; i < n; ++i) {
var sx:Number = width / size;
var sy:Number = height / size;
m.translate(-x, -y);
m.rotate(i * step);
m.scale(sx, sy);
m.translate(width / 2.0, height / 2.0);
m.translate(width * i, 0);
texture.draw(image, m);
m.identity();
}
return texture;
}
/**
* マウス押し下げ.
*/
protected function mouseDownHandler(e:MouseEvent):void
{
isPressed = true;
}
/**
* マウス押し上げ.
*/
protected function mouseUpHandler(e:MouseEvent):void
{
isPressed = false;
}
/**
* フレームイベント.
*/
protected function enterFrameHandler(e:Event):void
{
// マウス押されてる?
if (isPressed) {
// 新しいウンコ * 4 生成
for (var j:uint = 0; j < 4; ++j) {
appendParticle(makeParticle(mouseX - TEXTURE_W / 2.0, mouseY - TEXTURE_H / 2.0));
}
}
// クリア
canvas.lock();
// canvas.fillRect(canvas.rect, 0x00000000);
canvas.colorTransform(canvas.rect, CLEAR_TRANSFORM);
// ステージの高さ
var sh:Number = stage.stageHeight;
// テクスチャ幅
var w:Number = TEXTURE_W;
// 回転幅
var step:Number = TEXTURE_R;
// テクスチャ枚数
var n:uint = (Math.PI * 2) / step;
// 転送元矩形
var sr:Rectangle = new Rectangle(0, 0, 32, 32);
// ぐるぐる
var prev:UnkoParticle = null;
var p:UnkoParticle = particles;
while (p != null) {
// パーティクルの位置
var pos:Point = p.pos;
// 位置再計算
pos.x += p.vx;
pos.y += p.vy;
// 回転再計算
p.r += p.vr;
// 速度再計算 (重力)
p.vy += 0.98;
// 回転に応じた転送元矩形判別
var r:int = (((p.r / step) >> 0) % n);
if (r < 0) {
r += n;
}
sr.x = w * r;
// 描画
canvas.copyPixels(texture, sr, pos, null, null, true);
// 画面外に出た?
if (pos.y > sh) {
// リンクから外してさようなら
if (prev != null) {
prev.next = p.next;
}
else {
particles = p.next;
}
}
// 次へ
prev = p;
p = p.next;
}
// 反映
canvas.unlock();
}
/**
* 新しいパーティクル.
*
* @param x 初期X位置
* @param y 初期Y位置
* @return 新しいパーティクル
*/
protected function makeParticle(x:Number, y:Number):UnkoParticle
{
var p:UnkoParticle = new UnkoParticle();
p.pos = new Point(x, y);
p.r = 0;
p.vx = Math.random() * 20.0 - 10.0; // 水平方向速度; 左右に振る
p.vy = -(10 + Math.random() * 10); // 垂直方向速度
p.vr = Math.PI / 16 * (p.vy / 20) * (p.vx < 0 ? -1 : 1); // 回転速度
return p;
}
/**
* <code>p</code> をパーティクル群に追加する.
*
* @param p 追加するパーティクル
*/
protected function appendParticle(p:UnkoParticle):void
{
// 先頭が空でなければ
if (particles != null) {
// つなぐ
p.next = particles;
}
// 先頭へ
particles = p;
}
}
}
import flash.geom.Point;
class UnkoParticle
{
public var next:UnkoParticle;
public var pos:Point;
public var r:Number;
public var vx:Number;
public var vy:Number;
public var vr:Number;
}