別踩白塊兒 - 網頁版

講者:王譽錚

日期:2021/04/28

Outline

  • 基礎架構
  • Start
  • AddBox
  • DrawBox
  • BoxMove
  • playAudio
  • CountDown
  • 擊中判定
  • 小試身手
  • 參考資源

基礎架構

base

請將資料夾內所有檔案下載並放置在同個位置

使用到的函式

  • Start()
  • AddBox()
  • BoxMove()
  • CountDown()
  • drawbox()
  • playAudio()

Start

後續內容全部加在 head 的 scrpit 內

<head>
  <style type="text/css">
    ......
  </style>
  <script type="text/javascript">
    後續程式碼加在此處!!!
  </script>
</head>
//宣告畫布
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");

// 箱子相關資料:第幾排、方塊的類型、幾個箱子、存放用的list、是否觸發刪除
var ran_line;
var ran_type
var box_list;
var box_len;
var del_status;

// 分數相關資訊
var score;
var great;
var long_great;
var miss;

// 鍵盤狀態判斷
var key_down_status;

宣告變數

function Start(){
  ran_line = 0; //軌道
  box_list = [] //存放在場上的方塊
  box_len = 0;

  //狀態判斷
  del_status = false;
  key_down_status = false;

  //分數計算
  score = 0;
  great = 0;
  long_great = 0;
  miss = 0;

  document.getElementById("clock").innerHTML = "00:01:00";

  ctx.clearRect(0,0,410,512);//清除畫布重新繪製
}

初始化遊戲資料

AddBox

function AddBox(){
  ran_line = Math.floor(Math.random()*5); //隨機一條軌道
  ran_type = Math.floor(Math.random()*2); //普通方塊或長形方塊
  switch(ran_line){
    case 0:
      box_list.push({x:0,y:0,type:ran_type + 1});
      box_len += 1;
      break;
    case 1:
      box_list.push({x:82,y:0,type:ran_type + 1});
      box_len += 1;
      break;
    case 2:
      box_list.push({x:164,y:0,type:ran_type + 1});
      box_len += 1;
      break;
    case 3:
      box_list.push({x:246,y:0,type:ran_type + 1});
      box_len += 1;
      break;
    case 4:
      box_list.push({x:328,y:0,type:ran_type + 1});
      box_len += 1;
      break;
  }
}

box_list 所存放的資料

  • x軸位置
  • y軸位置
  • 方塊類型

(0, 0, 1) =>

(0, 0, 2) =>

function Start(){
  ......

  ctx.clearRect(0,0,410,512);//清除畫布重新繪製
  
  addboxstatus = setInterval(AddBox, 1000);
}

在 Stast 呼叫 AddBox

DrawBox

function drawbox(){
  ctx.fillStyle ="black"; //設定方塊顏色
  
  for(var k = 0; k < box_len; k++)//畫上方塊
  {
    //判定超出畫面的方塊
    if (box_list[k].y >= 512){
      del_status = true;
      miss = miss + 1;
    }
    ctx.fillRect(box_list[k].x, box_list[k].y, 82, box_list[k].type * 60);
  }
  //刪除超出的方塊
  if (del_status){
    box_list.shift();
    del_status = false;
    box_len -= 1;
  }

}

BoxMove

function BoxMove(){
  for(var k = 0; k < box_len; k++){//使方格移動
    box_list[k].y = box_list[k].y + 1;
  }
  ctx.clearRect(0,0,410,512);//清除畫布重新繪製
  drawbox();
}
function Start(){
  ......

  
  addboxstatus = setInterval(AddBox, 1000);
  boxmovestatus = setInterval(BoxMove, 1);
}

在 Stast 呼叫 BoxMove

playAudio

function playAudio(n) {
  const audio = document.getElementById("audio-element");
  audio.src = n + ".mp3";
  audio.currentTime = 0;
  audio.play();
}

CountDown

function CountDown(){
  var time = document.getElementById("clock").innerHTML.split(":");

  if(parseInt(time[2]) <= 0 && parseInt(time[1]) <= 0 && parseInt(time[0]) <= 0){
    clearInterval(addboxstatus);
    clearInterval(boxmovestatus);
    clearInterval(countdownstatus);

    ctx.clearRect(0,0,410,512);

    ctx.font = "20pt Arial";
    ctx.fillText("Score:" + String(long_great * 150 + great * 100 - miss * 50), 150, 180);
    ctx.fillText("Great:" + String(great), 150, 230);
    ctx.fillText("Miss:" + String(miss), 150, 280);
    ctx.fillText("LongGreat:" + String(long_great), 150, 330);

  }else if(parseInt(time[1]) <= 0 && parseInt(time[0]) > 0){
    time[0] = String(parseInt(time[0]) - 1);
    time[1] = "59";

    if (time[0].length < 2){
      time[0] = "0" + time[0];
    }

    document.getElementById("clock").innerHTML = time.join(":");
  }else if(parseInt(time[2]) <= 0 && parseInt(time[1]) > 0){
    time[1] = String(parseInt(time[1]) - 1);
    time[2] = "59";

    if (time[1].length < 2){
      time[1] = "0" + time[1];
    }

    document.getElementById("clock").innerHTML = time.join(":");
  }else{
    time[2] = String(parseInt(time[2]) - 1);

    if (time[2].length < 2){
      time[2] = "0" + time[2];
    }
    document.getElementById("clock").innerHTML = time.join(":");
  }

}
function Start(){
  ......

  
  addboxstatus = setInterval(AddBox, 1000);
  boxmovestatus = setInterval(BoxMove, 1);
  countdownstatus = setInterval(CountDown, 1000);	
}

