华容道游戏项目文档

这篇文章介绍了如何使用Python和simpleguitk库开发一个交互式的华容道游戏,包括游戏规则、代码结构(初始化、事件处理、逻辑和界面)、以及如何运行和安装所需的库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目介绍

华容道是一种古老的中国益智游戏,其目标是通过移动方块,将特定的方块移动到指定位置以完成布局。这个项目是一个基于Python的华容道游戏,通过图形界面展现游戏画面,并提供交互式操作。

安装要求

在运行本项目前,需要确保已安装Python编程语言以及simpleguitk库。如果尚未安装simpleguitk库,可以通过以下命令进行安装:

#pip install simpleguitk

如何运行

  1. 下载并保存华容道游戏的Python脚本文件(.py)。
  2. 在合适的Python开发环境中打开该文件。
  3. 运行程序即可启动华容道游戏的图形界面。

游戏规则

华容道游戏规则如下:

  • 通过点击方块或使用键盘上的方向键来移动空格位置,从而移动其他方块。
  • 将指定的方块移动至特定位置以完成游戏。

代码结构

本项目的代码结构分为以下几个部分:

  • 游戏初始化:对游戏进行初始化设置,包括界面布局、方块位置等。
  • 事件处理:处理用户操作,包括鼠标点击事件和键盘事件。
  • 游戏逻辑:根据用户操作更新游戏状态,判断游戏是否完成等。
  • 图形界面:使用simpleguitk库创建游戏的图形界面。

示例运行结果

在这里插入图片描述

示例代码

import simpleguitk as gui

# 全局变量
canvas_height = 500  # 画布高度,单位为像素
canvas_width = 400  # 画布宽度,单位为像素
game_over = False  # 游戏是否结束
figure_moving = False  # 是否有运动的人物
figures = {}  # 所有人物
steps = 0  # 移动步数
current_figure = None  # 鼠标点中的人物
current_center = []  # 鼠标点中人物的中心坐标
original_point = []  # 鼠标点击的初始位置坐标,用来计算鼠标拖动的方向
speed = 5  # 人物移动的速度
machao_image = gui.load_image('http://202.201.225.74/video/PythonResoure/ProjectResource/images/project6/machao.png')
zhangfei_image = gui.load_image(
    'http://202.201.225.74/video/PythonResoure/ProjectResource/images/project6/zhangfei.png')
zhaoyun_image = gui.load_image('http://202.201.225.74/video/PythonResoure/ProjectResource/images/project6/zhaoyun.png')
huangzhong_image = gui.load_image(
    'http://202.201.225.74/video/PythonResoure/ProjectResource/images/project6/huangzhong.png')
guanyu_image = gui.load_image('http://202.201.225.74/video/PythonResoure/ProjectResource/images/project6/guanyu.png')
caocao_image = gui.load_image('http://202.201.225.74/video/PythonResoure/ProjectResource/images/project6/caocao.png')
soldier_image = gui.load_image('http://202.201.225.74/video/PythonResoure/ProjectResource/images/project6/shibing.png')

TEST = 0


