QuickBox2Dで万華鏡
kaleidoscope
* 万華鏡
*
* 力技でとりあえず動きはできたレベル。
* Matrixで苦戦したりいろいろ試しているうちにコードの汚染が・・・もっと短く書けるはずなので要整理。
* 具は毎回ランダム。
/**
* Copyright takishiki ( http://wonderfl.net/user/takishiki )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/eTlV
*/
/*
* kaleidoscope
* 万華鏡
*
* 力技でとりあえず動きはできたレベル。
* Matrixで苦戦したりいろいろ試しているうちにコードの汚染が・・・もっと短く書けるはずなので要整理。
* 具は毎回ランダム。
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.MovieClip;
import com.actionsnippet.qbox.*;
import Box2D.Common.Math.b2Vec2;
import com.actionsnippet.qbox.QuickBox2D;
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.text.TextField;
import flash.display.BlendMode;
import flash.display.Graphics;
[SWF(width=465, height=465, frameRate=30, backgroundColor=0xFFFFFF)]
public class Main extends MovieClip
{
private const LEN:int = 100;
private const NUM:int = 20;
private const DEBUG:Boolean = false;
private var _sp:Sprite;
private var _bmp:Bitmap;
private var _bmpd:BitmapData;
private var _sim:QuickBox2D;
private var _deg:Number = 0;
private var _bmpd2:BitmapData;
//
public function Main():void {
stage.frameRate = 60;
_sim = new QuickBox2D(this, { debug:DEBUG } );
_sim.setDefault( { fillColor:0x000000, lineAlpha:0, radius:1.5 } );
_sim.createStageWalls();
var a:Number = stage.stageWidth / 4 / 30;
_sim.addBox( { x:a, y:a * 2, width:0.5, height:a * 2, angle:0, density:0, fillColor:0x000000 } );
_sim.addBox( { x:a * 3, y:a * 2, width:0.5, height:a * 2, angle:0, density:0, fillColor:0x000000 } );
_sim.addBox( { x:a * 2, y:a, width:a * 2, height:0.5, angle:0, density:0, fillColor:0x000000 } );
_sim.addBox( { x:a * 2, y:a * 3, width:a * 2, height:0.5, angle:0, density:0, fillColor:0x000000 } );
_sim.gravity = new b2Vec2(0, 0);
var type:int;
var i:int;
for (i = 0; i < NUM; i++) {
type = randRange(0, 1);
if (type == 0) {
_sim.addBox( {
x:stage.stageWidth / 30 / 2, y:stage.stageHeight / 30 / 2,
width:randRange(1, 15) / 10, height:randRange(1, 15) / 10,
fillColor:randRange(1, 0xFFFFFF), fillAlpha:randRange(5, 10) / 10,
lineColor:randRange(0, 0), lineAlpha:0
} );
}else {
_sim.addCircle( {
x:stage.stageWidth / 30 / 2, y:stage.stageHeight / 30 / 2,
radius:randRange(1, 10) / 10,
fillColor:randRange(1, 0xFFFFFF), fillAlpha:randRange(5, 10) / 10,
lineColor:randRange(0, 0), lineAlpha:0
} );
}
}
_sim.start();
_sim.mouseDrag();
var r3:Number = Math.sqrt(3);
var sp:Sprite = new Sprite();
//sp.graphics.beginFill(0xFF0000, 0.8);
sp.graphics.beginFill(0x000000, 1.0);
sp.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
drawPoly(sp, 3, stage.stageWidth / 2, stage.stageHeight / 2, LEN * 0.9 / 2 / r3 * 2, 30);
sp.graphics.endFill();
this.addChild(sp);
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
_bmpd2 = new BitmapData(LEN, LEN, false, 0x000000);
_bmpd = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x000000);
_bmp = new Bitmap(_bmpd);
_sp = new Sprite();
_sp.addChild(_bmp);
this.addChild(_sp);
}
//
private function drawPoly(sp:Sprite, num:int, x:int, y:int, r:int, deg:Number):void {
/*
* sp:対象Sprite
* num:頂点の数
* x:中心のx座標
* y:中心のy座標
* r:半径
* deg:回転角度(度)
*/
var g:Graphics = sp.graphics;
var rad:Number;
var i:int;
var step:Number = 360 / num;
// 描画スタート位置に移動
rad = deg2rad(0 + deg);
g.moveTo(x + r * Math.cos(rad), y + r * Math.sin(rad));
for (i = 0; i < num; i++) {
rad = deg2rad((i + 1) * step + deg);
g.lineTo(x + r * Math.cos(rad), y + r * Math.sin(rad));
}
}
//
private function onEnterFrame(event:Event):void {
_deg += 1;
if (_deg >= 360) {
_deg -= 360;
}
var rad:Number = _deg / 180 * Math.PI;
var s:Number = 20;
_sim.gravity = new b2Vec2(s * Math.cos(rad), s * Math.sin(rad));
makeImage();
}
//
private function makeImage():void {
_sp.visible = false;
var bmpd:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
bmpd.lock();
bmpd.draw(this);
bmpd.unlock();
var r3:Number = Math.sqrt(3);
var h:Number = LEN * r3 / 2;
var a:Number = LEN / 2 * r3;
var b:Number = h - LEN / 2 / r3;
var rect:Rectangle = new Rectangle();
rect.x = Math.floor((stage.stageWidth - LEN) / 2);
rect.y = Math.floor((stage.stageHeight - LEN) / 2);
rect.width = LEN;
rect.height = LEN;
_bmpd2.copyPixels(bmpd, rect, new Point(0, 0));
rect = new Rectangle();
rect.x = 0;
rect.y = 0;
rect.width = _bmpd2.width;
rect.height = _bmpd2.height;
_bmpd.lock();
_bmpd.fillRect(new Rectangle(0, 0, _bmpd.width, _bmpd.height), 0x000000);
draw(-LEN / 2, 0, 7);
draw(-LEN / 2, r3 * LEN * 0.85, 7);
draw(-LEN / 2, r3 * LEN * 2 * 0.85, 7);
draw( -LEN / 2, r3 * LEN * 3 * 0.85, 7);
_bmpd.unlock();
_sp.visible = true;
}
//
private function draw(x:Number, y:Number, num:int):void {
var r3:Number = Math.sqrt(3);
var matrix:Matrix = new Matrix();
matrix.tx = 0;
matrix.ty = 0;
var matrix2:Matrix = new Matrix();
var i:int;
var point:Point = new Point();
var l:Number = LEN / 2 * Math.SQRT2;
var rad:Number = Math.PI * 2 / 3;
var len:int = stage.stageWidth
for (i = 0; i < num; i++) {
point.x = l * Math.cos(rad * i + Math.PI / 4);
point.y = l * Math.sin(rad * i + Math.PI / 4);
matrix = new Matrix();
matrix2 = new Matrix();
matrix.translate( -LEN / 2, -LEN / 2);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.rotate(rad * i);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate(LEN / 2, LEN / 2);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate(i * LEN * 0.9, 0);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate(x, y);
matrix.concat(matrix2);
_bmpd.draw(_bmpd2, matrix, new ColorTransform(), BlendMode.LIGHTEN);// , rect, true);
}
for (i = 0; i < num; i++) {
point.x = l * Math.cos(rad * i + Math.PI / 4);
point.y = l * Math.sin(rad * i + Math.PI / 4);
matrix = new Matrix();
matrix.translate( -LEN / 2, -LEN / 2);
matrix2 = new Matrix();
matrix2.rotate(rad * i);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate(LEN / 2, LEN / 2);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate(i * LEN * 0.9, 0);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.scale(1, -1);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate(0, LEN / 2 * r3 * 2 * 0.86);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate(x, y);
matrix.concat(matrix2);
_bmpd.draw(_bmpd2, matrix, new ColorTransform(), BlendMode.LIGHTEN);// , rect, true);
}
rad = Math.PI * 2 / 3;
for (i = 0; i < (num-1); i++) {
point.x = l * Math.cos(rad * i + Math.PI / 4);
point.y = l * Math.sin(rad * i + Math.PI / 4);
matrix = new Matrix();
matrix2 = new Matrix();
matrix.translate( -LEN / 2, -LEN / 2); // 中央へ
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.rotate(rad * i); // 回転
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.scale(-1, 1); // 反転
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.rotate(-Math.PI / 3); // 回転
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate((i + 1) * LEN * 0.9 + 5.5, 26.5);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate(x, y);
matrix.concat(matrix2);
_bmpd.draw(_bmpd2, matrix, new ColorTransform(), BlendMode.LIGHTEN);// , rect, true);
}
rad = Math.PI * 2 / 3;
for (i = 0; i < (num-1); i++) {
point.x = l * Math.cos(rad * i + Math.PI / 4);
point.y = l * Math.sin(rad * i + Math.PI / 4);
matrix = new Matrix();
matrix2 = new Matrix();
matrix.translate( -LEN / 2, -LEN / 2); // 中央へ
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.rotate(rad * i); // 回転
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.scale(-1, 1); // 反転
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.rotate(-Math.PI / 3); // 回転
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.scale(1, -1); // 反転
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate(0, LEN / 2 * r3 * 2 * 0.86 - 26);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate((i + 1) * LEN * 0.9 + 5.5, 0);
matrix.concat(matrix2);
matrix2 = new Matrix();
matrix2.translate(x, y);
matrix.concat(matrix2);
_bmpd.draw(_bmpd2, matrix, new ColorTransform(), BlendMode.LIGHTEN);// , rect, true);
}
}
//
private function onMouseMove(event:MouseEvent):void {
var dx:Number = event.stageX - stage.stageWidth / 2;
var dy:Number = event.stageY - stage.stageHeight / 2;
var max:int = 10;
dx = dx / (stage.stageWidth / 2);
dy = dy / (stage.stageHeight / 2);
var ratio:Number = Math.sqrt(dx * dx + dy * dy);
if (ratio < 1) {
ratio = 1.0;
}
_sim.gravity = new b2Vec2(max * dx / ratio, max * dy / ratio);
}
// degree -> radian
private function deg2rad(deg:Number):Number {
deg %= 360;
return deg / 180 * Math.PI;
}
// a-bの乱数生成
private function randRange(min:Number = 0, max:Number = 1):Number {
var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + min;
return randomNum;
}
}
}