mirror of
https://github.com/kristoferssolo/2048.git
synced 2025-10-21 15:20:35 +00:00
feat(game): add header and center board
This commit is contained in:
parent
70e0172ec7
commit
e7932303c2
@ -61,10 +61,11 @@ class Block(pygame.sprite.Sprite):
|
||||
|
||||
def _is_out_if_bounds(self, x: int, y: int) -> bool:
|
||||
"""Return whether the block is out of bounds."""
|
||||
return not (
|
||||
0 <= x <= Config.GRID_WIDTH - Config.BLOCK_SIZE
|
||||
and 0 <= y <= Config.GRID_HEIGHT - Config.BLOCK_SIZE
|
||||
)
|
||||
board_left = Config.BOARD_X
|
||||
board_right = Config.BOARD_X + Config.BOARD_WIDTH - Config.BLOCK_SIZE
|
||||
board_top = Config.BOARD_Y
|
||||
board_bottom = Config.BOARD_Y + Config.BOARD_HEIGHT - Config.BLOCK_SIZE
|
||||
return not (board_left <= x <= board_right and board_top <= y <= board_bottom)
|
||||
|
||||
def _has_collision(self, x: int, y: int) -> bool:
|
||||
"""Checks whether the block has a collision with any other block."""
|
||||
|
||||
@ -10,12 +10,26 @@ from .utils import Direction
|
||||
|
||||
|
||||
class Board(pygame.sprite.Group):
|
||||
def __init__(self, screen: pygame.Surface):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.screen = screen
|
||||
self.rect = pygame.Rect(0, 0, Config.BOARD_WIDTH, Config.BOARD_HEIGHT)
|
||||
self.rect.x = Config.BOARD_X
|
||||
self.rect.y = Config.BOARD_Y
|
||||
self.initiate_game()
|
||||
|
||||
def initiate_game(self) -> None:
|
||||
"""Initiate the game."""
|
||||
self.generate_initial_blocks()
|
||||
|
||||
def draw(self, screen: pygame.Surface) -> None:
|
||||
"""Draw the board."""
|
||||
block: Block
|
||||
pygame.draw.rect(screen, Color.YELLOW, self.rect, 2)
|
||||
|
||||
super().draw(screen)
|
||||
|
||||
def move(self, direction: Direction):
|
||||
"""Move the blocks in the specified direction."""
|
||||
blocks = self.sprites()
|
||||
block: Block
|
||||
|
||||
@ -54,8 +68,8 @@ class Board(pygame.sprite.Group):
|
||||
"""Generate a block with random coordinates aligned with the grid."""
|
||||
while True:
|
||||
# Generate random coordinates aligned with the grid
|
||||
x = random.randint(0, 3) * Config.BLOCK_SIZE
|
||||
y = random.randint(0, 3) * Config.BLOCK_SIZE
|
||||
x = random.randint(0, 3) * Config.BLOCK_SIZE + Config.BOARD_X
|
||||
y = random.randint(0, 3) * Config.BLOCK_SIZE + Config.BOARD_Y
|
||||
block = Block(x, y, self)
|
||||
|
||||
colliding_blocks = pygame.sprite.spritecollide(
|
||||
@ -64,12 +78,11 @@ class Board(pygame.sprite.Group):
|
||||
|
||||
if not colliding_blocks:
|
||||
self.add(block)
|
||||
logger.debug(f"Created block at {block.pos}")
|
||||
break
|
||||
return
|
||||
|
||||
def _is_full(self) -> bool:
|
||||
"""Check if the board is full."""
|
||||
return len(self.sprites()) == Config.GRID_SIZE**2
|
||||
return len(self.sprites()) == Config.BOARD_SIZE**2
|
||||
|
||||
def _can_move(self) -> bool:
|
||||
"""Check if any movement is possible on the board."""
|
||||
@ -83,7 +96,7 @@ class Board(pygame.sprite.Group):
|
||||
"""Check if the game is over."""
|
||||
return self._is_full() and not self._can_move()
|
||||
|
||||
def restart(self) -> None:
|
||||
"""Restart the game."""
|
||||
def reset(self) -> None:
|
||||
"""Reset the board."""
|
||||
self.empty()
|
||||
self.generate_initial_blocks()
|
||||
self.initiate_game()
|
||||
|
||||
@ -1,11 +1,25 @@
|
||||
class Config:
|
||||
FONT_FAMILY = "Roboto"
|
||||
FONT_SIZE = 40
|
||||
GRID_SIZE = 4
|
||||
FONT_SIZE = 32
|
||||
|
||||
BOARD_SIZE = 4
|
||||
BLOCK_SIZE = 50
|
||||
WIDTH = GRID_SIZE * BLOCK_SIZE
|
||||
HEIGHT = GRID_SIZE * BLOCK_SIZE + 100
|
||||
GRID_HEIGHT = GRID_SIZE * BLOCK_SIZE
|
||||
GRID_WIDTH = GRID_SIZE * BLOCK_SIZE
|
||||
|
||||
# WIDTH = BOARD_SIZE * BLOCK_SIZE + BLOCK_SIZE
|
||||
# HEIGHT = BOARD_SIZE * BLOCK_SIZE + BLOCK_SIZE * 2
|
||||
|
||||
BOARD_WIDTH = BOARD_SIZE * BLOCK_SIZE
|
||||
BOARD_HEIGHT = BOARD_SIZE * BLOCK_SIZE
|
||||
|
||||
HEADER_WIDTH = BOARD_WIDTH + BLOCK_SIZE
|
||||
HEADER_HEIGHT = BLOCK_SIZE
|
||||
|
||||
BOARD_X = BLOCK_SIZE // 2
|
||||
BOARD_Y = HEADER_HEIGHT + BLOCK_SIZE // 2
|
||||
|
||||
SCREEN_WIDTH = HEADER_WIDTH
|
||||
SCREEN_HEIGHT = BOARD_HEIGHT + BLOCK_SIZE + HEADER_HEIGHT
|
||||
SCREEN_SIZE = SCREEN_WIDTH, SCREEN_HEIGHT
|
||||
|
||||
INITIAL_BLOCK_COUNT = 2
|
||||
BLOCK_VALUE_PROBABILITY = 0.9
|
||||
|
||||
@ -7,6 +7,7 @@ from .board import Board
|
||||
from .color import Color
|
||||
from .config import Config
|
||||
from .logger import setup_logger
|
||||
from .screens.header import Header
|
||||
from .utils import Direction
|
||||
|
||||
|
||||
@ -16,11 +17,10 @@ class Game:
|
||||
logger.info("Initializing game")
|
||||
|
||||
pygame.init()
|
||||
self.screen: pygame.Surface = pygame.display.set_mode(
|
||||
(Config.WIDTH, Config.HEIGHT)
|
||||
)
|
||||
self.screen: pygame.Surface = pygame.display.set_mode(Config.SCREEN_SIZE)
|
||||
pygame.display.set_caption("2048")
|
||||
self.blocks = Board(self.screen)
|
||||
self.board = Board()
|
||||
self.header = Header()
|
||||
|
||||
def run(self) -> None:
|
||||
"""Run the game loop."""
|
||||
@ -31,12 +31,13 @@ class Game:
|
||||
|
||||
def _update(self) -> None:
|
||||
"""Update the game."""
|
||||
self.blocks.update()
|
||||
self.board.update()
|
||||
|
||||
def _render(self) -> None:
|
||||
"""Render the game."""
|
||||
self.screen.fill(Color.BG)
|
||||
self.blocks.draw(self.screen)
|
||||
self.board.draw(self.screen)
|
||||
self.header.draw(self.screen)
|
||||
pygame.display.flip()
|
||||
|
||||
def _hande_events(self) -> None:
|
||||
@ -57,16 +58,16 @@ class Game:
|
||||
self.exit()
|
||||
|
||||
def move_up(self) -> None:
|
||||
self.blocks.move(Direction.UP)
|
||||
self.board.move(Direction.UP)
|
||||
|
||||
def move_down(self) -> None:
|
||||
self.blocks.move(Direction.DOWN)
|
||||
self.board.move(Direction.DOWN)
|
||||
|
||||
def move_left(self) -> None:
|
||||
self.blocks.move(Direction.LEFT)
|
||||
self.board.move(Direction.LEFT)
|
||||
|
||||
def move_right(self) -> None:
|
||||
self.blocks.move(Direction.RIGHT)
|
||||
self.board.move(Direction.RIGHT)
|
||||
|
||||
def exit(self) -> None:
|
||||
"""Exit the game."""
|
||||
|
||||
14
src/py2048/screens/header.py
Normal file
14
src/py2048/screens/header.py
Normal file
@ -0,0 +1,14 @@
|
||||
import pygame
|
||||
|
||||
from ..color import Color
|
||||
from ..config import Config
|
||||
|
||||
|
||||
class Header:
|
||||
def __init__(self) -> None:
|
||||
self.rect = pygame.Rect(0, 0, Config.HEADER_WIDTH, Config.HEADER_HEIGHT)
|
||||
self.score = 0 # TODO: Implement score
|
||||
|
||||
def draw(self, screen: pygame.Surface) -> None:
|
||||
"""Draw the header."""
|
||||
pygame.draw.rect(screen, Color.MAGENTA, self.rect, 2)
|
||||
Loading…
Reference in New Issue
Block a user