2015-07-09 3 views
2

Код, указанный ниже, должен создать зеленую кнопку, которая отображает текст оценки. К сожалению, кнопка ничего не делает, и единственный способ, которым мне удалось заставить ее работать, - это вызвать вызов функции makeText в цикле while, а не в функции clickButton, но если я это сделаю, это не будет более динамичным. Может кто-нибудь объяснить, почему текст не появляется, когда я нажимаю кнопку и исправляю свой код, чтобы он отображался?текст не отображается динамически, pygame

import pygame 
import sys 
#game stuff 
pygame.init() 
screen = pygame.display.set_mode((640, 480),0,32) 
clock = pygame.time.Clock() 

#functions 
def makeText(title,text,posx,posy): 
    font=pygame.font.Font(None,30) 
    scoretext=font.render(str(title)+ ": " +str(text), 1,(0,0,0)) 
    screen.blit(scoretext, (posx, posy)) 
def clickButton(name,x,y,width,height): 
    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) 
#update display 
    pygame.display.update() 
    clock.tick(60) 
#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) 

ответ

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.


Таким образом, решение, чтобы следить за тем, что кнопка была нажата, А.К.А. слежение за в состоянии.

Вот пример другого подхода, используя классы для кнопок и 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) 

enter image description here

+0

это отлично работает для меня, но теперь я пытаюсь добавить третью кнопку, которая меняет оценку от целого до строки, и я не могу заставить ее работать без двух текстов, написанных друг над другом и становящихся беспорядочный беспорядок. Если у вас есть предложения, я бы хотел их услышать, и спасибо за вашу помощь! – user3150635

1

Вы проверяете значение «нажмите» в функции ClickButton, но я не вижу, щелкните в любом месте определить, что ClickButton будет иметь к нему доступ. Возможно, вам нужно передать клик в качестве аргумента в функцию clickButton, которая затем может сделать условие if истинным?

+0

Я не уверен, почему теперь, когда вы упоминаете, но если условие выполняется. набрав «print click» после условия if, печатает кортеж при каждом нажатии кнопки, поэтому функция получает клик как переменную. – user3150635

+1

'click' определяется во второй последней строке. Это глобальная переменная. – sloth

Смежные вопросы