refactor: add base class for all game objects
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import sys
|
||||
import pygame
|
||||
|
||||
from util.ConfigurationManager import ConfigurationManager
|
||||
from util.PieceGenerator import PieceGenerator
|
||||
from entity.Well import Well
|
||||
@@ -15,7 +16,7 @@ class Tetris:
|
||||
self.well = None
|
||||
self.current_piece = None
|
||||
|
||||
def initialize(self):
|
||||
def initialize(self) -> None:
|
||||
pygame.init()
|
||||
|
||||
win_width = ConfigurationManager.configuration["window"]["width"]
|
||||
@@ -34,7 +35,7 @@ class Tetris:
|
||||
pygame.display.set_icon(loaded_icon)
|
||||
|
||||
# gets called from the games main loop
|
||||
def update(self):
|
||||
def update(self) -> None:
|
||||
# TODO write not initialized exception
|
||||
|
||||
self.clock.tick(self.fps)
|
||||
@@ -58,8 +59,10 @@ class Tetris:
|
||||
self.current_piece.move((0, self.tile_size))
|
||||
if event.key == pygame.K_z:
|
||||
self.__generate_piece((300, 100))
|
||||
if event.key == pygame.K_x:
|
||||
self.current_piece.revert()
|
||||
|
||||
def draw(self):
|
||||
def draw(self) -> None:
|
||||
# TODO write not initialized exception
|
||||
|
||||
# draw window bg
|
||||
|
||||
14
entity/Entity.py
Normal file
14
entity/Entity.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import pygame
|
||||
|
||||
class Entity:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def update(self) -> None:
|
||||
pass
|
||||
|
||||
def draw(self, surface: pygame.Surface) -> None:
|
||||
pass
|
||||
|
||||
def collide(self, entity) -> bool:
|
||||
pass
|
||||
@@ -1,19 +1,27 @@
|
||||
from typing import List, Tuple
|
||||
import pygame
|
||||
import copy
|
||||
|
||||
from entity.Entity import Entity
|
||||
from util.ConfigurationManager import ConfigurationManager
|
||||
|
||||
'''
|
||||
For information on the Tetris piece Tetromino go here:
|
||||
https://tetris.fandom.com/wiki/Tetromino
|
||||
'''
|
||||
class Piece: # TODO game objects base class / interface?
|
||||
class Piece(Entity):
|
||||
|
||||
def __init__(self, shape: Tuple, position: Tuple, color: str):
|
||||
super().__init__()
|
||||
|
||||
def __init__(self, shape, position, color):
|
||||
self.color = color
|
||||
self.points = self.__get_points(shape, position)
|
||||
self.center = self.__get_center(shape, position)
|
||||
|
||||
def draw(self, surface):
|
||||
self.previous_points = None
|
||||
self.previous_center = None
|
||||
|
||||
def draw(self, surface: pygame.Surface) -> None:
|
||||
tile_size = ConfigurationManager.configuration["engine"]["tile-size"]
|
||||
hex_color = ConfigurationManager.configuration["color"]["border"] # TODO should abstract out color call?
|
||||
|
||||
@@ -24,7 +32,10 @@ class Piece: # TODO game objects base class / interface?
|
||||
pygame.draw.polygon(surface, base_color, sub_points, 0)
|
||||
pygame.draw.polygon(surface, border_color, sub_points, max(tile_size // 6, 1))
|
||||
|
||||
def move(self, vector):
|
||||
def move(self, vector: Tuple) -> None:
|
||||
self.previous_points = copy.deepcopy(self.points)
|
||||
self.previous_center = copy.deepcopy(self.center)
|
||||
|
||||
self.center[0] += vector[0]
|
||||
self.center[1] += vector[1]
|
||||
|
||||
@@ -37,7 +48,10 @@ class Piece: # TODO game objects base class / interface?
|
||||
For more information on a rotation of a piece go here:
|
||||
https://gamedev.stackexchange.com/questions/17974/how-to-rotate-blocks-in-tetris
|
||||
'''
|
||||
def rotate(self):
|
||||
def rotate(self) -> None:
|
||||
self.previous_points = copy.deepcopy(self.points)
|
||||
self.previous_center = copy.deepcopy(self.center)
|
||||
|
||||
for sub_points in self.points:
|
||||
for point in sub_points:
|
||||
h = point[0] - self.center[0]
|
||||
@@ -46,10 +60,12 @@ class Piece: # TODO game objects base class / interface?
|
||||
point[0] = (k * -1) + self.center[0]
|
||||
point[1] = h + self.center[1]
|
||||
|
||||
def colliding(object):
|
||||
pass
|
||||
def revert(self) -> None:
|
||||
if self.previous_points and self.previous_center:
|
||||
self.points = self.previous_points
|
||||
self.center = self.previous_center
|
||||
|
||||
def __get_points(self, shape, position):
|
||||
def __get_points(self, shape: Tuple, position: Tuple) -> List:
|
||||
tile_size = ConfigurationManager.configuration["engine"]["tile-size"]
|
||||
|
||||
points = []
|
||||
@@ -62,7 +78,7 @@ class Piece: # TODO game objects base class / interface?
|
||||
|
||||
return points
|
||||
|
||||
def __get_center(self, shape, position):
|
||||
def __get_center(self, shape: Tuple, position: Tuple) -> List:
|
||||
tile_size = ConfigurationManager.configuration["engine"]["tile-size"]
|
||||
center = shape[-1]
|
||||
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
from typing import List, Tuple
|
||||
import pygame
|
||||
|
||||
from entity.Entity import Entity
|
||||
from util.ConfigurationManager import ConfigurationManager
|
||||
|
||||
class Well: # TODO game objects base class / interface?
|
||||
class Well(Entity):
|
||||
|
||||
WIDTH = 10 # standard tetris well width, should not be changed
|
||||
HEIGHT = 20 # standard tetris well height, should not be changed
|
||||
|
||||
def __init__(self, position):
|
||||
def __init__(self, position: Tuple):
|
||||
self.points = self.__get_points(position)
|
||||
|
||||
def draw(self, surface):
|
||||
def draw(self, surface: pygame.Surface) -> None:
|
||||
well_color_hex = ConfigurationManager.configuration["color"]["border"] # TODO Should abstract out color call?
|
||||
well_color = pygame.Color(well_color_hex)
|
||||
|
||||
for sub_points in self.points:
|
||||
pygame.draw.polygon(surface, well_color, sub_points, 0)
|
||||
|
||||
def __get_points(self, position):
|
||||
def __get_points(self, position: Tuple) -> List:
|
||||
tile_size = ConfigurationManager.configuration["engine"]["tile-size"]
|
||||
|
||||
shape = []
|
||||
|
||||
4
main.py
4
main.py
@@ -4,10 +4,12 @@
|
||||
https://tetris.com/play-tetris
|
||||
'''
|
||||
|
||||
# TODO review imports to make sure it is being done correctly
|
||||
|
||||
from Tetris import Tetris
|
||||
from util.ConfigurationManager import ConfigurationManager
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
ConfigurationManager.load()
|
||||
|
||||
tetris = Tetris()
|
||||
|
||||
@@ -8,6 +8,6 @@ class ConfigurationManager:
|
||||
configuration = []
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
def load(cls) -> None:
|
||||
with open(CONFIG_FILE_LOCATION, "r") as yaml_file:
|
||||
cls.configuration = yaml.safe_load(yaml_file)
|
||||
@@ -1,3 +1,4 @@
|
||||
from typing import Tuple
|
||||
import random
|
||||
|
||||
from entity.Piece import Piece
|
||||
@@ -11,20 +12,20 @@ class PieceGenerator:
|
||||
__bucket = []
|
||||
|
||||
@classmethod
|
||||
def get_piece(cls, position):
|
||||
def get_piece(cls, position: Tuple) -> Piece:
|
||||
if len(cls.__bucket) == 0:
|
||||
cls.__generate_bucket()
|
||||
|
||||
return Piece(cls.__get_piece_shape(cls.__bucket.pop()), position, cls.__get_piece_color())
|
||||
|
||||
@classmethod
|
||||
def __generate_bucket(cls):
|
||||
def __generate_bucket(cls) -> None:
|
||||
piece_types = list(range(7))
|
||||
while len(cls.__bucket) != 7:
|
||||
random_number = random.randint(0, 6 - len(cls.__bucket))
|
||||
cls.__bucket.append(piece_types.pop(random_number))
|
||||
|
||||
def __get_piece_shape(piece_number):
|
||||
def __get_piece_shape(piece_number: int) -> Tuple:
|
||||
if piece_number == 0:
|
||||
return Piece.I_SHAPE
|
||||
if piece_number == 1:
|
||||
@@ -42,6 +43,6 @@ class PieceGenerator:
|
||||
|
||||
return None
|
||||
|
||||
def __get_piece_color():
|
||||
def __get_piece_color() -> str:
|
||||
random_number = random.randint(1, 3)
|
||||
return ConfigurationManager.configuration["color"]["base-" + str(random_number)]
|
||||
|
||||
Reference in New Issue
Block a user