玩了一星期终于还是把HTA玩坏了。
由于不是专业码农,代码潦草,大意就是4*4记录方块,改用16位数字存储,加移位操作。流行的简化办法。
本来打算JS+SVG,考虑到window的尿性,还是作罢,还是用的JS+DOM。目测window, linux与ios,android(后缀html)都能运行。
 复制到文本文件,后缀改成html或者hta。
目测还有少许BUG,请轻拍。<!DOCTYPE html>
<html>
<!============Head============>
<head>
  <title>TetrisExxx</title>
  <style>div{margin:2px 2px 2px 2px; float:left}</style>
</head><!===========Script===========>
<script>
//global values
//sa=sahpeArray ta=transformArray dy=delay ss=status gs=girdSize ii=intervalID rc=rowCnt cc=colCnt lt=left tp=top
//csi=curShapeIdx ccr=curColor nsi=nextShapeIdx ncr=nextColor me=mode et=environment ga=gridArray
var sa = [0x32,0x31,0x13,0x23,0x70,0x222,//6
  0x33,0x63,0x132,0x36,0x231,0x470,0x322,0x71,0x226,0x170,0x223,0x740,0x622,0x270,0x232,0x72,0x262,0x4444,0xF00,//19
  0x272,0x471,0x326,0x174,0x623,0x75,0x626,0x57,0x323,//9
  0x233,0x76,0x662,0x370,0x266,0x670,0x332,0x73,0x271,0x236,0x472,0x362,0x274,0x632,0x172,0x263,//16
  0x8F00,0x3222,0xF1,0x444C,0x1F,0x2223,0xF8,0xC444,0x4F,0x2322,0xF2,0x44C4,0x2F,0x2232,0xF4,0x4C44];//16
var ta = [1,2,3,0,5,4,
  6,8,7,10,9,12,13,14,11,16,17,18,15,20,21,22,19,24,23,
  25,27,26,29,28,31,32,33,30,
  35,36,37,34,39,40,41,38,43,44,45,42,47,48,49,46,
  51,52,53,50,55,56,57,54,59,60,61,58,63,64,65,62];
