In the last post (Fastest way to move something on the screen with Pygame) we’ve seen this
Now we want to transform it into this:
The color now is unique for every square, but it changes continuosly.
def colorvariation(self): # <- pulsar ''' fills the surfaces with variable colors ''' self.surface.fill(( self.colorvar, self.colorvar2, 0)) def pulsar(self): variation = math.cos(timer/8) self.colorvar = 255-abs(int(math.sin(timer/16)*100)) self.colorvar2 = 255-abs(int(math.cos(timer/32)*100)) # print(int(math.cos(timer/2)*100)) match self.pos: case "right": self.rectx += variation self.colorvariation() case "left": self.rectx -= variation self.colorvariation() case "top": self.recty -= variation self.colorvariation() case "bottom": self.recty += variation self.colorvariation() case "center": self.colorvariation() screen.blit(self.surface, (self.rectx, self.recty))
This code has been added to the Shape class to do the color changing.
I splitted the code in different files like these
This is meant to get porganized while we write more lines of code, things may seems more complicated this way, but if you want to mantain control over the code when you add features and lines of code, I think is the best thing to do. You may think that is better to get all in one file and this can be also a good method, using different tecniques to do not lost the path of what you are doing as you go on. It is very important that you use names for functions and classes that are meaningful and intuitive of what they do, this will save you tons of time and thinking energy and so maybe you won’t lose interest in your project. Often go back to your code and polish it, avoid repetition. Think to this work as when you tidy your room, you can use it also if you do not put everything in order, but you will waste a lot of time looking for stuff you forgot where you put them, because you put them without a criteria. If you put same stuffs in the same place, you will soon find them. End of methaphor.
Let’s check the frame rate
Here is some code to check the frame rate of the game on the screen.
import pygame ''' Example to show fps with pygame 28.12.2021 - python 3.10 ''' def scale(x): scaled = pygame.transform.scale(x, (50,50)) return scaled def render_fps(background=""): ''' shows the frame rate on the screen ''' fps_text = font.render(str(int(clock.get_fps())),1,(255,255,255)) # get the clocl'fps if background != "": bck.fill((255,0,0)) bck.blit(fps_text,(0,0)) screen.blit(scale(bck),(0,0)) else: screen.blit(scale(fps_text),(0,0)) def mainloop(): ''' Infinite event loop where thing happens every frame ''' while True: # screen.fill(0) render_fps(1)# call the function to blit fps for event in pygame.event.get(): # close window if event.type == pygame.QUIT: pygame.quit() pygame.display.update() # update the display clock.tick(60) # max frame rate to save memory # INIT pygame.init() screen = pygame.display.set_mode((600, 400)) # the screen surface clock = pygame.time.Clock() # FONT INIT size = 20 font = pygame.font.SysFont("Arial", size) # a font for the fps bck = pygame.Surface((size,size)) bck.fill((255,0,0)) mainloop()
Now let’s see how we implement in the previous code.
import pygame from init6 import * ''' Example to show fps with pygame 28.12.2021 - python 3.10 ''' def scale(x): scaled = pygame.transform.scale(x, (50,50)) return scaled def render_fps(background=""): ''' shows the frame rate on the screen ''' fps_text = font.render(str(int(clock.get_fps())),1,(255,255,255)) # get the clocl'fps if background != "": bck.fill((255,0,0)) bck.blit(fps_text,(0,0)) screen.blit(scale(bck),(0,0)) else: screen.blit(scale(fps_text),(0,0)) def mainloop(): ''' Infinite event loop where thing happens every frame ''' while True: # screen.fill(0) render_fps(1)# call the function to blit fps for event in pygame.event.get(): # close window if event.type == pygame.QUIT: pygame.quit() pygame.display.update() # update the display clock.tick(60) # max frame rate to save memory # FONT INIT size = 20 font = pygame.font.SysFont("Arial", size) # a font for the fps bck = pygame.Surface((size,size)) bck.fill((255,0,0)) if __name__ == "__main__": # INIT pygame.init() screen = pygame.display.set_mode((600, 400)) # the screen surface clock = pygame.time.Clock() mainloop()
As the code is becoming complex, I will put it into github at this address:
https://github.com/formazione/pygamezero
So, for the moment we got 4 files, plus the main one. We’ve managed to do this so far, using this “modular” approach to add features. Next thing we want to add is voice from text to speech. I think is a nice touch and as we are good at this thing, why not? Let’s do it.
Adding voice to the game without files
If we do not want to use file we must use the google API from the module gtts and some other little tricks.
the code is the following:
from gtts import gTTS from io import BytesIO import pygame import time import os import sys # VERSION CLI def wait(): # print(pygame.mixer.get_busy()) while pygame.mixer.get_busy(): time.sleep(.1) def speak(text="", language='it'): ''' speaks without saving the audio file ''' mp3_fo = BytesIO() tts = gTTS(text, lang=language) tts.write_to_fp(mp3_fo) mp3_fo.seek(0) sound = pygame.mixer.Sound(mp3_fo) sound.play() # wait() pygame.init() pygame.mixer.init()
That is the result.
I have called the function speak in the loop.py file, right before the while loop (I changed the text since the video above was recorded).
See you in chapter 3.
speak("Chapter I, the game begins", "en")
Subscribe to the newsletter for updates
Tkinter templates
My youtube channel
Twitter: @pythonprogrammi - python_pygame