mirror of
https://github.com/kristoferssolo/Tetris.git
synced 2025-10-21 20:00:35 +00:00
feat(game): add vertical block collision
This commit is contained in:
parent
a211dd0254
commit
e68abf8f94
@ -7,9 +7,10 @@ readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
license = { text = "GPLv3" }
|
||||
dependencies = [
|
||||
"loguru==0.7.2",
|
||||
"attrs==23.1.0",
|
||||
"loguru==0.7.2",
|
||||
"neat-python==0.92",
|
||||
"numpy==1.26.3",
|
||||
"pygame-ce==2.4.0",
|
||||
]
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
loguru>=0.7.2
|
||||
attrs>=23.1.0
|
||||
loguru>=0.7.2
|
||||
neat-python>=0.92
|
||||
numpy>=1.26.3
|
||||
pygame-ce>=2.4.0
|
||||
.
|
||||
|
||||
@ -1,10 +1,16 @@
|
||||
import numpy as np
|
||||
import pygame
|
||||
from utils import CONFIG, Size
|
||||
|
||||
|
||||
class Block(pygame.sprite.Sprite):
|
||||
def __init__(
|
||||
self, /, *, group: pygame.sprite.Group, pos: pygame.Vector2, color: str
|
||||
self,
|
||||
/,
|
||||
*,
|
||||
group: pygame.sprite.Group,
|
||||
pos: pygame.Vector2,
|
||||
color: str,
|
||||
) -> None:
|
||||
super().__init__(group)
|
||||
self.image = pygame.Surface(CONFIG.game.cell)
|
||||
@ -16,8 +22,8 @@ class Block(pygame.sprite.Sprite):
|
||||
def update(self) -> None:
|
||||
self.rect.topleft = self.pos * CONFIG.game.cell.width
|
||||
|
||||
def vertical_collision(self, x: int) -> bool:
|
||||
return not 0 <= x < CONFIG.game.columns
|
||||
def vertical_collision(self, x: int, field: np.ndarray) -> bool:
|
||||
return not 0 <= x < CONFIG.game.columns or field[int(self.pos.y), x]
|
||||
|
||||
def horizontal_collision(self, y: int) -> bool:
|
||||
return y >= CONFIG.game.rows
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
import pygame
|
||||
from utils import CONFIG, Direction, Figure
|
||||
from typing import Optional
|
||||
|
||||
import numpy as np
|
||||
import pygame
|
||||
from utils import CONFIG, Direction, Field, Figure
|
||||
|
||||
from .block import Block
|
||||
from .log import log
|
||||
from .tetromino import Tetromino
|
||||
from .timer import Timer, Timers
|
||||
@ -12,10 +16,17 @@ class Game:
|
||||
self.dispaly_surface = pygame.display.get_surface()
|
||||
self.rect = self.surface.get_rect(topleft=CONFIG.game.pos)
|
||||
|
||||
self.sprites: pygame.sprite.Group[Block] = pygame.sprite.Group()
|
||||
|
||||
self._create_grid_surface()
|
||||
|
||||
self.sprites = pygame.sprite.Group()
|
||||
self.tetromino = Tetromino(self.sprites, self.create_new_tetromino)
|
||||
self.field = np.full((CONFIG.game.rows, CONFIG.game.columns), None, dtype=Field)
|
||||
|
||||
self.tetromino = Tetromino(
|
||||
self.sprites,
|
||||
self.create_new_tetromino,
|
||||
self.field,
|
||||
)
|
||||
|
||||
self.timers = Timers(
|
||||
Timer(CONFIG.game.initial_speed, True, self.move_down),
|
||||
@ -63,7 +74,11 @@ class Game:
|
||||
self.tetromino.move_horizontal(Direction.RIGHT)
|
||||
|
||||
def create_new_tetromino(self) -> None:
|
||||
self.tetromino = Tetromino(self.sprites, self.create_new_tetromino)
|
||||
self.tetromino = Tetromino(
|
||||
self.sprites,
|
||||
self.create_new_tetromino,
|
||||
self.field,
|
||||
)
|
||||
|
||||
def _create_grid_surface(self) -> None:
|
||||
self.grid_surface = self.surface.copy()
|
||||
|
||||
@ -1,22 +1,26 @@
|
||||
from typing import Callable, Optional
|
||||
|
||||
import numpy as np
|
||||
import pygame
|
||||
from utils import CONFIG, Direction, Figure, FigureConfig, Size
|
||||
|
||||
from .block import Block
|
||||
from .log import log
|
||||
|
||||
|
||||
class Tetromino:
|
||||
def __init__(
|
||||
self,
|
||||
group: pygame.sprite.Group,
|
||||
func: Callable[[None], None],
|
||||
func: Callable[[], None],
|
||||
field: np.ndarray,
|
||||
shape: Optional[Figure] = None,
|
||||
) -> None:
|
||||
self.figure: FigureConfig = shape.value if shape else Figure.random().value
|
||||
self.block_positions: list[pygame.Vector2] = self.figure.shape
|
||||
self.color: str = self.figure.color
|
||||
self.create_new = func
|
||||
self.field = field
|
||||
|
||||
self.blocks = [
|
||||
Block(group=group, pos=pos, color=self.color)
|
||||
@ -28,6 +32,8 @@ class Tetromino:
|
||||
for block in self.blocks:
|
||||
block.pos.y += 1
|
||||
else:
|
||||
for block in self.blocks:
|
||||
self.field[int(block.pos.y), int(block.pos.x)] = block
|
||||
self.create_new()
|
||||
|
||||
def move_horizontal(self, direction: Direction) -> None:
|
||||
@ -39,7 +45,7 @@ class Tetromino:
|
||||
self, blocks: list[Block], direction: Direction
|
||||
) -> bool:
|
||||
return any(
|
||||
block.vertical_collision(int(block.pos.x + direction.value))
|
||||
block.vertical_collision(int(block.pos.x + direction.value), self.field)
|
||||
for block in self.blocks
|
||||
)
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ from attrs import define, field
|
||||
class Timer:
|
||||
duration: int = field(converter=int)
|
||||
repeated: bool = field(default=False)
|
||||
func: Optional[Callable[[None], None]] = field(default=None)
|
||||
func: Optional[Callable[[], None]] = field(default=None)
|
||||
start_time: int = 0
|
||||
active: bool = False
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
from .config import CONFIG
|
||||
from .direction import Direction
|
||||
from .enum import Direction, Field
|
||||
from .figure import Figure, FigureConfig
|
||||
from .log import log
|
||||
from .path import BASE_PATH
|
||||
@ -13,4 +13,5 @@ __all__ = [
|
||||
"Figure",
|
||||
"FigureConfig",
|
||||
"Direction",
|
||||
"Field",
|
||||
]
|
||||
|
||||
@ -6,3 +6,8 @@ class Direction(Enum):
|
||||
RIGHT = 1
|
||||
DOWN = 1
|
||||
UP = -1
|
||||
|
||||
|
||||
class Field(Enum):
|
||||
EMPTY = None
|
||||
FILLED = "Block"
|
||||
@ -9,7 +9,7 @@ from .colors import TokyoNightNight
|
||||
|
||||
|
||||
class FigureConfig(NamedTuple):
|
||||
shape: list[Vec2, Vec2, Vec2, Vec2]
|
||||
shape: list[Vec2]
|
||||
color: str
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user