Selasa, 08 Oktober 2024

Kumpulan Modifikasi Game Tetris


modifikasi yang ke -1

Codingan:

<!DOCTYPE html>


<html>


<head>


  <title>Basic Tetris HTML Game</title>


  <meta charset="UTF-8">


  <style>


  html, body {


    height: 100%;


    margin: 0;


  }




  body {


    background: black;


    display: flex;


    align-items: center;


    justify-content: center;


  }




  canvas {


    border: 1px solid white;


  }


  </style>


</head>


<body>


<canvas width="355" height="645" id="game"></canvas>


<script>


// https://tetris.fandom.com/wiki/Tetris_Guideline




// get a random integer between the range of [min,max]


// @see https://stackoverflow.com/a/1527820/2124254


function getRandomInt(min, max) {


  min = Math.ceil(min);


  max = Math.floor(max);




  return Math.floor(Math.random() * (max - min + 1)) + min;


}




// generate a new tetromino sequence


// @see https://tetris.fandom.com/wiki/Random_Generator


function generateSequence() {


  const sequence = ['I', 'J', 'L', 'O', 'C', 'T', 'U'];




  while (sequence.length) {


    const rand = getRandomInt(0, sequence.length - 1);


    const name = sequence.splice(rand, 1)[0];


    tetrominoSequence.push(name);


  }


}




// get the next tetromino in the sequence


function getNextTetromino() {


  if (tetrominoSequence.length === 0) {


    generateSequence();


  }




  const name = tetrominoSequence.pop();


  const matrix = tetrominos[name];




  // I and O start centered, all others start in left-middle


  const col = playfield[0].length / 2 - Math.ceil(matrix[0].length / 2);




  // I starts on row 21 (-1), all others start on row 22 (-2)

  const row = name === 'I' ? -1 : -2;




  return {


    name: name, // name of the piece (L, O, etc.)


    matrix: matrix, // the current rotation matrix


    row: row, // current row (starts offscreen)


    col: col // current col


  };


}




// rotate an NxN matrix 90deg


// @see https://codereview.stackexchange.com/a/186834


function rotate(matrix) {


  const N = matrix.length - 1;


  const result = matrix.map((row, i) =>


    row.map((val, j) => matrix[N - j][i])


  );




  return result;


}




// check to see if the new matrix/row/col is valid


function isValidMove(matrix, cellRow, cellCol) {


  for (let row = 0; row < matrix.length; row++) {


    for (let col = 0; col < matrix[row].length; col++) {


      if (matrix[row][col] && (


          // outside the game bounds


          cellCol + col < 0 ||


          cellCol + col >= playfield[0].length ||


          cellRow + row >= playfield.length ||


          // collides with another piece


          playfield[cellRow + row][cellCol + col])


        ) {


        return false;


      }


    }


  }




  return true;


}




// place the tetromino on the playfield


function placeTetromino() {


  for (let row = 0; row < tetromino.matrix.length; row++) {


    for (let col = 0; col < tetromino.matrix[row].length; col++) {


      if (tetromino.matrix[row][col]) {




        // game over if piece has any part offscreen


        if (tetromino.row + row < 0) {


          return showGameOver();


        }

playfield[tetromino.row + row][tetromino.col + col] = tetromino.name;


      }


    }


  }




  // check for line clears starting from the bottom and working our way up


  for (let row = playfield.length - 1; row >= 0; ) {


    if (playfield[row].every(cell => !!cell)) {




      // drop every row above this one


      for (let r = row; r >= 0; r--) {


        for (let c = 0; c < playfield[r].length; c++) {


          playfield[r][c] = playfield[r-1][c];


        }


      }


    }


    else {


      row--;


    }


  }




  tetromino = getNextTetromino();


}




// show the game over screen


function showGameOver() {


  cancelAnimationFrame(rAF);


  gameOver = true;




  context.fillStyle = 'black';


  context.globalAlpha = 0.75;


  context.fillRect(0, canvas.height / 2 - 30, canvas.width, 60);




  context.globalAlpha = 1;


  context.fillStyle = 'white';


  context.font = '36px monospace';


  context.textAlign = 'center';


  context.textBaseline = 'middle';


  context.fillText('GAME OVER!', canvas.width / 2, canvas.height / 2);


}




const canvas = document.getElementById('game');


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


const grid = 32;


const tetrominoSequence = [];




// keep track of what is in every cell of the game using a 2d array


// tetris playfield is 10x20, with a few rows offscreen


const playfield = [];




// populate the empty state


for (let row = -2; row < 20; row++) {


  playfield[row] = [];




  for (let col = 0; col < 10; col++) {


    playfield[row][col] = 0;


  }


}

// how to draw each tetromino


// @see https://tetris.fandom.com/wiki/SRS


