2017-05-06 142 views
0

我一直在尝试写我的第一个JavaScript游戏。我花了很多时间努力使其尽可能好。游戏到了(我希望)功能齐全的地步。我唯一的问题是,我不知道如何在游戏开始时添加一个起始屏幕。我想添加一个新游戏按钮,也许还有一个信用按钮。任何人都可以帮我吗? 谢谢大家!如何为简单的js游戏创建游戏菜单?

const canvas = document.getElementById('tetris'); 
 
const context = canvas.getContext('2d'); 
 

 
context.scale(20, 20); 
 

 
function arenaSweep() { 
 
    let rowCount = 1; 
 
    outer: for (let y = arena.length -1; y > 0; --y) { 
 
     for (let x = 0; x < arena[y].length; ++x) { 
 
      if (arena[y][x] === 0) { 
 
       continue outer; 
 
      } 
 
     } 
 

 
     const row = arena.splice(y, 1)[0].fill(0); 
 
     arena.unshift(row); 
 
     ++y; 
 

 
     player.score += rowCount * 10; 
 
     rowCount *= 2; 
 
    } 
 
} 
 

 
function collide(arena, player) { 
 
    const m = player.matrix; 
 
    const o = player.pos; 
 
    for (let y = 0; y < m.length; ++y) { 
 
     for (let x = 0; x < m[y].length; ++x) { 
 
      if (m[y][x] !== 0 && 
 
       (arena[y + o.y] && 
 
       arena[y + o.y][x + o.x]) !== 0) { 
 
       return true; 
 
      } 
 
     } 
 
    } 
 
    return false; 
 
} 
 

 
function createMatrix(w, h) { 
 
    const matrix = []; 
 
    while (h--) { 
 
     matrix.push(new Array(w).fill(0)); 
 
    } 
 
    return matrix; 
 
} 
 

 
function createPiece(type) 
 
