0

I am trying to make a hangman game in pygame, but I cannot get buttons to work after they have been created from an event (in my case after pressing enter), they appear on screen but do not work ( rollover or activate events), please help!

from pygame.locals import *
import pygame, sys, eztext
import time

pygame.init()

Black      = (  0,   0,   0)
Grey       = (100, 100, 100)
DarkGrey   = (70,   70,  70)
White      = (255, 255, 255)
Blue       = (  0,   0, 255)
NavyBlue   = ( 60,  60, 100)
Cyan       = (  0, 255, 255)
Purple     = (255,   0, 255)
Red        = (255,   0,   0)
DarkRed    = (180,   0,   0)
Orange     = (255, 128,   0)
Yellow     = (255, 255,   0)
Green      = (  0, 255,   0)
DarkGreen  = (  0, 180,   0)
LightBlue  = ( 90, 164, 213)
Magenta    = (153,   0,  76)

screen = pygame.display.set_mode((1000,600),0,32)
screen.fill(Orange)
txtbx = eztext.Input(maxlength=45, color=(0,0,0), prompt='Enter username: ')

def text_objects(text, font):
    textSurface = font.render(text, True, Black)
    return textSurface, textSurface.get_rect()
smallText = pygame.font.Font("freesansbold.ttf",20)

def button(msg,x,y,w,h,ic,ac,action=None):
    if x+w > mouse[0] > x and y+h > mouse[1] > y:  
        pygame.draw.rect(screen, ac,(x, y, w, h))     
        if click [0] == 1 and action!= None:          
            if action == "Quit":
                pygame.quit() 
            if action == "Single player":
                pygame.draw.rect(screen, Green,(10, 10, 500, 500))

    else:
        pygame.draw.rect(screen, ic,(x, y, w, h))

    smallText = pygame.font.Font("freesansbold.ttf",20) 
    textSurf, textRect = text_objects(msg, smallText) 
    textRect.center = ((x+(w/2)), (y + (h/2))) 
    screen.blit(textSurf, textRect)
    
while True:
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    
    string1 = txtbx.value
    pygame.display.update()
    time.sleep(0.02)
        
    pygame.draw.rect(screen, Green,(10, 100, 500, 50))
    
    clock = pygame.time.Clock()   
    clock.tick(30)
    
    events = pygame.event.get()
    
    txtbx.set_pos(10,110)

    label = smallText.render("Enter you user name and then press enter!", 1, (0,0,0)) 
    screen.blit(label, (10, 10))                                 

    for event in events:
   
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_KP_ENTER or event.key == pygame.K_RETURN:
                button("Single player",10, 400, 150, 50, Green, DarkGreen,"Single player")
                if string1 in open('Users.txt').read():
                    username = string1
                    Welcomeold1 = smallText.render('Welcome back', 1, (0,0,0))
                    screen.blit(Welcomeold1, (10, 200))
                    Welcomeold2 = smallText.render(username, 1, (0,0,0))
                    screen.blit(Welcomeold2, (160, 200))

                else:
                    username = string1
                    f = open('Users.txt','a')
                    string1 = txtbx.value
                    f.write(string1)
                    f.write('\n')                                           
                    f.close()
                    Welcomenew1 = smallText.render('Welcome to my game', 1, (0,0,0))
                    screen.blit(Welcomenew1, (10, 200))
                    Welcomenew2 = smallText.render(username, 1, (0,0,0))
                    screen.blit(Welcomenew2, (230, 200))
            if event.key == pygame.K_BACKSPACE:
                screen.fill(Orange)
                                                   
    txtbx.update(events)
    txtbx.draw(screen)
    pygame.display.flip()

if __name__ == '__main__': main()

1
  • button function can only draw button - nothing more. you need other functions to do expected things. Create Button class with methods draw, handle_event Commented Jan 21, 2016 at 12:30

1 Answer 1

1

button function is inside event.key so it will work only when RETURN is pressed, released, and pressed again, and released again, etc.

You should create class with method draw and handle_event to use this method in mainloop in different places. You can create button in event.key but you have to check button pressed in different place.

-

Simple button. Full working example.

When you press button function do_it is called and background changed color.

#
# pygame (simple) template - by furas
#

# ---------------------------------------------------------------------

import pygame
import pygame.gfxdraw
import random

# === CONSTANS === (UPPER_CASE names)

BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)

RED   = (255,   0,   0)
GREEN = (  0, 255,   0)
BLUE  = (  0,   0, 255)

CYAN    = (  0, 255, 255)
MAGENTA = (255,   0, 255)
YELLOW  = (255, 255,   0)

SCREEN_WIDTH  = 800
SCREEN_HEIGHT = 600

# === CLASSES === (CamelCase names)

class Button():

    def __init__(self, text, x, y, width, height, on_click=None, fg_color=RED, bg_color=WHITE, font_size=35):
        self.text = text

        font = pygame.font.SysFont(None, font_size)

        # rectangle - without position, to put text in correct place
        self.rect = pygame.Rect(0, 0, width, height)

        # normal button - fill background
        self.normal_image = pygame.surface.Surface( self.rect.size )
        self.normal_image.fill(bg_color)

        # normal button - add text
        text_image = font.render(text, True, fg_color)
        text_rect = text_image.get_rect(center=self.rect.center)
        self.normal_image.blit(text_image, text_rect)

        # hover button - fill background
        self.hover_image = pygame.surface.Surface( self.rect.size )
        self.hover_image.fill(fg_color)

        # hover button - add text
        text_image = font.render(text, True, bg_color)
        text_rect = text_image.get_rect(center=self.rect.center)
        self.hover_image.blit(text_image, text_rect)

        # set position 
        self.rect.x = x
        self.rect.y = y

        # other 
        self.on_click = on_click
        self.hover = False

    def draw(self, surface):
        # draw normal or hover image
        if self.hover:
            surface.blit(self.hover_image, self.rect)
        else:
            surface.blit(self.normal_image, self.rect)

    def event_handler(self, event):
        # is mouse over button ?
        if event.type == pygame.MOUSEMOTION:
            self.hover = self.rect.collidepoint(event.pos)

        # is mouse clicked ? run function.
        if event.type == pygame.MOUSEBUTTONDOWN:
            if self.hover and self.on_click:
                self.on_click()

# === FUNCTIONS === (lower_case names)

def do_it():
    global background_color

    if background_color == BLACK:
        background_color = RED
    elif background_color == RED:
        background_color = GREEN
    else:
        background_color = BLACK

    print("Button pressed")


# === MAIN ===

# --- init ---

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
screen_rect = screen.get_rect()

# --- objects ---

# create button
button = Button('CHANGE COLOR', 0, 0, 300, 50, on_click=do_it)

# add function later
#button_quit.on_click = do_it

# center button
button.rect.center = screen_rect.center

# default bacground color - changed in do_it()
background_color = BLACK

# --- mainloop ---

clock = pygame.time.Clock()
is_running = True

while is_running:

    # --- events ---

    for event in pygame.event.get():

        # --- global events ---

        if event.type == pygame.QUIT:
            is_running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                is_running = False

        # --- objects events ---

        button.event_handler(event)

    # --- updates ---

        # empty

    # --- draws ---

    # clear buffer
    screen.fill(background_color)

    # draw all objects - widgets (buttons, labels)

    button.draw(screen)

    clock.tick(25)

    # send buffer to video card 
    pygame.display.update()

# --- the end ---

pygame.quit()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.