From 6e954c020467be020e326ebaf76191c34c175570 Mon Sep 17 00:00:00 2001 From: Giovani Date: Mon, 14 Jun 2021 13:17:18 -0400 Subject: [PATCH] refactor: improve keyboard input logic --- tetris/entity.py | 26 ++++++++++++++++++++++++++ tetris/game.py | 40 ++-------------------------------------- tetris/util.py | 23 +++++++++++++++++++++-- 3 files changed, 49 insertions(+), 40 deletions(-) diff --git a/tetris/entity.py b/tetris/entity.py index 3ea660f..cdc20d9 100644 --- a/tetris/entity.py +++ b/tetris/entity.py @@ -4,6 +4,7 @@ import pygame from typing import List, Tuple from pygame import mixer from tetris.util import ConfigurationManager +from tetris.util import Controller from typing import TYPE_CHECKING if TYPE_CHECKING: @@ -107,6 +108,7 @@ class Piece(Entity): def update(self, elapsed_time: int, game: "Game") -> None: super().update(elapsed_time) + tile_size = ConfigurationManager.get("engine", "tile-size") if self.applying_gravity: self.applying_gravity = self._apply_gravity(elapsed_time, game.well, game.stack) @@ -120,6 +122,30 @@ class Piece(Entity): self.applying_set = self._apply_set(elapsed_time, game) self.applying_gravity = not self.applying_set + # handle rotation, left and right movement + if Controller.key_down(pygame.K_SPACE): + self.rotate() + if game.well and self.collide(game.well) or game.stack and self.collide(game.stack): + self.revert() + if Controller.key_down(pygame.K_LEFT): + self.move((-tile_size, 0)) + if game.well and self.collide(game.well) or game.stack and self.collide(game.stack): + self.revert() + if Controller.key_down(pygame.K_RIGHT): + self.move((tile_size, 0)) + if game.well and self.collide(game.well) or game.stack and self.collide(game.stack): + self.revert() + + # handle soft drop movement + gravity_time = ConfigurationManager.get("engine", "piece-gravity-time") + set_time = ConfigurationManager.get("engine", "piece-set-time") + if Controller.key_pressed(pygame.K_DOWN): + self.gravity_time = gravity_time // 8 + self.set_time = set_time // 8 + if not Controller.key_pressed(pygame.K_DOWN): + self.gravity_time = gravity_time + self.set_time = set_time + def draw(self, surface: pygame.Surface, well: Well, stack: "Stack") -> None: tile_size = ConfigurationManager.get("engine", "tile-size") diff --git a/tetris/game.py b/tetris/game.py index 50ce935..d42be76 100644 --- a/tetris/game.py +++ b/tetris/game.py @@ -4,6 +4,7 @@ import pygame from pygame import mixer from tetris.util import ConfigurationManager from tetris.util import TextGenerator +from tetris.util import Controller from tetris.entity import PieceGenerator from tetris.entity import Well from tetris.entity import Stack @@ -57,54 +58,17 @@ class Game: self.current_piece.update(elapsed_time, self) else: self.current_piece = PieceGenerator.get_piece((360, 100)) # TODO calculate spawn position - if self.stack and self.current_piece.collide(self.stack): # game over + if self.stack and self.current_piece.collide(self.stack): # TODO game over redo pygame.quit() sys.exit() if self.stack: self.stack.update(elapsed_time) - # TODO create control utility class for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() - if event.type == pygame.KEYDOWN: - if self.current_piece: - if event.key == pygame.K_SPACE: - self.current_piece.rotate() - if self.well and self.current_piece.collide(self.well): - self.current_piece.revert() - if self.stack and self.current_piece.collide(self.stack): - self.current_piece.revert() - if event.key == pygame.K_LEFT: - self.current_piece.move((-self.tile_size, 0)) - if self.well and self.current_piece.collide(self.well): - self.current_piece.revert() - if self.stack and self.current_piece.collide(self.stack): - self.current_piece.revert() - if event.key == pygame.K_RIGHT: - self.current_piece.move((self.tile_size, 0)) - if self.well and self.current_piece.collide(self.well): - self.current_piece.revert() - if self.stack and self.current_piece.collide(self.stack): - self.current_piece.revert() - if event.key == pygame.K_DOWN: - self.is_pressing_down = True - if self.current_piece: - self.current_piece.gravity_time = ConfigurationManager.get("engine", "piece-gravity-time") / 8 - self.current_piece.set_time = ConfigurationManager.get("engine", "piece-gravity-time") / 8 - if event.type == pygame.KEYUP: - if event.key == pygame.K_DOWN: - self.is_pressing_down = False - if self.current_piece: - self.current_piece.gravity_time = ConfigurationManager.get("engine", "piece-gravity-time") - self.current_piece.set_time = ConfigurationManager.get("engine", "piece-set-time") - - if self.is_pressing_down: - if self.current_piece: - self.current_piece.gravity_time = ConfigurationManager.get("engine", "piece-gravity-time") / 8 - self.current_piece.set_time = ConfigurationManager.get("engine", "piece-set-time") / 8 def draw(self) -> None: diff --git a/tetris/util.py b/tetris/util.py index bf42aa2..5d9f194 100644 --- a/tetris/util.py +++ b/tetris/util.py @@ -1,6 +1,6 @@ import yaml import pygame -from typing import Tuple +from typing import KeysView, Tuple """ TODO description @@ -83,4 +83,23 @@ class TextGenerator: for char_ in text: if not char_.isspace(): surface.blit(cls.sheet, (position[0] + x_position, position[1]), pygame.Rect(cls.characters[char_.upper()], (cls.glyph_size[0], cls.glyph_size[1]))) - x_position += cls.glyph_size[0] \ No newline at end of file + x_position += cls.glyph_size[0] + + +""" + TODO description +""" +class Controller: + + keys_pressed = {} + + @classmethod + def key_down(cls, key: int) -> bool: + prior_pressed_state = False if key not in cls.keys_pressed else cls.keys_pressed[key] + cls.keys_pressed[key] = pygame.key.get_pressed()[key] + + return cls.keys_pressed[key] and not prior_pressed_state + + @classmethod + def key_pressed(cls, key: int) -> bool: + return pygame.key.get_pressed()[key] \ No newline at end of file