forked from: forked from: マウスで彗星を飛ばして衛星軌道に乗せるアレ

by Koutarou
...
@author koutarou
♥0 | Line 229 | Modified 2009-05-17 09:21:48 | MIT License
play

ActionScript3 source code

/**
 * Copyright Koutarou ( http://wonderfl.net/user/Koutarou )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/6mBY
 */

// forked from sugoiyoowsamsan's forked from: マウスで彗星を飛ばして衛星軌道に乗せるアレ
// forked from naoto5959's マウスで彗星を飛ばして衛星軌道に乗せるアレ
package
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;

	/**
	 * ...
	 * @author koutarou
	 */
	[SWF(backgroundColor="0x0")]
	public class OrbitGame_Test1 extends Sprite
	{
                  //実際の比率で再現できそうもなかったからゲームが成立するよう調整
		private const EARTH_GRAVITY:Number = 98;
		private const MOON_GRAVITY:Number = EARTH_GRAVITY / 2;
		private const EARTH_MASS:Number = 20;
		private const MOON_MASS:Number = EARTH_MASS / 81;
		private const MOON_SIZE:Number = 10;
		private const EARTH_SIZE:Number = MOON_SIZE * 3.7;
		private const RADIUS:Number = 200;
		private const SATELLITE_SIZE:Number = 1;
		private const SATELLITE_MASS:Number = 0.01;
		
		private var posTemp:Point
		private var container:Sprite;
		private var starContainer:Sprite;
		private var earth:Earth;
		private var moon:Moon;
		public function OrbitGame_Test1() 
		{
			if (stage) {
				init();
				stage.addEventListener(MouseEvent.MOUSE_MOVE,mouseDownHandler);
				stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
				addEventListener(Event.ENTER_FRAME,loopHandler);
			}
		}
		private function init():void {
			container = new Sprite();
			container.x = stage.stageWidth / 2;
			container.y = stage.stageHeight / 2;
			addChild(container);
			starContainer = new Sprite();
			starContainer.x = stage.stageWidth / 2;
			starContainer.y = stage.stageHeight / 2;
			addChild(starContainer);
			earth = new Earth( {
				mass:EARTH_MASS,
				size:EARTH_SIZE 
			});
			container.addChild(earth);
			moon = new Moon( {
				mass:MOON_MASS,
				size:MOON_SIZE,
				radius:RADIUS
			});
			container.addChild(moon);
			var bmd:BitmapData = new BitmapData(3, 3, true, 0x00ffffff);
			bmd.setPixel32(0, 0, 0x22ffffff);
			var dot:Shape = new Shape();
			dot.graphics.beginBitmapFill(bmd);
			dot.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
			dot.graphics.endFill();
			addChild(dot);
		}
		private function mouseUpHandler(evt:MouseEvent):void {
			removeEventListener(Event.ENTER_FRAME,dragHandler);
			var vx:Number = (starContainer.mouseX - posTemp.x);
			var vy:Number = (starContainer.mouseY - posTemp.y);
			var star:Star = new Star( {
				mass:SATELLITE_MASS,
				color:0xffff99,
				size:SATELLITE_SIZE,
				x:starContainer.mouseX,
				y:starContainer.mouseY,
				vx:vx,
				vy:vy,
				visible:true
			});
			starContainer.addChild(star);
		}
		private function mouseDownHandler(e:Event):void {
			addEventListener(Event.ENTER_FRAME,dragHandler);
		}
		private function dragHandler(e:Event):void {
			posTemp = new Point(starContainer.mouseX,starContainer.mouseY);
		}
		private function loopHandler(e:Event):void {
			for (var i:int = 0; i < starContainer.numChildren; i++) {
				var star:Star = starContainer.getChildAt(i) as Star;
				var isCrash:Boolean = false;
				var earthDisX:Number = earth.x - star.x;
				var earthDisY:Number = earth.y - star.y;
				var earthDis:Number = Math.sqrt(earthDisX * earthDisX + earthDisY * earthDisY);
				var moonDisX:Number = moon.x - star.x;
				var moonDisY:Number = moon.y - star.y;
				var moonDis:Number = Math.sqrt(moonDisX * moonDisX + moonDisY * moonDisY);
				var earthGravity:Number = EARTH_GRAVITY * earth.mass * star.mass / earthDis/earthDis*10;
				var moonGravity:Number = MOON_GRAVITY * moon.mass * star.mass / moonDis/moonDis*10;
				var earthAx:Number = earthGravity * earthDisX / earthDis;
				var earthAy:Number = earthGravity * earthDisY / earthDis;
				var moonAx:Number = moonGravity * moonDisX / moonDis;
				var moonAy:Number = moonGravity * moonDisY / moonDis;
				star.vx += (earthAx + moonAx) / star.mass;
				star.vy += (earthAy + moonAy) / star.mass;
				star.x += star.vx;
				star.y += star.vy;
				if (earthDis <= star.size + earth.size) {
					star.visible = false;
					var spark:Spark = new Spark( { radian:Math.atan2(earthDisY, earthDisX)+Math.PI, offset:earth.size} );
					container.addChild(spark);
				}
				else if (moonDis <= star.size + moon.size) {
					star.visible = false;
				}
				if (!star.visible) {
					starContainer.removeChild(star);
				}
			}
		}
	}
	
}
import flash.display.BitmapData;
import flash.display.GradientType;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.GlowFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
class Star extends Sprite {
	public var mass:Number = 1;
	public var size:Number = 1;
	public var color:uint = 0;
	public var ax:Number = 0;
	public var ay:Number = 0;
	public var vx:Number = 0;
	public var vy:Number = 0;
	public function Star(initObject:Object=null) {
		init(initObject);
		graphics.beginFill(color);
		graphics.drawCircle(0, 0, size);
		graphics.endFill();
	}
//この初期化方法は知らなかったのでかなり参考になった
	protected function init(initObject:Object):void {
		if (!initObject) {
			return;
		}
		else {
			for (var property:String in initObject) {
				if (hasOwnProperty(property)) {
					this[property] = initObject[property];
				}
			}
		}
	}
}
class Earth extends Star {
	
