Snake Game - Py
Snake Game - Py
import random
import time
import sys
import os
# Initialize Pygame
pygame.init()
pygame.mixer.init()
# Game constants
GRID_SIZE = 20
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
PURPLE = (128, 0, 128)
# Directions
UP = (0, -1)
DOWN = (0, 1)
LEFT = (-1, 0)
RIGHT = (1, 0)
class Snake:
def __init__(self):
self.reset()
self.color = GREEN
self.head_color = BLUE
self.speed = 10
self.level = 1
self.score = 0
self.high_score = self.load_high_score()
self.powerup_active = False
self.powerup_time = 0
def reset(self):
self.body = [(SCREEN_WIDTH//2, SCREEN_HEIGHT//2)]
self.direction = random.choice([UP, DOWN, LEFT, RIGHT])
self.length = 1
self.speed = 10
self.level = 1
self.score = 0
self.powerup_active = False
self.powerup_time = 0
def move(self):
head_x, head_y = self.body[0]
dx, dy = self.direction
new_head = ((head_x + dx * GRID_SIZE) % SCREEN_WIDTH,
(head_y + dy * GRID_SIZE) % SCREEN_HEIGHT)
self.body.insert(0, new_head)
if len(self.body) > self.length:
self.body.pop()
def grow(self):
self.length += 1
self.score += 10 * self.level
if self.score > self.high_score:
self.high_score = self.score
self.save_high_score()
def check_collision(self):
return len(self.body) != len(set(self.body))
def load_high_score(self):
try:
with open(HIGH_SCORE_FILE, 'r') as f:
return int(f.read())
except:
return 0
def save_high_score(self):
with open(HIGH_SCORE_FILE, 'w') as f:
f.write(str(self.high_score))
def check_powerup_expired(self):
if self.powerup_active and time.time() - self.powerup_time > 10:
self.powerup_active = False
self.speed = 10 + self.level * 2
class Food:
def __init__(self, snake):
self.position = (0, 0)
self.color = RED
self.spawn(snake)
class PowerUp:
def __init__(self, snake):
self.types = ['speed', 'double', 'shield']
self.type = random.choice(self.types)
self.colors = {'speed': YELLOW, 'double': PURPLE, 'shield': WHITE}
self.color = self.colors[self.type]
self.spawn(snake)
self.spawn_time = time.time()
def spawn(self, snake):
while True:
x = random.randint(0, (SCREEN_WIDTH//GRID_SIZE)-1) * GRID_SIZE
y = random.randint(0, (SCREEN_HEIGHT//GRID_SIZE)-1) * GRID_SIZE
if (x, y) not in snake.body:
self.position = (x, y)
break
class Game:
def __init__(self):
self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Advanced Snake Game")
self.clock = pygame.time.Clock()
self.font = pygame.font.Font(None, 36)
self.snake = Snake()
self.food = Food(self.snake)
self.powerup = None
self.running = True
self.game_over = False
self.in_menu = True
self.level_up = False
self.obstacles = []
def handle_input(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if event.type == pygame.KEYDOWN:
if self.in_menu:
if event.key == pygame.K_RETURN:
self.in_menu = False
elif event.key == pygame.K_q:
self.running = False
elif self.game_over:
if event.key == pygame.K_r:
self.reset_game()
elif event.key == pygame.K_q:
self.running = False
else:
if event.key == pygame.K_UP and self.snake.direction != DOWN:
self.snake.direction = UP
elif event.key == pygame.K_DOWN and self.snake.direction != UP:
self.snake.direction = DOWN
elif event.key == pygame.K_LEFT and self.snake.direction !=
RIGHT:
self.snake.direction = LEFT
elif event.key == pygame.K_RIGHT and self.snake.direction !=
LEFT:
self.snake.direction = RIGHT
def check_collisions(self):
# Food collision
if self.snake.body[0] == self.food.position:
self.snake.grow()
self.food.spawn(self.snake)
if random.random() < 0.3 and not self.powerup:
self.powerup = PowerUp(self.snake)
if self.snake.length % 5 == 0:
self.level_up = True
self.snake.level += 1
self.snake.speed += 2
self.generate_obstacles()
# Powerup collision
if self.powerup and self.snake.body[0] == self.powerup.position:
self.apply_powerup(self.powerup.type)
self.powerup = None
# Obstacle collision
for obstacle in self.obstacles:
if self.snake.body[0] == obstacle:
self.game_over = True
# Self collision
if self.snake.check_collision() and not self.snake.powerup_active:
self.game_over = True
def generate_obstacles(self):
self.obstacles = []
for _ in range(self.snake.level * 2):
while True:
x = random.randint(0, (SCREEN_WIDTH//GRID_SIZE)-1) * GRID_SIZE
y = random.randint(0, (SCREEN_HEIGHT//GRID_SIZE)-1) * GRID_SIZE
pos = (x, y)
if pos not in self.snake.body and pos != self.food.position:
self.obstacles.append(pos)
break
def reset_game(self):
self.snake.reset()
self.food.spawn(self.snake)
self.powerup = None
self.game_over = False
self.obstacles = []
self.level_up = False
def show_menu(self):
self.screen.fill(BLACK)
self.draw_text("SNAKE GAME", GREEN, SCREEN_WIDTH//2, SCREEN_HEIGHT//3)
self.draw_text("Press ENTER to Start", WHITE, SCREEN_WIDTH//2,
SCREEN_HEIGHT//2)
self.draw_text("Q to Quit", WHITE, SCREEN_WIDTH//2, SCREEN_HEIGHT//1.5)
pygame.display.flip()
def show_game_over(self):
self.screen.fill(BLACK)
self.draw_text("GAME OVER", RED, SCREEN_WIDTH//2, SCREEN_HEIGHT//3)
self.draw_text(f"Score: {self.snake.score}", WHITE, SCREEN_WIDTH//2,
SCREEN_HEIGHT//2)
self.draw_text("Press R to Restart", WHITE, SCREEN_WIDTH//2,
SCREEN_HEIGHT//1.5)
self.draw_text("Q to Quit", WHITE, SCREEN_WIDTH//2, SCREEN_HEIGHT//1.3)
pygame.display.flip()
def draw_hud(self):
self.draw_text(f"Score: {self.snake.score}", WHITE, 100, 20)
self.draw_text(f"High Score: {self.snake.high_score}", WHITE, SCREEN_WIDTH
- 150, 20)
self.draw_text(f"Level: {self.snake.level}", WHITE, SCREEN_WIDTH//2, 20)
if self.snake.powerup_active:
remaining = 10 - (time.time() - self.snake.powerup_time)
self.draw_text(f"Power: {int(remaining)}s", YELLOW, SCREEN_WIDTH//2,
50)
def run(self):
while self.running:
self.handle_input()
if self.in_menu:
self.show_menu()
continue
if self.game_over:
self.show_game_over()
continue
self.snake.check_powerup_expired()
self.snake.move()
self.check_collisions()
# Level up animation
if self.level_up:
self.screen.fill(BLACK)
self.draw_text(f"LEVEL {self.snake.level}!", GREEN,
SCREEN_WIDTH//2, SCREEN_HEIGHT//2)
pygame.display.flip()
pygame.time.wait(1000)
self.level_up = False
# Drawing
self.screen.fill(BLACK)
# Draw obstacles
for obstacle in self.obstacles:
pygame.draw.rect(self.screen, RED, (obstacle[0], obstacle[1],
GRID_SIZE, GRID_SIZE))
# Draw food
pygame.draw.rect(self.screen, self.food.color,
(self.food.position[0], self.food.position[1],
GRID_SIZE, GRID_SIZE))
# Draw powerup
if self.powerup:
pygame.draw.rect(self.screen, self.powerup.color,
(self.powerup.position[0], self.powerup.position[1],
GRID_SIZE, GRID_SIZE))
if time.time() - self.powerup.spawn_time > 7:
self.powerup = None
self.snake.draw(self.screen)
self.draw_hud()
pygame.display.flip()
self.clock.tick(self.snake.speed)
pygame.quit()
sys.exit()
if __name__ == "__main__":
game = Game()
game.run()