How to play a partially looping sound in python - python

I am making a game with pygame and I have a waiting music for the lobby. I want this to play until the game starts. It would play a beginning part and then loop the rest infinitely. I have gone back and forth on what I should use to make the game. At first I was using unity with FMOD. This is what it was like in FMOD and what I am aiming to do in python

well, you can set a countdown until the beginning part is completed and then it will start looping the middle part like this:
import pygame
from pygame import mixer
import sys
pygame.init()
screen = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
songBeginningLength = 15
pygame.time.set_timer(pygame.USEREVENT, 1000)
mixer.music.load('BeginningPart.wav')
pygame.mixer.music.play(1) # loop 1
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.USEREVENT:
songBeginningLength -= 1
if songBeginningLength == 0: # check if countdown is done
mixer.music.load('MiddlePart.wav')
pygame.mixer.music.play(-1, 0.0) # loop forever
clock.tick(60)

Related

How do I stop the screen from updating?

I'm making a calculator in pygame but when I click the button, I want the number to stay on the screen but instead of staying on the screen, the number just appears when my mouse is clicked. When I release it, the numbers disappears. Does anyone know a solution for this?
My code:
import pygame
from sys import exit
pygame.init()
screen = pygame.display.set_mode((600,800))
pygame.display.set_caption("Calculator")
clock = pygame.time.Clock()
font1 = pygame.font.Font("c:/Users/oreni/OneDrive/Masaüstü/sprites/minecraft.ttf", 100)
one = 1
one_main = font1.render(str(one), False, "black")
one_main_r = one_main.get_rect(center = (75,100))
one_button = pygame.Surface((142.5,142.5))
one_button.fill("white")
one_button_r = one_button.get_rect(topleft = (0,160))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.fill("black")
screen.blit(one_button,one_button_r)
if event.type == pygame.MOUSEBUTTONDOWN:
if one_button_r.collidepoint(event.pos):
screen.blit(one_main,one_main_r)
pygame.display.update()
clock.tick(60)
The usual way is to redraw the scene in each frame. You need to draw the text in the application loop. Set a variable that indicates that the image should be drawn when the mouse is clicked, and draw the image according to that variable:
draw_r = False
run = True
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
if one_button_r.collidepoint(event.pos):
draw_r = True
screen.fill("black")
screen.blit(one_button,one_button_r)
if draw_r:
screen.blit(one_main, one_main_r)
pygame.display.update()
clock.tick(60)
pygame.quit()
exit()
The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()

Why does pygame.time.set_timer() stop working when I give it a parameter higher than 16 miliseconds?

I have a custom user event that I have assigned to the variable enemy_fire, and have it set to activate every 100 ms with pygame.time.set_timer(enemy_fire, 100). However, this does not work. I tried setting it to 10 ms: pygame.time.set_timer(enemy_fire, 10) and it worked, and I kept playing with the time parameter until I found the threshold in which it stopped working, and have found that anything higher than 16 ms does not work. I've been reading the documentation, and I'm pretty sure I'm using this function correctly. This seems like odd behavior to me, I'm not really sure why this is happening.
Here is the main part of my code:
import pygame
import gametools
import players
import enemies
from sys import exit
# initilaization
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption('Bullet hell')
clock = pygame.time.Clock()
# Player
player = players.Player()
enemy = enemies.Enemy()
# Background
back_surf = pygame.image.load('sprites/backgrounds/background.png').convert()
enemy_fire = pygame.USEREVENT + 1
# main game loop
while True:
pygame.time.set_timer(enemy_fire, 100)
# event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == enemy_fire:
print('fire')
enemy.attack(screen)
# display background
screen.blit(back_surf, (0, 0))
player.draw(screen)
player.update(screen)
enemy.draw(screen)
enemy.update()
enemy.collision(enemy.rect, player.bullets)
pygame.display.update()
clock.tick(60)
You have to call pygame.time.set_timer(enemy_fire, 100) before the application loop, but not in the loop. When you call pygame.time.set_timer() in the loop, it will continuously restart and never fire unless you set an interval time faster than the application loop interval. Since the application loop is limited by clock.tick(60), that's about 16 milliseconds (1000/60).
pygame.time.set_timer(enemy_fire, 100) # <-- INSERT
# main game loop
while True:
# pygame.time.set_timer(enemy_fire, 100) <-- DELETE
# event loop
for event in pygame.event.get():
# [...]

