当地图在pygame中移动时用鼠标找到一个项目

时间:2019-04-16 07:28:59

标签: python pygame

我正在创建一个游戏,其中玩家居中于曲面中间。该表面会移动,而不是我希望能够添加剑之类的物体的玩家。我有一个问题,当我第一次开始游戏时,可以将鼠标光标放在对象上,但是当我四处移动时,将鼠标光标放在对象上没有任何作用,而在另一个区域,它却可以完成预期的工作。我认为随着地图的移动,它会离开屏幕,从而改变鼠标落在对象上的位置。我创建了此示例以显示我的意思

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。这基本上是我想要实现的,但无法弄清

2 个答案:

答案 0 :(得分:1)

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

  • 世界坐标(逻辑坐标,例如(0, 0)始终为(0, 0),无论滚动/摄像头还是地图移动

  • 屏幕坐标(用于确定某物在实际屏幕上的实际位置,例如itemPos = (4,8)在世界坐标中,并通过乘以32转换为屏幕坐标:{{1 }}。

因此,当您阅读鼠标位置时,将获得屏幕坐标。然后,您必须将它们转换为世界坐标,或者对照(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)

答案 1 :(得分:0)

我尝试了您的代码,但遇到相同的错误。我通过定义另一个名为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进行了测试。