snake javascriptの内容

snake javascriptの内容

You are currently viewing a revision titled "snake javascriptの内容", saved on 2024年11月27日 10:49 PM by fittingmind
タイトル
snake javascriptの内容
コンテンツ
htmlファイルとcssファイル、jsファイルの三つからなります。 index.html Snake Game
Score: 0
------------------------ style.css body { margin: 0; padding: 0; overflow: hidden; background-color: #f5f5f5; } .container { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; } canvas { border: 1px solid #ccc; } .score { font-size: 24px; font-weight: bold; margin-top: 20px; } #restart-btn { margin-top: 20px; padding: 10px 20px; font-size: 16px; background-color: #4CAF50; color: #fff; border: none; border-radius: 4px; cursor: pointer; } ------------------------------------ game.js // Snake class Snake { constructor(x, y) { this.body = [{ x, y }]; this.direction = "right"; } move() { const head = { ...this.body[0] }; switch (this.direction) { case "up": head.y--; break; case "down": head.y++; break; case "left": head.x--; break; case "right": head.x++; break; } this.body.unshift(head); this.body.pop(); } grow() { const head = this.getHead(); this.body.unshift(head); } getHead() { return { ...this.body[0] }; } checkCollision(canvasWidth, canvasHeight) { const head = this.getHead(); // if (head.x < 0 || head.x >= canvasWidth || head.y < 0 || head.y >= canvasHeight) { return true; } // return this.body.slice(1).some(segment => segment.x === head.x && segment.y === head.y); } } // Food class Food { constructor(canvasWidth, canvasHeight, blockSize) { this.pos = { x: 0, y: 0 }; this.canvasWidth = canvasWidth; this.canvasHeight = canvasHeight; this.blockSize = blockSize; this.respawn(); } respawn() { const maxX = Math.floor(this.canvasWidth / this.blockSize) - 1; const maxY = Math.floor(this.canvasHeight / this.blockSize) - 1; this.pos.x = Math.floor(Math.random() * maxX) * this.blockSize; this.pos.y = Math.floor(Math.random() * maxY) * this.blockSize; } getPos() { return { ...this.pos }; } } // Game class Game { constructor(canvas, canvasWidth, canvasHeight, blockSize) { this.canvas = canvas; this.ctx = canvas.getContext("2d"); this.canvasWidth = canvasWidth; this.canvasHeight = canvasHeight; this.blockSize = blockSize; this.snake = new Snake(5, 5); this.food = new Food(canvasWidth, canvasHeight, blockSize); this.score = 0; this.isGameOver = false; this.intervalId = null; this.init(); } init() { this.canvas.width = this.canvasWidth; this.canvas.height = this.canvasHeight; this.canvas.style.border = "1px solid #ccc"; this.canvas.style.background = "#fff"; this.canvas.style.margin = "0 auto"; document.addEventListener("keydown", this.handleInput.bind(this)); this.draw(); const restartBtn = document.getElementById("restart-btn"); restartBtn.addEventListener("click", () => { this.restart(); }); } start() { let lastFrameTime = performance.now(); let timeSinceLastFrame = 0; const interval = 100; const animate = (timestamp) => { timeSinceLastFrame += timestamp - lastFrameTime; lastFrameTime = timestamp; while (timeSinceLastFrame >= interval) { this.update(); this.draw(); timeSinceLastFrame -= interval; } if (!this.isGameOver) { requestAnimationFrame(animate); } }; animate(lastFrameTime); } stop() { } restart() { this.snake = new Snake(5, 5); this.food.respawn(); this.score = 0; this.updateScore(); if (this.isGameOver) { this.isGameOver = false; this.start(); } } update() { if (this.isGameOver) { return; } this.snake.move(); // if (this.snake.checkCollision()) { if (this.snake.checkCollision(this.canvasWidth / this.blockSize, this.canvasHeight / this.blockSize)) { this.isGameOver = true; this.stop(); alert(`Game over! Your score is ${this.score}.`); return; } const head = this.snake.getHead(); const foodPos = this.food.getPos(); if (head.x * this.blockSize === foodPos.x && head.y * this.blockSize === foodPos.y) { this.snake.grow(); this.food.respawn(); this.score++; this.updateScore(); } } draw() { this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight); this.ctx.fillStyle = "#4CAF50"; this.snake.body.forEach(segment => { this.ctx.fillRect(segment.x * this.blockSize, segment.y * this.blockSize, this.blockSize, this.blockSize); }); this.ctx.fillStyle = "#f44336"; this.ctx.fillRect(this.food.pos.x, this.food.pos.y, this.blockSize, this.blockSize); } handleInput(event) { switch (event.keyCode) { case 38: // up arrow this.snake.direction = "up"; break; case 40: // down arrow this.snake.direction = "down"; break; case 37: // left arrow this.snake.direction = "left"; break; case 39: // right arrow this.snake.direction = "right"; break; } } updateScore() { const scoreElem = document.getElementById("score"); scoreElem.textContent = this.score; } } // const canvas = document.getElementById("canvas"); const game = new Game(canvas, 400, 400, 10); game.start();
抜粋
脚注


Old New Date Created Author Actions
2024年11月27日 1:49 PM fittingmind

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です