<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-57  評論-202  文章-17  trackbacks-0

    用JavaScript做涂格子游戲
    原創:oq 2003年7月29日

    這是我以前玩過的一個智力游戲,那個游戲的名子叫"開窗",實質都是一樣的。學過JavaScript后我就試著做了一個,是用JavaScript和HTML及CSS做的一個.htm文檔。

    下面是這個文檔的界面及其源文件的詳細說明,點擊這里可以下載源文件:點擊下載源文件

    首先在源文件的開頭處我引用了一個名為game01.css的樣式表:<link rel="stylesheet" href="game01.css">,用過CSS的朋友應該很熟悉了。當把樣式表單獨寫成一個文件時就用<link>標記連接過來。下面我分別介紹游戲中的各個功能:

    游戲一開始會畫出一個10×10的網格,它的大小是可以更改的,只要在"棋盤大小"處輸入你想要的網格大小后再點擊"開始游戲"就可以了。一開始畫出10×10的網格是用drawBoard()函數完成的,如下:

    function drawBoard()
    {
     var str="<table align='center' border='5' cellspacing=' 0' cellpadding='0' id='gameBoard' bordercolor='#0000ff' onMouseOver='mouseOver()' onMouseOut='mouseOut()' onClick='clicktable()'>";
     for(var i=0;i<size;i++)
     {
      str+="<tr>";
      for(var j=0;j<size;j++)
        str+="<td>&nbsp;</td>";
      str+="</tr>";
     }
     str+="</table>";
     return str;
    }

    其中size是在<script></script>標記的一開始定義的全局變量,如下:

    var size=10;
    var totalMoves=0;
    var lightOn;
    var lightOff;
    var currentable;

    它的初值為10,所以游戲一開始先畫出一個10×10的表格。函數把一個完整的 <table> 賦給了變量str,最后返回str。兩個for循環是根據size的大小賦給str表格的行數和列數。第一個for循環用 str+="<tr>;賦給str 行標記<tr>,每一行中用第二個for循環:

    for(var j=0;j<size;j++)
             str+="<td>&nbsp;</td>"

    賦給str單元格標記<td>,總共要賦size個,因此循環條件為:j<size; 。程序運行時在<BODY>的<script>中調用drawBoard()即:document.write(drawBoard());就畫出了10×10的網格。而對網格的修改則是通過newGame()完成的:

    function newGame()
    {

     size=document.all.boardSize.value;
     if(size<2)
      size=2;

     if(size>14)
      size=14;

     document.all.boardSize.value=size;
     document.all.gameBoard.outerHTML=drawBoard();
     lightOn=0;
     document.all.LightOn.innerText=lightOn;
     lightOff=Math.pow(size,2);
     document.all.LightOff.innerText=lightOff;
     totalMoves=0;
     document.all.Move.innerText=totalMoves;
    }

    在單擊"開始游戲"時就觸發了 onClick="newGame()" 事件,在newGame()函數中我們對全局變量size的值進行了修改:size=document.all.boardSize.value; 即把玩家在棋盤大小處輸入的值賦給size,再調用drawBoard()重新畫一遍網格就實現了改變網格的大小。其中

    if(size<2) size=2;
    if(size>14) size=14;

    是為了保證網格的改變在頁面允許的范圍內,即把size限制在  2<=size<=14 。過大或過小的值都會被 document.all.boardSize.value=size;語句把2或14寫到"棋盤大小"處。newGame()中語句: document.all.gameBoard.outerHTML=drawBoard() 是用THML語言設置對象內容。newGame()中下面的內容:

    lightOn=0;
    document.all.LightOn.innerText=lightOn;
     lightOff=Math.pow(size,2);
    document.all.LightOff.innerText=lightOff;
    totalMoves=0;
     document.all.Move.innerText=totalMoves;

    是對記尋游戲狀態的變量賦初值,就是游戲板左邊的那三個記錄燈亮個數,燈滅個數,以及移動總數的變量。

    下面我們再來看在鼠標經過時如何使網格變色,這就是用了兩個事件:onMouseOver和onMouseOut,都定義在了drawBoard()的那個 <table> 中。當鼠標經過時調用mouseOver():

    function mouseOver()
    {
     currentable=event.srcElement;
     if(currentable.tagName=="TD")
      {
       currentable._background=currentable.style.backgroundColor;
       currentable.style.backgroundColor=
    "#999999";
      }
    }

    其中currentable表示當前發生事件的對象,用event.srcElement獲得。currentable.tagName表示當前發生事件對象的標識符名。于是鼠標經過時 <table> 時,currentable得到當前發生事件的 <td> 使得它的_background變為當前的backgroundColor即: currentable._background=currentable.style.backgroundColor;  把當前的backgroundColor變為"#999999"即: currentable.style.backgroundColor="#999999"; ??炊薽ouseOver()再看mouseOut()就不難了。以下是mouseOut():

    function mouseOut()
    { 

     if(currentable.tagName=="TD")
      currentable.style.backgroundColor=currentable._background;
    }

    很好理解吧,我在這里就不多廢話了。有了mouseOver()和mouseOut()就可以實現當鼠標經過每個單元格時使其改變顏色,而當鼠標移出后又變回原來的顏色。

    源文件中最重要的函數要屬clicktable()了,它的作用是當鼠標點下時使得當前對象和上下左右的方格都變色,而且要更改燈亮個數,燈滅個數,以及移動總數的值,還要判斷游戲是否結束等等很多事情。同onMouseOver和onMouseOut事件一樣,在drawBoard()的 <table> 中同樣定義了onClick事件。下面是clicktable():

    function clicktable()
    {
     totalMoves++;

     document.all.Move.innerText=totalMoves;
     if(currentable.tagName=="TD")
     {
      setColor(currentable);

      var cell=currentable.cellIndex;
      var row=currentable.parentElement.rowIndex;
      if(row>0)
       setColor(gameBoard.rows[row-1].cells[cell]);

      if(row<size-1)
       setColor(gameBoard.rows[row+1].cells[cell]);

      if(cell>0)
       setColor(gameBoard.rows[row].cells[cell-1]);

      if(cell<size-1)
       setColor(gameBoard.rows[row].cells[cell+1]);
     }
     var over=light();

     if(!over)
      document.all.LightOff.innerText="You Win!";
    }

    totalMoves就是記錄總移動次數的那個變量,totalMoves++就很明白了吧,每當鼠標在某個格子上單擊時就把totalMoves加1,并把totalMoves改變后的值寫在移動總數的位置:document.all.Move.innerText=totalMoves; 其中innerText用來設置或得到該對象起始標記到結束標記之間的內容。往下的if語句與另一個函數setColor(current)有關,setColor(current)通過參數current得到當前對象,然后將當前對象的顏色改為黃色(燈亮)。這樣通過

    cell=currentable.cellIndex;
    row=currentable.parentElement.rowIndex;

    取得當前對象所在表格的行、列,從而gameBoard.rows[row-1].cells[cell]就可以訪問到與該對象在同列但比它靠前一行的那個對象,也用 setColor(gameBoard.rows[row-1].cells[cell] 把它的顏色改變,同理在該對象右、下、左的對象也都可以訪問到,使它們的顏色都得以改變。下面是setColor():

    function setColor(current)
    {

     if(current._background==""||current._background==null||current._background=="#ccccff")
     {
      current.style.backgroundColo
    r="yellow";
      current._background="yellow";
     }
     else if(current._background=="yellow")
     {
      current.style.backgroundColo
    r="#ccccff";
      current._background="#ccccff";
     }
    }

    代碼不難,我就不細說了。clicktable()中最后的那個light()是判斷游戲是否結束的函數,因為函數中要數一下燈亮和燈滅的個數,所以我就叫它light()了,如下:

    function light()
    {
     lightOn=0;
     lightOff=0;

     for(var i=0;i<size;i++)
     for(var j=0;j<size;j++)
     if(gameBoard.rows[i].cells[j]._background=="yellow")
      lightOn++;
     else lightOff++;
     document.all.LightOn.innerText=lightOn;
     document.all.LightOff.innerText=lightOff;
     return lightOff;
    }

    lightOn和lightOff還是在一開始定義的全局變量,因為鼠標每次單擊后都要檢查一遍,所以要先給它們賦0。接下來就是用一個雙重循環訪問每一個 <td> 對象的 _background 如果是yellow則lightOn++,如果不是則lightOff++,最后不要忘記把lightOn和lightOff的值賦到LightOn和LightOff的innerText里。然后將lightOff反回并在clicktable()中判斷是否結束,如果lightOff==0就結束并在"燈滅"的位置出現"You Win"。

    最后還有一個規則說明,是一個超鏈接,點擊后調用newWin():

    function newWin()
    {

     var newin=open("","","height=170,width=250,resizable=0");
     newin.document.write("&nbsp;&nbsp;在'棋盤大小'處輸入數字 后按'開始游戲'鍵即可得到你想要的棋盤大小。棋盤中黃色表示燈亮, 白色表示燈滅。單擊鼠標后當前方格和上下左右的方格都會變色,把所有的方格都' 點亮'后你就勝利了!");
    }

    newWin()新打開一個窗口,并在新窗口中寫入游戲規則。

    以上就是對本游戲的全部講解,所有的功能我都調試通過,文章中若有疏漏之處還請高手指點。

    posted on 2005-07-15 16:46 小米 閱讀(1235) 評論(0)  編輯  收藏 所屬分類: 其它
    主站蜘蛛池模板: 久久久免费精品re6| 91嫩草国产在线观看免费| 丁香花在线观看免费观看| 亚洲国产精品成人久久蜜臀| 亚洲午夜视频在线观看| 狠狠入ady亚洲精品| 亚洲免费视频在线观看| 四虎免费久久影院| 亚洲美女视频网址| 日本一区二区在线免费观看 | 久久www免费人成看片| 国产在线观看www鲁啊鲁免费| 亚洲av日韩综合一区在线观看| 亚洲人成网站色7799| 免费在线看黄网站| 国产精品成人无码免费| 亚洲色成人网一二三区| sss在线观看免费高清| 国产三级在线观看免费| 久久久久久a亚洲欧洲AV| 未满十八私人高清免费影院| 天天影院成人免费观看| 久久久久久久尹人综合网亚洲| 亚洲区日韩精品中文字幕| 午夜免费福利小电影| 亚洲AV成人潮喷综合网| 亚洲综合av一区二区三区不卡| 久久免费视频精品| 亚洲一区二区三区免费| 亚洲精华国产精华精华液好用 | yy6080亚洲一级理论| 亚洲人成7777| 曰批全过程免费视频播放网站| 红杏亚洲影院一区二区三区| 亚洲国产精华液2020| 国产精品成人观看视频免费| 亚洲精品乱码久久久久久蜜桃不卡 | 国产精品亚洲а∨无码播放不卡 | 夜色阁亚洲一区二区三区| 亚洲人成综合网站7777香蕉| 免费无码VA一区二区三区|