如何在 Pygame 中生成第二次点击的位置?

2023-11-29

我正在建造河内塔。

它应该像这样工作:您单击第一个塔,从您想要磁盘移动的位置,然后单击第二个塔,您希望磁盘移动到的位置。磁盘应从第一个塔(一个列表)移动到第二个塔(另一个列表)。

我的问题是,当您第一次单击时,代码会生成位置,不久之后您应该再次单击以决定磁盘应该去哪里,但代码会自动采用第一次单击的位置。

这是我的代码示例:

import pygame, sys
from pygame.locals import *

pygame.init()

DISPLAYSURF = pygame.display.set_mode((500, 400))
pygame.display.set_caption("Tower of Hanoi")

block_red = pygame.image.load('red.png')
block_blue = pygame.image.load('blue.png')
block_green = pygame.image.load('green.png')

rod1 = [block_red, block_blue, block_green]
rod2 = []
rod3 = []

WHITE = (255, 255, 255)

while True:

    DISPLAYSURF.fill(WHITE)

    # get the position of the mouse click
    for event in pygame.event.get():
        if event.type == MOUSEBUTTONDOWN:
            mousex, mousey = pygame.mouse.get_pos()
            click1 = mousex, mousey

            # first in the left part of the screen
            if (mousex > 0) and (mousex < 166) and (mousey > 0) and (mousey < 400):

                if len(rod1) == 0:
                    print "not valid"

                elif len(rod1) == 1 or 2 or 3:
                    disk1 = rod1[-1]
                    rod1.remove(disk1)

                    # click again in a other part of the screen
                    if event.type == MOUSEBUTTONDOWN:
                        mousex, mousey = pygame.mouse.get_pos()   
                        click2 = mousex, mousey

                        if (mousex > 166) and (mousex < 333) and (mousey > 0) and (mousey < 400):
                            rod2.append(disk1)
                        elif (mousex > 333) and (mousex < 500) and (mousey > 0) and (mousey < 400):
                            rod3.append(disk1)
                        else: 
                            rod1.append(disk1)

    # if statement fot the middle part
    # if statement for the right part                        

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    pygame.display.update()

请记住,您的代码在循环中运行,因此您必须跟踪state你的游戏。

点击第一个塔改变状态游戏的部分:现在选择了一个塔,单击塔现在会执行不同的操作(它将一个块从第一个塔移动到第二个塔)。

在您的示例中,您只需要跟踪当前是否选择塔的事实(当然,以及每个塔具有的块)。不要害怕这个词state,一个简单的变量就足够了。

看一下下面的代码(注意注释)。它只是跟踪变量中选定的杆selected,然后检查是否设置为决定是否需要移动块。

import pygame
from collections import namedtuple

pygame.init()
screen = pygame.display.set_mode((500, 400))

# create a named tuple to keep track of the size/location of the rods and their blocks
Rod = namedtuple('Rod', ['rect', 'items'])

# first rod has 4 items. The just use a number to keep track of the size of the blocks 
rods = (Rod(pygame.rect.Rect((100, 150, 25, 250)), [6, 5, 4, 3, 2, 1]),
        Rod(pygame.rect.Rect((225, 150, 25, 250)), []),
        Rod(pygame.rect.Rect((350, 150, 25, 250)), []))

# keep track of the currently selected rod
selected = None

while True:
    if pygame.event.get(pygame.QUIT): break

    screen.fill(pygame.color.Color('white'))

    # draw the rods. It's easy since every rod has a rect which we can use with pygame.draw.rect
    for rod in rods:
        # if a rod is selected, we draw it yellow instead of black
        pygame.draw.rect(screen, pygame.color.Color('yellow' if selected == rod else 'black'), rod.rect)    
        # draw each block of each rod
        for i, item in enumerate(rod.items):
            r = pygame.rect.Rect(rod.rect.x - item * 8, 375 - 25 * i, 25 + item * 16, 25) 
            pygame.draw.rect(screen, pygame.color.Color('green' if selected == rod else 'darkgreen'), r)    

    for e in pygame.event.get():
        if e.type == pygame.MOUSEBUTTONDOWN:
            # check if we clicked a rod. It's easy since every rod has a rect
            rod = next((r for r in rods if r.rect.collidepoint(pygame.mouse.get_pos())), None)
            if rod:
                if selected:
                    # if there's already a rod selected, move block from one the selected
                    # rod to the clicked rod
                    rod.items.append(selected.items.pop())
                    selected = None
                elif rod.items:
                    # if no rod is selected, selected the currently clicked one (if it has blocks)
                    selected = rod
            else:
                selected = None

    pygame.display.flip()   

Result:

enter image description here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Pygame 中生成第二次点击的位置? 的相关文章

