【问题标题】:find an item with a mouse when map moves in pygame当地图在pygame中移动时用鼠标找到一个项目
【发布时间】:2019-04-16 07:28:59
【问题描述】:

我正在创建一个玩家位于表面中间的游戏。这个表面移动而不是这个玩家,我希望能够添加诸如剑之类的对象。我有一个问题,当我第一次开始游戏时,我可以将鼠标光标放在对象上,但是当我四处移动时,将鼠标光标放在对象上并没有做任何事情,而在另一个区域,它会做它应该做的事情。我认为随着地图的移动,它会离开屏幕,改变鼠标落在物体上的位置。我创建了这个示例来说明我的意思

import pygame

width,height = 800,600
screen = pygame.display.set_mode((width,height))
world = pygame.Surface((20 * 32, 40 * 32))
itemPos = (4,8)
for x in range(20):
    for y in range(40):
        pygame.draw.rect(world, (255,0,0), (x * 32,y * 32,32,32), 2)
x,y = 0,0
while True:
    screen.fill((0,0,0))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    key = pygame.key.get_pressed()
    if key[pygame.K_w]:
        y += 10
    if key[pygame.K_s]:
        y -= 10
    if key[pygame.K_a]:
        x += 10
    if key[pygame.K_d]:
        x -= 10
    screen.blit(world, (x,y))
    mouse = pygame.mouse.get_pos()
    pygame.draw.rect(world, (0,255,0), (itemPos[0] * 32,itemPos[1] * 32,20,20))
    if mouse[0] > itemPos[0] * 32 and mouse[0] < (itemPos[0] * 32) + 32:
        if mouse[1] > itemPos[1] * 32 and mouse[1] < (itemPos[1] * 32) + 32:
            print("Mouse is over item")
    pygame.display.update()

红色的空心方块只是地图。然后较小的绿色方块是我测试光标是否结束的对象。尝试代码并移动一下,然后尝试将光标放在绿色对象上以获取mouse is over item。这基本上是我想要实现但无法弄清楚的目标

【问题讨论】:

  • 我不明白我认为我没有使用 HDPI 缩放。如果您可以让程序加载移动一下然后尝试。我四处走动后会出现问题。
  • 我在高级显示设置中检查了我的图形,它是 Intel HD Graphics 520。不确定这是否是 HDPI。但如果是这样,如果这是我的问题,我将如何在我的游戏中解决这个问题

标签: python pygame


【解决方案1】:

您需要意识到,当您使用滚动/相机/移动地图创建游戏时,您需要处理两种不同的坐标:

  • 世界坐标(逻辑坐标,例如(0, 0)总是(0, 0),无论滚动/相机或地图移动

  • 屏幕坐标(用于确定实际屏幕上某物的实际位置,例如itemPos = (4,8) 是世界坐标,通过乘以 32 转换为屏幕坐标:(itemPos[0] * 32,itemPos[1] * 32)

因此,当您读取鼠标位置时,您会获得屏幕坐标。然后,您必须将它们转换为世界坐标,或对照您的 item 的屏幕坐标进行检查。

你已经在这里了:

if mouse[0] > itemPos_rel[0] * 32 and mouse[0] < (itemPos_rel[0] * 32) + 32:

但你没有看地图的滚动/移动。

所以要么平移鼠标位置:

...
mouse = pygame.mouse.get_pos()
mouse = mouse[0] - x, mouse[1] - y
...

或更好(注意我不再更改背景表面):

...
clock = pygame.time.Clock()
i=0
def world2screen(pos, scrolling):
    return pos[0] * 32 + scrolling[0], pos[1] * 32 + scrolling[1]

while True:
    ...

    screen.blit(world, (x,y))

    item_pos_screen = world2screen(itemPos, (x, y))
    pygame.draw.rect(screen, (0,255,0), (*item_pos_screen,20,20))

    mouse = pygame.mouse.get_pos()
    if mouse[0] > item_pos_screen[0] and mouse[0] < item_pos_screen[0] + 32:
        if mouse[1] > item_pos_screen[1] and mouse[1] < item_pos_screen[1] + 32:
            i+=1
            print("Mouse is over item" + str(i))


    pygame.display.update()
    clock.tick(60)

或事件更好:

...
clock = pygame.time.Clock()
i=0
def world2screen(pos, scrolling):
    return pos[0] * 32 + scrolling[0], pos[1] * 32 + scrolling[1]

def screen2world(pos, scrolling):
    return int((pos[0] - scrolling[0]) / 32), int((pos[1] - scrolling[1]) / 32 )

while True:
    ...
    screen.blit(world, (x,y))

    item_pos_screen = world2screen(itemPos, (x, y))
    pygame.draw.rect(screen, (0,255,0), (*item_pos_screen,20,20))

    mouse = pygame.mouse.get_pos()
    mouse_pos_world = screen2world(mouse, (x, y))

    if mouse_pos_world == itemPos:
        i+=1
        print("Mouse is over item" + str(i))

    pygame.display.update()
    clock.tick(60)

【讨论】:

    【解决方案2】:

    我试过你的代码,我得到了同样的错误。我通过定义另一个名为itemPos_rel 的列表来绕过它。我根据按键移动项目的相对位置。这不是一个优雅的解决方案,我相信有更好的方法来做到这一点。但也许它现在对你有用。

    import pygame
    import sys
    import time
    
    width,height = 800,600
    screen = pygame.display.set_mode((width,height))
    world = pygame.Surface((20 * 32, 40 * 32))
    itemPos = (4,8)
    itemPos_rel = [4,8] ## Add relative item position
    for x in range(20):
        for y in range(40):
            pygame.draw.rect(world, (255,0,0), (x * 32,y * 32,32,32), 2)
    x,y = 0,0
    while True:
        screen.fill((0,0,0))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
                break
        key = pygame.key.get_pressed()
        if key[pygame.K_w]:
            y += 10
            itemPos_rel[1] += 10/32
        if key[pygame.K_s]:
            y -= 10
            itemPos_rel[1] -= 10/32
        if key[pygame.K_a]:
            x += 10
            itemPos_rel[0] += 10/32
        if key[pygame.K_d]:
            x -= 10
            itemPos_rel[0] -= 10/32
        screen.blit(world, (x,y))
        mouse = pygame.mouse.get_pos()
        pygame.draw.rect(world, (0,255,0), (itemPos[0] * 32,itemPos[1] * 32,20,20))
        if mouse[0] > itemPos_rel[0] * 32 and mouse[0] < (itemPos_rel[0] * 32) + 32:
            if mouse[1] > itemPos_rel[1] * 32 and mouse[1] < (itemPos_rel[1] * 32) + 32:
                print(time.perf_counter(), "Mouse is over item")
        pygame.display.update()
    
    

    我用 python 3.7.1 和 pygame 1.9.5 对其进行了测试。

    【讨论】:

      猜你喜欢
      • 2022-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-19
      • 2016-12-23
      • 1970-01-01
      • 2011-02-04
      • 1970-01-01
      相关资源
      最近更新 更多