I am trying to follow a pygame tutorial and the pygame window keeps closing instantly after opening. I have tried multiple different snippets of code from various places and none seem to keep the window open. i am using VScode if that makes a difference,
import pygame
pygame.init()
WIDTH, HEIGHT= 900,500
WIN=pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("Rock Paper Scissors")
def main():
gameRunning = True
while gameRunning:
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("QUIT")
pygame.quit()
gameRunning = False
quit()
WIN.fill(0,0,0)
pygame.display.update()
if __name__=="__main__":
main()
pygame.Surface.fill has just a single argument, which is either a RGB sequence, a RGBA sequence or a mapped color index. e.g. a tuple with the RGB color components:
WIN.fill(0,0,0)
WIN.fill( (0,0,0) )
Related
I'm developing a grid based game in pygame, and want the window to be resizable. I accomplish this with the following init code:
pygame.display.set_mode((740, 440), pygame.RESIZABLE)
As well as the following in my event handler:
elif event.type == pygame.VIDEORESIZE:
game.screen = pygame.display.set_mode((event.w, event.h),
pygame.RESIZABLE)
# Code to re-size other important surfaces
The problem I'm having is that it seems a pygame.VIDEORESIZE event is only pushed once the user is done resizing the window, i.e. lets go of the border. screen.get_size() updates similarly. Since the graphics of my game are very simple, I'd really prefer for them to resize as the user drags the window. This is trivial in many other languages, but I can't find any reference for it in pygame - although I can't imagine a feature this basic would be impossible.
How can I update my game as the screen is being resized in pygame?
EDIT: Here is a minimal working example. Running on Windows 10, pygame 1.9.4, the following code will only draw the updated rectangle after the user finishes dragging the window.
import sys
import pygame
pygame.init()
size = 320, 240
black = 0, 0, 0
red = 255, 0, 0
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.VIDEORESIZE:
pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE)
screen.fill(black)
pygame.draw.rect(screen, red, (10,10,screen.get_width(),screen.get_height()))
pygame.display.flip()
If you run into this kind of problem, it's always worth to google it using SDL instead of pygame, since pygame is a pretty low-level SDL wrapper.
So that's not a problem of pygame itself, but rather how sdl and your window manager interact, e.g. see this SDL bug report.
Nonetheless, if you really need to update the window while resizing, if you're using Windows, you can listen for the actual WM_SIZE event of Windows, redraw your screen, and update the "Windows"-window by calling RedrawWindow.
Here's a simple example:
import pygame
import win32gui
import win32con
def wndProc(oldWndProc, draw_callback, hWnd, message, wParam, lParam):
if message == win32con.WM_SIZE:
draw_callback()
win32gui.RedrawWindow(hWnd, None, None, win32con.RDW_INVALIDATE | win32con.RDW_ERASE)
return win32gui.CallWindowProc(oldWndProc, hWnd, message, wParam, lParam)
def main():
pygame.init()
screen = pygame.display.set_mode((320, 240), pygame.RESIZABLE | pygame.DOUBLEBUF)
def draw_game():
screen.fill(pygame.Color('black'))
pygame.draw.rect(screen, pygame.Color('red'), pygame.Rect(0,0,screen.get_width(),screen.get_height()).inflate(-10, -10))
pygame.display.flip()
oldWndProc = win32gui.SetWindowLong(win32gui.GetForegroundWindow(), win32con.GWL_WNDPROC, lambda *args: wndProc(oldWndProc, draw_game, *args))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.VIDEORESIZE:
pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE| pygame.DOUBLEBUF)
draw_game()
if __name__ == '__main__':
main()
Default behaviour:
With RedrawWindow:
import pygame
pygame.init()
height=1000
width=600
screen = pygame.display.set_mode((height, width), pygame.RESIZABLE)
pygame.display.set_caption("𝕤𝕜𝕪")
screen.fill(color='#0093ad')
pygame.display.flip()
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
when I try to run this code, it will only fill the area that was already filled when it was minimized and will not fill the screen when I maximize the window.
This is due to the fact that fill simply changes the color values of the points specified in the fill (from 0,0 to current window x, current window y) it does not set the background color.
I wasn't able to find a way to have Pygame set the default window color
Neverless an easy and sometimes more usfull alternative is to just place the fill and flip functions in the loop, replacing the previous fills with a new correctly sized one.
that code would look a bit like
import pygame
pygame.init()
height=1000
width=600
screen = pygame.display.set_mode((height, width), pygame.RESIZABLE)
pygame.display.set_caption("𝕤𝕜𝕪")
run = True
while run:
screen.fill(color='#0093ad') #moved fill & flip inside the loop
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
I was practicing using the pygame package in python by making a graphics oriented game and in my game, I want to switch between multiple backgrounds as the user progresses through it. For the example I am posting, the first background will be a black screen with 5 statements on it and my second background will be a room. However, I am unable to figure this out because whenever I try to run the code, the game window doesn't show anything. I can post my code for the while loop below for further clarification.
while running:
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
first_line()
second_line()
third_line_1()
third_line_2()
fourth_line()
fifth_line()
sleep(10)
screen.blit(background_room, (0, 0))
pygame.display.update()
The way I would probably do it is something like
import pygame
from pygame.locals import *
class Backround:
FIVE_STATEMENTS = 0
ROOM = 1
viewport_size = (800, 600)
def main():
pygame.init()
screen = pygame.display.set_mode(viewport_size)
backround_room = pygame.Surface(viewport_size)
# load the image...
backround_statements = pygame.Surface(viewport_size)
backround_statements.fill((0, 0, 0))
# blit the five statements onto here
backround_to_render = Backround.FIVE_STATEMENTS
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
if backround_to_render == Backround.FIVE_STATEMENTS:
# if the statements ever change, probably want to fill() and re-blit them on
screen.blit(backround_statements, (0,0))
elif backround_to_render == Backround.ROOM:
screen.blit(backround_room, (0,0))
else:
print("Oh no!!!!!!!")
pygame.display.flip()
if __name__ == "__main__":
main()
I've got this code:
import pygame, sys
from pygame.locals import *
pygame.init()
WHITE = (255,255,255)
class setup():
def set_resolution(x, y):
global surf
global screen
surf = pygame.Surface((x,y))
screen = pygame.display.set_mode((x,y))
pygame.display.set_caption("Lewis' Game")
pygame.draw.rect(screen, WHITE,(200,150,150,50))
def menu():
pass
setup.set_resolution(1024,768)
setup.menu()
while True:
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
For some reason, the pygame.draw.rect(screen, WHITE,(200,150,150,50)) at the end of the setup function doesn't actually appear unless I show the desktop and them tab back in. I'm not sure why this is happening as it's never happened before. I should mention that I'm still learning pygame, and this code is just for practice.
Many thanks in advance.
change your while loop to include this:
while True:
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
pygame.display.flip() # pygame.display.update works as well
if you want more on the difference of these, see Difference between pygame.display.update and pygame.display.flip
This may seem like a really easy question to answer, but I'm just a beginner in need of quick help.
I'm trying to create a program that when you click somewhere on the pyGame window, it'll print out that you hit it with the left button on the mouse, and also print out co-ordinates of where it was pressed. I've got this already. I'm having problems with making it plot the pixel on the pyGame window. Basically, I want it to draw a pixel where I pressed down on the pyGame window.
#!/usr/bin/env python
#import the module for use
import pygame
#setting up some variables
running = 1
LEFT = 1
#Set up the graphics area/screen
screen=pygame.display.set_mode((640,400))
#continuous loop to keep the graphics running
while running==1:
event=pygame.event.poll()
if event.type==pygame.QUIT:
running=0
pygame.quit()
elif event.type==pygame.MOUSEBUTTONDOWN and event.button==LEFT:
print "You pressed the left mouse button at (%d,%d)" %event.pos
elif event.type==pygame.MOUSEBUTTONUP and event.button==LEFT:
print "You released the left mouse button at (%d,%d)" %event.pos
Try setting the color of each pixel when you receive the mouse down event.
elif event.type==pygame.MOUSEBUTTONDOWN and event.button==LEFT:
print "You pressed the left mouse button at (%d,%d)" %event.pos
screen.set_at((event.pos.x, event.pos.y), pygame.Color(255,0,0,255))
Note that this will temporarily lock and unlock the Surface as needed.
I edited Aesthete's code to a working standalone example:
Depending what you are doing, get/setting individual pixels can be slow. ( There is Surfarray and Pixelarray if you need to. )
import pygame
from pygame.locals import *
class Game(object):
done = False
def __init__(self, width=640, height=480):
pygame.init()
self.width, self.height = width, height
self.screen = pygame.display.set_mode((width, height))
# start with empty screen, since we modify it every mouseclick
self.screen.fill(Color("gray50"))
def main_loop(self):
while not self.done:
# events
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT: self.done = True
elif event.type == KEYDOWN:
if event.key == K_ESCAPE: self.done = True
elif event.type == MOUSEMOTION:
pass
elif event.type == MOUSEBUTTONDOWN and event.button == 1:
print "Click: ({})".format(event.pos)
self.screen.set_at(event.pos, Color("white"))
# draw
pygame.display.flip()
if __name__ == "__main__":
g = Game()
g.main_loop()