编辑:添加了更长的示例代码。
我在pygame中编码按钮时遇到了麻烦。我是pygame模块的新手,所以要温柔。
基本上,我们的目标是制作一种点击式指示游戏。每个游戏循环向玩家呈现两个选择,即“向左”或“向右”。因此,每个游戏循环中有两个按钮,它们都位于相同的坐标处。
这是功能:
import pygame
import os
import time
pygame.init()
display_width= 1280
display_height = 720
gameDisplay = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()
def button(msg,x, y, w, h, ic, ac, action=None): #message, x y location, width, height, inactive and active colour
if action ==None:
pygame.display.update()
clock.tick(15)
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x+w > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac,(x,y,w,h))
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
pygame.display.update()
clock.tick(15)
if action == "left1":
game_loop("loop1-1.png",0,0,"left2","left2","","")
else:
pygame.draw.rect(gameDisplay, ic,(x,y,w,h))
smallText = pygame.font.SysFont('timesnewroman',20)
textSurf, textRect = text_objects(msg, smallText, silver)
textRect.center = ( (x+(w/2)), (y+(h/2)) )
gameDisplay.blit(textSurf, textRect)
def game_loop(pic,width,heigth,act1,act2,left,right):
intro = True
while intro:
for event in pygame.event.get():
print(event)
if event.type == pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white)
gameDisplay.blit(get_image(pic), (0, 0)) #MAIN MENU PIC
button(left,440,450,width,heigth, dark_gray, gray, action=act1)#start nupp
button(right,740,450,width,heigth, dark_gray, gray, action=act2)#exit nupp
pygame.display.update()
clock.tick(15)
当我不小心点击按钮时会出现问题,这意味着如果我没有尽可能快地单击鼠标左键。一旦调用game_loop1并且如果我再点击一下,程序将在此game_loop1中再次读取第一次点击并运行下一个game_loop然后再运行下一个等等。这意味着玩家可能会意外跳过游戏循环。
有没有办法在第一次点击后延迟程序(无论多长时间)?或者也许是一种在函数中包含keyup的方法,所以它不计算下一个游戏循环中的点击次数?
谢谢!
我认为你的原始代码有点太复杂,无法解决它,我宁愿告诉你一些更好的方法来做你想要的。你需要一个finite-state machine来在不同的状态/场景之间转换。你可以用functions as scenes here找到一个简单的例子。
如果场景中的逻辑大致相同,您也可以尝试换出场景的数据,例如背景图像。每个州/场景都需要知道它可以切换到哪些新状态,因此我将数据放入字典词典中。嵌套的dicts包含场景的背景图像和连接的左右场景。当用户按下按钮/矩形时,我检查它是左按钮还是右按钮,然后切换到states
字典中的相应场景(子画面)。
import pygame
pygame.init()
display_width= 1280
display_height = 720
gameDisplay = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()
# Use uppercase names for constants that should never be changed.
DARK_GRAY = pygame.Color('gray13')
BACKGROUND1 = pygame.Surface((display_width, display_height))
BACKGROUND1.fill((30, 150, 90))
BACKGROUND2 = pygame.Surface((display_width, display_height))
BACKGROUND2.fill((140, 50, 0))
BACKGROUND3 = pygame.Surface((display_width, display_height))
BACKGROUND3.fill((0, 80, 170))
states = {
'scene1': {'background': BACKGROUND1, 'left_scene': 'scene2', 'right_scene': 'scene3'},
'scene2': {'background': BACKGROUND2, 'left_scene': 'scene1', 'right_scene': 'scene3'},
'scene3': {'background': BACKGROUND3, 'left_scene': 'scene1', 'right_scene': 'scene2'},
}
def game_loop():
# The buttons are just pygame.Rects.
left_button = pygame.Rect(440, 450, 60, 40)
right_button = pygame.Rect(740, 450, 60, 40)
# The current_scene is a dictionary with the relevant data.
current_scene = states['scene1']
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.MOUSEBUTTONDOWN:
# If the left button is clicked we switch to the 'left_scene'
# in the `current_scene` dictionary.
if left_button.collidepoint(event.pos):
current_scene = states[current_scene['left_scene']]
print(current_scene)
# If the right button is clicked we switch to the 'right_scene'.
elif right_button.collidepoint(event.pos):
current_scene = states[current_scene['right_scene']]
print(current_scene)
# Blit the current background.
gameDisplay.blit(current_scene['background'], (0, 0))
# Always draw the button rects.
pygame.draw.rect(gameDisplay, DARK_GRAY, left_button)
pygame.draw.rect(gameDisplay, DARK_GRAY, right_button)
pygame.display.update()
clock.tick(30) # 30 FPS feels more responsive.
game_loop()
pygame.quit()