/**
* Copyright junki ( http://wonderfl.net/user/junki )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/XBOz
*/
// 09'06.14ワールドルール(SRS)を追記
// 時間かかったあげくコード汚いけどAS3.0の練習ついでにテトリス25周年おめでと記念。消されてもしらね
package
{
import flash.desktop.ClipboardTransferMode;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import net.hires.debug.Stats;
[SWF(width="400",height="300",frameRate="60",backgroundColor="0x000000")]
/**
* ...
* @author junki
*/
public class Main extends Sprite
{
/****************************************
* 変数とか宣言とか
*****************************************/
// ブロックややこしすぎ\(^o^)/
private const mino:Vector.<Vector.<Vector.<Boolean>>> =
Vector.<Vector.<Vector.<Boolean>>>([
Vector.<Vector.<Boolean>>([
Vector.<Boolean>([false, false, false, false]),
Vector.<Boolean>([true, true, true, true]),
Vector.<Boolean>([false, false, false, false]),
Vector.<Boolean>([false, false, false, false])
]),
Vector.<Vector.<Boolean>>([
Vector.<Boolean>([true, false, false]),
Vector.<Boolean>([true, true, true]),
Vector.<Boolean>([false, false, false])
]),
Vector.<Vector.<Boolean>>([
Vector.<Boolean>([false, false, true]),
Vector.<Boolean>([true, true, true]),
Vector.<Boolean>([false, false, false])
]),
Vector.<Vector.<Boolean>>([
Vector.<Boolean>([true, true]),
Vector.<Boolean>([true, true])
]),
Vector.<Vector.<Boolean>>([
Vector.<Boolean>([false, true, true]),
Vector.<Boolean>([true, true, false]),
Vector.<Boolean>([false, false, false])
]),
Vector.<Vector.<Boolean>>([
Vector.<Boolean>([true, true, false]),
Vector.<Boolean>([false, true, true]),
Vector.<Boolean>([false, false, false])
]),
Vector.<Vector.<Boolean>>([
Vector.<Boolean>([false, true, false]),
Vector.<Boolean>([true, true, true]),
Vector.<Boolean>([false, false, false])
])
]);
// 回転法則。32(回転方向)と8(回転状態)と2(XY)を駆使汁。
private const offsetRule:Vector.<int> =
Vector.<int>([
//左回転
1, 0, 1, -1, 0, 2, 1, 2, //↑ > ←
1, 0, 1, 1, 0, -2, 1, -2, //→ > ↑
-1, 0, -1, -1, 0, 2, -1, 2, //↓ > →
-1, 0, -1, 1, 0, -2, -1, -2, //← > ↓
//右回転
-1, 0, -1, -1, 0, 2, -1, 2, //↑ > →
1, 0, 1, 1, 0, -2, 1, -2, //→ > ↓
1, 0, 1, -1, 0, 2, 1, 2, //↓ > ←
-1, 0, -1, 1, 0, -2, -1, -2, //← > ↑
0
]);
private const offsetRuleI:Vector.<int> =
Vector.<int>([
//左回転
-1, 0, 2, 0, -1, -2, 2, 1, //↑ > ←
2, 0, -1, 0, 2, -1, -1, 2, //→ > ↑
-2, 0, 1, 0, -2, -1, 1, 1, //↓ > →
-2, 0, 1, 0, 1, -2, -2, 1, //← > ↓
//右回転
-2, 0, 1, 0, -2, -1, 1, 2, //↑ > →
2, 0, -1, 0, 2, -1, -1, 1, //→ > ↓
2, 0, -1, 0, -1, -2, 2, 1, //↓ > ←
-2, 0, 1, 0, 1, -2, -2, 1, //← > ↑
0
]);
// ブロック色のインデックス( 0:I, 1:J, 2:L, 3:O, 4:S, 5:Z, 6:T )
private const boxColor:Vector.<int> =
Vector.<int>([0x88ddff, 0x4444ee, 0xee8822, 0xeeee44, 0x44ee44, 0xff2222, 0xee22ee]);
private const boxSize:int = 14;
// 当たり判定用の2次元bool配列
private var stageField:Vector.<Vector.<Boolean>> = new Vector.<Vector.<Boolean>>();
// NEXT表示のint配列 pushで入れて shiftで出す。
private const nextDisplayDigit:int = 5;
private var nextBlock:Vector.<int> = new Vector.<int>(nextDisplayDigit);
// 設置したブロックを描画する為のSprite配列
private var stageSprite:Vector.<Sprite> = new Vector.<Sprite>(23);
// ステージの横一列に存在するブロックの数を保持するint配列
private var stageBoxCnt:Vector.<int> = new Vector.<int>(23);
// ステータス
private var level:int;
private var score:int;
private var fileLineCnt:int;
private var fileLine:int;
private var nextView:Sprite;
private var gameStatus:String;
private var fallinBlockNum:int;
private var fallinBlock:Sprite;
private var fallinBlockX:int;
private var fallinBlockY:int;
private var fallinBlockRot:int;
private var fallinBlockAry:Vector.<Vector.<Boolean>> = new Vector.<Vector.<Boolean>>();
private const moveSpeed:int = 1;
private const moveInterval:int = 10;
private var moveCnt:int;
private const nextInterval:int = 10;
private var nextCnt:int;
private const onSpeed:int = 5;
private var onCnt:int;
private const fallSpeed:int = 30;
private var fallCnt:int;
private const eraseInterval:int = 5;
private var eraseCnt:int;
private var holdFlag:Boolean;
private var keyHandleMoveL:int;
private var keyHandleMoveR:int;
private var keyHandleRotL:int;
private var keyHandleRotR:int;
private var keyHandleFallS:int;
private var keyHandleFallQ:int;
private var keyHandleHold:int;
// gameStatus表示用
private var debugf:TextField;
private var kl:KeyListner;
/**
* コンストラクタ
*/
public function Main():void
{
stage.addChild(new Stats());
createStage();
// initStage();
initEventListner();
kl = new KeyListner(stage);
}
/****************************************
* 初期化とか
*****************************************/
/**
* コンストラクタから一回だけ呼び出されるステージの構築メソッド
*/
private function createStage():void
{
// テキストの描画
var startButton:Sprite = new Sprite();
startButton = createButton("start");
startButton.x = 30;
startButton.y = 250;
addChild(startButton);
startButton.addEventListener(MouseEvent.CLICK, gameStart);
var text_hold:TextField = new TextField();
text_hold = createTextField("HOLD", 10, 15, 20, "center");
text_hold.x = 38;
text_hold.y = 5;
addChild(text_hold);
var text_next:TextField = new TextField();
text_next = createTextField("NEXT", 10, 15, 20, "center");
text_next.x = 300;
text_next.y = 5;
addChild(text_next);
debugf = new TextField();
debugf = createTextField("gameStatus", 20, 15, 14, "left");
debugf.x = 30;
debugf.y = 270;
addChild(debugf);
// ラインの描画
var lines:Sprite = new Sprite();
var cx:int = 130
var cy:int = 10
lines.graphics.lineStyle(0.5, 0xffffff);
// lines.graphics.moveTo(cx, cy);
// lines.graphics.lineTo(cx, box * 20);
for (var i:int = 0; i < 21; i++ )
{
lines.graphics.moveTo(cx, cy + boxSize * i);
lines.graphics.lineTo(cx+boxSize*10, cy+boxSize*i);
}
for (i = 0; i < 11; i++ )
{
lines.graphics.moveTo(cx+boxSize*i, cy);
lines.graphics.lineTo(cx+boxSize*i, cy+boxSize*20);
}
addChild(lines)
// 23段分のSprite
for (i = 0; i < 23; i++ )
{
stageSprite[i] = new Sprite();
// stageSprite[i].x = 130;
// stageSprite[i].y = -32 + i * boxSize;
addChild(stageSprite[i]);
}
// new
level = 1;
score = 0;
fileLine = 0;
fileLineCnt = 0;
gameStatus = "pushStart";
fallinBlockX = 0;
fallinBlockY = 0;
fallinBlockRot = 0;
moveCnt = moveInterval;
nextCnt = nextInterval;
onCnt = onSpeed;
fallCnt = fallSpeed;
eraseCnt = eraseInterval;
holdFlag = true;
keyHandleMoveL = 0;
keyHandleMoveR = 0;
keyHandleRotL = 0;
keyHandleRotR = 0;
keyHandleFallS = 0;
keyHandleFallQ = 0;
keyHandleHold = 0;
nextView = new Sprite();
addChild(nextView);
}
/**
* ブロックの配置を記憶するステージの初期化
*/
private function initStage():void
{
stageField =
Vector.<Vector.<Boolean>>([
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]),
Vector.<Boolean>([false, true, true, true, true, true, true, true, true, true, true, true, true, true]),
Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true])
]);
for (var i:int = stageSprite.length-1; i >= 0; i-- )
{
removeChild(stageSprite[i]);
stageSprite[i] = new Sprite();
stageSprite[i].x = 130;
stageSprite[i].y = -32 + i * boxSize;
addChild(stageSprite[i]);
}
}
/**
* ゲーム酢太ートするごとに呼び出す、諸々のステータスの初期化
*/
private function initGameStatus():void
{
level = 1;
score = 0;
fileLine = 0;
fileLineCnt = 0;
fallinBlockX = 0;
fallinBlockY = 0;
fallinBlockRot = 0;
moveCnt = moveInterval;
nextCnt = nextInterval;
onCnt = onSpeed;
fallCnt = fallSpeed;
eraseCnt = eraseInterval;
holdFlag = true;
keyHandleMoveL = 0;
keyHandleMoveR = 0;
keyHandleRotL = 0;
keyHandleRotR = 0;
keyHandleFallS = 0;
keyHandleFallQ = 0;
keyHandleHold = 0;
for (var i:int = stageBoxCnt.length; i >= 0; i--)
{
stageBoxCnt[i] = 0;
}
// next表示数の倍だけgetNextBlockすると初期ブロックのバラ付きがなくなる
for (i = 0; i < 10; i++ )
{
getNextBlock();
}
displayNextBlock();
gameStatus = "getNext";
}
/**
* イベントリスナー初期化
*/
private function initEventListner():void
{
}
/****************************************
* ゲーム進行でよく呼ぶメソッドとか
*****************************************/
/**
* 次のブロックを呼び出す
* @param chance 抽選回数
* @return num
*/
private function getNextBlock():int
{
var num:int = 0;
var uniq:Boolean = false;
for (var i:int = 0; i < 3 && !uniq; i++ )
{
num = Math.floor(Math.random() * 7);
uniq = true;
for (var j:int = 0; j < nextDisplayDigit; j++ )
{
if (nextBlock[j] == num)
uniq = false;
}
}
nextBlock.push(num);
return nextBlock.shift();
}
/**
* ブロックの回転
* @param num ブロックの種類
* @param x ブロックのステージx座標
* @param y ブロックのステージy座標
* @param rot 回転方向(右:1 左:-1)
*/
private function rotate(num:int, x:int, y:int, r:int):void
{
var rot:int = (fallinBlockRot + r + 4) % 4;
if (!hitBlockTest(num, x, y, rot))
{
removeChild(fallinBlock);
fallinBlock = new Sprite();
fallinBlock = createBlock(num, 102 + (x * boxSize), -32 + (y * boxSize) , rot);
addChild(fallinBlock);
fallinBlockRot = rot;
return;
}
else if (r != 0)
{
var i:int;
var rx:int;
var ry:int;
r = (r + 1) * 16 + fallinBlockRot * 8;
//trace("SR!");
if (num != 3) //o型以外のの回転法則
{
if (num != 0) //普通の回転法則
{
for (i = 0; i < 4; i++ )
{
rx = offsetRule[r + (i * 2)];
ry = offsetRule[r + (i * 2) + 1];
trace(r,"rot:",rot,"rx:",rx,"ry:",ry);
if(!hitBlockTest(num, x + rx, y + ry, rot))
{
//trace("まわった!蔵らがまわった! : ",i);
removeChild(fallinBlock);
fallinBlock = new Sprite();
fallinBlock = createBlock(num, 102 + (x * boxSize), -32 + (y * boxSize) , rot);
fallinBlockX += rx;
fallinBlockY += ry;
fallinBlock.x += rx*boxSize;
fallinBlock.y += ry*boxSize;
addChild(fallinBlock);
fallinBlockRot = rot;
break;
}
}
}
else //Iの回転法則
{
for (i = 0; i < 4; i++ )
{
rx = offsetRuleI[r + (i * 2)];
ry = offsetRuleI[r + (i * 2) + 1];
//trace(rx,ry);
if(!hitBlockTest(num, x + rx, y + ry, rot))
{
//trace("まわった!蔵らがまわった! : ",i);
removeChild(fallinBlock);
fallinBlock = new Sprite();
fallinBlock = createBlock(num, 102 + (x * boxSize), -32 + (y * boxSize) , rot);
fallinBlockX += rx;
fallinBlockY += ry;
fallinBlock.x += rx*boxSize;
fallinBlock.y += ry*boxSize;
addChild(fallinBlock);
fallinBlockRot = rot;
break;
}
}
}
}
}
}
/**
* 当たり判定
* @param num ブロックの種類
* @param x ブロックのステージx座標
* @param y ブロックのステージy座標
* @param rot 回転状態
* @return hit
*/
private function hitBlockTest(num:int, x:int, y:int, rot:int):Boolean
{
var hit:Boolean = false;
var lng:int = new int(mino[num].length - 1);
var i:int = 0;
var j:int = 0;
for (i = lng; i >= 0; i-- )
{
for (j = lng; j >= 0; j-- )
{
var xx:int = 0;
var yy:int = 0;
switch(rot)
{
case 0:
xx = i;
yy = j;
break;
case 1:
xx = -j + lng;
yy = i;
break;
case 2:
xx = -i + lng;
yy = -j + lng;
break;
default:
xx = j;
yy = -i + lng;
break;
}
if ((stageField.length <= (i+y)) || (stageField[0].length <= (j+x)) || (i+y)<0 || (j+x)<0)
{
return true;
}
if (mino[num][xx][yy] && stageField[i + y][j + x])
{
return true;
}
}
}
return false;
}
/**
* ステージ(とSprite)に書き込む
* @param spr ブロックのスプライト
* @param num ブロックの種類
* @param x ブロックのx座標
* @param y ブロックのy座標
* @param rot 回転状態
* @return hit
*/
private function writeStageField(num:int, x:int, y:int, rot:int):void
{
var lng:int = mino[num].length - 1;
var i:int = 0;
var j:int = 0;
var xx:int = 0;
var yy:int = 0;
for (i = lng; i >= 0; i-- )
{
for (j = lng; j >= 0; j-- )
{
switch(rot)
{
case 0:
xx = i;
yy = j;
break;
case 1:
xx = -j + lng;
yy = i;
break;
case 2:
xx = -i + lng;
yy = -j + lng;
break;
default:
xx = j;
yy = -i + lng;
break;
}
if (mino[num][xx][yy])
{
var sp:Sprite = new Sprite();
sp = createBox(num);
stageField[i + y][j + x] = true;
stageBoxCnt[i + y]++;
sp.x = (j + x ) * boxSize - 28;
sp.y = 0;
stageSprite[i + y].addChild(sp);
}
}
}
gameStatus = "interval";
nextCnt = nextInterval;
removeChild(fallinBlock);
eraseLine();
gameOver();
}
/**
* 特定のラインにブロックが10個出来たらライン消去する
*/
private function eraseLine():void
{
var lineCnt:int = 0;
for (var i:int = stageBoxCnt.length-1; i >= 0; i-- )
{
// trace("stageboxcnt : " + i + " " + stageBoxCnt[i]);
if (stageBoxCnt[i] > 9)
{
trace("eraseLine! : " + i);
// stageBoxCnt[i] = 0;
fileLine ++;
// ラインを消しーの
removeChild(stageSprite[i]);
stageSprite[i] = null;
stageSprite.splice(i, 1);
stageField[i] = null;
stageField.splice(i, 1); //これは比較用の真偽配列
stageBoxCnt[i] = null;
stageBoxCnt.splice(i, 1); //
// 新しいスプライトを用意しーの
//stageSprite.unshift(new Sprite());
stageSprite.splice(0, 0, new Sprite());
// 上に積み重ねーの
stageSprite[0] = new Sprite();
stageSprite[0].x = 130;
//stageSprite[0].y = -32 - (fileLine * boxSize);
//stageField.unshift(Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true])); //これは比較用のの真偽配列
stageField.splice(0, 0, Vector.<Boolean>([true, true, false, false, false, false, false, false, false, false, false, false, true, true]));
//stageBoxCnt.unshift(0);
stageBoxCnt.splice(0, 0, 0);
// addChild
addChild(stageSprite[0]);
gameStatus = "erase";
i++;
}
}
}
/**
* 時間差をつけて空白を詰めるためだけに生まれたfunction
*/
private function trimDown():void
{
var current:int = stageSprite.length - 1;
for (var i:int = current; i >= 0; i-- )
{
stageSprite[i].y = -32 + i * boxSize;
//if (stageBoxCnt[i] > 9)
//{
//
//stageBoxCnt[current] = stageBoxCnt[i];
//stageBoxCnt[i] = 0;
//
//for (var j:int = stageField[current].length-3; j > 1; j-- )
//{
//stageField[current][j] = stageField[current][j];
//stageField[i][j] = false;
//}
//}
//else
//{
//current --;
//}
}
}
/**
* ゲームオーバーとか
*/
private function gameOver():void
{
}
/**
* メインループ
* @param event
*/
private function mainLoop(event:Event):void
{
switch(gameStatus)
{
// nextBlockから次のブロックを取得、
// nextを再表示してブロックを初期座標に配置する。
case "getNext":
fallinBlock = new Sprite();
fallinBlockNum = getNextBlock();
// 落下中のブロックのセット
fallinBlockAry = mino[fallinBlockNum];
fallinBlockX = (fallinBlockNum != 3 ? 5:6); // O型ブロックの場合は出現位置がズレる。
fallinBlockY = 1;
displayNextBlock();
fallinBlock = createBlock(fallinBlockNum, 102 + fallinBlockX * boxSize, -18, 0);
addChild(fallinBlock);
gameStatus = "fall";
fallCnt = fallSpeed;
onCnt = onSpeed;
fileLine = 0;
fallinBlockRot = 0;
// break; // 走りぬけおいしいです
// fallIntervalフレーム待ってブロックを落下させ
// 下にブロックがあったらonSpeedフレーム待ってブロックをstageSpriteに書き込む
// あとキー入力の受け付け
case "fall":
fallCnt--;
if (fallCnt < 0)
{
// trace(fallinBlockX,fallinBlockY);
fallCnt = fallSpeed;
if (!hitBlockTest(fallinBlockNum, fallinBlockX, fallinBlockY+1, fallinBlockRot))
{
fallinBlockY ++;
fallinBlock.y += boxSize;
onCnt = onSpeed;
}
else
{
onCnt --;
if (onCnt < 0)
{
onCnt = onSpeed;
writeStageField(fallinBlockNum, fallinBlockX, fallinBlockY, fallinBlockRot);
// 簡易ゲームオーバー
if (fallinBlockY < 2)
{
gameStatus = "gameOver";
break;
}
}
}
}
// キー入力の受け付け
key();
break;
// 一列消して詰める
case "erase":
if (eraseCnt < 0)
{
trimDown();
gameStatus = "interval";
eraseCnt = eraseInterval;
}
eraseCnt--;
break;
// ブロックが設置(or消)されてから次のブロックを降らせるまでの間
case "interval":
nextCnt--;
if (nextCnt < 0)
{
gameStatus = "getNext";
// 先行入力受付
// key();
keyHandleRotL = 1;
keyHandleRotR = 1;
holdFlag = true;
}
break;
case "pause":
break;
case "gameOver":
gameStatus = "pushStart";
break;
default:
break;
}
debugf.text = gameStatus;
function key():void
{
var kf:int = new int(kl.keyFlag);
kf = kf << 25;
// 左移動
if (kf < 0)
{
keyHandleMoveL--;
if (keyHandleMoveL < 0 )
{
if (!hitBlockTest(fallinBlockNum, fallinBlockX-1, fallinBlockY, fallinBlockRot))
{
fallinBlockX--;
fallinBlock.x -= boxSize;
}
keyHandleMoveL = moveInterval;
}
if (keyHandleMoveL < 1)
{
if (!hitBlockTest(fallinBlockNum, fallinBlockX-1, fallinBlockY, fallinBlockRot))
{
fallinBlockX--;
fallinBlock.x -= boxSize;
}
keyHandleMoveL = moveSpeed;
}
}
else
{
keyHandleMoveL = -1;
}
kf = kf << 1;
// 右移動
if (kf < 0)
{
keyHandleMoveR--;
if (keyHandleMoveR < 0 )
{
if (!hitBlockTest(fallinBlockNum, fallinBlockX+1, fallinBlockY, fallinBlockRot))
{
fallinBlockX++;
fallinBlock.x += boxSize;
}
keyHandleMoveR = moveInterval;
}
if (keyHandleMoveR < 1)
{
if (!hitBlockTest(fallinBlockNum, fallinBlockX+1, fallinBlockY, fallinBlockRot))
{
fallinBlockX++;
fallinBlock.x += boxSize;
}
keyHandleMoveR = moveSpeed;
}
}
else
{
keyHandleMoveR = -1;
}
kf = kf << 1;
// 左回転
if (kf < 0)
{
keyHandleRotL = (keyHandleRotL < 2)?0:2;
if (!keyHandleRotL)
{
rotate(fallinBlockNum, fallinBlockX, fallinBlockY, -1);
keyHandleRotL = 2;
}
}
else
{
keyHandleRotL = 1;
}
kf = kf << 1;
// 右回転
if (kf < 0)
{
keyHandleRotR = (keyHandleRotR < 2)?0:2;
if (!keyHandleRotR)
{
rotate(fallinBlockNum, fallinBlockX, fallinBlockY, 1);
keyHandleRotR = 2;
}
}
else
{
keyHandleRotR = 1;
}
kf = kf << 1;
// 落下速度上昇
if (kf < 0)
{
if (keyHandleFallS < 0)
{
onCnt = 0;
}
keyHandleFallS = 0;
if (keyHandleFallS == 0)
{
fallCnt -= 3;
}
}
else
{
keyHandleFallS = -1;
}
kf = kf << 1;
// 即時落下
if (kf < 0)
{
keyHandleFallQ = (keyHandleFallQ < 2)?0:2;
if ((!keyHandleFallQ) && (gameStatus == "fall"))
{
// 1fとか待ってらんないのでさっさとブロックを固定する作業に
for (var y:int = 1; !hitBlockTest(fallinBlockNum, fallinBlockX, fallinBlockY + y, fallinBlockRot); y++ )
{
}
fallinBlockY += y - 1;
keyHandleFallQ = 2;
writeStageField(fallinBlockNum, fallinBlockX, fallinBlockY, fallinBlockRot);
// 簡易ゲームオーバー
if (fallinBlockY < 2)
{
gameStatus = "gameOver";
}
}
}
else
{
keyHandleFallQ = 1;
}
kf = kf << 1;
// ホールド
if (kf < 0)
{
keyHandleHold = (keyHandleHold < 2)?0:2;
}
else
{
keyHandleHold = 1;
}
}
}
/****************************************
* イベントリスナとか
*****************************************/
/**
* マウスクリックで呼びだされる。initializeしてゲームスタート。
* @param event
*/
private function gameStart(event:MouseEvent):void
{
if (gameStatus == "pushStart")
{
initStage();
initGameStatus();
trace("gamestart!");
addEventListener(Event.ENTER_FRAME, mainLoop);
}
}
/****************************************
* 描画とか担当のメソッド。出来る子。
*****************************************/
/**
* ディスプレイにNEXTを表示する
*/
private function displayNextBlock():void
{
removeChild(nextView);
nextView = new Sprite();
addChild(nextView);
var nextSprite:Vector.<Sprite> = new Vector.<Sprite>(5);
for (var i:int = 0; i < nextDisplayDigit; i++ )
{
nextSprite[i] = createBlock(nextBlock[i], 300, 30+(i*32), 0);
nextView.addChild(nextSprite[i]);
}
}
/**
* テキストフィールドの作成
* @param str String
* @param wid width
* @param hei height
* @param size textSize
* @param type textAlign
* @return
*/
private function createTextField(str:String, wid:int, hei:int, size:int, type:String):TextField
{
var format:TextFormat = new TextFormat();
format.color = 0xffffff;
format.size = size;
var tf:TextField = new TextField;
tf.defaultTextFormat = format;
tf.text = str;
tf.type = TextFieldType.DYNAMIC;
tf.width = wid;
tf.height = hei;
tf.selectable = false;
tf.border = false;
tf.autoSize = type;
return tf;
}
/**
* 引数の文字を入れたボタンのムービークリップを返す
* @param str
* @return button
*/
private function createButton(str:String):Sprite
{
var btn:Sprite = new Sprite();
btn.buttonMode = true;
var format:TextFormat = new TextFormat();
format.size = 14;
format.color = 0xffffff;
var tf:TextField = new TextField();
tf.text = str;
tf.setTextFormat(format);
tf.type = TextFieldType.DYNAMIC;
tf.x = 0;
tf.y = 0;
tf.width = 80;
tf.height = 14;
tf.selectable = false;
tf.autoSize = "center";
var btnB:Sprite = new Sprite();
btnB.graphics.beginFill(0x888888);
btnB.graphics.drawRoundRect( 0, 0, 80, 18, 8);
btnB.graphics.endFill();
// テキストフィールドがボタンだと反応しなくなるのでmouseEnabledをfalseに。
tf.mouseEnabled = false;
btn.addChild(btnB);
btn.addChild(tf);
return btn;
}
/**
* ミノの種類を受け取ったら対応するスプライトを返す
* @param colorNum 0:I, 1:J, 2:L, 3:O, 4:S, 5:Z, 6:T
* @param x flash内のx座標
* @param y flash内のy座標
* @param rot 回転状態
* @return
*/
private function createBlock(colorNum:int, x:int, y:int, rot:int):Sprite
{
// trace("受け取った : " + rot);
var sp:Sprite = new Sprite();
var spr:Sprite = new Sprite();
var lng:int = mino[colorNum].length - 1;
var i:int;
var j:int;
for (i = lng; i >= 0; i-- )
{
for (j = lng; j >= 0; j-- )
{
if (mino[colorNum][i][j]) {
spr = new Sprite();
spr = createBox(colorNum);
switch(rot)
{
case 0:
spr.x = x + j * boxSize;
spr.y = y + i * boxSize;
break;
case 1:
spr.x = x + (-i + lng) * boxSize;
spr.y = y + j * boxSize;
break;
case 2:
spr.x = x + (-j + lng) * boxSize;
spr.y = y + (-i + lng) * boxSize;
break;
default:
spr.x = x + i * boxSize;
spr.y = y + (-j + lng) * boxSize;
break;
}
sp.addChild(spr);
}
}
}
return sp;
}
private function createBox(colorNum:int):Sprite
{
var sp:Sprite = new Sprite();
sp.graphics.lineStyle(0.5, 0xaaaaaa);
sp.graphics.drawRect(0 , 0, boxSize, boxSize);
sp.graphics.beginFill(boxColor[colorNum]);
sp.graphics.drawRect(0, 0, boxSize, boxSize);
sp.graphics.endFill();
sp.graphics.lineStyle(1, 0xffffff);
sp.graphics.moveTo(1 , 13);
sp.graphics.lineTo(2 , 2);
sp.graphics.lineTo(13, 1);
return sp;
}
}// end class
}// end package
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.KeyboardEvent;
/******************************************************************************************
* キーの入力状態を更新するクラス
* get KeyFlag()で8ビットのキー入力状況をget!
* 憧れのあの子のハートもget!
******************************************************************************************/
class KeyListner
{
/**
* 変数とか宣言しちゃう
*/
private var _keyFlag:int = new int(0x00);
private var moveL:int = new int(37); // 左移動
private var moveR:int = new int(39); // 右移動
private var lotL:int = new int(29); // 左回転
private var lotR:int = new int(32); // 右回転
private var fallS:int = new int(40); // 落下
private var fallQ:int = new int(38); // 即時落下
private var hold:int = new int(67); // ホールド
/**
* コンストラクタ
*/
public function KeyListner(myStage:Stage):void
{
myStage.addEventListener(KeyboardEvent.KEY_DOWN, keyOn);
myStage.addEventListener(KeyboardEvent.KEY_UP, keyOff);
myStage.addEventListener(Event.DEACTIVATE, keyReset);
}
private function keyOn(event:KeyboardEvent):void
{
switch(event.keyCode)
{
case moveL:
_keyFlag = _keyFlag | 0x40;
break;
case moveR:
_keyFlag = _keyFlag | 0x20;
break;
case lotL:
_keyFlag = _keyFlag | 0x10;
break;
case lotR:
_keyFlag = _keyFlag | 0x08;
break;
case fallS:
_keyFlag = _keyFlag | 0x04;
break;
case fallQ:
_keyFlag = _keyFlag | 0x02;
break
case hold:
_keyFlag = _keyFlag | 0x01;
break;
}
}
private function keyOff(event:KeyboardEvent):void
{
switch(event.keyCode)
{
case moveL:
_keyFlag = _keyFlag & 0xbf;
break;
case moveR:
_keyFlag = _keyFlag & 0xdf;
break;
case lotL:
_keyFlag = _keyFlag & 0xef;
break;
case lotR:
_keyFlag = _keyFlag & 0xf7;
break;
case fallS:
_keyFlag = _keyFlag & 0xfb;
break;
case fallQ:
_keyFlag = _keyFlag & 0xfd;
break
case hold:
_keyFlag = _keyFlag & 0xfe;
break;
}
}
private function keyReset(event:Event):void
{
_keyFlag = 0;
}
public function get keyFlag():int { return _keyFlag; }
}// end class