Make images appear randomly and disappear after certain time - python

I am extremely confused as to how to approach this and I can't get it to work. So, if you have played snake before you will remember that at certain times an image would appear that if you ate that, you would get more points but if you missed it, it would disappear (i.e not stay there forever until you caught it.)
I have written code that works with time (allowing you to activate a shield) as below:
if (count % 35 == 0):
ang = random.choice(angles)
particles.append(Particle(red, 5, ang, user))
score += 10
score_graphic = font.render("Score " + str(score), 1, white)
total_shields += 1
if total_shields > 10:
total_shields = 10
count += 1
curr_time = time.time()
if space_press:
if (curr_time - new_time) > 0.3:
new_time = time.time()
total_shields -= 1
shield_on = total_shields > 0
How can I implement the disappearing image in pygame?
I know this is unconventional, but if you could help, I'd appreciate as I have not been able to do it for the past hour.
Best,
Seyed

use variables with time of start showing and end showing.
It is popular method to control different elements in game.
import pygame
import random
# - init -
pygame.init()
screen = pygame.display.set_mode((800, 600))
# - objects -
display_apple = False
start_showing = None
end_showing = None
current_time = pygame.time.get_ticks()
# show first time
start_showing = current_time + random.randint(1,5)*1000
# - mainloop -
clock = pygame.time.Clock()
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
# - updates -
current_time = pygame.time.get_ticks()
if display_apple:
# is it time to hide ?
if end_showing and current_time >= end_showing:
# hide it
display_apple = False
end_showinge = False
# set time when to show
start_showing = current_time + random.randint(1,5)*1000
else:
# is it time to show ?
if start_showing and current_time >= start_showing:
# show it
display_apple = True
start_showing = False
# set time when to hide
end_showing = current_time + random.randint(1,5)*1000
# - draws -
screen.fill((0,0,0))
if display_apple:
pygame.draw.rect(screen, (255,0,0), (0,0,100,100))
pygame.display.flip()
# - FPS -
clock.tick(30)
# - end -
pygame.quit()

Related

Pygame freezes when for loop is running even when using pygame.event.pump() [duplicate]

