main
parent
93fc737eb5
commit
3a9060714a
@ -0,0 +1,206 @@
|
||||
import pygame
|
||||
import random
|
||||
|
||||
# 初始化 Pygame
|
||||
pygame.init()
|
||||
|
||||
# 游戏窗口设置
|
||||
WINDOW_X = 720
|
||||
WINDOW_Y = 480
|
||||
game_window = pygame.display.set_mode((WINDOW_X, WINDOW_Y))
|
||||
pygame.display.set_caption('贪吃蛇游戏')
|
||||
|
||||
# 颜色定义
|
||||
BLACK = pygame.Color(0, 0, 0)
|
||||
WHITE = pygame.Color(255, 255, 255)
|
||||
RED = pygame.Color(255, 0, 0)
|
||||
GREEN = pygame.Color(0, 255, 0)
|
||||
|
||||
# 游戏控制
|
||||
FPS = pygame.time.Clock()
|
||||
FONT_SMALL = pygame.font.SysFont('simhei', 20)
|
||||
FONT_MEDIUM = pygame.font.SysFont('simhei', 30)
|
||||
FONT_LARGE = pygame.font.SysFont('simhei', 50)
|
||||
|
||||
class SnakeGame:
|
||||
def __init__(self):
|
||||
self.reset_game()
|
||||
|
||||
def reset_game(self):
|
||||
"""重置游戏状态"""
|
||||
self.snake_position = [100, 50]
|
||||
self.snake_body = [[100, 50], [90, 50], [80, 50], [70, 50]]
|
||||
self.food_position = [
|
||||
random.randrange(1, (WINDOW_X // 10)) * 10,
|
||||
random.randrange(1, (WINDOW_Y // 10)) * 10
|
||||
]
|
||||
self.food_spawn = True
|
||||
self.direction = 'RIGHT'
|
||||
self.change_to = self.direction
|
||||
self.score = 0
|
||||
self.speed = 10
|
||||
self.game_over_flag = False
|
||||
self.key_press_time = None
|
||||
|
||||
def show_score(self, position=1):
|
||||
"""显示当前分数"""
|
||||
score_surface = FONT_SMALL.render(f'分数 : {self.score}', True, WHITE)
|
||||
score_rect = score_surface.get_rect()
|
||||
if position == 1:
|
||||
score_rect.midtop = (WINDOW_X / 10, 15)
|
||||
else:
|
||||
score_rect.midtop = (WINDOW_X / 2, WINDOW_Y / 1.25)
|
||||
game_window.blit(score_surface, score_rect)
|
||||
|
||||
def game_over(self):
|
||||
"""显示游戏结束界面"""
|
||||
game_over_surface = FONT_LARGE.render(f'你的分数 : {self.score}', True, RED)
|
||||
game_over_rect = game_over_surface.get_rect()
|
||||
game_over_rect.midtop = (WINDOW_X / 2, WINDOW_Y / 4)
|
||||
game_window.blit(game_over_surface, game_over_rect)
|
||||
|
||||
restart_surface = FONT_MEDIUM.render('按C键重新开始游戏', True, WHITE)
|
||||
restart_rect = restart_surface.get_rect()
|
||||
restart_rect.midtop = (WINDOW_X / 2, WINDOW_Y / 2)
|
||||
game_window.blit(restart_surface, restart_rect)
|
||||
|
||||
pygame.display.flip()
|
||||
|
||||
def handle_events(self):
|
||||
"""处理用户输入事件"""
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
return False
|
||||
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_UP:
|
||||
self.change_to = 'UP'
|
||||
self.key_press_time = pygame.time.get_ticks() / 1000
|
||||
if event.key == pygame.K_DOWN:
|
||||
self.change_to = 'DOWN'
|
||||
self.key_press_time = pygame.time.get_ticks() / 1000
|
||||
if event.key == pygame.K_LEFT:
|
||||
self.change_to = 'LEFT'
|
||||
self.key_press_time = pygame.time.get_ticks() / 1000
|
||||
if event.key == pygame.K_RIGHT:
|
||||
self.change_to = 'RIGHT'
|
||||
self.key_press_time = pygame.time.get_ticks() / 1000
|
||||
if event.key == pygame.K_c and self.game_over_flag:
|
||||
self.reset_game()
|
||||
|
||||
if event.type == pygame.KEYUP:
|
||||
self.key_press_time = None
|
||||
|
||||
return True
|
||||
|
||||
def update_speed(self):
|
||||
"""根据按键时间调整蛇的速度"""
|
||||
if self.key_press_time:
|
||||
elapsed_time = pygame.time.get_ticks() / 1000 - self.key_press_time
|
||||
if elapsed_time < 0.5:
|
||||
self.speed = 15
|
||||
elif elapsed_time < 1:
|
||||
self.speed = 20
|
||||
else:
|
||||
self.speed = 25
|
||||
else:
|
||||
self.speed = 10
|
||||
|
||||
def validate_direction(self):
|
||||
"""确保蛇不能直接反向移动"""
|
||||
if self.change_to == 'UP' and self.direction != 'DOWN':
|
||||
self.direction = self.change_to
|
||||
if self.change_to == 'DOWN' and self.direction != 'UP':
|
||||
self.direction = self.change_to
|
||||
if self.change_to == 'LEFT' and self.direction != 'RIGHT':
|
||||
self.direction = self.change_to
|
||||
if self.change_to == 'RIGHT' and self.direction != 'LEFT':
|
||||
self.direction = self.change_to
|
||||
|
||||
def move_snake(self):
|
||||
"""移动蛇并处理碰撞检测"""
|
||||
# 根据方向移动蛇头
|
||||
if self.direction == 'UP':
|
||||
self.snake_position[1] -= 10
|
||||
if self.direction == 'DOWN':
|
||||
self.snake_position[1] += 10
|
||||
if self.direction == 'LEFT':
|
||||
self.snake_position[0] -= 10
|
||||
if self.direction == 'RIGHT':
|
||||
self.snake_position[0] += 10
|
||||
|
||||
# 蛇吃食物
|
||||
self.snake_body.insert(0, list(self.snake_position))
|
||||
if self.snake_position == self.food_position:
|
||||
self.score += 10
|
||||
self.food_spawn = False
|
||||
else:
|
||||
self.snake_body.pop()
|
||||
|
||||
# 生成新食物
|
||||
if not self.food_spawn:
|
||||
self.food_position = [
|
||||
random.randrange(1, (WINDOW_X // 10)) * 10,
|
||||
random.randrange(1, (WINDOW_Y // 10)) * 10
|
||||
]
|
||||
# 确保新食物不会出现在蛇身上
|
||||
while self.food_position in self.snake_body:
|
||||
self.food_position = [
|
||||
random.randrange(1, (WINDOW_X // 10)) * 10,
|
||||
random.randrange(1, (WINDOW_Y // 10)) * 10
|
||||
]
|
||||
self.food_spawn = True
|
||||
|
||||
# 边界碰撞检测
|
||||
if (self.snake_position[0] < 0 or self.snake_position[0] > WINDOW_X - 10 or
|
||||
self.snake_position[1] < 0 or self.snake_position[1] > WINDOW_Y - 10):
|
||||
self.game_over_flag = True
|
||||
|
||||
# 自身碰撞检测
|
||||
for block in self.snake_body[1:]:
|
||||
if self.snake_position == block:
|
||||
self.game_over_flag = True
|
||||
|
||||
def draw(self):
|
||||
"""绘制游戏元素"""
|
||||
game_window.fill(BLACK)
|
||||
|
||||
# 绘制蛇身和食物
|
||||
for pos in self.snake_body:
|
||||
pygame.draw.rect(game_window, GREEN, pygame.Rect(pos[0], pos[1], 10, 10))
|
||||
pygame.draw.rect(game_window, WHITE, pygame.Rect(self.food_position[0], self.food_position[1], 10, 10))
|
||||
|
||||
# 显示分数
|
||||
self.show_score(1)
|
||||
|
||||
pygame.display.update()
|
||||
|
||||
def run(self):
|
||||
"""游戏主循环"""
|
||||
running = True
|
||||
while running:
|
||||
if self.game_over_flag:
|
||||
self.game_over()
|
||||
# 游戏结束后等待用户按键,不自动重置
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
running = False
|
||||
if event.type == pygame.KEYDOWN and event.key == pygame.K_c:
|
||||
self.reset_game()
|
||||
else:
|
||||
running = self.handle_events()
|
||||
if not running:
|
||||
break
|
||||
|
||||
self.update_speed()
|
||||
self.validate_direction()
|
||||
self.move_snake()
|
||||
self.draw()
|
||||
|
||||
FPS.tick(self.speed)
|
||||
|
||||
pygame.quit()
|
||||
|
||||
if __name__ == "__main__":
|
||||
game = SnakeGame()
|
||||
game.run()
|
Binary file not shown.
Loading…
Reference in new issue