在 Stast 呼叫 CountDown

擊中判定

document.onkeydown=function(e)
{
  if(box_list[0].type == 1){
    switch(e.keyCode){
        //d
      case 68:
        if(box_list[0].y + 80 >= 512 && box_list[0].y < 512 && box_list[0].x == 0){
          box_list.shift();
          box_len -= 1;

          great = great + 1;
          playAudio("C");

        }else{
          playAudio("miss");
        }
        break;
        //f
      case 70:
        if(box_list[0].y + 80 >= 512 && box_list[0].y < 512 && box_list[0].x == 82){
          box_list.shift();
          box_len -= 1;
          great = great + 1;
          playAudio("D");
        }else{
          playAudio("miss");
        }
        break;
        //g
      case 71:
        if(box_list[0].y + 80 >= 512 && box_list[0].y < 512 && box_list[0].x == 164){
          box_list.shift();
          box_len -= 1;
          great = great + 1;
          playAudio("E");
        }else{
          playAudio("miss");
        }
        break;
        //h
      case 72:
        if(box_list[0].y + 80 >= 512 && box_list[0].y < 512 && box_list[0].x == 246){
          box_list.shift();
          box_len -= 1;
          great = great + 1;
          playAudio("F");
        }else{
          playAudio("miss");
        }
        break;
        //j
      case 74:
        if(box_list[0].y + 80 >= 512 && box_list[0].y < 512 && box_list[0].x == 328){
          box_list.shift();
          box_len -= 1;
          great = great + 1;
          playAudio("G");
        }else{
          playAudio("miss");
        }
        break;
    }
  }else if(key_down_status == false){
    switch(e.keyCode){
        //d
      case 68:
        if(box_list[0].y + 140 >= 512 && box_list[0].y < 512 && box_list[0].x == 0){
          playAudio("C");
          key_down_status = true;
        }
        break;
        //f
      case 70:
        if(box_list[0].y + 140 >= 512 && box_list[0].y < 512 && box_list[0].x == 82){
          playAudio("D");
          key_down_status = true;
        }
        break;
        //g
      case 71:
        if(box_list[0].y + 140 >= 512 && box_list[0].y < 512 && box_list[0].x == 164){
          playAudio("E");
          key_down_status = true;
        }
        break;
        //h
      case 72:
        if(box_list[0].y + 140 >= 512 && box_list[0].y < 512 && box_list[0].x == 246){
          playAudio("F");
          key_down_status = true;
        }
        break;
        //j
      case 74:
        if(box_list[0].y + 140 >= 512 && box_list[0].y < 512 && box_list[0].x == 328){
          playAudio("G");
          key_down_status = true;
        }
        break;
    }
  }
} 
//尾判
document.onkeyup=function(e){
  if (key_down_status){
    switch(e.keyCode){
        //d
      case 68:
        if(box_list[0].y + 20 >= 512 && box_list[0].y <= 512 && box_list[0].x == 0){
          key_down_status = true;
          long_great = long_great + 1;
        }else{
          const audio = document.getElementById("audio-element");
          audio.pause();
          playAudio("miss");
        }
        key_down_status = false;
        break;
        //f
      case 70:
        if(box_list[0].y + 20 >= 512 && box_list[0].y <= 512 && box_list[0].x == 82){
          key_down_status = true;
          long_great = long_great + 1;
        }else{
          const audio = document.getElementById("audio-element");
          audio.pause();
          playAudio("miss");
        }
        key_down_status = false;
        break;
        //g
      case 71:
        if(box_list[0].y + 20 >= 512 && box_list[0].y <= 512 && box_list[0].x == 164){
          key_down_status = true;
          long_great = long_great + 1;
        }else{
          const audio = document.getElementById("audio-element");
          audio.pause();
          playAudio("miss");
        }
        key_down_status = false;
        break;
        //h
      case 72:
        if(box_list[0].y + 20 >= 512 && box_list[0].y <= 512 && box_list[0].x == 246){
          key_down_status = true;
          long_great = long_great + 1;
        }else{
          const audio = document.getElementById("audio-element");
          audio.pause();
          playAudio("miss");	
        }
        key_down_status = false;
        break;
        //j
      case 74:
        if(box_list[0].y + 20 >= 512 && box_list[0].y <= 512 && box_list[0].x == 328){
          key_down_status = true;
          long_great = long_great + 1;
        }else{
          const audio = document.getElementById("audio-element");
          audio.pause();	
          playAudio("miss");
        }
        key_down_status = false;
        break;
    }
  }
}

小試身手

1. 畫上輔助線

提示:
1.canvas 中線條的畫法

2. 請將軌道改為七軌,並讓方塊從隨機一條掉落

提示:
1.調整 canvas 的寬度 或 調整方塊的寬度

2 . 調整 AddBox 內關於方塊的資料

3. 擊中判定部分,增加對應軌道的按鍵

3. 讓方塊以指定樂曲的音掉落,使之可以彈奏出 一首歌

舉例: 1 1 3 3 6 6 5 4 4 3 3 2 2 1

提示:
1.設定一個 list 存放樂曲的軌道順序

2. 依照list內容指定方塊的掉落軌道

參考資源

Thank you for listening

Made with Slides.com