Pygame wait for screen to update - python

I just started with pygame, and I am just trying to move points across my screen. The problem is that it happens way to fast and my pygame screen freezes (Not Responding) while the loop runs and then only shows the last iterations position of dots.
I am thinking the updating happens to fast.
When I include pygame.event.wait() then as I give an input the loop progresses and I can follow live in the window how the dots are moving across the screen. However, I would like to have it that they move across the screen without an input required.
This is my main loop:
def run(self):
self.food_spread()
self.spawn_animal()
for k in range(20000):
print(k)
for member in self.zoo:
self.move(member)
self.screen.fill(black)
for i in range(self.food_locations.shape[0]):
pygame.draw.rect(self.screen, white, (self.food_locations[i,1], self.food_locations[i,2],1,1))
for member in self.zoo:
pygame.draw.circle(self.screen, green,(member.location[0], member.location[1]), 2,1)
pygame.display.update()
pygame.event.wait()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

You have an application loop, use if. Use pygame.time.Clock() to control the framerate . The application loop has to
control the framerate (clock.tick(60))
handel the events and move the objects
clear the display
draw the scene
update the display
e.g:
class App:
def __init__(self):
# [...]
self.clock = pygame.time.Clock()
def run(self):
self.food_spread()
self.spawn_animal()
run = True
while run:
# control the framerate
self.clock.tick(60) # 60 FPS
# handel the events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# move the objects
for member in self.zoo:
self.move(member)
# clear the display
self.screen.fill(black)
# draw the scene
for i in range(self.food_locations.shape[0]):
pygame.draw.rect(self.screen, white, (self.food_locations[i,1], self.food_locations[i,2],1,1))
for member in self.zoo:
pygame.draw.circle(self.screen, green,(member.location[0], member.location[1]), 2,1)
# update the display
pygame.display.update()

Related

My program will run, but the K_RIGHT command will not work

The screen pops up with the green rectangle but I can't move it.
I don't understand why it won't work. any help would be highly appreciated!
import pygame
pygame.init()
width=1800
height=900
red=(255,0,0)
green=(0,255,0)
blue=(0,0,255)
white=(0,0,0)
black=(255,255,255)
x=800
y=150
running = True
def main():
global running, screen, x, y
screen = pygame.display.set_mode((width,height))
pygame.draw.rect(screen, green,(x,y,100,300))
pygame.display.update()
while running:
ev = pygame.event.get()
for event in ev:
if event.type==pygame.KEYDOWN:
if event.type==pygame.K_RIGHT:
x+=20
pygame.display.update()
if event.type==pygame.QUIT:
pygame.quit()
exit()
pygame.display.update()
main()
You have to draw the object in the application not just before the application loop. See My program will run, but the K_RIGHT command will not work:
import pygame
pygame.init()
width, height = 1800, 900
x, y = 800, 150
def main():
global running, screen, x, y
screen = pygame.display.set_mode((width,height))
clock = pygame.time.Clock()
running = True
while running:
clock.tick(100)
ev = pygame.event.get()
for event in ev:
if event.type==pygame.QUIT:
running = False
if event.type==pygame.KEYDOWN:
if event.type==pygame.K_RIGHT:
x+=20
screen.fill("black")
pygame.draw.rect(screen, "green", (x,y,100,300))
pygame.display.update()
pygame.quit()
exit()
main()
The typical PyGame application loop has to:
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()
limit frames per second to limit CPU usage with pygame.time.Clock.tick

How to make the pygame mouse continue to return events using the pygame event loop

I would like to know how to make it so that when you hold down the pygame mouse, it continues getting events in the event loop.
I do not want to use pygame.mouse.get_pressed() because I want to also have a hold-down time to where it doesn't do anything.
Kind of like if you hold down a key in a text box in your browser: it types one key, then waits for about half a second, then starts typing a lot of keys really fast.
Also, I think it involves something before the main loop when the window is created or something, but I'm not sure.
I know there's a way to do this in pygame because I saw a Stack Overflow answer to it before, but after a while of searching, I cannot find it. If you have seen it or can find it, that is also appreciated too. This is my first time asking a question, so if I did anything wrong, please tell me.
Here is the code:
import pygame
WIDTH = 1000
HEIGHT = 800
WIN = pygame.display.set_mode()
def main():
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
print("the mouse was pressed")
WIN.fill((0, 0, 0))
pygame.display.update()
I would like to know how to make it so that when you hold down the pygame mouse, it continues getting events in the event loop.
Yo can't. However you can use pygame.mouse.get_pressed():
import pygame
WIDTH = 1000
HEIGHT = 800
WIN = pygame.display.set_mode()
def main():
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
buttons = pygame.mouse.get_pressed()
if any(buttons):
print("the mouse was pressed")
WIN.fill((0, 0, 0))
pygame.display.update()
The MOUSEBUTTONDOWN event occurs once when you click the mouse button and the MOUSEBUTTONUP event occurs once when the mouse button is released.
pygame.mouse.get_pressed() returns a list of Boolean values ​​that represent the current state (True or False) of all mouse buttons. The state of a button is True as long as a button is held down.

Doing something after a period of time: Pygame

