-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 87daf12
Showing
2 changed files
with
335 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Snake Game</title> | ||
<style> | ||
body { | ||
margin: 0; | ||
overflow: hidden; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: 100vh; | ||
background-color: black; | ||
color: white; | ||
} | ||
|
||
canvas { | ||
border: 10px solid #000; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<canvas id="gameCanvas"></canvas> | ||
|
||
<script> | ||
class Game { | ||
constructor(canvas) { | ||
this.canvas = canvas; | ||
this.ctx = canvas.getContext('2d'); | ||
this.gridSize = 20; | ||
this.snake = [{ x: 100, y: 100 }]; | ||
this.direction = 'right'; | ||
this.food = this.createFood(); | ||
this.score = 0; | ||
this.highScore = 0; | ||
this.gameRunning = true; | ||
|
||
this.drawSquare = this.drawSquare.bind(this); | ||
this.createFood = this.createFood.bind(this); | ||
this.draw = this.draw.bind(this); | ||
this.update = this.update.bind(this); | ||
this.collisionWithSelf = this.collisionWithSelf.bind(this); | ||
this.resetGame = this.resetGame.bind(this); | ||
|
||
document.addEventListener('keydown', this.handleKeyPress.bind(this)); | ||
window.addEventListener('resize', this.handleWindowResize.bind(this)); | ||
|
||
this.handleWindowResize(); | ||
setInterval(this.update, 200); | ||
} | ||
|
||
createFood() { | ||
const x = Math.floor(Math.random() * (this.canvas.width / this.gridSize)) * this.gridSize; | ||
const y = Math.floor(Math.random() * (this.canvas.height / this.gridSize)) * this.gridSize; | ||
return { x, y }; | ||
} | ||
|
||
drawSquare(x, y, color) { | ||
this.ctx.fillStyle = color; | ||
this.ctx.fillRect(x, y, this.gridSize, this.gridSize); | ||
} | ||
|
||
drawCircle(x, y, radius, color) { | ||
this.ctx.fillStyle = color; | ||
this.ctx.beginPath(); | ||
this.ctx.arc(x, y, radius, 0, 2 * Math.PI); | ||
this.ctx.fill(); | ||
} | ||
|
||
draw() { | ||
// Clear the canvas | ||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); | ||
|
||
// Draw the snake | ||
this.snake.forEach((segment, index) => { | ||
const color = index % 2 === 0 ? 'green' : 'darkgreen'; | ||
this.drawSquare(segment.x, segment.y, color); | ||
}); | ||
|
||
// Draw the food as a circle | ||
const foodRadius = this.gridSize / 2; | ||
this.drawCircle(this.food.x + foodRadius, this.food.y + foodRadius, foodRadius, 'red'); | ||
|
||
// Draw the score and high score | ||
this.ctx.fillStyle = 'white'; | ||
this.ctx.font = '15px Arial'; | ||
this.ctx.fillText(`Score: ${this.score} High Score: ${this.highScore}`, 10, 15); | ||
|
||
if (!this.gameRunning) { | ||
this.ctx.fillStyle = 'white'; | ||
this.ctx.font = '20px Arial'; | ||
const gameOverText = 'Game Over! Press Enter to restart.'; | ||
const textWidth = this.ctx.measureText(gameOverText).width; | ||
this.ctx.fillText(gameOverText, (this.canvas.width - textWidth) / 2, this.canvas.height / 2); | ||
} | ||
} | ||
|
||
update() { | ||
if (!this.gameRunning) { | ||
return; | ||
} | ||
|
||
// Move the snake | ||
const head = { ...this.snake[0] }; | ||
switch (this.direction) { | ||
case 'up': | ||
head.y -= this.gridSize; | ||
break; | ||
case 'down': | ||
head.y += this.gridSize; | ||
break; | ||
case 'left': | ||
head.x -= this.gridSize; | ||
break; | ||
case 'right': | ||
head.x += this.gridSize; | ||
break; | ||
} | ||
this.snake.unshift(head); | ||
|
||
// Check for collision with food | ||
if (head.x === this.food.x && head.y === this.food.y) { | ||
this.score += 10; | ||
if (this.score > this.highScore) { | ||
this.highScore = this.score; | ||
} | ||
this.food = this.createFood(); | ||
} else { | ||
// Remove the tail | ||
this.snake.pop(); | ||
} | ||
|
||
// Check for collision with walls or itself | ||
if ( | ||
head.x < 0 || | ||
head.x >= this.canvas.width || | ||
head.y < 0 || | ||
head.y >= this.canvas.height || | ||
this.collisionWithSelf() | ||
) { | ||
this.gameRunning = false; | ||
} | ||
|
||
this.draw(); | ||
} | ||
|
||
collisionWithSelf() { | ||
return this.snake.slice(1).some(segment => segment.x === this.snake[0].x && segment.y === this.snake[0].y); | ||
} | ||
|
||
resetGame() { | ||
this.snake = [{ x: 100, y: 100 }]; | ||
this.direction = 'right'; | ||
this.score = 0; | ||
this.food = this.createFood(); | ||
this.gameRunning = true; | ||
} | ||
|
||
handleKeyPress(event) { | ||
switch (event.key) { | ||
case 'ArrowUp': | ||
this.direction = 'up'; | ||
break; | ||
case 'ArrowDown': | ||
this.direction = 'down'; | ||
break; | ||
case 'ArrowLeft': | ||
this.direction = 'left'; | ||
break; | ||
case 'ArrowRight': | ||
this.direction = 'right'; | ||
break; | ||
case 'Enter': | ||
this.resetGame(); | ||
break; | ||
} | ||
} | ||
|
||
handleWindowResize() { | ||
this.canvas.width = window.innerWidth - 20; // Adjust as needed | ||
this.canvas.height = window.innerHeight - 20; // Adjust as needed | ||
this.food = this.createFood(); // Reset food position on window resize | ||
this.draw(); | ||
} | ||
} | ||
|
||
const canvas = document.getElementById('gameCanvas'); | ||
const game = new Game(canvas); | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import tkinter as tk | ||
import random | ||
from flask import Flask, render_template | ||
|
||
class SnakeGame: | ||
def __init__(self, root, width=400, height=400, delay=100): | ||
self.root = root | ||
self.root.title("Snake Game") | ||
self.canvas = tk.Canvas(root, width=width, height=height, bg="black") | ||
self.canvas.pack() | ||
self.root.bind("<Key>", self.on_key_press) | ||
|
||
self.width = width | ||
self.height = height | ||
self.delay = delay | ||
|
||
self.snake = [(100, 100), (90, 100), (80, 100)] | ||
self.direction = "Right" | ||
|
||
self.food = self.create_food() | ||
|
||
self.score = 0 | ||
self.high_score = 0 | ||
|
||
self.game_over = False | ||
self.update() | ||
|
||
def on_key_press(self, event): | ||
key = event.keysym | ||
directions = ["Up", "Down", "Left", "Right"] | ||
|
||
if key in directions: | ||
opposite_directions = {"Up": "Down", "Down": "Up", "Left": "Right", "Right": "Left"} | ||
if key != opposite_directions[self.direction]: | ||
self.direction = key | ||
|
||
def create_food(self): | ||
x = random.randint(1, (self.width - 10) // 10) * 10 | ||
y = random.randint(1, (self.height - 10) // 10) * 10 | ||
return x, y | ||
|
||
def draw_snake(self): | ||
self.canvas.delete("snake") | ||
for segment in self.snake: | ||
x, y = segment | ||
self.canvas.create_rectangle(x, y, x + 10, y + 10, fill="white", tags="snake") | ||
|
||
def draw_food(self): | ||
x, y = self.food | ||
self.canvas.create_rectangle(x, y, x + 10, y + 10, fill="red", tags="food") | ||
|
||
def draw_score(self): | ||
self.canvas.delete("score") | ||
self.canvas.create_text( | ||
50, | ||
10, | ||
text=f"Score: {self.score} High Score: {self.high_score}", | ||
fill="white", | ||
anchor="nw", | ||
font=("Helvetica", 10), | ||
tags="score", | ||
) | ||
|
||
def check_collision(self): | ||
head = self.snake[0] | ||
if ( | ||
head[0] < 0 | ||
or head[0] >= self.width | ||
or head[1] < 0 | ||
or head[1] >= self.height | ||
or head in self.snake[1:] | ||
): | ||
self.game_over = True | ||
|
||
def update(self): | ||
if not self.game_over: | ||
self.move() | ||
self.check_collision() | ||
self.check_food_collision() | ||
self.draw_snake() | ||
self.draw_food() | ||
self.draw_score() | ||
self.root.after(self.delay, self.update) | ||
else: | ||
self.canvas.create_text( | ||
self.width // 2, | ||
self.height // 2, | ||
text=f"Game Over\nYour Score: {self.score}\nClick to Restart", | ||
fill="white", | ||
font=("Helvetica", 16), | ||
tags="game_over", | ||
) | ||
self.update_high_score() | ||
self.canvas.bind("<Button-1>", self.restart) | ||
|
||
def move(self): | ||
head = list(self.snake[0]) | ||
if self.direction == "Up": | ||
head[1] -= 10 | ||
elif self.direction == "Down": | ||
head[1] += 10 | ||
elif self.direction == "Left": | ||
head[0] -= 10 | ||
elif self.direction == "Right": | ||
head[0] += 10 | ||
self.snake = [tuple(head)] + self.snake[:-1] | ||
|
||
def check_food_collision(self): | ||
if self.snake[0] == self.food: | ||
self.snake.append(self.snake[-1]) | ||
self.canvas.delete("food") # Remove the food from the canvas | ||
self.food = self.create_food() | ||
self.draw_food() # Draw the new food | ||
self.score += 10 | ||
|
||
def update_high_score(self): | ||
if self.score > self.high_score: | ||
self.high_score = self.score | ||
|
||
def restart(self, event): | ||
self.canvas.delete("food") # Remove all food from the canvas | ||
self.snake = [(100, 100), (90, 100), (80, 100)] | ||
self.direction = "Right" | ||
self.food = self.create_food() | ||
self.score = 0 | ||
self.game_over = False | ||
self.canvas.delete("game_over") | ||
self.update() | ||
|
||
if __name__ == "__main__": | ||
root = tk.Tk() | ||
game = SnakeGame(root) | ||
root.mainloop() | ||
|
||
app = Flask(__name__) | ||
|
||
@app.route('/') | ||
def index(): | ||
return render_template('index.html') | ||
|
||
if __name__ == '__main__': | ||
app.run(debug=True) |