太陽系を通過せよ!改
2010.08.04 スコアランキングを追加しました。
ゴールまで到達するとランキング登録できます。
航続距離が長い方がランキング上位となります。
「太陽系を通過せよ!」の改良版です。
画面をクリックするとスタートし、宇宙船が太陽系を斜めに横切り始めます。
加速・減速・速度維持のコントロールを左下のセレクタで変更しながら
惑星の引力にを避けてゴールを目指しましょう。
惑星の引力に負けると惑星に墜落。
逆に引力を利用して他の惑星の引力から逃れたり、加速したりすることもできます。
それにしてもこのコンテンツ、もう少しなんとかならないのか?
改良してもやっぱり無理ゲーだし…
ラストのパーティクルのクラスDropは http://wonderfl.net/c/h1P2 を
参考にさせていただきました。
/**
* Copyright mousepancyo ( http://wonderfl.net/user/mousepancyo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/eNfT
*/
/*
2010.08.04 スコアランキングを追加しました。
ゴールまで到達するとランキング登録できます。
航続距離が長い方がランキング上位となります。
*/
/*
「太陽系を通過せよ!」の改良版です。
画面をクリックするとスタートし、宇宙船が太陽系を斜めに横切り始めます。
加速・減速・速度維持のコントロールを左下のセレクタで変更しながら
惑星の引力にを避けてゴールを目指しましょう。
惑星の引力に負けると惑星に墜落。
逆に引力を利用して他の惑星の引力から逃れたり、加速したりすることもできます。
それにしてもこのコンテンツ、もう少しなんとかならないのか?
改良してもやっぱり無理ゲーだし…
ラストのパーティクルのクラスDropは http://wonderfl.net/c/h1P2 を
参考にさせていただきました。
*/
package{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.display.Shape;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import com.bit101.components.*;
[SWF(width=465, height=465, backgroundColor=0,frameRate=30)]
public class Main extends Sprite{
private var _circleList:Vector.<Circle> = new Vector.<Circle>()
private var _motionList:Vector.<CircleMotion> = new Vector.<CircleMotion>()
private var _ship:Ship;
private var _shipSpeed:Number
private var _tracer:Shape = new Shape();
private var _msg:TextField = new TextField();
private var _fmt:TextFormat = new TextFormat("_typewriter", 14, 0xFFFFFF, true, false, false, null, null, "center", null, null, null, 2);
//
private const _sizeList:Vector.<int> = Vector.<int>([3, 4, 6, 4, 16, 18, 12, 10]);
private const _speedList:Vector.<Number> = Vector.<Number>([4.166,1.64,1,0.53,0.084,0.034,0.012,0.0061]);
private const _radList:Vector.<int> = Vector.<int>([30, 50, 75, 100, 125, 160, 190,220]);
private const _gravityList:Vector.<int> = Vector.<int>([80, 100, 160, 100, 320, 460, 240, 200]);
private const _circleColorList:Vector.<int> = Vector.<int>([0xB3B0B8, 0xADA224, 0x2DD0AB, 0xB34D0C, 0x907853, 0xA08B14, 0x83AAD7, 0x2D7DB8]);
private const _deceleration:Number = 0.3;
private const _incidence:int = 1000;
private var _distnce:Number;
private var _oldPoint:Point;
private var _meter:Meter;
private var _selector:RotarySelector;
private var _light:IndicatorLight;
private var _label:Label
private var _drop:Drop;
private var _scoreBoard:ScoreAPI
public function Main(){
init();
}
private function init():void{
var base:Base = new Base(0, stage.stageWidth, stage.stageHeight)
addChild(base)
var start_tx:TextField = new TextField()
var goal_tx:TextField = new TextField()
start_tx.defaultTextFormat = _fmt
goal_tx.defaultTextFormat = _fmt
start_tx.autoSize = "left"
goal_tx.autoSize = "right"
start_tx.text = "[Start]"
goal_tx.text = "[Goal]"
goal_tx.x = stage.stageWidth-goal_tx.width
goal_tx.y = stage.stageHeight-goal_tx.height
addChild(start_tx)
addChild(goal_tx)
//
for(var i:int=0; i<_sizeList.length; i++){
var col:int = 0x303030
createPlanet(_circleColorList[i], _sizeList[i], _speedList[i]*_deceleration, _radList[i], _gravityList[i])
_circleList[i].addEventListener(Event.ENTER_FRAME, update)
base.graphics.lineStyle(1, col, 1, true, "normal",null, null, 1)
base.graphics.drawCircle(stage.stageWidth/2, stage.stageHeight/2, _radList[i])
}
createMoon()
createRing()
//
_msg.defaultTextFormat = _fmt
_msg.selectable = false
_msg.width = stage.stageWidth
_msg.y = 350
_msg.autoSize = "center"
_msg.text = "惑星の引力に捕まらないように太陽系を通り抜けろ\nPlease avoid getting caught in\nthe solar system through gravitational.\n\nステージクリックでスタート\nClick on the Start Stage."
addChild(_msg)
//
_meter = new Meter(this, 320, 5, "SHIP SPEED");
_meter.minimum = 0;
_meter.maximum = 3;
_meter.value = 0;
_meter.scaleX = 0.7
_meter.scaleY = 0.7
_meter.alpha = 0.5
_meter.blendMode = "add"
_meter.visible = false
//
_selector = new RotarySelector(this, 20, 385, "Speed Selector", selectorClick);
_selector.labelMode = RotarySelector.NUMERIC;
_selector.numChoices = 3;
_selector.alpha = 0.8
_selector.visible = false
//
_light = new IndicatorLight(this, _meter.x+(_meter.width/4.5), _meter.y+(_meter.height/2), 0xFF0000, "Caution!");
_light.visible = false
//
_label = new Label(null, 40, 405, "");
addChild(_label);
_label.visible = false;
//
addChild(_tracer)
stage.addEventListener(MouseEvent.CLICK, shipStart)
//
_scoreBoard = new ScoreAPI(stage)
}
private function shipStart(e:MouseEvent):void{
_ship = new Ship()
addChild(_ship)
_ship.addEventListener(Event.ENTER_FRAME, shipUpdate)
_shipSpeed = 0.5
_tracer.graphics.clear()
_tracer.graphics.lineStyle(1, 0x33FF66, 0.5)
_tracer.graphics.moveTo(_ship.x, _ship.y)
stage.removeEventListener(MouseEvent.CLICK, shipStart)
for(var i:int=0; i<_circleList.length; i++){
_circleList[i].addEventListener(Circle.CRASH, crashCheck)
}
_msg.text = "左のセレクタの番号をクリックして速度チェンジ\n1:減速 2:速度維持 3:加速\n\nSpeed change selector on the left\n1:Down 2:Maintenance 3:Up"
//
_distnce = 0
_oldPoint = new Point()
_meter.visible = true
_selector.visible = true
_selector.choice = 1
_light.visible = true
_light.isLit = false;
_label.visible = true;
_label.text = ""
//
if(_drop != null) {
try{
_drop.stopDrop()
}catch(e:Error){
}
}
}
private function selectorClick(e:Event):void{
var n:Number = e.currentTarget.choice
switch(n){
case 0:
addEventListener(Event.ENTER_FRAME, speedDown)
removeEventListener(Event.ENTER_FRAME, speedUp)
break;
case 1:
removeEventListener(Event.ENTER_FRAME, speedUp)
removeEventListener(Event.ENTER_FRAME, speedDown)
break;
case 2:
addEventListener(Event.ENTER_FRAME, speedUp)
removeEventListener(Event.ENTER_FRAME, speedDown)
break;
}
}
private function speedUp(e:Event):void{
if(_shipSpeed < 3){
if(_shipSpeed < 0.3) _shipSpeed = 0.3
if(_shipSpeed > 2){
_light.isLit = true;
}else{
_light.isLit = false;
}
_shipSpeed = _shipSpeed * 1.01
}else{
_shipSpeed = 0.3
}
//_meter.value = _shipSpeed
}
private function speedDown(e:Event):void{
if(_shipSpeed > 0.01){
_shipSpeed = _shipSpeed / 1.02
if(_shipSpeed > 2){
_light.isLit = true;
}else{
_light.isLit = false;
}
}else{
_shipSpeed = 0
}
//_meter.value = _shipSpeed
}
private function createPlanet(color:int, size:int, speed:Number, rad:Number, grav:int):void{
var circle:Circle = new Circle(color, size, speed, rad, grav)
_circleList.push(circle)
circle.x = stage.stageWidth/2
circle.y = stage.stageHeight/2
circle.pos = new Point(circle.x, circle.y)
addChild(circle)
}
private function createMoon():void{
var moon:Circle = new Circle(0xB9D7EC, 2, 13.18*_deceleration, 9, 0)
moon.x = 0
moon.y = 0
moon.pos = new Point(moon.x, moon.y)
_circleList[2].addChild(moon)
moon.addEventListener(Event.ENTER_FRAME, update)
}
private function createRing():void{
_circleList[5]._shape.graphics.lineStyle(1,0xFFE7BE, 0.5)
_circleList[5]._shape.graphics.drawCircle(0,0,20)
_circleList[5]._shape.graphics.lineStyle(2,0xFFE7BE, 0.2)
_circleList[5]._shape.graphics.drawCircle(0,0,22)
_circleList[5]._shape.graphics.lineStyle(1,0xFFE7BE, 0.3)
_circleList[5]._shape.graphics.drawCircle(0,0,24)
}
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
}
private function crashCheck(e:Event):void{
for(var i:int=0; i<_circleList.length; i++){
_circleList[i].removeEventListener(Circle.CRASH, crashCheck)
}
_ship.visible = false
}
private function shipUpdate(e:Event):void{
if(_ship.visible){
var point:Point = new Point()
for(var i:int=0; i<_circleList.length; i++){
var p:Point = _circleList[i].gravity(_ship)
point.x += p.x
point.y += p.y
}
p = null
p = shipMove(_ship ,_shipSpeed)
point.x += p.x
point.y += p.y
_ship.x += point.x
_ship.y += point.y
_distnce += Math.sqrt((_ship.x-_oldPoint.x)*(_ship.x-_oldPoint.x)+(_ship.y-_oldPoint.y)*(_ship.y-_oldPoint.y));
_oldPoint.x = _ship.x
_oldPoint.y = _ship.y
_label.text = Math.round(_distnce).toString()
//
_tracer.graphics.lineTo(_ship.x, _ship.y)
//
_meter.value = _shipSpeed;
//
if(_ship.x >= stage.stageWidth && _ship.y >= stage.stageHeight){
_ship.removeEventListener(Event.ENTER_FRAME, shipUpdate)
removeChild(_ship)
_ship = null
_msg.text = "作戦成功!航続距離 "+_label.text+" で無事太陽系を抜けました!\nOperation successful!\nSolar system passed through a "+_label.text+" range! \n\nステージクリックで再スタートできます\nClick on the Restart Stage."
_meter.visible = false
_selector.visible = false
_light.visible = false
_label.visible = false;
//
_drop = new Drop(stage.stageWidth, stage.stageHeight)
_drop.blendMode = "screen"
_drop.mouseEnabled = false
addChild(_drop)
_drop.startDrop()
//
addScore(int(_label.text))
}
}else{
for(i=0; i<_circleList.length; i++){
_circleList[i].graphicsClear()
}
perticle()
_ship.removeEventListener(Event.ENTER_FRAME, shipUpdate)
removeChild(_ship)
_ship = null
stage.addEventListener(MouseEvent.CLICK, shipStart)
_msg.text = "惑星の引力に引き込まれました\nWas drawn into the planet's gravitational pull\n\nステージクリックで再スタート\nClick on the Restart Stage."
_meter.visible = false
_selector.visible = false
_light.visible = false
_label.visible = false;
}
}
private function shipMove(target:Sprite ,speed:Number):Point{
var p:Point = new Point()
var rad:Number = Math.atan2(stage.stageHeight-target.y, target.stage.stageWidth-target.x);
var rot:Number = rad*180/Math.PI;
p.x = Math.cos(rot*Math.PI/180)*speed
p.y = Math.sin(rot*Math.PI/180)*speed
target.rotation = -rot
return p
}
private function perticle():void{
for(var i:int=0; i<_incidence; i++){
var size:int = Math.floor(Math.random()*4+1)
var speed:Number = Math.random()*29+1
var dust:Dust = new Dust(size/2, speed)
addChild(dust)
dust.x = _ship.x
dust.y = _ship.y
dust.cacheAsBitmap = true
dust.addEventListener(Event.ENTER_FRAME, dust.bomb)
dust.addEventListener(Dust.LIFE_END, removed)
}
}
private function removed(e:Event):void{
e.target.removeEventListener(Event.ENTER_FRAME, e.target.bomb)
e.target.removeEventListener(Dust.LIFE_END, removed)
removeChild(e.target as Dust)
}
private function addScore(score:int):void{
_scoreBoard.showScoreForm(score)
_scoreBoard.addEventListener(ScoreAPI.CLOSED, rankingClosed)
}
private function rankingClosed(e:Event):void{
_scoreBoard.removeEventListener(ScoreAPI.CLOSED, rankingClosed)
stage.addEventListener(MouseEvent.CLICK, shipStart)
}
}
}
//class Circle
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.events.Event;
import flash.display.Shape;
class Circle extends Sprite{
public var _shape:Shape = new Shape()
private var _pos:Point = new Point()
private var _speed:Number
private var _radius:Number
private var _motion:CircleMotion;
private var _gravity:int
private var _gravityArea:int
public static const CRASH:String = "crash"
public function Circle(color:int,r:int, speed:Number, rad:Number, gravity:int):void{
_speed = speed
_radius = rad
_gravity = gravity
_gravityArea = r*10
//
var colors:Array = [color, 0]
var alphas:Array = [1, 1]
var ratios:Array = [0, 50]
addChild(_shape)
_shape.graphics.beginGradientFill("radial", colors, alphas, ratios)
_shape.graphics.drawCircle(0,0,r)
_shape.graphics.endFill()
//
_motion = new CircleMotion(_speed, _radius)
}
public function gravity(target:Sprite):Point{
var p:Point = new Point()
var dist:Number = Math.sqrt((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;
if(dist < _gravityArea){
p.x = Math.cos(rot*Math.PI/180)*_gravity/dist/10
p.y = Math.sin(rot*Math.PI/180)*_gravity/dist/10
graphics.clear()
graphics.lineStyle(0,0xFF0000, 0.4)
graphics.moveTo(0, 0)
graphics.lineTo(target.x-this.x, target.y-this.y)
}else{
graphics.clear()
p.x = 0
p.y = 0
}
if(target.hitTestPoint(this.x, this.y, true)){
dispatchEvent(new Event(Circle.CRASH))
return new Point(0, 0)
}else{
return p
}
}
public function graphicsClear():void{
graphics.clear()
}
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
}
}
//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 Ship
import flash.display.Sprite;
class Ship extends Sprite{
public function Ship(){
graphics.beginFill(0x33FF66)
graphics.moveTo(-5,-5)
graphics.lineTo(0,-2)
graphics.lineTo(5,-5)
graphics.lineTo(0,7)
graphics.lineTo(-5,-5)
graphics.endFill()
}
}
//Class Dust
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.geom.ColorTransform;
class Dust extends Sprite{
private var _size:int
private var _speed:Number
private var _life:uint = 15
private var _rot:Number
public static const COLOR:int = 0xFFFFFF
public static const LIFE_END:String = "life_end"
public function Dust(size:int, speed:Number){
graphics.beginFill(COLOR)
graphics.drawCircle(0,0,size)
graphics.endFill()
_speed = speed
_size = size
_rot = Math.random()*360
}
public function bomb(e:Event):void{
e.target.x += Math.cos(_rot*Math.PI/180)*_speed
e.target.y += Math.sin(_rot*Math.PI/180)*_speed
//
_rot-=3
_life--
if(_life==0){
e.target.addEventListener(Event.ENTER_FRAME, death)
}
}
private function death(e:Event):void{
if(e.target.scaleX >= 0){
e.target.scaleX-=0.01
e.target.scaleY-=0.01
}else{
e.target.removeEventListener(Event.ENTER_FRAME, bomb)
e.target.removeEventListener(Event.ENTER_FRAME, death)
dispatchEvent(new Event(Dust.LIFE_END))
}
}
}
//Class Drop
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.filters.GlowFilter;
import flash.geom.ColorTransform;
import flash.geom.Point;
import flash.geom.Rectangle;
class Drop extends Sprite{
private var _starList:Vector.<Star>
private var _bmd:BitmapData;
private var _circle:BitmapData;
private var _bm:Bitmap;
private var _ctransform:ColorTransform = new ColorTransform(0.9, 0.9, 0.9);
private var _w:Number
private var _h:Number
private var _g:Number
public function Drop(W:Number, H:Number){
_w = W
_h = H
_g = Math.random() * 0.03 + 0.005
//
var shape:Shape = new Shape();
shape.graphics.beginFill(0x66FFDD);
shape.graphics.drawCircle(6, 6, 1);
shape.graphics.endFill();
//
_circle = new BitmapData(12, 12, true, 0);
_circle.draw(shape);
_circle.applyFilter(_circle, _circle.rect, new Point(), new GlowFilter(0xFFFFFF));
}
public function startDrop():void{
_starList = new Vector.<Star>();
_bmd = new BitmapData(_w, _h, false, 0)
_bm = new Bitmap(_bmd)
addChild(_bm);
addEventListener(Event.ENTER_FRAME, update);
}
public function stopDrop():void{
if(_bmd){
removeEventListener(Event.ENTER_FRAME, update);
removeChild(_bm);
_bmd.dispose()
}
}
public function update(e:Event):void{
var star:Star = new Star();
star.x = _w/2
star.y = 0
star.vx = Math.random() * 18-9;
star.vy = Math.random() * 5;
_starList.push(star);
_bmd.colorTransform(_bmd.rect, _ctransform);
//
for (var i:int = 0; i < _starList.length; i++){
star = _starList[i];
star.x += star.vx;
star.y += star.vy + star.y * _g;
_bmd.copyPixels(_circle, _circle.rect, new Point(star.x, star.y), null, null, true);
if (star.x >= _w || star.y >= _h){
_starList.splice(i--, 1);
}
}
}
}
//class Star
import flash.display.Shape;
class Star extends Shape{
private var _vx:Number;
private var _vy:Number;
//
public function set vx(n:Number):void{
_vx = n
}
public function set vy(n:Number):void{
_vy = n
}
public function get vx():Number{
return _vx
}
public function get vy():Number{
return _vy
}
}
//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()
}
}
//class ScoreAPI
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.display.DisplayObjectContainer;
import flash.display.Stage;
import flash.utils.Timer;
import com.bit101.components.Component;
import com.bit101.components.PushButton;
import net.wonderfl.score.basic.BasicScoreForm;
import net.wonderfl.score.basic.BasicScoreRecordViewer;
class ScoreAPI extends EventDispatcher {;
private var _form:BasicScoreForm;
private var _ranking:BasicScoreRecordViewer
private var _stage:Stage
private var _timer:Timer
public static const CLOSED:String = "closed"
public function ScoreAPI(target:Stage) {
_stage = target
Component.initStage(_stage);
}
public function showScoreForm(score:int):void{
_form = new BasicScoreForm(_stage, (465-BasicScoreForm.WIDTH)/2, (465-BasicScoreForm.HEIGHT)/2, score, 'SAVE SCORE', showRanking);
}
private function showRanking($didSavedScore:Boolean):void {
//removes form
_stage.removeChild(_form);
//
_ranking = new BasicScoreRecordViewer(_stage, (465-BasicScoreRecordViewer.WIDTH)/2,(465-BasicScoreRecordViewer.HEIGHT)/2,'RANKING', 99, true, onClosed);
}
private function onClosed():void{
_stage.removeChild(_ranking)
//
_timer = new Timer(300, 1)
_timer.addEventListener(TimerEvent.TIMER_COMPLETE, timerComplete)
_timer.start()
}
private function timerComplete(e:TimerEvent):void{
_timer.removeEventListener(TimerEvent.TIMER_COMPLETE, timerComplete)
_timer = null
dispatchEvent(new Event(ScoreAPI.CLOSED))
}
}