Quit function is not working in pygame - python-3.x

I want the system to exit when I click the "x" on the window of pygame. I want to be able to call the quit_game function whenever I need to. So if the user does quit, it actually quits. I have tried sys exit and pygame.quit(), but I haven't been able to successfully implement those. Right now I just have the quit function built into the intro screen. I am using python 3.4.3. Here is the code.
import math
import random
import time
import pygame
import sys
import glob
pygame.init()
move=0
FPS=60
blue=(0,0,255)
white=(255,255,255)
black=(0,0,0)
green=(0,155,0)
display_width=800
display_height=600
gamedisplay=pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Stacker')
clock=pygame.time.Clock()
speed=2
smallfont=pygame.font.SysFont("Arial",int(display_width/32))
mediumfont=pygame.font.SysFont("Arial",int(display_width/16))
largefont=pygame.font.SysFont("Arial",int(display_width/10))
gamedisplay.fill(green)
block=display_height/12
pygame.display.update()
def quit_game():
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
quit()
def intro_screen():
welcome_message = mediumfont.render(str("Welcome to Stacker!!!"), True,black)
gamedisplay.blit(welcome_message,(display_width/4,display_height/40))
how_to_play_1=smallfont.render(str("Your goal is to get to the major prize bar"),True,black)
gamedisplay.blit(how_to_play_1,(display_width/3.619909502,display_height/2))
how_to_play=smallfont.render(str("Press the space bar to stop the shape"),True,black)
gamedisplay.blit(how_to_play,(display_width/3.48583878,display_height/(12/7)))
quit_game()
pygame.display.update()
def middle_block():
pygame.draw.rect(gamedisplay, blue,(display_width/(32/15),display_height-block,block,block))
pygame.display.update()
def left_block():
pygame.draw.rect(gamedisplay, blue,(display_width/(32/13),display_height-block,block,block))
pygame.display.update()
def right_block():
pygame.draw.rect(gamedisplay, blue,(display_width/(32/17),display_height-block,block,block))
pygame.display.update()
def major_screen():
major_message = mediumfont.render(str("Major Prize Here!"), True,black)
gamedisplay.blit(major_message,(display_width/(10/3),display_height/40))
pygame.display.update()
intro_screen()
pygame.time.delay(8000)
gamedisplay.fill(green)
major_screen()
pygame.draw.rect(gamedisplay, blue,(display_width-display_width,display_height/8,display_width,display_height/60))
pygame.draw.rect(gamedisplay, blue,(display_width-display_width,display_height/2.4,display_width,display_height/60))
middle_block()
left_block()
right_block()
pygame.display.update()

Your code has no main game-loop. You may thinks this:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
quit()
Is your game-loop. While that is almost correct, it is missing a key part. A while loop. Your telling Python to loop through every single event that Pygame is tracking. After it finishes looping through the events once, it stops. You want Python to continually loop through the Pygame events, until the window is closed. To do this create a variable to control your loop. Such as running = True or not_quit = True. Next wrap a while-loop around your for-loop using the control variable as your condition. Lastly, if the user closes the window, set your control variable to False.
running = True # our variable to control the loop.
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False # break the loop
pygame.quit()
sys.exit()
quit()
This should allow you to close your window. I should note however that none of the text/shapes your blitting/drawing to the screen will be visible unless inside your game-loop. So you may need to rethink your code a bit.

Related

Pygame gamepad won't run anymore with an Xbox 360 controller and an Ubuntu machine [duplicate]

This code goes into infinite loop. I cant use A button on xbox 360 controller
import pygame
from pygame import joystick
pygame.init()
joystick = pygame.joystick.Joystick(0)
pygame.joystick.init()
print("start")
while True:
if joystick.get_button(0) == 1 :
print("stoped")
break
I cant use A button on xbox 360 controller
Personnaly, I can, so this seems to be possible. You are just missing that pretty much every user input needs to be updated by pygame through pygame.event.get().
From the pygame documentation:
Once the device is initialized the pygame event queue will start receiving events about its input.
So, apparently you need to get the events in the while loop like such to make the joystick work:
import pygame
from pygame.locals import *
pygame.init()
joystick = pygame.joystick.Joystick(0)
while True:
for event in pygame.event.get(): # get the events (update the joystick)
if event.type == QUIT: # allow to click on the X button to close the window
pygame.quit()
exit()
if joystick.get_button(0):
print("stopped")
break
Also,
In the line if joystick.get_button(0) == 1, you don't need to type == 1 because the statement is already True.
You are initializing pygame.joystick twice: through the line pygame.init() and pygame.joystick.init().
You don't need to type from pygame import joystick because you already already have it in the line import pygame.
You can take this as reference and use it in your own way.
import pygame
import sys
pygame.init()
pygame.joystick.init()
clock = pygame.time.Clock()
WIDTH,HEIGHT = 500,500
WHITE = (255,255,255)
BLUE = (0,0,255)
BLUISH = (75,75,255)
YELLOW =(255,255,0)
screen = pygame.display.set_mode((WIDTH,HEIGHT))
smile = pygame.image.load("smile.jpg")
smile = pygame.transform.scale(smile,(WIDTH,HEIGHT))
idle = pygame.image.load("idle.jpg")
idle = pygame.transform.scale(idle,(WIDTH,HEIGHT))
joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.JOYBUTTONDOWN:
if event.button == 0: #press A button to smile
screen.fill(WHITE)
screen.blit(smile,(0,0))
pygame.display.update()
clock.tick(10)
elif event.type == pygame.JOYBUTTONUP:
if event.button == 0:
screen.fill(WHITE)
screen.blit(idle,(0,0))
pygame.display.update()
clock.tick(10)

