ボール
操作方法、工夫した点、解説したい内容、こだわったところや参考文献のURL等を書いてください
書かない場合、クラス宣言までのコメント文から自動抽出します
/**
* Copyright 1coro ( http://wonderfl.net/user/1coro )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/Angt
*/
package {
import flash.display.Graphics;
import flash.geom.Point;
import flash.display.Shape;
import flash.events.Event;
import flash.display.Sprite;
[SWF(width="320", height="320", backgroundColor="0xffffff", frameRate="30")]
public class BallTest extends Sprite {
static public const SCREEN_SIZE:int = 320;
static public const BALL_NUM:int = 24;
private var ball:Array;
private var shape:Shape;
public function BallTest() {
Init();
}
public function Init():void
{
var i:int;
shape = new Shape();
stage.addChild(shape);
// ボール
ball = new Array(BALL_NUM);
for(i = 0; i < BALL_NUM; i++)
{
var color:uint = Math.random() * (1 << 24);
ball[i] = new Ball(Math.random() * 320, Math.random() * 320, Math.random() * 32.0, color);
}
addEventListener(Event.ENTER_FRAME, Update);
addEventListener(Event.REMOVED_FROM_STAGE, Finish);
}
public function Update(e:Event):void
{
var g:Graphics = shape.graphics;
g.clear();
var i:int;
// 更新
const ratio:Number = 0.01;
// マウスに追従
ball[i].point.pos.x += (stage.mouseX - ball[i].point.pos.x) * 0.2;
ball[i].point.pos.y += (stage.mouseY - ball[i].point.pos.y) * 0.2;
for(i = 0; i < BALL_NUM; i++)
{
// 減衰
ball[i].point.prev.x += (ball[i].point.pos.x - ball[i].point.prev.x) * 0.01; // 冗長
ball[i].point.prev.y += (ball[i].point.pos.y - ball[i].point.prev.y) * 0.01;
ball[i].Update();
}
// 衝突
for(i = 0; i < BALL_NUM; i++)
{
for(var j:int = i; j < BALL_NUM; j++)
{
if(Collision.Circle_Circle(ball[i].circle, ball[j].circle))
{
var v:Point = ball[j].point.pos.subtract(ball[i].point.pos);
var len:Number = Math.sqrt((v.x*v.x) + (v.y*v.y));
if(len > 0)
{
var d:Number = ((ball[i].circle.r + ball[j].circle.r) - len) * 0.5 / len;
v.x *= d; v.y *= d;
ball[i].point.AddPrev(v.x, v.y);
ball[j].point.AddPrev(-v.x, -v.y);
}
}
}
}
for(i = 0; i < BALL_NUM; i++)
{
if(ball[i].point.pos.x < 0.0)
{
ball[i].point.pos.x = 0.0;
ball[i].point.prev.x = ball[i].point.pos.x + (ball[i].point.pos.x - ball[i].point.prev.x) * 0.8; // 冗長
}
else if(ball[i].point.pos.x > SCREEN_SIZE)
{
ball[i].point.pos.x = SCREEN_SIZE;
ball[i].point.prev.x = ball[i].point.pos.x + (ball[i].point.pos.x - ball[i].point.prev.x) * 0.8;
}
if(ball[i].point.pos.y < 0.0)
{
ball[i].point.pos.y = 0.0;
ball[i].point.prev.y = ball[i].point.pos.y + (ball[i].point.pos.y - ball[i].point.prev.y) * 0.8;
}
else if(ball[i].point.pos.y > SCREEN_SIZE)
{
ball[i].point.pos.y = SCREEN_SIZE;
ball[i].point.prev.y = ball[i].point.pos.y + (ball[i].point.pos.y - ball[i].point.prev.y) * 0.8;
}
}
// 描画
for(i = 0; i < BALL_NUM; i++)
{
ball[i].Draw(g);
}
}
public function Finish(e:Event):void
{
removeEventListener(Event.REMOVED_FROM_STAGE, Finish);
removeEventListener(Event.ENTER_FRAME, Update);
removeEventListener(Event.ADDED_TO_STAGE, Init);
}
}
}
import flash.display.Graphics;
import flash.geom.Point;
class VerletPoint
{
public var pos:Point;
public var prev:Point;
public function VerletPoint()
{
pos = new Point();
prev = new Point();
pos.x = pos.y = 0.0;
prev.x = prev.y = 0.0;
}
public function Update():void
{
var nx:Number = pos.x, ny:Number = pos.y;
pos.x = nx + (nx - prev.x);
pos.y = ny + (ny - prev.y);
prev.x = nx; prev.y = ny;
}
public function Set(x:Number, y:Number, fix:Boolean = true):void
{
pos.x = x; pos.y = y;
if(fix) { prev.x = x; prev.y = y; }
}
public function Add(x:Number, y:Number):void
{
pos.x += x; pos.y += y;
}
public function AddPrev(x:Number, y:Number):void
{
prev.x += x; prev.y += y;
}
}
class Circle
{
public var c:Point;
public var r:Number;
public function Circle()
{
c = new Point();
r = 1.0;
}
public function Set(x:Number, y:Number, rr:Number):void
{
c.x = x; c.y = y;
r = rr;
}
public function Update(x:Number, y:Number):void
{
c.x = x; c.y = y;
}
}
class Ball
{
public var point:VerletPoint;
public var circle:Circle;
public var color:uint;
public function Ball(x:Number, y:Number, r:Number, c:uint)
{
point = new VerletPoint();
point.Set(x, y);
circle = new Circle();
circle.Set(x, y, r);
color = c;
}
public function Update():void
{
point.Update();
circle.Update(point.pos.x, point.pos.y);
}
public function Draw(g:Graphics):void
{
g.beginFill(color, 1);
g.drawCircle(circle.c.x, circle.c.y, circle.r);
}
}
class Collision
{
static public function Circle_Circle(a:Circle, b:Circle):Boolean
{
return (a.r+b.r) * (a.r+b.r) > ((a.c.x-b.c.x)*(a.c.x-b.c.x) + (a.c.y-b.c.y)*(a.c.y-b.c.y));
}
}