{ 
 
    if (type === 'I') { 
 
     return [ 
 
      [0, 1, 0, 0], 
 
      [0, 1, 0, 0], 
 
      [0, 1, 0, 0], 
 
      [0, 1, 0, 0], 
 
     ]; 
 
    } else if (type === 'L') { 
 
     return [ 
 
      [0, 2, 0], 
 
      [0, 2, 0], 
 
      [0, 2, 2], 
 
     ]; 
 
    } else if (type === 'J') { 
 
     return [ 
 
      [0, 3, 0], 
 
      [0, 3, 0], 
 
      [3, 3, 0], 
 
     ]; 
 
    } else if (type === 'O') { 
 
     return [ 
 
      [4, 4], 
 
      [4, 4], 
 
     ]; 
 
    } else if (type === 'Z') { 
 
     return [ 
 
      [5, 5, 0], 
 
      [0, 5, 5], 
 
      [0, 0, 0], 
 
     ]; 
 
    } else if (type === 'S') { 
 
     return [ 
 
      [0, 6, 6], 
 
      [6, 6, 0], 
 
      [0, 0, 0], 
 
     ]; 
 
    } else if (type === 'T') { 
 
     return [ 
 
      [0, 7, 0], 
 
      [7, 7, 7], 
 
      [0, 0, 0], 
 
     ]; 
 
    } 
 
} 
 

 
function drawMatrix(matrix, offset) { 
 
    matrix.forEach((row, y) => { 
 
     row.forEach((value, x) => { 
 
      if (value !== 0) { 
 
       context.fillStyle = colors[value]; 
 
       context.fillRect(x + offset.x, 
 
           y + offset.y, 
 
           1, 1); 
 
      } 
 
     }); 
 
    }); 
 
} 
 

 
function draw() { 
 
    context.fillStyle = '#000'; 
 
    context.fillRect(0, 0, canvas.width, canvas.height); 
 

 
    drawMatrix(arena, {x: 0, y: 0}); 
 
    drawMatrix(player.matrix, player.pos); 
 
} 
 

 
function merge(arena, player) { 
 
    player.matrix.forEach((row, y) => { 
 
     row.forEach((value, x) => { 
 
      if (value !== 0) { 
 
       arena[y + player.pos.y][x + player.pos.x] = value; 
 
      } 
 
     }); 
 
    }); 
 
} 
 

 
function rotate(matrix, dir) { 
 
    for (let y = 0; y < matrix.length; ++y) { 
 
     for (let x = 0; x < y; ++x) { 
 
      [ 
 
       matrix[x][y], 
 
       matrix[y][x], 
 
      ] = [ 
 
       matrix[y][x], 
 
       matrix[x][y], 
 
      ]; 
 
     } 
 
    } 
 

 
    if (dir > 0) { 
 
     matrix.forEach(row => row.reverse()); 
 
    } else { 
 
     matrix.reverse(); 
 
    } 
 
} 
 

 
function playerDrop() { 
 
    player.pos.y++; 
 
    if (collide(arena, player)) { 
 
     player.pos.y--; 
 
     merge(arena, player); 
 
     playerReset(); 
 
     arenaSweep(); 
 
     updateScore(); 
 
    } 
 
    dropCounter = 0; 
 
} 
 

 
function playerMove(offset) { 
 
    player.pos.x += offset; 
 
    if (collide(arena, player)) { 
 
     player.pos.x -= offset; 
 
    } 
 
} 
 

 
function playerReset() { 
 
    const pieces = 'TJLOSZI'; 
 
    player.matrix = createPiece(pieces[pieces.length * Math.random() | 0]); 
 
    player.pos.y = 0; 
 
    player.pos.x = (arena[0].length/2 | 0) - 
 
        (player.matrix[0].length/2 | 0); 
 
    if (collide(arena, player)) { 
 
     arena.forEach(row => row.fill(0)); 
 
     player.score = 0; 
 
     updateScore(); 
 
    } 
 
} 
 

 
function playerRotate(dir) { 
 
    const pos = player.pos.x; 
 
    let offset = 1; 
 
    rotate(player.matrix, dir); 
 
    while (collide(arena, player)) { 
 
     player.pos.x += offset; 
 
     offset = -(offset + (offset > 0 ? 1 : -1)); 
 
     if (offset > player.matrix[0].length) { 
 
      rotate(player.matrix, -dir); 
 
      player.pos.x = pos; 
 
      return; 
 
     } 
 
    } 
 
} 
 

 
let dropCounter = 0; 
 
let dropInterval = 1000; 
 

 
let lastTime = 0; 
 
function update(time = 0) { 
 
    const deltaTime = time - lastTime; 
 

 
    dropCounter += deltaTime; 
 
    if (dropCounter > dropInterval) { 
 
     playerDrop(); 
 
    } 
 

 
    lastTime = time; 
 

 
    draw(); 
 
    requestAnimationFrame(update); 
 
} 
 

 
function updateScore() { 
 
    document.getElementById('score').innerText = player.score; 
 
} 
 

 
document.addEventListener('keydown', event => { 
 
    if (event.keyCode === 37) { 
 
     playerMove(-1); 
 
    } else if (event.keyCode === 39) { 
 
     playerMove(1); 
 
    } else if (event.keyCode === 40) { 
 
     playerDrop(); 
 
    } else if (event.keyCode === 81) { 
 
     playerRotate(-1); 
 
    } else if (event.keyCode === 87) { 
 
     playerRotate(1); 
 
    } 
 
}); 
 

 
const colors = [ 
 
    null, 
 
    '#FF0D72', 
 
    '#0DC2FF', 
 
    '#0DFF72', 
 
    '#F538FF', 
 
    '#FF8E0D', 
 
    '#FFE138', 
 
    '#3877FF', 
 
]; 
 

 
const arena = createMatrix(12, 20); 
 

 
const player = { 
 
    pos: {x: 0, y: 0}, 
 
    matrix: null, 
 
    score: 0, 
 
}; 
 

 
playerReset(); 
 
