Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android示例程序剖析之Snake貪吃蛇(一:暫停/繼續、穿牆和全屏)

Android示例程序剖析之Snake貪吃蛇(一:暫停/繼續、穿牆和全屏)

編輯:Android開發實例

       本文開始將為大家剖析Android示例程序-Snake貪吃蛇。貪吃蛇游戲大部分人都玩過,它是怎樣實現的呢?Android示例程序給出了代碼,下面進行詳細分析。

       游戲暫停/繼續機制

       由於原來的代碼中在游戲運行時沒有提供控制選項(比如暫停/繼續),因此除非你死了,否則只能玩到底。我這裡對代碼進行一些修改,加入一個Option Menu來提供暫停/繼續機制。

       首先加入一個變量記錄游戲當前狀態:

       private int mState = SnakeView.READY;

       然後重載onCreateOptionsMenu函數,創建一個控制菜單項,並對其進行處理,提供暫停/繼續機制。

Java代碼
  1. /*     
  2.  * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)     
  3.  * @Author:phinecos     
  4.  * @Date:2009-08-28     
  5.  */      
  6. @Override      
  7. public boolean onOptionsItemSelected(MenuItem item)      
  8. {      
  9.     switch (item.getItemId())      
  10.     {      
  11.         case MENU_CONTROL:      
  12.         {      
  13.             if (mState == SnakeView.PAUSE)      
  14.             {//此前狀態是"停止",則轉為"運行"      
  15.                 mState = SnakeView.RUNNING;      
  16.                 mSnakeView.setMode(SnakeView.RUNNING);      
  17.                     item.setIcon(android.R.drawable.ic_media_pause).setTitle(R.string.cmd_pause);      
  18.             }      
  19.             else if(mState == SnakeView.RUNNING)      
  20.             {//此前狀態是"運行",則轉為“暫停"      
  21.                 mState = SnakeView.PAUSE;      
  22.                 mSnakeView.setMode(SnakeView.PAUSE);      
  23.                     item.setIcon(android.R.drawable.ic_media_play).setTitle(R.string.cmd_run);      
  24.             }      
  25.             else if(mState == SnakeView.READY)      
  26.             {//此前是"初始狀態",則轉為"運行"      
  27.                 mState = SnakeView.RUNNING;      
  28.             }      
  29.     return true;      
  30.         }      
  31.     }      
  32.     return super.onOptionsItemSelected(item);      
  33. }      
  34. /*     
  35.  * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)     
  36.  * @Author:phinecos     
  37.  * @Date:2009-08-28     
  38.  */      
  39. @Override      
  40. public boolean onCreateOptionsMenu(Menu menu)       
  41. {      
  42.      super.onCreateOptionsMenu(menu);      
  43.      menu.add(0, MENU_CONTROL, 0, R.string.cmd_pause).setIcon(android.R.drawable.ic_media_pause);      
  44.      return true;      
  45. }  

       修改後運行截圖如下:

Android Snake貪吃蛇程序

Android Snake貪吃蛇程序暫停

       當然,這段代碼還是有問題的,游戲剛開始時,必須先點擊菜單確認,再按上方向鍵才能開始。(以後再來修改。。。)

    穿牆貪食蛇

       第二個修改是把這個普通的貪食蛇改成可以穿牆(呵呵,這樣就可以不死了。。。)。想必要修改的就是撞牆檢測那段代碼?沒錯,就是下面這段!

Java代碼
  1. // Collision detection   
  2. // For now we have a 1-square wall around the entire arena   
  3. if ((newHead.x < 1) || (newHead.y < 1) || (newHead.x > mXTileCount - 2)|| (newHead.y > mYTileCount - 2))    
  4. {//撞牆   
  5.      setMode(LOSE);   
  6.      return;   
  7. }  

       原來的版本是發現撞牆時就直接判定為失敗,我這裡做個小小的修改,讓它可以穿牆而去:

