Python Forum
Thread Rating:
  • 1 Vote(s) - 1 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Basic Text Class
#1
Hi there, I am working on creating a simple text class where you could create a text object, define the text, text size, location, colour (and eventually duration on scree).

I'm obviously having a brain fart here. My message isn't rendering. I've no errors. But the message doesn't display. Can anyone see what obviously silly mistake I've made? This is driving me bonkers!!

#GrumpyOgre
#Text Class

import pygame, sys
from pygame.locals import *

# set up the window and environment
pygame.init()
iFPS = 160 # frames per second setting
fpsClock = pygame.time.Clock()
frmWindow = pygame.display.set_mode((600, 600), 0, 32)
pygame.display.set_caption('Text Demo')

# pen inks
clrBlack = (0, 0, 0)
clrRed = (255, 0, 0)
clrGreen = (0, 255, 0)
clrBlue = (0, 0, 255)
clrWhite = (255, 255, 255)

class text:
	def __init__(self):
		self.x = 0
		self.y = 0
		self.colour = clrBlack
		self.size = 12
		self.duration = 10
		self.text = ""
		self.font = pygame.font.Font('comic.ttf', self.size)
		self.surface = self.font.render(self.text , 1, self.colour)
	
	def define(self, x, y, colour, size, duration, message):
		self.x = x
		self.y = y
		self.colour = colour
		self.size = size
		self.duration = duration
		self.text = message
	
	def display(self):
		frmWindow.blit( self.surface, (self.x,self.y))

message = text()
message.define(200, 200, clrBlack, 12, 20, 'boom')
frmWindow.fill(clrWhite)		 
while True: # the main game loop
	for event in pygame.event.get():
		if event.type == QUIT:
			pygame.quit()
			sys.exit()
	
	message.display()
	pygame.display.update()
	fpsClock.tick(iFPS)
Thx for any tips in advance.
Reply
#2
The main problem is self.font and self.surface need to be updated after the values change anytime. You did not, and hence self.text was empty from the constructor. You should also pass your window to display. You should also be using pygame Rects instead of inserting x and y positions yourself. This will help later when you want to position the text based on its different sizes of text. Also you should always cap your classname. Here is your full code changed to what i mean to at least get it working.

#GrumpyOgre
#Text Class
 
import pygame, sys
from pygame.locals import *
 
# set up the window and environment
pygame.init()
iFPS = 160 # frames per second setting
fpsClock = pygame.time.Clock()
frmWindow = pygame.display.set_mode((600, 600), 0, 32)
pygame.display.set_caption('Text Demo')
 
# pen inks
clrBlack = (0, 0, 0)
clrRed = (255, 0, 0)
clrGreen = (0, 255, 0)
clrBlue = (0, 0, 255)
clrWhite = (255, 255, 255)
 
class Text:
    def __init__(self):
        self.x = 0
        self.y = 0
        self.colour = clrBlack
        self.size = 12
        self.duration = 10
        self.text = ""
        self.update()
        
    def update(self):
        self.font = pygame.font.SysFont('Arial', self.size)
        self.surface = self.font.render(self.text , 1, self.colour)
     
    def define(self, x, y, colour, size, duration, message):
        self.x = x
        self.y = y
        self.colour = colour
        self.size = size
        self.duration = duration
        self.text = message
        self.update()
     
    def display(self,root):
        root.blit( self.surface, (self.x,self.y))
 
message = Text()
message.define(200, 200, clrBlack, 12, 20, 'boom')
frmWindow.fill(clrWhite)         
while True: # the main game loop
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
     
    message.display(frmWindow)
    pygame.display.update()
    fpsClock.tick(iFPS)
Here is a class that outputs a random number to the screen every 3 seconds. Hence it is very important to update the text objects. Although the size and other stats doesnt change it could very easily be adapted to do that.
import pygame as pg
import random

pg.init()

screen = pg.display.set_mode((800,600))
screen_rect = screen.get_rect()
clock = pg.time.Clock()
done = False

class Number:
    def __init__(self):
        self.timer = 0.0
        self.delay = 3000
        self.new_num()

    def new_num(self):
        num = random.randint(1,100)
        self.image, self.rect = self.make_text(str(num), (255,0,0), screen_rect.center, 75, 'Ariel')

    def make_text(self,message,color,center,size, fonttype):
        font = pg.font.SysFont(fonttype, size)
        text = font.render(message,True,color)
        rect = text.get_rect(center=center)
        return text,rect

    def update(self):
        if pg.time.get_ticks()-self.timer > self.delay:
            self.timer = pg.time.get_ticks()
            self.new_num()

    def draw(self, surf):
        surf.blit(self.image, self.rect)

num = Number()

while not done:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            done = True
    screen.fill((0,0,0))
    num.update()
    num.draw(screen)
    pg.display.update()
clock.tick(60)
Recommended Tutorials:
Reply
#3
Wow! That totally flew under the radar. Thanks. Fresh eyes sometimes are a blessing. So I created a blank surface upon initialization and that was what was getting drawn. Ugh.

Thanks again. Adding rect and a timer member function now.

Cheers,

GrumpyOgre
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020