JavaScript 寫遊戲 : 搬運工

<title>dwin.net - web application - sokoban</title>
<body>
Written by David NG @ <a href="http://dwin.net">http://dwin.net</a><BR>
Copyright(c) 1998-2007 dwin.net all rights reserved<BR>
<style>
.Ground{}
.Floor{}
.Wall{overflow:hidden;border:2px outset #ADFF2F;background-color:#888888;z-index:0}
.Aim{overflow:hidden;background-color:#FF69B4;opacity:0.4;-moz-opacity:0.4;filter:Alpha(opacity=100,FinishOpacity=0,Style=3);z-index:0}
.Box{overflow:hidden;background-color:#87CEFA;opacity:0.5;-moz-opacity:0.5;filter:Alpha(opacity=0,FinishOpacity=100,Style=3);z-index:1}
.Man{overflow:hidden;z-index:1;}
</style>
<br>
Current Map : <input id="CurrentMap" size=5 ><br>
<input type=button value='Previous Map' οnmοusedοwn='ChangeMap(-1)'>
<input type=button value='Next Map' οnmοusedοwn='ChangeMap(1)'><br><br>

<textarea id="SolutionInfo" style="word-wrap:break-word; word-break:break-all"  wrap="virtual" rows=20></textarea><br>
<input type=button value='copy' οnclick='document.getElementById("SolutionInfo").select();document.execCommand("Copy")'>
<input type=button value='paste' οnclick='document.getElementById("SolutionInfo").focus();if(!/[^(l|r|u|d|L|R|U|D)]/g.exec(window.clipboardData.getData("Text")))document.execCommand("Paste")'>
<input type=button value='Clear' οnclick='document.getElementById("SolutionInfo").value=""'>
<input type=button value='Auto Run' οnmοusedοwn='AutoRun()'><br><br>

Boxes has Moved<br><input id=BoxMoveInfo readonly> Steps<br>
Man has Moved<br><input id=ManMoveInfo readonly> Steps

<div id=Base style='position:absolute;overflow:hidden'></div>
<script>
// firefox
if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.insertAdjacentElement)
{
 HTMLElement.prototype.insertAdjacentElement = function(where,parsedNode)
 {
  switch( where )
  {
   case 'beforeBegin':
    this.parentNode.insertBefore(parsedNode,this)
    break;
   case 'afterBegin':
    this.insertBefore(parsedNode,this.firstChild);
    break;
   case 'beforeEnd':
    this.appendChild(parsedNode);
    break;
   case 'afterEnd':
    if (this.nextSibling)
     this.parentNode.insertBefore(parsedNode,this.nextSibling);
    else
     this.parentNode.appendChild(parsedNode);
    break;
  }
 }

 HTMLElement.prototype.insertAdjacentHTML = function(where,htmlStr)
 {
  var r = this.ownerDocument.createRange();
  r.setStartBefore(this);
  var parsedHTML = r.createContextualFragment(htmlStr);
  this.insertAdjacentElement(where,parsedHTML)
 }

 HTMLElement.prototype.insertAdjacentText = function(where,txtStr)
 {
  var parsedText = document.createTextNode(txtStr)
  this.insertAdjacentElement(where,parsedText)
 }
}

 

 

/*
Written by David NG @ http://dwin.net
Copyright(c) 1998-2004 dwin.net all rights reserved

Start:   2002-10-02 17:50
Finish:  2002-10-15 22:41

2003-06-11 18:55
bug fix

2007-08-08 19:44
firefox support
*/
Map = [];
Solution = [];
FormatAry = [];
CurrentMapPtr = 0;

function init( MapPtr )
{
 MainMap = [];
 CurrentMapPtr = MapPtr;
 FormatPtr = 0;
 MaxWidth = 0;

 RePlayTime = 100 //million second
 MapW = MapH = 30;
 PushScrollNo = 30;
 BoxCompletes = 0;
 TotalBox = 0;

 Timer = null;
 canMove = true
 BoxMoves = 0;
 Count = -1;
 BackRecord = [];
 document.getElementById('BoxMoveInfo').value = 0;
 document.getElementById('ManMoveInfo').value = 0;
 document.getElementById('CurrentMap').value = CurrentMapPtr;
 document.getElementById('SolutionInfo').value = Solution[CurrentMapPtr]; 
}

 

 

function ReadMap( MapPtr )
{
 init( MapPtr );
 
 for( var y=0; y<Map[MapPtr].length; y++ )
 {
  if( Map[MapPtr][y].indexOf('$') != -1 )
   FormatPtr = 1;
  if( MaxWidth < Map[MapPtr][y].length )
   MaxWidth = Map[MapPtr][y].length;
 }
 var h = Map[MapPtr].length*MapW;
 var w = MaxWidth*MapW; 
 var baseObj = document.getElementById('Base')
 baseObj.innerHTML = '';
 baseObj.style.width = w;
 baseObj.style.height = h;
 baseObj.style.left = (w>document.body.clientWidth)?0:(document.body.offsetWidth-w)/2;
 baseObj.style.top = 10;

 for( var y=0; y<Map[MapPtr].length; y++ )
 {
  MainMap[y] = new Array(MaxWidth)
  for( var x=0; x<MaxWidth; x++ )
  {
   try{ MainMap[y][x] = Map[MapPtr][y].charAt(x); }
   catch(e){ MainMap[y][x] = FormatAry[FormatPtr].Floor; }

   if( MainMap[y][x] == FormatAry[FormatPtr].Wall )
    iHtml( x, y, 'Wall' );
   else
   {
    iHtml( x, y, 'Ground' );
    switch( MainMap[y][x] )
    {
     case FormatAry[FormatPtr].Box : iBox(x,y,0);
             break;
     case FormatAry[FormatPtr].Aim : iHtml(x,y,'Aim');
             break;
     case FormatAry[FormatPtr].BoxOnAim : iHtml(x,y,'Aim');
              iBox(x,y,1);
              BoxCompletes++;
              break;
     case FormatAry[FormatPtr].Player : iMan(x,y,0);
              break;
     case FormatAry[FormatPtr].PlayerOnAim : iHtml(x,y,'Aim');
               iMan(x,y,1);
               break;
    }
   }
  }
 }
}

 

function iHtml( x, y, k )
{
 document.getElementById('Base').insertAdjacentHTML("beforeEnd","<span style='position:absolute;left:"+x*MapW+";top:"+y*MapH+";width:"+MapW+";height:"+MapH+"' class='"+k+"' x="+x+" y="+y+">");
}

 

function iBox( x, y, k )
{
 var obj = document.createElement("span");
 obj.style.position = 'absolute';
 obj.style.left = x*MapW;
 obj.style.top = y*MapH;
 obj.style.width = MapW;
 obj.style.height = MapH;
 obj.className = 'Box';
 obj.setAttribute('class','Box');
 obj.setAttribute('complete', k);

 document.getElementById('Base').appendChild( obj );
 MainMap[y][x] = obj;
 TotalBox++;
}

 

function iMan( x, y, k)
{
 Man = document.createElement("img");
 Man.src = 'http://dwin.net/webapp/cow.gif';
 Man.style.position = 'absolute';
 Man.style.left = x*MapW;
 Man.style.top = y*MapH;
 Man.style.width = MapW;
 Man.style.height = MapH;
 Man.className = 'Man';
 Man.setAttribute('class','Man');
 Man.setAttribute('x',x);
 Man.setAttribute('y',y);

 document.getElementById('Base').appendChild( Man );
 MainMap[y][x] = (k==0)?FormatAry[FormatPtr].Floor:FormatAry[FormatPtr].Aim;
}

 

 

 

 


function Dir( x, y, k)
{
 if( !canMove || y+(Man.getAttribute('y')|0)<0 || y+(Man.getAttribute('y')|0)>=Map[CurrentMapPtr].length || x+(Man.getAttribute('x')|0)<0 || x+(Man.getAttribute('x')|0)>=MaxWidth )
  return


 var ManFront = MainMap[y+(Man.getAttribute('y')|0)][x+(Man.getAttribute('x')|0)];
 
 if( ManFront==FormatAry[FormatPtr].Floor || ManFront==FormatAry[FormatPtr].Aim )
 {
  if( k != null )
   Move1( x, y, k.toLowerCase() );
  else
   Move1(x,y);
 }
 else
 {
  if( typeof(ManFront) == 'object' )
  {
  
   var ManFrontFront = MainMap[2*y+(Man.getAttribute('y')|0)][2*x+(Man.getAttribute('x')|0)];

   if( ManFrontFront == FormatAry[FormatPtr].Floor )
   {
    if( k != null )
     Move1( x, y, k.toUpperCase() );
    else
     Move1( x, y );
    Move2( ManFront, x, y );
   }
   else if( ManFrontFront == FormatAry[FormatPtr].Aim )
   {
    if( k != null )
     Move1( x, y, k.toUpperCase() );
    else
     Move1( x, y );
    Move3( ManFront, x, y );
   }
   BoxMoves++
  }
 }
}

 

function Move1( x, y, k)
{
 if( k != null )
 {
  BackRecord[++Count] = k
  BackRecord.length = Count+1
 }
 Man.setAttribute('x', x+(Man.getAttribute('x')|0) );
 Man.setAttribute('y', y+(Man.getAttribute('y')|0) );
 Man.style.left = (Man.getAttribute('x')|0)*MapW;
 Man.style.top  = (Man.getAttribute('y')|0)*MapH;
}

 

function Move2( obj, x, y)
{
 obj.style.left = (x+(Man.getAttribute('x')|0))*MapW;
 obj.style.top  = (y+(Man.getAttribute('y')|0))*MapH;
 MainMap[y+(Man.getAttribute('y')|0)][x+(Man.getAttribute('x')|0)] = obj;

 if( obj.getAttribute('complete') == 0 )
  MainMap[Man.getAttribute('y')|0][Man.getAttribute('x')|0]=FormatAry[FormatPtr].Floor;
 else
 {
  MainMap[Man.getAttribute('y')|0][Man.getAttribute('x')|0] = FormatAry[FormatPtr].Aim;
  BoxCompletes --;
 }
 obj.setAttribute('complete', 0);
}

 

function Move3( obj, x, y)
{
 obj.style.left = (x+(Man.getAttribute('x')|0))*MapW;
 obj.style.top  = (y+(Man.getAttribute('y')|0))*MapH;
 MainMap[y+(Man.getAttribute('y')|0)][x+(Man.getAttribute('x')|0)] = obj;

 if( obj.getAttribute('complete') == 1 )
  MainMap[Man.getAttribute('y')|0][Man.getAttribute('x')|0]=FormatAry[FormatPtr].Aim;
 else
 {
  MainMap[Man.getAttribute('y')|0][Man.getAttribute('x')|0] = FormatAry[FormatPtr].Floor;
  if(++BoxCompletes == TotalBox)
   oWin();
 }
 obj.setAttribute('complete', 1);
}

 

function UnDo()
{
 if(Count >= 0)
 {
  canMove = true
  switch( BackRecord[Count] )
  {
   //not object
   case 'l':Move1(1,0);break;//left -> right
   case 'u':Move1(0,1);break;//up -> down
   case 'r':Move1(-1,0);break;//right -> left
   case 'd':Move1(0,-1);break;//down -> up
   //object
   case 'L':UnGo(1,0);break;//left -> right
   case 'U':UnGo(0,1);break;//up -> down
   case 'R':UnGo(-1,0);break;//right -> left
   case 'D':UnGo(0,-1);break;//down -> up
  }
  iSelects(--Count)
 }
}

 

function UnGo( x, y )
{
 BoxMoves--;
 var obj = MainMap[-y+(Man.getAttribute('y')|0)][-x+(Man.getAttribute('x')|0)];

 if( MainMap[Man.getAttribute('y')|0][Man.getAttribute('x')|0]==FormatAry[FormatPtr].Floor )
 {
  if( obj.getAttribute('complete') == 0 )
   MainMap[-y+(Man.getAttribute('y')|0)][-x+(Man.getAttribute('x')|0)]=FormatAry[FormatPtr].Floor;
  else
  {
   MainMap[-y+(Man.getAttribute('y')|0)][-x+(Man.getAttribute('x')|0)]=FormatAry[FormatPtr].Aim;
   BoxCompletes --;
  }
  obj.setAttribute('complete', 0);
 }
 else
 {
  if( obj.getAttribute('complete') == 0 )
  {
   MainMap[-y+(Man.getAttribute('y')|0)][-x+(Man.getAttribute('x')|0)]=FormatAry[FormatPtr].Floor;
   if( ++BoxCompletes == TotalBox )
    oWin();
  }
  else
   MainMap[-y+(Man.getAttribute('y')|0)][-x+(Man.getAttribute('x')|0)]=FormatAry[FormatPtr].Aim;
  obj.setAttribute('complete', 1);
 }
 obj.style.left = (Man.getAttribute('x')|0)*MapW;
 obj.style.top  = (Man.getAttribute('y')|0)*MapH;
 MainMap[Man.getAttribute('y')|0][Man.getAttribute('x')|0] = obj;
 Move1( x, y );
}

 

function ReDo()
{
 if( Count+1 < BackRecord.length )
 {
  switch( BackRecord[++Count] )
  {
   case 'l': case 'L': Dir(-1,0);break;//left
   case 'u': case 'U': Dir(0,-1);break;//up
   case 'r': case 'R': Dir(1,0);break;//right
   case 'd': case 'D': Dir(0,1);break;//down
  }
  iSelects(Count)
 }
 else
  clearInterval(Timer);
}

 

function oWin()
{
 canMove = false
 alert('Congratulation!')
}

 

function AutoRun()
{
 var temp = document.getElementById('SolutionInfo').value;
 if(temp == '')
  return;

 ReadMap(CurrentMapPtr);
 BackRecord = temp.split("");
 Timer = setInterval(ReDo,RePlayTime);
}

 

function iSelects(x)
{
 var obj = document.getElementById('SolutionInfo');
 if( obj.createTextRange )
 {
  var iRange = obj.createTextRange()
  iRange.collapse(true)
  iRange.moveStart("character",x)
  iRange.moveEnd("character",1)
  iRange.select()
 }
 else if( obj.setSelectionRange )
 {
  obj.selectionStart = x;
  obj.selectionEnd = x+1;
 }
 document.getElementById('BoxMoveInfo').value = BoxMoves;
 document.getElementById('ManMoveInfo').value = x+1;
}

 

function ChangeMap( ptr )
{
 var GoMap = (CurrentMapPtr+ptr) % Map.length;
 GoMap = GoMap<0 ? Map.length-1:GoMap;
 ReadMap( GoMap );
}

 

document.getElementById('CurrentMap').onkeydown = ChangeMapHandler;
function ChangeMapHandler( evt )
{
 if( typeof(evt) == 'undefined' )
  evt = window.event||window.Event;
 var keyCode = 0;
 if( evt.keyCode )
  keyCode = evt.keyCode;
 else if( typeof(evt.which) != 'undefined')
  keyCode = evt.which;

 if( keyCode == 13 )
  ChangeMap( this.value|0 );

 evt.cancelBubble = true
 if( evt.preventDefault )
  evt.stopPropagation();
}

 

 

 

 


document.onkeydown = function( evt )
{
 if( typeof(evt) == 'undefined' )
  evt = window.event||window.Event;
 var keyCode = 0;
 if( evt.keyCode )
  keyCode = evt.keyCode;
 else if( typeof(evt.which) != 'undefined')
  keyCode = evt.which;

 if( evt.ctrlKey )
 {
  switch( keyCode )
  {
   case 37 : document.body.scrollLeft-=PushScrollNo;break;//left
   case 38 : document.body.scrollTop-=PushScrollNo;break;//up
   case 39 : document.body.scrollLeft+=PushScrollNo;break;//right
   case 40 : document.body.scrollTop+=PushScrollNo;break;//down
  }
 }
 else
 {
  switch( keyCode )
  {
   case 37 : Dir(-1,0,'l');break;//left
   case 38 : Dir(0,-1,'u');break;//up
   case 39 : Dir(1,0,'r');break;//right
   case 40 : Dir(0,1,'d');break;//down
  }

  if( evt.returnValue != false )
   evt.returnValue = false;
  if( evt.preventDefault )
   evt.preventDefault();

  document.getElementById('SolutionInfo').value = BackRecord.join("")
  iSelects(Count)
 }
}

 

document.onmouseup = function( evt )
{
 if( typeof(evt) == 'undefined' )
  evt = window.event||window.Event;

 if( evt.button==1 || evt.button==0 )
  ReDo()
}

 

document.oncontextmenu = function( evt )
{
 if( typeof(evt) == 'undefined' )
  evt = window.event||window.Event;

 if( evt.returnValue != false )
  evt.returnValue = false;
 if( evt.preventDefault )
  evt.preventDefault();

 UnDo();
}

 

window.onload = function()
{
 ReadMap( CurrentMapPtr % Map.length );
 document.body.scroll='no'
 window.focus();
 document.getElementById('Base').focus();
}

 

 

 

 

 

 

/*
XSB Format:
$ = Box
* = Box on Aim
@ = Player
+ = Player on Aim
# = Wall
. = Aim
  = Floor

My Format:
0 = Box
@ = Box on Aim
* = Player
# = Player on Aim
W = Wall
. = Aim
  = Floor
*/
FormatAry[0] = {
 Box      : "0",
 BoxOnAim : "@",
 Player      : "*",
 PlayerOnAim : "#",
 Wall  : "W",
 Aim   : ".",
 Floor : " "
}
FormatAry[1] = {
 Box      : "$",
 BoxOnAim : "*",
 Player      : "@",
 PlayerOnAim : "+",
 Wall  : "#",
 Aim   : ".",
 Floor : " "
}

 

 

Map[Map.length] = [
'WWWWWWWWWWW',
'W    W*   W',
'W 00000 0 W',
'W         W',
'WWWWW WWWWW',
'   W  .W   ',
'   W  .W   ',
'   W...W   ',
'   W  .W   ',
'   WWWWW   ']
Solution[Solution.length] = 'rddlllllluurDurrDLdRRRRuulDrdLuLDDDDuuulluullddRRRluurDrDDDrddLUluRuurruurrdLrdLLLulDDDDrddllURuuuuruurDrdLLulDDDDDldRuuuuuulldRurDDDlDRuuulluulDldRRRurDDDD';

Map[Map.length] = [
'   ## ##',
' ##  #  ##',
' ##     ##',
'#  *$#$*  #',
'#  $...$  #',
' # #.@.# #',
'#  $...$  #',
'#  *$#$*  #',
' ##     ##',
' ##  #  ##',
'   ## ##']
Solution[Solution.length] = 'luULuurDDDrrRUrrdLLLddDRddlUUUllLDlluRRRlluuRuurrrDrrdddLddlllUddlUrrrruurrdLuuuulluurDllllddlluR';

Map[Map.length] = [
'      #####',
'      #   #',
'     ## $ ##',
'   ### $.$ ###',
'   #  $.*.$  #',
'  ## $.*.*.$ ##',
'### $.*.$.*.$ ###',
'#  $.*.$ $.*.$  #',
'# $.*.$   $.*.$ #',
'#  $.*.$ $.*.$  #',
'### $.*.$.*.$ ###',
'  ## $.*.*.$ ##',
'   #  $.*.$  #',
'   ### $.$ ###',
'     ## $ ##',
'      # @ #',
'      #####']
Solution[Solution.length] = 'ruUrUrruUrUrruulLuLuulLuLuulldDlDlldDlDllddrRdRddrRdRddrruururruulUlUdrdrrurruulluluulldLdLruruuluullddldllddrDrDululldllddrrdrddrruRuRlUddldlluululluurrurrdrdRdddlddrUdddrruuLrddlUlUlulluRdrdrdrrururruululLLrrrdrddlldldllulululululluurrRlllddrUluRRuruurDururuurrddrddldldLdDrrrrdrruLLdrddlUruurrruulDrdLLruululuulldldldlddrrRllluurDldRRuluuruUUdddlddrUUUruulDDurrrdLrdrdrddldlddlldldllulululululuururuurruruurrDDDuuulldRurDD';

Map[Map.length] = [
'       ####',
'       #  ##',
'      ## $####',
'     ###. .  #',
'  #### $ # $ #',
'  #  #  . .####',
' ## $####$ #  ##',
'###. . $. $# $####',
'# $ # $ **.#. .  #',
'#  . .#.** $ # $ #',
'####$ #$ .$ . .###',
'  ##  # $####$ ##',
'   ####. .  #  #',
'    # $ # $ ####',
'    #  . .###',
'    ####$ ##',
'      ## @#',
'       ####']
Solution[Solution.length] = '';

 

 

</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值