Unionぷらすぶろっく - プレイ中の人のスコア共有
ぷらすぶろっく
*
* 右上に書かれた数値を目標に、パネルをクリックして数を足していってください。
* 足した数の合計と右上の数値がちょうど同じ数になればブロックが消えます。
*
* 例えば、右上の数値が10であれば、
* 1 + 9
* 2 + 3 + 5
* 1 + 2 + 3 + 4
* などのブロックをクリックしてください。
*
* 選択したパネルをもう一度クリックすれば選択が解除されます。
* 選択した数の合計が右上の数値を超えると選択が自動解除されます。
// forked from rsakane's ぷらすぶろっく - スコア共有
/*
* ぷらすぶろっく
*
* 右上に書かれた数値を目標に、パネルをクリックして数を足していってください。
* 足した数の合計と右上の数値がちょうど同じ数になればブロックが消えます。
*
* 例えば、右上の数値が10であれば、
* 1 + 9
* 2 + 3 + 5
* 1 + 2 + 3 + 4
* などのブロックをクリックしてください。
*
* 選択したパネルをもう一度クリックすれば選択が解除されます。
* 選択した数の合計が右上の数値を超えると選択が自動解除されます。
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import net.user1.reactor.IClient;
import net.user1.reactor.Reactor;
import net.user1.reactor.ReactorEvent;
import net.user1.reactor.Room;
import net.user1.reactor.RoomEvent;
[SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "0x0")]
public class PlusBlock extends Sprite
{
private var canvas:Sprite = new Sprite();
private var frame:Number = 0;
private var reactor:Reactor = new Reactor();
private var room:Room;
private const ROOM_NAME:String = "wonderfl.plusblock.room";
private var sharedScore:SharedScore = new SharedScore();
public function PlusBlock()
{
Panel.init(canvas);
addChild(canvas);
canvas.x = canvas.y = 2;
canvas.addEventListener("scoreUpdate", onScoreUpdate);
addChild(sharedScore);
sharedScore.x = 2; sharedScore.y = 330;
for (var y:int = 9; y >= 7; y--)
{
for (var x:int = 9; x >= 0; x--)
{
var panel:Panel = new Panel();
panel.x = x * Panel.SIZE;
panel.y = y * Panel.SIZE;
canvas.addChild(panel);
Panel.panels[y][x] = panel;
}
}
addEventListener(Event.ENTER_FRAME, onEnterFrame);
reactor.addEventListener(ReactorEvent.READY, onReady);
reactor.connect("tryunion.com", 9100);
}
private function onReady(e:ReactorEvent):void {
sharedScore.myId = reactor.getClientManager().self().getClientID();
room = reactor.getRoomManager().createRoom(ROOM_NAME);
room.addEventListener(RoomEvent.UPDATE_CLIENT_ATTRIBUTE, onUpdateClientAttribute);
room.addEventListener(RoomEvent.SYNCHRONIZE, onSynchronize);
room.join();
}
private function onSynchronize(e:RoomEvent):void {
var arr:Array = room.getClients();
for each( var client:IClient in arr ) {
var str:String = client.getAttribute("score", ROOM_NAME);
if ( str != "" ) {
if ( Number(str) >= 0 ) {
sharedScore.addScore( client.getClientID(), str );
}
}
}
reactor.getClientManager().self().setAttribute("score", String(Panel.score), ROOM_NAME);
}
private function onUpdateClientAttribute(e:RoomEvent):void {
if( e.getChangedAttr().name == "score" )
sharedScore.addScore( e.getClientID(), e.getChangedAttr().value );
}
private function onScoreUpdate(e:Event):void {
if ( reactor.isConnected() ) {
reactor.getClientManager().self().setAttribute("score", String(Panel.score), ROOM_NAME);
}
}
private function onEnterFrame(event:Event):void
{
frame += 1;
// frame += (Panel.score + 10000) / 10000;
if (frame > Panel.frame)
{
frame = 0;
Panel.up(canvas);
}
if (Panel.endFlag)
{
if ( reactor.isConnected() ) {
reactor.getClientManager().self().setAttribute("score", String(-1*Panel.score), "wonderfl.plusblock.room");
}
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
var tf:flash.text.TextField = Panel.createTextField(this, "GAME OVER", 58, 0x393939);
tf.y = 160;
tf.x = 0;
addChild(tf);
}
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.Graphics;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;
import org.libspark.betweenas3.events.TweenEvent;
class SharedScore extends Sprite {
private var obj:Object = {};
private var tf:TextField = new TextField;
public var myId:String = "";
public function SharedScore() {
this.addChild( tf );
tf.defaultTextFormat = new TextFormat("Arial", 15, 0xFFFFFF);
tf.autoSize = TextFieldAutoSize.LEFT;
}
public function addScore(id:String, score:String):void {
obj[id] = Number(score);
updateScore();
}
public function deleteScore(id:String):void {
obj[id] = null;
updateScore();
}
private function updateScore():void {
var arr:Array = [];
for ( var id:String in obj ) {
arr.push([id, obj[id]]);
}
arr.sort(sortFunc);
var str:String = "";
for ( var i:int = 0; i < arr.length; i++ ) {
if ( arr[i][1] < 0 ) continue;
if ( arr[i][0] == myId ) {
str += "<font color='#00FF00'>Guest" + arr[i][0] + "</font>";
} else {
str += "Guest" + arr[i][0];
}
str += ": " + arr[i][1] + "\n";
}
tf.htmlText = str;
}
private function sortFunc(val1:Array, val2:Array):int {
if ( val1[1] > val2[1] ) return -1;
else if ( val1[1] < val2[1] ) return 1;
else return 0;
}
}
class Color
{
public static var COLORS:Array =
[
[0xffef98, 0xffcc01],
[0xf26b53, 0xef4123],
[0x00d27e, 0x00B16B],
[0x09bbff, 0x009AD6],
[0xfacfde, 0xF6ADC6],
[0xffae28, 0xf39800],
[0xb672b6, 0xA757A8],
[0x5993d2, 0x3170b9],
[0xf25773, 0xED1A3D]
]
}
class Panel extends Sprite
{
public static var score:int = 0; // スコア
public static var scoreTF:TextField;
public static var frame:int = 270; // 速度調整用
public static var canvas:Sprite; // キャンバス
public static const SIZE:int = 32; // パネルのサイズ。縦横共有
public static var MAX:int = 9; // パネルに表示されれる最大の数字(1~MAX)
public static var count:int = 0; // 選択しているパネルの合計数値
public static var TVALUE:int = 10; // 目標の数値
public static var panels:Vector.<Vector.<Panel>>; // 10 * 10のパネルが入っている(何も入っていないところはnull)
public static var spanels:Vector.<Panel> = new Vector.<Panel>(); // 選択している(複数の)パネル
public static var endFlag:Boolean = false; // 終了フラグ
private static var targetTF:TextField;
public var number:int; // パネルに表示されている数字
private var frame:Frame = new Frame(SIZE); // 選択されている時に表示する枠
private var effect:Effect; // パネルが消えたときのエフェクト
public static function init(canvas:Sprite):void
{
Panel.canvas = canvas;
panels = new Vector.<Vector.<Panel>>();
for (var i:int = 0; i < 10; i++)
{
panels.push(new Vector.<Panel>(10));
}
canvas.graphics.lineStyle(3.0, 0xFF0000);
canvas.graphics.moveTo(0, SIZE);
canvas.graphics.lineTo(SIZE * 10, SIZE);
var tf:TextField = createTextField(canvas, "BORDER LINE", 17, 0xFF0000);
tf.x = SIZE * 10 + 5;
tf.y = SIZE - tf.height / 2;
canvas.graphics.lineStyle(10.0);
var matrix:Matrix = new Matrix();
matrix.createGradientBox(80, 10, 0, 350, 130);
canvas.graphics.lineGradientStyle("linear", [0xfbd5d2, 0xF8ABA6], [1.0, 1.0], [0, 255], matrix);
canvas.graphics.moveTo(350, 130);
canvas.graphics.lineTo(430, 130);
Panel.TVALUE = 10;
Panel.targetTF = createTextField(canvas, String(Panel.TVALUE), 60, 0xFFFFFF);
Panel.targetTF.x = 352;
Panel.targetTF.y = 70;
tf = createTextField(canvas, "Score", 20, 0xFFFF00);
tf.x = 370, tf.y = 200;
Panel.scoreTF = createTextField(canvas, String(score), 24, 0xffc905);
Panel.scoreTF.x = 400;
Panel.scoreTF.y = 220;
}
public function Panel()
{
this.number = Math.random() * MAX + 1;
var matrix:Matrix = new Matrix();
matrix.createGradientBox(SIZE, SIZE, 45 * Math.PI / 180);
graphics.beginGradientFill("linear", [Color.COLORS[number - 1][0], Color.COLORS[number - 1][1]], [1.0, 1.0], [0, 255], matrix);
graphics.drawRoundRect(0, 0, SIZE - 2, SIZE - 2, SIZE / 4, SIZE / 4);
graphics.endFill();
frame.visible = false;
addChild(frame);
effect = new Effect(this, SIZE / 2, SIZE / 2);
addChild(effect);
createTextField(this, String(number), SIZE * 0.8);
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
}
public static function createTextField(parent:Sprite = null, text:String = "", size:int = 20, color:int = 0x0):TextField
{
var tf:TextField = new TextField();
tf.defaultTextFormat = new TextFormat("Courier New", size, color, true);
tf.text = text;
tf.width = SIZE;
tf.y += 2;
tf.autoSize = TextFieldAutoSize.CENTER;
tf.selectable = false;
if (parent) parent.addChild(tf);
return tf;
}
public static function up(canvas:Sprite):void
{
for (var y:int = 1; y < 10; y++)
{
for (var x:int = 0; x < 10; x++)
{
panels[y - 1][x] = panels[y][x];
if (panels[y - 1][x] != null)
{
BetweenAS3.tween(panels[y - 1][x], { y:(y - 1) * SIZE }, null, 0.8).play();
}
}
}
for (x = 0; x < 10; x++)
{
var panel:Panel = new Panel();
panel.y = 9 * SIZE;
panel.x = x * SIZE;
canvas.addChildAt(panel, 0);
panels[9][x] = panel;
var t:ITween = BetweenAS3.tween(panel, { x:panel.x, y:panel.y, alpha:1.0, scaleX:1.0, scaleY:1.0}, { x:panel.x + SIZE / 2, y:panel.y + SIZE / 2, alpha:0.0, scaleX:0.0, scaleY:0.0 }, 0.8);
t.addEventListener(TweenEvent.COMPLETE, borderCheck);
t.play();
}
}
private static function borderCheck(event:TweenEvent):void
{
for (var x:int = 0; x < 10; x++)
{
if (panels[0][x] == null) continue;
if (panels[0][x].y <= SIZE) endFlag = true;
}
}
private function onMouseDown(event:MouseEvent):void
{
if (endFlag) return;
if (this.number == 0) return;
if (frame.visible)
{
frame.visible = false;
count -= this.number;
spanels.splice(spanels.indexOf(this), 1);
return;
}
spanels.push(this);
frame.visible = true;
count += this.number;
if (TVALUE <= count)
{
if (TVALUE == count)
{
this.number = 0;
count = 0;
score += spanels.length * 10;
canvas.dispatchEvent(new Event("scoreUpdate"));
Panel.scoreTF.text = String(score);
spanels.sort(sort);
for (var i:int = 0; i < spanels.length; i++) spanels[i].remove();
TVALUE = Math.random() * 14 + 9;
targetTF.text = String(TVALUE);
}
count = 0;
while (spanels.length != 0)
{
spanels[0].frame.visible = false;
spanels.splice(0, 1);
}
}
}
private function sort(a:Panel, b:Panel):Number
{
if (a.y < b.y) return 1
else if (a.y > b.y) return -1;
else return 0;
}
private function remove():void
{
effect.play();
var found:Boolean;
for (var i:int = 0; i < spanels.length; i++)
{
found = false;
for (var y:int = 0; y < 10; y++)
{
for (var x:int = 0; x < 10; x++)
{
if (spanels[i] == panels[y][x])
{
for (var yy:int = y; yy >= 1; yy--)
{
panels[yy][x] = panels[yy - 1][x];
}
found = true;
break;
}
}
if (found) break;
}
}
for (y = 0; y < 10; y++)
{
for (x = 0; x < 10; x++)
{
var panel:Panel = panels[y][x];
if (panel == null) continue;
BetweenAS3.tween(panel, { y:y * SIZE }, null, 0.8).play();
}
}
}
}
class Frame extends Sprite
{
public function Frame(size:int)
{
graphics.lineStyle(3.0, 0xFFFFFF);
graphics.drawRoundRect(0, 0, size, size, size / 4, size / 4);
}
}
class Effect extends Sprite
{
private var p:Sprite;
private var cx:int;
private var cy:int;
public function Effect(p:Sprite, cx:int, cy:int)
{
this.p = p;
this.cx = cx;
this.cy = cy;
}
public function play():void
{
for (var degree:Number = 0; degree < 360; degree += 360 / 5)
{
var star:Star = new Star();
addChild(star);
BetweenAS3.serial
(
BetweenAS3.parallel
(
BetweenAS3.tween(star, { x:cx + Math.cos(degree * Math.PI / 180) * 30, y:cy + Math.sin(degree * Math.PI / 180) * 30}, { x:cx, y:cy }, 1.0),
BetweenAS3.tween(p, { alpha:0.0 } )
),
BetweenAS3.removeFromParent(star),
BetweenAS3.removeFromParent(p)
).play();
}
}
}
class Star extends Sprite
{
public function Star()
{
const pi:Number = 0.017453;
var g:Graphics = this.graphics;
for (var degree:int = 0; degree < 360; degree += 72)
{
var rot:Number = degree;
g.beginFill(0xFFFFFF);
g.moveTo(0,0 );
g.lineTo( Math.cos( (rot + 36) *pi) * 10 , Math.sin( (rot +36) *pi) * 10 );
g.lineTo(Math.cos( rot *pi) * 22.85, Math.sin( rot *pi) * 22.85);
g.lineTo( Math.cos( (rot -36) *pi) * 10 ,Math.sin( (rot -36) *pi) * 10 );
g.lineTo(0,0 );
g.endFill();
this.scaleX = this.scaleY = 0.3;
}
}
}