pygame sprite not moving across screen when updates

I am trying to move my sprite across the screen when the window starts.... It moves for a second than stops for a while than it starts back up again. its not giving me an error.... So im really not sure whats going on here.... anyway here is the code.... any info is needed!
thanks,
import pygame
from sys import exit
pygame.init()
screen = pygame.display.set_mode((800,400))
sky_surface = pygame.image.load("bg_desert.png")
snail_surface = pygame.image.load("snailWalk1.png")
snail_x_pos = 600
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
snail_x_pos -=1
screen.blit(sky_surface,(0,0))
screen.blit(snail_surface,(snail_x_pos,350))
pygame.display.update()
Your loop will only execute when there are events. When there are no events, you don't move. If you wiggle your mouse in front of the screen, for example, you'll see pretty continuous movement.
You need to use pygame.time.set_timer to force an event for you to update.
It looks like the final 4 lines you have written are designed to run on each cycle of the for loop, however they will only run when an event occurs, because they are indented a block too far.
Your new code should look like this:
import pygame
from sys import exit
pygame.init()
screen = pygame.display.set_mode((800,400))
sky_surface = pygame.image.load("bg_desert.png")
snail_surface = pygame.image.load("snailWalk1.png")
snail_x_pos = 600
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
snail_x_pos -=1
screen.blit(sky_surface,(0,0))
screen.blit(snail_surface,(snail_x_pos,350))
pygame.display.update()

Why is my Pygame window only displaying for only a few seconds?

I'm new to PyGame (and python in general) and I am just trying to get a window to pop up. That's all I'm after for now. Here's my code:
import pygame
pygame.init()
win = pygame.display.set_mode((600, 600))
pygame.display.set_caption('First Game')
I am using Python 3.7.0 in Pycharm and PyGame 1.9.4.
Following Python's PyGame tutorial, your next step is to start a while loop to handle the game frames:
import pygame
pygame.init()
win = pygame.display.set_mode((600, 600))
pygame.display.set_caption('First Game')
clock = pygame.time.Clock() # Determine FPS (frames-per-second)
crashed = False
# Game loop
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
print(event)
pygame.display.update()
clock.tick(60)
Because you need to first put it inside a loop (so it refreshes whatever is inside it), that way it stays on until something alters the condition of that loop.
# Event loop (HERE YOU PUT IT).
while 1:
for event in pygame.event.get():
if event.type == QUIT:
return
screen.blit(background, (0, 0))
pygame.display.flip()
if __name__ == '__main__': main()

Pygame Window Not Responding

