I have a simple project that display a "button" with an image,a text and a background color:
import os
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
import pygame, sys
from pygame.locals import *
import requests
import io
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
GRAY = (200, 200, 200)
class Main_window:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((800, 600))
def draw(self):
Btn1 = Button(0,0,200,200,"hello",color=RED, text="test",text_color=BLACK)
def mainLoop(self):
done = False
while not done:
eventlist = pygame.event.get()
for ev in eventlist:
if ev.type == QUIT:
done = True
if ev.type == MOUSEBUTTONDOWN:
Button.getButton(ev)
pygame.quit()
class Button:
Buttons = []
def __init__(self, left, top, w, h,function,color=RED, text="", text_color = BLACK):
self.left = left
self.top = top
self.w = w
self.h = h
self.right = self.left+w
self.bottom = self.top+h
self.function = function
surf1 = pygame.Surface((w, h))
surf1.fill(color)
rect1 = pygame.Rect(left, top, w, h)
main.screen.blit(surf1, rect1)
Button.Buttons.append(self)
if text != "":
font1 = pygame.font.SysFont('chalkduster.ttf', 72)
text1 = font1.render(text, True, text_color)
text_rect = text1.get_rect(center=(int(w/2), int(h/2)))
main.screen.blit(text1, text_rect)
image_url = "https://image.flaticon.com/icons/png/512/31/31990.png"
r = requests.get(image_url)
img = io.BytesIO(r.content)
image = pygame.image.load(img)
image = pygame.transform.scale(image, (w, h))
main.screen.blit(image, (0, 0))
pygame.display.flip()
def getButton(event):
for i in Button.Buttons:
x, y = event.pos
if x>=i.left and x<=i.right and y<=i.bottom and y>=i.top:
eval(i.function+"()")
def hello():
print("hello")
main = Main_window()
main.draw()
main.mainLoop()
that's works fine but the problem is that when i launch the game it load the main window, wait some time(something like 1 second) and then load the button.I tried to add more button and it loaded them one at a time.I don't undestand why.
Two Fixes
Use a local image rather than an image sent with requests
It loads slowly maybe because of the draw function of the MainWindow class.
Try this in the main loop function
def mainLoop(self):
done = False
while not done:
eventlist = pygame.event.get()
for ev in eventlist:
if ev.type == QUIT:
done = True
if ev.type == MOUSEBUTTONDOWN:
Button.getButton(ev)
self.draw()
pygame.display.flip()
pygame.quit()
And at the end
main = Main_window()
main.mainLoop()
So you don't have to call main.draw() because it is already being called in the main loop.
Related
Right now, my game blits all the images in random positions correctly and also gets the rect of the images correctly, but I can´t figure out how to use colliderect to make sure the images don´t overlap. How could it work for my code?
Also I´m trying to make the first text fade out and I don´t know why it doesn´t work for me.
Here is the code:
class GAME1:
def __init__(self, next_scene):
self.background = pygame.Surface(size)
# Create an array of images with their rect
self.images = []
self.rects = []
self.imagenes1_array = ['autobus.png','coche.png','barco.png','autobus2.png','grua.png','bici.png']
for i in self.imagenes1_array:
# We divide in variables so we can then get the rect of the whole Img (i2)
i2 = pygame.image.load(i)
self.images.append(i2)
s = pygame.Surface(i2.get_size())
r = s.get_rect()
# Trying to use colliderect so it doesnt overlap
if pygame.Rect.colliderect(r,r) == True:
x = random.randint(300,1000)
y = random.randint(200,700)
self.rects.append(r)
def start(self, gamestate):
self.gamestate = gamestate
for rect in self.rects:
# Give random coordinates (we limit the dimensions (x,y))
x = random.randint(300,1000)
y = random.randint(200,700)
rect.x = x
rect.y = y
def draw(self,screen):
self.background = pygame.Surface(size)
font = pygame.font.SysFont("comicsansms",70)
# First half (Show image to remember)
text1 = font.render('¡A recordar!',True, PURPLE)
text1_1 = text1.copy()
# This surface is used to adjust the alpha of the txt_surf.
alpha_surf = pygame.Surface(text1_1.get_size(), pygame.SRCALPHA)
alpha = 255 # The current alpha value of the surface.
if alpha > 0:
alpha = max(alpha-4, 0)
text1_1 = text1.copy()
alpha_surf.fill((255, 255, 255, alpha))
text1_1.blit(alpha_surf, (0,0), special_flags = pygame.BLEND_RGBA_MULT)
screen.blit(text1_1, (600,50))
# Second half (Show all similar images)
text2 = font.render('¿Cuál era el dibujo?',True, PURPLE)
#screen.blit(text2, (500,50))
for i in range(len(self.images)):
#colliding = pygame.Rect.collidelistall(self.rects)
screen.blit(self.images[i], (self.rects[i].x, self.rects[i].y))
def update(self, events, dt):
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
for rect in self.rects:
if rect.collidepoint(event.pos):
print('works!')
Use collidelist() to test test if one rectangle in a list intersects:
for i in self.imagenes1_array:
s = pygame.image.load(i)
self.images.append(s)
r = s.get_rect()
position_set = False
while not position_set:
r.x = random.randint(300,1000)
r.y = random.randint(200,700)
margin = 10
rl = [rect.inflate(margin*2, margin*2) for rect in self.rects]
if len(self.rects) == 0 or r.collidelist(rl) < 0:
self.rects.append(r)
position_set = True
See the minimal example, that uses the algorithm to generate random not overlapping rectangles:
import pygame
import random
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
def new_recs(rects):
rects.clear()
for _ in range(10):
r = pygame.Rect(0, 0, random.randint(30, 40), random.randint(30, 50))
position_set = False
while not position_set:
r.x = random.randint(10, 340)
r.y = random.randint(10, 340)
margin = 10
rl = [rect.inflate(margin*2, margin*2) for rect in rects]
if len(rects) == 0 or r.collidelist(rl) < 0:
rects.append(r)
position_set = True
rects = []
new_recs(rects)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
new_recs(rects)
window.fill(0)
for r in rects:
pygame.draw.rect(window, (255, 0, 0), r)
pygame.display.flip()
pygame.quit()
exit()
I am just playing around with pygame, and I came to an idea to make a coloring app. i made the painting part pretty easly, but now I want to be able to change the color, and for that I tought it would be a good idea to use tkinters colorchooser. I made this function for that:
def color():
c = colorchooser.askcolor()[0]
brush.image.fill(c) #brush is a sprite class and image is a surface
i have tried doing this in many ways such as:
def color():
c = colorchooser.askcolor()[0]
brush.image.fill((c[0], c[1], c[2]))
But it didnt work.
Here is my full code. It is probably really bad but I am somewhat new to this:
from pygame import *
from tkinter import colorchooser as cl
from sys import exit
init()
width, height = 1080, 1920
screen = display.set_mode((width, height))
clock = time.Clock()
background = Surface((width * 3, height + 200))
pos = (width / 2, height / 2)
speed = 10
outline = Surface((40, 40))
outline.fill('yellow')
outrect = outline.get_rect(center = pos)
fill = Surface((30, 30))
fill.fill('dark blue')
fillrect = fill.get_rect(center = pos)
button = Surface((150, 100))
button.fill('red')
buttrect = button.get_rect(topleft = (0, 0))
Cbutton = Surface((150, 100))
Cbutton.fill('white')
Cbuttrect = button.get_rect(topleft = (150, 0))
class Player(sprite.Sprite):
def __init__(self):
super().__init__()
self.image = Surface((50, 50))
self.image.fill('yellow')
self.rect = self.image.get_rect(center = (width / 2, height/2))
brush = Player()
brushGroup = sprite.Group()
brushGroup.add(brush)
def color():
c = cl.askcolor()[0]
brush.image.fill((c[0], c[1], c[2]))
while True:
for e in event.get():
if e.type == QUIT:
exit()
if e.type == MOUSEBUTTONDOWN or e.type == MOUSEMOTION:
pos1 = mouse.get_pos()
if buttrect.collidepoint(pos1):
brush.rect.center = (5000, 5000)
screen.blit(background, (0, 0))
elif Cbuttrect.collidepoint(pos1):
color()
brush.rect.center = pos1
brushGroup.draw(screen)
screen.blit(button, buttrect)
screen.blit(Cbutton, Cbuttrect)
display.update()
And here is the full error message(I am runing this on phone so that is why the path looks like it does):
Traceback (most recent call last):
File "/storage/emulated/0/python /game.py", line 62, in <module>
screen.blit(background, (0, 0))
File "/storage/emulated/0/python /game.py", line 48, in color
ps.add(p)
File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/tkinter/colorchooser.py", line 79, in askcolor
return Chooser(**options).show()
File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/tkinter/commondialog.py", line 42, in show
w = Frame(self.master)
File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/tkinter/__init__.py", line 3134, in __init__
Widget.__init__(self, master, 'frame', cnf, {}, extra)
File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/tkinter/__init__.py", line 2576, in __init__
BaseWidget._setup(self, master, cnf)
File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/tkinter/__init__.py", line 2543, in _setup
master = _get_default_root()
File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/tkinter/__init__.py", line 299, in _get_default_root
assert _default_root is root
AssertionError
If someone knows how I can make this work I would be very heppy. Thnks in advance!
I see two problems which can generate errors.
First:
If you close colorchooser.askcolor() without selecting color then it will return (None, None) and you will have color = (None, None)[0] and finally you use color = None and this can make problem.
You should check value
c = cl.askcolor()
if c[0]:
brush.image.fill(c[0])
Second:
When you first run colorchooser.askcolor() then automatically it creates main/root window because tkinter needs it.
If you close this window then next colorchooser.askcolor() will not create again main/root but it will raise error.
You should manually create root at start, and hide it - so you can't close it accidently.
import tkinter as tk
root = tk.Tk()
root.wm_withdraw()
Working code with other changes.
I use clock.tick(120) to reduce speed to 120 FPS (frames per second) and use less CPU. But it may make gaps in drawing line. Normally you should remeber previous position and draw line from previous position to current position (instead fo single rectangle/point)
import pygame as pg # PEP8: `import *` is not preferred
import tkinter as tk # to create main window manually
from tkinter import colorchooser as cl
from sys import exit
# --- classes --- # PEP8: `CamelCasenames` for class names
# PEP8: `nouns` for class names
class Player(pg.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pg.Surface((50, 50))
self.image.fill('yellow')
self.rect = self.image.get_rect(center=(width/2, height/2)) # PEP8: parameters without spaces around `=`
# --- functions --- # PEP8: `lower_case_names` for function names
# PEP8: `verbs` for function names
def select_color():
color = cl.askcolor()
print(color)
if color[0] is not None:
brush.image.fill(color[0])
# --- main --- # PEP8: `lower_case_names` for variables
width, height = 1080, 1920
speed = 10
# - tkinter -
root = tk.Tk()
#root.iconify()
root.wm_withdraw()
# - pygame -
pg.init()
screen = pg.display.set_mode((width, height))
screen_rect = screen.get_rect()
#pos = screen_rect.center # (width/2, height/2)
background = pg.Surface((width * 3, height + 200))
outline = pg.Surface((40, 40))
outline.fill('yellow')
outline_rect = outline.get_rect(center=screen_rect.center)
fill = pg.Surface((30, 30))
fill.fill('dark blue')
fill_rect = fill.get_rect(center=screen_rect.center)
button = pg.Surface((150, 100))
button.fill('red')
button_rect = button.get_rect(topleft=(0, 0))
c_button = pg.Surface((150, 100))
c_button.fill('white')
c_button_rect = button.get_rect(topleft=(150, 0))
brush = Player()
brush_group = pg.sprite.Group()
brush_group.add(brush)
clock = pg.time.Clock()
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit() # destroy pygame window
root.destroy() # destroy root window
exit()
#if event.type in (pg.MOUSEBUTTONDOWN, pg.MOUSEMOTION):
elif event.type == pg.MOUSEBUTTONDOWN:
if button_rect.collidepoint(event.pos):
brush.rect.center = (5000, 5000)
screen.blit(background, (0, 0))
elif c_button_rect.collidepoint(event.pos):
select_color()
elif event.type == pg.MOUSEMOTION:
brush.rect.center = event.pos
# - draw -
brush_group.draw(screen)
screen.blit(button, button_rect)
screen.blit(c_button, c_button_rect)
pg.display.update()
clock.tick(120) # reduce FPS to use less CPU
PEP 8 -- Style Guide for Python Code
Everything works fine until a .mp3 file is loaded with mixer.music.load(). After that, there are buttons on the window that I have created are still responsive, but the window itself is unresponsive. I cannot drag the window around, and I cannot use the x button to close the window. They don't highlight as if you could press them at all after the music is loaded. I know the main loop is still running because my buttons highlight when the mouse is colliding with them as they should. I just don't know why the window itself is not responding.
What is weird is I have a load button that opens a tkinter filedialog to get a directory, if I click on that and just close the filedialog, the pygame main window becomes responsive again like normal.
import os
import pygame as pg
import tkinter.filedialog
import tkinter
from pygame import mixer
pg.init()
WIDTH, HEIGHT = 500, 800
HW = WIDTH // 2
HH = HEIGHT // 2
win = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption("Music Player")
CLOCK = pg.time.Clock()
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
def play_song(directory, song_list):
mixer.init()
mixer.music.load(os.path.join(directory, song_list[0]))
pg.mixer.music.play()
def get_files(directory):
file_list = []
for entry in os.listdir(directory):
file = os.path.join(directory, entry)
ext = os.path.splitext(entry)[-1].lower()
if os.path.isfile(file) and ext == '.mp3': # adds only files, that are .mp3
file_list.append(entry)
return file_list
def get_directory():
tkinter.Tk().withdraw() # Without this a blank tkinter window will appear.
try:
directory = tkinter.filedialog.askdirectory() # This opens the file browser.
files_list = get_files(directory)
return directory, files_list
except FileNotFoundError:
return 0, []
class Button(object):
def __init__(self, pic, hover, click, x, y):
self.pic = pic
self.hover = hover
self.click = click
self.x = x
self.y = y
self.w = self.pic.get_width()
self.h = self.pic.get_height()
self.hw = self.w // 2
self.hh = self.h // 2
def collide(self, mouse_x, mouse_y):
if mouse_x > self.x and mouse_x < self.x + self.w:
if mouse_y > self.y and mouse_y < self.y + self.h:
return True
def draw(self, win1, clicked=False):
mouse_pos = pg.mouse.get_pos()
if clicked:
win1.blit(self.click, (self.x, self.y))
elif self.collide(mouse_pos[0], mouse_pos[1]):
win1.blit(self.hover, (self.x, self.y))
else:
win1.blit(self.pic, (self.x, self.y))
play_idle = pg.image.load('play.png')
play_hover = pg.image.load('play_hover.png')
play_click = pg.image.load('play_click.png')
play = Button(play_idle, play_hover, play_click, HW - 52, HEIGHT - 152)
pause_idle = pg.image.load('pause.png')
pause_hover = pg.image.load('pause_hover.png')
pause_click = pg.image.load('pause_click.png')
pause = Button(pause_idle, pause_hover, pause_click, HW - 52, HEIGHT - 152)
skip_idle = pg.image.load('skip.png')
skip_hover = pg.image.load('skip_hover.png')
skip_click = pg.image.load('skip_click.png')
skip = Button(skip_idle, skip_hover, skip_click, WIDTH - 152, HEIGHT - 152)
load_idle = pg.image.load('load.png')
load_hover = pg.image.load('load_hover.png')
load_click = pg.image.load('load_click.png')
load = Button(load_idle, load_hover, load_click, 50, 50)
def draw(win, clicked_play, clicked_load, playing):
win.fill(WHITE)
if playing:
pause.draw(win, clicked_play)
else:
play.draw(win, clicked_play)
skip.draw(win)
load.draw(win, clicked_load)
pg.display.update()
def main():
directory, song_list = '', []
CLOCK.tick(60)
run = True
while run:
clicked_play = False
clicked_load = False
loaded = False
playing = mixer.music.get_busy()
events = pg.event.get()
for event in events:
if event.type == pg.QUIT:
run = False
if event.type == pg.MOUSEBUTTONDOWN:
print('button down')
if event.button == 1:
mouse_pos = pg.mouse.get_pos()
if load.collide(mouse_pos[0], mouse_pos[1]):
# Pause music
clicked_load = True
draw(win, clicked_play, clicked_load, playing)
directory, song_list = get_directory()
if play.collide(mouse_pos[0], mouse_pos[1]) and not playing:
clicked_play = True
if len(song_list) > 0:
play_song(directory, song_list)
print('playing')
if pause.collide(mouse_pos[0], mouse_pos[1]) and playing:
clicked_play = False
pg.mixer.music.stop()
print('pause')
draw(win, clicked_play, clicked_load, playing)
pg.display.quit()
pg.quit()
main()
I found a solution. It was a threading issue. Thank you to #stovfl for pointing me in the right direction.
with concurrent.futures.ThreadPoolExecutor() as executor:
future = executor.submit(get_directory)
return_value = future.result()
get_directory is a function using tkinter.
I am starting to write a game but whenever I run my code it takes 2 minutes to boot up and even then some methods are not working. The main ones that's not working are quitting pygame and drawGameScene().
My code is:
import os, random
from pygame import *
init()
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" %(0, 20)
scalefactor = 2
FPS = 60
screenWidth = round(224 * scalefactor)
screenHeight = round(298 * scalefactor)
size = screenWidth, screenHeight
screen = display.set_mode(size)
button = 0
RED = (255, 0, 0)
BLUE = (0,0,255)
STATEGAME = 1
STATEQUIT = 3
curState = STATEGAME
titleFont = font.SysFont("Times New Roman",45)
def drawText(words, screen,position, color, font):
text = font.render(words, False, color)
textSize = text.get_size()
position[0] = position[0] - textSize[0]//2
position[1] = position[1] - textSize[1]//2
#centers the text
screen.blit(text,position)
def gameRun():
while curState != STATEQUIT:
if curState == STATEGAME:
drawGameScene()
eventCheck()
updater()
def eventCheck():
for evnt in event.get():
if evnt.type == QUIT:
curState == STATEQUIT
def updater():
pass
def drawGameScene():
draw.rect(screen,RED,(0,0,screenWidth,screenHeight))
drawText("High Score", screen, [0,0], BLUE, titleFont)
display.update
gameRun()
display.flip()
no error messages are given
Please Help, It's for a project
For the quitting pygame:
You should use the code as below:
for events in event.get():
if events.type == QUIT:
pygame.quit()
exit() #this is from sys module
This way, your pygame is quitted at the first place. So, you don't need anything about curstate, etc.
Also, you need to use while True statement to repeat the blitting process.
Full code:
import os, random
from pygame import *
from sys import exit
init()
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" %(0, 20)
scalefactor = 2
FPS = 60
screenWidth = round(224 * scalefactor)
screenHeight = round(298 * scalefactor)
size = screenWidth, screenHeight
screen = display.set_mode(size)
button = 0
RED = (255, 0, 0)
BLUE = (0,0,255)
titleFont = font.SysFont("Times New Roman",45)
def drawText(words,screen,position,color,font):
text = font.render(words, False, color)
textSize = text.get_size()
position[0] = position[0] - textSize[0]//2
position[1] = position[1] - textSize[1]//2
#centers the text
screen.blit(text,position)
def gameRun():
drawGameScene()
eventCheck()
updater()
def eventCheck():
for events in event.get():
if events.type == QUIT:
quit()
exit()
def updater():
pass
def drawGameScene():
draw.rect(screen,RED,(0,0,screenWidth,screenHeight))
drawText("High Score", screen, [0,0], BLUE, titleFont)
#display.update()
while True:
gameRun()
display.flip()
so i'm making a basic weather app using pygame and im having a problem with the gui
so all the code works fine but the window doesnt properly show
here is the code:
import ast, sys
import pygame
from pygame.locals import *
import inputbox
import get_info
class Weather():
def __init__(self):
self.zip = '99354'
self.get_info()
pygame.font.init()
self.state = 2
self.font = pygame.font.Font("resources\Sansation_Light.ttf", 16)
self.font_render()
self.bg = pygame.image.load('resources/background.png')
self.refresh = pygame.image.load('resources/button1.png')
self.refresh_r = self.refresh.get_bounding_rect()
self.refresh_r.x, self.refresh_r.y = (155,550)
self.chg_zip = pygame.image.load('resources/button2.png')
self.chg_zip_r = self.chg_zip.get_bounding_rect()
self.chg_zip_r.x, self.chg_zip_r.y = (20,135)
self.main()
def font_render(self):
self.current_img = pygame.image.load('resources/%s.png'%self.weather)
self.cur_temp = self.font.render(self.temp, 0, (255,255,255))
self.cur_weather = self.font.render(self.weather, 0, (255,255,255))
self.updated = self.font.render(self.update[0], 0, (255,255,255))
self.updated2 = self.font.render(self.update[2], 0, (255,255,255))
self.ref_text = self.font.render("Refresh", 0, (255,255,255))
self.zip_text = self.font.render("Change Zip", 0, (255,255,255))
def Draw(self):
self.screen.blit(self.bg,(0,0))
self.screen.blit(self.refresh,(155,550))
self.screen.blit(self.ref_text,(200,560))
self.screen.blit(self.chg_zip,(20,135))
self.screen.blit(self.zip_text,(40,140))
self.screen.blit(self.radar_img,(12,175))
self.screen.blit(self.updated,(100,500))
self.screen.blit(self.updated2,(175,525))
self.screen.blit(self.current_img,(20,20))
self.screen.blit(self.cur_temp,(150,50))
self.screen.blit(self.cur_weather,(150,70))
row = 25
for i in range(0,5):
stat_str = str(self.info[0][i][0])+' : '+ str(self.info[0][i][1])
self.cur_stats = self.font.render(stat_str, 0, (255,255,255))
self.screen.blit(self.cur_stats,(275,row))
row+=25
def button(self):
if self.refresh_r.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
self.get_info()
if self.chg_zip_r.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
self.state = 1
def get_zip(self):
self.screen.blit(self.bg,(0,0))
self.zip = inputbox.ask(self.screen,"Zipcode")
self.__init__()
self.screen.blit(self.bg,(0,0))
self.state = 2
def get_info(self):
get_info.get_info(self.zip)
print "done"
with open('info.txt','r') as info:
fore_info = info.read()
weather = ast.literal_eval(fore_info)
current = weather[0]
self.info = weather[1]
forecast = weather[2]
self.place = weather[3]
self.update = self.place.strip().split('.')
self.temp = current[0]
self.weather = current[1]
self.radar_img = pygame.image.load('radar.jpg')
def main(self):
clock = pygame.time.Clock()
self.screen = pygame.display.set_mode((475,600))
pygame.display.set_caption('Weather')
while True:
clock.tick(45)
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
if self.state == 1:
self.get_zip()
else:
self.Draw()
self.button()
Weather()
i know my code is very sloppy and not the best but it still works except when i run it this is what the window looks like:
it shows what ever is behind it until you drag another window over it or you min and max it then it shows what i should
so how should i change my code so that it pops up and shows properly
It's probably because you never call pygame.display.flip()