forked from: colin challenge for professionals ブラックホール
forked from colin challenge for professionals (diff: 676)
制限時間内に玉を集めて高得点をねらいます。 * 青が10点、黄色が20点、白が50点です。 * * 中央のNEWを押すとスタートします。 * * 玉の位置の同期や、スコアの同期がいまいちうまく行かなかったので、 * 対戦ゲーム的なものにはできませんでした。 同時接続した人はジャマする役になります。 * * はいタイムアップ。
ActionScript3 source code
/**
* Copyright whirlpower ( http://wonderfl.net/user/whirlpower )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/3E1Y
*/
/*
* 制限時間内に玉を集めて高得点をねらいます。
* 青が10点、黄色が20点、白が50点です。
*
* 中央のNEWを押すとスタートします。
*
* 玉の位置の同期や、スコアの同期がいまいちうまく行かなかったので、
* 対戦ゲーム的なものにはできませんでした。 同時接続した人はジャマする役になります。
*
* はいタイムアップ。
*/
package
{
import flash.display.Sprite;
import net.user1.reactor.*;
import net.user1.logger.Logger;
import flash.events.Event;
import flash.display.BlendMode;
import flash.events.MouseEvent;
import caurina.transitions.Tweener;
[SWF(width = "465", height = "465", backgroundColor = "0x000000", frameRate = "60")]
// メインクラス
public class UnionRamen extends Sprite
{
// Union用オブジェクト
protected var reactor :Reactor;
protected var ramenRoom :Room;
// ゲーム用
private var balls /*Ball*/:Array = [];
private var gravitys /*GravityBall*/:Array = [];
private var gravity :GravityBall;
private var ballMax :int = 50;
private var dotNew :DotNew;
// コンストラクタ
public function UnionRamen():void
{
trace( "UnionRamen" );
reactor = new Reactor();// 接続用のReactorオブジェクトを作成
reactor.addEventListener(ReactorEvent.READY, readyListener); // 接続完了したら readyListener() を起動
// Unionに接続。
reactor.connect("tryunion.com", 9100); // "tryunion.com:9100"は自由に使えるUnionテスト用の公開サーバーです
reactor.getLog().setLevel(Logger.DEBUG);
}
// 接続完了時に起動されるメソッド
protected function readyListener (e:ReactorEvent):void
{
// このアプリ用のルームを作成
ramenRoom = reactor.getRoomManager().createRoom( "wonderfl.whirlPowerRoom" ); // あなたのアプリ専用のIDを使ってください
// プレイヤーの参加 メッセージ受け取り
ramenRoom.addMessageListener("NEW_PLAYER", newPlayerLisner ); // 新しいプレイヤーの追加
ramenRoom.addMessageListener("CHANGE_POSITION", onGestPosition); // その他のプレイヤーの位置変更を受け取
ramenRoom.addMessageListener("DELETE_POSITION", onGestDelete); // その他のプレイヤーの位置変更を受け取る
ramenRoom.join(); // ルームに入室
gameInit();
}
// メッセージをうけとって、表示位置を変更する。
private function onGestPosition( from:IClient,data:String ):void
{
var str :/*String*/Array = data.split(",");
var id :Number = Number( str[0] );
var posX :Number = Number( str[1] );
var posY :Number = Number( str[2] );
var g:GravityBall = getGravityById( id );
if ( !g ) return;
g.x = posX;
g.y = posY;
}
// メッセージをうけとって、重力源を削除する。
private function onGestDelete( from:IClient,data:String ):void
{
var str :/*String*/Array = data.split(",");
var id :Number = Number( str[0] );
var newArray :Array = [];
var leng:int = gravitys.length;
for (var i:int = 0; i < leng; i++)
{
if ( gravitys[i].id == id )
{
removeChild( gravitys[i] );
}
else
{
newArray.push( gravitys[i] );
}
}
gravitys = newArray;
}
// 入力のIDの重力源を取得する
private function getGravityById( id:Number ):GravityBall
{
var leng:int = gravitys.length;
for (var i:int = 0; i < leng; i++)
if ( gravitys[i].id == id )
return gravitys[i];
return null;
}
// メッセージをうけとって、新規に重力源を取得する
private function newPlayerLisner( from:IClient,data:String ):void
{
var str :/*String*/Array = data.split(",");
var id :Number = Number( str[0] );
var color :Number = Number( str[1] );
var posX :Number = Number( str[2] );
var posY :Number = Number( str[3] );
//trace( "new Player id = " + id + "color = " + color + "posX = " + posX + "posY = " + posY );
// 重力源を作る
var _gravity:GravityBall = createGravity( id, color, 4, 100, 3 );
_gravity.x = posX;
_gravity.y = posY;
}
// NEWボタンが押されたとき、自分の重力源をつくる。
private function newClick( evt:MouseEvent ):void
{
if ( gravity )
{
removeChild( gravity );
}
// 重力源を作る
gravity = createGravity( Math.random(), Math.random() * 0xFFFFFF, 4, 100, 3 );
gravity.addEventListener( GravityBall.DEAD, myGrvityisDead );
// メッセージ送信 sendMessage( メッセージ名, 自分自身も受信するかどうか, フィルター )
ramenRoom.sendMessage( "NEW_PLAYER", false, null, String( gravity.id +", " + gravity.color + ","+ gravity.x + "," + gravity.y ) );
dotNew.visible = false;
}
// 重力源を生成する
private function createGravity( id:Number, color:uint, radius:Number, area:int, mass:int ):GravityBall
{
var _gravity:GravityBall = new GravityBall( id, color, radius, area );
_gravity.x = stage.stageWidth / 2;
_gravity.y = stage.stageHeight / 2;
_gravity.mass = mass; // 引力
addChild( _gravity );
gravitys.push( _gravity );
return _gravity;
}
// ステージをクリックで場所を移動
private function onClick( evt:MouseEvent ):void
{
if( gravity )
{
gravity.x = mouseX;
gravity.y = mouseY;
}
// メッセージ送信 sendMessage( メッセージ名, 自分自身も受信するかどうか, フィルター )
ramenRoom.sendMessage("CHANGE_POSITION", false, null, String( gravity.id +","+ gravity.x + "," + gravity.y ) );
}
// 自分の重力源が死亡
private function myGrvityisDead( evt:Event ):void
{
dotNew.visible = true;
ramenRoom.sendMessage( "DELETE_POSITION", false, null, String( gravity.id ) );
}
// ゲームの初期化
private function gameInit():void
{
for (var i:uint = 0; i < 3000; i++)
{
createBall();
}
// new
dotNew = new DotNew( 0xFFFFFF, 1 );
addChild( dotNew );
dotNew.x = int( stage.stageWidth/2 - dotNew.width / 2 );
dotNew.y = int( stage.stageHeight * 0.5 );
dotNew.addEventListener( MouseEvent.CLICK, newClick );
addEventListener( Event.ENTER_FRAME, loop);
stage.addEventListener( MouseEvent.CLICK, onClick );
}
private var count:uint = 0;
// エンターフレーム
private function loop( evt:Event ):void
{
var ball:Ball;
var gravity:GravityBall;
// ボールの挙動
for each( ball in balls )
{
ball.next();
// 画面の端っこの衝突判定
if ( ball.x < 0 )
{
ball.x = 0;
ball.vx *= -1;
}
if( ball.x > stage.stageWidth )
{
ball.x = stage.stageWidth;
ball.vx *= -1;
}
if ( ball.y < 0 )
{
ball.y = 0;
ball.vy *= -1;
}
if( ball.y > stage.stageHeight )
{
ball.y = stage.stageHeight;
ball.vy *= -1;
}
}
// 引力の影響
for each( gravity in gravitys )
{
var newArray:Array = [];
for each( ball in balls )
{
// 引力計算
if ( gravity.inArea( ball ) )
{
gravitate( gravity, ball );
}
// 吸収判定と配列の作り直し
if ( !gravity.isEat( ball ) )
{
newArray.push( ball )
}
else
{
removeChild( ball );
}
}
balls = newArray;
}
// ボールを追加する
createBall();
}
// 玉を生成する
private function createBall():void
{
count ++;
if ( count % 600 == 0 && balls.length < ballMax )
{
newBall( 0xFFFFFF, 3, 50 );
}
if ( count % 300 == 0 && balls.length < ballMax )
{
newBall( 0xFFEE33, 2, 20 );
}
if ( count % 30 == 0 && balls.length < ballMax )
{
newBall( 0x5577EE, 2, 10 );
}
}
private function newBall( color:uint, radius:Number = 2, score:int = 10 ):void
{
var ball:Ball = new Ball( color, radius );
ball.x = Math.random() * stage.stageWidth;
ball.y = Math.random() * stage.stageHeight;
ball.vx = Math.random() * 10 - 5;
ball.vy = Math.random() * 10 - 5;
ball.mass = 3;
ball.score = score;
ball.blendMode = BlendMode.ADD;
addChildAt( ball, 0 );
balls.push(ball);
}
//引力の計算
private function gravitate( ballA:Ball, ballB:Ball ):void
{
var dx :Number = ballB.x - ballA.x;
var dy :Number = ballB.y - ballA.y;
var dist :Number = Math.sqrt( dx * dx + dy * dy );
var force :Number = ballA.mass * ballB.mass / dist*2;
var ax :Number = force * dx / dist;
var ay :Number = force * dy / dist;
ballA.vx += ax / ballA.mass;
ballA.vy += ay / ballA.mass;
ballB.vx -= ax / ballB.mass;
ballB.vy -= ay / ballB.mass;
}
}
}
import flash.display.Shape;
import flash.display.Sprite;
// 吸い込まれるボール ------------------------------------------------------
internal class Ball extends Sprite
{
public var core :Shape = new Shape();
public var vx :Number = 0;
public var vy :Number = 0;
public var radius :Number = 10;
public var mass :Number = 10;
public var friction :Number = 0.998;
public var dead :Boolean = false;
public var score :int = 10;
public function Ball( color:uint, radius:Number ):void
{
this.radius = radius;
core.graphics.beginFill( color, 1 );
core.graphics.drawCircle( 0, 0, radius );
core.graphics.endFill();
addChild( core );
}
public function next():void
{
x += vx;
y += vy;
vx *= friction;
vy *= friction;
}
}
import caurina.transitions.Tweener;
import flash.utils.Timer;
import flash.events.Event;
// 吸い込むボール ------------------------------------------------------
internal class GravityBall extends Ball
{
public var id :Number = 0;
public var color :int = 0;
public var ring :Shape = new Shape();
public var area :Number = 10;
public var myScore :int = 0;
private var dotScore :DotScore;
private var timer :Timer;
private var dotTimer :DotScore;
private var life :int = 10;
public static const DEAD:String = "dead";
public function GravityBall( id:Number, color:int, radius:Number, area:Number ):void
{
super( color, radius );
this.area = area;
this.color = color
this.id = id;
mouseEnabled = false;
mouseChildren = false;
// スコアの表示
dotScore = new DotScore( 0xFFFFFF, 4, 1 );
dotScore.score = myScore;
addChild( dotScore );
dotScore.x = int( -dotScore.width / 2 );
dotScore.y = int( radius + 2 );
// 吸引範囲の表示
ring.graphics.beginFill( 0xFFFFFF, 0.15 );
ring.graphics.drawCircle( 0, 0, 10 );
ring.graphics.endFill();
addChild( ring );
Tweener.addTween( ring, { scaleX:area * 0.1, scaleY:area * 0.1, time:0.5, transition:"easeOutSine" } );
// タイマー
timer = new Timer( 1000, 0 );
timer.addEventListener( "timer", onTimerCount );
timer.start();
dotTimer = new DotScore( 0xFFFFFF, 2, 1 );
dotTimer.score = life;
addChild( dotTimer );
dotTimer.x = int( -dotTimer.width / 2 );
dotTimer.y = int( -radius - 2 -dotTimer.height );
}
public function onTimerCount( evt:Event ):void
{
life -= 1;
dotTimer.score = life;
if ( life <= 0 )
{
dispatchEvent( new Event( DEAD ) );
timer.stop();
Tweener.addTween( ring, { scaleX:0, scaleY:0, time:0.5, transition:"easeOutSine" } );
}
}
public function isEat( ball:Ball ):Boolean
{
// 寿命が尽きていたら処理しない
if ( !life ) return false;
if ( radius > dist( ball ) )
{
myScore += ball.score;
dotScore.score = myScore;
return true;
}
return false;
}
public function inArea( ball:Ball ):Boolean
{
// 寿命が尽きていたら処理しない
if ( !life ) return false;
if ( dist( ball ) < area )
{
return true;
}
return false;
}
public function dist( ball:Ball ):Number
{
var dx:Number = x -ball.x;
var dy:Number = y -ball.y;
return Math.sqrt( dx * dx + dy * dy );
}
}
// ドット数字のスコアのグラフィック ------------------------------------------------------
internal class DotScore extends Shape
{
private var maxCount :int = 1;
private var padding :int = 1;
private var dotSize :int = 2;
private var color :int = 0x000000;
private var currentX :int = 0;
private var _score:int = 0;
public function set score( v:int ):void
{
if ( v >= maxCount ) return;
draw( v );
}
public function get score():int { return _score; }
public function DotScore( color:uint, padding:int, dotSize:int = 2 )
{
this.padding = padding;
this.dotSize = dotSize;
this.color = color;
setGraphic();
for (var i:int = 0; i < padding; i++)
maxCount *= 10;
}
private function draw( num:int ):void
{
graphics.clear();
currentX = 0;
var numList:Array = [];
var tempNum:int = num;
var i:int = 0;
// 入力の数字を解体する
for ( i = 0; i < padding; i++ )
{
var drawNum:int = tempNum % 10;
numList.push( drawNum );
tempNum = int( tempNum * 0.1 );
}
// 描画する
for ( i = numList.length-1; i >= 0; i-- )
{
drawGraph( numList[i] );
}
}
private function drawGraph( num:int ):void
{
var dot:Array = dotNumData[num];
for (var i:int = 0; i < 3; i++) // 横
{
for (var j:int = 0; j < 5; j++) // 縦
{
if ( dot[j][i] )
{
graphics.beginFill( color, 1 );
graphics.drawRect( currentX + i*dotSize, j*dotSize, dotSize, dotSize );
graphics.endFill();
}
}
}
currentX += dotSize * 4;
}
private var dotNumData /*Array*/:Array = [];
private function setGraphic():void
{
var array:Array;
// 0
array = [
[ 1, 1, 1 ],
[ 1, 0, 1 ],
[ 1, 0, 1 ],
[ 1, 0, 1 ],
[ 1, 1, 1 ]
]
dotNumData.push( array );
// 1
array = [
[ 1, 1, 0 ],
[ 0, 1, 0 ],
[ 0, 1, 0 ],
[ 0, 1, 0 ],
[ 0, 1, 0 ]
]
dotNumData.push( array );
// 2
array = [
[ 1, 1, 1 ],
[ 0, 0, 1 ],
[ 1, 1, 1 ],
[ 1, 0, 0 ],
[ 1, 1, 1 ]
]
dotNumData.push( array );
// 3
array = [
[ 1, 1, 1 ],
[ 0, 0, 1 ],
[ 1, 1, 1 ],
[ 0, 0, 1 ],
[ 1, 1, 1 ]
]
dotNumData.push( array );
// 4
array = [
[ 1, 0, 1 ],
[ 1, 0, 1 ],
[ 1, 1, 1 ],
[ 0, 0, 1 ],
[ 0, 0, 1 ]
]
dotNumData.push( array );
// 5
array = [
[ 1, 1, 1 ],
[ 1, 0, 0 ],
[ 1, 1, 1 ],
[ 0, 0, 1 ],
[ 1, 1, 1 ]
]
dotNumData.push( array );
// 6
array = [
[ 1, 1, 1 ],
[ 1, 0, 0 ],
[ 1, 1, 1 ],
[ 1, 0, 1 ],
[ 1, 1, 1 ]
]
dotNumData.push( array );
// 7
array = [
[ 1, 1, 1 ],
[ 1, 0, 1 ],
[ 0, 0, 1 ],
[ 0, 0, 1 ],
[ 0, 0, 1 ]
]
dotNumData.push( array );
// 8
array = [
[ 1, 1, 1 ],
[ 1, 0, 1 ],
[ 1, 1, 1 ],
[ 1, 0, 1 ],
[ 1, 1, 1 ]
]
dotNumData.push( array );
// 9
array = [
[ 1, 1, 1 ],
[ 1, 0, 1 ],
[ 1, 1, 1 ],
[ 0, 0, 1 ],
[ 1, 1, 1 ]
]
dotNumData.push( array );
}
}
// ドットのNEW ------------------------------------------------------
internal class DotNew extends Sprite
{
private var currentX :int = 0;
private var dotNumData /*Array*/:Array =
[
[ 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1 ],
[ 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1 ],
[ 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1 ],
[ 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1 ],
[ 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1 ]
];
public function DotNew( color:uint, dotSize:int = 2 )
{
buttonMode = true;
graphics.beginFill( color, 0.2 );
graphics.drawRect( -3, -3, dotNumData[0].length * dotSize + 6, dotNumData.length * dotSize + 6 );
graphics.endFill();
for (var i:int = 0; i < dotNumData[0].length; i++) // 横
{
for (var j:int = 0; j < dotNumData.length; j++) // 縦
{
if ( dotNumData[j][i] )
{
graphics.beginFill( color, 1 );
graphics.drawRect( currentX + i*dotSize, j*dotSize, dotSize, dotSize );
graphics.endFill();
}
}
}
}
}