Utilising the pygame.mixer.music.get_endevent()

I want a tkinter label to show nothing when a sound effect has finished.
I've been researching the www on how to create/initialise/catch the end of music event with no luck.
def play_btn():
if mixer.music.get_busy():
mixer.music.fadeout(1000)
snd_fyl.set(snd_list.get(ACTIVE))
mixer.music.load(snd_dir+"/"+snd_list.get(ACTIVE)+"mp3")
mixer.music.play()
def stop_btn():
mixer.music.stop()
clear_label()
def clear_label():
snd_fyl.set("")
snd_lbl1 = LabelFrame(MainWindow, text="Sound effect playing", labelanchor=N)
snd_playing_lbl = Label(snd_lbl1, width=40, textvariable=snd_fyl)
Obviously play_btn function plays a sound effect from a list.
The stop_btn function prematurely halts the sound effect and clears the label.
The clear_label function has been created in readiness for the end_of_song event
You have to use set_endevent() to set value which it will send to event queue when music has finished.
MUSIC_END = pygame.USEREVENT+1
pygame.mixer.music.set_endevent(MUSIC_END)
And then you can test it in event loop
if event.type == MUSIC_END:
print('music end event')
It will print text when music has finished - but not when you stop it or pause it.
BTW: on Linux I see this text few milliseconds before it ends playing music.
Full working example - but without tkinter
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
MUSIC_END = pygame.USEREVENT+1
pygame.mixer.music.set_endevent(MUSIC_END)
pygame.mixer.music.load('sound.wav')
pygame.mixer.music.play()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == MUSIC_END:
print('music end event')
if event.type == pygame.MOUSEBUTTONDOWN:
# play again
pygame.mixer.music.play()
pygame.quit()
EDIT: Example with tkinter
import pygame
import tkinter as tk
def check_event():
for event in pygame.event.get():
if event.type == MUSIC_END:
print('music end event')
label['text'] = ''
root.after(100, check_event)
def play():
label['text'] = 'playing'
pygame.mixer.music.play()
# --- main ---
pygame.init()
MUSIC_END = pygame.USEREVENT+1
pygame.mixer.music.set_endevent(MUSIC_END)
pygame.mixer.music.load('sound.wav')
root = tk.Tk()
label = tk.Label(root)
label.pack()
button = tk.Button(root, text='Play', command=play)
button.pack()
check_event()
root.mainloop()
pygame.quit()

Key Pressing System PyGame

I'm making a basic pong game and want to make a system where a button press makes the paddle goes up or down. I'm fairly new to PyGame and here's my code so far.
import pygame, sys
from pygame.locals import*
def Pong():
pygame.init()
DISPLAY=pygame.display.set_mode((600,400),0,32)
pygame.display.set_caption("Pong")
BLACK=(0,0,0)
WHITE=(255,255,255)
RED=(255,0,0)
DISPLAY.fill(BLACK)
while True:
def P(b):
pygame.draw.rect(DISPLAY,WHITE,(50,b,50,10))
xx=150
P(xx)
for event in pygame.event.get():
if event.type==KEYUP and event.key==K_W:
P(xx+10)
xx=xx+10
pygame.display.update()
elif event.type==QUIT:
pygame.quit()
sys.exit()
Please read some tutorials and/or docs. This is really basic and if you don't get this right it will bite you later.
Anyway, here's how it could look:
import pygame
pygame.init()
DISPLAY = pygame.display.set_mode((600,400))
paddle = pygame.Rect(0, 0, 10, 50)
paddle.midleft = DISPLAY.get_rect().midleft
speed = 10
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
raise SystemExit(0)
keystate = pygame.key.get_pressed()
dy = keystate[pygame.K_s] - keystate[pygame.K_w]
paddle.move_ip(0, dy * speed)
DISPLAY.fill(pygame.Color("black"))
pygame.draw.rect(DISPLAY, pygame.Color("white"), paddle)
pygame.display.update()
clock.tick(30)
That is ok for Pong but I still wouldn't write my game like this. So read some tutorials and maybe try CodeReview if you really want to improve your code.

How to use keyboard in pygame?

I tried the simple script below, but I get no response. Maybe I don't understand what pygame is capable of doing. I simply want to assign a certain function to a certain key. Like if I press the letter 'h' I want "Bye" to print on the screen or if I press 'g' then play a certain song. And so on and so on...
import pygame
from pygame.locals import *
pygame.init()
print K_h #It prints 104
while True:
for event in pygame.event.get():
if event.type==KEYDOWN:
if event.key==K_h:
print "Bye" #Nothing is printed when I press h key
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((640,480))
clock = pygame.time.Clock()
while True:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == KEYDOWN:
if event.key == K_h:
print "bye"
for what ever reason for me atleast it seems the event command wouldn't work with out the use of a screen even if it has no purpose this will get you the results you want.

Pygame waiting the user to keypress a key

I am searching a method, where the program stops and waiting for a spesific key to be pressed by the user. May I can implement this one with a while loop? I need the best algorithm, if there exist a build-in function of waiting, to avoid the loop.
I found several information on the official website of pygame, but nothing help.
Here is a testing algorithms but won't work:
key = "f"
while key != "K_f":
key = pygame.key.get_pressed()
if key[Keys.K_f]:
do something...
If you are waiting for a key to be pressed you can use the event.wait() function. This is useful, because it does not require a-lot of processing.
import pygame
from pygame.locals import *
pygame.event.clear()
while True:
event = pygame.event.wait()
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key = K_f:
do something...
Note that event.wait() waits for events to appear in the event cache, the event cache should be cleared first.
pygame.event documentation
You could do it with a while loop and an event queue:
from pygame.locals import *
def wait():
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN and event.key == K_f:
return

Resources