import sys from typing import Text import pygame from pygame import mixer from tetris.util import ConfigurationManager from tetris.util import TextGenerator from tetris.entity import PieceGenerator from tetris.entity import Well from tetris.entity import Stack # TODO should be a singleton and refactor the whole file? class Game: def __init__(self): self.fps = -1 self.tile_size = -1 self.screen = None self.clock = None self.main_music = None self.current_piece = None self.well = None self.stack = None def initialize(self) -> None: pygame.init() TextGenerator.load("resource/font/retro-font.bmp", (20, 30)) win_width = ConfigurationManager.get("window", "width") win_height = ConfigurationManager.get("window", "height") win_icon = ConfigurationManager.get("window", "icon") win_title = ConfigurationManager.get("window", "title") self.fps = ConfigurationManager.get("engine", "fps") self.tile_size = ConfigurationManager.get("engine", "tile-size") self.screen = pygame.display.set_mode((win_width, win_height)) self.clock = pygame.time.Clock() self.main_music = mixer.Channel(0) self.well = Well((280, 80), ConfigurationManager.get("color", "well-1"), ConfigurationManager.get("color", "well-border-1")) # TODO calculate position later and redo color config for well self.stack = Stack(ConfigurationManager.get("color", "stack-1"), ConfigurationManager.get("color", "stack-border-1")) loaded_icon = pygame.image.load(win_icon) pygame.display.set_caption(win_title) pygame.display.set_icon(loaded_icon) self.is_pressing_down = False # TODO move into control util later main_music_file = ConfigurationManager.get("sound", "main-music") self.main_music.set_volume(0.7) # TODO add volume to the config self.main_music.play(mixer.Sound(main_music_file), -1) # gets called from the games main loop def update(self) -> None: # TODO write not initialized exception elapsed_time = self.clock.tick(self.fps) if self.current_piece: 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 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: # TODO write not initialized exception # draw window bg bg_color = pygame.Color(ConfigurationManager.get("color", "window-bg")) self.screen.fill(bg_color) # draw all game objects if self.well: self.well.draw(self.screen) if self.stack: self.stack.draw(self.screen) if self.current_piece: self.current_piece.draw(self.screen) TextGenerator.draw("SCORE", (0, 0), self.screen) # update display pygame.display.update()