Pygame project, screen doesn't update in one function, but it works within two other functions - python

My pygame project consists of several parts, including global map and towns. I use one Game class to contain necessary objects. All game is shown on one screen and works properly with global map and town (in_city function), it changes the screen and shows necessary information, but when I call another function (buy), it doesn't update screen.
def buy(self):
while self.running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if event.type == pygame.KEYDOWN:
return
self.screen.fill('BLACK')
pygame.display.update()
pygame.display.flip()
def in_city(self):
while self.running:
stop = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if event.type == pygame.MOUSEMOTION:
all_sprites.update(pygame.mouse.get_pos())
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = pygame.mouse.get_pos()
button_right.click(mouse_pos)
button_left.click(mouse_pos)
button_next.click(mouse_pos)
button_prev.click(mouse_pos)
if button_close.on_button(mouse_pos):
stop = True
if event.type == pygame.KEYDOWN:
self.buy()
if stop:
self.player.route = [(0, 0)]
self.player.next_move(self.maps)
self.camera.update(self.player)
return
screen.fill('WHITE')
city.render(screen)
current_text = city.enemies[city.current_enemy]
window.show(screen, current_text.get_text())
print(current_text.goods)
all_sprites.draw(screen)
pygame.display.update()
pygame.display.flip()`

Never run game loops recursively. Use the one application loop to draw the scene depending on states. You should never jump to another application loop in an event. The event should only change a state that is used to draw the scene. e.g.:
game_state = 'A'
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
game_state = 'B'
screen.fill('WHITE')
if game_state == 'A':
# draw scene A
elif game_state == 'B':
# draw scene B
pygame.display.flip()

Related

My pause statement is not working for pygame loop

My collide_rect function is not working as I expect to be. The problem is when press the key 'r', it should be able to reset everything and continue the game. But when I actually press the key 'r', it does not change anything when I add in the pause statement. I want to have the game pause when two of the sprites I have(ball, obstacle) collide. After the user inputs the letter 'r', it should go back to running and reset position for both sprites. The error I am getting is when I press the key 'r', it does not change anything on the surface.
This is my while loop:
paused = False
def display_text(text):
font = pygame.freetype.Font('helvetica.ttc', 32)
text_attributed = font.render_to(gameDisplay, (300,300), text, black)
while not crashed:
time = pygame.time.get_ticks()
obstacle.change_x()
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
ball.jump_true()
if event.key == pygame.K_SPACE:
ball.jump_true()
if event.key == pygame.K_r:
paused = not paused
if ball.collide == True:
gameDisplay.fill(white)
display_text('You Lost! type "R" to restart')
paused = True
if paused == True:
ball.reset_position()
obstacle.reset_position()
pygame.display.flip()
clock.tick(20)
else:
ball.jump()
ball.test_collision(obstacle)
gameDisplay.fill(white)
ball.update()
obstacle.update()
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
Don't overcomplicate things. You don't need multiple event loops. Use 1 main loop, 1 event loop and a state which indicates if the game is paused. e.g.:
paused = False
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r
# Toggle pause
paused = not paused
if paused:
# "pause" mode
# [...]
else
# "run" mode
# [...]
# update display etc.
# [...]

How to move image in python using pygame?

I'm a beginner in python and I am trying to learn the features of pygame in order to make a simple game. I want to move an image using the wasd keys, but it's not working. Please help.
I'm using python (3.7.0) on windows 10.
The following is the code:
import pygame
from pygame.locals import *
pygame.init()
pygame.display.init()
keys = [False, False, False, False]
screen=pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
background=pygame.Surface(screen.get_size())
background.fill((255,255,255))
playerpos=[100,100]
player=pygame.image.load("Copper.png")
while 1:
pygame.display.init()
screen.fill(0)
screen.blit(background,(0,0))
screen.blit(player,playerpos)
for event in pygame.event.get():
pygame.display.init()
pygame.display.flip()
if event.type == pygame.KEYDOWN:
if event.key==pygame.K_RETURN:
pygame.display.quit()
pygame.display.flip()
# 8 - loop through events
for event in pygame.event.get():
# 9 - check if event is X button
if event.type==pygame.QUIT:
# 10 - quit the game
pygame.quit()
exit(0)
if event.type == pygame.KEYDOWN:
if event.key==K_w:
keys[0]=True
elif event.key==K_a:
keys[1]=True
elif event.key==K_s:
keys[2]=True
elif event.key==K_d:
keys[3]=True
if event.type == pygame.KEYUP:
if event.key==pygame.K_w:
keys[0]=False
elif event.key==pygame.K_a:
keys[1]=False
elif event.key==pygame.K_s:
keys[2]=False
elif event.key==pygame.K_d:
keys[3]=False
# 9 - Move player
if keys[0]:
playerpos[1]-=500
elif keys[2]:
playerpos[1]+=500
if keys[1]:
playerpos[0]-=500
elif keys[3]:
playerpos[0]+=500
I expect the image "Copper.png" to move when I press w,a,s,d but the image does not move. The image does refresh everytime I press w,a,s,d but does not move.
Get rid of the multiple even handling loops. Use a single loop to handle all the events.
Further it is sufficient to init the display once (pygame.display.init())
Create a variable speed, which defines the number of pixels, the position of the image changes by each step
First evaluate the pygame.QUIT event and stop running the main loop when the event happens:
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
Then handle the other events like the pygame.KEYDOWN and pygame.KEYUP.
For a continuously movement, the manipulation of the player position has to be done outside the event loop. If it would be don in the loop, the the position of the player would only change if en event occurs. Note use a small "speed" (speed = 1), else the player would rapidly moved out of the window.
for event in pygame.event.get():
# event handling
if keys[0]:
playerpos[1]-=speed
elif keys[2]:
playerpos[1]+=speed
if keys[1]:
playerpos[0]-=speed
elif keys[3]:
playerpos[0]+=speed
Do the drawing of the scene at the end of main loop:
speed = 1
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key==pygame.K_RETURN:
done = True
for i in range(4):
if event.key == (K_w, K_a, K_s, K_d)[i]:
keys[i]=True
elif event.type == pygame.KEYUP:
for i in range(4):
if event.key == (K_w, K_a, K_s, K_d)[i]:
keys[i]=False
if keys[0]:
playerpos[1]-=speed
elif keys[2]:
playerpos[1]+=speed
if keys[1]:
playerpos[0]-=speed
elif keys[3]:
playerpos[0]+=speed
screen.fill(0)
screen.blit(background,(0,0))
screen.blit(player,playerpos)
pygame.display.flip()
Note, alternatively you can use pygame.key.get_pressed() to get all states of of all keyboard buttons at once. So you don't need to evaluate the key events separately:
speed = 1
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
done = True
allKeys = pygame.key.get_pressed()
playerpos[0] += -speed if allKeys[K_a] else speed if allKeys[K_d] else 0
playerpos[1] += -speed if allKeys[K_w] else speed if allKeys[K_s] else 0
screen.fill(0)
screen.blit(background,(0,0))
screen.blit(player,playerpos)
pygame.display.flip()

My game won't work when I use the controls, how do I fix it?

I can not get the controls to work, I try to press escape to open a menu I made but it will not open and I do not know if I am checking for events correctly, is there a way I am SUPPOSED to do it?
I tried using the functions for checking for different keys and I went to the spread-sheet that displays all the event names so you can map them at pygame.org but it will not open when I use the escape or also known as:
elif event.type == pygame.K_ESCAPE:
Frame.blit('Textures/GUI/loom.png', (0,0))
Heres the full code:
import pygame
#Textures/Blocks/loom_side.png
pygame.init()
Screen = "None"
DB = 0
Width = 800
Height = 600
Frame = pygame.display.set_mode((Width,Height))
pygame.display.set_caption("HypoPixel")
FPS = pygame.time.Clock()
def Raycast(TTR, RayXPos, RayYPos, RaySizeX, RaySizeY):
RaycastThis = pygame.image.load(TTR)
RaycastThis = pygame.transform.scale(RaycastThis,(RaySizeX,RaySizeY))
Frame.blit(RaycastThis, (RayXPos, RayYPos))
Loop = True
Raycast('Textures/Screens/Skybox/Earth.png',0,0,800,600)
while Loop == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.K_ESCAPE:
Frame.blit('Textures/GUI/loom.png', (0,0))
pygame.display.update()
FPS.tick(60)
I expected to get the loom GUI that I made. Once I tried to press escape, nothing happened.
pygame.K_ESCAPE is not event type (see pygame.event), but it is a pygame.key.
First check if a key was pressed by comparing the event type to pygame.KEYDOWN:
event.type == pygame.KEYDOWN
Then check if the event.key, which cause the event, is the pygame.K_ESCAPE key:
event.key == pygame.K_ESCAPE
Furthermore, the parameter to Surface.blit() has to be a Surface object rather than a filename.
first load the image to a Surface, by pygame.image.load(), then blit the Surface:
sprite = pygame.image.load('Textures/GUI/loom.png')
Frame.blit(sprite, (0,0))
Of course the your Raycast function can be called to do so:
Raycast('Textures/GUI/loom.png',0,0,800,600)
Your code should look somehow like this:
while Loop == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
Raycast('Textures/GUI/loom.png',0,0,800,600)

Pygame not restoring from pause

I'm trying to pause my game by pressing the 'p' key, but after it pauses it does not unpause when p is pressed again. Here are the relevant segments of my code, I'd like to know how to fix this and/or if there are better alternative methods of implementing a game pause.
pause = False
while True:
if not pause:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#game code
keys = pygame.key.get_pressed()
#if key up
elif keys[pygame.K_p]:
pause = True #appears to work correctly, screen freezes and
#prints "PAUSED" every tick.
#more game code
pygame.display.update()
fpsClock.tick(FPS)
else:
print("PAUSED")
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.type == pygame.K_p:
pause = False
pygame.display.update()
fpsClock.tick(FPS)
The code below does the trick.
I have added in if not pause: ... else: section also a handler for a keypress because without it there will be no chance to come out of the pause (the part if not pause won't never ever be run without this keypress check if once paused).
import pygame
pygame.init() # start PyGame (necessary because 'import pygame' doesn't start PyGame)
colorWhite = (255, 255, 255) # RGB color for later use in PyGame commands (valueRed=255, valueGreen=255, valueBlue=255)
colorWhite = (255, 255, 255) # RGB color for later use in PyGame commands (valueRed=255, valueGreen=255, valueBlue=255)
winDisplay = pygame.display.set_mode((1024, 768)) # set PyGame window size to 1024x768 pixel
pygame.display.set_caption("Minimal PyGame Test Script")
winDisplay.fill(colorWhite)
fpsClock = pygame.time.Clock()
FPS = 15
pause = False
pauseCounter = 0
while True:
if not pause:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_p:
pause = not pause
#game code
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#more game code
pygame.display.update()
fpsClock.tick(FPS)
else:
pauseCounter += 1
print(pauseCounter, "PAUSED")
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN and event.key == pygame.K_p:
pause = not pause
#more game code
pygame.display.update()
fpsClock.tick(FPS)

Multiple instances of pygame.event.get()

There are two for event in pygame.event.get(): instances. It doesn't work inside the second one. I guess that calling the function twice will not work. What should be done here? By the way this is a function to move a piece from square to square in a board game.
def movement_one(blit1,charac1,screen,squareblitter,boardcoord,placecheck_True):
global mouse1, mouse1_des
run1=True
while run1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse1 = pygame.mouse.get_pos()
for i in range(80):
if squareblitter[i].collidepoint(mouse1):
collided = i
break
print "wow"
print i
print collided in placecheck_True
if collided in placecheck_True:
#checks if the square is occupied or not
print "wiw"
for event in pygame.event.get():
print "wtf"
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse1_des = pygame.mouse.get_pos()
print "omg"
squareblitter[i]
pygame.display.update()
for i in range(80):
if squareblitter[i].collidepoint(mouse1_des):
screen.blit(placecheck_True[collided], squareblitter[i])
placecheck_True.update[i]=placecheck_True[collided]
pygame.display.update()
run1=False
break
else:
break
Calling pygame.event.get() again while handling an event from a previous call usually won't work. It's unclear from your code precisely what you're trying to accomplish. However, I suggest you rry moving the code for processing pygame.MOUSEBUTTONDOWN events when there's a collision that's currently in you inner for event loop to the outer one (and remove the inner for event loop altogether).
Here's what I mean (untested, of course):
def movement_one(blit1, charac1, screen, squareblitter, boardcoord, placecheck_True):
global mouse1, mouse1_des
run1 = True
while run1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse1 = pygame.mouse.get_pos()
for i in range(80):
if squareblitter[i].collidepoint(mouse1):
collided = i
break
print "wow"
print i
print collided in placecheck_True
if collided in placecheck_True:
mouse1_des = pygame.mouse.get_pos()
print "omg"
squareblitter[i]
pygame.display.update()
for i in range(80):
if squareblitter[i].collidepoint(mouse1_des):
screen.blit(placecheck_True[collided], squareblitter[i])
placecheck_True.update[i] = placecheck_True[collided]
pygame.display.update()
run1 = False # not sure you should do this...
break

Categories