найти предмет с помощью мыши, когда карта перемещается в пигме - PullRequest
2 голосов
/ 16 апреля 2019

Я создаю игру, в которой игрок находится в центре поверхности. Эта поверхность движется вместо этого игрока. Я хочу иметь возможность добавлять такие объекты, как мечи. У меня проблема: я могу навести курсор мыши на объект при первом запуске игры, но когда я перемещаюсь, наведение курсора мыши на объект ничего не делает, а в другой области он делает то, что должен делать. Я думаю, что когда карта движется, она исчезает с экрана, меняя положение мыши, падающей на объект. Я создал этот образец, чтобы показать, что я имею в виду

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 ]

1 голос
/ 16 апреля 2019

Вы должны понимать, что когда вы создаете игру с прокруткой / камерой / движущейся картой, вы имеете дело с двумя различными типами координат:

  • мировые координаты ( логические координаты, например, (0, 0) всегда (0, 0), независимо от того, движется ли прокрутка / камера или карта

  • координаты экрана (которые вы используете для определения фактического положения чего-либо на текущем экране, например, itemPos = (4,8) в мировых координатах, и get переводится в координаты экрана путем умножения на 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)
0 голосов
/ 16 апреля 2019

Я попробовал ваш код и получаю ту же ошибку.Я обхожу это путем определения другого списка с именем 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...