I wanted to do something after a period of time. On stack overflow I found a question that helps solve that, (Link) but when I run the program the code works, however it goes away after a millisecond. Whereas I want it to stay there after the amount of time I want it to wait. In this case for a test run I am blitting some text onto the screen. Here is the code:
import pygame
# Importing the modules module.
pygame.init()
# Initializes Pygame
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((800, 600))
# Sets the screen to pygame looks and not normal python looks.
pygame.display.set_caption("Test Run")
# Changes the title
# Heading
headingfont = pygame.font.Font('Bouncy-PERSONAL_USE_ONLY.otf', 45)
headingX = 230
headingY = 10
class Other():
def show_heading():
Heading = headingfont.render("Health Run!", True, (255, 255, 255))
screen.blit(Heading, (headingX, headingY))
pygame.time.set_timer(pygame.USEREVENT, 100)
running = True
while running:
screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.USEREVENT:
Other.show_heading()
#Update Display
pygame.display.update()
If you want to draw the text permanently, you need to draw it in the application loop. Set a Boolean variable "draw_text" when the timer event occurs. Draw the text depending on draw_text in the application loop:
draw_text = False
running = True
while running:
screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.USEREVENT:
draw_text = True
if draw_text:
Other.show_heading()
#Update Display
pygame.display.update()
For more information about timers and timer events, see Spawning multiple instances of the same object concurrently in python, How can I show explosion image when collision happens? or Adding a particle effect to my clicker game and many more.

Pygame window opening and closing immediately

So when I set
while not game_over = False
, my window opens properly, but the text doesn't show. Whereas if I set it to True, the text shows but window closes immediately.
Here's the code:
***#Write a Python program to create a simple math quiz.
#Importing libraries
import pygame
import sys
import math
from pygame.locals import *
#Initialising fonts
pygame.init()
pygame.font.init()
#Assigning variables
WIDTH = 600
HEIGHT = 600
#Other important things
background_color = (127,255,0)
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
pygame.display.set_caption("Math Game")
screen.fill(background_color)
pygame.display.flip()
font = pygame.font.Font("freesansbold.ttf", 40)
textX=10
textY=10
def show_text(x,y):
text=font.render("Math Game", True, (0,0,0))
screen.blit(text,(x,y))
"""
#Adding the Calculator bit
x = input("Enter Your First Nummber To Add: ")
y = input("Enter Your Second Number To Add: ")
z = str(int(x)+int(y))
print(z)
"""
#Game loop
game_over = True
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
show_text(textX, textY)
pygame.display.update()***
It is a matter of Indentation. show_text and pygame.display.update() must be called in the application loop instead of after the application loop.
Additionally you should clear the display in the application loop.
game_over = False
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# INDENTATION
#-->|
screen.fill(background_color)
show_text(textX, textY)
pygame.display.update()
The typical PyGame application loop has to:
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()
limit the frames per second to limit CPU usage with pygame.time.Clock.tick

Syntax Error When Following Pygame/Python Tutorial on youtube

I've just downloaded python 3.3.2 and pygame-1.9.2a0.win32-py3.3.msi.
I have decided to try a few tutorials on youtube and see if they work.
I have tried thenewboston's 'Game Development Tutorial - 2 - Basic Pygame Program' to see if it works. It is supposed to produce a black background and a ball that is the mouse (or so i think). It comes up with a syntax error when i try to run it, if i delete it it just produces a black pygame window. Here is the code:
bgg="bg.jpg"
ball="ball.png"
import pygame, sys
from pygame.locals import *
pygame.init()
screen=pygame.display.set_mode((540,341),0,32)
background=pygame.image.load(bgg).convert()
mouse_c=pygame.image.load(ball).convert_alpha()
while True:
for event in pygame.event.get():
if event.type ==QUIT:
pygame.quit()
sys.exit()
screen.blit(background), (0,0))
The screen.blit(bakcgorund, (0,0)) command is the problem, when it comes up with the syntax error it highlights the second bracket on the furthest right of the command. If I delete it it just shows a black pygame window. can anyone help me?
I updated your code:
import pygame
from pygame.locals import *
#about: pygame boilerplate
class GameMain():
# handles intialization of game and graphics, as well as game loop
done = False
def __init__(self, width=800, height=600):
"""Initialize PyGame window.
variables:
width, height = screen width, height
screen = main video surface, to draw on
fps_max = framerate limit to the max fps
limit_fps = boolean toggles capping FPS, to share cpu, or let it run free.
now = current time in Milliseconds. ( 1000ms = 1second)
"""
pygame.init()
# save w, h, and screen
self.width, self.height = width, height
self.screen = pygame.display.set_mode(( self.width, self.height ))
pygame.display.set_caption( "pygame tutorial code" )
self.sprite_bg = pygame.image.load("bg.jpg").convert()
self.sprite_ball = pygame.image.load("ball.png").convert_alpha()
def main_loop(self):
"""Game() main loop."""
while not self.done:
self.handle_events()
self.update()
self.draw()
def draw(self):
"""draw screen"""
self.screen.fill(Color('darkgrey'))
# draw your stuff here. sprites, gui, etc....
self.screen.blit(self.sprite_bg, (0,0))
self.screen.blit(self.sprite_ball, (100,100))
pygame.display.flip()
def update(self):
"""physics/move guys."""
pass
def handle_events(self):
"""handle events: keyboard, mouse, etc."""
events = pygame.event.get()
kmods = pygame.key.get_mods()
for event in events:
if event.type == pygame.QUIT:
self.done = True
# event: keydown
elif event.type == KEYDOWN:
if event.key == K_ESCAPE: self.done = True
if __name__ == "__main__":
game = GameMain()
game.main_loop()
Your parenthesis are unbalanced; there are 2 opening parenthesis, and 3 closing parenthesis; that is one closing parenthesis too many:
screen.blit(background), (0,0))
# -----^ ------^ ---^
You probably want to remove the closing parenthesis after background:
screen.blit(background, (0,0))

Categories

Resources