This question already has answers here:
Pygame window not responding after a few seconds
(3 answers)
Closed 5 months ago.
I'm currently making a rhythm game in Pygame and I have been trying to output "notes", but in my sprite class they are called enemies for a separate reason, based on the current time being the same(ish) to floats in a text file. However when I try to use the loop whether it be an infinite for loop or a while loop it cause the window to freeze whilst it's activated. I have tried pygame.event.pump() but that just makes it so that after the loop has ended it is no longer frozen.
Anything commented is what I have tried already.
import pygame
from sys import exit
class Enemies(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load(r'\slime.png').convert_alpha()
self.image = pygame.transform.rotozoom(self.image,0,4)
self.rect = self.image.get_rect(center = (1040,-50))
# def d_notes(self):
# keys = pygame.key.get_pressed()
# if keys[pygame.K_SPACE]:
# maps = beat_read()
# temp = list(maps)
# note = 0
# p_note = 0
# for x in iter(int, 1):
# pygame.event.pump()
# pygame.event.pump()
# if p_note == len(maps):
# break
# current_time = (pygame.time.get_ticks() / 1000) - start_time
# x_lower = maps[note] - 0.02
# x_upper = maps[note] + 0.02
# if x_lower <= current_time <= x_upper:
# out = temp.pop(0)
# print(out)
# note = note + 1
# p_note = p_note + 1
def update(self):
self.rect.y +=5
#self.d_notes()
def beat_read():
with open(r'\simple.txt') as f:
ll = []
for x in f:
x = float(x)
ll.append(x)
ll = tuple(ll)
return ll
# def d_notes():
# maps = beat_read()
# temp = list(maps)
# note = 0
# p_note = 0
# for x in iter(int,1):
# pygame.event.pump()
# pygame.event.pump()
# if p_note == len(maps):
# break
# current_time = (pygame.time.get_ticks() / 1000) - start_time
# x_lower = maps[note] - 0.02
# x_upper = maps[note] + 0.02
# if x_lower <= current_time <= x_upper:
# out = temp.pop(0)
# print(out)
# note = note + 1
# p_note = p_note + 1
# print(note)
# print(maps)
# print(temp)
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((1366,850))
pygame.display.set_caption('Rhythmic')
game_active = False
enemies_group = pygame.sprite.Group()
enemies_group.add(Enemies())
background = pygame.image.load(r'\background.png').convert()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
game_active = True
start_time = pygame.time.get_ticks() / 1000
# maps = beat_read()
# temp = list(maps)
# note = 0
# p_note = 0
# for x in iter(int, 1):
# pygame.event.pump()
# pygame.event.pump()
# if p_note == len(maps):
# break
# current_time = (pygame.time.get_ticks() / 1000) - start_time
# x_lower = maps[note] - 0.02
# x_upper = maps[note] + 0.02
# if x_lower <= current_time <= x_upper:
# out = temp.pop(0)
# print(out)
# note = note + 1
# p_note = p_note + 1
if game_active:
# d_notes()
screen.blit(background,(0,0))
enemies_group.draw(screen)
enemies_group.update()
pygame.display.flip()
clock.tick(60)
[Aside: User input handling does not belong in a Sprite class. ]
The for x in iter(int, 1): is an infinite loop, is this your intention?
So the code is:
If space was pressed:
Loop forever, doing:
touch the event handler
if the timing calculation is correct:
advance to next beat
print some stuff
check if we should exit the loop
I would say your timing-calculation check is never-ok.
Assuming you're writing some kind of follow-the-beat game, don't you need to repeatedly check for the time of the key-press, then check against the beat-time?
Also you need to advance the counters when the key-press has incorrect timing. I think this is the #1 reason it's getting stuck in the loop.
Probably you could (with a pencil and paper), re-work your control loop.
Load some beat-files.
Main Loop:
For every event:
Does the event say [space] was pressed?
Make a note of the press-timing
Do we have any beats left?:
Is it time for the next beat:
Advance to the next beat
else:
Show Game Over
Use the next beat-file, or whatever
Update any screen elements
Paint the screen
Was [space] pressed and is the timing accurate:
Increase player score (or whatever)

How do I get an animation to happen at the location my enemy was last at when the enemy is removed Pygame [duplicate]

I don't know why explosion effect doesn't happen.
The other images were drawn well, but only explosion image didn't
explosion = pygame.image.load(os.path.join(image_path, "explosion.png"))
explosion_size = explosion.get_rect().size
explosion_width = explosion_size[0]
for missile_idx, missile_val in enumerate(missiles):
missile_pos_x = missile_val[0]
missile_pos_y = missile_val[1]
#weapon information upgrade
missile_rect = missile.get_rect()
missile_rect.left = missile_pos_x
missile_rect.top = missile_pos_y
if missile_rect.colliderect(rock_rect):
explosion_sound.play()
**explosion_pos_x = missile_pos_x
explosion_pos_y = missile_pos_y
screen.blit(explosion,(explosion_pos_x,explosion_pos_y))**
del(rock)
del(missiles)
missiles = []
# missile position coordination
missiles = [[m[0], m[1] - missile_speed] for m in missiles]
# top missile elimination
missiles = [[m[0], m[1]] for m in missiles if m[1]>0]
The explosion is just shown for a short moment. Use pygame.time.get_ticks() to return the number of milliseconds since pygame.init() was called. Calculate the point in time after that the explosion image has to be removed. Add the coordinates of the explosion and the end time point to the head of a list (explosionList ). Draw the explosion(s) in the main application loop. Remove the expired explosions from the tail of the list:
explosionList = []
while run:
current_time = pygame.time.get_ticks()
# [...]
for missile_idx, missile_val in enumerate(missiles)
# [...]
if missile_rect.colliderect(rock_rect):
explosion_sound.play()
explosion_pos_x = missile_pos_x
explosion_pos_y = missile_pos_y
end_time = current_time + 2000 # 2000 milliseconds = 2 seconds
explosionList.insert(0, (end_time, explosion_pos_x, explosion_pos_y))
# [...]
for i in range(len(explosionList)):
if current_time < explosionList[i][0]:
screen.blit(explosion, (explosionList[i][1], explosionList[i][2]))
else:
explosionList = explosionList[:i]
break
# [...]
With this algorithm it is possible to manage multiple explosions.
See Time, timer event and clock
Minimal example
import pygame
pygame.init()
window = pygame.display.set_mode((210, 210))
def create_rectangles():
global rectangles
w, h = window.get_size()
rectangles = []
for x in range(0, w - 60, 60):
for y in range(0, h - 60, 60):
rectangles.append(pygame.Rect(x + 30, y + 30, 30, 30))
create_rectangles()
hit_list = []
fade_out_time = 3000
run = True
while run:
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
point = pygame.mouse.get_pos()
collideindex = pygame.Rect(point, (1, 1)).collidelist(rectangles)
if collideindex >= 0:
end_time = current_time + fade_out_time
hit_list.insert(0, (end_time, rectangles[collideindex].center))
del rectangles[collideindex]
if not hit_list and not rectangles:
create_rectangles()
window.fill(0)
for r in rectangles:
pygame.draw.rect(window, (255, 0, 0), r)
for i in range(len(hit_list)):
delta_time = hit_list[i][0] - current_time
if delta_time > 0:
radius = round(30 * delta_time / fade_out_time)
pygame.draw.circle(window, (255, 255, 0), hit_list[i][1], radius)
else:
hit_list = hit_list[:i]
break
pygame.display.flip()
If you want to show explosion image for a while this method can be useful.
explosion_list = [] # list for explosion effect
running = True
while running:
start_time = pygame.time.get_ticks() # add time for explosion effect
for missile_idx, missile_val in enumerate(missiles):
missile_pos_x = missile_val[0]
missile_pos_y = missile_val[1]
#weapon information upgrade
missile_rect = missile.get_rect()
missile_rect.left = missile_pos_x
missile_rect.top = missile_pos_y
if missile_rect.colliderect(rock_rect):
explosion_sound.play()
explosion_pos_x = missile_pos_x
explosion_pos_y = missile_pos_y
explosion_time = start_time + 2000 # 1000 milliseconds = 2 seconds
**explosion_list.insert(0, (explosion_time, explosion_pos_x, explosion_pos_y))**
del(rock)
del(missiles)
missiles = []
# missile position coordination
missiles = [[m[0], m[1] - missile_speed] for m in missiles]
# top missile elimination
missiles = [[m[0], m[1]] for m in missiles if m[1]>0]
**for i in range(len(explosion_list)):
if start_time < explosion_time:
pygame.display.update()
screen.blit(explosion, (explosion_pos_x - 30, explosion_pos_y - 30))
pygame.time.delay(10)**
else:
explosion_list = explosion_list[:i]

Disable Pygame MOUSEBUTTONDOWN/UP update on a given area/image after it's clicked once

I am new to python and Pygame. I am trying to make a Schulte table game.
Here's what the game is doing:
I have a 5 * 5 grid of total 25 pictures of numbers from 1-25.
(5*5 Schulte grid)
The number position is displayed in random order.
When you tap the correct number's picture, the number changes color. When you click on the wrong number, a sound is played to indicate the wrong click, and the number does not change color.
(Image changing colors or mouse click)
There's a start button and the restart button.
And finally, it displays the total elapsed time it took you to click all the numbers in order.
The program works as intended. Once a button is clicked, the colored number image is updated and a counter for each click is updated. But the problem is, if I click again on an already clicked number image, it keeps updating the counter.
For example, picture 1 is clicked, it turns red and now the click counter is 1. Then if I click again on the same picture 1, the program keep updating the counter. This way, if the counter reaches 25 even though I have not clicked all of the number pictures from 1-25 in order, the game will be over. I have tried to use pygame.event.set_allowed(pygame.MOUSEBUTTONDOWN), but it does not work(perhaps I don't know where in the loop to use it).
I am not sure where and how to exactly include this logic that the Mousebutton click will not update after a single click on the same picture. Please refer to the code below. Any help/tips is greatly appreciated. Thanks!
import pygame # import pygame library
import sys # import sys library
import random # import random library
import numpy as np # import numpy library
import itertools # Import the itertools library
import time # import time library
# Initialize settings
pygame.init() # Initialize pygame
size = width, height = 240, 320 # set the window size
screen = pygame.display.set_mode(size) # display the window
pygame.display.set_caption("Schulte Grid") # Give the window a name
# Image preparation
Xpts = [0, 48, 96, 144, 192]
Ypts = [0, 48, 96, 144, 192]
map = np.array(list(itertools.product(Xpts, Ypts))) # 25 picture coordinates
# load sound
wavFileName = 'sounds/fire.wav'
sndTrack = pygame.mixer.music.load(wavFileName)
# Timer text preparation
myfont = pygame.font.SysFont('Comic Sans MS', 60)
GREEN = (0, 255, 0)
BLUE = (0, 0, 128)
def ready():
global list1
list1 = [[i] for i in range(25)]
random.shuffle(list1)
# start interface
def start(start_page):
while start_page:
for event in pygame.event.get(): # Traverse all events
if event.type == pygame.QUIT: # if click to close the window, exit
sys.exit() # exit
screen.blit(pygame.image.load(
"pic/start-0.png"), (30, 190)) # show start screen
global t_x, t_y
t_x, t_y = pygame.mouse.get_pos() # Get the position of the mouse
if 30 <= t_x <= 200 and 190 <= t_y <= 250: # 18*50 #Mouse over the picture
screen.blit(pygame.image.load("pic/start-1.png"),
(30, 190)) # Get the mouse position and change color when moving to a certain position
if event.type == pygame.MOUSEBUTTONDOWN and 30 <= t_x <= 200 and 190 <= t_y <= 250:
start_page = False # start page
game_page = True # game page
global time_start # Define the global variable to start timing
time_start = time.time() # timing
pygame.display.flip() # update all display
# game interface
def gamepage(game_page):
# A variable is added here to make sure to start with the smallest number.
zero = 0
waiting_for_sleep_to_over = False
# The status of the question interface, it is guaranteed that only one question will be generated.
pic_zero = 1
while game_page:
while pic_zero:
for i in range(25): # must be 25 here
screen.blit(pygame.image.load(
"pic/pic" + str(*list1[i - 1]) + ".png"), map[i])
pic_zero = 0
for event in pygame.event.get(): # Traverse all events
if event.type == pygame.QUIT: # if click to close the window, exit
sys.exit()
for i in range(25):
# Determine the mouse position and whether it is pressed down. :
if event.type == pygame.MOUSEBUTTONDOWN and map[i][0] <= event.pos[0] <= map[i][0] + 48 and map[i][1] <= event.pos[1] <= map[i][1] + 48:
# print(i)
if int(*list1[i-1]) <= zero:
screen.blit(pygame.image.load(
"pic/qic" + str(*list1[i-1]) + ".png"), map[i]) # Display the color map
# waiting_for_sleep_to_over = True
zero = zero + 1
# if event.type == pygame.MOUSEBUTTONDOWN and map[i][0] <= event.pos[0] <= map[i][0] + 48 and map[i][1] <= event.pos[1] <= map[i][1] + 48:
# waiting_for_sleep_to_over = FALSE
# pygame.event.set_blocked(pygame.MOUSEBUTTONDOWN)
# time.sleep(0.5)
# zero = zero
# pygame.event.clear()
# pygame.event.set_allowed(pygame.MOUSEBUTTONDOWN)
print(zero)
if zero == 25:
time_end = time.time() # end timing
time_c = round(
time_end - time_start, 2) # time spent running
print('time cost:', int(time_c), 's')
textImage = myfont.render(
str(time_c) + 's', True, GREEN, BLUE)
screen.blit(textImage, (30, 250))
# screen.blit(pygame.image.load("pic/start-0.png"), (30, 210))
if event.type == pygame.MOUSEBUTTONDOWN and 30 <= t_x <= 210 and 200 <= t_y <= 250:
start_page = True
game_page = False
pygame.display.flip() # update all display
else:
pygame.mixer.music.play() # play music on error
pygame.display.flip() # update all display
# main loop
start_page = True
game_page = True
while True:
ready()
start(start_page)
gamepage(game_page)
The line if int(*list1[i-1]) <= zero: should be if int(*list1[i-1]) == zero:.

Pygame beginner, player animation not working despite doing it by the tutorial

First time ever working with Pygame for a school assignment and I'm following a tutorial for it with my project members (tutorial link https://youtu.be/AY9MnQ4x3zk).
Problem is that despite following the tutorial to the dot at the "animating the player", my character (named "Marko" in the game and code) doesn't have his animation playing. When I start the game the character is stuck on it's first frame of animation. I've created a 3-frame animation and have the frames as separate png-files. The game so far itself works (it's on very beginner level, just a couple spawning enemies, collision and intro screens done so far), but the animation has had me and my project group scratching our heads for days. So far haven't found a solution by Googling nor searching here.
Also at the "# Marko's animations" -part "marko" is darkened and when hovering mouse on it, it says ""(variable) marko: Surface - "marko" is not accessed Pylance""
Here's the entire code:
import sys
from pygame.locals import *
from random import randint
from pygame import mixer
pygame.init()
width = 1920
height = 1080
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption("Putkimies Marko")
start_time = 0
score = 0
nopeus = [3,3]
clock = pygame.time.Clock()
game_active = False
marko_gravity = 0
# Score
def display_score():
current_time = int(pygame.time.get_ticks() / 1000) - start_time
score_surf = test_font.render(f'Score: {current_time}',False,(black))
score_rect = score_surf.get_rect(center = (900,50))
screen.blit(score_surf,score_rect)
return current_time
def obstacle_movement(obstacle_list):
if obstacle_list:
for obstacle_rect in obstacle_list:
obstacle_rect.x -= 5
if obstacle_rect.bottom == 955:
screen.blit(rat,obstacle_rect)
else:
screen.blit(fly,obstacle_rect)
return obstacle_list
else: return[]
def collisions(marko,obstacles):
if obstacles:
for obstacle_rect in obstacles:
if marko.colliderect(obstacle_rect): return False
return True
# Surfaces
background = pygame.image.load("marko_background.png").convert_alpha()
sewer = pygame.image.load("background_sewer.png").convert_alpha()
ground = pygame.image.load("ground.png").convert_alpha()
rat = pygame.image.load("rat.png").convert_alpha()
game_over = pygame.image.load("game_over.png").convert_alpha()
fly = pygame.image.load("fly.png").convert_alpha()
# Marko Surfaces
marko_run_1 = pygame.image.load("marko_run_1.png").convert_alpha()
marko_run_2 = pygame.image.load("marko_run_2.png").convert_alpha()
marko_run_3 = pygame.image.load("marko_run_3.png").convert_alpha()
marko_run = [marko_run_1,marko_run_2,marko_run_3]
marko_index = 0
marko_jump = pygame.image.load("marko_jump.png").convert_alpha()
marko = marko_run[marko_index]
# Fonts
test_font = pygame.font.Font("supermario.ttf", 50)
# Colors
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
light_blue = (94,129,162)
purple = (36,5,83)
# Rects
game_overSurface = game_over.get_rect(midtop = (970,-200))
platform = pygame.Surface((300,50))
groundSurface = ground.get_rect(midtop = (960,480))
markoSurface = marko.get_rect()
text_surface = test_font.render('Putkimies Marko', False, red)
markoSurface.left = 50
markoSurface.bottom = 714
# Obstacles
obstacle_rect_list = []
# Intro screen
player_stand = pygame.image.load("putkimies_marko_idle.png")
player_stand = pygame.transform.rotozoom(player_stand,0,2)
player_stand_rect = player_stand.get_rect(center = (950,500))
game_name = test_font.render("PUTKIMIES MARKO", False,"Black")
game_name_rect = game_name.get_rect(center = (950,350))
game_message = test_font.render('PRESS SPACE TO PLAY',False,"Black")
game_message_rect = game_message.get_rect(center = (950,650))
game_message_start_again = test_font.render('PRESS SPACE TO PLAY AGAIN',False,"Black")
game_message_start_again_rect = game_message.get_rect(center = (850,720))
# Marko's animations
def marko_animation():
global markoSurface, marko_index
if markoSurface.bottom < 955:
marko = marko_jump
else:
marko_index += 0.1
if marko_index >= len(marko_run):marko_index = 0
marko = marko_run[int(marko_index)]
# Timer
obstacle_timer = pygame.USEREVENT + 1
pygame.time.set_timer(obstacle_timer,1500)
# Background music
mixer.music.load('smb_stage_clear.wav')
mixer.music.play(0)
# -1 Makes the music loop
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if game_active:
if event.type == KEYDOWN:
if event.key == K_SPACE and markoSurface.bottom >= 955:
marko_gravity = -18
else:
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
game_active = True
start_time = int(pygame.time.get_ticks() / 1000)
if event.type == obstacle_timer and game_active:
if randint (0,2):
obstacle_rect_list.append(rat.get_rect(midbottom = (randint(2000,2200),955)))
else:
obstacle_rect_list.append(fly.get_rect(midbottom = (randint(2000,2200),855)))
if game_active:
# Draw
screen.blit(sewer, (0,0))
screen.blit(ground, (0,955))
marko_animation()
screen.blit(marko,markoSurface)
score = display_score()
# Key uses
key_use = pygame.key.get_pressed()
if key_use[K_LEFT]:
markoSurface.move_ip((-7,0))
if key_use[K_RIGHT]:
markoSurface.move_ip((7,0))
# Marko
marko_gravity += 1
markoSurface.y += marko_gravity
if markoSurface.bottom >= 955: markoSurface.bottom = 955
if markoSurface.left <= 0: markoSurface.left = 0
if markoSurface.right >= 1920: markoSurface.right = 1920
# Obstacle movement
obstacle_rect_list = obstacle_movement(obstacle_rect_list)
# Collision
game_active = collisions(markoSurface,obstacle_rect_list)
else: # Intro screen
screen.fill ("Light blue")
screen.blit(player_stand,player_stand_rect)
obstacle_rect_list.clear()
markoSurface.left = 80 # returns marko to 80
# Draws score message if score > 0
score_message = test_font.render(f'Your score: {score}',False,(red))
score_message_rect = score_message.get_rect(center = (950,650))
screen.blit(game_name,game_name_rect)
if score == 0: screen.blit(game_message,game_message_rect)
else:
screen.blit(score_message,score_message_rect)
screen.blit(game_over,game_overSurface)
screen.blit(game_message_start_again,game_message_start_again_rect)
pygame.display.update()
clock.tick(60)```
marko is a variable in global namespace. You must use the global statement to change a variable in the global namespace within a function:
def marko_animation():
global marko # <---
global marko_index
if markoSurface.bottom < 955:
marko = marko_jump
else:
marko_index += 0.1
if marko_index >= len(marko_run):
marko_index = 0
marko = marko_run[int(marko_index)]

Python time counter in Pygame-mouse events

I want to calculate the time of user's mouse events in Pygame, if user doesn't move his mouse about 15 seconds, then I want to display a text to the screen. I tried time module for that, but it's not working.
import pygame,time
pygame.init()
#codes
...
...
font = pygame.font.SysFont(None,25)
text = font.render("Move your mouse!", True, red)
FPS = 30
while True:
#codes
...
...
start = time.time()
cur = pygame.mouse.get_pos() #catching mouse event
end = time.time()
diff = end-start
if 15 < diff:
gameDisplay.blit(text,(10,500))
pygame.display.update()
clock.tick(FPS)
pygame.quit()
quit()
Well output is not what I want, I don't know how to calculate it if user doesn't move his mouse.
If I want to write a text when user's mouse in a special area, it's working like;
if 100 < cur[0] < 200 and 100 < cur[1] < 200:
gameDisplay.blit(text,(10,500))
But how can I calculate? I even couldn't find how to tell Python, user's mouse is on the same coordinates or not.Then I can say, if mouse coordinates changes, start the timer, and if it's bigger than 15, print the text.
Edit: You can assume it in normal Python without Pygame module, assume you have a function that catching the mouse events, then how to tell Python if coordinates of mouse doesn't change, start the timer, if the time is bigger than 15 seconds,print a text, then refresh the timer.
To display a text on the screen if there is no mouse movement within the pygame window for 3 seconds:
#!/usr/bin/python
import sys
import pygame
WHITE, RED = (255,255,255), (255,0,0)
pygame.init()
screen = pygame.display.set_mode((300,200))
pygame.display.set_caption('Warn on no movement')
font = pygame.font.SysFont(None, 25)
text = font.render("Move your mouse!", True, RED, WHITE)
clock = pygame.time.Clock()
timer = pygame.time.get_ticks
timeout = 3000 # milliseconds
deadline = timer() + timeout
while True:
now = timer()
if pygame.mouse.get_rel() != (0, 0): # mouse moved within the pygame screen
deadline = now + timeout # reset the deadline
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(WHITE)
if now > deadline: # no movement for too long
screen.blit(text, (10, 50))
pygame.display.flip()
clock.tick(60) # set fps
You should add:
start = time.time()
cur = None
before while loop.
You should also change start = time.time() in while loop to:
if cur != pygame.mouse.get_pos():
start = time.time()
Also you could use pygame.time (it's similar to time but measure time in milliseconds)
In your code, the while True: code block is continuously running. The cur = pygame.mouse.get_pos() function is non blocking. This means it does not wait for mouse input - it will return straight away. So you need to initialize the start and cur variables before your while True: code block and then check the mouse position constantly in your loop.
If cur has changed since the last time the loop ran, then reset the start variable to the current time, and if the difference between the current time and start becomes larger than your 15 seconds, you can display the text.
You can also do that even without getting time, since you can calculate the pause as an integer counter through your FPS. Consider following example. Note that if the cursor is out of the window, the values of its positon will not change even if you move the cursor.
import pygame
pygame.init()
clock = pygame.time.Clock( )
DISP = pygame.display.set_mode((600, 400))
FPS = 25
Timeout = 15
Ticks = FPS*Timeout # your pause but as an integer value
count = 0 # counter
MC = pygame.mouse.get_pos()
MC_old = MC
MainLoop = True
while MainLoop :
clock.tick(FPS)
pygame.event.pump()
Keys = pygame.key.get_pressed()
if Keys[pygame.K_ESCAPE]:
MainLoop = False
MC = pygame.mouse.get_pos() # get mouse position
if (MC[0]-MC_old[0] == 0) and (MC[1]-MC_old[1] == 0) :
count = count + 1
else : count = 0
if count > Ticks :
print "What are you waiting for"
count = 0
MC_old = MC # save mouse position
pygame.display.flip( )
pygame.quit( )

Categories