[pygame] Clocks in pygame - Tetris lock delay

27 views
Skip to first unread message

Jan Gregorczyk

unread,
May 9, 2021, 12:09:47 PM5/9/21
to pygame...@seul.org
Hi!

I'm trying to create simple Tetris clone. I want to implement this: https://tetris.fandom.com/wiki/Lock_delay
I need 0.5 seconds with player's control over the brick. I have no idea how to do that using pygame clocks.

You can find my full code here: https://github.com/yanazPL/Tetris/blob/main/main.py (it's not finished)

Skeleton of my code is below:
class Brick:
"""Represents active brick which player can control"""

def touches_ground(self):
"""Checks whether brick is touching last row of world"""


def touches_tile(self):
"""Checks if brick touches any non-brick tile"""

def freeze(self):
"""Ends control of player over the bricks"""

class GameState:

def update(self):
"""Non player controlled after-move actions are here"""
if (self.brick.touches_ground() or
self.brick.touches_tile()):
# I WANT TIME FOR MOVEMENT/ROTATION HERE
self.brick.freeze()
self._clear_lines()
self.respawn()
else:
self.move_bricks_down()
# check lines

def move_bricks_down(self):
epoch_dividor = 20
brick = self.brick

if self.epoch >= epoch_dividor:
brick.move(
(brick.position[0], brick.position[1] + 1)
)
self.epoch = 0
self.epoch += 1

class UserInterface():
""" user actions and game state. Uses pyGame"""
def __init__(self):

pygame.init()

# Game state
self.game_state = GameState()

#window management here ...

self.clock = pygame.time.Clock()
self.running = True

def reset(self):
self.game_state = GameState()
self.clock = pygame.time.Clock()

def process_input(self):
"""Processing inupt here ..."""

def update(self):
self.game_state.update()
if self.game_state.game_lost():
self.running = False

def draw(self):
"""Drawing tiles with approperiate colors ..."""

def run(self):
"""Runs the game loop"""
while True:
self.process_input()
if self.running:
self.update()
self.draw()
self.clock.tick(UserInterface.FPS)


if __name__ == "__main__":
UserInterface().run()


BW

unread,
May 9, 2021, 5:09:34 PM5/9/21
to pygame...@seul.org

Hi,

To do this you would implement states. There are many ways to manage states, from organic to design pattern. For very simple games it's common to use a member attribute and some code (e.g. brick.state, and an if:elif:else block that's sensitive to brick.state) to handle the brick according to its state. (You can do more fancy state concepts, but they would take a much longer explanation.)

For example, store a number in brick.state:
0 = init
1 = falling
2 = collided with ground
3 = locked on ground

The brick would default to 0=init while waiting to be placed into play.

Then it would transition to 1=falling, where the player would have some control.

Next, collision with the ground would be detected, and trigger transition to 2=collide_with_ground; and a timer would be started to count elapsed time. I would store the elapsed time on the brick, but there are other ways to do it. Accumulate the elapsed time for every clock tick and check for expiration in code.

When the timer expires, then transition the brick to 3=locked_on_ground and do your win/end game checks.

Hope that helps.

Reply all
Reply to author
Forward
0 new messages