Using pygame.event.wait() to decrease system overhead between events. But the way I'm using it seems to filter out most events. Must not be placing it in the right spot in my program.
Can someone please take a look and comment about whether I'm using it wrong?
run the game loop
LEFT=1
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
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
pygame.display.update()
pygame.event.wait()
pygame.event.wait returns the event in question and pops it from the queue, so you have to manage it with the other ones:
for event in [pygame.event.wait()]+pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
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
Related
I need some help with reseting a game I made. I've got the main loop going and the collision detection working. I'm trying to get an instant restart on the game, one that just resets the score and gets going again - I don't want it to have any user input before it restarts the game again.
MoveAsteroids() simply moves asteroids across the screen which the player has to avoid. It's also the function where score is incremented by 1 each time an asteroid is dodged.
def game_loop():
global score
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
spaceship.change = -5
elif event.key == pygame.K_DOWN:
spaceship.change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
spaceship.change = 0
spaceship.y += spaceship.change
if spaceship.y > window_height - spaceship.height: # Creating borders on the window
spaceship.y = window_height - spaceship.height
elif spaceship.y < 0:
spaceship.y = 0
window.blit(bg_img, (0, 0))
MoveAsteroids()
CollisionDetection()
Score_display("Score: " + str(score * 100), white)
pygame.display.update()
def CollisionDetection():
global score
spaceship_rect = pygame.Rect(spaceship.x, spaceship.y, spaceship.width, spaceship.height)
for x in range(1, 5):
rect = pygame.Rect(asteroids[x].x, asteroids[x].y, asteroids[x].width, asteroids[x].height)
if spaceship_rect.colliderect(rect):
pass
# The part I need help with is this line of code just above^. .colliderect() returns true when a collision happens.
If I get you right you just want to reset the game. Just do
def CollisionDetection():
global score
spaceship_rect = pygame.Rect(spaceship.x, spaceship.y, spaceship.width, spaceship.height)
for x in range(1, 5):
rect = pygame.Rect(asteroids[x].x, asteroids[x].y, asteroids[x].width, asteroids[x].height)
if spaceship_rect.colliderect(rect):
score = 0
// here you reset your spaceship.x and y to the normal state
you could also have a look at sprites. It makes collision detection easier and is nice for larger games with it's groups.
I wanted to make a simple game in pygame where i moved the character(a square) with WASD keys. I have somewhat achieved that but the movement is not smooth and when i move my mouse the character refuses to move.
I assume it is something to do with my for loop
for event in pygame.event.get():
if event.type is pygame.QUIT:
pygame.quit()
sys.exit()
I know it is stuck in the loop whilst there is input but i'm not sure how to fix it without not being able to close the program.
Here is the main game loop:
while launchGame:
for event in pygame.event.get():
if event.type is pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(WHITE)
player.draw()
player.move()
pygame.display.flip()
And here is my move script if that helps:
def move(self):
if event.type == pygame.KEYDOWN:
if pygame.key.get_pressed()[K_w]:
self.y -= self.speed
if pygame.key.get_pressed()[K_s]:
self.y += self.speed
if pygame.key.get_pressed()[K_a]:
self.x -= self.speed
if pygame.key.get_pressed()[K_d]:
self.x += self.speed
How can I fix this.
Its a simple typo. In the second line you have if event.type is pygame.QUIT:
And should be if event.type == pygame.QUIT:
If this didn't work, try:
while RUNNING:
for event in pygame.event.get():
if event.type is pygame.QUIT:
RUNNING = False;
screen.fill(WHITE)
player.draw()
player.move()
pygame.display.flip()
And run the program from the command line to see if it's a problem with pycharm
I found the problem. I don't need if event.type == pygame.KEYDOWN: if i'm using pygame.key.get_pressed() because it's not an event function.
Thanks but no thanks i guess xD
I'm trying to create program using pygame to store the hold time and time intervals between successive keys.
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
show_times()
t1 = time.time()
char = pygame.key.name(event.key)
char_list.append(pygame.key.name(event.key))
update_screen()
if event.type == pygame.KEYUP:
t2 = time.time()
if pygame.key.name(event.key) == char:
holdtimes[char] = [t1,t2,(t2 - t1)]
//for debugging
print holdtimes.keys()
This code works fine when user presses keys relatively slow but however when keys are typed faster it misses some keys. How can I make it work when typing is faster?
How often are you calling the function with this code in? If you set a clock (pygame.time.clock ()) and call clock.tick (200) this will update 200 times per second.
I'm having some issues with my game in Pygame. I wanted the cross on the top right of Windows to exit the game if clicked. But it does not seem to work. I also want it to take input from the space bar and roll the dice.
diceRoll = random.randint(1, 4)
while True:
events = pygame.event.get()
for event in events:
if event.type == pygame.KEYDOWN:
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.key == pygame.K_SPACE:
diceRoll
The rest of the code falls under this but the screen goes black when I do the loop with this.
To tell PyGame to quit correctly, you must do
if event.type == pygame.QUIT:
pygame.quit()
# perhaps force a quit using sys.exit()
If you're in a loop, you should also break that loop, using break
For the space bar event, you're already half-way there.
if event.key =0 pygame.K_SPACE:
roll_dice()
You are making a very big mistake with your first if statement. You are supposed to have the event.type lines in line with each other. You are doing this:
if event.type == pygame.KEYDOWN:
if event.type == pygame.QUIT:
when you should be doing this:
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
pass #Put your other code here
The second error is that you NEVER put pygame.quit in the while loop. It will exit the game/make the screen have nothing on it and make your program go crazy. The only logical way to safely exit the program inside the loop is with sys.exit().So your new while loop should be:
while True:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
print 'diceRoll' #Doing diceRoll alone won't do anything
pygame.quit() #This is the proper location of this function
I hope this helps you!
I'm using the pygame library. The following is pseudo code for my event handling for the player:
#generates multiple events for keys that are held down
pygame.key.set_repeat(30,30)
for event in pygame.event.get()
nextPos = currentPos
if(keyUp):
if event.key == w :
key_w = false
#do the same for s, a and d
if(keyDown):
if event.key == w:
key_w = true
#same for s,a and d
if(key_w):
#update nextPos
#do same for key_s, key_a and key_d
currentPos = nextPos
The problem is that sometimes when I move my mouse on the screen, and I'm pressing a key at the same time, while processing the events of the mouse, the events of the key are queued up, and these multiple keypresses are executed together, so that the player seems to jump a huge distance.
This problem is not caused if I don't move the mouse at all.
Update to my answer:
I checked my game code to see how I handle keys every frame and it seems that I don't get key information from the events but use pygame.key.get_pressed():
for event in pygame.event.get():
if event.type == pygame.QUIT:
gl.loop_main_loop = False # exit main loop and terminate
keys = pygame.key.get_pressed()
for key, state in enumerate(keys):
if (key in self.key_handlers) and state:
self.key_handlers[key]() # call key handler proc
That means that I only process each relevant key once per frame. The mouse can be read the way I describe below.
Just remember to use delta time in move vector calculation if your game doesn't have fixed frame rate.
Maybe the better idea is to during each process all keyboard event first and build your own key status representation, i.e. a structure which tell you which keys important to you (e.g. WSAD) are up or down. When all events have been processed in that frame, run you movement code using your key status data.
Do not use mousemotion events to track your mouse but read the position and buttons directly using pygame.mouse.get_pos() and pygame.mouse.get_pressed().
Your movement code should also take into account the fact that your game runs at variable frame rate (unless you forced pygame to keep the frame rate constant) and use time delta in your move vector calculations.
I use the following method...
I initialize the cooridinate variables...
x = 300
y = 300
pX = 0
pY = 0
In this case, x and y are the actual coordinates used by the player sprite, and pX and pY are used by the event handler.
Then I use the following code in the event handler...
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit(0)
if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
pX -= 2
if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
pX += 2
if event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
pY -= 2
if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
pY += 2
if event.type == pygame.KEYUP and event.key == pygame.K_LEFT:
pX += 2
if event.type == pygame.KEYUP and event.key == pygame.K_RIGHT:
pX -= 2
if event.type == pygame.KEYUP and event.key == pygame.K_UP:
pY += 2
if event.type == pygame.KEYUP and event.key == pygame.K_DOWN:
pY -= 2
Finally in the main game loop where the player's coordinates are handled, I put...
x += pX
y += pY
Maybe an event queue is not the best solution here, and instead, say, polling once per frame would be better?
I would not use pygame.event.get()
In my opinion, the best input for player movement pygame.key.get_pressed()
I would format it like this:
while True:
keys = pygame.key.get_pressed()
if keys[K_a]:
player.pos.x -= 10
if keys[K_d]:
player.pos.x += 10
if keys[K_w]:
player.pos.y -= 10
if keys[K_s]:
player.pos.y += 10
This way the system will check for pressed down keys on every frame.
I can't test right now sadly but do this
CODE:
import pygame, sys
clock = pygame.time.Clock()
playerX,playerY = 100,100 # Change 100 to the starting point you want
playerXc,playerYc = 0,0
while True:
playerX += playerXc
playerY += playerYc
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Keydown Events
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
playerYc = 1 # Change value to the speed you would like also change it to -1 if it goes wrong direction
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
playerXc = -1 # Change value to the speed you would like to change and set it to 1 if it goes the wrong direction
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
playerYc = -1 # Change value to the speed you would like also change it to 1 if it goes the wrong direction
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
playerXc = 1 # Change value to the speed you would like to change and set it to -1 if it goes the wrong direction
# Keyup Events
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
playerXc = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_w:
playerYc = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_s:
playerYc = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_d:
playerXc = 0
pygame.display.update()
clock.tick(60) # Change 60 to the framerate you would like so it runs smoother or the opposite.