贪吃蛇(python版)
·
安装依赖
pip install pygame
完整代码
import pygame
import random
import sys
# 初始化pygame
pygame.init()
# 游戏配置
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
CELL_SIZE = 20
CELL_NUMBER_X = WINDOW_WIDTH // CELL_SIZE
CELL_NUMBER_Y = WINDOW_HEIGHT // CELL_SIZE
# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
DARK_GREEN = (0, 200, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GRAY = (40, 40, 40)
GRASS_COLOR = (167, 209, 61)
TEXT_COLOR = (255, 255, 255)
# 设置游戏窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('贪吃蛇游戏')
clock = pygame.time.Clock()
# 字体设置
font = pygame.font.SysFont('arial', 25)
big_font = pygame.font.SysFont('arial', 50)
class Snake:
def __init__(self):
# 初始位置(身体由多个方块组成)
self.body = [
pygame.Vector2(5, 10),
pygame.Vector2(4, 10),
pygame.Vector2(3, 10)
]
self.direction = pygame.Vector2(1, 0) # 初始向右移动
self.new_block = False
def draw_snake(self):
"""绘制蛇"""
for index, block in enumerate(self.body):
x_pos = int(block.x * CELL_SIZE)
y_pos = int(block.y * CELL_SIZE)
block_rect = pygame.Rect(x_pos, y_pos, CELL_SIZE, CELL_SIZE)
# 蛇头用深绿色,身体用浅绿色
if index == 0:
pygame.draw.rect(screen, DARK_GREEN, block_rect)
else:
pygame.draw.rect(screen, GREEN, block_rect)
def move_snake(self):
"""移动蛇"""
if self.new_block:
body_copy = self.body[:]
body_copy.insert(0, body_copy[0] + self.direction)
self.body = body_copy[:]
self.new_block = False
else:
body_copy = self.body[:-1]
body_copy.insert(0, body_copy[0] + self.direction)
self.body = body_copy[:]
def add_block(self):
"""增加蛇的长度"""
self.new_block = True
def check_collision(self):
"""检查碰撞(撞墙或撞自己)"""
# 检查是否撞墙
if not 0 <= self.body[0].x < CELL_NUMBER_X or not 0 <= self.body[0].y < CELL_NUMBER_Y:
return True
# 检查是否撞到自己
for block in self.body[1:]:
if block == self.body[0]:
return True
return False
class Food:
def __init__(self):
self.randomize()
def draw_food(self):
"""绘制食物"""
food_rect = pygame.Rect(
int(self.pos.x * CELL_SIZE),
int(self.pos.y * CELL_SIZE),
CELL_SIZE,
CELL_SIZE
)
pygame.draw.rect(screen, RED, food_rect)
def randomize(self):
"""随机生成食物位置"""
self.x = random.randint(0, CELL_NUMBER_X - 1)
self.y = random.randint(0, CELL_NUMBER_Y - 1)
self.pos = pygame.Vector2(self.x, self.y)
class Game:
def __init__(self):
self.snake = Snake()
self.food = Food()
self.score = 0
self.game_over = False
def update(self):
"""更新游戏状态"""
if not self.game_over:
self.snake.move_snake()
self.check_collision()
self.check_fail()
def draw_elements(self):
"""绘制所有游戏元素"""
self.food.draw_food()
self.snake.draw_snake()
self.draw_score()
if self.game_over:
self.draw_game_over()
def check_collision(self):
"""检查蛇是否吃到食物"""
if self.food.pos == self.snake.body[0]:
self.food.randomize()
self.snake.add_block()
self.score += 1
# 确保食物不会生成在蛇身上
for block in self.snake.body[1:]:
if block == self.food.pos:
self.food.randomize()
def check_fail(self):
"""检查游戏是否失败"""
if self.snake.check_collision():
self.game_over = True
def draw_score(self):
"""绘制分数"""
score_text = str(self.score)
score_surface = font.render(score_text, True, TEXT_COLOR)
score_x = int(WINDOW_WIDTH - 60)
score_y = int(WINDOW_HEIGHT - 40)
score_rect = score_surface.get_rect(center=(score_x, score_y))
screen.blit(score_surface, score_rect)
def draw_game_over(self):
"""绘制游戏结束界面"""
# 半透明遮罩
overlay = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT))
overlay.set_alpha(150)
overlay.fill((0, 0, 0))
screen.blit(overlay, (0, 0))
game_over_surface = big_font.render('GAME OVER', True, WHITE)
game_over_rect = game_over_surface.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 50))
screen.blit(game_over_surface, game_over_rect)
restart_text = font.render('Press R to Restart or Q to Quit', True, WHITE)
restart_rect = restart_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 20))
screen.blit(restart_text, restart_rect)
def reset(self):
"""重置游戏"""
self.snake = Snake()
self.food = Food()
self.score = 0
self.game_over = False
def main():
game = Game()
# 自定义事件,控制蛇的移动速度
SCREEN_UPDATE = pygame.USEREVENT
pygame.time.set_timer(SCREEN_UPDATE, 150) # 每150毫秒更新一次
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == SCREEN_UPDATE and not game.game_over:
game.update()
if event.type == pygame.KEYDOWN:
if not game.game_over:
# 控制蛇的方向(不能直接反向)
if event.key == pygame.K_UP and game.snake.direction.y != 1:
game.snake.direction = pygame.Vector2(0, -1)
if event.key == pygame.K_DOWN and game.snake.direction.y != -1:
game.snake.direction = pygame.Vector2(0, 1)
if event.key == pygame.K_RIGHT and game.snake.direction.x != -1:
game.snake.direction = pygame.Vector2(1, 0)
if event.key == pygame.K_LEFT and game.snake.direction.x != 1:
game.snake.direction = pygame.Vector2(-1, 0)
else:
# 游戏结束时可以重新开始或退出
if event.key == pygame.K_r:
game.reset()
if event.key == pygame.K_q:
pygame.quit()
sys.exit()
screen.fill(GRAY)
game.draw_elements()
pygame.display.update()
clock.tick(60)
if __name__ == '__main__':
main()
更多推荐


所有评论(0)