	public function Earth(initObject:Object) {
		init(initObject);
		var bmd:BitmapData = new BitmapData(size * 2, size * 2, true, 0xffffffff);
		bmd.perlinNoise(size / 3, size / 4, 3, Math.random() * 0xff, true, true, 0, true);
		bmd.colorTransform(bmd.rect,new ColorTransform(1,1,1,1,0,45,222,0));
		graphics.beginBitmapFill(bmd);
		graphics.drawCircle(0, 0, size);
		graphics.endFill();
		filters = [new GlowFilter(0xffffcc,0.5,7,7)];
	}
}
class Moon extends Star {
	public var radian:Number = 0;
	public var radius:Number = 0;
	public function Moon(initObject:Object=null) {
		init(initObject);
		var mtx:Matrix = new Matrix();
		mtx.createGradientBox(size*2, size*2, 0, -size/4, -size);
		graphics.beginGradientFill(GradientType.RADIAL, [0xffff00, 0x666666], [1, 1], [255, 255], mtx);
		graphics.drawCircle(0, 0, size);
		graphics.endFill();
		radian = 360 * Math.PI / 180 * Math.random();
		x = radius * Math.cos(radian);
		y = radius * Math.sin(radian);
		addEventListener(Event.ENTER_FRAME,loopHandler);
	}
	private function loopHandler(evt:Event):void {
		radian += 5 * Math.PI / 180;
		x = radius * Math.cos(radian);
		y = radius * Math.sin(radian);
	}
}
//地球に落下したときのエフェクトを担当するクラス
class Spark extends Sprite {
	public var radian:Number = 0;
	public var offset:Number = 0;
	public function Spark(initObject:Object) {
		init(initObject);
		x = offset * Math.cos(radian);
		y = offset * Math.sin(radian);
		for (var i:int = 0; i < 20; i++) {
			var eachRadian:Number = Math.random() * Math.PI / 8 - Math.PI / 16 + radian;
			var dist:Number = Math.random() * 2;
			addChild(new Star( { color:0x999999, ax:dist * Math.cos(eachRadian), ay:dist * Math.sin(eachRadian) } ));
		}
		addEventListener(Event.ENTER_FRAME,loopHandler);
	}
	private function loopHandler(evt:Event):void {
		for (var i:int = 0; i < numChildren; i++) {
			var star:Star = getChildAt(i) as Star;
			star.vx += star.ax;
			star.vy += star.ay;
			star.x += star.vx;
			star.y += star.vy;
			star.alpha += -(star.alpha * 0.3);
			if (star.alpha < 0) {
				removeEventListener(evt.type, arguments.callee);
				for (var j:int = 0; j < numChildren; j++) {
					removeChildAt(i);
				}
			}
		}
	}
	private function init(initObject:Object):void {
		if (!initObject) {
			return;
		}
		else {
			for (var property:String in initObject) {
				if (hasOwnProperty(property)) {
					this[property] = initObject[property];
				}
			}
		}
	}
}