Skip to content

Commit

Permalink
Feat: snake-game 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
play3step authored Jan 13, 2024
1 parent 321ab52 commit 5e4fc66
Show file tree
Hide file tree
Showing 2 changed files with 251 additions and 0 deletions.
83 changes: 83 additions & 0 deletions game-server/src/main/resources/static/snake-game.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Snake Game</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: 'Arial', sans-serif;
background-color: #F7F7F7;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}

.game-container {
background-color: #FFFFFF;
padding: 2rem;
border-radius: 1rem;
box-shadow: 0 0 1rem rgba(0, 0, 0, .1);
text-align: center;
}

h1 {
font-size: 2rem;
margin-bottom: 1rem;
}

canvas {
display: block;
margin: 0 auto;
border: 1px solid #000;
}

.buttons {
margin-top: 1rem;
}

.buttons button {
background-color: #4CAF50;
border: none;
color: white;
padding: 0.5rem 1rem;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 1rem;
margin: 0 0.5rem;
cursor: pointer;
border-radius: 0.5rem;
}

.buttons button:hover {
background-color: #45a049;
}

.score {
font-size: 1.2rem;
margin-top: 1rem;
}
</style>
</head>

<body>
<div class="game-container">
<canvas id="game-board" width="720" height="720"></canvas>
<div class="buttons">
<button id="start-btn">시작</button>
<button id="stop-btn">정지</button>
</div>
<p class="score">점수: <span id="score">0</span></p>
</div>
<script src="snake-game.js"></script>
</body>

</html>
168 changes: 168 additions & 0 deletions game-server/src/main/resources/static/snake-game.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
const canvas = document.getElementById("game-board");
const ctx = canvas.getContext("2d");
const scale = 40;
const rows = canvas.height / scale;
const columns = canvas.width / scale;
let score = 0;

let snake;
let fruit;
let gameInterval;

(function setup() {
snake = new Snake();
fruit = new Fruit();

fruit.pickLocation();

}());

function startGame() {
if (!gameInterval) {
gameInterval = setInterval(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
fruit.draw();
snake.update();
snake.draw();

if (snake.eat(fruit)) {
score++;
document.getElementById("score").textContent = score;
fruit.pickLocation();
}

snake.checkCollision();
}, 100);
}
}

function stopGame() {
clearInterval(gameInterval);
gameInterval = null;
}

function gameOver() {
alert("게임 오버! 점수: " + score);
fetch("http://54.210.228.54:8080/log", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userId: "1",
gameId: 58,
gameScore: score,
}),
})
.then((response) => {
console.log(response);
})
.catch((error) => {
console.error("게임 점수 전송 중 오류 발생:", error);
});
snake.reset();
stopGame();
}

function Snake() {
this.x = 0;
this.y = 0;
this.xSpeed = scale;
this.ySpeed = 0;
this.tail = [];

this.draw = function () {
ctx.fillStyle = "#4CAF50";

for (let i = 0; i < this.tail.length; i++) {
ctx.fillRect(this.tail[i].x, this.tail[i].y, scale, scale);
}

ctx.fillRect(this.x, this.y, scale, scale);
};

this.update = function () {
for (let i = 0; i < this.tail.length - 1; i++) {
this.tail[i] = this.tail[i + 1];
}

this.tail[this.tail.length - 1] = { x: this.x, y: this.y };

this.x += this.xSpeed;
this.y += this.ySpeed;

if (this.x < 0 || this.y < 0 || this.x >= canvas.width || this.y >= canvas.height) {
gameOver();
}
};

this.changeDirection = function (direction) {
switch (direction) {
case "w":
this.xSpeed = 0;
this.ySpeed = -scale;
break;
case "s":
this.xSpeed = 0;
this.ySpeed = scale;
break;
case "a":
this.xSpeed = -scale;
this.ySpeed = 0;
break;
case "d":
this.xSpeed = scale;
this.ySpeed = 0;
break;
}
};

this.eat = function (fruit) {
if (this.x === fruit.x && this.y === fruit.y) {
this.tail.push({ x: this.x - this.xSpeed, y: this.y - this.ySpeed });
return true;
}
return false;
};

this.checkCollision = function () {
for (let i = 0; i < this.tail.length; i++) {
if (this.x === this.tail[i].x && this.y === this.tail[i].y) {
gameOver();
}
}
};

this.reset = function () {
this.x = 0;
this.y = 0;
this.tail = [];
this.xSpeed = scale;
this.ySpeed = 0;
score = 0;
document.getElementById("score").textContent = score;
};
}

function Fruit() {
this.x = 0;
this.y = 0;

this.pickLocation = function () {
this.x = Math.floor(Math.random() * columns) * scale;
this.y = Math.floor(Math.random() * rows) * scale;
};

this.draw = function () {
ctx.fillStyle = "#FF4136";
ctx.fillRect(this.x, this.y, scale, scale);
};
}

window.addEventListener("keydown", (event) => {
const direction = event.key.replace("Arrow", "");
snake.changeDirection(direction);
});

document.getElementById("start-btn").addEventListener("click", startGame);
document.getElementById("stop-btn").addEventListener("click", stopGame);

0 comments on commit 5e4fc66

Please sign in to comment.