ボールの衝突
/**
* Copyright termat ( http://wonderfl.net/user/termat )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/zWua
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import frocessing.color.ColorHSV;
[SWF(width = "480", height = "480", backgroundColor = "0x000000", fps = "60")]
public class Practice82 extends Sprite{
private var balls:Vector.<Ball>;
private var isPress:Boolean = false;
private var pos:Point;
private var col:ColorHSV = new ColorHSV();
private var fls:Array = new Array();
public function Practice82() {
balls = new Vector.<Ball>();
Vect2D.width = 480;
Vect2D.height = 480;
Flash.color = col;
Ball.fls = fls;
initBalls();
for each(var b:Ball in balls) {
addChild(b);
}
addEventListener(Event.ENTER_FRAME, update);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
private function onDown(e:MouseEvent):void {
pos = new Point(e.stageX, e.stageY);
}
private function onUp(e:MouseEvent):void {
var dx:Number = mouseX - pos.x;
var dy:Number = mouseY - pos.y;
var lg:Number = Math.sqrt(dx * dx + dy * dy);
var vec:Number = lg / 10 + 1;
var rad:Number = Math.min(40,200 / vec);
if (!check(pos.x, pos.y, rad)) return;
var b:Ball = new Ball();
var tt:Number = Math.atan2(dx, dy);
b.setBall(pos.x, pos.y, rad);
b.vec.vx = dx/10;
b.vec.vy = dy / 10;
col.h = 360 * Math.random();
b.color = col.value;
b.init();
balls.push(b);
addChild(b);
pos = null;
}
private function check(xx:Number, yy:Number, rr:int):Boolean {
for (var i:int = 0; i < balls.length; i++) {
var dx:Number = balls[i].x - xx;
var dy:Number = balls[i].y - yy;
var lg:Number = Math.sqrt(dx * dx + dy * dy);
if (lg < (balls[i].r + rr)) return false;
}
return true;
}
private function addBall(xx:Number, yy:Number, rr:int):void {
if (check(xx, yy,rr)) {
var b:Ball = new Ball();
b.setBall(xx, yy, rr);
b.vec.vx = 0;
b.vec.vy = 0;
col.h = 360 * Math.random();
b.color = col.value;
b.init();
balls.push(b);
addChild(b);
}else {
addBall(460*Math.random()+10, 460*Math.random()+1, 20*Math.random()+5);
}
}
private function initBalls():void {
for (var i:int = 0; i < 10; i++) {
addBall(460 * Math.random() + 10, 460 * Math.random() + 1, 20 * Math.random() + 5);
}
}
private function update(e:Event):void {
graphics.clear();
if (pos != null) {
var dx:Number = mouseX - pos.x;
var dy:Number = mouseY - pos.y;
var lg:Number = Math.sqrt(dx * dx + dy * dy);
var vec:Number = lg / 10 + 1;
var rad:Number = Math.min(40,200 / vec);
graphics.lineStyle(1, 0x888888);
graphics.drawCircle(pos.x, pos.y, rad);
graphics.lineStyle(1, 0xcc6666);
graphics.moveTo(pos.x, pos.y);
graphics.lineTo(mouseX, mouseY);
}
for (var n:Number = 0; n < 20; n++) {
for (var i:int = 0; i < balls.length; i++) {
balls[i].move(20);
balls[i].checkBoundaryCollision();
}
for (i = 0; i < balls.length; i++) {
for (var j:int = i + 1; j < balls.length; j++) {
checkCollision(balls[i], balls[j]);
}
}
}
for (i = 0; i < fls.length; i++) {
var f:Flash = fls.shift();
f.draw(graphics);
if (f.counter < Flash.size) fls.push(f);
}
}
private function checkCollision(b0:Ball,b1:Ball):void{
var bVect:Vect2D = new Vect2D();
bVect.vx = b1.x - b0.x;
bVect.vy = b1.y - b0.y;
var bVectMag:Number = Math.sqrt(bVect.vx * bVect.vx + bVect.vy * bVect.vy);
if (bVectMag < b0.r + b1.r) {
var f:Flash = new Flash();
f.x = (b0.x + b1.x) / 2, f.y = (b0.y + b1.y) / 2;
fls.push(f);
var theta:Number = Math.atan2(bVect.vy, bVect.vx);
var sine:Number = Math.sin(theta);
var cosine:Number = Math.cos(theta);
var bTemp:Array = [ new Ball(), new Ball()];
bTemp[1].x = cosine * bVect.vx + sine * bVect.vy;
bTemp[1].y = cosine * bVect.vy - sine * bVect.vx;
var vTemp:Array = [new Vect2D(), new Vect2D()];
vTemp[0].vx = cosine * b0.vec.vx + sine * b0.vec.vy;
vTemp[0].vy = cosine * b0.vec.vy - sine * b0.vec.vx;
vTemp[1].vx = cosine * b1.vec.vx + sine * b1.vec.vy;
vTemp[1].vy = cosine * b1.vec.vy - sine * b1.vec.vx;
var vFinal:Array = [new Vect2D(), new Vect2D()];
vFinal[0].vx = ((b0.m - b1.m) * vTemp[0].vx + 2 * b1.m *
vTemp[1].vx) / (b0.m + b1.m);
vFinal[0].vy = vTemp[0].vy;
vFinal[1].vx = ((b1.m - b0.m) * vTemp[1].vx + 2 * b0.m *
vTemp[0].vx) / (b0.m + b1.m);
vFinal[1].vy = vTemp[1].vy;
bTemp[0].x += vFinal[0].vx;
bTemp[1].x += vFinal[1].vx;
var bFinal:Array = [new Ball(), new Ball()];
bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;
b1.x = b0.x + bFinal[1].x;
b1.y = b0.y + bFinal[1].y;
b0.x = b0.x + bFinal[0].x;
b0.y = b0.y + bFinal[0].y;
b0.vec.vx = cosine * vFinal[0].vx - sine * vFinal[0].vy;
b0.vec.vy = cosine * vFinal[0].vy + sine * vFinal[0].vx;
b1.vec.vx = cosine * vFinal[1].vx - sine * vFinal[1].vy;
b1.vec.vy = cosine * vFinal[1].vy + sine * vFinal[1].vx;
bVect.vx = b1.x - b0.x;
bVect.vy = b1.y - b0.y;
while (Math.sqrt(bVect.vx * bVect.vx + bVect.vy * bVect.vy) < b0.r + b1.r) {
b0.x += b0.vec.vx; b0.y += b0.vec.vy;
b1.x += b1.vec.vx; b1.y += b1.vec.vy;
bVect.vx = b1.x - b0.x;
bVect.vy = b1.y - b0.y;
}
}
}
}
}
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.filters.DropShadowFilter;
import frocessing.color.ColorHSV;
class Ball extends MovieClip {
public static var fls:Array;
public var m:Number = 1;
public var r:Number = 1;
public var color:uint = 0xffffff;
public var vec:Vect2D=new Vect2D();
public function setBall(_x:Number,_y:Number,_r:Number):void {
this.x = _x;
this.y = _y;
this.r = _r;
m = r * .1;
vec = new Vect2D();
var dropShadow:DropShadowFilter = new DropShadowFilter(4, 45, 0x000000, 0.2, 8, 8, 1, 1);
filters = [dropShadow];
}
public function init():void {
graphics.beginFill(color);
graphics.drawCircle(0,0,r);
graphics.endFill();
}
public function move(n:Number):void {
x += vec.vx/n;
y += vec.vy/n;
}
public function checkBoundaryCollision():void {
if (vec.checkBoundaryCollision(this, vec)) {
var f:Flash = new Flash();
f.x = x; f.y = y;
fls.push(f);
}
}
}
class Vect2D {
public static var width:Number;
public static var height:Number;
public var vx:Number;
public var vy:Number;
public function checkBoundaryCollision(ball:Ball,vel:Vect2D):Boolean{
if (ball.x > width-ball.r&&ball.vec.vx>0){
ball.x = width-ball.r;
vel.vx *= -0.95;
return true;
} else if (ball.x < ball.r&&ball.vec.vx<0){
ball.x = ball.r;
vel.vx *= -0.95;
return true;
} else if (ball.y > height-ball.r&&ball.vec.vy>0){
ball.y = height-ball.r;
vel.vy *= -0.95;
return true;
} else if (ball.y < ball.r&&ball.vec.vy<0){
ball.y = ball.r;
vel.vy *= -0.95;
return true;
}
return false;
}
}
class Flash {
public static var color:ColorHSV;
public var x:Number;
public var y:Number;
public var h:Number=360*Math.random();
public var counter:int = 1;
public static var size:Number = 80;
public function draw(g:Graphics):void {
color.h = h;
color.v = (size - counter) / size;
g.lineStyle(0.1, color.value);
g.drawCircle(x, y, counter);
counter +=2;
}
}