0

I'm not so sure why but my game screen window/pygame window sometimes freezes or is not responding because of the added SFX or music in my game. If I remove the SFX or music the game runs smoothly. Hoping that anyone can help me or at least tell me why it keeps freezing. Thanks very much.

The specific code for music and sounds in class Game can be found in load_data method, run method, and update method. This is where you can find my music, target SFX when hit, bonus SFX when hit.

Below is from my main.py module

import pygame as py
import sys
from os import kill, path
from Setting import *
from Sprite import *
import random

#BUGs (BULLET DISAPPEAR WHEN PAUSED [PROBABLY FROM get_tick()])
#add highscore later in end screen
class Game():
def __init__(self):
    py.mixer.pre_init(44100, -16, 1, 512)
    py.init()
    self.screen = py.display.set_mode((Width, Height),py.RESIZABLE)
    py.display.set_caption("Hit Me!")
    self.clock = py.time.Clock()
    self.load_data()
    self.score_value = 0
    self.time_value = 90
    self.paused = False
    self.channel1 = py.mixer.Channel(1)
    self.channel2 = py.mixer.Channel(2)
    self.channel3 = py.mixer.Channel(3)
    
def draw_data(self, text, font_name, size, color, x, y,type=0, align="center", value=""):
    
    font = py.font.Font(font_name, size)
    if type == 0:
        text_surface = font.render(text + str(value), True, color)
        if self.paused == True:
            text_surface.set_alpha(125)   
    else:
        text_surface = font.render(text, True, color)
                       
    text_rect = text_surface.get_rect()
    if align == "nw":
        text_rect.topleft = (x, y)
    if align == "ne":
        text_rect.topright = (x, y)
    if align == "sw":
        text_rect.bottomleft = (x, y)
    if align == "se":
        text_rect.bottomright = (x, y)
    if align == "n":
        text_rect.midtop = (x, y)
    if align == "s":
        text_rect.midbottom = (x, y)
    if align == "e":
        text_rect.midright = (x, y)
    if align == "w":
        text_rect.midleft = (x, y)
    if align == "center":
        text_rect.center = (x, y)
    self.screen.blit(text_surface, text_rect)
    
def load_data(self):
    game_folder = path.dirname(__file__)
    self.map_data = []
    with open(path.join(game_folder, 'map.txt'), 'rt') as f:
        for line in f:
            self.map_data.append(line)
            
    image_folder = path.join(game_folder, 'images')
    sfx_folder = path.join(game_folder, 'sfx_music')
    
    self.dim_screen = py.Surface(self.screen.get_size()).convert_alpha()
    self.dim_screen.fill((0, 0, 0, 150))
    
    self.player_img = py.image.load(
        path.join(image_folder, character)).convert_alpha()

    self.bullet_img = py.image.load(
        path.join(image_folder, bullets)).convert_alpha()

    self.target_img = py.image.load(
        path.join(image_folder, targets)).convert_alpha()

    self.target_img = py.transform.scale(
        self.target_img, (TileSize + 20, TileSize + 20))

    self.bonus_img = py.image.load(
        path.join(image_folder, time)).convert_alpha()

    self.bonus_img = py.transform.scale(
        self.bonus_img, (TileSize + 30, TileSize + 30))
    
    #sound loading
    self.music = py.mixer.Sound(path.join(sfx_folder,background_music))
    self.music.set_volume(0.25)
    self.gun_sfx = py.mixer.Sound(path.join(sfx_folder,gun_sound))
    self.bonus_sfx = py.mixer.Sound(path.join(sfx_folder,bonus_sound))
    self.target_sfx = py.mixer.Sound(path.join(sfx_folder,target_sound))
    self.gun_sfx.set_volume(0.4)
    self.target_sfx.set_volume(0.5)
    
def new(self):
    self.sprites = py.sprite.Group()
    self.walls = py.sprite.Group()
    self.grass = py.sprite.Group()
    self.targets = py.sprite.Group()
    self.bullets = py.sprite.Group()
    self.bonuss = py.sprite.Group()
    for row, tiles in enumerate(self.map_data):
        for col, tile in enumerate(tiles):
            if tile == 'P':
                self.player = Player(self, col, row)
    py.time.set_timer(py.USEREVENT, 1000)
    
def newTarget(self):
    self.targets = py.sprite.Group()
    for row, tiles in enumerate(self.map_data):
        for col, tile in enumerate(tiles):    
            if tile == '.':
                target_chances = random.randint(0, 100)
                if target_chances <= 10: # 10% chance 
                    tile = 'T'
                    
            if tile == 'M':
                bonus_chances = random.randint(0,100)
                if bonus_chances <= 5: # 5% chance bonus time (add 2 or 3 seconds to timer) [specified area]
                    tile = 'B'
                    
            if tile == 'T':
                Target(self, col, row)
            if tile == 'B':
                Bonus(self,col,row)
    
def run(self):
    self.playing = True 
    
    self.music_played = False
    if not self.music_played:
        self.channel3.play(self.music, loops = -1)
        self.music_played = True
    
    while self.playing:
        self.dt = self.clock.tick(FPS) / 1000
        self.events()
        if not self.paused:
            self.update()
            self.channel3.unpause()
        if self.paused:
            self.channel3.pause()
        self.draw()
    

def quit(self):
    py.quit()
    sys.exit()
    
