Python实现一笔画游戏

Python实现一笔画游戏

关于一笔画介绍可参见“HTML5实现一笔画游戏”https://blog.csdn.net/cnds123/article/details/136669088

在Python中,Tkinter是一个广泛使用的标准GUI库,我们将使用它来实现这个游戏。

先给出效果图:

连接线段时,必须按照一定的顺序来连接点。
两点间连线方法:从一个点按下鼠标左键拖动到释放。

源码如下:

import tkinter as tk
from math import sqrt

# 游戏关卡设置
levels = {
    "easy": {
        "points": [
            {"id": 1, "x": 50, "y": 50},
            {"id": 2, "x": 150, "y": 50},
            {"id": 3, "x": 150, "y": 150},
            {"id": 4, "x": 50, "y": 150}
        ],
        "lines": [
            {"start": 1, "end": 2},
            {"start": 2, "end": 3},
            {"start": 3, "end": 4},
            {"start": 4, "end": 1},
            {"start": 2, "end": 4}
        ]
    },
    "medium": {
        "points": [
            {"id": 1, "x": 50, "y": 100}, 
            {"id": 2, "x": 150, "y": 100}, 
            {"id": 3, "x": 250, "y": 100}, 
            {"id": 4, "x": 100, "y": 200}, 
            {"id": 5, "x": 200, "y": 200}
        ],
        "lines": [
            {"start": 1, "end": 2}, 
            {"start": 2, "end": 3}, 
            {"start": 1, "end": 4}, 
            {"start": 2, "end": 5}, 
            {"start": 3, "end": 5}, 
            {"start": 4, "end": 5}
        ]
    },
    "hard": {
        "points": [
            {"id": 1, "x": 50, "y": 50}, 
            {"id": 2, "x": 150, "y": 50}, 
            {"id": 3, "x": 250, "y": 50}, 
            {"id": 4, "x": 50, "y": 150}, 
            {"id": 5, "x": 150, "y": 150}, 
            {"id": 6, "x": 250, "y": 150}, 
            {"id": 7, "x": 50, "y": 250}, 
            {"id": 8, "x": 150, "y": 250}, 
            {"id": 9, "x": 250, "y": 250}
        ],
        "lines": [
            {"start": 1, "end": 2}, 
            {"start": 2, "end": 3}, 
            {"start": 1, "end": 4}, 
            #{"start": 2, "end": 5}, 
            {"start": 3, "end": 6}, 
            {"start": 4, "end": 5}, 
            #{"start": 5, "end": 6}, 
            {"start": 4, "end": 7}, 
            {"start": 5, "end": 8}, 
            {"start": 6, "end": 9}, 
            {"start": 7, "end": 8}, 
            {"start": 8, "end": 9}
        ]
    }
}

class OneStrokeGame:
    def __init__(self, master):
        self.master = master
        self.canvas = tk.Canvas(master, width=300, height=300, bg="white")
        self.canvas.pack()
        
        self.start_point = None
        self.last_point_id = None
        self.user_lines = []
        
        # 添加难度选择按钮
        self.easy_button = tk.Button(master, text="简单", command=lambda: self.start_game("easy"))
        self.easy_button.pack(side="left")
        self.medium_button = tk.Button(master, text="中等", command=lambda: self.start_game("medium"))
        self.medium_button.pack(side="left")
        self.hard_button = tk.Button(master, text="困难", command=lambda: self.start_game("hard"))
        self.hard_button.pack(side="left")
        
        self.preset_points = []
        self.preset_lines = []
        
        self.canvas.bind("<Button-1>", self.on_mouse_down)
        self.canvas.bind("<ButtonRelease-1>", self.on_mouse_up)
        
    def start_game(self, difficulty):
        level = levels.get(difficulty)
        if not level:
            print("未知的难度级别")
            return
        
        self.preset_points = level["points"]
        self.preset_lines = level["lines"]
        self.user_lines = []
        self.last_point_id = None
        self.draw()
        
    def on_mouse_down(self, event):
        self.start_point = self.get_point_from_mouse_event(event.x, event.y)
        
    def on_mouse_up(self, event):
        end_point = self.get_point_from_mouse_event(event.x, event.y)
        if self.start_point and end_point and self.start_point["id"] != end_point["id"]:
            if self.last_point_id is None or self.last_point_id == self.start_point["id"]:
                if self.is_preset_line(self.start_point["id"], end_point["id"]):
                    self.user_lines.append({"start": self.start_point, "end": end_point})
                    self.last_point_id = end_point["id"]
                    self.draw()
                else:
                    print("不能绘制原图中不存在的线段。")
            else:
                print("必须按顺序连接点。")
        
    def get_point_from_mouse_event(self, x, y):
        for point in self.preset_points:
            if sqrt((point["x"] - x) ** 2 + (point["y"] - y) ** 2) < 10:
                return point
        return None
    
    def is_preset_line(self, start_id, end_id):
        return any(line for line in self.preset_lines if (line["start"] == start_id and line["end"] == end_id) or (line["start"] == end_id and line["end"] == start_id))
    
    def draw(self):
        self.canvas.delete("all")
        
        for line in self.preset_lines:
            start = next(p for p in self.preset_points if p["id"] == line["start"])
            end = next(p for p in self.preset_points if p["id"] == line["end"])
            self.canvas.create_line(start["x"], start["y"], end["x"], end["y"], fill="black")
        
        for line in self.user_lines:
            self.canvas.create_line(line["start"]["x"], line["start"]["y"], line["end"]["x"], line["end"]["y"], fill="red")
        
        for point in self.preset_points:
            self.canvas.create_oval(point["x"] - 5, point["y"] - 5, point["x"] + 5, point["y"] + 5, fill="blue")
        
        # 检查胜利条件
        if self.check_win():
            self.canvas.create_text(150, 150, text="恭喜,你完成了这个难度级别的游戏!", fill="green")

    def check_win(self):
        if len(self.user_lines) != len(self.preset_lines):
            return False
        
        # 创建一个用于比较的预设线段副本
        preset_lines_copy = [line.copy() for line in self.preset_lines]
        
        # 检查每个用户线段是否都能在预设线段副本中找到匹配项
        for user_line in self.user_lines:
            matching_line = None
            for line in preset_lines_copy:
                if ((line["start"] == user_line["start"]["id"] and line["end"] == user_line["end"]["id"]) or
                    (line["start"] == user_line["end"]["id"] and line["end"] == user_line["start"]["id"])):
                    matching_line = line
                    break
            
            if matching_line:
                preset_lines_copy.remove(matching_line)
            else:
                return False
                
        return True
            

# 创建Tkinter窗口
root = tk.Tk()
root.title("一笔画游戏")

# 创建游戏实例
game = OneStrokeGame(root)

root.mainloop()

说明,定义不同难度的关卡数据:

const levels = {
    "easy ":{
          // 定义简单难度的点和线段
    },
    "medium": {
        // 定义中等难度的点和线段
    },
    "hard": {
        // 定义高难度的点和线段
    }
};

这些点的 x 和 y 坐标是基于画布的尺寸和布局预设的。你可能需要根据你的具体实现调整这些坐标值,以确保点和线在你的游戏界面中正确显示。此外,这些关卡设计仅作为示例,你可以根据需要调整点和线的数量及布局,创造出更多不同难度的关卡。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习&实践爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值