I am trying to make a game in Pygame where he objective is to start the game but the start button keeps moving whenever you touch it but the window will not respond. I am not finished with the code yet because I tested it and it didn't work. Here is my code so far:
import pygame
import random
import time
pygame.init()
display = pygame.display.set_mode((800,600))
pygame.display.set_caption('BEST 3D PLATFORMER FPS GAME!')
clock = pygame.time.Clock()
pygame.display.update()
clock.tick(60)
display.fill((255,255,255))
def newposition()
randx = random.randrange(100, 700)
randy = random.randrange(100,500)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pass
if event.ty
button = pygame.image.load('start.png')
display.blit(button,(randx,randy))
pygame.quit()
quit()
All comments inside code
import pygame
import random
# --- constants --- (UPPER_CASE names)
WHITE = (255, 255, 255) # space after every `,`
FPS = 30
# --- classes --- (CamelCase names)
#empty
# --- functions --- (lower_case names)
def new_position():
x = random.randrange(100, 700) # space after every `,`
y = random.randrange(100, 500) # space after every `,`
return x, y # you have to return value
# --- main --- (lower_case names)
# - init -
pygame.init()
display = pygame.display.set_mode((800, 600)) # space after every `,`
pygame.display.set_caption('BEST 3D PLATFORMER FPS GAME!')
# - objects -
# load only once - don't waste time to load million times in loop
button = pygame.image.load('start.png').convert_alpha()
button_rect = button.get_rect() # button size and position
button_rect.topleft = new_position() # set start position
# - mainloop -
clock = pygame.time.Clock()
running = True
while running:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
#pass # it does nothing so you can't exit
running = False # to exit `while running:`
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False # to exit `while running:`
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # left button
button_rect.topleft = new_position() # set new position
# if event.ty # Syntax Error
# - updates (without draws) -
#empty
# - draws (without updates) -
# you have to use it inside loop
display.fill(WHITE) # clear screeen before you draw elements in new place
display.blit(button, button_rect)
# you have to use it inside loop
pygame.display.update() # you have to send buffer to monitor
# - FPS -
# you have to use it inside loop
clock.tick(FPS)
# - end -
pygame.quit()
BTW: simple template which you can use when you start new project.
PEP 8 -- Style Guide for Python Code
I had a similar issue, the fix is not straight forward. Here are my notes for python 3.6.1 and Pygame 1.9.3:
1) The event is unresponsive because there is no display generated for pygame, add a window display after pygame initialization:
pygame.init() # Initializes pygame
pygame.display.set_mode((500, 500)) # <- add this line. It generates a window of 500 width and 500 height
2) pygame.event.get() is a generates a list of event but not all event classes have .key method for example mouse motion. Thus, change all .key event handling codes such as
if event.key == pygame.K_q:
stop = True
To
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
stop = True
3) In some mac/python combinations even after the window is generated it doesn't focus / record keyboard events, this is a pygame issue and is fixed in a reimplementation of pygame using sdl2 (SDL is a cross-platform development library which provides low level access to keyboard, audio ,mouse etc). it can be installed by following the instructions here https://github.com/renpy/pygame_sdl2. One might need to install homebrew for it, which is another package manager for macOS. Instructions can be found here https://brew.sh/
4) after installing it using the instructions on github link you need to change all import pygame to import pygame_sdl2 as pygame
5) Voila! fixed ...
You've got to load button outside the loop (it only needs to be done once.)
button = pygame.image.load('start.png')
Also, you have defined newposition(), but have not called it. Also, randx and randy would not be accessible from outside of the function, because the would be local to it.
So, change your function to this :
def newposition()
randx = random.randrange(100, 700)
randy = random.randrange(100,500)
return randx, randy # Output the generated values
Then, before the loop :
rand_coords = newposition()
You simply forgot to update the pygame display with your modifications to it.
At the end of your loop, add pygame.display.update(), like this:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pass
# if event.ty why is that here?
display.blit(button,(rand_coords[0],rand_coords[1])) # Take our generated values
pygame.display.update()
Final code :
import pygame
import random
import time
pygame.init()
display = pygame.display.set_mode((800,600))
pygame.display.set_caption('BEST 3D PLATFORMER FPS GAME!') # Yeah, exactly :)
clock = pygame.time.Clock()
display.fill((255,255,255))
def newposition()
randx = random.randrange(100, 700)
randy = random.randrange(100,500)
return randx, randy # Output the generated values
rand_coords = newposition() # Get rand coords
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # Quit pygame if window in closed
# if event.ty why is that here?
clock.tick(60) # This needs to be in the loop
display.fill((255,255,255)) # You need to refill the screen with white every frame.
display.blit(button,(rand_coords[0],rand_coords[1])) # Take our generated values
pygame.display.update()

Categories