updateScore(); 
 
update();
<html> 
 
<head> 
 
    <title>Tetris</title> 
 
    <style> 
 
     body { 
 
     background: #202028; 
 
     color: #fff; 
 
     font-family: sans-serif; 
 
     font-size: 2em; 
 
     text-align: center; 
 
     } 
 
     canvas { 
 
     border: solid .2em #fff; 
 
     height: 90vh; 
 
     } 
 
    </style> 
 
</head> 
 
<body> 
 
    <div id="score"></div> 
 
    <canvas id="tetris" width="240" height="400" /> 
 
    <script src="tetris.js"></script> 
 
</body> 
 
</html>

+0

游戏看起来令人惊讶! –

回答

0

这里是我的想法,我希望它能帮助。请运行该代码段。

const canvas = document.getElementById('tetris'); 
 
const context = canvas.getContext('2d'); 
 

 
context.scale(20, 20); 
 

 
function arenaSweep() { 
 
    let rowCount = 1; 
 
    outer: for (let y = arena.length -1; y > 0; --y) { 
 
     for (let x = 0; x < arena[y].length; ++x) { 
 
      if (arena[y][x] === 0) { 
 
       continue outer; 
 
      } 
 
     } 
 

 
     const row = arena.splice(y, 1)[0].fill(0); 
 
     arena.unshift(row); 
 
     ++y; 
 

 
     player.score += rowCount * 10; 
 
     rowCount *= 2; 
 
    } 
 
} 
 

 
function collide(arena, player) { 
 
    const m = player.matrix; 
 
    const o = player.pos; 
 
    for (let y = 0; y < m.length; ++y) { 
 
     for (let x = 0; x < m[y].length; ++x) { 
 
      if (m[y][x] !== 0 && 
 
       (arena[y + o.y] && 
 
       arena[y + o.y][x + o.x]) !== 0) { 
 
       return true; 
 
      } 
 
     } 
 
    } 
 
    return false; 
 
} 
 

 
function createMatrix(w, h) { 
 
    const matrix = []; 
 
    while (h--) { 
 
     matrix.push(new Array(w).fill(0)); 
 
    } 
 
    return matrix; 
 
} 
 

 
function createPiece(type) 
 
