I have a ball animation and I want it so that it that runs until you CLOSE the program (A.K.A until pygame.QUIT is activated) And then after pygame.QUIT is activated it will count down from 10 seconds before it closes.
(PS. If you're an admin of this website the other post you send me doesn't help with my specific problem)
import pygame
import random
pygame.init()
window = pygame.display.set_mode([400,400])
c = pygame.time.Clock()
black = (0,0,0)
white = (255,255,255)
x = random.randint(10,390)
y = random.randint(10,390)
speed_x = random.randint(3,5)
speed_y = random.randint(3,5)
time = 10
#this is definitely wrong so this where I need help on
playing = True
while playing:
for event in pygame.event.get():
if event.type == pygame.QUIT:
time -= 1
print(time)
pygame.time.wait(1000)
time -= 1
print(time)
pygame.time.wait(1000)
time -= 1
print(time)
pygame.time.wait(1000)
time -= 1
print(time)
pygame.time.wait(1000)
time -= 1
print(time)
pygame.time.wait(1000)
time -= 1
print(time)
pygame.time.wait(1000)
time -= 1
print(time)
pygame.time.wait(1000)
time -= 1
print(time)
pygame.time.wait(1000)
time -= 1
print(time)
pygame.time.wait(1000)
time -= 1
print(time)
pygame.time.wait(1000)
if time == 0:
playing = False
x += speed_x
y += speed_y
window.fill((white))
pygame.draw.circle(window,black,(x,y),20)
if x > 390 or x < 10:
speed_x = speed_x * -1
if y > 390 or y < 10:
speed_y = speed_y * -1
c.tick(60)
pygame.display.flip()
Instead of exiting the application, start a countdown timer. Quit the application when the countdown is complete.
See Countdown timer in Pygame.
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((200, 200))
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 100)
counter = 0
text = font.render(str(10), True, (0, 128, 0))
timer_event = pygame.USEREVENT+1
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
counter = 10
pygame.time.set_timer(timer_event, 1000)
elif event.type == timer_event:
counter -= 1
text = font.render(str(counter), True, (0, 128, 0))
if counter == 0:
run = False
window.fill((255, 255, 255))
# draw game
# [...]
if counter > 0:
text_rect = text.get_rect(center = window.get_rect().center)
window.blit(text, text_rect)
pygame.display.flip()
pygame.quit()
exit()
Related
This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?
(1 answer)
Closed 4 months ago.
Hello i need to programm a Game with pygame for school. I nearly finish the Game but when i want to Press the "C" button in the Gameover loop then nothing happends and the game will not restart.
unti i spam the "C" Button. I dont think that there is a problem with the detection of pressing the button because i made a print command thatalways prints something when i press the "C" Button and it always print something out.
I hope you can help me with the Problem :)
from turtle import pos
import pygame
import time
from pygame.locals import *
import random
pygame.init()
dis_width = 600
dis_height = 400
pos_x = 303
pos_y = 370
x_change = 0
y_change = 0
enemie_pos_x = random.randint(180, 420)
enemie_pos_y = 30
clock = pygame.time.Clock()
screen=pygame.display.set_mode((dis_width, dis_height))
font_style = pygame.font.SysFont("bahnschrift", 25)
time_font = pygame.font.SysFont("bahnschrift", 25)
running=True
obj = False
obj2 = False
enemie = False
game_over = False
crash = True
start = time.time() + 0.1
tolleranz = 40
speed = 5
timer = 5
score = 0
displayscore = 0
highscore = 0
ROT = (255, 0, 0)
BLACK = (0, 0, 0)
pygame.display.update()
def stopwatch(time):
value = time_font.render("Time: " + str(time), True, ROT)
screen.blit(value, [0, 0])
value2 = time_font.render("Score: " + str(score), True, ROT)
screen.blit(value2, [0, 30])
value6 = time_font.render("HighScore: " + str(highscore), True, ROT)
screen.blit(value6, [0, 60])
def enemies():
counter = 1
global enemie_pos_x, enemie_pos_y, speed, aTimeRound, timer, displayscore, highscore
enemie_pos_y += speed
if aTimeRound > timer:
speed += 5
timer += 5
if enemie_pos_y > 430:
enemie_pos_y = 0
enemie_pos_x = random.randint(180, 420)
global score
score += 1
if highscore <= score:
if highscore != score:
highscore += 1
displayscore = score
def gameoverF():
global score, start, speed, timer, game_over, displayscore, highscore
screen.fill(BLACK)
value3 = time_font.render("GAMEOVER", True, ROT)
screen.blit(value3, [230, 100])
value6 = time_font.render("Score:" + str(displayscore), True, ROT)
screen.blit(value6,[230, 150])
value4 = time_font.render("Highscore: " + str(highscore), True, ROT)
screen.blit(value4,[225, 200])
value5 = time_font.render("Press 'C' to play again OR Press 'Q' to Quit", True, ROT)
screen.blit(value5,[70,250])
score = 0
start = time.time()
speed = 5
timer = 5
pygame.display.update()
while running:
while game_over == True:
for event in pygame.event.get(): # Bei jeden GameLoop die Liste an Events abfragen
if event.type == pygame.QUIT:
running = False
pygame.quit()
quit()
if event.type == pygame.KEYDOWN: # Prüfen, ob der Eventtyp ein Tastendruck ist
if event.key == ord("c"): # Prüfen, ob die Cursor-Links-Taste gedrückt wurde...
game_over = False
speed = 5
timer = 5
score = 0
print("GEDRÜCKT!!!!!!!")
if event.key == ord("q"):
pygame.quit()
gameoverF()
#Messung der Zeit
aTime = time.time()-start
aTimeRound = round(time.time()-start,1)
#print(aTime)
#Malen der Steuer Kugel und der Linien
pos_x += x_change
screen.fill(BLACK)
pygame.draw.line(screen, ROT, (150,0),(150,400), 10)
pygame.draw.line(screen, ROT, (450,0),(450,400), 10)
pygame.draw.circle(screen, [255,255,255],(pos_x,pos_y), 25)
stopwatch(aTimeRound)
enemies()
pygame.draw.circle(screen, [255,255,255],(enemie_pos_x,enemie_pos_y), 25)
#print( enemie_pos_x - pos_x)
check_x = pos_x - enemie_pos_x
if check_x < 0:
check_x = check_x * -1
print(check_x)
if check_x < tolleranz and pos_y - enemie_pos_y < tolleranz:
game_over = True
clock.tick(30)
if pos_x <= 192:
pos_x = 192
if pos_x >= 410:
pos_x = 410
for event in pygame.event.get(): # Bei jeden GameLoop die Liste an Events abfragen
if event.type == pygame.QUIT:
running = False
pygame.quit()
quit()
if event.type == pygame.KEYDOWN: # Prüfen, ob der Eventtyp ein Tastendruck ist
if event.key == pygame.K_LEFT or event.key == ord("a"): # Prüfen, ob die Cursor-Links-Taste gedrückt wurde...
x_change = -10
y_change = 0 # Aktion bei Cursor-Links
if event.key == pygame.K_RIGHT or event.key == ord("d"):
x_change = 10
y_change = 0
pygame.display.update()
gameoverF()
Played your game got highscore of 22 oh I mean I read the code and and I debugged it
Well actually playing was the debugging haha. The problem is that after you press C game restarts as it should but the enemy which hit you is not removed and it instantly kills you again and moves tiny bit lower. By spamming C you move it out of screen and game continues
Simple fix to reset enemy pose when C is pressed
if event.key == ord("c"):
enemie_pos_y = 30 # Reset enemy pose
Keep up the good work!
I'm trying to build a space invader-like game for fun.
It's mostly done, but when I shoot the enemy I want the text on the screen with his health to decrease.
Here is my code stripped only to the health updating part:
import pygame
from sys import exit
enemy_health = 10
pygame.init()
win = pygame.display.set_mode((1000, 1000))
pygame.display.set_caption("Fighter Pilot Go!")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 55)
enemy_health_text = font.render(f'Enemy Health: {enemy_health}', False, 'white')
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
enemy_health_text -= 1
win.blit(enemy_health_text, (350, 60)
That's not all of the game, but it's the basic idea.
The score doesn't update in the game till a laser hits the enemy.
Here is the whole game, if the code helps you understand my issue:
import pygame
from sys import exit
import random
speed = 5
laser_speed = 7
bullets = []
score = 0
max_num_of_bullet = 3
background_speed = 3
enemy_health = 10
direction = True
enemy_speed = 7
pygame.init()
win = pygame.display.set_mode((1000, 1000))
pygame.display.set_caption("Fighter Pilot Go!")
clock = pygame.time.Clock()
background1 = pygame.image.load('assets/background.gif')
background2 = pygame.image.load('assets/background.gif')
background1_rect = background1.get_rect(topleft=(0, 0))
background2_rect = background2.get_rect(topleft=(0, -1000))
player = pygame.image.load('assets/player.gif')
player_rect = player.get_rect(midtop=(500, 750))
enemy = pygame.image.load('assets/enemy.gif')
enemy_rect = enemy.get_rect(center=(500, 350))
laser = pygame.image.load('assets/laser.gif')
# laser_rect = laser.get_rect(midtop=(500, 800))
font = pygame.font.Font(None, 55)
enemy_health_text = font.render(f'Enemy Health: {enemy_health}', False, 'white')
def is_collided_with(a, b):
return abs(a[0] - b.centerx) < 51 and abs(a[1] - b.centery) < 51
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
if len(bullets) <= max_num_of_bullet - 1:
bullets.append([player_rect.x + 49, player_rect.y - 60])
elif len(bullets) > max_num_of_bullet - 1:
continue
else:
print("Something Weird is Happening!")
key = pygame.key.get_pressed()
if key[pygame.K_a]:
player_rect.x -= speed
if key[pygame.K_d]:
player_rect.x += speed
win.blit(background1, background1_rect)
win.blit(background2, background2_rect)
win.blit(player, player_rect)
win.blit(enemy, enemy_rect)
background1_rect.y += background_speed
background2_rect.y += background_speed
if direction:
enemy_rect.x -= enemy_speed
elif not direction:
enemy_rect.x += enemy_speed
if enemy_rect.x <= 0:
direction = False
elif enemy_rect.x >= 900:
direction = True
if player_rect.x < -20:
player_rect.x = 1020
if player_rect.x > 1020:
player_rect.x = -20
for bullet in bullets:
win.blit(laser, bullet)
for bullet in bullets:
bullet[1] -= laser_speed
win.blit(enemy_health_text, (350, 60))
for bullet in bullets:
if is_collided_with(bullet, enemy_rect):
bullets.remove(bullet)
enemy_health -= 1
for bullet in bullets:
if bullet[1] < 0:
bullets.remove(bullet)
if background1_rect.y >= 1000:
background1_rect.topleft = (0, -1000)
if background2_rect.y >= 1000:
background2_rect.topleft = (0, -1000)
if enemy_health <= 0:
pass
pygame.display.update()
clock.tick(60)
Any help would be appreciated. :) Thanks!
The text is rendered in the enemy_health_text Surface with the value of enemy_health. You have to change enemy_health and render the text again:
font = pygame.font.Font(None, 55)
enemy_health_text = font.render(f'Enemy Health: {enemy_health}', False, 'white')
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
enemy_health -= 1
enemy_health_text = font.render(f'Enemy Health: {enemy_health}', False, 'white')
win.fill(0)
win.blit(enemy_health_text, (350, 60)
pygame.display.flip()
I am trying to create a reaction time test game in python using pygame for gui. Since, I am fairly new to the technology, I am stuck at a portion of the code as how to register further keypresses and then record time accordingly.
This is my code till now:
import pygame
from datetime import datetime
import time
import random
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Reaction Time Test")
font = pygame.font.SysFont(None, 30)
text = font.render("PRESS ANY KEY TO START TEST", 0, (255,255,255))
w = font.render("PRESS ANY KEY",0,(0,255,0))
count = 0
screen.blit(text, (150,240))
running = True
while running:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
if count <= 5 and event.type == pygame.KEYDOWN:
screen.fill(pygame.Color("black"))
pygame.display.flip()
wait_time = random.randint(1,4)
time.sleep(wait_time)
reaction_start = datetime.now()
print(reaction_start)
screen.blit(w,(225,200))
count = count + 1
if event.type == pygame.KEYDOWN:
reaction_end = datetime.now()
print(reaction_end)
t = reaction_end - reaction_start
print(t)
f = font.render("REACTION TIME: "+ str(t),0,(255,255,255))
screen.blit(f,(225,300))
if count > 5:
screen.fill(pygame.Color("black"))
pygame.display.flip()
s = font.render("AVERAGE REACTION TIME IS: ",0,(255,255,255))
screen.blit(s,(150,200))
pygame.display.flip()
The part where I am stuck at it is this code snippet
if count <= 5 and event.type == pygame.KEYDOWN:
screen.fill(pygame.Color("black"))
pygame.display.flip()
wait_time = random.randint(1,4)
time.sleep(wait_time)
reaction_start = datetime.now()
print(reaction_start)
screen.blit(w,(225,200))
count = count + 1
if event.type == pygame.KEYDOWN:
reaction_end = datetime.now()
print(reaction_end)
t = reaction_end - reaction_start
print(t)
f = font.render("REACTION TIME: "+ str(t),0,(255,255,255))
screen.blit(f,(225,300))
It would register the reaction_start and reaction_end almost simulataneously and would not wait for the key press.
This currently prints both the statements "PRESS ANY KEY" and "REACTION TIME:" together, but when I had put the statements of screen.fill(pygame.Color("black") and pygame.display.flip() before the screen.blit(f), it would only show REACTION TIME: and not "PRESS ANY KEY"
In pygame the system time can be obtained by calling pygame.time.get_ticks(), which returns the number of milliseconds since pygame.init() was called.
Do not try to delay or to wait in the application loop. Add a game_state variabel, that which can have the states "start", "wait" and "wait_for_reaction".
Get the current time at the begin of the application loop:
while running:
current_time = pygame.time.get_ticks()
Set the start time when a key is pressed:
if event.type == pygame.KEYDOWN:
if game_state == "start":
game_state = "wait"
start_time = current_time + random.randint(1000, 4000)
Chang the game_state form "wait" to "wait_for_reaction" when the current time is greater or equal the start time:
if game_state == "wait":
if current_time >= start_time:
game_state = "wait_for_reaction"
Compute the reaction time and restart the process, when a key is hit again:
if event.type == pygame.KEYDOWN:
# [...]
if game_state == "wait_for_reaction":
game_state = "wait"
reaction_time = (current_time - start_time) / 1000
start_time = current_time + random.randint(1000, 4000)
count += 1
average_time = (average_time * (count-1) + reaction_time) / count
r_surf = font.render(f"REACTION TIME: {reaction_time:.03f}",0,(255,255,255))
ar_surf = font.render(f"AVERAGE REACTION TIME IS: {average_time:.03f}",0,(255,255,255))
Redraw the scene in every frame, dependent on the state of the game:
while running:
# [...]
screen.fill(pygame.Color("black"))
center = screen.get_rect().center
if game_state == "start":
screen.blit(text, text.get_rect(center = center))
if game_state == "wait_for_reaction":
screen.blit(w, w.get_rect(center = center))
if r_surf:
screen.blit(r_surf, r_surf.get_rect(center = (center[0], 350)))
if ar_surf:
screen.blit(ar_surf, ar_surf.get_rect(center = (center[0], 400)))
pygame.display.flip()
Complete example:
import pygame
import random
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Reaction Time Test")
font = pygame.font.SysFont(None, 30)
text = font.render("PRESS ANY KEY TO START TEST", 0, (255,255,255))
w = font.render("PRESS ANY KEY",0,(0,255,0))
r_surf = None
ar_surf = None
game_state = "start"
start_time = 0
average_time = 0
count = 0
running = True
while running:
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
if event.type == pygame.KEYDOWN:
if game_state == "start":
game_state = "wait"
start_time = current_time + random.randint(1000, 4000)
if game_state == "wait_for_reaction":
game_state = "wait"
reaction_time = (current_time - start_time) / 1000
start_time = current_time + random.randint(1000, 4000)
count += 1
average_time = (average_time * (count-1) + reaction_time) / count
r_surf = font.render(f"REACTION TIME: {reaction_time:.03f}",0,(255,255,255))
ar_surf = font.render(f"AVERAGE REACTION TIME IS: {average_time:.03f}",0,(255,255,255))
if game_state == "wait":
if current_time >= start_time:
game_state = "wait_for_reaction"
screen.fill(pygame.Color("black"))
center = screen.get_rect().center
if game_state == "start":
screen.blit(text, text.get_rect(center = center))
if game_state == "wait_for_reaction":
screen.blit(w, w.get_rect(center = center))
if r_surf:
screen.blit(r_surf, r_surf.get_rect(center = (center[0], 350)))
if ar_surf:
screen.blit(ar_surf, ar_surf.get_rect(center = (center[0], 400)))
pygame.display.flip()
I am building a mole shooter game. I want to be able to restart the game when you press the space bar. I have currently set it to 'a' for testing purposes but that also doesn't seem to be working. I need help to restart my game without exiting the program.
I have added /// to the area where I seem to be facing a problem. I also need a way to reset my score and counter.
import pygame
import random
import time
from threading import Timer
pygame.font.init()
win_width = 1000
win_height = 710
FPS = 90
screen = pygame.display.set_mode((win_width, win_height))
pygame.display.set_caption("Mole Shooter")
white = (255, 255, 255)
red = (255, 0, 0)
counter, text = 30, 'Time Left: 30'.rjust(3)
font = pygame.font.Font('freesansbold.ttf', 32)
score = pygame.font.Font('freesansbold.ttf', 32)
score_text = 'Score: 0'.rjust(3)
run = True
clock = pygame.time.Clock()
background = pygame.transform.scale(pygame.image.load('back_land.png'), (win_width, win_height))
aim = pygame.image.load("aim.png")
mole = pygame.image.load("mole.png")
moles = []
score_check = 0
def mole_spawn_easy():
molex = random.randint(50, 950)
moley = random.randint(450, 682)
moles.append((molex, moley))
pygame.time.set_timer(pygame.USEREVENT, 1000)
# pygame.time.set_timer(pygame.USEREVENT, 1000)
# mask = pygame.mask.from_surface(mole.png)
def paused():
largeText = pygame.font.Font("freesansbold.ttf", 115)
# TextSurf, TextRect = text_objects("Your Score: " + score_check, largeText)
# TextRect.center = ((display_width/2),(display_height/2))
# screen.blit(TextSurf, TextRect)
final_score = ('Your Score: ' + str(score_check)).rjust(3)
screen.blit(score.render(final_score, True, (0, 0, 0)), (((win_width / 2) - 100), (win_height / 2)))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
# gameDisplay.fill(white)
# button("Continue",150,450,100,50,green,bright_green,unpause)
# button("Quit",550,450,100,50,red,bright_red,quitgame)
pygame.display.update()
clock.tick(15)
def main():
global FPS
global screen
global counter
global text
global font
global score
global score_text
global run
global background
global aim
global mole
global moles
global score_check
global clock
while run:
ax, ay = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.USEREVENT:
counter -= 1
text = ("Time Left: " + str(counter)).rjust(3)
if counter > 0:
mole_spawn_easy()
else:
# print("game over")
paused()
///if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
main()
counter = 30///
if event.type == pygame.MOUSEBUTTONDOWN:
mx = mole.get_width()
my = mole.get_height()
for i in moles:
if ax in range(i[0], i[0] + int(mx)) and ay in range(i[1], i[1] + int(my)):
# print("hit")
score_check += 1
score_text = ("Score: " + str(score_check)).rjust(3)
screen.blit(background, [0, 0])
for pos in moles:
screen.blit(mole, pos)
# print(pos)
if len(moles) >= 2:
del (moles[0])
screen.blit(aim, ((ax - 32), (ay - 32)))
screen.blit(font.render(text, True, (0, 0, 0)), (32, 48))
screen.blit(score.render(score_text, True, (0, 0, 0)), (800, 48))
clock.tick(FPS)
pygame.display.flip()
main()
Your indenting is incorrect in this section:
if event.type == pygame.USEREVENT:
counter -= 1
text = ("Time Left: " + str(counter)).rjust(3)
if counter > 0:
mole_spawn_easy()
else:
# print("game over")
paused()
///if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
main()
counter = 30///
You have the if testing for the event.KEYDOWN inside the if that tested if the event was a USEREVENT, so it will never match. It needs to be like this:
if event.type == pygame.USEREVENT:
counter -= 1
text = ("Time Left: " + str(counter)).rjust(3)
if counter > 0:
mole_spawn_easy()
else:
# print("game over")
paused()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
main()
counter = 30
However, I should point out a different issue I see with your code structure. To restart the game you are calling main(), but you are doing that from inside main(), causing it to be recursive. You would be better off to do this in a non recursive way. perhaps move the run loop to a new method that main calls and then have the above exit from that and then main can recall it or something.
Just break the run loop whenever you want, set the default values of your variables after that loop, and call to main again.
if event.type == pygame.USEREVENT:
counter -= 1
text = ("Time Left: " + str(counter)).rjust(3)
if counter > 0:
mole_spawn_easy()
else:
# print("game over")
paused()
if event.type == pygame.KEYDOWN:
break
After run loop:
# Prev code ....
screen.blit(font.render(text, True, (0, 0, 0)), (32, 48))
screen.blit(score.render(score_text, True, (0, 0, 0)), (800, 48))
clock.tick(FPS)
pygame.display.flip()
reset_vars() // You have to implement this method or reset your variables here
main()
I've got a variable that increases when the user presses a button.
When the user presses another button, I'd like to set that variable to 0,
but not instantly-- I'd like it to tick down over the course of a few seconds.
During this time I'd like the user to be able to perform other actions-- hence why I'm not using sleep.
I've looked at using pygame's events, time.clock, etc., but I can't seem to get this to work. Here is what I've tried so far:
import pygame, sys, math
from pygame.locals import *
pygame.init()
pygame.font.init()
scrw = 640
scrh = 480
screen = pygame.display.set_mode((scrw, scrh))
ttwist = 0
recentering = False
fps = 15
clock = pygame.time.Clock()
my_font = pygame.font.SysFont("arial", 12)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pressed = pygame.key.get_pressed()
if not recentering:
if pressed[pygame.K_d]:
ttwist +=1
if pressed[pygame.K_a]:
ttwist -=1
RECENTERTORSOEVENT = USEREVENT
if event.type == pygame.KEYDOWN and event.key == pygame.K_BACKSLASH:
recentering = True
pygame.time.set_timer(RECENTERTORSOEVENT, 1000*abs(ttwist))
if ttwist == 0:
recentering = False
if event.type == USEREVENT:
if ttwist < 0:
ttwist += 1
elif ttwist > 0:
ttwist -= 1
drawtext = my_font.render("TTWIST:"+str(ttwist), True, (255,255,255),(0,0,0))
screen.blit(drawtext,(10,130))
pygame.display.update()
clock.tick(fps)
What am i doing wrong?
You are on the right track, but some parts of the code need to be changed:
All the if event.type == ... blocks should be inside of the event loop.
RECENTERTORSOEVENT = USEREVENT should be defined above the while loop (but that doesn't cause problems).
You're setting the time interval for the RECENTERTORSOEVENT way too high: 1000*abs(ttwist). That means, if the ttwist is 10, you're setting it to 10.000 ms (10 seconds). Just set it to a constant value like 100 ms.
When the ttwist is recentered, call pygame.time.set_timer(RECENTERTORSOEVENT, 0) to stop the timer.
Fill the screen each frame screen.fill((30, 30, 30)), otherwise you see artifacts because the font surface keeps changing its size.
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
my_font = pygame.font.SysFont('arial', 22)
clock = pygame.time.Clock()
ttwist = 0
RECENTERTORSOEVENT = pygame.USEREVENT
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
print('recentering')
# Start to add the USEREVENT every 100 ms.
pygame.time.set_timer(RECENTERTORSOEVENT, 100)
elif event.type == RECENTERTORSOEVENT:
ttwist += 1 if ttwist < 0 else -1
if ttwist == 0:
print('done')
# Stop to add the USEREVENT to the queue.
pygame.time.set_timer(RECENTERTORSOEVENT, 0)
pressed = pygame.key.get_pressed()
if pressed[pygame.K_d]:
ttwist += 1
if pressed[pygame.K_a]:
ttwist -= 1
screen.fill((30, 30, 30))
drawtext = my_font.render(
'TTWIST: {}'.format(ttwist), True, (255, 255, 255))
screen.blit(drawtext, (10, 130))
pygame.display.update()
clock.tick(30)
ttwist += 1 if ttwist < 0 else -1 is a conditional expression and does basically the same as:
if ttwist < 0:
ttwist += 1
elif ttwist > 0:
ttwist -= 1