随机推荐

  • 复杂MySQL查询错误结果

    我正在尝试构建复杂的 mysql 查询 但它返回错误的结果 SELECT b name AS batch name b id AS batch id COUNT DISTINCT s id AS total students COALESC
  • 如何在我的应用程序中将状态栏设置为白色背景和黑色文本(黑色图标)

    我想在我的应用程序中将状态栏设置为白色背景和黑色文本 和黑色图标 我发现一些应用程序可以做到这一点 但是从谷歌搜索 我找不到任何解决方案来做到这一点 有很多关于如何设置状态栏颜色的解决方案 还有像 SystemBarTint 它只能设置背景
  • 使用 jQuery 获取当前 URL? [复制]

    这个问题在这里已经有答案了 我正在使用 jQuery 如何获取当前 URL 的路径并将其分配给变量 示例网址 http localhost menuname de foo bar amp number 0 要获取路径 您可以使用 var p
  • 如何通过脚本创建 crontab

    我需要通过运行来设置服务器的脚本添加一个 cron 作业 我目前正在使用Ubuntu 我可以用crontab e但这将打开一个编辑器来编辑当前的 crontab 我想以编程方式执行此操作 可以这样做吗 这是一个不使用 不要求新作业位于文件中
  • 如何在循环遍历向量时从向量中删除元素?

    我正在循环遍历一个带有循环的向量 例如for int i 0 i lt vec size i 在此循环中 我检查该向量索引处元素的条件 如果某个条件为真 我想删除该元素 如何在循环遍历向量元素时删除向量元素而不崩溃 从 STL 容器中删除满
  • Python - 在列表理解中保留计数器

    是否可以为以下循环编写列表理解 m counter 0 for i x in enumerate l if x field something counter 1 m append counter i 我不知道如何增加列表理解中的计数器 你
  • Symfony - 未找到表单请求的 url

    我正在从事 symfony 项目 我正在与一个不会重定向到自己页面的表单作斗争 action 属性设置为 method 设置为 post 在这种情况下 它应该调用同一页面 但我会以 404 页面结束 这是我的页面在操作文件中的代码 公共函数
  • 无法识别的选择器发送到实例

    我向核心数据支持的 UITableView 添加了索引搜索 搜索工作正常 但是导航回 tableView 后出现此错误 NSSQLRow controllerDidChangeContent 无法识别的选择器发送到实例 0x815edf0
  • javascript - 在单击再次起作用之前需要 onclick 走完全程

    我有这个 javascript 函数 我使用它 当单击时会移动一定的距离 这是在使用大约 7 个 div 的从左到右的滚动条中使用的 我的问题是 在再次使用点击之前 如何让点击先走完整距离 问题是 如果用户快速单击箭头按钮 它会重置距离 有
  • 在属性窗口中更改自定义属性时不会保存

    我为 DataGridView 创建了一个自定义列 原因是我想向列添加属性 类型 我右键单击 DataGridView 并选择 编辑列 然后 当我选择作为自定义列类型的列时 我可以编辑该属性 但如果我在编辑后单击 确定 然后再次转到 编辑列
  • iOS 8 中 UIKeyboardWillShowNotification 的行为是否有变化?

    我有一个简单的UIView块动画 用于在键盘显示时将一组文本字段动画化到视图中 并在键盘隐藏时将它们动画化回来 这在 iOS 6 和 7 中工作得很好 但现在我得到了不正确的行为 这一切都表明了一些变化UIKeyboardWillShowN
  • 查询包含对不同数据上下文中定义的项目的引用

    我在 Stackoverflow 上阅读了其他几篇文章 但我的问题很简单且不同 我有 2 个独立的数据库 这就是为什么我有两个独立的 Datacontext 这是我的查询 我在其中传递参数并将其绑定到我的 GridView if Sessi
  • Ruby/Rails - 如何根据十进制进行验证?

    如何根据小数位数进行验证 例如 假设我们要存储小数点后最多 2 位小数的酒店评级 4 34 3 76 ETC 我在网上读到了基于您与列绑定的精度 比例截断的 sqlite 因此 如果您的精度为 3 小数位数为 2 并输入 1 34567 则
  • 将特定文件复制到新文件夹,同时保留原始子目录树

    我有一个大目录 其中有许多子目录 我正在尝试对其进行排序 我正在尝试将特定文件类型复制到新文件夹 但我想保留原始子目录 def copyFile src dest try shutil copy src dest except shutil
  • 交换两个变量的 XOR 技巧如何真正在字符串上起作用?

    我刚刚遇到了这段代码 用于在 PHP 中交换两个变量的值
  • 检查 iOS 模拟器类型和版本

    我有以下代码片段来检测 iOS 设备 NSString platformNSString size t size sysctlbyname hw machine NULL size NULL 0 char machine malloc si
  • 我可以在 MySQL 下直接在 SQL 中运行 HTTP GET 吗?

    我很乐意这样做 UPDATE table SET blobCol HTTPGET urlCol WHERE whatever LIMIT n 有代码可以做到这一点吗 我知道这应该是可能的 因为MySQL 文档包括添加执行 DNS 查找的函数
  • 等待与事件处理程序异步

    我对如何最好地处理这种情况感到困惑 我不想等待异步调用的响应 具体来说我有 public async Task
  • 如何在 ASP.Net MVC 5 中动态添加新行

    我正在寻求有关如何在 ASP Net MVC 5 应用程序的创建 Razor 视图中向发票添加新行 LineItems 的帮助 我读过几乎所有类似的问题 但没有一个解决了我认为的简单用例 这是我的发票模型类 public class Inv
  • 如何在 Pygame 中生成第二次点击的位置?

    我正在建造河内塔 它应该像这样工作 您单击第一个塔 从您想要磁盘移动的位置 然后单击第二个塔 您希望磁盘移动到的位置 磁盘应从第一个塔 一个列表 移动到第二个塔 另一个列表 我的问题是 当您第一次单击时 代码会生成位置 不久之后您应该再次单