I am making a game in pygame, but the display doesn't update. I am using the update() function and am clearing the screen at the beginning of the loop with fill(). Pygame also does not load very quickly; I have to hit "quit" on the pygame application once it shows in the running applications on my mac for the screen to appear.
"Module Imports"
import pygame as pg
import shelve
"Import Classes"
from Settings import Settings
from Settings import Screen
from Settings import Save
from Random import Random
from Input import Input
from Input import Button
# Init Classes
Settings = Settings()
Screen = Screen()
Random = Random()
Save = Save()
on = True
pg.init()
event_const = pg.event.wait()
save_file = shelve.open("/Volumes/HISTORYGAME/Game_Saves/Save_File")
clock = pg.time.Clock()
MainDisplay = pg.display.set_mode((Screen.width, Screen.height))
pg.display.set_caption(Settings.title)
pg.display.init()
class Mouse:
def __init__(self):
self.left = False
self.right = False
Mouse = Mouse()
def begin_game():
players = []
num_players = input("How Many Players (enter int): ")
save_file["num_players_var"] = num_players
for pl in range(num_players):
players.append(raw_input("Enter Player Name: "))
save_file["players_var"] = players
print(players)
def intro():
intro = True
for event in pg.event.get():
if event.get == pg.QUIT:
intro = False
on = False
if event.get == pg.event.KEYDOWN:
pass
# begin_game()
test_button = Button(0, 0, 200, 200, "Enter Text Here", MainDisplay)
buttons = []
buttons.append(test_button)
loops = 0
test_x = 10
test_y = 10
while on:
MainDisplay.fill((0, 0, 0))
for event in pg.event.get():
if event.type == pg.QUIT:
On = False
pg.quit()
exit()
if event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
On = False
pg.quit()
exit()
if event.key == pg.K_RIGHT:
test_x += 10
print("right")
if event.type == pg.MOUSEBUTTONDOWN:
if event.button == 1:
Mouse.left = True
else:
Mouse.left = False
if event.type == pg.MOUSEBUTTONUP:
if event.button == 1:
Mouse.left = False
for button in buttons:
button.draw(pg.mouse.get_pos(), event_const)
if button.clicked is True:
print("True \n" * 100)
pg.draw.line(MainDisplay, (255, 0, 0), (100, 100), (600, 600))
pg.draw.rect(MainDisplay, (255, 0, 0), (test_x, test_y, 20, 20))
pg.display.flip()
pg.display.update()
clock.tick(Settings.FPS)
loops += 1
print(str(loops))
I suspect the waiting for an event, or reading of the stdin with input() is causing a lockup issue. But in the presented code, the call to this is commented-out. It's not possible to really know.
This version of the code, with a re-created Button class works ok, but obviously it doesn't have any of the referenced classes.
"Module Imports"
import pygame
#import shelve
"Import Classes"
#from Settings import Settings
#from Settings import Screen
#from Settings import Save
#from Random import Random
#from Input import Input
#from Input import Button
# Init Classes
#Settings = Settings()
#Screen = Screen()
#Random = Random()
#Save = Save()
WINDOW_WIDTH = 600
WINDOW_HEIGHT = 600
class Mouse:
def __init__(self):
self.left = False
self.right = False
class Button:
def __init__( self, x, y, width, height, label, window ):
self.rect = pygame.Rect( x, y, width, height )
self.clicked = False
self.window = window
self.font = pygame.font.Font( None, 20 )
self.label = self.font.render( label, True, ( 255, 255, 255 ) ) # large white text
def draw( self, mouse_pos ):
if ( self.rect.collidepoint( mouse_pos ) ):
colour = ( 0, 200, 0 ) # green if mouse over
else:
colour = (0, 0, 200) # blue otherwise
pygame.draw.rect( self.window, colour, self.rect, 0 ) # filled rectangle
# centred text
label_rect = self.label.get_rect()
x_offset = ( self.rect.width - label_rect.width ) // 2
y_offset = ( self.rect.height - label_rect.height ) // 2
self.window.blit( self.label, ( x_offset, y_offset ) )
def checkClick( self, mouse_pos ):
if ( self.rect.collidepoint( mouse_pos ) ):
self.clicked = True
else:
self.clicked = False
def begin_game():
players = [ "Mork", "Mindy", "E.T." ] # test data
#players = []
#num_players = input("How Many Players (enter int): ")
#save_file["num_players_var"] = num_players
#for pl in range(num_players):
# players.append(raw_input("Enter Player Name: "))
#save_file["players_var"] = players
print(players)
# Initialisation
pygame.init()
pygame.font.init()
#event_const = pygame.event.wait()
#save_file = shelve.open("/Volumes/HISTORYGAME/Game_Saves/Save_File")
clock = pygame.time.Clock()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ) )
pygame.display.set_caption( "Settings.title" )
pygame.display.init()
Mouse = Mouse()
begin_game()
test_button = Button(0, 0, 200, 200, "Enter Text Here", window)
buttons = []
buttons.append(test_button)
loops = 0
test_x = 10
test_y = 10
on = True
while on:
window.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
on = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
on = False
elif event.key == pygame.K_RIGHT:
test_x += 10
print("right")
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
Mouse.left = True
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
Mouse.left = False
for button in buttons:
button.checkClick( event.pos ) # buttons actuate on mouse-up
for button in buttons:
button.draw( pygame.mouse.get_pos() ) #, event_const)
if button.clicked is True:
print("True \n" * 5) # 100
pygame.draw.line(window, (255, 0, 0), (100, 100), (600, 600))
pygame.draw.rect(window, (255, 0, 0), (test_x, test_y, 20, 20))
pygame.display.flip()
#pygame.display.update() # only need update() or flip()
clock.tick( 60 ) #Settings.FPS)
loops += 1
#print(str(loops)) # Too noisy
# exiting
pygame.quit()
Related
I am having an issue with PyGame i can't resolve. So:
my idea is that I have a map I can zoom in/out on. zooming in works fine. But zooming out shows that the rest of the picture got deleted and only the part of the image that was previously visible on the window exists now.
This is my code:
import pygame
from pygame.locals import *
import os
class App:
def __init__(self):
self.running = True
self.size = (800,600)
#create window
self.window = pygame.display.set_mode(self.size, pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
#create map
currentdir = os.path.dirname(os.path.realpath(__file__))
imagedir = currentdir+'/images/europe.png'
self.map = pygame.image.load(imagedir)
self.maprect = self.map.get_rect()
self.mapsurface = pygame.Surface(self.size)
self.mapsurface.blit(pygame.transform.scale(self.map,(self.size)),(0,0))
self.window.blit(self.mapsurface,(0,0))
self.scale = 1
#create window
pygame.display.flip()
def on_init(self):
self.country = Country()
def on_cleanup(self):
pygame.quit()
def check_event(self,event):
if event.type == pygame.QUIT:
self.running = False
elif event.type == pygame.VIDEORESIZE:
self.window = pygame.display.set_mode(event.dict['size'], pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
self.window.blit(pygame.transform.scale(self.map,(event.dict['size'])),(0,0))
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4:
zoom = 2
wnd_w,wnd_h = self.window.get_size()
zoom_size = (round(wnd_w/zoom), round(wnd_h/zoom))
zoom_area = pygame.Rect(0,0, *zoom_size)
pos_x,pos_y = pygame.mouse.get_pos()
zoom_area.center = (pos_x, pos_y)
zoom_surf = pygame.Surface(zoom_area.size)
zoom_surf.blit(self.window, (0, 0), zoom_area)
zoom_surf = pygame.transform.smoothscale(zoom_surf, (wnd_w, wnd_h))
self.window.blit(zoom_surf, (0, 0))
elif event.button == 5:
zoom = 0.5
wnd_w,wnd_h = self.window.get_size()
zoom_size = (round(wnd_w/zoom), round(wnd_h/zoom))
zoom_area = pygame.Rect(0,0,*zoom_size)
pos_x,pos_y = pygame.mouse.get_pos()
zoom_area.center = (pos_x, pos_y)
zoom_surf = pygame.Surface(zoom_area.size)
zoom_surf.blit(self.window, (0, 0), zoom_area)
zoom_surf = pygame.transform.smoothscale(zoom_surf, (wnd_w, wnd_h))
self.window.blit(zoom_surf, (0, 0))
pygame.display.flip()
pygame.display.update()
def on_execute(self):
while self.running == True:
for event in pygame.event.get():
self.check_event(event)
self.on_cleanup()
class Country(App):
def __init__(self):
super().__init__()
start = App()
start.on_init()
start.on_execute()
Here are the screenshots of my problem:
so far so good:
zooming in works fine:
zooming out causes this:
You'll need to scale and blit the original image when you zoom. Use the attribute maprect to define the scaled size and relative location of the map. Add a method blit map that can scale and blit the map. Use the method in the constructor of the class App:
class App:
def __init__(self):
# [...]
self.map = pygame.image.load(imagedir)
self.maprect = self.map.get_rect(center = self.window.get_rect().center)
self.blitmap()
#create window
pygame.display.flip()
def blitmap(self):
self.mapsurface = pygame.transform.smoothscale(self.map, self.maprect.size)
self.window.fill(0)
self.window.blit(self.mapsurface, self.maprect)
# [...]
When the image is zoomed, calculate the new mapping rectangle (self.maprect) and call the method again:
class App:
# [...]
def check_event(self,event):
if event.type == pygame.QUIT:
self.running = False
elif event.type == pygame.VIDEORESIZE:
self.window = pygame.display.set_mode(event.dict['size'], pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
self.blitmap()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4 or event.button == 5:
zoom = 2 if event.button == 4 else 0.5
mx, my = event.pos
left = mx + (self.maprect.left - mx) * zoom
right = mx + (self.maprect.right - mx) * zoom
top = my + (self.maprect.top - my) * zoom
bottom = my + (self.maprect.bottom - my) * zoom
self.maprect = pygame.Rect(left, top, right-left, bottom-top)
self.blitmap()
See also Scale and zoom window
Complete example:
repl.it/#Rabbid76/PyGame-ZoomInAndOut
import pygame
from pygame.locals import *
import os
class App:
def __init__(self):
self.running = True
self.size = (800,600)
#create window
self.window = pygame.display.set_mode(self.size, pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
#create map
currentdir = os.path.dirname(os.path.realpath(__file__))
imagedir = currentdir+'/images/europe.png'
self.map = pygame.image.load(imagedir)
self.maprect = self.map.get_rect(center = self.window.get_rect().center)
self.blitmap()
#create window
pygame.display.flip()
def blitmap(self):
self.mapsurface = pygame.transform.smoothscale(self.map, self.maprect.size)
self.window.fill(0)
self.window.blit(self.mapsurface, self.maprect)
def on_init(self):
self.country = Country()
def on_cleanup(self):
pygame.quit()
def check_event(self,event):
if event.type == pygame.QUIT:
self.running = False
elif event.type == pygame.VIDEORESIZE:
self.window = pygame.display.set_mode(event.dict['size'], pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
self.blitmap()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4 or event.button == 5:
zoom = 2 if event.button == 4 else 0.5
mx, my = event.pos
left = mx + (self.maprect.left - mx) * zoom
right = mx + (self.maprect.right - mx) * zoom
top = my + (self.maprect.top - my) * zoom
bottom = my + (self.maprect.bottom - my) * zoom
self.maprect = pygame.Rect(left, top, right-left, bottom-top)
self.blitmap()
pygame.display.update()
def on_execute(self):
while self.running == True:
for event in pygame.event.get():
self.check_event(event)
self.on_cleanup()
class Country(App):
def __init__(self):
super().__init__()
start = App()
start.on_init()
start.on_execute()
I have been following this tutorial about animated buttons in pygame. It worked perfectly until I created a button outside of the main loop in another function.
Here is my code:
import pygame
from pygame.locals import *
import sys
import random
# Constants
SCREEN = pygame.display.set_mode((1280, 720), 0, 32)
# Colours
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREY = (100, 100, 100)
LIGHT_BLUE = (66, 233, 245)
# Button Class
class Button:
def __init__(self, text, width, height, pos, elevation):
# Core attributes
self.pressed = False
self.elevation = elevation
self.dynamicElevation = elevation
self.originalYPos = pos[1]
# Top Rectangle
self.topRectangle = pygame.Rect(pos, (width, height))
self.topColor = '#457B9D'
# Bottom Rectangle
self.bottomRectangle = pygame.Rect(pos, (width, elevation))
self.bottomColor = '#1D3557'
# Text
self.textSurface = gui_font.render(text, True, '#FFFFFF')
self.textRectangle = self.textSurface.get_rect(center = self.topRectangle.center)
def draw(self):
# Elevation Logic
self.topRectangle.y = self.originalYPos - self.dynamicElevation
self.textRectangle.center = self.topRectangle.center
self.bottomRectangle.midtop = self.topRectangle.midtop
self.bottomRectangle.height = self.topRectangle.height + self.dynamicElevation
bottom =pygame.draw.rect(SCREEN, self.bottomColor, self.bottomRectangle, border_radius = 12)
top = pygame.draw.rect(SCREEN, self.topColor, self.topRectangle, border_radius = 12)
pygame.draw.rect(SCREEN, '#000000', top, 1, border_radius = 12)
pygame.draw.rect(SCREEN, '#000000', bottom, 1, border_radius = 12)
SCREEN.blit(self.textSurface, self.textRectangle)
self.check_click()
def check_click(self):
mousePosition = pygame.mouse.get_pos()
if self.topRectangle.collidepoint(mousePosition):
self.topColor = '#F1FAEE'
if pygame.mouse.get_pressed()[0]:
self.dynamicElevation = 0
self.pressed = True
else:
self.dynamicElevation = self.elevation
if self.pressed == True:
print("Click")
self.pressed = False
else:
self.topColor = '#457B9D'
class GameState():
def __init__(self):
self.state = "welcome"
def welcomeScreen(self):
SCREEN.fill(WHITE)
for event in pygame.event.get():
if event.type == QUIT:
exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
exit()
if event.key == K_F1:
self.state = "mainGame"
pygame.display.update()
def mainGame(self):
SCREEN.fill(GREY)
buttonBack = Button("Back to Main Screen", 250, 30, (1000, 650), 8)
for event in pygame.event.get():
if event.type == QUIT:
exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
exit()
if event.key == K_F2:
self.state = "welcome"
buttonBack.draw()
pygame.display.update()
def stateManager(self):
if self.state == "welcome":
self.welcomeScreen()
if self.state == "mainGame":
self.mainGame()
pygame.init()
clock = pygame.time.Clock()
gameState = GameState()
pygame.display.set_caption("Button Test")
gui_font = pygame.font.Font(None, 30)
while True:
gameState.stateManager()
clock.tick(60)
I have tried to play around with putting the button in a different screen or at different stages of the loop. Is there a logic error I cannot see or lies my mistake somewhere else?
You are actually creating the button inside the main loop since you create it each time mainGame is called. mainGame is called by stateManager if the state is "mainGame", and that's called at each frame in your while True loop. So as you are recreating your button at each frame I think your problems might come from there.
I suggest you create your button in the parent's class constructor instead:
class GameState():
def __init__(self):
self.state = "welcome"
# Create the button here to make the object persistent.
self.buttonBack = Button("Back to Main Screen", 250, 30, (1000, 650), 8)
# ...
def mainGame(self):
SCREEN.fill(GREY)
for event in pygame.event.get():
if event.type == QUIT:
exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
exit()
if event.key == K_F2:
self.state = "welcome"
self.buttonBack.draw() # <- use your button with self.buttonBack
pygame.display.update()
# ...
I am having an issue with PyGame i can't resolve. So:
my idea is that I have a map I can zoom in/out on. zooming in works fine. But zooming out shows that the rest of the picture got deleted and only the part of the image that was previously visible on the window exists now.
This is my code:
import pygame
from pygame.locals import *
import os
class App:
def __init__(self):
self.running = True
self.size = (800,600)
#create window
self.window = pygame.display.set_mode(self.size, pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
#create map
currentdir = os.path.dirname(os.path.realpath(__file__))
imagedir = currentdir+'/images/europe.png'
self.map = pygame.image.load(imagedir)
self.maprect = self.map.get_rect()
self.mapsurface = pygame.Surface(self.size)
self.mapsurface.blit(pygame.transform.scale(self.map,(self.size)),(0,0))
self.window.blit(self.mapsurface,(0,0))
self.scale = 1
#create window
pygame.display.flip()
def on_init(self):
self.country = Country()
def on_cleanup(self):
pygame.quit()
def check_event(self,event):
if event.type == pygame.QUIT:
self.running = False
elif event.type == pygame.VIDEORESIZE:
self.window = pygame.display.set_mode(event.dict['size'], pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
self.window.blit(pygame.transform.scale(self.map,(event.dict['size'])),(0,0))
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4:
zoom = 2
wnd_w,wnd_h = self.window.get_size()
zoom_size = (round(wnd_w/zoom), round(wnd_h/zoom))
zoom_area = pygame.Rect(0,0, *zoom_size)
pos_x,pos_y = pygame.mouse.get_pos()
zoom_area.center = (pos_x, pos_y)
zoom_surf = pygame.Surface(zoom_area.size)
zoom_surf.blit(self.window, (0, 0), zoom_area)
zoom_surf = pygame.transform.smoothscale(zoom_surf, (wnd_w, wnd_h))
self.window.blit(zoom_surf, (0, 0))
elif event.button == 5:
zoom = 0.5
wnd_w,wnd_h = self.window.get_size()
zoom_size = (round(wnd_w/zoom), round(wnd_h/zoom))
zoom_area = pygame.Rect(0,0,*zoom_size)
pos_x,pos_y = pygame.mouse.get_pos()
zoom_area.center = (pos_x, pos_y)
zoom_surf = pygame.Surface(zoom_area.size)
zoom_surf.blit(self.window, (0, 0), zoom_area)
zoom_surf = pygame.transform.smoothscale(zoom_surf, (wnd_w, wnd_h))
self.window.blit(zoom_surf, (0, 0))
pygame.display.flip()
pygame.display.update()
def on_execute(self):
while self.running == True:
for event in pygame.event.get():
self.check_event(event)
self.on_cleanup()
class Country(App):
def __init__(self):
super().__init__()
start = App()
start.on_init()
start.on_execute()
Here are the screenshots of my problem:
so far so good:
zooming in works fine:
zooming out causes this:
You'll need to scale and blit the original image when you zoom. Use the attribute maprect to define the scaled size and relative location of the map. Add a method blit map that can scale and blit the map. Use the method in the constructor of the class App:
class App:
def __init__(self):
# [...]
self.map = pygame.image.load(imagedir)
self.maprect = self.map.get_rect(center = self.window.get_rect().center)
self.blitmap()
#create window
pygame.display.flip()
def blitmap(self):
self.mapsurface = pygame.transform.smoothscale(self.map, self.maprect.size)
self.window.fill(0)
self.window.blit(self.mapsurface, self.maprect)
# [...]
When the image is zoomed, calculate the new mapping rectangle (self.maprect) and call the method again:
class App:
# [...]
def check_event(self,event):
if event.type == pygame.QUIT:
self.running = False
elif event.type == pygame.VIDEORESIZE:
self.window = pygame.display.set_mode(event.dict['size'], pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
self.blitmap()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4 or event.button == 5:
zoom = 2 if event.button == 4 else 0.5
mx, my = event.pos
left = mx + (self.maprect.left - mx) * zoom
right = mx + (self.maprect.right - mx) * zoom
top = my + (self.maprect.top - my) * zoom
bottom = my + (self.maprect.bottom - my) * zoom
self.maprect = pygame.Rect(left, top, right-left, bottom-top)
self.blitmap()
See also Scale and zoom window
Complete example:
repl.it/#Rabbid76/PyGame-ZoomInAndOut
import pygame
from pygame.locals import *
import os
class App:
def __init__(self):
self.running = True
self.size = (800,600)
#create window
self.window = pygame.display.set_mode(self.size, pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
#create map
currentdir = os.path.dirname(os.path.realpath(__file__))
imagedir = currentdir+'/images/europe.png'
self.map = pygame.image.load(imagedir)
self.maprect = self.map.get_rect(center = self.window.get_rect().center)
self.blitmap()
#create window
pygame.display.flip()
def blitmap(self):
self.mapsurface = pygame.transform.smoothscale(self.map, self.maprect.size)
self.window.fill(0)
self.window.blit(self.mapsurface, self.maprect)
def on_init(self):
self.country = Country()
def on_cleanup(self):
pygame.quit()
def check_event(self,event):
if event.type == pygame.QUIT:
self.running = False
elif event.type == pygame.VIDEORESIZE:
self.window = pygame.display.set_mode(event.dict['size'], pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
self.blitmap()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4 or event.button == 5:
zoom = 2 if event.button == 4 else 0.5
mx, my = event.pos
left = mx + (self.maprect.left - mx) * zoom
right = mx + (self.maprect.right - mx) * zoom
top = my + (self.maprect.top - my) * zoom
bottom = my + (self.maprect.bottom - my) * zoom
self.maprect = pygame.Rect(left, top, right-left, bottom-top)
self.blitmap()
pygame.display.update()
def on_execute(self):
while self.running == True:
for event in pygame.event.get():
self.check_event(event)
self.on_cleanup()
class Country(App):
def __init__(self):
super().__init__()
start = App()
start.on_init()
start.on_execute()
I made a while loop and .blit() works fine, but when it gets to the if statements, my loading sign appears and nothing seems to work. Am I doing my while loop incorrectly? I also want my menu1 == False to trigger the next while loop.
#Importing Stuff
import pygame
import sys
import time
import random
from pygame.locals import*
pygame.init()
#Naming Variables
menu = 0
color = (65,105,225)
tcolor = (255,255,255)
pcolor = (255,255,255)
hcolor = (255,255,255)
width, height = 1920, 1080
screen = pygame.display.set_mode((width, height))
hecolor = (255,255,255)
sys_font = pygame.font.SysFont \
("None", 60)
menu1 = True
#Initializing Screen
pygame.display.set_caption("TSA Trend Game")
screen.fill(((color)))
pygame.display.update()
#Making Menu
while 1 == 1 and menu == 0:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
#More Variables
rendered = sys_font.render \
("Welcome to Trends of 2016!", True, ((tcolor)))
play = sys_font.render \
("Play Game", True, ((pcolor)))
help = sys_font.render \
("Help", True, ((hcolor)))
play_r = play.get_rect()
play_r.x, play_r.y = 710, 500
help_r = help.get_rect()
help_r.x, help_r.y = 1170, 500
render_r = play.get_rect()
render_r.x, render_r.y = 710, 500
#Display Text
while menu1 == True:
screen.blit(rendered, (710, 440))
screen.blit(help, (1170, 500))
screen.blit(play, (710, 500))
pygame.display.update()
if render_r.collidepoint(pygame.mouse.get_pos()):
pcolor = (255,255,0)
else:
pcolor = (255,255,255)
if help_r.collidepoint(pygame.mouse.get_pos()):
hcolor = (255,255,0)
else:
hcolor = (255,255,255)
if event.type == pygame.MOUSEBUTTONDOWN and help_r.collidepoint(pygame.mouse.get_pos()):
menu1 == False
while menu1 == False:
screen.fill(color)
pygame.display.update()
pygame.display.update()
You need
= instead of == in menu1 = False
if menu1 == True instead of while menu1 == True
But you could organize code in better way (or use separated mainloop for menu, game and help).
import pygame
# --- constants --- (UPPER_CASE names)
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
WIDTH = 1920
HEIGHT = 1080
# --- main --- (lower_case namse)
bg_color = (65,105,225)
text_color = WHITE
play_color = WHITE
help_color = WHITE
menu_background = ( 65, 105, 225)
play_background = (255, 0, 0)
help_background = ( 0, 255, 255)
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen_rect = screen.get_rect()
pygame.display.set_caption("TSA Trend Game")
sys_font = pygame.font.SysFont(None, 60)
# create only once
render = sys_font.render("Welcome to Trends of 2016!", True, text_color)
render_rect = render.get_rect(x=710, y=440)
play = sys_font.render("Play Game", True, play_color)
play_rect = play.get_rect(x=710, y=500)
help = sys_font.render("Help", True, help_color)
help_rect = help.get_rect(x=1170, y=500)
other = sys_font.render("click mouse in any place", True, WHITE)
other_rect = other.get_rect(center=screen_rect.center)
# - mainloop -
state_menu = True
state_play = False
state_help = False
running = True
while running:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
if state_menu:
if event.type == pygame.MOUSEBUTTONDOWN:
if help_rect.collidepoint(event.pos):
print("Help")
state_menu = False
state_help = True
elif play_rect.collidepoint(event.pos):
print("Play")
state_menu = False
state_play = True
elif state_play:
if event.type == pygame.MOUSEBUTTONDOWN:
state_menu = True
state_play = False
elif state_help:
if event.type == pygame.MOUSEBUTTONDOWN:
state_menu = True
state_help = False
# - updates -
if state_menu:
mouse_pos = pygame.mouse.get_pos()
if play_rect.collidepoint(mouse_pos):
play_color = (255,255,0)
else:
play_color = WHITE
if help_rect.collidepoint(mouse_pos):
help_color = (255,255,0)
else:
help_color = WHITE
play = sys_font.render("Play Game", True, play_color)
help = sys_font.render("Help", True, help_color)
elif state_play:
pass
# do something
elif state_help:
pass
# do something
# - draws -
if state_menu:
screen.fill(menu_background)
screen.blit(render, render_rect)
screen.blit(help, help_rect)
screen.blit(play, play_rect)
elif state_play:
screen.fill(play_background)
screen.blit(other, other_rect)
elif state_help:
screen.fill(help_background)
screen.blit(other, other_rect)
pygame.display.update()
# - end -
pygame.quit()
exit()
I'm new to python. I programmed with vb2010, but it's time to try something new. I want to hide a action after 5 seconds after mouse down event(like in start()).
import pygame
import sys
from pygame.locals import *
from time import gmtime, strftime
import threading
import time
white = (255,255,255)
black = (0,0,0)
blue = (0,0,255)
width = 600
height = 400
channel = '0001'
name = 'Channel 3'
class screen(object):
def __init__(self):
pygame.init()
self.font = pygame.font.SysFont('Arial', 25)
pygame.display.set_caption('PyTV')
self.screen = pygame.display.set_mode((width,height), 0, 32)
self.screen.fill((black))
pygame.display.update()
def printData(self):
self.rect = pygame.draw.rect(self.screen, (blue), (0, 0, width, height - 350), 0)
self.screen.blit(self.font.render(channel, True, white), (width - 590, 0))
self.screen.blit(self.font.render(name, True, white), (height - 335, 0))
self.screen.blit(self.font.render(strftime("%H:%M %d/%m/%Y", gmtime()), True, white), (width - 590, height - 377))
pygame.display.update()
def clean(self):
self.screen.fill((black))
pygame.display.update()
if __name__ == '__main__':
def start():
Pan3.printData()
time.sleep(5)
Pan3.clean()
Pan3 = screen()
threading.Thread(target=start).start()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(); sys.exit();
if event.type == pygame.MOUSEBUTTONDOWN:
print 'Event! Mouse Down! Code here....'
A timer may suit your needs, given that you also use threading.
EDIT: Addressing your needs for a more detailed explanation as to how to get it to work, here's some pseudo-code.
if event.type == pygame.MOUSEBUTTONDOWN:
if active_timer:
timer.cancel()
timer = Timer(5.0, show_info_things)
timer.start()
I hope this gets you going well enough.
When you click left mouse first time then it shows date, when you click second time then it hides date. If you don't click second time then it hides automatically after 5 seconds.
The same with key SPACE - first press shows, second hides. If you don't press second time then it hides automatically after 5 seconds.
Key ESC and right click hides too.
import pygame
import sys
import time
# --- constants --- (UPPER_CASE names)
WHITE = (255,255,255)
BLACK = ( 0, 0, 0)
BLUE = ( 0, 0,255)
WIDTH = 600
HEIGHT = 400
# --- classes --- (CamelCase names)
class Screen(object):
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32)
pygame.display.set_caption('PyTV')
self.font = pygame.font.SysFont('Arial', 25)
self.channel = '0001'
self.name = 'Channel 3'
self.show_data = None
self.current_time = pygame.time.get_ticks()
def draw_data(self):
self.rect = pygame.draw.rect(self.screen, BLUE, (0, 0, WIDTH, HEIGHT-350), 0)
self.screen.blit(self.font.render(self.channel, True, WHITE), (WIDTH-590, 0))
self.screen.blit(self.font.render(self.name, True, WHITE), (HEIGHT-335, 0))
self.screen.blit(self.font.render(time.strftime("%H:%M:%S %d/%m/%Y", time.gmtime()), True, WHITE), (WIDTH-590, HEIGHT-377))
def events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
self.show_data = None
elif event.key == pygame.K_SPACE:
if self.show_data:
self.show_data = None
else:
self.show_data = self.current_time + 5000
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if self.show_data:
self.show_data = None
else:
self.show_data = self.current_time + 5000
elif event.button == 3:
# hide on right click
self.show_data = None
def update(self):
# if displayed
if self.show_data:
# check time
if self.current_time >= self.show_data:
# hide after time
self.show_data = None
def draw(self):
self.screen.fill(BLACK)
if self.show_data:
self.draw_data()
pygame.display.update()
def run(self): # mainloop
while True:
self.current_time = pygame.time.get_ticks()
if self.events() is False:
break
self.update()
self.draw()
#sys.exit()
# --- fucntions --- (lower_case names)
# empty
# --- main ---
if __name__ == '__main__':
Screen().run()