const tetrominos = {


  'I': [


    [0,0,0,0],


    [1,1,1,1],


    [0,0,0,0],


    [0,0,0,0]


  ],


  'J': [


    [1,0,0],


    [1,1,1],


    [0,0,0],


  ],


  'L': [


    [0,0,1],


    [1,1,1],


    [0,0,0],


  ],


  'O': [


    [1,1],


    [1,1],


  ],


  's': [


    [0,1,1],


    [1,1,0],


    [0,0,0],


  ],


  'Z': [


    [1,1,0],


    [0,1,1],


    [0,0,0],


  ],


  'T': [


    [0,1,0],


    [1,1,1],


    [0,0,0],


  ]


};

let count = 0;

let tetromino = getNextTetromino();

let rAF = null; // keep track of the animation frame so we can cancel it

let gameOver = false;

// game loop

function loop() {

  rAF = requestAnimationFrame(loop);

 context.clearRect(0,0,canvas.width,canvas.height);

  // draw the playfield

  for (let row = 0; row < 20; row++) {

    for (let col = 0; col < 10; col++) {

      if (playfield[row][col]) {

        const name = playfield[row][col];

        context.fillStyle = colors[name];

        // drawing 1 px smaller than the grid creates a grid effect

        context.fillRect(col * grid, row * grid, grid-1, grid-1);

      }

    }

  }

  // draw the active tetromino

  if (tetromino) {

    // tetromino falls every 35 frames

    if (++count > 35) {

      tetromino.row++;

      count = 0;

      // place piece if it runs into anything

      if (!isValidMove(tetromino.matrix, tetromino.row, tetromino.col)) {

        tetromino.row--;

        placeTetromino();

      }

    }

    context.fillStyle = colors[tetromino.name];

    for (let row = 0; row < tetromino.matrix.length; row++) {

      for (let col = 0; col < tetromino.matrix[row].length; col++) {

        if (tetromino.matrix[row][col]) {

          // drawing 1 px smaller than the grid creates a grid effect

          context.fillRect((tetromino.col + col) * grid, (tetromino.row + row) * grid, grid-1, grid-1);

        }

      }

    }

  }

}

// listen to keyboard events to move the active tetromino

document.addEventListener('keydown', function(e) {

  if (gameOver) return;

  // left and right arrow keys (move)

  if (e.which === 37 || e.which === 39) {

    const col = e.which === 37

      ? tetromino.col - 1

      : tetromino.col + 1;

    if (isValidMove(tetromino.matrix, tetromino.row, col)) {

      tetromino.col = col;

    }

  }

  // up arrow key (rotate)

  if (e.which === 38) {

    const matrix = rotate(tetromino.matrix);

    if (isValidMove(matrix, tetromino.row, tetromino.col)) {

      tetromino.matrix = matrix;

    }

  }

  // down arrow key (drop)

  if(e.which === 40) {

    const row = tetromino.row + 1;

    if (!isValidMove(tetromino.matrix, row, tetromino.col)) {

      tetromino.row = row - 1;

      placeTetromino();

      return;

    }

    tetromino.row = row;

  }

});

// start the game

rAF = requestAnimationFrame(loop);

</script>

</body>

</html>

Hasil kodingan:





Modifikasi yang ke-2

Kodingan:

<!DOCTYPE html>


<html>


<head>


  <title>Basic Julia Tetris HTML Game</title>


  <meta charset="UTF-8">


  <style>


  html, body {


    height: 100%;


    margin: 0;


  }




  body {


    background: rgb(13, 187, 240);


    display: flex;


    align-items: center;


    justify-content: center;


  }




  canvas {


    border: 1px solid rgb(226, 27, 166);


  }


  </style>


</head>


<body>


<canvas width="355" height="645" id="game"></canvas>


<script>


// https://tetris.fandom.com/wiki/Tetris_Guideline




// get a random integer between the range of [min,max]


// @see https://stackoverflow.com/a/1527820/2124254


function getRandomInt(min, max) {


  min = Math.ceil(min);


  max = Math.floor(max);




  return Math.floor(Math.random() * (max - min + 1)) + min;


}




// generate a new tetromino sequence


// @see https://tetris.fandom.com/wiki/Random_Generator


function generateSequence() {


  const sequence = ['I', 'J', 'L', 'O', 'C', 'T', 'U'];




  while (sequence.length) {


    const rand = getRandomInt(0, sequence.length - 1);


    const name = sequence.splice(rand, 1)[0];


    tetrominoSequence.push(name);


  }


}




// get the next tetromino in the sequence


function getNextTetromino() {


  if (tetrominoSequence.length === 0) {


    generateSequence();


  }




  const name = tetrominoSequence.pop();


  const matrix = tetrominos[name];


  // I and O start centered, all others start in left-middle


  const col = playfield[0].length / 2 - Math.ceil(matrix[0].length / 2);




  // I starts on row 21 (-1), all others start on row 22 (-2)


  const row = name === 'I' ? -1 : -2;




  return {


    name: name, // name of the piece (L, O, etc.)


    matrix: matrix, // the current rotation matrix


    row: row, // current row (starts offscreen)


    col: col // current col


  };


}




// rotate an NxN matrix 90deg


// @see https://codereview.stackexchange.com/a/186834


