Reputation: 155
I'm making a Tetris game now. I want to implement it so that if I press the down key , the block falls quickly, and if I press the left and right keys, the block moves quickly. Pressing the key used the pygame.key.get_pressed() function and used pygame.time.set_timer() function to make speed change. The game speed was set to 600 for the interval of pygame.time.set_timer(), but if I press the down key, the block drops quickly because the interval was set to 150 to speed up the game so that the block drops quickly. The problem is to implement the function on the left and right direction keys. It is also possible to move the left and right keys quickly if I change the interval. The problem is that the pygame.time.set_timer() function changes the speed of the entire game, so the block falls quickly as well as the left and right movements of the block. Is there a way to speed up left and right movements without touching the speed of other things? I'd appreciate it if you let me know, thanks!
code
elif start:
for event in pygame.event.get():
attack_stack = 0
pos = pygame.mouse.get_pos()
if event.type == QUIT:
done = True
elif event.type == USEREVENT:
# Set speed
if not game_over:
keys_pressed = pygame.key.get_pressed()
# Soft drop
if keys_pressed[K_DOWN]:
pygame.time.set_timer(pygame.USEREVENT, 100)
elif keys_pressed[K_RIGHT]:
pygame.time.set_timer(pygame.USEREVENT, 100)
if not is_rightedge1(dx, dy, mino_en, rotation, matrix):
ui_variables.move_sound.play()
dx += 1
elif keys_pressed[K_LEFT]:
pygame.time.set_timer(pygame.USEREVENT, 100)
if not is_leftedge1(dx, dy, mino_en, rotation, matrix):
ui_variables.move_sound.play()
dx -= 1
else:
pygame.time.set_timer(pygame.USEREVENT, 600)
Upvotes: 0
Views: 124
Reputation: 39973
Waiting a long time (100 ms is already long) before reacting to user input feels bad, so you don’t want to wait a full piece-movement time before checking for input again just because there is none at the moment you check. Instead, poll for input at a steady pace of (say) 30 Hz; for simplicity, the usual approach is to just run the whole game at that frequency even if nothing needs to change on the screen for some (or even most) frames. (This technique also naturally allows smooth animations of or between piece movements.)
The usual implementation of “nothing” on a frame is to adjust the piece’s position every frame but integer-divide that position by some constant before using it for anything other than keeping track of its progress toward the next movement (like drawing it or checking for collisions). You might use pixels as the “invisible unit” when movement must be by whole tiles; games where sprites can be drawn at any pixel divide each into some convenient number of subpixels in the same fashion.
Upvotes: 2
Reputation: 268
It looks to me that the reason your piece is dropping faster when you press a button is because if the user doesn't press a button the timer is set to 600ms. If they do press a button then the timer is set to 100ms.
As for how to fix this, you'll need to decouple the downward piece movement and user-input movement. I'd suggest making another event that only handles downward movement.
DROPEVENT = pygame.USEREVENT + 1
elif event.Type == DROPEVENT:
pygame.time.set_timer(DROPEVENT, 600)
# Your piece drop logic.
This snippet is not complete nor tested at all, but I hope it get the idea across. You don't seem to have posted the logic that handles dropping the piece, but you would need to move this into the new event.
Upvotes: 1