I'm trying to implement a pause function in my tamagotchi clone (I'm practising for my controlled assessment next year) and I can't get the left and up keys to work simultaneously as a pause button. If possible I want to stay as true to the original game as possible so I would prefer not to use on-screen buttons. Thanks!
import pygame
import time
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
size =(200, 200)
screen = pygame.display.set_mode(size)
pygame.display.set_caption('Tama v4.5')
screen.fill(WHITE)
pygame.init()
clock = pygame.time.Clock()
sprites = ['AdultSpriteAAA.png']
up_pressed = False
left_pressed = False
right_pressed = False
def main():
controls()
if up_pressed == True and left_pressed == True:
time.sleep(2)
pause()
player_position = pygame.mouse.get_pos()
x = player_position[0]
y = player_position[1]
screen.blit(background, [0,0])
screen.blit(sprite, [x, y])
pygame.display.flip()
clock.tick(60)
def controls():
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
print(animate())
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
global up_pressed
right_pressed = True
if event.key == pygame.K_LEFT:
global left_pressed
left_pressed = True
if event.key == pygame.K_RIGHT:
global right_pressed
right_pressed = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
global up_pressed
right_pressed = False
if event.key == pygame.K_LEFT:
global left_pressed
left_pressed = False
if event.key == pygame.K_RIGHT:
global right_pressed
right_pressed = False
def info():
return 0
def food():
return 1
def toilet():
return 2
def game():
return 3
def connect():
return 4
def talk():
return 5
def medic():
return 6
def post():
return 7
def history():
return 8
def animate():
return 9
def pause():
time.sleep(2)
while True:
controls()
if up_pressed == True and left_pressed == True:
time.sleep(2)
break
sprite = pygame.image.load(sprites[0]).convert()
background = pygame.image.load('Background 200x200.png').convert()
sprite.set_colorkey(BLACK)
while True:
main()
A way to make it pause when both left iey and up key are pressed is this:
import pygame
from pygame.locals import *
#game code
…
def pause():
keyspressed = pygame.keys.get_pressed()
if keyspressed[K_LEFT] and keyspressed[K_UP]:
#pause code
…
This code should be correct, but if you find any weird things, try to research the pygame key module. Keep in note that K_LEFT and K_UP are from pygame.locals, which is imported seperately from pygame
Here is a method that I have found really useful when writing games in PyGame:
if event.type == pygame.KEYDOWN
if event.key == (pygame.K_RIGHT and pygame.K_LEFT):
while True: # Infinite loop that will be broken when the user press the space bar again
event = pygame.event.wait()
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: # decid how to unpause?
break #Exit infinite loop
An interesting tid-bit I only recently discovered is that pygame.key.get_pressed() returns a tuple of 1s and 0s representing all of the keys on the keyboard, and these can be used as booleans or indexed to get the effective "value" of a key. Some great tuts at http://programarcadegames.com/
Related
I have this 2D platformer game in PyGame where a character moves left, right and up (jump). I recently implemented a function to pause the game, which works great.
However since the code stops the character on pygame.KEYUP then if the user lets off the side-moving keys (A for left, D for right) AFTER they have paused the game then after resuming the character will be stuck running since it never got the KEYUP event.
Any ideas that makes the character stop X-axis movement after pause? Thankful for any help!
Pause function:
def game_pause:
pause = True
while pause == True:
pygame.init()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
pause = False
Main
loop:
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
#---Key presses---
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
player.go_left()
elif event.key == pygame.K_d:
player.go_right()
elif event.key == pygame.K_SPACE:
player.jump()
elif event.key == pygame.K_RETURN:
game_pause()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_a and player.change_x < 0:
player.stop()
elif event.key == pygame.K_d and player.change_x > 0:
player.stop()
Functions that moves the player-class:
def go_left(self):
self.change_x = -5
def go_right(self):
self.change_x = 5
def stop(self):
self.change_x = 0
Maybe you could set
pause = False
in the main loop and in the go_left(), go_right(), stop() functions make an if statement like
def go_left(self):
if not pause :
self.change_x = -5
so when you pause the game the if statement becomes false
I want to be able to hold the key down and move my little black dot, and then release the key and have it stop. However even if I hold the key down my if statement for key up is being executed. Here is my code:
manmovemaster = 0
l = 1
f1 = 0
from random import randint
from math import sin, cos, tan, pi
import pygame
from pygame.locals import*
Fps = pygame.time.Clock()
#starting variables
sw = 1200
sh = 650
r = 250
g = 250
b = 250
framerate = 40
#beginning of a man
man1x = 650
man1y = 50
mancolor=(0,0,0)
manlocation = (man1x, man1y)
Diamaterofhead = (5)
man1ymovedown = 0
man1ymoveup = False
man1xmoveright = False
man1xmoveleft = False
#game logic
while l:
pygame.init()
screen = pygame.display.set_mode((sw,sh))
pygame.display.set_caption("WGD THE GAME")
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((r,g,b))
man1 = pygame.draw.circle(background,mancolor,(man1x,man1y),Diamaterofhead)
if man1ymovedown== True:
man1y += 1
manmovemaster = 0
if man1ymoveup == True:
man1y -= 1
if man1xmoveright == True:
man1x +=1
if man1xmoveleft == True:
man1x -=1
#screen refresh
for event in pygame.event.get():
if event.type ==pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
man1xmoveleft = True
if event.key == pygame.K_RIGHT:
man1xmoveright = True
if event.key == pygame.K_UP:
man1ymoveup = True
if event.key == pygame.K_DOWN:
man1ymovedown = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
man1xmoveleft = False
if event.key == pygame.K_RIGHT:
man1xmoveright = False
if event.key == pygame.K_UP:
man1ymoveup = False
if event.key == pygame.K_DOWN:
man1ymovedown = False
else:
screen.blit(background, (0,0))
pygame.display.flip()
pygame.time.get_ticks
Fps.tick(framerate)
Use this instead:
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((400,400))
pygame.display.set_caption("WGD THE GAME")
Fps = pygame.time.Clock()
man1x = 200
man1y = 200
while True:
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
pygame.draw.circle(screen,(255, 255, 255),(man1x,man1y), 25)
pressed = pygame.key.get_pressed()
if pressed[pygame.K_LEFT]:
man1x -= 1
if pressed[pygame.K_RIGHT]:
man1x += 1
if pressed[pygame.K_UP]:
man1y -= 1
if pressed[pygame.K_DOWN]:
man1y += 1
pygame.display.flip()
Fps.tick(60)
using pygame.key.get_pressed() instead of pygame.event.get() returns the state of the keys at all times, not just when you press it. So you can hold a key down and it will, and when you release it, it will stop. This will also work for diagonal movement. because it checks the state of all keys, it will check up and left so both will be true (pressed) and the character will move diagonally.
https://www.pygame.org/docs/ref/key.html#pygame.key.get_pressed
and then you can take all the event checking and boolean movement flags out. Also, each time through the loop you are calling pygame.init(). This isn't necessary. you also don't need to set the mode each time through the game loop, as well as the caption, and background
I have started making something on pygame but I have encountered an issue when moving left or right. if I quickly change from pressing the right arrow key to pressing the left one and also let go of the right one the block just stops moving. this is my code
bg = "sky.jpg"
ms = "ms.png"
import pygame, sys
from pygame.locals import *
x,y = 0,0
movex,movey=0,0
pygame.init()
screen=pygame.display.set_mode((664,385),0,32)
background=pygame.image.load(bg).convert()
mouse_c=pygame.image.load(ms).convert_alpha()
m = 0
pygame.event.pump()
while 1:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type==KEYDOWN:
if event.key==K_LEFT:
movex =-0.5
m = m + 1
if event.key==K_RIGHT:
movex=+0.5
m = m + 1
elif event.type == KEYUP:
if event.key==K_LEFT and not event.key==K_RIGHT:
movex = 0
if event.key==K_RIGHT and not event.key==K_LEFT:
movex =0
x+=movex
y=200
screen.blit(background, (0,0))
screen.blit(mouse_c,(x,y))
pygame.display.update()
is there a way I can change this so if the right arrow key is pressed and the left arrow key is released that it will go right instead of stopping?
P.S
I am still learning pygame and am very new to the module. I'm sorry if this seems like a stupid question but i couldn't find any answers to it.
Your problem is that when you test the KEYDOWN events with
if event.key==K_LEFT and not event.key==K_RIGHT:
you always get True, because when event.key==K_LEFT is True,
it also always is not event.key==K_RIGHT (because the key of the event is K_LEFT after all).
My approach to this kind of problem is to separate
the intent from the action. So, for the key
events, I would simply keep track of what action
is supposed to happen, like this:
moveLeft = False
moveRight = False
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_LEFT: moveLeft = True
if event.key == K_RIGHT: moveRight = True
elif event.type == KEYUP:
if event.key == K_LEFT: moveLeft = False
if event.key == K_RIGHT: moveRight = False
Then, in the "main" part of the loop, you can
take action based on the input, such as:
while True:
for event in pygame.event.get():
...
if moveLeft : x -= 0.5
if moveRight : x += 0.5
the problem is that you have overlapping key features; If you hold down first right and then left xmove is first set to 1 and then changes to -1. But then you release one of the keys and it resets xmove to 0 even though you are still holding the other key. What you want to do is create booleans for each key. Here is an example:
demo.py:
import pygame
window = pygame.display.set_mode((800, 600))
rightPressed = False
leftPressed = False
white = 255, 255, 255
black = 0, 0, 0
x = 250
xmove = 0
while True:
window.fill(white)
pygame.draw.rect(window, black, (x, 300, 100, 100))
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
rightPressed = True
if event.key == pygame.K_LEFT:
leftPressed = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
rightPressed = False
if event.key == pygame.K_LEFT:
leftPressed = False
xmove = 0
if rightPressed:
xmove = 1
if leftPressed:
xmove = -1
x += xmove
pygame.display.flip()
One way could be to create a queue that keeps track of the button that was pressed last. If we press the right arrow key we'll put the velocity first in the list, and if we then press the left arrow key we put the new velocity first in the list. So the button that was pressed last will always be first in the list. Then we just remove the button from the list when we release it.
import pygame
pygame.init()
screen = pygame.display.set_mode((720, 480))
clock = pygame.time.Clock()
FPS = 30
rect = pygame.Rect((350, 220), (32, 32)) # Often used to track the position of an object in pygame.
image = pygame.Surface((32, 32)) # Images are Surfaces, so here I create an 'image' from scratch since I don't have your image.
image.fill(pygame.Color('white')) # I fill the image with a white color.
velocity = [0, 0] # This is the current velocity.
speed = 200 # This is the speed the player will move in (pixels per second).
dx = [] # This will be our queue. It'll keep track of the horizontal movement.
while True:
dt = clock.tick(FPS) / 1000.0 # This will give me the time in seconds between each loop.
for event in pygame.event.get():
if event.type == pygame.QUIT:
raise SystemExit
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
dx.insert(0, -speed)
elif event.key == pygame.K_RIGHT:
dx.insert(0, speed)
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
dx.remove(-speed)
elif event.key == pygame.K_RIGHT:
dx.remove(speed)
if dx: # If there are elements in the list.
rect.x += dx[0] * dt
screen.fill((0, 0, 0))
screen.blit(image, rect)
pygame.display.update()
# print dx # Uncomment to see what's happening.
You should of course put everything in neat functions and maybe create a Player class.
I know my answer is pretty late but im new to Pygame to and for beginner like me doing code like some previous answer is easy to understand but i have a solution to.I didn`t use the keydown line code, instead i just put the moving event code nested in the main game while loop, im bad at english so i give you guy an example code.
enter code here
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.K_ESCAPE:
run = False
win.blit(bg, (0, 0))
pressed = pygame.key.get_pressed()
if pressed[pygame.K_LEFT]:
x -= 5
if pressed[pygame.K_RIGHT]:
x += 5
if pressed[pygame.K_UP]:
y -= 5
if pressed[pygame.K_DOWN]:
y += 5
win.blit(image,(x,y))
pygame.display.update()
pygame.quit()
This will make the image move rapidly without repeating pushing the key, at long the code just in the main while loop with out inside any other loop.
I'm working on a small script in Python 2.7.9 and Pygame that would be a small display for our IT department. The idea is that there are several toggle switches that indicate our current status (in, out, etc) , some information about our program at the school, and play a short video that repeats with images of the IT staff etc. I have an older version of Pygame compiled that still allows for pygame.movie to function.
All of the parts of the script work, but when it gets to the end of the .mpg, the movie will not replay until there is an EVENT, like switching our status or moving the mouse. I have tried to define a variable with movie.get_time and call to rewind at a certain time, but the movie will not rewind (currently commented out) . Is there a way to play the movie on repeat without requiring an event, or maybe I could spoof an event after a certain length of time (note that the documentation for pygame.movie is outdated, the loops function does not work) ?
Thank you for the help!
import pygame, sys, os, time, random
from pygame.locals import *
pygame.init()
windowSurface = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
pygame.display.set_caption("DA IT Welcome Sign")
pygame.font.get_default_font()
bg = pygame.image.load('da.jpg')
in_img = pygame.image.load('in.png')
out_img = pygame.image.load('out.png')
etc_img = pygame.image.load('etc.png')
present = in_img
done = False
img = 1
clock = pygame.time.Clock()
movie = pygame.movie.Movie('wallace.mpg')
movie_screen = pygame.Surface(movie.get_size()).convert()
playing = movie.get_busy()
movie.set_display(movie_screen)
length = movie.get_length()
currenttime = movie.get_time()
movie.play()
while not done:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
done = True
if event.type == pygame.QUIT:
movie.stop()
done = True
if event.type == pygame.KEYDOWN and event.key == pygame.K_1:
img = 1
if event.type == pygame.KEYDOWN and event.key == pygame.K_2:
img = 2
if event.type == pygame.KEYDOWN and event.key == pygame.K_3:
img = 3
if event.type == pygame.KEYDOWN and event.key == K_w:
pygame.display.set_mode((800, 600))
if event.type == pygame.KEYDOWN and event.key == K_f:
pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
if img == 1:
present = in_img
if img == 2:
present = out_img
if img == 3:
present = etc_img
if not(movie.get_busy()):
movie.rewind()
movie.play()
#movie.get_time()
#if currenttime == 25.0:
# movie.stop()
# movie.rewind()
# movie.play()
windowSurface.blit(bg, (0, 0))
windowSurface.blit(movie_screen,(550,175))
windowSurface.blit(present, (0,0))
pygame.display.flip()
You need to take the code for replaying the movie out of the for loop that gets current events. Do this for that code and any other code you want to happen continuously without waiting for an event by moving the code 4 spaces to the left.
Like so:
while not done:
for event in pygame.event.get(): #gets most recent event, only executes code below when there is an event
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
done = True
if event.type == pygame.QUIT:
movie.stop()
done = True
if event.type == pygame.KEYDOWN and event.key == pygame.K_1:
img = 1
if event.type == pygame.KEYDOWN and event.key == pygame.K_2:
img = 2
if event.type == pygame.KEYDOWN and event.key == pygame.K_3:
img = 3
if event.type == pygame.KEYDOWN and event.key == K_w:
pygame.display.set_mode((800, 600))
if event.type == pygame.KEYDOWN and event.key == K_f:
pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
#code below is out of the event for loop and thus executes whenever the while loop runs through
if img == 1:
present = in_img
if img == 2:
present = out_img
if img == 3:
present = etc_img
if not(movie.get_busy()):
movie.rewind()
movie.play()
#movie.get_time()
#if currenttime == 25.0:
# movie.stop()
# movie.rewind()
# movie.play()
windowSurface.blit(bg, (0, 0))
windowSurface.blit(movie_screen,(550,175))
windowSurface.blit(present, (0,0))
pygame.display.flip()
I have run into this problem too while trying to do things with pygame, it seems to be a common error.
I am kinda stuck with a supposed to be simple code to check if the user has pressed "w" or "s".
Below you can see my code:
import pygame
pygame.init()
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_w:
print('Forward')
elif event.type == pygame.KEYDOWN and event.key == pygame.K_s:
print('Backward')
Am I forgetting something here?
Thanks!
A window needs to be created to receive key presses, the following works.
import pygame
import sys
pygame.init()
pygame.display.set_mode((100, 100))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
print('Forward')
elif event.key == pygame.K_s:
print('Backward')
This is what seems to me the most simple and understandable way to do it:
import pygame
pygame.init()
pygame.display.set_mode((300, 300))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
print('Forward')
elif event.key == pygame.K_s:
print('Backward')
Instead of using the sys.exit() method I prefer to just use pygame.quit()
it is no good to ask the gamer to keep hitting w to get the response. If you want to read the "pressed" state. You could consider the followings:
from pygame import *
import time
flag = False # The flag is essential.
DONE = False
screen = display.set_mode((500,500)) # 1180, 216
count=0
while not DONE:
event.pump() # process event queue
keys = key.get_pressed() # It gets the states of all keyboard keys.
#print("%d"%count,keys)
count+=1
if keys[ord('w')]: # And if the key is K_DOWN:
print("%d w down"%count)
if keys[ord('s')]: # And if the key is K_DOWN:
print("%d s down"%count)
time.sleep(0.1)
Try this:
import pygame
pygame.init()
key = pygame.key.get_pressed()
while True:
for event in pygame.event.get():
if event.type == KEYDOWN and event.key == pygame.K_w:
print('Forward')
elif event.type == KEYDOWN and event.key == pygame.K_s:
print('Backward')
Sample code to understand how key press events work.
import pygame
from pygame.locals import *
def main():
pygame.init()
pygame.display.set_caption("Move Box With Arrow Keys")
wndsize = (320, 240)
display = pygame.display.set_mode(wndsize)
x = 5
y = 5
black = (0, 0, 0)
white = (255, 255, 255)
rectpos = (x, y)
rectdim = (50, 50)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
x += 5
print("K_RIGHT")
if event.key == pygame.K_LEFT:
x -= 5
print("K_LEFT")
if event.key == pygame.K_UP:
y -= 5
print("K_UP")
if event.key == pygame.K_DOWN:
y += 5
print("K_DOWN")
# Don't allow coords below 0
if 0 > x:
x = 5
if 0 > y:
y = 5
# Don't allow overflow
if x + rectdim[0] > wndsize[0]:
x = wndsize[0] - rectdim[0] - 5
if y + rectdim[1] > wndsize[1]:
y = wndsize[1] - rectdim[1] - 5
rectpos = (x, y)
display.fill(white)
rect = pygame.draw.rect(display, black, ((rectpos), (rectdim)))
pygame.display.update()
main()
This might work:
from pygame import *
init()
if key.get_pressed()[K_w] == True:
print('Forwards')
if key.get_pressed()[K_s] == True:
print('Backwards')`