{ 
 
    if (type === 'I') { 
 
     return [ 
 
      [0, 1, 0, 0], 
 
      [0, 1, 0, 0], 
 
      [0, 1, 0, 0], 
 
      [0, 1, 0, 0], 
 
     ]; 
 
    } else if (type === 'L') { 
 
     return [ 
 
      [0, 2, 0], 
 
      [0, 2, 0], 
 
      [0, 2, 2], 
 
     ]; 
 
    } else if (type === 'J') { 
 
     return [ 
 
      [0, 3, 0], 
 
      [0, 3, 0], 
 
      [3, 3, 0], 
 
     ]; 
 
    } else if (type === 'O') { 
 
     return [ 
 
      [4, 4], 
 
      [4, 4], 
 
     ]; 
 
    } else if (type === 'Z') { 
 
     return [ 
 
      [5, 5, 0], 
 
      [0, 5, 5], 
 
      [0, 0, 0], 
 
     ]; 
 
    } else if (type === 'S') { 
 
     return [ 
 
      [0, 6, 6], 
 
      [6, 6, 0], 
 
      [0, 0, 0], 
 
     ]; 
 
    } else if (type === 'T') { 
 
     return [ 
 
      [0, 7, 0], 
 
      [7, 7, 7], 
 
      [0, 0, 0], 
 
     ]; 
 
    } 
 
} 
 

 
function drawMatrix(matrix, offset) { 
 
    matrix.forEach((row, y) => { 
 
     row.forEach((value, x) => { 
 
      if (value !== 0) { 
 
       context.fillStyle = colors[value]; 
 
       context.fillRect(x + offset.x, 
 
           y + offset.y, 
 
           1, 1); 
 
      } 
 
     }); 
 
    }); 
 
} 
 

 
function draw() { 
 
    context.fillStyle = '#000'; 
 
    context.fillRect(0, 0, canvas.width, canvas.height); 
 

 
    drawMatrix(arena, {x: 0, y: 0}); 
 
    drawMatrix(player.matrix, player.pos); 
 
} 
 

 
function merge(arena, player) { 
 
    player.matrix.forEach((row, y) => { 
 
     row.forEach((value, x) => { 
 
      if (value !== 0) { 
 
       arena[y + player.pos.y][x + player.pos.x] = value; 
 
      } 
 
     }); 
 
    }); 
 
} 
 

 
function rotate(matrix, dir) { 
 
    for (let y = 0; y < matrix.length; ++y) { 
 
     for (let x = 0; x < y; ++x) { 
 
      [ 
 
       matrix[x][y], 
 
       matrix[y][x], 
 
      ] = [ 
 
       matrix[y][x], 
 
       matrix[x][y], 
 
      ]; 
 
     } 
 
    } 
 

 
    if (dir > 0) { 
 
     matrix.forEach(row => row.reverse()); 
 
    } else { 
 
     matrix.reverse(); 
 
    } 
 
} 
 

 
function playerDrop() { 
 
    player.pos.y++; 
 
    if (collide(arena, player)) { 
 
     player.pos.y--; 
 
     merge(arena, player); 
 
     playerReset(); 
 
     arenaSweep(); 
 
     updateScore(); 
 
    } 
 
    dropCounter = 0; 
 
} 
 

 
function playerMove(offset) { 
 
    player.pos.x += offset; 
 
    if (collide(arena, player)) { 
 
     player.pos.x -= offset; 
 
    } 
 
} 
 

 
function playerReset() { 
 
    const pieces = 'TJLOSZI'; 
 
    player.matrix = createPiece(pieces[pieces.length * Math.random() | 0]); 
 
    player.pos.y = 0; 
 
    player.pos.x = (arena[0].length/2 | 0) - 
 
        (player.matrix[0].length/2 | 0); 
 
    if (collide(arena, player)) { 
 
     arena.forEach(row => row.fill(0)); 
 
     player.score = 0; 
 
     updateScore(); 
 
    } 
 
} 
 

 
function playerRotate(dir) { 
 
    const pos = player.pos.x; 
 
    let offset = 1; 
 
    rotate(player.matrix, dir); 
 
    while (collide(arena, player)) { 
 
     player.pos.x += offset; 
 
     offset = -(offset + (offset > 0 ? 1 : -1)); 
 
     if (offset > player.matrix[0].length) { 
 
      rotate(player.matrix, -dir); 
 
      player.pos.x = pos; 
 
      return; 
 
     } 
 
    } 
 
} 
 

 
let dropCounter = 0; 
 
let dropInterval = 1000; 
 

 
let lastTime = 0; 
 
function update(time = 0) { 
 
    const deltaTime = time - lastTime; 
 

 
    dropCounter += deltaTime; 
 
    if (dropCounter > dropInterval) { 
 
     playerDrop(); 
 
    } 
 

 
    lastTime = time; 
 

 
    draw(); 
 
    requestAnimationFrame(update); 
 
} 
 

 
function updateScore() { 
 
    document.getElementById('score').innerText = player.score; 
 
} 
 

 
document.addEventListener('keydown', event => { 
 
    if (event.keyCode === 37) { 
 
     playerMove(-1); 
 
    } else if (event.keyCode === 39) { 
 
     playerMove(1); 
 
    } else if (event.keyCode === 40) { 
 
     playerDrop(); 
 
    } else if (event.keyCode === 81) { 
 
     playerRotate(-1); 
 
    } else if (event.keyCode === 87) { 
 
     playerRotate(1); 
 
    } 
 
}); 
 

 
const colors = [ 
 
    null, 
 
    '#FF0D72', 
 
    '#0DC2FF', 
 
    '#0DFF72', 
 
    '#F538FF', 
 
    '#FF8E0D', 
 
    '#FFE138', 
 
    '#3877FF', 
 
]; 
 

 
const arena = createMatrix(12, 20); 
 

 
const player = { 
 
    pos: {x: 0, y: 0}, 
 
    matrix: null, 
 
    score: 0, 
 
};
<html> 
 
