This is a simple custom font rendering class I wrote. The idea was to code something that could be passed a lengthy string and render that properly in any game that uses pygame.
On top of this, the class can draw each character one at time for a kind of typewriter effect.
Anyway, I'm just looking for feedback or any tip on improving the code. Anything you might notice really.
Thanks for your time.
Here is the custom renderer class:
import pygame
import time
class customRenderer():
def __init__(self,p_screen,p_screenX, p_screenY, p_font,p_fontSize, p_fontColor, p_text, p_startPosX, p_startPosY, p_waitTime):
self.initialStartX = p_startPosX
self.initialStartY = p_startPosY
self.currentScreen = p_screen
self.maxWidth = p_screenX
self.maxHeight = p_screenY
self.font = p_font
self.fontSize = p_fontSize
self.fontColor = p_fontColor
self.text = p_text
self.startPosX = p_startPosX
self.startPosY = p_startPosY
self.waitTime = p_waitTime
#innate properties
self.splitTxt = None
self.done = False
''' splits the string to be used for the render '''
def setSplitText(self):
self.splitTxt = self.text.split(" ")
''' Fully render and blit the string '''
def renderTxt(self):
''' set starting position coords for render blits '''
self.startPosX = self.initialStartX
self.startPosY = self.initialStartY
for word in self.splitTxt:
''' if current word not fully blitted '''
if not self.done:
'''create render and set offsets for x and y pos'''
ren = self.font.render(word, 1, self.fontColor)
offsetX = (ren.get_width() + 8)
offsetY = (ren.get_height() + self.fontSize/2)
''' If wordpos x is greater than render surface width
offset y position, reset x position for word '''
if (self.startPosX + ren.get_width()) >= self.maxWidth - self.initialStartX:
self.startPosY += offsetY
self.startPosX = self.initialStartX
''' blit string render and increment x offset position '''
self.currentScreen.blit(ren,(self.startPosX,self.startPosY))
self.startPosX += offsetX
''' if last word of string is blitted, render blit is done '''
if self.splitTxt.index(word) == len(self.splitTxt) -1:
self.done = True
def typewritter(self):
'''vars'''
interrupted = False
idx = 0
spacer = 0
for word in self.splitTxt:
idx = 0
wordRen = self.font.render(word, 1, self.fontColor)
wordStartX = self.startPosX
for letter in word:
''' if current word not fully blitted '''
if not self.done:
''' if user hasn't pressed start, continue blitting letters '''
if not interrupted:
'''create render'''
ren = self.font.render(letter, 1, self.fontColor)
'''set spacer'''
# if letter is the same as the,
# last letter of a word
if letter == word[len(word)-1]:
#if truly last letter
if idx == len(word)-1:
spacer = 8
else:
spacer = 0
else:
spacer = 0
''' If letter pos x is greater than render surface width
offset y position, reset x positions for word and letter'''
if (wordStartX + wordRen.get_width()) >= self.maxWidth - self.initialStartX:
self.startPosY += offsetY
self.startPosX = self.initialStartX
wordStartX = self.startPosX
''' set blit offsets for x and y positions'''
offsetX = (ren.get_width() + spacer)
offsetY = (ren.get_height() + (self.fontSize/2))
''' blit string render and increment x offset position '''
self.currentScreen.blit(ren,(self.startPosX,self.startPosY))
self.startPosX += offsetX
''' if last char of string is blitted, word is done '''
if self.splitTxt.index(word) == len(self.splitTxt) -1:
if word.index(letter) == len(word) -1:
self.done = True
''' increment, wait and update '''
idx +=1
pygame.time.wait(self.waitTime)
pygame.display.update()
''' class event loop '''
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
interrupted = True
screen.fill((0,0,0))
''' if user pressed start, blit entire string with renderTxt()'''
else:
self.renderTxt()
And here's the client:
#================================= Setup =======================================
#imports
import pygame
import time
from renderWithLineBreak import customRenderer
# Init
pygame.init()
# Game Window size
screen_size = [1600, 900]
screen = pygame.display.set_mode(screen_size)
#conversation array
convoOne = []
# Game Captions
pygame.display.set_caption('My caption here')
#Font
popUpFonts = pygame.font.Font("fonts/Tahoma.ttf", 32)
#test string
string = "When Mr. Bilbo Baggins of Bag End announced that he would shortly be celebrating his eleventy-first birthday with a party of special magnificence, there was much talk and excitement in Hobbiton"
stringTwo = "Bilbo was very rich and very peculiar, and had been the wonder of the Shire for sixty years, ever since his remarkable disappearance and unexpected return. The riches he had brought back from his travels had now become a local legend, and it was popularly believed, whatever the old folk might say, that the Hill at Bag End was full of tunnels stuffed with treasure. "
convoOne.append(string)
convoOne.append(stringTwo)
#Ints
convoIdx = 0
clock = pygame.time.Clock()
#=========================== Program Loop ======================================
done = False
typingDone = False
while done == False:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
done = True
if event.key == pygame.K_RETURN:
if not typingDone:
screen.fill((0,0,0))
testWord = customRenderer(screen,screen_size[0],screen_size[1],popUpFonts,32,(255,255,255),convoOne[convoIdx],100,100,75)
testWord.setSplitText()
testWord.typewritter()
if convoIdx < len(convoOne)-1:
convoIdx+=1
else:
typingDone = True
else:
done = True
pygame.display.update()
clock.tick(60)
#========================== End Loop =============================================
pygame.quit()