So apparently pygame.time.set_timer() doesn't work when used inside a class and I just can make it behave as a timer. Inside a class it will be called every frame
import pygame
pygame.init()
screen = pygame.display.set_mode((100, 100))
FPS = 60
clock = pygame.time.Clock()
class Bird():
def __init__(self):
self.count = 1
self.count_timer = pygame.USEREVENT + 1
pygame.time.set_timer(self.count_timer, 1000)
def go(self):
if event.type == self.count_timer:
print(self.count)
self.count += 1
b = Bird()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
b.go()
pygame.display.update()
clock.tick(FPS)
pygame.quit()
If the timer is outside of a class it works as expected and will be called once per second
import pygame
pygame.init()
screen = pygame.display.set_mode((100, 100))
FPS = 60
clock = pygame.time.Clock()
count = 1
count_timer = pygame.USEREVENT + 1
pygame.time.set_timer(count_timer, 1000)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == count_timer:
print(count)
count += 1
pygame.display.update()
clock.tick(FPS)
pygame.quit()
Can anyone explain what needs to be done to make it work inside of a class? Thank you
This has nothing to do with set_timer. However, you have to call the go method in the event loop for each event:
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
b.go() # <--- INSTERT
# b.go() <--- DELETE
I recommend passing the event object as an argument to the method:
class Bird():
# [...]
def go(self, e):
if e.type == self.count_timer:
print(self.count)
self.count += 1
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
b.go(event)
# [...]
Or pass the full list of events to the method:
import pygame
pygame.init()
screen = pygame.display.set_mode((100, 100))
FPS = 60
clock = pygame.time.Clock()
class Bird():
def __init__(self):
self.count = 1
self.count_timer = pygame.USEREVENT + 1
pygame.time.set_timer(self.count_timer, 1000)
def go(self, event_list):
if self.count_timer in [e.type for e in event_list]:
print(self.count)
self.count += 1
b = Bird()
running = True
while running:
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
running = False#
b.go(event_list)
pygame.display.update()
clock.tick(FPS)
pygame.quit()
Related
I want to view my blit() however once i add the line self.screen_dim.fill([255, 255, 255])
pygame.display.update() it overlaps
def __init__(self):
self.width = 500
self.height = 500
self.screen_dim = pygame.display.set_mode((self.width, self.height))
self.mole = pygame.image.load("mole.png")
self.mole_hit = pygame.image.load("mole-hit.png")
I am confused on how to get my pygame screen the images within that function is working however it overlaps if i added a new background color
def start(self):
stat = True
num_display = 1
x_array = []
y_array = []
for i in self.mole_pos:
x_array.append(i[0])
y_array.append(i[1])
while stat:
Rand_Pos = random.randint(0, 8)
if num_display == 1:
self.screen_dim.blit(self.mole, (x_array[Rand_Pos], y_array[Rand_Pos]))
for Event in pygame.event.get():
if Event.type == pygame.QUIT:
stat = False
if self.mouse_clicked(mouse.get_pos(), self.mole_pos[Rand_Pos]):
num_display = 0
self.screen_dim.blit(self.mole_hit, (x_array[Rand_Pos], y_array[Rand_Pos]))
continue
pygame.display.flip()
This ahs nothing to to with class. It is just a matter of Indentation. You have to draw self.mole_hit in the application loop rather than the event loop:
def start(self):
# [...]
while stat:
# [...]
for Event in pygame.event.get():
if Event.type == pygame.QUIT:
stat = False
#<--| INDENTATION
if self.mouse_clicked(mouse.get_pos(), self.mole_pos[Rand_Pos]):
num_display = 0
self.screen_dim.blit(self.mole_hit, (x_array[Rand_Pos], y_array[Rand_Pos]))
pygame.display.flip()
I want to close the game after was pressed the esc button. how can I do? And where should I place it?
I also found some problems that I can't solve, so if you solve them for me I would be happy
This is the code:
#Import Libraries
import pygame
import random
#PyGame Initialization
pygame.init()
#Images Variables
background = pygame.image.load('images/sfondo.png')
bird = pygame.image.load('images/uccello.png')
base = pygame.image.load('images/base.png')
gameover = pygame.image.load('images/gameover.png')
tube1 = pygame.image.load('images/tubo.png')
tube2 = pygame.transform.flip(tube1, False, True)
#Display Create
display = pygame.display.set_mode((288,512))
FPS = 60
#Define Functions
def draw_object():
display.blit(background, (0,0))
display.blit(bird, (birdx, birdy))
def display_update():
pygame.display.update()
pygame.time.Clock().tick(FPS)
def animations():
global birdx, birdy, bird_vely
birdx, birdy = 60, 150
bird_vely = 0
#Move Control
animations()
while True:
bird_vely += 1
birdy += bird_vely
for event in pygame.event.get():
if ( event.type == pygame.KEYDOWN
and event.key == pygame.K_UP):
bird_vely = -10
if event.type == pygame.QUIT:
pygame.quit()
draw_object()
display_update()
Well you do so by implementing below code snippet in your code:
running = True
while running:
# other code
event = pygame.event.wait ()
if event.type == pygame.QUIT:
running = False # Be interpreter friendly
pygame.quit()
Make sure that you call pygame.quit() before you exit your main function
You can also reference this thread
Pygame escape key to exit
You must terminate the application loop when the QUIT event occurs. You have implmented the QUIT event, but you don't terminate the loop. Add a variabel run = True and set run = False when the event occurs.
To terminate the game when ESC is pressed you have to implement the KEYDOWN event. Set run = False when the KEDOWN event occurs and event.key == pgame.K_ESC:
run = True
while run:
bird_vely += 1
birdy += bird_vely
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
if event.key == pgame.K_ESC:
run = False
elif event.key == pygame.K_UP:
bird_vely = -10
draw_object()
display_update()
pygame.quit()
exit()
This question already has an answer here:
Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?
(1 answer)
Closed 2 years ago.
In this I want the program to close when they hit the quit button but if I enable my Check_Key_Press() function, the Close() function does not work however If I comment out the Check_Key_Press() function then it works again.
import pygame
pygame.init()
width, height = 500,500
win = pygame.display.set_mode((width, height))
pygame.display.set_caption("Tic Tac Toe(GUI)")
clock = pygame.time.Clock()
white = (255,255,255)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
Tile_dime = 59
Diff = (Tile_dime+1)/2
board_det = [['-',(width/2-3*Diff,height/2-3*Diff)],['-',(width/2-Diff,height/2-3*Diff)],['-',(width/2+Diff,height/2-3*Diff)],
['-',(width/2-3*Diff,height/2-Diff)],['-',(width/2-Diff,height/2-Diff)],['-',(width/2+Diff,height/2-Diff)],
['-',(width/2-3*Diff,height/2+Diff)],['-',(width/2-Diff,height/2+Diff)],['-',(width/2+Diff,height/2+Diff)]]
def draw_board():
for i in range(len(board_det)):
pygame.draw.rect(win, white, [board_det[i][1], (Tile_dime, Tile_dime)])
def Close():
global run
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
def Check_Key_Press():
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
pass
if event.key == pygame.K_LEFT:
pass
run = True
while run:
clock.tick(60)
draw_board()
Check_Key_Press()
Close()
pygame.display.update()
pygame.event.get() get all the messages and remove them from the queue. If pygame.event.get () is called in multiple event loops, only one loop receives the events, but never all loops receive all events. As a result, some events appear to be missed.
Get the events once and use them in multiple loops or pass the list or events to functions and methods where they are handled:
def Close(event_list):
global run
for event in event_list:
if event.type == pygame.QUIT:
run = False
def Check_Key_Press(event_list):
for event in event_list:
if event.type == pygame.KEYDOWN:
pass
if event.key == pygame.K_LEFT:
pass
run = True
while run:
clock.tick(60)
event_list = pygame.event.get()
draw_board()
Check_Key_Press(event_list)
Close(event_list)
pygame.display.update()
While doing some game programming, I ran into a problem with the keyboard commands. In my code, I have a food bar and a money bank variable named money_bar. The food bar in my game would increase when I press a key, say f, in my game, and also the game deduct say $10 from my money_bar when I press f.
The food bar shows the current amount of food I have, which is supposed to decrease every second. However, it appears that none of my keyboard commands in the event() are working. May I know what is the problem in my code?
This is my food_bar and `money_bar initialisation:
def __init__(self):
pygame.init()
self.clock = pygame.time.Clock()
self.living = 1
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
self.time = pygame.time.get_ticks()
pygame.key.set_repeat(500, 100)
self.all_sprites = pygame.sprite.Group()
self.console = Console(self, 0)
self.player = Player(self, 390, 595)
self.work = Work(self, 450, 250)
self.food_station = Food_Station(self, 750, 200)
self.food = Food(self, 25, 20)
self.education = Education(self, 300, 10)
self.school = School(self, 100, 200)
self.family = Family(self, 600, 10)
self.money = Money(self, 800, 15)
initial_food = 100
self.food_bar = initial_food
initial_money = 0
self.money_bar = initial_money
initial_education = "Student"
self.education_level = initial_education
initial_family = 3
self.family_member = 3
This is where i run the main algorithm:
def run(self):
self.playing = True
self.hunger()
while self.playing:
self.dt = self.clock.tick(FPS) / 1000
self.events()
self.draw()
self.update()
and here's how i check for events(including keyboard commands)
def events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.quit()
if event.type == self.HUNGEREVENT:
self.food_bar = self.food_bar - 10
self.all_sprites.update()
pygame.display.flip()
if event.type == pygame.K_f:
self.money_bar = self.money_bar - 10
self.food_bar = self.food_bar + 15
self.all_sprites.update()
pygame.display.flip()
if event.type == pygame.K_ESCAPE:
self.quit()
Thanks in advance
While pygame.K_f is a key enumerator constant (see pygame.key) the content of event.type is event enumerator constant (see pygame.event).
If you want to determine if a certain key is pressed, the you've to verify if the event type is pygame.KEYDOWN (or pygame.KEYUP for button release) and if the .key attribute of the event is equal the key enumerator. e.g.:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.quit()
# [...]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_f:
# [...]
import pygame, os, sys
from pygame import *
pygame.init()
RED = ( 255, 0, 0)
class WPawn():
def __init__(self, x, y):
self.x = x
self.y = y
self.image = pygame.transform.scale(pygame.image.load('wpawn.png'), (100,100))
self.move_x = 0
self.move_y = 0
def event_handler(self):
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_UP:
self.move_y = -100
if event.key == K_DOWN:
self.move_y = 100
elif event.type == KEYUP:
if event.key in (K_UP, K_DOWN):
self.move_y = 0
def update(self, screen):
self.y = self.y + self.move_y
def draw(self, screen):
screen.blit(self.image, (self.x, self.y))
class Game():
def __init__(self):
screen_width = 900
screen_height = 900
self.screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption ("Chess Project")
self.pawn1 = WPawn(50,650)
self.pawn2 = WPawn(150,650)
self.pawn3 = WPawn(250,650)
self.pawn4 = WPawn(350,650)
self.pawn5 = WPawn(450,650)
self.pawn6 = WPawn(550,650)
self.pawn7 = WPawn(650,650)
self.pawn8 = WPawn(750,650)
def play(self):
clock = pygame.time.Clock()
RUNNING = True
while RUNNING:
for event in pygame.event.get():
if event.type == pygame.QUIT:
RUNNING = False
clock.tick(30)
self.pawn1.event_handler()
self.pawn2.event_handler()
self.pawn3.event_handler()
self.pawn4.event_handler()
self.pawn5.event_handler()
self.pawn6.event_handler()
self.pawn7.event_handler()
self.pawn8.event_handler()
self.pawn1.update(self.screen)
self.pawn2.update(self.screen)
self.pawn3.update(self.screen)
self.pawn4.update(self.screen)
self.pawn5.update(self.screen)
self.pawn6.update(self.screen)
self.pawn7.update(self.screen)
self.pawn8.update(self.screen)
self.screen.fill(RED)
self.pawn1.draw(self.screen)
self.pawn2.draw(self.screen)
self.pawn3.draw(self.screen)
self.pawn4.draw(self.screen)
self.pawn5.draw(self.screen)
self.pawn6.draw(self.screen)
self.pawn7.draw(self.screen)
self.pawn8.draw(self.screen)
pygame.display.update()
Game().play()
pygame.quit()
The KEY_UP event (or whatever) is consumed when you process it. So whichever WPawn class gets the event first will move.
Generally an event-driven program has only one event loop.
It may be easier to make this work by handling the event processing outside of the game objects. Have the single event loop handle record the key press, then move each WPawn that you wish to be moved.
Perhaps something like:
event = pygame.event.get()
if event.type == K_DOWN:
foreach pawn in all_pawns:
pawn.moveDown()
elif event.type == K_UP:
foreach pawn in all_pawns:
pawn.moveUp()