# Figure类(棋子类)
class Figure:
    def __init__(self, image, src_center, src_size, des_center, des_size, name, move_direction=None):
        self.image = image  # 棋子图像
        self.src_center = src_center  # 源图像中心坐标
        self.src_size = src_size  # 源图像大小
        self.des_center = des_center  # 画布显示图像中心坐标
        self.des_size = des_size  # 画布显示图像大小
        self.name = name  # 棋子名称,如“曹操”
        self.move_direction = move_direction  # 移动方向

    def get_des_center(self):
        return self.des_center

    def get_des_size(self):
        return self.des_size

    def get_name(self):
        return self.name

    def set_move_direction(self, direction):
        self.move_direction = direction

    def draw(self, canvas):
        canvas.draw_image(self.image, self.src_center, self.src_size, self.des_center, self.des_size)

    def update(self):
        if self.move_direction == 'left':
            self.des_center[0] = self.des_center[0] - speed
        elif self.move_direction == 'right':
            self.des_center[0] = self.des_center[0] + speed
        elif self.move_direction == 'up':
            self.des_center[1] = self.des_center[1] - speed
        elif self.move_direction == 'down':
            self.des_center[1] = self.des_center[1] + speed

    def collide(self, other):
        global figure_moving, steps, TEST
        # 判断鼠标拖动的方向
        # 如果向左拖动,
        if self.move_direction == 'left':
            self_left = self.des_center[0] - self.des_size[0] / 2
            other_right = other.get_des_center()[0] + other.get_des_size()[0] / 2
            self_top = self.des_center[1] - self.des_size[1] / 2
            self_bottom = self.des_center[1] + self.des_size[1] / 2
            other_top = other.get_des_center()[1] - other.get_des_size()[1] / 2
            other_bottom = other.get_des_center()[1] + other.get_des_size()[1] / 2

            TEST += 1
            if (self_left == other_right and self_bottom > other_top
                and self_top < other_bottom) or self_left == 0:
                if TEST < 10:
                    self.move_direction = None
                    figure_moving = False
                    TEST = 0
                else:
                    steps += 1
                    self.move_direction = None
                    figure_moving = False
                    TEST = 0
        elif self.move_direction == 'right':
            self_right = self.des_center[0] + self.des_size[0] / 2
            other_left = other.get_des_center()[0] - other.get_des_size()[0] / 2
            self_top = self.des_center[1] - self.des_size[1] / 2
            self_bottom = self.des_center[1] + self.des_size[1] / 2
            other_top = other.get_des_center()[1] - other.get_des_size()[1] / 2
            other_bottom = other.get_des_center()[1] + other.get_des_size()[1] / 2
            TEST += 1
            if (
                    self_right == other_left and self_bottom > other_top and self_top < other_bottom) or self_right == canvas_width:
                if TEST < 10:
                    self.move_direction = None
                    figure_moving = False
                    TEST = 0
                else:
                    steps += 1
                    self.move_direction = None
                    figure_moving = False
                    TEST = 0
        elif self.move_direction == 'up':
            self_top = self.des_center[1] - self.des_size[1] / 2
            other_bottom = other.get_des_center()[1] + other.get_des_size()[1] / 2
            self_left = self.des_center[0] - self.des_size[0] / 2
            self_right = self.des_center[0] + self.des_size[0] / 2
            other_left = other.get_des_center()[0] - other.get_des_size()[0] / 2
            other_right = other.get_des_center()[0] + other.get_des_size()[0] / 2
            TEST += 1
            if (self_top == other_bottom and self_right > other_left and self_left < other_right) or self_top == 0:
                if TEST < 10:
                    self.move_direction = None
                    figure_moving = False
                    TEST = 0
                else:
                    steps += 1
                    self.move_direction = None
                    figure_moving = False
                    TEST = 0
        elif self.move_direction == 'down':
            self_bottom = self.des_center[1] + self.des_size[1] / 2
            other_top = other.get_des_center()[1] - other.get_des_size()[1] / 2
            self_left = self.des_center[0] - self.des_size[0] / 2
            self_right = self.des_center[0] + self.des_size[0] / 2
            other_left = other.get_des_center()[0] - other.get_des_size()[0] / 2
            other_right = other.get_des_center()[0] + other.get_des_size()[0] / 2
            TEST += 1
            if figure_moving:
                if (
                        self_bottom == other_top and self_right > other_left and self_left < other_right) or self_bottom == canvas_height:
                    if TEST < 10:
                        self.move_direction = None
                        figure_moving = False
                        TEST = 0
                    else:
                        steps += 1
                        self.move_direction = None
                        figure_moving = False
                        TEST = 0


# # 检查移动与其它静止棋子及边界的碰撞
def check_collide():
    global game_over, steps, figure_moving, TEST
    # 当前鼠标点中的图像的大小[200,200]和中心坐标[200,400]时,曹操已经到达出逃位置,向下移动,步数加一
    # 否则 遍历figures,检测图像和当前鼠标点中的图像是否发生碰撞

    # 如果当前图像中心位置的纵坐标大于600,说明棋子曹操已经消失,游戏结束,gameover设置True

    if current_figure.get_des_center()[1] > 600:  # 曹操已经消失
        game_over = True

    if current_figure.get_des_size()[0] == 200 and current_figure.get_des_size()[1] == 200 \
            and current_figure.get_des_center()[0] == 200 \
            and current_figure.get_des_center()[1] == 400:  # 曹操到达逃出位置
        current_figure.set_move_direction("down")
        steps += 1
    else:
        for figure in figures.values():
            if figure != current_figure:
                current_figure.collide(figure)