function rotate(matrix) {


  const N = matrix.length - 1;


  const result = matrix.map((row, i) =>


    row.map((val, j) => matrix[N - j][i])


  );




  return result;


}




// check to see if the new matrix/row/col is valid


function isValidMove(matrix, cellRow, cellCol) {


  for (let row = 0; row < matrix.length; row++) {


    for (let col = 0; col < matrix[row].length; col++) {


      if (matrix[row][col] && (


          // outside the game bounds


          cellCol + col < 0 ||


          cellCol + col >= playfield[0].length ||


          cellRow + row >= playfield.length ||


          // collides with another piece


          playfield[cellRow + row][cellCol + col])


        ) {


        return false;


      }


    }


  }




  return true;


}




// place the tetromino on the playfield


function placeTetromino() {


  for (let row = 0; row < tetromino.matrix.length; row++) {


    for (let col = 0; col < tetromino.matrix[row].length; col++) {


      if (tetromino.matrix[row][col]) {




        // game over if piece has any part offscreen


        if (tetromino.row + row < 0) {


          return showGameOver();


        }




        playfield[tetromino.row + row][tetromino.col + col] = tetromino.name;


      }


    }


  }


 // check for line clears starting from the bottom and working our way up


  for (let row = playfield.length - 1; row >= 0; ) {


    if (playfield[row].every(cell => !!cell)) {




      // drop every row above this one


      for (let r = row; r >= 0; r--) {


        for (let c = 0; c < playfield[r].length; c++) {


          playfield[r][c] = playfield[r-1][c];


        }


      }


    }


    else {


      row--;


    }


  }




  tetromino = getNextTetromino();


}




// show the game over screen


function showGameover() {


  cancelAnimationFrame(rAF);


  gameOver = true;




  context.fillStyle = 'black';


  context.globalAlpha = 0.75;


  context.fillRect(0, canvas.height / 2 - 30, canvas.width, 60);




  context.globalAlpha = 1;


  context.fillStyle = 'white';


  context.font = '36px monospace';


  context.textAlign = 'center';


  context.textBaseline = 'middle';


  context.fillText('GAME OVER!', canvas.width / 2, canvas.height / 2);


}




const canvas = document.getElementById('game');


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


const grid = 32;


const tetrominoSequence = [];




// keep track of what is in every cell of the game using a 2d array


// tetris playfield is 10x20, with a few rows offscreen


const playfield = [];

// populate the empty state


for (let row = -2; row < 20; row++) {


  playfield[row] = [];




  for (let col = 0; col < 10; col++) {


    playfield[row][col] = 0;


  }


}




// how to draw each tetromino


// @see https://tetris.fandom.com/wiki/SRS


const tetrominos = {


  'I': [


    [0,0,0,0],


    [1,1,1,1],


    [0,0,0,0],


    [0,0,0,0]


  ],


  'J': [


    [1,0,0],


    [1,1,1],


    [0,0,0],


  ],


  'L': [


    [0,0,1],


    [1,1,1],


    [0,0,0],


  ],


  'O': [


    [1,1],


    [1,1],


  ],


  's': [


    [0,1,1],


    [1,1,0],


    [0,0,0],


  ],


  'Z': [


    [1,1,0],


    [0,1,1],


    [0,0,0],


  ],


  'T': [


    [0,1,0],


    [1,1,1],


    [0,0,0],


  ]


};


// color of each tetromino


const colors = {


  'I': 'mint',


  'O': 'pink',


  'T': 'maroon',


  'S': 'blue',


  'Z': 'white',


  'J': 'silver',


  'L': 'purple'


};




let count = 0;


let tetromino = getNextTetromino();


let rAF = null; // keep track of the animation frame so we can cancel it


let gameOver = false;




// game loop


function loop() {


  rAF = requestAnimationFrame(loop);


  context.clearRect(0,0,canvas.width,canvas.height);




  // draw the playfield


  for (let row = 0; row < 20; row++) {


    for (let col = 0; col < 10; col++) {


      if (playfield[row][col]) {


        const name = playfield[row][col];


        context.fillStyle = colors[name];




        // drawing 1 px smaller than the grid creates a grid effect


        context.fillRect(col * grid, row * grid, grid-1, grid-1);


      }


    }


  }




  // draw the active tetromino


  if (tetromino) {




    // tetromino falls every 35 frames


    if (++count > 35) {


      tetromino.row++;


      count = 0;




      // place piece if it runs into anything


      if (!isValidMove(tetromino.matrix, tetromino.row, tetromino.col)) {


        tetromino.row--;


        placeTetromino();


      }


    }


  context.fillStyle = colors[tetromino.name];




    for (let row = 0; row < tetromino.matrix.length; row++) {


      for (let col = 0; col < tetromino.matrix[row].length; col++) {


        if (tetromino.matrix[row][col]) {




          // drawing 1 px smaller than the grid creates a grid effect


          context.fillRect((tetromino.col + col) * grid, (tetromino.row + row) * grid, grid-1, grid-1);


        }


      }


    }


  }


}




// listen to keyboard events to move the active tetromino