var dy,se,ss,gs,ii,ei,ec,rc,cc,lt,tp,csi,ccr,nsi,ncr,me,et,i,j,ga,ra;
//ss
//1:normal running; -1:paused; 2:accelerated; 0:stoppedfunction _x(id){return document.getElementById(id);}function doLoad()
{
  ss=et=0;
  for(i=14;i<=28;++i)
  {
    var op=document.createElement("option");
    op.value=op.innerText=i;
    _x("rcs").appendChild(op);
  }
  _x("rcs").value=rc=16;
  
  for(i=8;i<=16;++i)
  {
    var op=document.createElement("option");
    op.value=op.innerText=i;
    _x("ccs").appendChild(op);
  }
  _x("ccs").value=cc=9;
  
  for(i=20;i<=40;++i)
  {
    var op=document.createElement("option");
    op.value=op.innerText=i;
    _x("gss").appendChild(op);
  }
  _x("gss").value=gs=30;
  
  for(i=0;i<rc*cc;++i)
  {
    grid=document.createElement("div");
    grid.id="A"+i;
    grid.style.cssText="width:30px;height:30px;visibility:hidden;border:solid 1px black";
    _x("bc").appendChild(grid);
  }
  for(i=0;i<16;++i)
  {
    grid=document.createElement("div");
    grid.id="N"+i;
    grid.style.cssText="width:30px;height:30px;visibility:hidden;border:solid 1px black;";
    _x("nc").appendChild(grid);
  }
}function doTransform(dir)
{
  if(interference(dir)) return;
  showCur(false);
  dir==1?--lt:(dir==2?++lt:csi=ta[csi]);
  showCur(true);
}function doAccelerate(v)
{
  if(ss==1&&v>=0)
  {
    window.clearInterval(ii);
    ii=window.setInterval("timer()",50);
    ss=2;
  }
  else if(ss==2&&v<=0)
  {
    window.clearInterval(ii);
    ii=window.setInterval("timer()",dy);
    ss=1;
  }
}function doKeyDown()
{
  switch(window.event.keyCode)
  {
    case 37: doTransform(1);break;
    case 38: doTransform(3);break;
    case 39: doTransform(2);break;
    case 40: doAccelerate(1);break;
    case 80: doPause();break;
    default: break;
  }
}function doKeyUp()
{
  if(window.event.keyCode==40) doAccelerate(-1);
}function doStart()
{
  ra=new Array(48);
  for(i=0;i<48;++i) ra[i]=0;
  if(ss==0)
  {
    ss=1;
    getEnv();
    getMode();
    _x("Start").value="Stop";
    ga = new Array(rc);
    for(i=0;i<rc;++i) ga[i]=0;
    for(i=0;i<rc*cc;++i) _x("A"+i).style.visibility="hidden";
    _x("score").innerText=se=0;
    _x("speed").innerText=(dy=1000)+"ms";
    ncr="rgb("+Math.round(Math.random()*255)+","+Math.round(Math.random()*255)+","+Math.round(Math.random()*255)+")";
    nsi=Math.round(Math.random()*(me>>1))+(me&1)*6;
    showNext();
    ii=window.setInterval("timer()",dy);
    ei=window.setInterval("envTimer()",1000);
    ec=0;
  }
  else
  {
    ss=0;
    _x("Start").value="Start";
    window.clearInterval(ii);
    window.clearInterval(ei);
    for(i=0;i<rc*cc;++i) _x("A"+i).style.visibility="hidden";
  }
}function showNext()
{
  csi=nsi;
  ccr=ncr;
  lt=(cc>>1)-2;
  tp=sa[csi]&0xF?-4:(sa[csi]&0xF0?-3:-2);
  ncr="rgb("+Math.round(Math.random()*255)+","+Math.round(Math.random()*255)+","+Math.round(Math.random()*255)+")";
  nsi=Math.round(Math.random()*(me>>1))+(me&1)*6;
  for(i=0;i<16;++i)
  {
    _x("N"+i).style.visibility=(sa[nsi]&(0x8000>>i))?"":"hidden";
    _x("N"+i).style.backgroundColor=ncr;
  }
}function timer()
{
  if(interference(0))
  {
    if(tp<0)
    {
      window.clearInterval(ii);
      if(et) window.clearInterval(ei);
      alert("Game Over.");
    }
    else
    {
      if(et&4) showCur(true);
      clear();
      showNext();
    }
  }
  else
  {
    showCur(false);
    ++tp;
    if(!(et&4))showCur(true);
  }
}function envTimer()
{
  if(++ec==0xFFFF)ec=0;
  if((et&1)&&!(ec%2))
  {
    showCur(false);
    if(!interference(2)) ++lt;
    else if(!interference(1)) --lt;
    showCur(true);
  }
  if((et&2)&&!(ec%2))
  {
    var fr=Math.round(Math.random()*(rc-1));
    var fc=Math.round(Math.random()*(cc-1));
    ga[fr]|=(1<<fc);
    ga[fr]-=(1<<fc);
    _x("A"+(fr*cc+fc)).style.visibility="hidden";
  }
  if((et&8)&&!(ec%10))
  {
    if(interference(0))
    {
      clear();
      showNext();
    }
    for(i=0;i<rc;++i)
    {
      ga[i]=i+1<rc?ga[i+1]:Math.round(Math.random()*((1<<cc)-1));
      for(j=0;j<cc;++j) _x("A"+(i*cc+j)).style.visibility = (ga[i]&(1<<j))?"":"hidden";
    }
    showCur(true);
  }
}//0:down; 1:left; 2:right; 3:rotate
//false: no interference
function interference(direction)
{
  for(i=0; i<16; ++i)
  {
    if(direction==0 && (sa[csi]&(0x8000>>i)))
    {
      if(tp+(i>>2)>=rc-1) return true;
      if((sa[csi]&(0x8000>>(i+4)))==0 && tp+(i>>2)>=0 && (ga[tp+(i>>2)+1]&(1<<(lt+i%4)))) return true;
    }
    if(direction==1 && (sa[csi]&(0x8000>>i)))
    {
      if((lt+i%4)%cc==0) return true;
      if((sa[csi]&(0x8000>>(i-1)))==0 && tp+(i>>2)>=0 && (ga[tp+(i>>2)]&(1<<(lt-1+i%4)))) return true;
    }
    if(direction==2 && (sa[csi]&(0x8000>>i)))
    {
      if((lt+1+i%4)%cc==0) return true;
      if((sa[csi]&(0x8000>>(i+1)))==0 && tp+(i>>2)>=0 && (ga[tp+(i>>2)]&(1<<(lt+1+i%4)))) return true;
    }
    if(direction==3 && (sa[ta[csi]]&(0x8000>>i)))
    {
      if((tp+(i>>2)>=rc) || (lt+(i%4)<0) || (lt+(i%4)>=cc)) return true;
      if((sa[csi]&(0x8000>>i))==0 && tp+(i>>2)>=0 && (ga[tp+(i>>2)]&(1<<(lt+i%4)))) return true;
    }
  }
  return false;
}function clear()
{
  for(i=0;i<16;++i)
  {
    if(sa[csi]&(0x8000>>i)) ga[tp+(i>>2)]|=(1<<(lt+i%4));
  }
  var tag=0;
  for(i=rc-1;i>=0;)
  {
    if(tag) ga[i]=(i-tag>=0)?ga[i-tag]:0;
    if(ga[i]==(1<<cc)-1)
    {
      ++tag;
      continue;
    }
    else --i;
  }
  if(tag)
  {
    _x("score").innerText=(se+=tag);
    if(se%10==0&&dy>10)
    {
      dy=Math.round(0.8*dy);
      _x("speed").innerText=dy+"ms";
    }
    for(i=rc-1;i>=0;--i)
    {
      for(j=0;j<cc;++j) _x("A"+(i*cc+j)).style.visibility=(ga[i]&(1<<j))?"":"hidden";
    }
  }
}function doPause()
{
  if(ss==-1) ii=window.setInterval("timer()",dy);
  else window.clearInterval(ii);
  ss=(ss==-1?1:-1);
  _x("Pause").value=(ss==1?"Pause":"Continue");
}function doChangeRow()
{
  var rcp=rc;
  var grid;
  rc=_x("rcs").value;
  for(i=rcp*cc;i<rc*cc;++i)
  {
    grid=document.createElement("div");
    grid.id="A"+i;
    grid.style.cssText="width:"+gs+"px;height:"+gs+"px;visibility:hidden;border:solid 1px black";
    _x("bc").appendChild(grid);
  }
  for(i=rc*cc;i<rcp*cc;++i) _x("A"+i).parentElement.removeChild(_x("A"+i));
  changeLayout();
}function doChangeCol()
{
  var ccp=cc;
  cc=_x("ccs").value;
  for(i=ccp*rc;i<cc*rc;++i)
  {
    grid=document.createElement("div");
    grid.id="A"+i;
    grid.style.cssText="width:"+gs+"px;height:"+gs+"px;visibility:hidden;border:solid 1px black";
    _x("bc").appendChild(grid);
  }
  for(i=cc*rc;i<ccp*rc;++i) _x("A"+i).parentElement.removeChild(_x("A"+i));
  changeLayout();
}function doChangeGrid()
{
  gs=_x("gss").value;
  for(i=0;i<rc*cc;++i)
  {
    _x("A"+i).style.width=gs+"px";
    _x("A"+i).style.height=gs+"px";
  }
  for(i=0;i<16;++i)
  {
    _x("N"+i).style.width=gs+"px";
    _x("N"+i).style.height=gs+"px";
  }
  changeLayout();
}function changeLayout()
{
  _x("tc").style.width=(gs*cc+6*cc+212)+"px";
  _x("tc").style.height=((gs*rc+6*rc)>700?(gs*rc+6*rc)+6:706)+"px";
  _x("bc").style.width=(gs*cc+6*cc)+"px";
  _x("bc").style.height=(gs*rc+6*rc)+"px";
  _x("nc").style.width=(gs*4+24)+"px";
  _x("nc").style.height=(gs*4+24)+"px";
}function getMode()
{
  for(i=0;i<6;++i) if(_x("me"+i).checked) me=_x("me"+i).value;
}function getEnv()
{
  et=0;
  for(i=0;i<4;++i) if(_x("et"+i).checked) et|=(1<<i);
}function showCur(bShow)
{
  for(i=0;i<16;++i)
  {
   if(tp+(i>>2)<0) continue;
    if(sa[csi]&(0x8000>>i))
    {
      _x("A"+((tp+(i>>2))*cc+lt+i%4)).style.visibility=bShow?"":"hidden";
      _x("A"+((tp+(i>>2))*cc+lt+i%4)).style.backgroundColor=ccr;
    }
  }
}
</script>

