반응형
프롬프트 개발 코드 (단순 기능, 프롬프트 5회 사용)
<!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>
game-body {
padding: 20px 0;
font-family: 'Arial', sans-serif;
background-color: #f4f4f4;
display: flex;
flex-direction: column;
align-items: center;
margin: 0;
}
game-container {
display: grid;
grid-template-columns: repeat(10, 30px);
grid-template-rows: repeat(21, 30px); /* Modified to 21 rows */
gap: 1px;
background-color: #222;
}
game-container > game-cell {
width: 30px;
height: 30px;
background-color: #eee;
}
game-container > game-cell.taken {
background-color: #333;
}
game-container > game-cell.tetromino {
background-color: #007bff;
}
game-controls {
margin-top: 20px;
text-align: center;
}
game-controls > game-button {
padding: 10px 20px;
font-size: 16px;
margin: 5px;
cursor: pointer;
}
game-score {
margin-top: 20px;
font-size: 20px;
}
game-guide {
margin-top: 10px;
font-size: 16px;
}
</style>
</head>
<body>
<game-body>
<game-container id="grid">
<script>
for (let i = 0; i < 210; i++) { /* Modified to 210 cells */
document.write('<game-cell></game-cell>');
}
</script>
</game-container>
<game-controls>
<game-button onclick="startGame()">Start Game</game-button>
<game-button onclick="pauseGame()">Pause</game-button>
<game-button onclick="resetGame()">Reset</game-button>
</game-controls>
<game-score>Score: <span id="score">0</span></game-score>
<game-guide>Controls: W (회전), A (왼쪽), S (내리기), D (오른쪽)</game-guide>
</game-body>
<script>
document.addEventListener('DOMContentLoaded', () => {
const grid = document.querySelector('#grid');
let squares = Array.from(document.querySelectorAll('#grid game-cell'));
const width = 10;
let nextRandom = 0;
let timerId;
let score = 0;
let dropSpeed = 1000;
// The Tetrominoes
const lTetromino = [
[1, width + 1, width * 2 + 1, 2],
[width, width + 1, width + 2, width * 2 + 2],
[1, width + 1, width * 2 + 1, width * 2],
[width, width * 2, width * 2 + 1, width * 2 + 2]
];
const zTetromino = [
[0, width, width + 1, width * 2 + 1],
[width + 1, width + 2, width * 2, width * 2 + 1],
[0, width, width + 1, width * 2 + 1],
[width + 1, width + 2, width * 2, width * 2 + 1]
];
const tTetromino = [
[1, width, width + 1, width + 2],
[1, width + 1, width + 2, width * 2 + 1],
[width, width + 1, width + 2, width * 2 + 1],
[1, width, width + 1, width * 2 + 1]
];
const oTetromino = [
[0, 1, width, width + 1],
[0, 1, width, width + 1],
[0, 1, width, width + 1],
[0, 1, width, width + 1]
];
const iTetromino = [
[1, width + 1, width * 2 + 1, width * 3 + 1],
[width, width + 1, width + 2, width + 3],
[1, width + 1, width * 2 + 1, width * 3 + 1],
[width, width + 1, width + 2, width + 3]
];
const theTetrominoes = [lTetromino, zTetromino, tTetromino, oTetromino, iTetromino];
let currentPosition = 4;
let currentRotation = 0;
// randomly select a Tetromino and its first rotation
let random = Math.floor(Math.random() * theTetrominoes.length);
let current = theTetrominoes[random][currentRotation];
// draw the Tetromino
function draw() {
current.forEach(index => {
if (squares[currentPosition + index]) {
squares[currentPosition + index].classList.add('tetromino');
}
});
}
// undraw the Tetromino
function undraw() {
current.forEach(index => {
if (squares[currentPosition + index]) {
squares[currentPosition + index].classList.remove('tetromino');
}
});
}
// move down function
function moveDown() {
undraw();
currentPosition += width;
draw();
freeze();
}
// freeze function
function freeze() {
if (current.some(index => (currentPosition + index + width) >= 210 || squares[currentPosition + index + width].classList.contains('taken'))) {
current.forEach(index => squares[currentPosition + index].classList.add('taken'));
// start a new Tetromino falling
random = nextRandom;
nextRandom = Math.floor(Math.random() * theTetrominoes.length);
current = theTetrominoes[random][currentRotation];
currentPosition = 4;
draw();
addScore();
gameOver();
increaseSpeed();
}
}
// move the Tetromino left, unless is at the edge or there is a blockage
function moveLeft() {
undraw();
const isAtLeftEdge = current.some(index => (currentPosition + index) % width === 0);
if (!isAtLeftEdge) currentPosition -= 1;
if (current.some(index => squares[currentPosition + index]?.classList.contains('taken'))) {
currentPosition += 1;
}
draw();
}
// move the Tetromino right, unless is at the edge or there is a blockage
function moveRight() {
undraw();
const isAtRightEdge = current.some(index => (currentPosition + index) % width === width - 1);
if (!isAtRightEdge) currentPosition += 1;
if (current.some(index => squares[currentPosition + index]?.classList.contains('taken'))) {
currentPosition -= 1;
}
draw();
}
// rotate the Tetromino
function rotate() {
undraw();
currentRotation++;
if (currentRotation === current.length) { // if currentRotation gets to 4, make it go back to 0
currentRotation = 0;
}
current = theTetrominoes[random][currentRotation];
draw();
}
// move down quickly
function moveDownQuickly() {
undraw();
while (!current.some(index => (currentPosition + index + width) >= 210 || squares[currentPosition + index + width].classList.contains('taken'))) {
currentPosition += width;
}
draw();
freeze();
}
// add functionality to the button
document.addEventListener('keydown', control);
function control(e) {
if (e.key === 'a' || e.key === 'A') {
moveLeft();
} else if (e.key === 'w' || e.key === 'W') {
rotate();
} else if (e.key === 'd' || e.key === 'D') {
moveRight();
} else if (e.key === 's' || e.key === 'S') {
moveDownQuickly();
}
}
function startGame() {
draw();
timerId = setInterval(moveDown, dropSpeed);
nextRandom = Math.floor(Math.random() * theTetrominoes.length);
}
function pauseGame() {
if (timerId) {
clearInterval(timerId);
timerId = null;
}
}
function resetGame() {
pauseGame();
squares.forEach(square => {
square.classList.remove('tetromino');
square.classList.remove('taken');
});
currentPosition = 4;
currentRotation = 0;
random = Math.floor(Math.random() * theTetrominoes.length);
current = theTetrominoes[random][currentRotation];
score = 0;
dropSpeed = 1000;
document.getElementById('score').innerText = score;
draw();
startGame();
}
function addScore() {
for (let i = 0; i < 210; i += width) {
const row = [i, i + 1, i + 2, i + 3, i + 4, i + 5, i + 6, i + 7, i + 8, i + 9];
if (row.every(index => squares[index].classList.contains('taken'))) {
score += 10;
document.getElementById('score').innerText = score;
row.forEach(index => {
squares[index].classList.remove('taken');
squares[index].classList.remove('tetromino');
});
const squaresRemoved = squares.splice(i, width);
squares = squaresRemoved.concat(squares);
squares.forEach(cell => grid.appendChild(cell));
}
}
}
function increaseSpeed() {
if (score % 50 === 0) {
dropSpeed *= 0.9;
clearInterval(timerId);
timerId = setInterval(moveDown, dropSpeed);
}
}
function gameOver() {
if (current.some(index => squares[currentPosition + index].classList.contains('taken'))) {
document.getElementById('score').innerText = 'Game Over';
clearInterval(timerId);
}
}
window.startGame = startGame;
window.pauseGame = pauseGame;
window.resetGame = resetGame;
});
</script>
</body>
</html>
728x90
반응형
'Develop' 카테고리의 다른 글
[Spring Boot] IndexOutOfBoundsException 개선 작업 (0) | 2024.07.24 |
---|---|
[Java] Mybatis Column '{컬럼명}' in IN/ALL/ANY subquery is ambiguous 해결 (0) | 2024.07.19 |
[Flutter] 안드로이드 스튜디오 Profiler, Devtools (0) | 2024.07.12 |
[JDK, PASS] cannot access class com.sun.crypto.provider.SunJCE (0) | 2024.06.20 |
계좌이체 자동화 프로그램 (0) | 2024.05.26 |
[입금이체] 웹뷰 환경에서의 앱링크 미동작 이슈 (0) | 2024.05.25 |
[설계] 웹앱 서비스 계좌/입금이체 기능 추가의 건 (0) | 2024.05.22 |
[SQL] 불필요한 쿼리 제거 작업 (0) | 2024.05.08 |