4-Direction Samegame
4方向に寄せられるさめがめ風ゲーム。
・明るいマスをクリックすることで、隣接した同じ色のマスを消すことができます。
・隣とくっついていない独立したマスも消すことができます。
・消せる回数は20回までです。
・周囲の三角ボタンを押すことで空白部分を寄せることができます。
/**
* Copyright Scmiz ( http://wonderfl.net/user/Scmiz )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/af1O
*/
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.net.*;
import flash.utils.escapeMultiByte;
public class FourDirectionSamegame extends Sprite {
private var _score:Score;
private var _restCount:RestCount;
private var _buttonTwit:ButtonTwit;
private var _blockContainer:BlockContainer;
private var _shadow:Sprite;
public function FourDirectionSamegame() {
_score = new Score();
_restCount = new RestCount();
_restCount.y = 420;
_buttonTwit = new ButtonTwit();
_buttonTwit.x = 340;
_buttonTwit.y = 430;
_buttonTwit.addEventListener(MouseEvent.CLICK, onClickTwit);
_blockContainer = new BlockContainer(_score, _restCount, _buttonTwit);
this.addChild(_blockContainer);
_shadow = new Sprite();
_shadow.graphics.beginFill(0x000000, 0.5);
_shadow.graphics.drawRect(0, 0, 465, 115);
_shadow.graphics.drawRect(0, 465 - 116, 465, 116);
_shadow.graphics.drawRect(0, 115, 115, 234);
_shadow.graphics.drawRect(349, 115, 116, 234);
_shadow.graphics.endFill();
this.addChild(_shadow);
this.addChild(_score);
this.addChild(_restCount);
this.addChild(_buttonTwit);
var btnUp:ButtonCompress = new ButtonCompress();
var btnDown:ButtonCompress = new ButtonCompress();
var btnLeft:ButtonCompress = new ButtonCompress();
var btnRight:ButtonCompress = new ButtonCompress();
btnUp.x = 232.5; btnUp.y = 90; btnUp.rotationZ = 180;
btnDown.x = 232.5; btnDown.y = 375; btnDown.rotationZ = 0;
btnLeft.x = 90; btnLeft.y = 232.5; btnLeft.rotationZ = 90;
btnRight.x = 375; btnRight.y = 232.5; btnRight.rotationZ = -90;
btnUp.addEventListener(MouseEvent.CLICK, onClickUp);
btnDown.addEventListener(MouseEvent.CLICK, onClickDown);
btnLeft.addEventListener(MouseEvent.CLICK, onClickLeft);
btnRight.addEventListener(MouseEvent.CLICK, onClickRight);
this.addChild(btnUp);
this.addChild(btnDown);
this.addChild(btnLeft);
this.addChild(btnRight);
}
private function onClickUp(e:MouseEvent):void { _blockContainer.compress(BlockContainer.Dir_Up); }
private function onClickDown(e:MouseEvent):void { _blockContainer.compress(BlockContainer.Dir_Down); }
private function onClickLeft(e:MouseEvent):void { _blockContainer.compress(BlockContainer.Dir_Left); }
private function onClickRight(e:MouseEvent):void { _blockContainer.compress(BlockContainer.Dir_Right); }
// つぶやく
private function onClickTwit(e:MouseEvent):void {
var request:URLRequest = new URLRequest("http://twitter.com/?status="
+ escapeMultiByte("[4D Samegame] Score : "
+ _score.value.toString()
+ " http://wonderfl.net/c/af1O #wonderful #w4ds"));
navigateToURL(request);
}
}
}
import flash.text.TextFormat;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.display.SimpleButton;
import flash.display.Sprite;
import caurina.transitions.Tweener;
// 定数
class Constant {
static public var WIDTH:uint = 21;
static public var HEIGHT:uint = WIDTH;
static public var MAX_REST_COUNT:uint = 20;
}
// 圧縮ボタン
class ButtonCompress extends SimpleButton {
private var _sprite:Sprite;
public function ButtonCompress() {
_sprite = new Sprite();
_sprite.graphics.beginFill(0xFFFFFF, 0.5);
var vertexes:Vector.<Number> = new Vector.<Number>();
vertexes.push(0, -20, -60, 20, 60, 20);
_sprite.graphics.drawTriangles(vertexes);
_sprite.graphics.endFill();
super(_sprite, _sprite, _sprite, _sprite);
}
}
// つぶやくボタン
class ButtonTwit extends SimpleButton {
private var _sprite:Sprite;
private var _tf:TextField;
public function ButtonTwit() {
_sprite = new Sprite();
_sprite.graphics.beginFill(0xFFFFFF, 0.8);
_sprite.graphics.drawRect(0, 0, 120, 30);
_sprite.graphics.endFill();
_tf = new TextField();
var scale:Number = 1.5;
_tf.textColor = 0x222222;
_tf.scaleX = scale;
_tf.scaleY = scale;
_tf.selectable = false;
_tf.text = "post to twitter";
_tf.x = 8;
_sprite.addChild(_tf);
super(_sprite, _sprite, _sprite, _sprite);
}
}
// スコア
class Score extends TextField {
private var _value:uint;
public function Score() {
value = 0;
var scale:Number = 3.0;
this.textColor = 0xFFFFFF;
this.scaleX = scale;
this.scaleY = scale;
this.selectable = false;
this.width = 465;
this.height = 16;
}
public function get value():uint {
return _value;
}
public function set value(v:uint):void {
_value = v;
this.text = "Score : " + _value;
}
}
// 残り回数
class RestCount extends TextField {
private var _value:uint;
public function RestCount() {
value = 0;
var scale:Number = 3.0;
this.textColor = 0xFFFFFF;
this.scaleX = scale;
this.scaleY = scale;
this.selectable = false;
this.width = 465;
this.height = 16;
}
public function get value():uint {
return _value;
}
public function set value(v:uint):void {
_value = v;
this.text = "Rest : " + _value;
}
}
// コンテナ
class BlockContainer extends Sprite {
private var _score:Score;
private var _restCount:RestCount;
private var _buttonTwit:ButtonTwit;
private var _array:Array;
private var _count:uint;
private var _combo:uint;
static public const Dir_Up:uint = 0;
static public const Dir_Down:uint = 1;
static public const Dir_Left:uint = 2;
static public const Dir_Right:uint = 3;
public function BlockContainer(score:Score, restCount:RestCount, buttonTwit:ButtonTwit) {
_score = score;
_restCount = restCount;
_buttonTwit = buttonTwit;
init();
}
public function onDead(x:uint, y:uint, color:uint):void {
++_combo;
if (x > 0) deadIfSameColor(x - 1, y, color);
if (x < Constant.WIDTH - 1) deadIfSameColor(x + 1, y, color);
if (y > 0) deadIfSameColor(x, y - 1, color);
if (y < Constant.HEIGHT - 1) deadIfSameColor(x, y + 1, color);
}
public function addScore():void {
if (_combo >= 100) _score.value += _combo * 20;
else if (_combo >= 90) _score.value += _combo * 15;
else if (_combo >= 80) _score.value += _combo * 12;
else if (_combo >= 70) _score.value += _combo * 10;
else if (_combo >= 60) _score.value += _combo * 9;
else if (_combo >= 50) _score.value += _combo * 8;
else if (_combo >= 40) _score.value += _combo * 7;
else if (_combo >= 30) _score.value += _combo * 6;
else if (_combo >= 20) _score.value += _combo * 5;
else if (_combo >= 10) _score.value += _combo * 4;
else if (_combo >= 5) _score.value += _combo * 3;
else if (_combo >= 3) _score.value += _combo * 2;
else _score.value += _combo * 1;
_combo = 0;
}
public function compress(dir:uint):void {
if (_count >= Constant.MAX_REST_COUNT) return;
// 不要なブロックを削除
for (var y:uint = 0; y < Constant.HEIGHT; ++y) {
for (var x:uint = 0; x < Constant.WIDTH; ++x) {
var block:Block = _array[y][x];
if (block.isDead) {
_array[y][x] = null;
}
}
}
switch (dir) {
case Dir_Up:
compressUp();
fillUp();
break;
case Dir_Down:
compressDown();
fillDown();
break;
case Dir_Left:
compressLeft();
fillLeft();
break;
case Dir_Right:
compressRight();
fillRight();
break;
}
}
// クリックされたときに呼ばれる
public function onClick():void {
++_count;
_restCount.value = Constant.MAX_REST_COUNT - _count;
if (_count >= Constant.MAX_REST_COUNT) {
for (var x:uint = 0; x < Constant.WIDTH; ++x) {
for (var y:int = 0; y < Constant.HEIGHT; ++y) {
_array[y][x].mouseEnabled = false;
}
}
_buttonTwit.visible = true;
}
}
// 各方向に圧縮
private function compressUp():void {
for (var x:uint = 0; x < Constant.WIDTH; ++x) {
for (var y:int = Constant.HEIGHT - 1; y >= 0; --y) {
if (_array[y][x] == null) {
var block:Block = null;
for (var index:int = y; index >= 0; --index) {
if (_array[index][x] != null) {
block = _array[index][x];
_array[index][x] = null;
break;
}
}
if (block != null) {
_array[y][x] = block;
_array[y][x].move(x, y);
}
}
}
}
}
private function compressDown():void {
for (var x:uint = 0; x < Constant.WIDTH; ++x) {
for (var y:int = 0; y < Constant.HEIGHT; ++y) {
if (_array[y][x] == null) {
var block:Block = null;
for (var index:int = y; index < Constant.HEIGHT; ++index) {
if (_array[index][x] != null) {
block = _array[index][x];
_array[index][x] = null;
break;
}
}
if (block != null) {
_array[y][x] = block;
_array[y][x].move(x, y);
}
}
}
}
}
private function compressLeft():void {
for (var y:uint = 0; y < Constant.HEIGHT; ++y) {
for (var x:int = Constant.WIDTH - 1; x >= 0; --x) {
if (_array[y][x] == null) {
var block:Block = null;
for (var index:int = x; index >= 0; --index) {
if (_array[y][index] != null) {
block = _array[y][index];
_array[y][index] = null;
break;
}
}
if (block != null) {
_array[y][x] = block;
_array[y][x].move(x, y);
}
}
}
}
}
private function compressRight():void {
for (var y:uint = 0; y < Constant.HEIGHT; ++y) {
for (var x:int = 0; x < Constant.WIDTH; ++x) {
if (_array[y][x] == null) {
var block:Block = null;
for (var index:int = x; index < Constant.WIDTH; ++index) {
if (_array[y][index] != null) {
block = _array[y][index];
_array[y][index] = null;
break;
}
}
if (block != null) {
_array[y][x] = block;
_array[y][x].move(x, y);
}
}
}
}
}
// 空きを埋める
private function fillUp():void {
for (var y:uint = 0; y < Constant.HEIGHT; ++y) {
var stock:uint = 0;
for (var x:uint = 0; x < Constant.WIDTH; ++x) {
if (_array[y][x] != null) continue;
var block:Block = new Block(this, x, y, Math.random() * Block.Color_Num);
block.x = -28 + (26 * x);
block.y = -28 - (26 * stock);
this.addChild(block);
_array[y][x] = block;
block.move(x, y);
++stock;
}
}
}
private function fillDown():void {
for (var y:uint = 0; y < Constant.HEIGHT; ++y) {
var stock:uint = 0;
for (var x:uint = 0; x < Constant.WIDTH; ++x) {
if (_array[y][x] != null) continue;
var block:Block = new Block(this, x, y, Math.random() * Block.Color_Num);
block.x = -28 + (26 * x);
block.y = 465 + 28 + (26 * stock);
this.addChild(block);
_array[y][x] = block;
block.move(x, y);
++stock;
}
}
}
private function fillLeft():void {
for (var x:uint = 0; x < Constant.WIDTH; ++x) {
var stock:uint = 0;
for (var y:uint = 0; y < Constant.HEIGHT; ++y) {
if (_array[y][x] != null) continue;
var block:Block = new Block(this, x, y, Math.random() * Block.Color_Num);
block.x = -28 - (26 * stock);
block.y = -28 + (26 * y);
this.addChild(block);
_array[y][x] = block;
block.move(x, y);
++stock;
}
}
}
private function fillRight():void {
for (var x:uint = 0; x < Constant.WIDTH; ++x) {
var stock:uint = 0;
for (var y:uint = 0; y < Constant.HEIGHT; ++y) {
if (_array[y][x] != null) continue;
var block:Block = new Block(this, x, y, Math.random() * Block.Color_Num);
block.x = 465 + 28 + (26 * stock);
block.y = -28 + (26 * y);
this.addChild(block);
_array[y][x] = block;
block.move(x, y);
++stock;
}
}
}
// 同じ色なら消滅
private function deadIfSameColor(x:uint, y:uint, color:uint):void {
var block:Block = _array[y][x];
if (block.color == color) {
block.dead();
}
}
// 初期化
private function init():void {
_score.value = 0;
_restCount.value = Constant.MAX_REST_COUNT;
_buttonTwit.visible = false;
_array = new Array();
_count = 0;
_combo = 0;
for (var y:uint = 0; y < Constant.HEIGHT; ++y) {
_array.push(new Array());
for (var x:uint = 0; x < Constant.WIDTH; ++x) {
var block:Block = new Block(this, x, y, Math.random() * Block.Color_Num);
block.x = -28 + (26 * x);
block.y = -28 + (26 * y);
this.addChild(block);
_array[y].push(block);
}
}
}
}
// ブロックひとつ
class Block extends SimpleButton {
static private const Color_Red:uint = 0;
static private const Color_Green:uint = 1;
static private const Color_Blue:uint = 2;
static public const Color_Num:uint = 3;
private var _container:BlockContainer;
private var _x:uint;
private var _y:uint;
private var _color:uint;
private var _sprite:Sprite;
private var _isDead:Boolean;
public function Block(container:BlockContainer, x:uint, y:uint, color:uint) {
_container = container;
_x = x;
_y = y;
_sprite = new Sprite();
_color = color;
_isDead = false;
var fillColor:uint = 0;
switch (_color) {
case Color_Red: fillColor = 0xFF2020; break;
case Color_Green: fillColor = 0x20DF20; break;
case Color_Blue: fillColor = 0x2020FF; break;
}
_sprite.graphics.beginFill(fillColor);
_sprite.graphics.drawRoundRect(-12, -12, 24, 24, 4);
_sprite.graphics.endFill();
super(_sprite, _sprite, _sprite, _sprite);
this.addEventListener(MouseEvent.CLICK, onClick);
}
// 死亡挙動
public function dead():void {
if (_isDead) return;
_isDead = true;
this.mouseEnabled = false;
_container.onDead(_x, _y, color);
Tweener.addTween(this, {scaleX:1.10, scaleY:1.10, delay:0, time:4, useFrames:true});
Tweener.addTween(this, {scaleX:0.01, scaleY:0.01, delay:4, time:10, useFrames:true, onComplete:onDeadEnd});
}
// 移動挙動
public function move(x:uint, y:uint):void {
_x = x;
_y = y;
Tweener.addTween(this, {x:(-28 + (26 * _x)), y:(-28 + (26 * _y)), delay:0, time:20, useFrames:true});
}
// アクセサ
public function get color():uint { return _color; }
public function get isDead():Boolean { return _isDead; }
// クリック時の処理
private function onClick(e:MouseEvent):void {
dead();
_container.onClick();
_container.addScore();
}
// 死亡完了コールバック
private function onDeadEnd():void {
parent.removeChild(this);
}
}