Skip to content

Instantly share code, notes, and snippets.

@RadianSmile
Last active November 28, 2016 11:41
Show Gist options
  • Save RadianSmile/7e612560ac37c9cd84d03fb0dfa32a19 to your computer and use it in GitHub Desktop.
Save RadianSmile/7e612560ac37c9cd84d03fb0dfa32a19 to your computer and use it in GitHub Desktop.

1.虛擬碼實作技巧

1.把需求拆解成狀態跟動作

  • 狀態:按空白鍵
  • 動作:發射子彈

2.把狀態跟動作結構化

  • IF 按空白鍵 THEN 發射子彈

3.轉換成電腦能懂的中文

  • bad : 發射子彈
  • good : 子彈從戰機位置向右飛行
這三個步驟是沒有順序性的,隨時視情形使用。例如我可能在第2步時發現需求又能夠拆解,那就可以再進行拆解。
好的虛擬碼會很像程式碼,因為狀態跟動作都會隊應清楚。等差不多語句都可以直接轉換成程式碼的時候,就可以開始寫程式了。

2.以作業四A級要求為例

 '★★★ 按空白鍵後,主角會發射子彈,子彈打到敵人會殲滅飛機。'
 '★★★ 畫面中同時間最多只能有五顆子彈(也就是說當畫面中有五個子彈時按下空白鍵是沒有作用的)。'
  1. 把需求拆解成狀態跟動作
// 拆解按空白鍵後主角會發射子彈」
「子彈打到敵人會殲滅飛機。」
「畫面中同時間最多只能有五顆子彈」
-> 「當畫面中有五個子彈時按下空白鍵是沒有作用
  1. 把狀態跟動作結構化
// 結構化 1
按到空白鍵時 -> 發射子彈
當畫面中有五個子彈時 -> 不發射子彈

子彈打到敵人會殲滅飛機           // 因為要處理很多數量(要用到 array )還不知道怎麼想,決定待會處理
// 結構化 2 
按到空白鍵時
  IF 當畫面中有五個子彈時
    不發射子彈
  ELSE
    發射子彈

子彈打到敵人會殲滅飛機
// 結構化 3 : 想出執行時機
KEY_PRESSED:
  按到空白鍵時
    IF 當畫面中有五個子彈時  // 放在這裡是因為,
      不發射子彈
    ELSE
      發射子彈

DRAW :                   // 放在這裡是因為,至件事情是每一個 frame 都可能發生   
  子彈打到敵人會殲滅飛機         
  1. 轉換成電腦能懂的中文
// 發現含糊的敘述
KEY_PRESSED :
  按到空白鍵時
    IF 當畫面中有五個子彈時
      不發射子彈
    ELSE
      '發射子彈' // 含糊

DRAW : 
  子彈打到敵人會殲滅飛機
// 轉換
KEY_PRESSED :
  按到空白鍵時
    IF 當畫面中有五個子彈時
      不發射子彈
    ELSE
      '子彈會從戰機位置由右往左移動' // 將問題拆解

DRAW : 
  子彈打到敵人會殲滅飛機
// 持續拆解
KEY_PRESSED :
  按到空白鍵時
    IF 當畫面中有五個子彈時
      不發射子彈
    ELSE
      '子彈會從戰機位置由右往左移動' // 發現移動是每個 frame 都會 update ,應該要擺在 draw 裡面

DRAW : 
  子彈打到敵人會殲滅飛機
// 持續排列
KEY_PRESSED :
  按到空白鍵時
    IF 當畫面中有五個子彈時
      不發射子彈
    ELSE
      '子彈會從戰機位置發射'  // 將發射講述成電腦實作方式

DRAW : 
  '子彈會由左往右移動'  // 被擺到這了。
  子彈打到敵人會殲滅飛機
// 補充電腦的執行細節
KEY_PRESSED :
  按到空白鍵時
    IF 當畫面中有五個子彈時
      不發射子彈
    ELSE
      '將子彈擺在戰機位置'   

DRAW :
  子彈會由左往右移動  
  子彈打到敵人會殲滅飛機
  '顯示敵機'                // 補充程式執行細節
  1. 轉換成程式碼
keyReleased :

"按到空白鍵時==============================="
  if (keyCode === SAPCE)
    // 發射子彈 

  "發射子彈==================================="
  ->發現需要容器來儲存 5 顆子彈位置 -> 想到用 array 
  ->回去定義變數 shootX[] , shootY[]

    shootX[i] = fx 
    shootY[i] = fx


  "當畫面中有五個子彈時========================"
  -> 要怎麼知道畫面中有幾顆子彈?
  -> 想想有哪些數值與這問題有關 
  -> 子彈的位置 -> shootX[] , shootY[]
  -> 如果子彈陣列中超過 5 顆子彈在畫面中count = 0 ;  
    for ( i = 0 ~ shootY)
      if  0 < shootX[i] < width AND  0 < shootY[i] < height
        count ++

    if count >= 5 THEN  不該[發射子彈]



draw : 

  "子彈會由左往右移動==========================="
  for (i = 0 ~ shoots.length)
    shootX[i] ++ ;

  "子彈打到敵人會殲滅飛機======================="
  -> 要檢查每一顆子彈
  -> 要檢查每一個敵機

  for (i = 0 ~ shootX.length)
    for (j = 0 ~ enemyX.length )
     if shootX[i], Y , w , j  enemyX[i] x y w h 碰撞
       shootX , y = 1000 ;
       enemyX  y  = 1000 ;

  "顯示子彈===================================="
  for (i = 0 ~ shoots.length)
    image 
  • 發現移動、碰撞偵測、顯示,可以濃縮在同一個 for
'按到空白鍵時'
keyReleased :
  if (keyCode === SAPCE)  
    '找有沒有空的彈夾 -> 有空彈夾,填入子彈'
    for ( i = 0 ~ shoots.length)
      if  0 < shootX[i] < width AND  0 < shootY[i] < height // 這個子彈在使用中 -> 不能填入子彈 
      
      else                                                  // 這個子彈不在使用中 ->   填入子彈 
        shootX[i] = fx 
        shootY[i] = fx
        break ;  // 只需要填一次就好。

draw:

  for (i = 0 ~ shoots.length)
    "子彈會由左往右移動"
    shootX[i] ++ ;


    "子彈打到敵人會殲滅飛機"
    for (j = 0 ~ enemyX.length )
     if shootX[i], Y , w , j  enemyX[i] x y w h 碰撞
       shootX , y = 1000 ;
       enemyX  y  = 1000 ;

    "顯示子彈"
    image shootImg at shootX[i] , y 

3.完成!試著自己做做看吧

Credit 國立政治大學 玩電玩・學程式
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment