refactor: improve keyboard input logic

This commit is contained in:
Giovani Rodriguez
2021-06-14 13:17:18 -04:00
parent f52f218a5f
commit bc8721e077
3 changed files with 49 additions and 40 deletions

View File

@@ -4,6 +4,7 @@ import pygame
from typing import List, Tuple from typing import List, Tuple
from pygame import mixer from pygame import mixer
from tetris.util import ConfigurationManager from tetris.util import ConfigurationManager
from tetris.util import Controller
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -107,6 +108,7 @@ class Piece(Entity):
def update(self, elapsed_time: int, game: "Game") -> None: def update(self, elapsed_time: int, game: "Game") -> None:
super().update(elapsed_time) super().update(elapsed_time)
tile_size = ConfigurationManager.get("engine", "tile-size")
if self.applying_gravity: if self.applying_gravity:
self.applying_gravity = self._apply_gravity(elapsed_time, game.well, game.stack) 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_set = self._apply_set(elapsed_time, game)
self.applying_gravity = not self.applying_set 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: def draw(self, surface: pygame.Surface, well: Well, stack: "Stack") -> None:
tile_size = ConfigurationManager.get("engine", "tile-size") tile_size = ConfigurationManager.get("engine", "tile-size")

View File

@@ -4,6 +4,7 @@ import pygame
from pygame import mixer from pygame import mixer
from tetris.util import ConfigurationManager from tetris.util import ConfigurationManager
from tetris.util import TextGenerator from tetris.util import TextGenerator
from tetris.util import Controller
from tetris.entity import PieceGenerator from tetris.entity import PieceGenerator
from tetris.entity import Well from tetris.entity import Well
from tetris.entity import Stack from tetris.entity import Stack
@@ -57,54 +58,17 @@ class Game:
self.current_piece.update(elapsed_time, self) self.current_piece.update(elapsed_time, self)
else: else:
self.current_piece = PieceGenerator.get_piece((360, 100)) # TODO calculate spawn position 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() pygame.quit()
sys.exit() sys.exit()
if self.stack: if self.stack:
self.stack.update(elapsed_time) self.stack.update(elapsed_time)
# TODO create control utility class
for event in pygame.event.get(): for event in pygame.event.get():
if event.type == pygame.QUIT: if event.type == pygame.QUIT:
pygame.quit() pygame.quit()
sys.exit() 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: def draw(self) -> None:

View File

@@ -1,6 +1,6 @@
import yaml import yaml
import pygame import pygame
from typing import Tuple from typing import KeysView, Tuple
""" """
TODO description TODO description
@@ -83,4 +83,23 @@ class TextGenerator:
for char_ in text: for char_ in text:
if not char_.isspace(): 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]))) 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] 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]