如何在pygame中创建交互式对象?

时间:2017-04-03 08:16:14

标签: python pygame

在我正在创建的pygame程序中,我需要屏幕上的一个交互式对象,当玩家角色移动到该按钮并按下回车键时将调用该功能。这是我到目前为止的代码:

import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))
done = False
x = 30
y = 30

clock = pygame.time.Clock()

while not done:
        for event in pygame.event.get():
                if event.type == pygame.QUIT:
                        done = True

    pressed = pygame.key.get_pressed()
    if pressed[pygame.K_UP] and y > 0: y -= 5
    if pressed[pygame.K_DOWN] and y < 600 - 60: y += 5
    if pressed[pygame.K_LEFT] and x > 0: x -= 5
    if pressed[pygame.K_RIGHT] and x < 800 - 60: x += 5

    screen.fill((0, 0, 0))
    color = (0, 128, 255)
    pygame.draw.rect(screen, color, pygame.Rect(x, y, 60, 60))

    myfont = pygame.font.SysFont("monospace", 15)

    label = myfont.render("Start the experiment simulator", 1, (255,255,255))
    screen.blit(label, (100, 100))

    label2 = myfont.render("Start the quiz", 1, (255,255,255))
    screen.blit(label2, (550, 100))

    label3 = myfont.render("Quit game", 1, (255,255,255))
    screen.blit(label3, (350, 400))

    pygame.draw.rect(screen, red, pygame.Rect(600, 125, 30, 30))
    pygame.draw.rect(screen, red, pygame.Rect(225, 125, 30, 30))
    pygame.draw.rect(screen, red, pygame.Rect(375, 425, 30, 30))

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

目前,对象只是一个测试,所以最好是一个小红色矩形,大约是玩家大小的一半,以后可以用图标替换。这个矩形应该放在“退出游戏”下方。在pygame窗口上标记并在与之交互时退出游戏。这是我到目前为止尝试过的一种方法:

if pressed[pygame.K_RETURN] and x >= 375 or x <= 405 and y >=425 or y <= 455:
            pygame.display.quit()
            pygame.quit()
            sys.exit()

理论上,系统检查用户是否在特定区域并在执行命令之前按下了回车键。

3 个答案:

答案 0 :(得分:1)

回答我自己的问题,我设法通过在本节的x和y检查周围添加括号来进行我的第一次尝试:

and x >= 375 or x <= 405 and y >=425 or y <= 455:

现在它写着:

and (x >= 375 and x <= 405) and (y >= 425 and y <= 455):

答案 1 :(得分:1)

您可以使用pygame的NaN

检查碰撞

首先,创建三个代表你的三个选项的rects:

colliderect

接下来,我们将创建一个代表蓝色选择器rect的矩形:

simulator_rect = pygame.Rect(600, 125, 30, 30)
quiz_rect = pygame.Rect(225, 125, 30, 30)
quit_rect = pygame.Rect(375, 425, 30, 30)

所以现在你有了只创建一次的rects,而不是每次都创建的未命名的rects

现在,对于实际的碰撞检测:

selector_rect = pygame.Rect(50, 50, 60, 60)

最终代码:

# Check to see if the user presses the enter key
    if pressed[pygame.K_RETURN]:
        # Check to see if the selection rect 
        # collides with any other rect
        for rect in option_rects:
            if selector_rect.colliderect(rect):
                if rect == simulator_rect:
                    # Do simulations stuff!
                    print('Simulating!')
                elif rect == quiz_rect:
                    # Do quizzing stuff!
                    print('Quizzing!')
                elif rect == quit_rect:
                    # Quit!
                    done = True

这确实会给你的程序带来一些复杂性,但至少它是一个坚如磐石的方法,你也可以添加功能,并且它将保持稳健。

答案 2 :(得分:0)

我只是为可交互对象创建一个系统,它很容易扩展。

listBox = [] # this list used to store all object inside

listBox.append(("text", pos, size, bgColor, textColor, InteractAction)) 
# add dumy object to the list, "text" can be empty if you dont want.

def InteractAction(mousePos):  # sample action used to tie to object
    print("do somehthing")    

def newDrawBox(IableO):
      pygame.draw.rect(gameDisplay, IableO[3],(IableO[1][0], IableO[1][1], IableO[2][0], IableO[2][1]))
      text = basicfont.render(str(IableO[0]), True,IableO[4], None)
      textrect = text.get_rect()
      textrect.centerx = IableO[1][0] + IableO[2][0] / 2
      textrect.centery = IableO[1][1] + IableO[2][1] / 2
      gameDisplay.blit(text, textrect)

while not gameExit:
  for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameExit = True
        elif event.type == pygame.MOUSEBUTTONDOWN:
            Mouse[event.button] = 1
            Mouse[0] = (event.pos[0], event.pos[1])
        elif event.type == pygame.MOUSEBUTTONUP:
            Mouse[event.button] = 0
            Mouse[0] = (event.pos[0], event.pos[1])
#-------- check if mouse is click on any object in the list of Interatable object
  if Mouse[1] == 1:
        for x in listBox:
            if x[1][0] < Mouse[0][0] < x[1][0] + x[2][0] and x[1][1] < Mouse[0][1] < x[1][1] + x[2][1]:
                x[5](Mouse[0])
#---- draw all object -----
  for x in listBox:
        newDrawBox(x)