下面的代码应该创建一个绿色按钮,使得分数文本出现。不幸的是,按钮什么都不做,我设法让它工作的唯一方法是将makeText的函数调用放在while循环而不是clickButton函数中,但是如果我这样做的话,那就是不再动态。有人可以解释为什么当我按下按钮并修复我的代码以便它显示时文本没有显示出来吗?
{{1}}
答案 0 :(得分:1)
您正在检查clickButton函数中“click”的值,但我没有看到clickButton可以访问它的任何地方的click。 也许你应该在clickButton函数中传递click作为参数,这可能会使if条件为真?
答案 1 :(得分:1)
问题是,一旦你创建了文本,主循环就会继续并调用screen.fill
,甚至在调用pygame.display.update()
之前就会覆盖文本。
您可以将其更改为:
...
def clickButton(name,x,y,width,height):
print x + width > cur[0] > x and y + height > cur[1] > y
if x + width > cur[0] > x and y + height > cur[1] > y:
if click == (1,0,0):
makeText("score",300,100,10)
#objects
button1 = pygame.Rect((0,0), (32,32))
while True:
screen.fill((255,255,255))
screen.fill((55,155,0), button1)
#event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
elif event.type == pygame.MOUSEBUTTONDOWN:
cur = event.pos
click = pygame.mouse.get_pressed()
clickButton("button1",button1.left,button1.top,button1.width,button1.height)
...
因此在使用背景颜色填充屏幕之后和调用pygame.display.update()
之前创建文本,但这不能解决在while
循环的下一次迭代中再次填充屏幕的问题
因此,解决方案是跟踪按下按钮的事实,a.k.a。跟踪状态。
这是一个不同方法的示例,使用按钮类和全局状态dict
(因此您不需要全局变量,这应该避免大部分时间,因为如果你的游戏开始变得越来越复杂,它会变得非常混乱。)
点击第一个按钮显示或隐藏分数,然后单击第二个按钮更改背景颜色并获得100分。
看看创建新按钮有多容易;它只是添加一个简单的功能。
import pygame
import sys
import random
pygame.init()
screen = pygame.display.set_mode((640, 480),0,32)
clock = pygame.time.Clock()
# create font only once
font = pygame.font.Font(None,30)
# it's always a good idea to cache all text surfaces, since calling 'Font.render' is
# an expensive function. You'll start to notice once your game becomes more complex
# and uses more text. Also, use python naming conventions
text_cache = {}
def make_text(title, text):
key = "{title}: {text}".format(title=title, text=text)
if not key in text_cache:
text = font.render(key, 1,(0,0,0))
text_cache[key] = text
return text
else:
return text_cache[key]
# we use the 'Sprite' class because that makes drawing easy
class Button(pygame.sprite.Sprite):
def __init__(self, rect, color, on_click):
pygame.sprite.Sprite.__init__(self)
self.rect = rect
self.image = pygame.Surface((rect.w, rect.h))
self.image.fill(color)
self.on_click = on_click
# this happens when the first button is pressed
def toggle_score_handler(state):
state['show_score'] = not state['show_score']
# this happens when the second button is pressed
def toggle_backcolor_handler(state):
state['backcolor'] = random.choice(pygame.color.THECOLORS.values())
state['score'] += 100
# here we create the buttons and keep them in a 'Group'
buttons = pygame.sprite.Group(Button(pygame.Rect(30, 30, 32, 32), (55, 155 ,0), toggle_score_handler),
Button(pygame.Rect(250, 250, 32, 32), (155, 0, 55), toggle_backcolor_handler))
# here's our game state. In a real
# game you probably have a custom class
state = {'show_score': False,
'score': 0,
'backcolor': pygame.color.Color('White')}
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
# you can check for the first mouse button with 'event.button == 1'
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
# to check if the mouse is inside the button, you
# can simple use the 'Rect.collidepoint' function
for button in (b for b in buttons if b.rect.collidepoint(event.pos)):
button.on_click(state)
screen.fill(state['backcolor'])
# draw all buttons by simple calling 'Group.draw'
buttons.draw(screen)
if state['show_score']:
screen.blit(make_text("score", state['score']), (100, 30))
pygame.display.update()
clock.tick(60)