贪吃蛇程序

import tkinter as tk
from tkinter import messagebox, ttk  # 导入ttk模块用于创建Combobox
import random


class SnakeGame:
    def __init__(self, master):
        self.master = master
        self.master.title("贪吃蛇游戏")
        self.master.geometry("400x520")  # 设置初始窗口大小
        self.master.resizable(True, True)  # 允许窗口调整大小

        # 创建控制面板框架
        control_frame = tk.Frame(self.master)
        control_frame.pack(fill=tk.X, pady=5)  # 填充整个宽度

        self.score_label = tk.Label(control_frame, text="得分: 0", font=("Arial", 12))
        self.score_label.pack(side=tk.LEFT, padx=20)

        # 添加暂停按钮
        self.pause_button = tk.Button(
            control_frame,
            text="暂停",
            command=self.toggle_pause,
            width=8,
            state=tk.DISABLED  # 初始状态下禁用暂停按钮
        )
        self.pause_button.pack(side=tk.RIGHT, padx=20)

        # 添加开始按钮
        self.start_button = tk.Button(
            control_frame,
            text="开始",
            command=self.start_game,
            width=8
        )
        self.start_button.pack(side=tk.RIGHT, padx=20)

        # 使用ttk.Combobox创建速度调节菜单
        self.speed_var = tk.StringVar(value="中等")
        speed_options = ["慢速", "中等", "快速"]
        self.speed_menu = ttk.Combobox(control_frame, textvariable=self.speed_var, values=speed_options,
                                       state='readonly', width=8)
        self.speed_menu.bind('<<ComboboxSelected>>', self.set_speed)  # 绑定选择事件
        self.speed_menu.bind("<KeyPress>", self.ignore_keypress)  # 禁用游戏运行时的键盘导航
        self.speed_menu.pack(side=tk.RIGHT, padx=20)

        # 创建游戏区域框架
        game_frame = tk.Frame(self.master)
        game_frame.pack(expand=True, fill=tk.BOTH)  # 扩展并填充剩余空间

        self.canvas = tk.Canvas(game_frame, bg="black", width=400, height=400)
        self.canvas.pack(expand=True, fill=tk.BOTH)  # 扩展并填充剩余空间

        # 初始化游戏状态变量
        self.snake = [(100, 100), (80, 100), (60, 100)]
        self.food = None
        self.direction = "Right"
        self.score = 0
        self.paused = False  # 新增暂停状态
        self.game_started = False  # 标记游戏是否已经开始
        self.speed = 100  # 初始速度为100毫秒每帧

        # 绑定键盘事件
        self.master.bind("<KeyPress>", self.change_direction)
        self.canvas.focus_set()

        # 添加署名标签
        self.signature_label = tk.Label(self.master, text="© 2025 程序员姓名", fg="gray", font=("Arial", 10))
        self.signature_label.pack(side=tk.BOTTOM, pady=5)  # 将署名标签放置在窗口底部

        # 监听窗口大小变化
        self.master.bind("<Configure>", self.on_resize)

    def start_game(self):
        if not self.game_started:
            self.game_started = True
            self.food = self.create_food()  # 在游戏开始时生成食物
            self.score = 0
            self.score_label.config(text=f"得分: {self.score}")
            self.start_button.config(state=tk.DISABLED)  # 禁用开始按钮
            self.pause_button.config(state=tk.NORMAL)  # 启用暂停按钮
            self.canvas.focus_set()  # 确保焦点回到画布上
            self.game_loop()  # 开始游戏循环

    def set_speed(self, event):
        value = self.speed_var.get()
        if value == "慢速":
            self.speed = 150
        elif value == "中等":
            self.speed = 100
        elif value == "快速":
            self.speed = 50
        # 移除吃食物时的速度调整逻辑(在move_snake方法中)

    def create_food(self):
        while True:
            x = random.randint(0, int(self.canvas.winfo_width() / 10) - 1) * 10
            y = random.randint(0, int(self.canvas.winfo_height() / 10) - 1) * 10
            if (x, y) not in self.snake:
                return self.canvas.create_rectangle(x, y, x + 10, y + 10, fill="red")

    def ignore_keypress(self, event):
        """忽略在游戏运行时 Combobox 上的按键事件"""
        if self.game_started and not self.paused:
            return "break"  # 阻止事件进一步传播

    def change_direction(self, event):
        if self.paused:  # 暂停时禁止改变方向
            return

        key = event.keysym
        if key in ["Up", "Down", "Left", "Right"]:
            if (key == "Up" and self.direction != "Down" or
                    key == "Down" and self.direction != "Up" or
                    key == "Left" and self.direction != "Right" or
                    key == "Right" and self.direction != "Left"):
                self.direction = key
                self.canvas.focus_set()  # 确保焦点回到画布上

    def move_snake(self):
        head_x, head_y = self.snake[0]

        if self.direction == "Up":
            new_head = (head_x, head_y - 10)
        elif self.direction == "Down":
            new_head = (head_x, head_y + 10)
        elif self.direction == "Left":
            new_head = (head_x - 10, head_y)
        else:
            new_head = (head_x + 10, head_y)

        # 实现穿墙效果
        canvas_width = self.canvas.winfo_width()
        canvas_height = self.canvas.winfo_height()
        new_head = (
            new_head[0] % canvas_width,  # X坐标超出范围时回到另一边
            new_head[1] % canvas_height  # Y坐标超出范围时回到另一边
        )

        # 自身碰撞检测
        if new_head in self.snake[1:]:
            self.game_over()
            return

        self.snake.insert(0, new_head)

        # 吃食物检测
        food_coords = self.canvas.coords(self.food)
        if (new_head[0] == food_coords[0] and new_head[1] == food_coords[1]):
            self.score += 1
            self.score_label.config(text=f"得分: {self.score}")
            self.canvas.delete(self.food)
            self.food = self.create_food()
            self.speed = max(20, self.speed - 5)  # 提高游戏速度
        else:
            self.snake.pop()

        self.draw_snake()

    def draw_snake(self):
        self.canvas.delete("snake")
        for x, y in self.snake:
            self.canvas.create_rectangle(x, y, x + 10, y + 10, fill="green", tags="snake")

    def game_loop(self):
        if self.game_started and not self.paused:  # 根据暂停状态决定是否移动
            self.move_snake()
        self.master.after(self.speed, self.game_loop)  # 使用当前速度值

    def toggle_pause(self):
        """切换暂停/继续状态"""
        self.paused = not self.paused
        self.pause_button.config(text="继续" if self.paused else "暂停")
        if not self.paused:
            self.canvas.focus_set()  # 恢复焦点以便接收键盘事件

    def game_over(self):
        self.canvas.delete("all")
        answer = messagebox.askyesno("游戏结束", f"得分: {self.score}\n重新开始?")
        if answer:
            self.reset_game()  # 重置游戏状态
        else:
            self.master.destroy()

    def reset_game(self):
        """重置游戏状态"""
        self.snake = [(100, 100), (80, 100), (60, 100)]
        self.food = None
        self.direction = "Right"
        self.score = 0
        self.paused = False
        self.game_started = False
        self.speed = 100
        self.score_label.config(text="得分: 0")
        self.start_button.config(state=tk.NORMAL)
        self.pause_button.config(state=tk.DISABLED)
        self.game_loop()

    def on_resize(self, event):
        if event.widget == self.master:
            # 调整画布尺寸为10的倍数
            new_width = event.width - (event.width % 10)
            new_height = event.height - (event.height % 10)
            self.canvas.config(width=new_width, height=new_height)
            # 更新蛇的位置
            self.snake = [(x % new_width, y % new_height) for x, y in self.snake]
            self.draw_snake()
            # 重新生成食物
            if self.food is not None:
                self.canvas.delete(self.food)
                self.food = self.create_food()


if __name__ == "__main__":
    root = tk.Tk()
    game = SnakeGame(root)
    root.mainloop()
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值