<head> 
 
    <title>Tetris</title> 
 
    <style> 
 
     body { 
 
     background: #202028; 
 
     color: #fff; 
 
     font-family: sans-serif; 
 
     font-size: 2em; 
 
     text-align: center; 
 
     } 
 
     canvas { 
 
     border: solid .2em #fff; 
 
     height: 90vh; 
 
     } 
 
     #main{ 
 
     display: none; 
 
     } 
 
     #newGame, #creditBtn, #backBtn{ 
 
     text-align: center; 
 
     vertical-align: middle; 
 
     border: 2px solid goldenrod; 
 
     border-radius: 7px; 
 
     background-color: gold; 
 
     color: orangeRed; 
 
     font-size: 32px; 
 
     font-weight: bold; 
 
     font-family: "Courier New"; 
 
     width: 5em; 
 
     margin: 5px auto; 
 
     
 
     } 
 
     #theHead{ 
 
     margin: auto; 
 
     color: orange; 
 
     font-size: 2em; 
 
     font-family: "Courier New"; 
 
     } 
 
     #credits{ 
 
     margin: auto; 
 
     color: orange; 
 
     font-size: 1em; 
 
     font-family: "Courier New"; 
 
     display: none; 
 
     background-color: inherit; 
 
     } 
 
     #backBtn{ 
 
     display: none; 
 
     } 
 
    </style> 
 
</head> 
 
<body> 
 
    <div id="theHead">Welcome to Tetris!</div> 
 
    <div id="newGame" onclick="runGame()" onmouseover="this.style.backgroundColor = 'goldenrod'" onmouseout="this.style.backgroundColor = 'gold'">New Game</div> 
 
    <div id="creditBtn" onmouseover="this.style.backgroundColor = 'goldenrod'" onmouseout="this.style.backgroundColor = 'gold'" onclick="showCredits()">Credits</div> 
 
    <div id="credits">Tetris: Made by Maya</div> 
 
    <div id="backBtn" onmouseover="this.style.backgroundColor = 'goldenrod'" onmouseout="this.style.backgroundColor = 'gold'" onclick="goBack()">Back</div> 
 
    <div id="main"> 
 
    <div id="score"></div> 
 
    <canvas id="tetris" width="240" height="400" /> 
 
    </div> 
 
    <script src="tetris.js"></script> 
 
    <script> 
 
     var runGame = function(){ 
 
     document.getElementById("newGame").style.display = "none"; 
 
     document.getElementById("theHead").style.display = "none"; 
 
     
 
document.getElementById("credits").style.display = "none";  
 
     document.getElementById("main").style.display = "block"; 
 
     document.getElementById("creditBtn").style.display = "none"; 
 
     playerReset(); 
 
     updateScore(); 
 
     update(); 
 
     }; 
 
    var showCredits = function(){ 
 
     document.getElementById("theHead").style.display = "none"; 
 
     document.getElementById("creditBtn").style.display = "none"; 
 
     document.getElementById("newGame").style.display = "none"; 
 
     document.getElementById("credits").style.display = "block"; 
 
     document.getElementById("backBtn").style.display = "block"; 
 
    }; 
 
     
 
    var goBack = function(){ 
 
     document.getElementById("backBtn").style.display = "none"; 
 
     document.getElementById("credits").style.display = "none"; 
 
     document.getElementById("theHead").style.display = "block"; 
 
     document.getElementById("newGame").style.display = "block"; 
 
     document.getElementById("creditBtn").style.display = "block"; 
 
    }; 
 
    </script> 
 
    
 
</body> 
 
<html>

+0

您已经很好地使用了JavaScript! – Frost