/**
* Copyright 12346 ( http://wonderfl.net/user/12346 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/uUTk
*/
/*
この作品は「カスケード」のルールを含んだテトリスです。
操作方法
矢印キー左右:テトロミノを左右に移動
矢印キー上 :テトロミノを瞬間的に落下
矢印キー下 :テトロミノを速めに落下
zキー :テトロミノを左回転
xキー :テトロミノを右回転
スペースキー: 〃
基本ルール
制限時間以内に、ステージ上にある茶色いX印のブロックを
全て消せばステージクリア。
ステージが進むにつれて、テトロミノの落下が速くなり、
X印のブロックが高いところまで出現するようになります。
カスケードについて
テトロミノが落下した後、同じ色同士のブロックはくっつき、
ひとつの塊になります。(以下、ブロック1つも塊と表記)
塊の下に落ちるスペースがあれば、塊はその形のまま下に落
ちてくれます。
塊の落下によって横一列そろったラインも消すことができ、
落下した後も同じ色と触れていればそれらはくっつきます。
ただし、X印のブロックの落下は期待してはいけません。
点数計算
何列か消えた後、カスケードしたブロックでまたさらに列を
消すと、連鎖となります。
このときの連鎖数と、何列同時に消したかで点数が計算され
ます。
5×(同時に消した列数+1)×連鎖数
また、ステージクリア後の残り時間もタイムボーナスとして
計算されます。
残り時間×3
その他どうでもよいこと
・スコアが1万を超えた方は作者を上回っている可能性が高
いです。
・レベルが高くなると、開始と同時にgame overなんていう
惨劇があったので、レベルは20で停滞するようにしました。
・カスケードによる連鎖を楽しんでほしいのでホールドは実
装しませんでした(サボり)
・http://ja.wikipedia.org/wiki/%E3%83%86%E3%83%88%E3%83%AA%E3%82%B9#.E3.82.AC.E3.82.A4.E3.83.89.E3.83.A9.E3.82.A4.E3.83.B3
ガイドラインってなんだよー。作り始める前に教えてくれ
よー。色とか結構違うじゃん。
・2人対戦用のも作ったけど画面が狭いのでWonderflには
出しません。
・制限時間が短すぎると言われそうな気がしてならない。
そのうち修正しようか・・・?
・下のほうのXを消したときの挙動が、既知のバグ。
直すためにはその為だけの判定用プロパティが必要かも。
面倒だからたぶん直さない。ごめんなさい。
・スコアランキング?何それ?
・コードは見ないほうが・・・身のためです・・
読みづらさが高められています。そういう趣味です。
*/package{import flash.display.*;import flash.events.*
[SWF(backgroundColor=0,frameRate=60)]
public class M extends Sprite{
public var P:G,B:Z,V:Boolean,
X:Array=[[6,6,7,6],[6,7,7,6],[6,6,6,6],[6,7,7,6],[7,7,7,6],[6,5,7,6],[6,7,7,6]],
Y:Array=[[1,0,0,2],[1,1,2,0],[1,2,0,3],[1,0,1,2],[1,0,2,0],[0,0,0,1],[1,0,1,0]]
public function M():void{addChild(P=new G(this)).x=100;P.y=32
addChild(B=new Z("start")).x=250;B.y=160,B.u=S
stage.addEventListener("keyDown",K);P.t.S("Press start")}
public function S():void{B.text="restart",P.t.S("game start");P.I(),P.b()}
public function K(e:KeyboardEvent):void{if(P.k)switch(e.keyCode-37){
case 0:if(P.g.L()){if(P.c)P.c=20;P.g.X(-1)}break
case 1:P.g.V();break
case 2:if(P.g.R()){if(P.c)P.c=20;P.g.X(1)}break
case 3:P.d=true;break
case-5:case 51:P.g.O(-1);break
case 53:P.g.O(1)}}
}}
import flash.display.*;import flash.events.*;import flash.text.*;
class B extends Bitmap{
public var $:G,X:int,Y:int,w:Number,a:int,H:Boolean,I:Boolean,C:Boolean=true
public function B(_:G,_X:int,_Y:int,A:int){$=_;x=(X=_X)*16;y=(w=Y=_Y)*16
bitmapData=J.b[a=A].clone();addEventListener("enterFrame",v)}
public function v(e:Event):void{var _:Number=X*16-x;if(_)-2<_&&_<2?x=X*16:x+=_>>1}
public function D():Boolean{return Y<24&&!$.a.q[Y+1][X]}
public function R():Boolean{return X<7&&!$.a.q[Y][X+1]&&(y-Y*16?!$.a.Q(X+1,Y-1):1)}
public function L():Boolean{return X>0&&!$.a.q[Y][X-1]&&(y-Y*16?!$.a.Q(X-1,Y-1):1)}
public function o(b:B,u:int):void{
for(var s:int,t:int,c:uint=J.c[a],i:int=15;--i;)s=u-1?u-3?i:0:15,t=u-2?u?i:0:15,
bitmapData.setPixel(s,t,c),b.bitmapData.setPixel(15-s,15-t,c)}
public function c(b:B,u:Boolean):void{var i:int=15,c:uint=J.c[b.a]
for(c=u?0x333333|c:0xcccccc&c;--i;)b.bitmapData.setPixel(i,u?0:15,c)}
public function n():void{
if($.a.Q(X+1,Y)&&$.a.z.a==a&&!$.a.z.I)I=false
if($.a.Q(X-1,Y)&&$.a.z.a==a&&!$.a.z.I)I=false}
public function F():void{H=I=false;y=Y*16;$.a.q[Y][X]=this
if(C)f(0,-1,0),f(1,0,1),f(0,1,2),f(-1,0,3),C=false}
private function f(s:int,t:int,u:int):void{if(!$.a.Q(X+s,Y+t))return
if($.a.z)$.a.z.a-a||o($.a.z,u)}
public function d():Boolean{
if(Y>23||($.a.Q(X,Y+1)&&!$.a.z.I))return I=false
if(0<X)if($.a.Q(X-1,Y)&&$.a.z.a==a)if($.a.z.H)if(!$.a.z.I)return I=false
if(X<7)if($.a.Q(X+1,Y)&&$.a.z.a==a)if($.a.z.H)if(!$.a.z.I)return I=false
if(Y>1)if($.a.Q(X,Y-1)&&$.a.z.a==a)if($.a.z.H)if(!$.a.z.I)return I=false
return true}
public function N():void{C=true,$.a.q[Y++][X]=null,$.a.q[Y][X]=this}
public function P():void{H=I=false;$.a.q[Y][X]=null;if(a>6)$.Y--
if($.a.Q(X,Y-1))$.a.z.a-a||c($.a.z,false);if($.a.Q(X,Y+1))$.a.z.a-a||c($.a.z,true)}
}
class G extends Sprite{
public var $:M,l:int,f:Number,k:Boolean=false,c:int,h:int=25,d:Boolean,
v:Vector.<B>=new Vector.<B>,w:Vector.<B>=new Vector.<B>,n:int,r:int,Y:int,
p:Vector.<Vector.<B>>=new Vector.<Vector.<B>>(4),s:int,g:Q,a:J,t:T,u:U
public function G(_:M):void{
g=new Q(this),a=new J,t=new T(this),u=new U(this);$=_
for(var i:int=25;i--;)a.q[i]=new Vector.<B>(8)
for(graphics.lineStyle(0,0x404040);++i<8;)graphics.moveTo(i*16+15,0),graphics.lineTo(i*16+15,400)
for(graphics.lineTo(0,400),graphics.lineStyle(0,0x202020);i--;)graphics.moveTo(i*16,0),graphics.lineTo(i*16,400)
}
public function I():void{R(m),R(o),R(q),R(D),R(t.E);k=false;Y=l=s=0,f=.0078125
for(var j:int,i:int=25;i--;)for(j=8;j--;)if(a.q[i][j])removeChild(a.q[i][j]),a.q[i][j]=null
for(i=p.length;i--;p[i]=null)if(p[i])for(j=4;j--;)removeChild(p[i][j]),p[i][j]=null
}
public function m(e:Event):void{
if(c){if(g.D())c=0;else --c||F();return}
for each(var b:B in p[0]){d?b.y=(b.w+=.5)*16:b.w+=f;b.y<b.w*16&&b.y++}d=false
if(b.y>=b.Y*16){if(!g.D()){c=60;for each(b in p[0])b.y=b.Y*16;return}for each(b in p[0])b.Y++}}
public function o(e:Event):void{for each(var b:B in v)b.y+=2;if(!--c){
for each(b in v)b.N();V();C();S();V();n?c=8:(R(o),N())}}
public function q(e:Event):void{d=false;if(p[0][3].x==48){R(q);
for each(var b:B in p[0])if(a.q[b.Y][b.X])return O();A(m),k=true}}
public function F():void{k=false;var i:int,j:int=4,b:B;g.F();
if(C()){p.shift();return}for each(b in p[0])b.H=b.I=true;for each(b in p[0])b.n()
do{i=j;for each(b in p[0])if(b.I)if(!b.d())b.I=false,j--}while(j-i)
for each(b in p.shift())b.H=false;S();V();R(m);n?(c=8,A(o)):N()}
public function H(l:int):Boolean{for each(var b:B in a.q[l])if(!b||b.I)return false
addChild(new W(a.q[l]));return true}
public function C():Boolean{
for(var i:int=-1,j:int=0,k:int=0,b:B;++i<25;)if(H(i))j=24,k++
if(j>0){while(j--)for each(b in a.q[j])if(b)b.I=true;s+=j=5*(1+k)*++r
t.S(k+" line(s)"+(r-1?", "+r+" chain ":" ")+j+" points")}if(Y)return false
t.S("stage clear"),R(m),R(o),R(t.E),s+=j=t.C*3
t.S("time bonus : "+j),A(D),c=1,h=25;return true}
public function S():void{v.length=n=0;
for(var b:B,i:int=25;i--;)for each(b in a.q[i])if(b&&b.I)v.push(b),n++,b.H=true}
public function V():void{var i:int,j:int
do{for(i=j=n;i--;)if(!v[i].d())w.push(v.splice(i,1)[0]),n--}while(j-n);L()}
public function L():void{for each(var b:B in w)b.F();w.length=0}
public function b():void{for(var j:int,k:int,i:int=4;i--;)p[i]=P(i);if(++l>20)l=20;
f+=1/512;g.v=p[0];
for(i=4;i--;)p[0][i].X-=3;t.S("----------"),t.S("level "+l+" start"),t.B()
for(i=l+1;i--;)for(k=Math.random()*8|0,j=8;j--;)if(j-k&&j+k-8?Math.random()<.25:1)
addChild(a.q[24-i][j]=new X(this,j,24-i)),Y++;A(q)}
public function O():void{k=false;R(m),R(o),R(q),A(D),R(t.E)
f=c=0,h=25,$.B.text="start",t.S("game over")}
public function D(e:Event):void{if(!c--)c=4,addChild(new W(a.q[--h]));if(!h){
for(var j:int,i:int=p.length;i--;p[i]=null)if(p[i])for(j=4;j--;)
removeChild(p[i][j]),p[i][j]=null;R(D),f&&b()}}
public function N():void{A(q);var i:int=3,j:int;p[3]=P(3);g.v=p[r=0];
while(i--)for(j=4;j--;)p[i][j].X-=i?4:7}
public function P(w:int):Vector.<B>{for(var r:Vector.<B>=new Vector.<B>(4),
a:int=7*Math.random(),i:int=4;i--;)addChild(r[i]=new B(this,w*4+$.X[a][i],
$.Y[a][i],Math.random()<.75?a:a?a-1:6));return r}
public function A(f:Function):void{addEventListener("enterFrame",f)}
public function R(f:Function):void{removeEventListener("enterFrame",f)}
}
class J{
public static const c:Array=[255,0xff00,0xffff,0xff0000,0xff00ff,0xffff00,0xaaaaaa,
0x660000],b:Vector.<BitmapData>=V()
public static function C(c:uint):BitmapData{
for(var i:int=16,r:BitmapData=new BitmapData(i,i,false,c);i--;)
r.setPixel(0,i,0x333333|c),r.setPixel(i,0,0x333333|c)
for(i=16;--i;)r.setPixel(15,i,0xcccccc&c),r.setPixel(i,15,0xcccccc&c)
return r}
public static function V():Vector.<BitmapData>{
for(var r:Vector.<BitmapData>=new Vector.<BitmapData>(8),
i:int=8;i--;)r[i]=C(c[i])
for(i=15;--i;)r[7].setPixel(i,i,0x440000),r[7].setPixel(i,15-i,0x440000)
return r}
public var q:Vector.<Vector.<B>>=new Vector.<Vector.<B>>(25),z:B
public function P(X:int,Y:int):Boolean{return -1<X&&X<8&&-1<Y&&Y<25}
public function Q(X:int,Y:int):Boolean{z=null;return P(X,Y)&&(z=q[Y][X])}
public function I():void{for(var j:int,i:int=25;i--;)for(j=8;j--;)q[i][j]=null}
}
class Q{
public var $:G,b:B,v:Vector.<B>
public function Q(_:G){$=_}
public function D():Boolean{for each(b in v)if(!b.D())return false;return true}
public function R():Boolean{for each(b in v)if(!b.R())return false;return true}
public function L():Boolean{for each(b in v)if(!b.L())return false;return true}
public function X(d:int):void{for each(b in v)b.X+=d}
public function Y(d:int):void{for each(b in v)b.Y+=d}
public function F():void{for each(b in v)b.F(),b.removeEventListener("enterFrame",b.v)}
public function V():void{while(D())Y(1);for each(b in v)b.y=(b.w=b.Y)*16;$.c=20}
public function O(r:int):void{$.u.r=r
for(var x:Vector.<int>=new Vector.<int>(4),y:Vector.<int>=new Vector.<int>(4),
j:int=0,i:int=-1;++i<4;)x[i]=v[i].X,y[i]=v[i].Y
for(;--i;)v[i].Y=y[0]+(x[0]-x[i])*r,v[i].X=x[0]+(y[i]-y[0])*r,
j|=v[i].X>7?v[i].X-7:0,j|=v[i].X<0?-v[i].X:0;if(j)j=j&2?2:1,X(x[0]>3?-j:j)
for(i=4;i--;)
j|=v[i].Y>24?v[i].Y-24:0,j|=v[i].Y<0?-v[i].Y:0;if(j)j=j&2?2:1,Y(y[0]>9?-j:j)
j=-1;while(++j<3){for(i=-1;++i<4;)v[i].Y+=j-2?-j:j
for(;i--;)if(!$.a.P(v[i].X,v[i].Y)||$.a.Q(v[i].X,v[i].Y))break
if(i<0)return o(0);if(r<0&&R())return o(1);if(L())return o(-1);if(R())return o(1)}
for(i=4;i--;)v[i].X=x[i],v[i].Y=y[i]
}
private function o(X:int):void{var Y:int=v[0].Y,y:Number=v[$.c=0].w,
_:Number=Y-1<y&&y<Y?y-Y:-1
if(Y-1-y|0)_=0;for each(b in v)b.x=(b.X+=X)*16,b.y=(b.w=b.Y+_)*16;$.u.R(v)
}
}
class T{
public var t:TextField=new TextField,C:int,$:G,c:int,
m:TextField=new TextField,v:Vector.<String>=Vector.<String>(["","","","","",""])
public function T(_:G){$=_;$.addChild(t).x=$.addChild(m).x=150,m.y=300,t.y=230
m.border=true,m.width=140,t.textColor=0xffffff;m.borderColor=m.textColor=0xffffff
}
public function B():void{C=$.l*20+60;c=60;$.A(E);$.A(D)}
public function E(e:Event):void{if(!--c)c=60,--C||$.O()}
private function D(e:Event):void{t.text="LV: "+$.l+"\nscore: "+$.s+"\ntime: "+C}
public function S(s:String):void{
m.text="";v.pop();v.unshift(s);for each(s in v)m.appendText(s+"\n")
}
}
class U{
public var r:int,t:int=5,P:Sprite=new Sprite,b:B,V:Vector.<B>;
private static const S:Vector.<int>=Vector.<int>([0,10,29,52,64]),
C:Vector.<int>=Vector.<int>([64,63,57,38,0])
public function U(_:G){_.addChild(P)}
public function R(v:Vector.<B>):void{
for(t=4,V=v;t--;)P.addChild(b=v[t]);t=5;P.addEventListener("enterFrame",E)
}
private function E(e:Event):void{
if(!t--){for(t=4;t--;)P.parent.addChild(V[t]);return P.removeEventListener("enterFrame",E)}
var X:int=b.x+8,Y:int=b.y+8,s:int=S[t],c:int=C[t]
P.x=X+(s*Y*r-c*X>>6);P.y=Y-(s*X*r+c*Y>>6);P.rotation=r*4.5*t*(t+1)
}
}
class W extends Sprite{private var d:int=-8
public function W(v:Vector.<B>){x=64,addEventListener("enterFrame",E)
for(var i:int=8;i--;)if(v[i])addChild(v[i]).x-=64,v[i].P()}
private function E(e:Event):void{y+=++d>>2;width++;alpha-=.03125
if(d>32)removeEventListener("enterFrame",E),parent.removeChild(this)}
}
class X extends B{
public function X(_:G,_X:int,_Y:int){super(_,_X,_Y,7);removeEventListener("enterFrame",v)}
public override function d():Boolean{
if(Y>23)return I=false;for(var i:int=8;i--;)if($.a.q[Y+1][i])return I=false
return I=true}
public override function o(b:B,u:int):void{}
}
class Z extends TextField{
public var u:Function=null
public function Z(s:String){border=background=true,borderColor=textColor=0xcccccc
backgroundColor=0x222222,height=18,width=90,selectable=false
var f:TextFormat=new TextFormat("_等幅");f.align="center",defaultTextFormat=f
text=s;addEventListener("mouseDown",D),addEventListener("mouseUp",U)}
private function D(e:MouseEvent):void{backgroundColor=0x666666}
private function U(e:MouseEvent):void{backgroundColor=0x222222;if(u!=null)u()}
}