document.addEventListener('keydown', function(e) {


  if (gameOver) return;




  // left and right arrow keys (move)


  if (e.which === 37 || e.which === 39) {


    const col = e.which === 37


      ? tetromino.col - 1


      : tetromino.col + 1;




    if (isValidMove(tetromino.matrix, tetromino.row, col)) {


      tetromino.col = col;


    }


  }




  // up arrow key (rotate)


  if (e.which === 38) {


    const matrix = rotate(tetromino.matrix);


    if (isValidMove(matrix, tetromino.row, tetromino.col)) {


      tetromino.matrix = matrix;


    }


  }




  // down arrow key (drop)


  if(e.which === 40) {


    const row = tetromino.row + 1;




    if (!isValidMove(tetromino.matrix, row, tetromino.col)) {


      tetromino.row = row - 1;




      placeTetromino();


      return;


    }




    tetromino.row = row;


  }


});




// start the game


rAF = requestAnimationFrame(loop);


</script>


</body>


</html>

Hasil codingan:



Modifikasi yang ke-3

Kodingan:

<!DOCTYPE html>



<html>



<head>



  <title>Basic Tetris HTML Game</title>



  <meta charset="UTF-8">



  <style>



  html, body {



    height: 100%;



    margin: 0;



  }







  body {



    background: black;



    display: flex;



    align-items: center;



    justify-content: center;



  }







  canvas {



    border: 1px solid white;



  }



  </style>



</head>



<body>



<canvas width="355" height="645" id="game"></canvas>



<script>



// https://tetris.fandom.com/wiki/Tetris_Guideline

// get a random integer between the range of [min,max]



// @see https://stackoverflow.com/a/1527820/2124254



function getRandomInt(min, max) {



  min = Math.ceil(min);



  max = Math.floor(max);







  return Math.floor(Math.random() * (max - min + 1)) + min;



}







// generate a new tetromino sequence



// @see https://tetris.fandom.com/wiki/Random_Generator



function generateSequence() {



  const sequence = ['I', 'J', 'L', 'O', 'C', 'T', 'U'];







  while (sequence.length) {



    const rand = getRandomInt(0, sequence.length - 1);



    const name = sequence.splice(rand, 1)[0];



    tetrominoSequence.push(name);



  }



}



// get the next tetromino in the sequence



function getNextTetromino() {



  if (tetrominoSequence.length === 0) {



    generateSequence();



  }







  const name = tetrominoSequence.pop();



  const matrix = tetrominos[name];







  // I and O start centered, all others start in left-middle



  const col = playfield[0].length / 2 - Math.ceil(matrix[0].length / 2);







  // I starts on row 21 (-1), all others start on row 22 (-2)

  const row = name === 'I' ? -1 : -2;

return {



    name: name, // name of the piece (L, O, etc.)



    matrix: matrix, // the current rotation matrix



    row: row, // current row (starts offscreen)



    col: col // current col



  };



}







// rotate an NxN matrix 90deg



// @see https://codereview.stackexchange.com/a/186834



function rotate(matrix) {



  const N = matrix.length - 1;



  const result = matrix.map((row, i) =>



    row.map((val, j) => matrix[N - j][i])



  );







  return result;



}

// check to see if the new matrix/row/col is valid



function isValidMove(matrix, cellRow, cellCol) {



  for (let row = 0; row < matrix.length; row++) {



    for (let col = 0; col < matrix[row].length; col++) {



      if (matrix[row][col] && (



          // outside the game bounds



          cellCol + col < 0 ||



          cellCol + col >= playfield[0].length ||



          cellRow + row >= playfield.length ||



          // collides with another piece



          playfield[cellRow + row][cellCol + col])



        ) {



        return false;



      }



    }



  }







  return true;



}

// place the tetromino on the playfield



function placeTetromino() {



  for (let row = 0; row < tetromino.matrix.length; row++) {



    for (let col = 0; col < tetromino.matrix[row].length; col++) {



      if (tetromino.matrix[row][col]) {







        // game over if piece has any part offscreen



        if (tetromino.row + row < 0) {



          return showGameOver();



        }

playfield[tetromino.row + row][tetromino.col + col] = tetromino.name;



      }



    }



  }

// check for line clears starting from the bottom and working our way up



  for (let row = playfield.length - 1; row >= 0; ) {



    if (playfield[row].every(cell => !!cell)) {







      // drop every row above this one



      for (let r = row; r >= 0; r--) {



        for (let c = 0; c < playfield[r].length; c++) {



          playfield[r][c] = playfield[r-1][c];



        }



      }



    }



    else {



      row--;



    }



  }







  tetromino = getNextTetromino();



}







// show the game over screen



function showGameOver() {



  cancelAnimationFrame(rAF);



  gameOver = true;

context.fillStyle = 'black';



  context.globalAlpha = 0.75;



  context.fillRect(0, canvas.height / 2 - 30, canvas.width, 60);







  context.globalAlpha = 1;



  context.fillStyle = 'white';



  context.font = '36px monospace';



  context.textAlign = 'center';



  context.textBaseline = 'middle';



  context.fillText('GAME OVER!', canvas.width / 2, canvas.height / 2);



}







const canvas = document.getElementById('game');



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



const grid = 32;



const tetrominoSequence = [];







// keep track of what is in every cell of the game using a 2d array



// tetris playfield is 10x20, with a few rows offscreen



const playfield = [];







// populate the empty state



for (let row = -2; row < 20; row++) {



  playfield[row] = [];







  for (let col = 0; col < 10; col++) {



    playfield[row][col] = 0;

  }



      }



    }



    else {



      row--;



    }



  }







  tetromino = getNextTetromino();



}







// show the game over screen



function showGameOver() {



  cancelAnimationFrame(rAF);



  gameOver = true;



  context.fillStyle = 'black';



  context.globalAlpha = 0.75;



  context.fillRect(0, canvas.height / 2 - 30, canvas.width, 60);

  context.globalAlpha = 1;



  context.fillStyle = 'white';



  context.font = '36px monospace';



  context.textAlign = 'center';



  context.textBaseline = 'middle';



  context.fillText('GAME OVER!', canvas.width / 2, canvas.height / 2);



}

}







const canvas = document.getElementById('game');



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



const grid = 32;



const tetrominoSequence = [];







// keep track of what is in every cell of the game using a 2d array



// tetris playfield is 10x20, with a few rows offscreen



const playfield = [];







// populate the empty state



for (let row = -2; row < 20; row++) {



  playfield[row] = [];







  for (let col = 0; col < 10; col++) {



    playfield[row][col] = 0;



  }



}

// how to draw each tetromino



// @see https://tetris.fandom.com/wiki/SRS



