円同士が衝突するまでのフレーム時間検出
-------------------------------------------------
円同士が衝突するまでのフレーム時間検出
円は、ドラッグすることができます。
円以外の余白をクリックすると円を追加できます。
-------------------------------------------------
/**
* Copyright Hakuhin ( http://wonderfl.net/user/Hakuhin )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/q2fX
*/
// -------------------------------------------------
//
// 円同士が衝突するまでのフレーム時間検出
//
// 円は、ドラッグすることができます。
// 円以外の余白をクリックすると円を追加できます。
//
// -------------------------------------------------
package {
import flash.events.*;
import flash.display.*;
import flash.net.*;
import flash.text.*;
import flash.utils.*;
import flash.system.*;
import flash.geom.*;
import flash.filters.*;
import flash.ui.*;
import flash.media.*;
public class Main extends Sprite {
public function Main() {
// -------------------------------------------------
// コンストラクタ
// -------------------------------------------------
// キャプチャタイミング
Wonderfl.capture_delay( 30 );
// フレームレート
stage.frameRate = 60;
// 100%表示
stage.scaleMode = StageScaleMode.NO_SCALE;
// 左上
stage.align = StageAlign.TOP_LEFT;
stage.align = "TL";
// スプライトを作成
var sprite:Sprite = new Sprite();
var g:Graphics = sprite.graphics;
addChild(sprite);
// 円の作成
function CircleObjCreate():Object{
var w:int = 400;
var h:int = 400;
var s:Number = 5; // 最高速度
var d:Number = Math.random(); // 乱数
var r:Number = d * 45 + 5; // 半径
var m:Number = d * 100 + 1; // 質量
return {
pos:new Point(Math.random() * w,Math.random() * h),
spd:new Point((Math.random() * 2 - 1) * s,(Math.random() * 2 - 1) * s),
r:r,
m:m
};
}
// 円の処理
function CircleObjExecute(obj:Object):void{
var w:int = stage.stageWidth;
var h:int = stage.stageHeight;
// 座標に速度を加算
obj.pos = obj.pos.add(obj.spd);
// 壁との当たり判定
if(obj.pos.x < obj.r){
obj.pos.x = obj.r;
obj.spd.x *= -1.0;
}
if(obj.pos.y < obj.r){
obj.pos.y = obj.r;
obj.spd.y *= -1.0;
}
if(obj.pos.x > w - obj.r){
obj.pos.x = w - obj.r;
obj.spd.x *= -1.0;
}
if(obj.pos.y > h - obj.r){
obj.pos.y = h - obj.r;
obj.spd.y *= -1.0;
}
}
// 円の描画
function CircleObjDraw(obj:Object,g:Graphics):void{
g.lineStyle ( 5.0 , 0xD02020 , 1.0 );
g.beginFill (0xFFBBBB, 1.0); // 面のスタイル設定
g.drawCircle (obj.pos.x, obj.pos.y , obj.r - 2.5);
}
var layer_back:Shape = new Shape();
addChild(layer_back);
var layer_front:Shape = new Shape();
addChild(layer_front);
var layer_font:Sprite = new Sprite();
addChild(layer_font);
var i:int;
var j:int;
var e:Number = 1.0; // 反発係数
var num:int = 1; // 初期生成数
var circle_obj:Array = new Array();
// 円を作成
for(i=0;i<num;i++){
circle_obj.push(CircleObjCreate());
}
addEventListener(Event.ENTER_FRAME,function(event:Event):void {
// クリア
layer_back.graphics.clear();
layer_front.graphics.clear();
while(layer_font.numChildren){
layer_font.removeChildAt(0);
}
// マウス移動
mouse_spd.x = stage.mouseX - mouse_pos.x;
mouse_spd.y = stage.mouseY - mouse_pos.y;
mouse_pos.x = stage.mouseX;
mouse_pos.y = stage.mouseY;
mouse_ave.x = (mouse_ave.x * 4.0 + mouse_spd.x) / 5.0;
mouse_ave.y = (mouse_ave.y * 4.0 + mouse_spd.y) / 5.0;
// ドラッグ中
if(drag){
drag.pos.x = mouse_pos.x;
drag.pos.y = mouse_pos.y;
drag.spd.x = mouse_ave.x;
drag.spd.y = mouse_ave.y;
}
// 総当り判定を計算
for(i=0;i<circle_obj.length - 1;i++){
var a:Object = circle_obj[i];
for(j=i+1;j<circle_obj.length;j++){
var b:Object = circle_obj[j];
var _a:Number = (a.spd.x * a.spd.x) - 2 * (a.spd.x * b.spd.x) + (b.spd.x * b.spd.x) + (a.spd.y * a.spd.y) - 2 * (a.spd.y * b.spd.y) + (b.spd.y * b.spd.y);
var _b:Number = 2 * (a.pos.x * a.spd.x) - 2 * (a.pos.x * b.spd.x) - 2 * (a.spd.x * b.pos.x) + 2 * (b.pos.x * b.spd.x) + 2 * (a.pos.y * a.spd.y) - 2 * (a.pos.y * b.spd.y) - 2 * (a.spd.y * b.pos.y) + 2 * (b.pos.y * b.spd.y);
var _c:Number = (a.pos.x * a.pos.x) - 2 * (a.pos.x * b.pos.x) + (b.pos.x * b.pos.x) + (a.pos.y * a.pos.y) - 2 * (a.pos.y * b.pos.y) + (b.pos.y * b.pos.y) - (a.r + b.r) * (a.r + b.r);
var _d:Number = _b * _b - 4 * _a * _c;
var vx:Number;
var vy:Number;
if(_d <= 0){
}else{
// 当たりあり
_d = Math.sqrt(_d);
var f0:Number = (- _b - _d) / (2 * _a); // 接触する瞬間
var f1:Number = (- _b + _d) / (2 * _a); // 離れる瞬間
// 衝突する瞬間の座標
var apx:Number = a.pos.x + a.spd.x * f0;
var apy:Number = a.pos.y + a.spd.y * f0;
var bpx:Number = b.pos.x + b.spd.x * f0;
var bpy:Number = b.pos.y + b.spd.y * f0;
var cpx:Number = (bpx - apx) / 2.0 + apx;
var cpy:Number = (bpy - apy) / 2.0 + apy;
if(f0 >= 0){
var g:Graphics
g = layer_back.graphics;
g.lineStyle ( a.r * 2 , 0x0000FF , 0.1 );
g.moveTo (a.pos.x, a.pos.y); // 面のスタイル設定
g.lineTo (apx, apy);
g.lineStyle ( b.r * 2 , 0x00FF00 , 0.1 );
g.moveTo (b.pos.x, b.pos.y); // 面のスタイル設定
g.lineTo (bpx, bpy);
var tf:TextField = new TextField();
var format:TextFormat = new TextFormat();
format.size = 14;
format.font = "MS ゴシック";
format.align = TextFormatAlign.CENTER;
tf.defaultTextFormat = format;
tf.x = cpx - 30;
tf.y = cpy - 15;
tf.width = 60;
tf.height = 30;
tf.text = String(Math.floor(f0 * 100) / 100);
tf.alpha = 0.2;
layer_font.addChild(tf);
}
// めり込み補正
if(f0 * f1 < 0){
vx = (a.pos.x - b.pos.x);
vy = (a.pos.y - b.pos.y);
var len:Number = Math.sqrt(vx * vx + vy * vy);
var distance:Number = a.r + b.r - len;
if(len > 0) len = 1 / len;
vx *= len;
vy *= len;
distance /= 2.0;
a.pos.x += vx * distance;
a.pos.y += vy * distance;
b.pos.x -= vx * distance;
b.pos.y -= vy * distance;
}else if(f0 <= 1 && f0 >= 0){
var f:Number = (Math.abs(f0) < Math.abs(f1)) ? f0 : f1;
// 衝突する瞬間の座標
a.pos.x = a.pos.x + a.spd.x * f;
a.pos.y = a.pos.y + a.spd.y * f;
b.pos.x = b.pos.x + b.spd.x * f;
b.pos.y = b.pos.y + b.spd.y * f;
}
// 接触する瞬間は反射
if(f0 > 1) continue;
if(f0 < 0 && f1 < 0) continue;
// 移動運動用ベクトルと回転運動用ベクトルに分離
var t:Number;
vx = (b.pos.x - a.pos.x);
vy = (b.pos.y - a.pos.y);
t = -(vx * a.spd.x + vy * a.spd.y) / (vx * vx + vy * vy);
var arx:Number = a.spd.x + vx * t;
var ary:Number = a.spd.y + vy * t;
t = -(-vy * a.spd.x + vx * a.spd.y) / (vy * vy + vx * vx);
var amx:Number = a.spd.x - vy * t;
var amy:Number = a.spd.y + vx * t;
t = -(vx * b.spd.x + vy * b.spd.y) / (vx * vx + vy * vy);
var brx:Number = b.spd.x + vx * t;
var bry:Number = b.spd.y + vy * t;
t = -(-vy * b.spd.x + vx * b.spd.y) / (vy * vy + vx * vx);
var bmx:Number = b.spd.x - vy * t;
var bmy:Number = b.spd.y + vx * t;
// 移動運動成分同士の衝突後の方向
var adx:Number = (a.m * amx + b.m * bmx + bmx * e * b.m - amx * e * b.m) / (a.m + b.m);
var bdx:Number = - e * (bmx - amx) + adx;
var ady:Number = (a.m * amy + b.m * bmy + bmy * e * b.m - amy * e * b.m) / (a.m + b.m);
var bdy:Number = - e * (bmy - amy) + ady;
// 回転運動用ベクトルと加算
a.spd.x = adx + arx;
a.spd.y = ady + ary;
b.spd.x = bdx + brx;
b.spd.y = bdy + bry;
}
}
}
// 実行
var p:String;
for(i=0;i<circle_obj.length;i++){
CircleObjExecute(circle_obj[i]);
}
// 描画
for(i=0;i<circle_obj.length;i++){
CircleObjDraw(circle_obj[i],layer_front.graphics);
}
});
var drag:Object = null;
var mouse_pos:Point = new Point(0,0);
var mouse_spd:Point = new Point(0,0);
var mouse_ave:Point = new Point(0,0);
// マウスが押されたときに実行されるイベント
stage.addEventListener(MouseEvent.MOUSE_DOWN,function(event:MouseEvent):void {
// 当たり判定チェック
for(i=0;i<circle_obj.length;i++){
var vx:Number = circle_obj[i].pos.x - event.localX;
var vy:Number = circle_obj[i].pos.y - event.localY;
if(vx * vx + vy * vy < circle_obj[i].r * circle_obj[i].r){
drag = circle_obj[i];
return;
}
}
// 生成
var obj:Object = CircleObjCreate();
circle_obj.push(obj);
obj.pos.x = event.localX;
obj.pos.y = event.localY;
obj.spd.x = 0;
obj.spd.y = 0;
drag = obj;
});
// マウスが離されたときに実行されるイベント
stage.addEventListener(MouseEvent.MOUSE_UP,function(event:MouseEvent):void {
// ドラッグ開放
drag = null;
});
}
}
}
// -------------------------------------------------
// 外部画像をサムネイルとしてキャプチャ
// -------------------------------------------------
import flash.net.*;
import flash.events.*;
import flash.display.*;
import flash.geom.*;
function ThumbnailCapture(url:String,time:uint,stage:Stage):void{
// キャプチャタイミング
Wonderfl.capture_delay( time );
// スプライト作成
var sprite : Sprite = new Sprite();
// ステージ最前面に配置
stage.addChildAt(sprite,stage.numChildren);
// ローダー
var loader_obj : Loader = new Loader();
loader_obj.contentLoaderInfo.addEventListener (Event.INIT,function(e:Event):void{
// メモリからインスタンス化
var loader_memory : Loader = new Loader();
loader_memory.contentLoaderInfo.addEventListener (Event.INIT,function(e:Event):void{
// キャプチャ
var bmp : BitmapData = new BitmapData(loader_memory.width,loader_memory.height,true,0);
sprite.addChild(loader_memory);
bmp.draw(sprite);
sprite.removeChild(loader_memory);
loader_memory.unload();
loader_obj.unload();
loader_memory = null;
loader_obj = null;
// 画像を配置
var bmp_obj : Bitmap = new Bitmap(bmp);
bmp_obj .width = stage.stageWidth;
bmp_obj .height = stage.stageHeight;
stage.addChild(bmp_obj );
});
// 読み込み開始
loader_memory.loadBytes(loader_obj.contentLoaderInfo.bytes);
});
// 読み込み開始
loader_obj.load(new URLRequest(url));
}