728x90
안녕하세요 오늘은 지난번에 만들었던 테트리스 게임에
레벨업 기능을 추가시켜보도록 하겠습니다.
기존 게임에서는 1초 간격으로 블럭이 하단으로 떨어지도록 구현하였습니다.
전체 코드는 하단에서 확인하실 수 있습니다
오늘은 여기에 레벨업 기능을 추가하여 1분마다 블럭의 하강 속도가 기존 속도대비 20%씩 빨라지도록 구현해보겠습니다.
간단한 테트리스 게임 만들기 1편은 아래 링크에서 확인하실 수 있습니다.
자바스크립트 코드입니다.
변경된 부분은 아래와 같습니다.
// 1분마다 레벨을 증가시키고, 속도를 올리는 타이머
setInterval(() => {
increaseLevel();
}, 60000);
let level = 0;
let linesCleared = 0;
// 레벨 증가 및 속도 조절 함수
function increaseLevel() {
level += 1;
dropInterval *= 0.8; // 속도 증가 비율을 20%로 조정
updateLevelAndSpeed(); // 레벨과 속도 UI 업데이트
}
// 레벨과 속도 UI 업데이트 함수
function updateLevelAndSpeed() {
document.getElementById('level').textContent = `Level: ${level}`;
document.getElementById('speed').textContent = `Speed: ${Math.round(dropInterval)}ms`;
}
기존 속도에서 20% 증가되도록 dropInterval 변수에 0.8 을 곱해줍니다.
html 파일의 ui 요소를 1분마다 변경해줍니다.
(현재 레벨이 0부터 시작하도록 설정되어 있습니다. )
현재 레벨과 블럭 속도를 표시하는 div 가 추가된 html 코드입니다
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tetris Game</title>
<style>
canvas {
background-color: #000;
display: block;
margin: 0 auto;
color: rgb(0, 0, 0); /* 글씨 색상을 흰색으로 명확히 설정 */
border: 2px solid;
}
#info {
text-align: center;
color: rgb(0, 0, 0);
font-family: Arial, sans-serif;
margin-top: 10px;
}
#level, #speed {
font-size: 18px;
margin: 5px 0;
}
</style>
</head>
<body>
<canvas id="tetris" width="300" height="600"></canvas>
<div id="info">
<div id="level">Level: 0</div>
<div id="speed">Speed: 1000ms</div>
</div>
<script src="tetris1.js"></script>
</body>
</html>
레벨, 속도를 표시하는 info 블럭을 컨버스 아래에 추가해줍니다
전체 코드는 아래와 같습니다
tetris1.js
const canvas = document.getElementById('tetris');
const context = canvas.getContext('2d');
const grid = 20; // 테트리스 그리드 크기
const cols = canvas.width / grid;
const rows = canvas.height / grid;
let board = Array.from({ length: rows }, () => Array(cols).fill(0));
const colors = [
null,
'cyan',
'blue',
'orange',
'yellow',
'green',
'purple',
'red'
];
const tetrominoes = [
[
[1, 1, 1, 1], // I
],
[
[0, 2, 0],
[2, 2, 2], // T
],
[
[3, 3],
[3, 3], // O
],
[
[0, 4, 4],
[4, 4, 0], // S
],
[
[5, 5, 0],
[0, 5, 5], // Z
],
[
[6, 0, 0],
[6, 6, 6], // J
],
[
[0, 0, 7],
[7, 7, 7], // L
]
];
function createPiece(type) {
return tetrominoes[type];
}
function drawMatrix(matrix, offset) {
matrix.forEach((row, y) => {
row.forEach((value, x) => {
if (value !== 0) {
context.fillStyle = colors[value];
context.fillRect((x + offset.x) * grid, (y + offset.y) * grid, grid, grid);
}
});
});
}
function collide(board, player) {
const [m, o] = [player.matrix, player.pos];
for (let y = 0; y < m.length; y++) {
for (let x = 0; x < m[y].length; x++) {
if (m[y][x] !== 0 &&
(board[y + o.y] &&
board[y + o.y][x + o.x]) !== 0) {
return true;
}
}
}
return false;
}
function merge(board, player) {
player.matrix.forEach((row, y) => {
row.forEach((value, x) => {
if (value !== 0) {
board[y + player.pos.y][x + player.pos.x] = value;
}
});
});
clearLines();
}
function clearLines() {
outer: for (let y = board.length - 1; y >= 0; y--) {
for (let x = 0; x < board[y].length; x++) {
if (board[y][x] === 0) {
continue outer;
}
}
const row = board.splice(y, 1)[0].fill(0);
board.unshift(row);
linesCleared += 1;
}
}
let dropCounter = 0;
let dropInterval = 1000;
let lastTime = 0;
function update(time = 0) {
const deltaTime = time - lastTime;
lastTime = time;
dropCounter += deltaTime;
if (dropCounter > dropInterval) {
playerDrop();
}
draw();
requestAnimationFrame(update);
}
function playerDrop() {
player.pos.y++;
if (collide(board, player)) {
player.pos.y--;
merge(board, player);
playerReset();
}
dropCounter = 0;
}
function playerMove(dir) {
player.pos.x += dir;
if (collide(board, player)) {
player.pos.x -= dir;
}
}
function playerReset() {
player.matrix = createPiece(Math.floor(Math.random() * tetrominoes.length));
player.pos.y = 0;
player.pos.x = Math.floor((cols - player.matrix[0].length) / 2);
if (collide(board, player)) {
board.forEach(row => row.fill(0));
}
}
function draw() {
context.clearRect(0, 0, canvas.width, canvas.height);
drawMatrix(board, { x: 0, y: 0 });
drawMatrix(player.matrix, player.pos);
}
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();
}
return matrix;
}
const player = {
pos: { x: 0, y: 0 },
matrix: createPiece(Math.floor(Math.random() * tetrominoes.length))
};
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) {
player.matrix = rotate(player.matrix, -1);
} else if (event.keyCode === 87) {
player.matrix = rotate(player.matrix, 1);
}
});
update();
// 1분마다 레벨을 증가시키고, 속도를 올리는 타이머
setInterval(() => {
increaseLevel();
}, 60000);
let level = 0;
let linesCleared = 0;
// 레벨 증가 및 속도 조절 함수
function increaseLevel() {
level += 1;
dropInterval *= 0.8; // 속도 증가 비율을 20%로 조정
updateLevelAndSpeed(); // 레벨과 속도 UI 업데이트
}
// 레벨과 속도 UI 업데이트 함수
function updateLevelAndSpeed() {
document.getElementById('level').textContent = `Level: ${level}`;
document.getElementById('speed').textContent = `Speed: ${Math.round(dropInterval)}ms`;
}
// 게임 시작 시 UI 초기화
updateLevelAndSpeed();
tetris.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tetris Game</title>
<style>
canvas {
background-color: #000;
display: block;
margin: 0 auto;
color: rgb(0, 0, 0); /* 글씨 색상을 흰색으로 명확히 설정 */
border: 2px solid;
}
#info {
text-align: center;
color: rgb(0, 0, 0);
font-family: Arial, sans-serif;
margin-top: 10px;
}
#level, #speed {
font-size: 18px;
margin: 5px 0;
}
</style>
</head>
<body>
<canvas id="tetris" width="300" height="600"></canvas>
<div id="info">
<div id="level">Level: 0</div>
<div id="speed">Speed: 1000ms</div>
</div>
<script src="tetris1.js"></script>
</body>
</html>
시연 영상입니다
'JavaScript' 카테고리의 다른 글
[JavaScript] 틱택토(Tic-Tac-Toe) 게임 만들기 (2) | 2024.09.09 |
---|---|
[JavaScript] 도형을 드래그하여 테두리에 정확히 맞추기 (2) | 2024.09.05 |
[JavaScript] 벽돌깨기 게임 발전시키기 - 가속도와 마찰력 추가하기 (2) | 2024.09.03 |
[JavaScript] 벽돌깨기 게임 발전시키기 - 목숨 기능 추가하기 (0) | 2024.08.28 |
[JavaScript] 간단한 테트리스 게임 만들기 (0) | 2024.08.24 |