Java代碼
  1. private void updateSnake()   
  2. {   
  3.      boolean growSnake = false;   
  4.   
  5.      // grab the snake by the head   
  6.      Coordinate head = mSnakeTrail.get(0);   
  7.      Coordinate newHead = new Coordinate(1, 1);   
  8.   
  9.      mDirection = mNextDirection;   
  10.   
  11.      switch (mDirection)    
  12.      {   
  13.      case EAST:    
  14.      {   
  15.          newHead = new Coordinate(head.x + 1, head.y);   
  16.          break;   
  17.      }   
  18.      case WEST:    
  19.      {   
  20.          newHead = new Coordinate(head.x - 1, head.y);   
  21.          break;   
  22.      }   
  23.      case NORTH:    
  24.      {   
  25.          newHead = new Coordinate(head.x, head.y - 1);   
  26.          break;   
  27.      }   
  28.      case SOUTH:    
  29.      {   
  30.          newHead = new Coordinate(head.x, head.y + 1);   
  31.          break;   
  32.      }   
  33.      }   
  34.   
  35.      //穿牆的處理   
  36.       if (newHead.x == 0)   
  37.      {//穿左邊的牆   
  38.          newHead.x = mXTileCount - 2;   
  39.      }   
  40.      else if (newHead.y == 0)   
  41.      {//穿上面的牆   
  42.          newHead.y = mYTileCount - 2;   
  43.      }   
  44.      else if (newHead.x == mXTileCount - 1)   
  45.      {//穿右邊的牆   
  46.          newHead.x = 1;   
  47.      }   
  48.      else if (newHead.y == mYTileCount - 1)   
  49.      {//穿下面的牆   
  50.          newHead.y = 1;   
  51.      }   
  52.      // 判斷是否撞到自己   
  53.       int snakelength = mSnakeTrail.size();   
  54.      for (int snakeindex = 0; snakeindex < snakelength; snakeindex++)    
  55.      {   
  56.          Coordinate c = mSnakeTrail.get(snakeindex);   
  57.          if (c.equals(newHead))   
  58.          {   
  59.              setMode(LOSE);   
  60.              return;   
  61.          }   
  62.      }   
  63.      // 判斷是否吃掉“蘋果”   
  64.       int applecount = mAppleList.size();   
  65.      for (int appleindex = 0; appleindex < applecount; appleindex++)   
  66.      {   
  67.          Coordinate c = mAppleList.get(appleindex);   
  68.          if (c.equals(newHead))    
  69.          {   
  70.              mAppleList.remove(c);   
  71.              addRandomApple();   
  72.              mScore++;   
  73.              mMoveDelay *= 0.9;   
  74.              growSnake = true;   
  75.          }   
  76.      }   
  77.      // push a new head onto the ArrayList and pull off the tail   
  78.      mSnakeTrail.add(0, newHead);   
  79.      // except if we want the snake to grow   
  80.      if (!growSnake)    
  81.      {   
  82.          mSnakeTrail.remove(mSnakeTrail.size() - 1);   
  83.      }   
  84.      int index = 0;   
  85.      for (Coordinate c : mSnakeTrail)    
  86.      {   
  87.          if (index == 0)   
  88.          {   
  89.              setTile(YELLOW_STAR, c.x, c.y);   
  90.          }    
  91.          else    
  92.          {   
  93.              setTile(RED_STAR, c.x, c.y);   
  94.          }   
  95.          index++;   
  96.      }   
  97. }  

       其實修改後的代碼非常簡單,就是把新節點的值做些處理,讓它移動到對應的行/列的頭部或尾部即可。下面就是修改後的“穿牆”貪食蛇的運行截圖:

Android “穿牆”貪吃蛇

       全屏機制

       游戲一般都是全屏的,原始代碼也考慮到標題欄太過難看了,於是使用下面這句代碼就去掉了標題欄:

Java代碼
  1. requestWindowFeature(Window.FEATURE_NO_TITLE);  

       可還是沒有達到全屏的效果,在Android1.5中實現全屏效果非常簡單,只需要一句代碼即可實現:

Java代碼
  1. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);  

       運行效果如下圖所示:

Android Snake貪吃蛇程序全屏顯示

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved