I am quite new to Python and currently trying to make my first game with Pygame. I just started and got a problem. My screen is flickering white (fill colour) to black. I tried to lower the tick (even to 1), but it didn't help (actually, it was flickering less, but still visible a lot). I tried to find any help online, but everywhere "display.update / flip used more than once per cycle" was suggested as a problem and it didn't fix mine.
I am currently running a Fedora 20 box, with Nvidia graphic card (and nouveau drivers), if the issue is connected with this.
My code:
import pygame
from pygame.locals import *
class visualisation(object):
def __init__(self):
pygame.init()
pygame.time.Clock().tick()
self.window = pygame.display.set_mode((0, 0), pygame.FULLSCREEN, 0)
pygame.mouse.set_visible(False)
pygame.display.set_caption('MY GAME')
self.background = pygame.Surface(self.window.get_size())
self.background = self.background.convert()
self.background.fill((250, 250, 250))
self.window.blit(self.background, (0, 0))
pygame.display.update()
if __name__ == '__main__':
running = True
while(running):
arcade = visualisation()
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
pygame.quit()
Thanks a lot in advance :)
You are calling the following functions in a loop:
pygame.init()
pygame.display.set_mode((0, 0), pygame.FULLSCREEN, 0)
If I am not mistaken this creates a new screen variable which is very bad.
You probably wanted to create a new arcade at the start of the game, instead of on each frame.
Try moving it before the loop:
running = True
arcade = visualisation()
while(running):
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
Related
I tried to use python to display image:
import pygame
win = pygame.display.set_mode((500, 500))
DisplayImage("Prologue.jpg", win)
And when it runs, nothing happened. It also happened for
DisplayImage("Streets.jpg", win)
However, when I tried the exact same thing later on in the code, it ran perfectly.
I checked, the picture was in the same folder as the .py file, and I didn't type the name wrong.
The function is:
def DisplayImage(imageName, screen):
screen.fill((0, 0, 0))
Image = pygame.image.load(imageName).convert()
screen_rect = screen.get_rect()
Image_rect = Image.get_rect().fit(screen_rect)
Image = pygame.transform.scale(Image, Image_rect.size)
screen.blit(Image, [0, 0])
pygame.display.update()
Update:
I commented out all of the lines and copy and pasted that line out so it's the only line that runs. It runs perfectly.
Update 2:
Found the issue. The reason it doesn't work was that the pygame window was "not responding". I don't know what caused it to not respond, but in one of the test runs I didn't make it show "not responding", and the images were loaded fine. The "not responding" always shows up when I type in my player name, and the function looks like this:
def createName():
playerName = input("Enter the player name\n")
desiredName = input("Is "+playerName+" the desired name?[1]Yes/[2]No\n")
if desiredName == "1":
return playerName
elif desiredName == "2":
playerName = createName()
Sometimes when I type the player name nothing happens, and the letters only show up after a while. If this happens, the pygame window is bound to not respond.
You cannot use input in the application loop. input waits for an input. While the system is waiting for input, the application loop will halt and the game will not respond.
Use the KEYDOWN event instead of input:
run = True
while run:
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if pygame.key == pygame.K_1:
# [...]
if pygame.key == pygame.K_2:
# [...]
Another option is to get the input in a separate thread.
Minimal example:
import pygame
import threading
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
color = "red"
def get_input():
global color
color = input('enter color (e.g. blue): ')
input_thread = threading.Thread(target=get_input)
input_thread.start()
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window_center = window.get_rect().center
window.fill(0)
pygame.draw.circle(window, color, window_center, 100)
pygame.display.flip()
pygame.quit()
exit()
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)
so Ive been trying to find a way to store multiple click x and y's with no luck, Ive worked with pygame and opencv but I cannot find a way to store multiple x and y's without deleting the previous set.
import pygame
pygame.init()
while True:
for e in pygame.event.get():
if e.type == pygame.MOUSEBUTTONDOWN:
print (pygame.mouse.get_pos())
Just append the event.pos or pygame.mouse.get_pos() to a list or collections.deque if the size should be limited.
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
clicks = []
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.MOUSEBUTTONDOWN:
clicks.append(event.pos)
print(clicks)
screen.fill((30, 30, 30))
pg.display.flip()
clock.tick(30)
pg.quit()
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.
Hello i'm trying to make a simple program to change the background colour on key press but it just crashes. It's to do with my loop but i don't really understand why it crashes.
thanks
import sys, pygame, random, time
from threading import Thread
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
green = (0, 100, 0)
red = (255, 0, 0)
Colour = (0,0,0)
size = width, height = 350, 350
screen = pygame.display.set_mode(size)
Running = True
while True:
key = pygame.key.get_pressed()
if key[pygame.K_ESCAPE]: # Escape key
Running = False
elif key[pygame.K_DOWN]: # down key
print("down")
Colour = red
elif key[pygame.K_UP]: # up key
print("h")
Colour = black
elif key[pygame.K_RIGHT]: # right key
Colour = green
print("h")
elif key[pygame.K_LEFT]: # left key
Colour = white
print("h")
pygame.draw.rect(screen, Colour, pygame.Rect(0, 0, width, height))
pygame.display.update()
pygame.display.flip()
You're missing a way for pygame to know if you want to quit the window. Instead of doing key = pygame.key.get_pressed() use:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit
if event.key == K_UP:
Colour = black
if event.key == K_DOWN:
Colour = red
if event.key == K_LEFT:
Colour = white
if event.key == K_RIGHT:
Colour = green
You also need a way for the program to handle time e.g. not run faster than you can see. You can do this by setting this variable at the top of your code:
clock = pygame.time.Clock()
and running this at the very end of your while loop:
clock.tick(FPS)
where you set the FPS as a number equal to the desired frames per second.
You can also remove your Running = True variable from the program. That should be all you need to get it running. Good luck! Ask questions below.
Two things:
You have a bug: the while loop while go forever because you are testing while True instead of while Running. You could change to while Running or after testing for escape key, you could break to exit the while loop.
Also, all pygame examples I have looked up just now have an event checker. Without that, pygame freezes. If you add it, everything is smooth.
Here are both of those corrected:
import sys, pygame, time
pygame.init()
size = 350, 350
screen = pygame.display.set_mode(size)
Running = True
while Running: # <----- changed this from True to Running
time.sleep(0.03) # avoid blasting the CPU. I think pygame.time.Clock also exists
# this makes pygame responsive
for event in pygame.event.get():
if event.type == pygame.QUIT:
Running = False # <---- or you could just break
# from here is as you originally wrote
key = pygame.key.get_pressed()
if key[pygame.K_ESCAPE]:
print('exit')
Running = False # <---- or you could just break
pygame.quit()
sys.exit()