I have this problem with using pygame with this certain effect I'm using to have scrolling text. When I tried calling a function I defined, the function is being ignored until it's the very last time that function is called. This results in an output of 1 message being typed and not all of them. How could i fix this. The code:
import pygame
import os
import time
#Sets the width and height of the screen
WIDTH = 320
HEIGHT = 240
#Importing the external screen
os.putenv('SDL_FBDEV', '/dev/fb1')
os.putenv('SDL_MOUSEDRV', 'TSLIB')
os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen')
#Initializes the screen - Careful: all pygame commands must come after the init
pygame.init()
clock = pygame.time.Clock()
#Sets mouse cursor visibility
pygame.mouse.set_visible(False)
#Sets the screen note: must be after pygame.init()
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
class Board(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((900,900))
self.image.fill((13,13,13))
self.image.set_colorkey((13,13,13))
self.rect = self.image.get_rect()
self.font = pygame.font.Font('PressStart2P-Regular.ttf', 18)
def add(self, letter, pos):
s = self.font.render(letter, 1, (230, 230, 0))
self.image.blit(s, pos)
class Cursor(pygame.sprite.Sprite):
def __init__(self, board):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((10, 20))
self.image.fill((255,255,255))
self.text_height = 34
self.text_width = 20
self.rect = self.image.get_rect(topleft=(self.text_width, self.text_height))
self.board = board
self.text = ''
self.cooldown = 0
self.cooldowns = {'.': 12,
'[': 18,
']': 18,
' ': 5,
'\n': 30}
def write(self, text):
self.text = list(text)
def update(self):
if not self.cooldown and self.text:
letter = self.text.pop(0)
if letter == '\n':
self.rect.move_ip((0, self.text_height))
self.rect.x = self.text_width
else:
self.board.add(letter, self.rect.topleft)
self.rect.move_ip((self.text_width, 0))
self.cooldown = self.cooldowns.get(letter, 8)
if self.cooldown:
self.cooldown -= 1
all_sprites = pygame.sprite.Group()
board = Board()
cursor = Cursor(board)
all_sprites.add(cursor, board)
text = """[i] Initializing ...
[i] Entering ghost mode ...
done ...
"""
text = """[Me] What you talking about?
done ...
"""
cursor.write(text)
#Main loop
running = True
while running:
for e in pygame.event.get():
if e.type == pygame.QUIT:
running = False
all_sprites.update()
screen.fill((0, 0, 0))
all_sprites.draw(screen)
pygame.display.flip()
clock.tick(60)
Only "[Me] What you talking about?
done ..." is displayed and not the first message.
I had tried time sleep and simple while loops to solve this but the program just ignores the first function, waits the sleep, then goes on to the second action.
I think your problem is here:
text = """[i] Initializing ...
[i] Entering ghost mode ...
done ...
"""
text = """[Me] What you talking about?
done ...
"""
You are defining the variable text
as something and then immediately redefining it, so the first value of text
is never written.
I modified your code to have a list dialogueLoop
that contains all the dialogues beside the first one and, when the first dialogue is done being typed, switches the text of cursor
to the next dialogue. Worked for me.
The following is a working version of your code. You could replace the lines after self.cooldown -= 1
with the following, and it should work.
board = Board()
cursor = Cursor(board)
all_sprites.add(cursor, board)
text = """[i] Initializing ...
[i] Entering ghost mode ...
done ...
"""
cursor.write(text)
cursor.update()
#Main loop
running = True
dialogueLoop = ["""[Me] What you talking about?
done ...
"""
] # all the dialogues beside the first one
while running:
for e in pygame.event.get():
if e.type == pygame.QUIT:
running = False
while len(cursor.text) > 0: # updating loop
for e in pygame.event.get():
if e.type == pygame.QUIT:
running = False
screen.fill((0, 0, 0))
all_sprites.update()
all_sprites.draw(screen)
pygame.display.flip()
clock.tick(60)
if len(dialogueLoop) > 0: # switching dialogues
text = dialogueLoop[0]
dialogueLoop.pop(0)
else:
# dialogue is all finished
pass