I'm new to pygame, and I'm trying to make a menu for my game. For now, I want two different screens, one that will show in the menu and other that will show in the "custom" part of the game. I tried to create a main loop and two inner loops that only run when they are supposed to.
For now, the transition between menu and custom is done thought pressing key "d". The transition menu to custom is done perfectly, but the transition custom to menu is crashing the game
This is the main loop:
while running:
while menu:
pygame.display.flip()
screen.blit(bg, (0, 0))
for event in pygame.event.get():
if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
running = 0
menu = 0
elif (event.type == pygame.KEYDOWN and event.key == pygame.K_d):
custom = 1
menu = 0
while custom:
pygame.display.flip()
screen.blit(bgCustom, (0, 0))
for event in pygame.event.get():
if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
running = 0
custom = 0
elif (event.type == pygame.KEYDOWN and event.key == pygame.K_d):
custom = 0
menu = 1
pygame.quit()
The error I'm getting when I'm in "while custom" and press "d" to go back to the menu is "pygame.error: video system not initializated". The logic seems the same for both so I'm bewildered. Also, I have already initializated pygame, using pygame.init(), so that is not the problem here. Any thoughts?
Thanks in advance!
EDIT: As Rabbid76 stated, in his answer, the error was my identation in "pygame.quit()". It stopped my video system. The only problem was the last line. Correct loop below:
while running:
while menu:
pygame.display.flip()
screen.blit(bg, (0, 0))
for event in pygame.event.get():
if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
running = 0
menu = 0
elif (event.type == pygame.KEYDOWN and event.key == pygame.K_d):
custom = 1
menu = 0
elif (event.type == pygame.KEYDOWN and event.key == pygame.K_1):
playMusic(1)
elif (event.type == pygame.KEYDOWN and event.key == pygame.K_2):
playMusic(2)
elif (event.type == pygame.KEYDOWN and event.key == pygame.K_0):
playMusic(0)
elif (event.type == pygame.KEYDOWN and event.key == pygame.K_3):
playMusic(3)
while custom:
pygame.display.flip()
screen.blit(bgCustom, (0, 0))
for event in pygame.event.get():
if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
running = 0
custom = 0
elif (event.type == pygame.KEYDOWN and event.key == pygame.K_d):
custom = 0
menu = 1
pygame.quit()
It is a matter of Indentation. The last statement in the while loop is pygame.quit(). pygame.quit() uninitialize all pygame modules.
Invoke pygame.quit() after the loop. rather than in the loop:
while running:
while menu:
# [...]
while custom:
# [...]
#<--| INDENTATION
pygame.quit()
Related
I would like to control delay for my program, now is set to pygame.time.delay(50) as default value, below is my code snippet.
pygame.time.delay(50)
pygame.display.update()
clockobject = pygame.time.Clock()
clockobject.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
quit()
if event.key == pygame.K_1:
print('K_1')
if event.key == pygame.K_2:
print('K_2')
I tried to control it by changing the values.
if event.key == pygame.K_1:
pygame.time.delay(20)
pygame.display.update()
print('K_1')
if event.key == pygame.K_2:
pygame.time.delay(90)
pygame.display.update()
print('K_2')
When i press the keys the print value returns on my terminal but i doesn't slow down or accelerate!
You have to use a variable for the delay:
time_delay = 50
while run:
pygame.time.delay(time_delay)
# [...]
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
if time_delay > 0:
time_delay -= 10
if event.key == pygame.K_2:
if time_delay < 100:
time_delay += 10
Pygame.time.delay() delays the time your code runs on the window, there is no way that pygame.time.delay() delays your keyboard inputs so what you can do is set a variable to like 20 and then if a user presses a, decrease the variable by 1 and if that variable reaches 0 or below, then do what you want to do.
I want to insert values on the sudoku grid, using pygame, editing an internal matrix. If the user clicks an empty cell, I want them to be able to choose a keyboard number and the internal matrix would be updated, with this number in the respective cell. For now, my loop code looks like this:
while custom:
pygame.display.flip()
screen.blit(bgCustom, (0, 0))
for event in pygame.event.get():
if (event.type == pygame.MOUSEBUTTONDOWN):
setGrid(board)
and setGrid looks like this:
def setGrid(board):
position = pygame.mouse.get_pos()
x = position[0]
y = position[1]
#print(y, x)
line = x // 92
col = y // 80
#print(col, line)
#print(board)
for event in pygame.event.get():
if event.type == pygame.KEYUP :
if event.key == pygame.K_1:
board[line][col] = 1
print(board)
elif event.key == pygame.K_2:
board[line][col] = 2
elif event.key == pygame.K_3:
board[line][col] = 3
elif event.key == pygame.K_4:
board[line][col] = 4
elif event.key == pygame.K_5:
board[line][col] = 5
elif event.key == pygame.K_6:
board[line][col] = 6
elif event.key == pygame.K_7:
board[line][col] = 7
elif event.key == pygame.K_8:
board[line][col] = 8
elif event.key == pygame.K_9:
board[line][col] = 9
There is no syntax error, but the board remains uneditaded. My guess is that, when the user activates setGrid, the computer immediately tries to detect keyboard input, but the user is not "fast enough" to make the function work. I thought about making some kind of wait function, to wait for keyboard input, but I don't want the user to get stuck in setGrid. Any thoughts?
Thanks in advance
You have to set a variable (clicked_cell) which is initialized by None. Assign a tuple with the line and column to the cell when it is clicked. Reset the variable after the button was pressed:
clicked_cell = None
while custom:
# [...]
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
line = event.pos[0] // 92
col = event.pos[1] // 80
clicked_cell = (line, col)
if event.type == pygame.KEYUP:
if clicked_cell != None:
if pygame.K_1 <= event.key <= pygame.K_9:
line, col = clicked_cell
clicked_cell = None
number = int(event.unicode)
board[line][col] = number
# [...]
I made this thinking that it would works, but it doesn't XD
it only moves the image one time per click
Help me please
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
while event.type == pygame.KEYDOWN:
right == K_RIGHT
left == K_LEFT
if right == 1
posX += velocidad
elif lef == 1:
posX -= velocidad
I think you want to used pygame.key.get_pressed() as follows.
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pressed_keys = pygame.key.get_pressed()
if pressed_keys[K_RIGHT]:
posX += velocidad
if pressed_keys[K_LEFT]:
posX -= velocidad
event.type == pygame.KEYDOWN only catches when a key is first pressed down.
If you want to use this you could switch some attribute like your_object.moving_right = True. Then use keyup to turn it off again.
Overall, I think what you want is to check event.key with an if statement.
However there are multiple problems (both structural and syntactic) with your code. event.type doesn't change, so using while doesn't make sense (and this will run forever and make your program hang). I'm not sure what your intent is with the == 1 comparisons, as K_RIGHT and K_LEFT are arbitrary constants for key code values. Not to mention that right == K_RIGHT is an expression that does nothing (did you mean right = K_RIGHT?) and you've got a clear typo with lef. I think the closest working code to the structure you've provided (assuming the other code not shown also works) would look something like this:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
right = K_RIGHT
left = K_LEFT
if event.key == right:
posX += velocidad
elif event.key == left:
posX -= velocidad
I am making a two player game in which two players can move simultaneously throughout.
The while loop goes like this:
while stop==0:
for event in pygame.event.get():
if event.type == pygame.QUIT:
stop = 1
#For player 1
#on pressing an arrow key
# xv, yv = velocity at which the object moves
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
xv = -1
elif event.key == pygame.K_RIGHT:
xv = 1
elif event.key == pygame.K_UP:
yv = -1
elif event.key == pygame.K_DOWN:
yv = 1
# on releasing an arrow key
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
xv = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
yv = 0
#For player 2
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
xv2 = -1
elif event.key == pygame.K_d:
xv2 = 1
elif event.key == pygame.K_w:
yv2 = -1
elif event.key == pygame.K_s:
yv2 = 1
# on releasing an arrow key
elif event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d:
xv2 = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
yv2 = 0
Using the above code, only player 1 was able to move while player 2 remained still.
but after modifying the code like this it worked,
while stop==0:
for event in pygame.event.get():
if event.type == pygame.QUIT:
stop = 1
#For player 1
#on pressing an arrow key
# xv, yv = velocity at which the object moves
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
xv = -1
elif event.key == pygame.K_RIGHT:
xv = 1
elif event.key == pygame.K_UP:
yv = -1
elif event.key == pygame.K_DOWN:
yv = 1
# on releasing an arrow key
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
xv = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
yv = 0
#For player 2
if event.type == pygame.QUIT:
stop = 1
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
xv2 = -1
elif event.key == pygame.K_d:
xv2 = 1
elif event.key == pygame.K_w:
yv2 = -1
elif event.key == pygame.K_s:
yv2 = 1
# on releasing an arrow key
elif event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d:
xv2 = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
yv2 = 0
The only change made was inserting
if event.type == pygame.QUIT:
stop = 1
before the elif statement of player 2. Can anyone help with this confusion?
You have
if event.type == pygame.QUIT:
elif event.type == pygame.KEYDOWN:
# player1
elif event.type == pygame.KEYUP:
elif event.type == pygame.KEYDOWN: # <-- this will never checked
# player2
Second pygame.KEYDOWN will be never use because first pygame.KEYDOWN catchs all KEYDOWN events.
You need only one pygame.KEYDOWN
if event.type == pygame.QUIT:
elif event.type == pygame.KEYDOWN:
# player1
# player2
elif event.type == pygame.KEYUP:
# player1
# player2
or you have to use two if
if event.type == pygame.QUIT:
elif event.type == pygame.KEYDOWN:
# player1
elif event.type == pygame.KEYUP:
# player1
if event.type == pygame.KEYDOWN:
# player2
elif event.type == pygame.KEYUP:
# player2
BTW. when you will use Classes then you will have two objects with own method to check events
if event.type == pygame.QUIT:
# quit
player1.handle_event(event)
player2.handle_event(event)
and every player will have own
def handle_event(self, event)
if event.type == pygame.KEYDOWN:
# do something
elif event.type == pygame.KEYUP:
# do something
So, I'm working on a basic Pygame and one of the mechanics is having a bullet sprite follow the mouse and explode. But I'm having just two bugs.
BUG 1: Removing the bullets removes all bullets in bullet_list. I understand why this happens but I don't know how to correct it. Solved
BUG 2: Moving the mouse seems to override the detection of key presses. You cannot move or shoot bullets while moving the mouse.
Update
#Checking Keys
for event in pygame.event.get():
print("CAKE")
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
pPlayer.image = pDown
pPlayer.chy = 2
elif event.key == pygame.K_UP:
pPlayer.image = pUp
pPlayer.chy = -2
elif event.key == pygame.K_LEFT:
pPlayer.image = pLeft
pPlayer.chx = -2
elif event.key == pygame.K_RIGHT:
pPlayer.image = pRight
pPlayer.chx = 2
elif event.key == pygame.K_SPACE:
if pPlayer.canFire == True:
bullet = Bullet()
bullet.rect.x = int(player.x)
bullet.rect.y = int(player.y)
all_sprites_list.add(bullet)
bullet_list.add(bullet)
pPlayer.canFire = False
elif event.key == pygame.K_ESCAPE:
if gameState.togglePause == True:
if gameState.pause == True:
gameState.game = True
gameState.pause = False
elif gameState.pause == False:
gameState.game = False
gameState.pause = True
gameState.togglePause = False
elif event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN or event.key == pygame.K_UP:
pPlayer.chy = 0
elif event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
pPlayer.chx = 0
elif event.key == pygame.K_SPACE:
pPlayer.canFire = True
elif event.key == pygame.K_ESCAPE:
gameState.togglePause = True
else:
pPlayer.chx = 0
pPlayer.chy = 0
New Bug! I'm unfamiliar with pygame.event.get() and I'm probably doing something wrong here but the examples provided by the pygame docs don't quite help. I can't tell if it has fixed the handling of multiple events because it doesn't seem to even register them. The code prints out "cake" rarely and very delayed and very seldom do any bullets fire when I hit space.
I don't know how well this answer applies because your code is only a sample, but I'll do my best.
Bug 1: For if dist < 30, dist is not updating because you're calculating it in a different for-loop. From your sample, it looks like you can just include the kill check at the end of the first "for bullet in bullet_list" loop.
Bug 2: You're only checking for one event per step, so when multiple events happen (ie mouse motion and a keypress) you only handle on of them. To fix this, iterate through a list of all events:
for event in pygame.event.get():
#Your "Checking Keys" code goes here