# 绘制全部棋子
def draw_figures(figures, canvas):
    for figure in figures.values():
        figure.draw(canvas)


# 绘制游戏结束信息
def draw_game_over_msg(canvas, msg):
    msgwidth = frame.get_canvas_textwidth(msg, 48, 'sans-serif')
    canvas.draw_text(msg, ((canvas_width - msgwidth) / 2, canvas_height / 2), 48, 'Red', 'sans-serif')


# 鼠标点击事件的处理函数
def mouse_click(pos):
    global current_figure, current_center, original_point, original_center
    if not figure_moving:
        current_figure = None
        for key, figure in figures.items():
            center = figure.get_des_center()
            size = figure.get_des_size()
            if pos[0] >= center[0] - size[0] / 2 and pos[0] <= center[0] + size[0] / 2 and pos[1] >= center[1] - size[
                1] / 2 and pos[1] <= center[1] + size[1] / 2:
                current_figure = figure
                current_center = figure.get_des_center()
                original_point = pos
                original_center = [figure.get_des_center(), 0]
                break


# 鼠标拖动事件的处理函数
def mouse_drag(pos):
    global current_figure, current_center, original_point, figure_moving
    if current_figure != None:
        horizontal_move = pos[0] - original_point[0]
        vertical_move = pos[1] - original_point[1]
        figure_moving = True
        if abs(horizontal_move) > abs(vertical_move):
            if horizontal_move > 0:
                current_figure.set_move_direction("right")
            else:
                current_figure.set_move_direction("left")
        else:
            if vertical_move > 0:
                current_figure.set_move_direction("down")
            else:
                current_figure.set_move_direction("up")


# 屏幕刷新事件处理函数
def draw(canvas):
    global steps
    if game_over:
        draw_game_over_msg(canvas, '通关成功')
    else:
        draw_figures(figures, canvas)
        if current_figure != None:
            check_collide()
            current_figure.update()

    label_text = "移动次数 = " + str(steps) + " 步"
    label.set_text(label_text)


# 为游戏开始或重新开始初始化全局变量,也是鼠标点击按钮的事件处理函数
def start_game():
    global steps, figures, game_over, current_figure, figure_moving
    figure_moving = False
    steps = 0
    figures = {}
    figures['马超'] = Figure(machao_image, [50, 100], [100, 200], [50, 100], [100, 200], '马超')
    figures['曹操'] = Figure(caocao_image, [100, 100], [200, 200], [200, 100], [200, 200], '曹操')
    figures['张飞'] = Figure(zhangfei_image, [50, 100], [100, 200], [350, 100], [100, 200], '张飞')
    figures['赵云'] = Figure(zhaoyun_image, [50, 100], [100, 200], [50, 300], [100, 200], '赵云')
    figures['关羽'] = Figure(guanyu_image, [100, 50], [200, 100], [200, 250], [200, 100], '关羽')
    figures['黄忠'] = Figure(huangzhong_image, [50, 100], [100, 200], [350, 300], [100, 200], '黄忠')
    figures['卒一'] = Figure(soldier_image, [50, 50], [100, 100], [150, 350], [100, 100], '卒一')
    figures['卒二'] = Figure(soldier_image, [50, 50], [100, 100], [250, 350], [100, 100], '卒二')
    figures['卒三'] = Figure(soldier_image, [50, 50], [100, 100], [50, 450], [100, 100], '卒三')
    figures['卒四'] = Figure(soldier_image, [50, 50], [100, 100], [350, 450], [100, 100], '卒四')
    game_over = False
    label.set_text("移动次数 = 0 步")


# 创建窗口初始化画布
frame = gui.create_frame("华容道之横刀立马", canvas_width, canvas_height)
label = frame.add_label("移动次数 = 0 步")

# 注册事件处理函数
frame.set_draw_handler(draw)  # 显示处理,每秒调用draw函数60次
button = frame.add_button('重新开始游戏', start_game, 50)  # 鼠标每次点击“重新开始游戏”按钮,调用start_game函数1次
frame.set_mouseclick_handler(mouse_click)  #
frame.set_mousedrag_handler(mouse_drag)

start_game()
frame.start()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

力江

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

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

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

打赏作者

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

抵扣说明:

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

余额充值