const tetrominos = {

  'I': [



    [0,0,0,0],



    [1,1,1,1],



    [0,0,0,0],



    [0,0,0,0]



  ],



  'J': [



    [1,0,0],



    [1,1,1],



    [0,0,0],



  ],



  'L': [



    [0,0,1],



    [1,1,1],



    [0,0,0],



  ],



  'O': [



    [1,1],



    [1,1],



  ],



  's': [



    [0,1,1],



    [1,1,0],



    [0,0,0],



  ],



  'Z': [



    [1,1,0],



    [0,1,1],



    [0,0,0],

  'T': [



    [0,1,0],



    [1,1,1],



    [0,0,0],



  ]



};

let count = 0;

let tetromino = getNextTetromino();

let rAF = null; // keep track of the animation frame so we can cancel it

let gameOver = false;

// game loop

function loop() {

  rAF = requestAnimationFrame(loop);

 context.clearRect(0,0,canvas.width,canvas.height);

  // draw the playfield

  for (let row = 0; row < 20; row++) {

    for (let col = 0; col < 10; col++) {

      if (playfield[row][col]) {

        const name = playfield[row][col];

        context.fillStyle = colors[name];

        // drawing 1 px smaller than the grid creates a grid effect

        context.fillRect(col * grid, row * grid, grid-1, grid-1);

      }

    }

  }

  // draw the active tetromino

  if (tetromino) {

    // tetromino falls every 35 frames

    if (++count > 35) {

      tetromino.row++;

      count = 0;

      // place piece if it runs into anything

      if (!isValidMove(tetromino.matrix, tetromino.row, tetromino.col)) {

        tetromino.row--;

        placeTetromino();

      }

    }

context.fillStyle = colors[tetromino.name];

    for (let row = 0; row < tetromino.matrix.length; row++) {

      for (let col = 0; col < tetromino.matrix[row].length; col++) {

        if (tetromino.matrix[row][col]) {

          // drawing 1 px smaller than the grid creates a grid effect

          context.fillRect((tetromino.col + col) * grid, (tetromino.row + row) * grid, grid-1, grid-1);

        }

      }

    }

  }

}

// listen to keyboard events to move the active tetromino

document.addEventListener('keydown', function(e) {

  if (gameOver) return;

  // left and right arrow keys (move)

  if (e.which === 37 || e.which === 39) {

    const col = e.which === 37

      ? tetromino.col - 1

      : tetromino.col + 1;

    if (isValidMove(tetromino.matrix, tetromino.row, col)) {

      tetromino.col = col;

    }

  }

  // up arrow key (rotate)

  if (e.which === 38) {

    const matrix = rotate(tetromino.matrix);

    if (isValidMove(matrix, tetromino.row, tetromino.col)) {

      tetromino.matrix = matrix;

    }

  }

  // down arrow key (drop)

  if(e.which === 40) {

    const row = tetromino.row + 1;

    if (!isValidMove(tetromino.matrix, row, tetromino.col)) {

      tetromino.row = row - 1;

      placeTetromino();

      return;

    }

    tetromino.row = row;

  }

});

// start the game

rAF = requestAnimationFrame(loop);

</script>

</body>

</html>

Hasil kodingan :


Modifikasi game yang ke-4

Kodingan:

<!DOCTYPE html>
<html>
<head>
<title>Basic Tetris HTML Game</title>
<meta charset="UTF-8">
<style>
html, body {
height: 100%;
margin: 0;
}
body {
background: rgb(24, 22, 22);
display: flex;
align-items: center;
justify-content: center;
}
canvas {
border: 1px solid rgb(240, 230, 230);
}
</style>
</head>
<body>
<canvas width="320" height="640" id="game"></canvas>
<script>
// https://tetris.fandom.com/wiki/Tetris_Guideline
// get a random integer between the range of [min,max]
// @see https://stackoverflow.com/a/1527820/2124254
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// generate a new tetromino sequence
// @see https://tetris.fandom.com/wiki/Random_Generator
function generateSequence() {
const sequence = ['I', 'J', 'L', 'O', 'S', 'T', 'Z'];
while (sequence.length) {
const rand = getRandomInt(0, sequence.length - 1);
const name = sequence.splice(rand, 1)[0];
tetrominoSequence.push(name);
}
}
// get the next tetromino in the sequence
function getNextTetromino() {
if (tetrominoSequence.length === 0) {
generateSequence();
}
const name = tetrominoSequence.pop();
const matrix = tetrominos[name];
// I and O start centered, all others start in left-middle
const col = playfield[0].length / 2 - Math.ceil(matrix[0].length / 2);
// I starts on row 21 (-1), all others start on row 22 (-2)
const row = name === 'I' ? -1 : -2;
return {
name: name, // name of the piece (L, O, etc.)
matrix: matrix, // the current rotation matrix
row: row, // current row (starts offscreen)
col: col // current col
};
}
// rotate an NxN matrix 90deg
// @see https://codereview.stackexchange.com/a/186834
function rotate(matrix) {
const N = matrix.length - 1;
const result = matrix.map((row, i) =>
row.map((val, j) => matrix[N - j][i])
);
return result;
}
// check to see if the new matrix/row/col is valid
function isValidMove(matrix, cellRow, cellCol) {
for (let row = 0; row < matrix.length; row++) {
for (let col = 0; col < matrix[row].length; col++) {
if (matrix[row][col] && (
// outside the game bounds
cellCol + col < 0 ||
cellCol + col >= playfield[0].length ||
cellRow + row >= playfield.length ||
// collides with another piece
playfield[cellRow + row][cellCol + col])
) {
return false;
}
}
}
return true;
}
// place the tetromino on the playfield
function placeTetromino() {
for (let row = 0; row < tetromino.matrix.length; row++) {
for (let col = 0; col < tetromino.matrix[row].length; col++) {
if (tetromino.matrix[row][col]) {
// game over if piece has any part offscreen
if (tetromino.row + row < 0) {
return showGameOver();
}
playfield[tetromino.row + row][tetromino.col + col] = tetromino.name;
}
}
}
// check for line clears starting from the bottom and working our way up
for (let row = playfield.length - 1; row >= 0; ) {
if (playfield[row].every(cell => !!cell)) {
// drop every row above this one
for (let r = row; r >= 0; r--) {
for (let c = 0; c < playfield[r].length; c++) {
playfield[r][c] = playfield[r-1][c];
}
}
}
else {
row--;
}
}
tetromino = getNextTetromino();
}
// show the game over screen
function showGameOver() {
cancelAnimationFrame(rAF);
gameOver = true;
context.fillStyle = 'black';
context.globalAlpha = 0.75;
context.fillRect(0, canvas.height / 2 - 30, canvas.width, 60);
context.globalAlpha = 1;
context.fillStyle = 'white';
context.font = '36px monospace';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillText('GAME OVER!', canvas.width / 2, canvas.height / 2);
}
const canvas = document.getElementById('game');
const context = canvas.getContext('2d');
const grid = 32;
const tetrominoSequence = [];
// keep track of what is in every cell of the game using a 2d array
// tetris playfield is 10x20, with a few rows offscreen
const playfield = [];
// populate the empty state
for (let row = -2; row < 20; row++) {
playfield[row] = [];
for (let col = 0; col < 10; col++) {
playfield[row][col] = 0;
}
}
// how to draw each tetromino
// @see https://tetris.fandom.com/wiki/SRS
const tetrominos = {
'I': [
[0,0,0,0],
[1,1,1,1],
[0,0,0,0],
[0,0,0,0]
],
'J': [
[1,0,0],
[1,1,1],
[0,0,0],
],
'L': [
[0,0,1],
[1,1,1],
[0,0,0],
],
'O': [
[1,1],
[1,1],
],
'S': [
[0,1,1],
[1,1,0],
[0,0,0],
],
'Z': [
[1,1,0],
[0,1,1],
[0,0,0],
],
'T': [
[0,1,0],
[1,1,1],
[0,0,0],
]
};
// color of each tetromino
const colors = {
'I': 'pink',
'O': 'yellow',
'T': 'purple',
'S': 'green',
'Z': 'red',
'J': 'blue',
'L': 'teal'
};
let count = 0;
let tetromino = getNextTetromino();
let rAF = null; // keep track of the animation frame so we can cancel it
let gameOver = false;
// game loop
function loop() {
rAF = requestAnimationFrame(loop);
context.clearRect(0,0,canvas.width,canvas.height);
// draw the playfield
for (let row = 0; row < 20; row++) {
for (let col = 0; col < 10; col++) {
if (playfield[row][col]) {
const name = playfield[row][col];
context.fillStyle = colors[name];
// drawing 1 px smaller than the grid creates a grid effect
context.fillRect(col * grid, row * grid, grid-1, grid-1);
}
}
}
// draw the active tetromino
if (tetromino) {
// tetromino falls every 35 frames
if (++count > 35) {
tetromino.row++;
count = 0;
// place piece if it runs into anything
if (!isValidMove(tetromino.matrix, tetromino.row, tetromino.col)) {
tetromino.row--;
placeTetromino();
}
}
context.fillStyle = colors[tetromino.name];
for (let row = 0; row < tetromino.matrix.length; row++) {
for (let col = 0; col < tetromino.matrix[row].length; col++) {
if (tetromino.matrix[row][col]) {
// drawing 1 px smaller than the grid creates a grid effect
context.fillRect((tetromino.col + col) * grid, (tetromino.row + row) * grid, grid-1, grid-1);
}
}
}
}
}
// listen to keyboard events to move the active tetromino
document.addEventListener('keydown', function(e) {
if (gameOver) return;
// left and right arrow keys (move)
if (e.which === 37 || e.which === 39) {
const col = e.which === 37
? tetromino.col - 1
: tetromino.col + 1;
if (isValidMove(tetromino.matrix, tetromino.row, col)) {
tetromino.col = col;
}
}
// up arrow key (rotate)
if (e.which === 38) {
const matrix = rotate(tetromino.matrix);
if (isValidMove(matrix, tetromino.row, tetromino.col)) {
tetromino.matrix = matrix;
}
}
// down arrow key (drop)
if(e.which === 40) {
const row = tetromino.row + 1;
if (!isValidMove(tetromino.matrix, row, tetromino.col)) {
tetromino.row = row - 1;
placeTetromino();
return;
}
tetromino.row = row;
}
});
// start the game
rAF = requestAnimationFrame(loop);
</script>
</body>
</html>

Hasil kodingan :




Modifikasi game yang ke-5

Kodingan:

<!DOCTYPE html>

<html>

<head>

<title>Basic Tetris HTML Game</title>

<meta charset="UTF-8">

<style>

html, body {

height: 100%;

margin: 0;

}

body {

background: rgb(24, 22, 22);

display: flex;

align-items: center;

justify-content: center;

}

canvas {

border: 1px solid rgb(240, 230, 230);

}

</style>

</head>

<body>

<canvas width="320" height="640" id="game"></canvas>

<script>

// https://tetris.fandom.com/wiki/Tetris_Guideline

// get a random integer between the range of [min,max]

// @see https://stackoverflow.com/a/1527820/2124254

function getRandomInt(min, max) {

min = Math.ceil(min);

max = Math.floor(max);

return Math.floor(Math.random() * (max - min + 1)) + min;

}

// generate a new tetromino sequence

// @see https://tetris.fandom.com/wiki/Random_Generator

function generateSequence() {

const sequence = ['I', 'J', 'L', 'O', 'S', 'T', 'Z'];

while (sequence.length) {

const rand = getRandomInt(0, sequence.length - 1);

const name = sequence.splice(rand, 1)[0];

tetrominoSequence.push(name);

}

}

// get the next tetromino in the sequence

function getNextTetromino() {

if (tetrominoSequence.length === 0) {

generateSequence();

}

const name = tetrominoSequence.pop();

const matrix = tetrominos[name];

// I and O start centered, all others start in left-middle

const col = playfield[0].length / 2 - Math.ceil(matrix[0].length / 2);

// I starts on row 21 (-1), all others start on row 22 (-2)

const row = name === 'I' ? -1 : -2;

return {

name: name, // name of the piece (L, O, etc.)

matrix: matrix, // the current rotation matrix

row: row, // current row (starts offscreen)

col: col // current col

};

}

// rotate an NxN matrix 90deg

// @see https://codereview.stackexchange.com/a/186834

function rotate(matrix) {

const N = matrix.length - 1;

const result = matrix.map((row, i) =>

row.map((val, j) => matrix[N - j][i])

);

return result;

}

// check to see if the new matrix/row/col is valid

function isValidMove(matrix, cellRow, cellCol) {

for (let row = 0; row < matrix.length; row++) {

for (let col = 0; col < matrix[row].length; col++) {

if (matrix[row][col] && (

// outside the game bounds

cellCol + col < 0 ||

cellCol + col >= playfield[0].length ||

cellRow + row >= playfield.length ||

// collides with another piece

playfield[cellRow + row][cellCol + col])

) {

return false;

}

}

}

return true;

}

// place the tetromino on the playfield

function placeTetromino() {

for (let row = 0; row < tetromino.matrix.length; row++) {

for (let col = 0; col < tetromino.matrix[row].length; col++) {

if (tetromino.matrix[row][col]) {

// game over if piece has any part offscreen

if (tetromino.row + row < 0) {

return showGameOver();

}

playfield[tetromino.row + row][tetromino.col + col] = tetromino.name;

}

}

}

// check for line clears starting from the bottom and working our way up

for (let row = playfield.length - 1; row >= 0; ) {

if (playfield[row].every(cell => !!cell)) {

// drop every row above this one

for (let r = row; r >= 0; r--) {

for (let c = 0; c < playfield[r].length; c++) {

playfield[r][c] = playfield[r-1][c];

}

}

}

else {

row--;

}

}

tetromino = getNextTetromino();

}

// show the game over screen

function showGameOver() {

cancelAnimationFrame(rAF);

gameOver = true;

context.fillStyle = 'black';

context.globalAlpha = 0.75;

context.fillRect(0, canvas.height / 2 - 30, canvas.width, 60);

context.globalAlpha = 1;

context.fillStyle = 'white';

context.font = '36px monospace';

context.textAlign = 'center';

context.textBaseline = 'middle';

context.fillText('GAME OVER!', canvas.width / 2, canvas.height / 2);

}

const canvas = document.getElementById('game');

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

const grid = 32;

const tetrominoSequence = [];

// keep track of what is in every cell of the game using a 2d array

// tetris playfield is 10x20, with a few rows offscreen

const playfield = [];

// populate the empty state

for (let row = -2; row < 20; row++) {

playfield[row] = [];

for (let col = 0; col < 10; col++) {

playfield[row][col] = 0;

}

}

// how to draw each tetromino

// @see https://tetris.fandom.com/wiki/SRS

const tetrominos = {

'I': [

[0,0,0,0],

[1,1,1,1],

[0,0,0,0],

[0,0,0,0]

],

'J': [

[1,0,0],

[1,1,1],

[0,0,0],

],

'L': [

[0,0,1],

[1,1,1],

[0,0,0],

],

'O': [

[1,1],

[1,1],

],

'S': [

[0,1,1],

[1,1,0],

[0,0,0],

],

'Z': [

[1,1,0],

[0,1,1],

[0,0,0],

],

'T': [

[0,1,0],

[1,1,1],

[0,0,0],

]

};

// color of each tetromino

const colors = {

'I': 'pink',

'O': 'yellow',

'T': 'purple',

'S': 'green',

'Z': 'red',

'J': 'blue',

'L': 'teal'

};

let count = 0;

let tetromino = getNextTetromino();

let rAF = null; // keep track of the animation frame so we can cancel it

let gameOver = false;

// game loop

function loop() {

rAF = requestAnimationFrame(loop);

context.clearRect(0,0,canvas.width,canvas.height);

// draw the playfield

for (let row = 0; row < 20; row++) {

for (let col = 0; col < 10; col++) {

if (playfield[row][col]) {

const name = playfield[row][col];

context.fillStyle = colors[name];

// drawing 1 px smaller than the grid creates a grid effect

context.fillRect(col * grid, row * grid, grid-1, grid-1);

}

}

}

// draw the active tetromino

if (tetromino) {

// tetromino falls every 35 frames

if (++count > 35) {

tetromino.row++;

count = 0;

// place piece if it runs into anything

if (!isValidMove(tetromino.matrix, tetromino.row, tetromino.col)) {

tetromino.row--;

placeTetromino();

}

}

context.fillStyle = colors[tetromino.name];

for (let row = 0; row < tetromino.matrix.length; row++) {

for (let col = 0; col < tetromino.matrix[row].length; col++) {

if (tetromino.matrix[row][col]) {

// drawing 1 px smaller than the grid creates a grid effect

context.fillRect((tetromino.col + col) * grid, (tetromino.row + row) * grid, grid-1, grid-1);

}

}

}

}

}

// listen to keyboard events to move the active tetromino

document.addEventListener('keydown', function(e) {

if (gameOver) return;

// left and right arrow keys (move)

if (e.which === 37 || e.which === 39) {

const col = e.which === 37

? tetromino.col - 1

: tetromino.col + 1;

if (isValidMove(tetromino.matrix, tetromino.row, col)) {

tetromino.col = col;

}

}

// up arrow key (rotate)

if (e.which === 38) {

const matrix = rotate(tetromino.matrix);

if (isValidMove(matrix, tetromino.row, tetromino.col)) {

tetromino.matrix = matrix;

}

}

// down arrow key (drop)

if(e.which === 40) {

const row = tetromino.row + 1;

if (!isValidMove(tetromino.matrix, row, tetromino.col)) {

tetromino.row = row - 1;

placeTetromino();

return;

}

tetromino.row = row;

}

});

// start the game

rAF = requestAnimationFrame(loop);

</script>

</body>

</html>

Hasil kodingan:



Tidak ada komentar:

Posting Komentar

Ulangan Akhir Bab 5

 A. Pilihlah salah satu jawaban yang tepat.  1. Jenis usaha yang memiliki uang kas sebagai modal dan biaya produksi dengan besaran tidak leb...