解决方案 »

  1.   

    body在这里。<!============Body============>
    <body onLoad="doLoad()" onKeyDown="doKeyDown()" onKeyUp="doKeyUp()">
      <div id="tc" style="width:536px; height:706px;border:1px solid blue;">
        <div id="bc" style="border:solid 1px blue; width:324px; height:576px;"></div>
        <div id="ic" style="width:200px;height:700px; border:1px solid blue">
          <span>Score:</span><span id="score">0</span><br>
          <span>Speed:</span><span id="speed">0</span><br>
          <span>Next:</span>
          <div id="nc" style="border:solid 1px blue; width:144px; height:144px;float:none"></div><hr>
          <span>Mode:</span><br>
          <input type="radio" id="me0" name="mode" value="10">Child<br>
          <input type="radio" id="me1" name="mode" value="48">Easy<br>
          <input type="radio" id="me2" name="mode" value="37" checked>Basic<br>
          <input type="radio" id="me3" name="mode" value="55">Advanced<br>
          <input type="radio" id="me4" name="mode" value="87">Master<br>
          <input type="radio" id="me5" name="mode" value="119">What's The Hell?<hr>
          <span>Environment:</span><br>
          <input type="checkbox" id="et0">Wind<br>
          <input type="checkbox" id="et1">Rain<br>
          <input type="checkbox" id="et2">Fog<br>
          <input type="checkbox" id="et3">Earthquake<hr>
          <span>Row Count:</span><select id="rcs" size="0" onChange="doChangeRow()"></select><br>
          <span>Col Count:</span><select id="ccs" size="0" onChange="doChangeCol()"></select><br>
          <span>Grid Size:</span><select id="gss" size="0" onChange="doChangeGrid()"></select><hr>
          <input type="button" id="Start" value="Start" style="width:40%;margin:2px 2px 2px 2px" onClick="doStart()">
          <input type="button" id="Pause" value="Pause" style="width:40%;margin:2px 2px 2px 2px" onClick="doPause()"><hr>
          <input type="button" value="Rotate" style="width:40%;margin:2px 2px 2px 2px" onClick="doTransform(3)">
          <input type="button" value="Accelerate" style="width:40%;margin:2px 2px 2px 2px" onClick="doAccelerate(0)">
          <input type="button" value="Left" style="width:40%;margin:2px 2px 2px 2px" onClick="doTransform(1)">
          <input type="button" value="Right" style="width:40%;margin:2px 2px 2px 2px" onClick="doTransform(2)">
        </div>
      </div>
    </body>
    </html>
      

  2.   

    有点变态。。不过那是What the hell
    不是What's the hell