def update(self):
    self.sprites.update()
    hits = py.sprite.groupcollide(
        self.targets, self.bullets, True, True, py.sprite.collide_mask)
    bonus_hits = py.sprite.groupcollide(
        self.bonuss, self.bullets, True, True, py.sprite.collide_mask)
    
    #for bullets & targets
    for hit in hits:
        hit.kill()
        self.score_value += 1
        self.target_sfx_played = False
        if not self.target_sfx_played:
            self.channel1.play(self.target_sfx)
            self.target_sfx_played = True

    #for bullets & bonus
    for hit in bonus_hits:
        hit.kill()
        self.time_value += 3
        self.bonus_sfx_played = False
        if not self.bonus_sfx_played:
            self.channel2.play(self.bonus_sfx)
            self.bonus_sfx_played = True
            
    #if there is no target in screen, it will create a new set 
    if len(self.targets) == 0:
        self.newTarget()    

def drawGrid(self):
    for x in range(0, Width, TileSize):
        py.draw.line(self.screen, Black, (x, 0), (x, Height))

    for y in range(0, Height, TileSize):
        py.draw.line(self.screen, Black, (0, y), (Width, y))

def draw(self):
    py.display.set_caption("{:.2f}".format(self.clock.get_fps()))
    self.screen.fill(BGcolor)
    self.drawGrid()
    self.sprites.draw(self.screen)
    py.draw.rect(self.screen, Green, self.player.rect, 1)
    
    if self.paused:
        self.screen.blit(self.dim_screen, (0, 0))
        self.draw_data("Paused",'freesansbold.ttf', 105, White, Width / 2, Height / 2,1)
        
    self.draw_data("Score: ",'freesansbold.ttf', 40, White, 100, 35,value = self.score_value)
    self.draw_data("Time: ",'freesansbold.ttf', 40, White, 450, 35 ,value = self.time_value)
    self.draw_data("HighScore: ",'freesansbold.ttf', 40, White, Width - 225, 35) # add data in end game   
    py.display.flip()

def events(self):
    for event in py.event.get():
        if event.type == py.QUIT:
            self.quit()
        if event.type == py.KEYDOWN:
            if event.key == py.K_ESCAPE:
                self.paused = not self.paused    
        if event.type == py.MOUSEBUTTONDOWN:
            if event.button == 1:
                if not self.paused:
                    self.player.shoot()
        if event.type == py.USEREVENT:
            if not self.paused:
                self.time_value -=1
                   
                   
def show_start_screen(self):
    pass

def show_go_screen(self):
    pass

# main loop
g = Game()
g.show_start_screen()

while True:
    g.new()
    g.run()
    g.show_go_screen()

In the Sprite.py module, this is where you can find the SFX for gun shooting whenever I press/hold the left mouse button.

Below is from my Sprite.py module

 import pygame as py
 from Setting import *
 from pygame.locals import *
 vec = py.math.Vector2

class Player(py.sprite.Sprite):
  def __init__(self, game,x,y):
    self.groups = game.sprites
    py.sprite.Sprite.__init__(self, self.groups)
    self.game = game
    self.orig_image = game.player_img
    self.rect = self.orig_image.get_rect()
    self.pos = vec(x,y) * TileSize 
    self.rect.center = self.pos 
    self.last_shot = 0
    self.gun_sfx = game.gun_sfx
    self.channel4 = py.mixer.Channel(4)

  def shoot(self):
    if py.mouse.get_pressed()[0]:
        now = py.time.get_ticks()
        if now - self.last_shot > bullet_rate:
            self.gun_sfx_played = False
            if not self.gun_sfx_played:
                self.channel4.play(self.gun_sfx)
                self.gun_sfx_played = True
            self.last_shot = now
            dir = py.mouse.get_pos() - self.pos
            radius, angle = dir.as_polar()
            direction = vec(1, 0).rotate(angle - 3)
            pos = self.pos + Barrel_offset.rotate(angle)
            Bullet(self.game, pos, direction, -angle)

  def rotate(self):
    dir = py.mouse.get_pos() - self.pos
    radius, angle = dir.as_polar()
    self.image = py.transform.rotate(self.orig_image, -angle)
    self.rect = self.image.get_rect(center=self.rect.center)

  def update(self):
    self.shoot()
    self.rotate()

Below is from my Setting.py

 # sounds
 gun_sound = 'gun_sfx.mp3'
 background_music = 'bg_music.mp3'
 target_sound = 'target_sfx_broken.mp3'
 bonus_sound = 'hourglass_sfx.mp3'
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Spikes
  • 1
  • 2
  • I don't know if it's because of my IDE or because of the software I am using that makes somehow the pygame window freeze – Spikes Apr 17 '22 at 13:37
  • 2
    Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Apr 17 '22 at 13:52
  • Can you edit your question so that it is reproducible, either by cutting back some of the code or linking all of the assets so it can run it properly. This would make it much easier to help you out. Thanks! – Cmd858 Apr 18 '22 at 15:05
  • 1
    @CmdCoder858 Thanks for the concern. The problem I am facing on the previous day just suddenly vanished. It may be because of me running too much of the code that it suddenly freezes my pygame window. The code itself actually works fine. If it arises again, I will inform you all ASAP. – Spikes Apr 19 '22 at 02:23

0 Answers0