0

So I'm making an rpg project in Pygame and I need a button class that has text. This is my Code so far. I tried to use some code examples online and on this site but I couldn't make them work in the way I wanted. ;-;

What I want is a button that can drawn to my GameWindow that includes text. I'll figure out the event handling later on.

It would be greatly appreciated if someone could give me an explanation of how a button class that utilises text would work in pygame and explain it in a way I could implement in my Button Class. Previously I have tried simply placing text in the centre of the screen by dividing the width and height by two and placing coloured rects adjacent to the text to try and label the rects so I could use them as buttons. However I realised this wasn't a practical solution, as I would be needing many buttons throughout my game and this method took up large portions of my screen. I do not understand how to blit a message onto a rect using a class. The Button class below is where I attempted to place text onto top of a rect but I found this very hard. Ideally my goal here is to be able to call an instance of my button class which I can use as a button.

BTW asking here was a last resort. I spent almost three hours trying to figure this out and its bad for me to stare at a screen for that long.

import pygame, random, sys, math, time
from pygame.locals import *

pygame.init()

FPS = 30
fpsClock = pygame.time.Clock()

GameWindow = pygame.display.set_mode((650,520))

#Variables
Blue = (0,0,255)
Green = (0,255,0)
Red = (255,0,0)
White = (255,255,255)
Black = (0,0,0)

def Button():
    def__init__(self, surface, x, y, width, height, colour, message, action=None)
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.font = pygame.font.Font(None, 20)
    self.message = message
    
                
background_image = pygame.image.load('map.JPG')
title_image = pygame.image.load('title.PNG')

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        GameWindow.blit(background_image, [0,0])
        GameWindow.blit(title_image, [100,0])
        pygame.display.flip()
        fpsClock.tick(FPS)
  • 1
    Please tell us exactly what you would like. Telling us to " help me finish my Button class" is not helpful. Also, please tell us about your attempts and what went wrong, or what you are confused about. Thank you. – Ethanol Mar 28 '18 at 21:56
  • Good point haha. Is my question better now? :) – SourCream Sunbites Mar 28 '18 at 22:51
  • Take a look at the [examples here](https://stackoverflow.com/a/47664205/6220679), especially the second, object-oriented example. Or you could use one of the GUI librarires like [SGC](http://www.pygame.org/project-SGC-2089-4505.html). – skrx Mar 29 '18 at 02:18

2 Answers2

0

Here is a button class:

class Button(object):
    global screen_width,screen_height,screen
    def __init__(self,x,y,width,height,text_color,background_color,text):
        self.rect=pygame.Rect(x,y,width,height)
        self.x=x
        self.y=y
        self.width=width
        self.height=height
        self.text=text
        self.text_color=text_color
        self.background_color=background_color
        self.angle=0

    def check(self):
        return self.rect.collidepoint(pygame.mouse.get_pos())

    def draw(self):
        pygame.draw.rect(screen, self.background_color,(self.rect),0)
        drawTextcenter(self.text,font,screen,self.x+self.width/2,self.y+self.height/2,self.text_color)  
        pygame.draw.rect(screen,self.text_color,self.rect,3)

Use the check function to see if your button is clicked on, and the draw function to draw your button.

Implemented into your main loop:

button=Button(x,y,width,height,text_color,background_color,text)
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type==pygame.MOUSEBUTTONDOWN:
            if button.check()==True:       
                #do what you want to do when button is pressed  
    GameWindow.blit(background_image, [0,0])
    GameWindow.blit(title_image, [100,0])
    pygame.display.flip()
    fpsClock.tick(FPS)

I also recommend using these functions to draw text:

def drawTextcenter(text,font,screen,x,y,color):
    textobj=font.render(text,True,color)
    textrect=textobj.get_rect(center=(x,y))
    screen.blit(textobj,textrect)

def drawText(text, font, surface, x, y,color):
    textobj=font.render(text, 1, color)
    textrect=textobj.get_rect()
    textrect.topleft=(x, y)
    surface.blit(textobj, textrect)
gnawydna
  • 385
  • 1
  • 5
  • 22
0

While you're question is still a bit confusing, I can tell you how you blit your text near or in your button. So what you just do is just place the location of the text near the button, basing the texts x and y variables on the buttons x and y variable.

Copied from your code:

def Button():
    def__init__(self, surface, x, y, width, height, colour, message, action=None)
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.font = pygame.font.Font(None, 20)
    self.message = message           
    self.font = pygame.font.SysFont('Comic Sans MS', 30) #Example Font

    def draw_button(self):
         pygame.draw.rect(GameWindow, Red, (self.x, self.y, self.width, self.height))
         self.text = myfont.render(message, False, (0, 0, 0))
         GameWindow.blit(self.text, (self.x + self.width/2, self.y + self.height/2)) #Displays text at coordinates at middle of the button.

This draws the button (it still doesn't do anything), but also displays the text in the button. HOWEVER, since the text is displayed at the top-left corner of the surface it is on, it will not be exactly in the middle, and will look odd. You can modify the exact location if you want. I hope this answers your question.

Ethanol
  • 370
  • 6
  • 18