/**
* Copyright Nicolas ( http://wonderfl.net/user/Nicolas )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/oaBX
*/
// forked from mousepancyo's 引力に引き込まれテスト
/*
とりあえず引力の実装を始めました。
まずは惑星一個からテストです。
なんだかとりあえず的な激しく汚いコードですが…
*/
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
[SWF(width=465, height=465, backgroundColor=0,frameRate=30)]
public class Main extends Sprite{
private var _satList:Vector.<Sat> = new Vector.<Sat>
private var _satNum:int = 500;
public function Main() {
var base:Base = new Base(0,stage.stageWidth,stage.stageHeight)
addChild(base)
for(var i:int=0; i<_satNum; i++){
var sat:Sat = new Sat()
sat.x = Math.floor(Math.random()*stage.stageWidth);
sat.y = Math.floor(Math.random()*stage.stageHeight);
sat.mass = 10 * Math.random();
addChild(sat)
_satList.push(sat)
}
//
createPlanet(0xFFFFFF, 15, 0.1, 150);
}
private function createPlanet(color:int, size:int, speed:Number, rad:Number):void{
var circle:Circle = new Circle(color, size, speed, rad)
circle.x = stage.stageWidth/2
circle.y = stage.stageHeight/2
circle.pos = new Point(circle.x, circle.y)
circle.mass = 200;
addChild(circle)
circle.addEventListener(Event.ENTER_FRAME, update)
}
private function update(e:Event):void{
e.target.x = e.target.motion.setPos(e.target.pos).x
e.target.y = e.target.motion.setPos(e.target.pos).y
//
for(var i:int=0; i<_satNum; i++){
var speed:Point = _satList[i].speed;
var gravity:Point = e.target.gravity(_satList[i]);
speed.x += gravity.x;
speed.y += gravity.y;
_satList[i].x += speed.x;
_satList[i].y += speed.y;
}
}
private function satMove(target:Sprite ,speed:Number):Point{
var p:Point = (target as Sat).speed;
var rad:Number = Math.atan2(stage.stageHeight/2-target.y, target.stage.stageWidth/2-target.x);
var rot:Number = rad*180/Math.PI;
p.x = Math.cos(rad)*speed;
p.y = Math.sin(rad)*speed;
target.rotation = rot
return p
}
}
}
//
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;
class Sat extends Sprite{
public var mass:Number = 1;
public var speed:Point = new Point(1 * Math.random() - 0.5, 1 * Math.random() - 0.5);
public function Sat(){
var maxColor:int = 0xFFFFFF
graphics.beginFill(Math.floor(Math.random()*(maxColor/2)+(maxColor/2)))
graphics.drawRect(-5, -5, 10, 10)
graphics.endFill()
}
}
//class Circle
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Point;
class Circle extends Sprite{
private var _pos:Point = new Point()
private var _speed:Number
private var _radius:Number
private var _motion:CircleMotion;
private var _gravity:Number = 1
private var _targetRot:Number
private var _mass:Number;
private var _size:Number;
public function Circle(color:int,r:int, speed:Number, rad:Number):void{
_size = r;
_speed = speed
_radius = rad
//
var colors:Array = [color, 0]
var alphas:Array = [1, 1]
var ratios:Array = [0, 50]
graphics.beginGradientFill("radial", colors, alphas, ratios)
graphics.drawCircle(0,0,r)
graphics.endFill()
//
_motion = new CircleMotion(_speed, _radius)
}
public function gravity(target:Sprite):Point{
var p:Point = new Point()
var dist:Number = (this.x-target.x)*(this.x-target.x)+(this.y-target.y)*(this.y-target.y);
var rad:Number = Math.atan2(this.y-target.y, this.x-target.x);
var rot:Number = rad*180/Math.PI;
//・万有引力は距離の2乗に反比例する。
//・万有引力は2物体(Sat,Circle)の質量(mass)それぞれに比例する。
//・Satの加速度は万有引力に比例するがSatの質量に反比例するので、Satの質量は考えなくてよい。
//⇒Satの加速度はCircleの質量に比例させ、距離の2乗に反比例させればよい。
//(今回はその比例定数として_gravityを使いました。値は適当です)
var g:Number = _gravity * _mass / dist;
//詳しい証明は忘れましたが、半径より近づいた場合引力は(距離の3乗)/(星の半径の3乗)倍したものになると考えていいらしいです。
//(普通半径より近づけませんがw)
if(dist < _size * _size) {
var r:Number = Math.sqrt(dist);
g *= r * r * r / (_size * _size * _size)
}
p.x = Math.cos(rad)*g;
p.y = Math.sin(rad)*g;
_targetRot = rot;
return p
}
public function get motion():CircleMotion{
return _motion
}
public function set pos(p:Point):void{
_pos = p
}
public function get pos():Point{
return _pos
}
public function set speed(s:Number):void{
_speed = s
}
public function get speed():Number{
return _speed
}
public function set radius(r:Number):void{
_radius = r
}
public function get radius():Number{
return _radius
}
public function get targetRot():Number{
return _targetRot
}
public function get mass():Number{
return _mass;
}
public function set mass(value:Number):void{
_mass = value;
}
public function get size():Number{
return _size;
}
}
//class CircreMotion
import flash.geom.Point;
class CircleMotion{
private var _angle:Number;
private var _speed:Number;
private var _radius:Number;
private var _point:Point = new Point()
public function CircleMotion(speed:Number, rad:Number){
_speed = speed
_radius = rad
_angle = (Math.floor(Math.random()*18))*10
}
public function setPos(pos:Point):Point{
var radian:Number = _angle * Math.PI / 90;
_point.x = pos.x + _radius * Math.cos(radian);
_point.y = pos.y + _radius * Math.sin(radian);
_angle += _speed;
return _point
}
public function set speed(speed:Number):void{
_speed = speed;
}
public function get speed():Number{
return _speed;
}
public function set radius(rad:Number):void{
_radius = rad;
}
public function get radius():Number{
return _radius;
}
}
//class Base
import flash.display.Sprite
class Base extends Sprite{
public function Base(color:int,w:int,h:int):void{
graphics.beginFill(color, 1)
graphics.drawRect(0,0,w,h)
graphics.endFill()
}
}