Merge pull request '0.0.5' (#5) from 0.0.5 into main

Reviewed-on: https://gitpot-lerking.servehttp.com/CodingPirates/PyGame-Tetris/pulls/5
This commit was merged in pull request #5.
This commit is contained in:
2025-04-25 17:14:44 +02:00
6 changed files with 105 additions and 58 deletions

View File

@@ -1,25 +1,13 @@
import pygame
import globals
import enums
from random import choice
BRICKS = [
" X " + "\n" + "XXX" + "\n" + " X ",
" X" + "\n" + "XXX",
"X " + "\n" + "XXX",
"X",
"XXXX",
"XX" + "\n" + "XX",
" XX" + "\n" + "XX ",
"XX " + "\n" + " XX",
"X X" + "\n" + "XXX",
"XXX" + "\n" + " X "
]
TILE_SIZE = 48
class Brick:
def __init__(self, brick, state = enums.BrickState.Next):
self.layout = []
self.shape = []
self.color = choice(list(enums.BrickColor))
self.set_state(state)
self.angle = 0
@@ -43,19 +31,19 @@ class Brick:
self.img = pygame.image.load("assets/magenta_block.png").convert_alpha()
def load_brick(self, brick):
self.layout = [l for l in BRICKS[brick].splitlines()]
self.shape = [l for l in globals.BRICKS[brick]]
self.rows = len(self.layout)
self.cols = len(self.layout[0])
self.width = self.cols * TILE_SIZE
self.height = self.rows * TILE_SIZE
self.rows = len(self.shape)
self.cols = len(self.shape[0])
self.width = self.cols * globals.TILE_SIZE
self.height = self.rows * globals.TILE_SIZE
def draw_brick(self):
self.brick = pygame.Surface((self.width, self.height))
for y, row in enumerate(self.layout):
for y, row in enumerate(self.shape):
for x, char in enumerate(row):
if char == "X":
self.brick.blit(self.block_image, (1 + x * TILE_SIZE, 1 + y * TILE_SIZE))
if char:
self.brick.blit(self.block_image, (1 + x * globals.TILE_SIZE, 1 + y * globals.TILE_SIZE))
def is_current(self):
return True if self.state == enums.BrickState.Current else False
@@ -64,20 +52,50 @@ class Brick:
self.y += 1
self.location = (self.x, self.y)
def rotate(self):
print("Rotating")
def rotate_clockwise(self, shape):
return [list(row)[::-1] for row in zip(*shape)]
def rotate(self):
new_shape = self.rotate_clockwise(self.shape)
print(new_shape)
if not self.collision(new_shape, self.x, self.y):
self.shape = new_shape
self.rows = len(self.shape)
self.cols = len(self.shape[0])
self.width = self.cols * globals.TILE_SIZE
self.height = self.rows * globals.TILE_SIZE
self.draw_brick()
print(self.shape)
def collision(self, shape, x, y):
for row_idx, row in enumerate(shape):
for col_idx, cell in enumerate(row):
if cell:
new_x = x + col_idx
new_y = y + row_idx
if new_x <= 0 or new_x >= globals.GRID_WIDTH or new_y >= globals.GRID_HEIGHT:
return True
if new_y >= 0 and globals.dropgrid[new_y][new_x]:
return True
return False
def set_state(self, state):
self.state = state
print(f"State set to {self.state}")
def move_right(self):
self.x += 1
self.location = (self.x, self.y)
if self.collision(self.shape, self.x, self.y):
return
else:
self.x += 1
self.location = (self.x, self.y)
def move_left(self):
self.x -= 1
self.location = (self.x, self.y)
if self.collision(self.shape, self.x, self.y):
return
else:
self.x -= 1
self.location = (self.x, self.y)
def drop(self):
print("Dropping")

View File

@@ -1,4 +1,5 @@
import pygame
import globals
from enums import BrickColor
class DropNext():
@@ -8,8 +9,8 @@ class DropNext():
self.height = height
self.dropnext.fill((0, 0, 0)) # Fill with black
def draw(self, screen, tile_size):
screen.blit(self.dropnext, (tile_size * 15, tile_size * 2))
def draw(self, screen):
screen.blit(self.dropnext, (globals.TILE_SIZE * 15, globals.TILE_SIZE * 2))
def draw_block(self, brick):
self.dropnext.fill(BrickColor.Black.value)

View File

@@ -1,18 +1,17 @@
import pygame
import globals
from enums import BrickColor
class DropZone():
def __init__(self, tile_size, width, height):
self.dropzone = pygame.Surface((width * tile_size, height * tile_size))
def __init__(self, width, height):
self.dropzone = pygame.Surface((width * globals.TILE_SIZE, height * globals.TILE_SIZE))
self.width = width
self.height = height
self.tile_size = tile_size
self.grid_row = [" "] * self.width
self.grid = [self.grid_row] * self.height
print(globals.dropgrid)
def draw(self, screen):
screen.blit(self.dropzone, (self.tile_size * 4, self.tile_size * 1))
screen.blit(self.dropzone, (globals.TILE_SIZE * 4, globals.TILE_SIZE * 1))
def draw_brick(self, brick, location):
self.dropzone.fill(BrickColor.Black.value)
self.dropzone.blit(brick, (location[0] * self.tile_size, location[1] * self.tile_size))
self.dropzone.blit(brick, (location[0] * globals.TILE_SIZE, location[1] * globals.TILE_SIZE))

22
globals.py Normal file
View File

@@ -0,0 +1,22 @@
def init():
global BRICKS
BRICKS = [
[[0,1,0], [1,1,1], [0,1,0]],
[[0, 0, 1], [1, 1, 1]],
[[1, 0, 0], [1, 1, 1]],
[[1]],
[[1, 1, 1, 1]],
[[1, 1], [1, 1]],
[[0, 1, 1], [1, 1, 0]],
[[1, 1, 0], [0, 1, 1]],
[[1, 0, 1], [1, 1, 1]],
[[1, 1, 1], [0, 1, 0]]
]
global TILE_SIZE
TILE_SIZE = 48
global GRID_WIDTH
GRID_WIDTH = 10
global GRID_HEIGHT
GRID_HEIGHT = 18
global dropgrid
dropgrid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]

22
hud.py
View File

@@ -1,9 +1,10 @@
import pygame
import os
from globals import TILE_SIZE
from enums import BrickColor
class Hud:
def __init__(self, screen_width, screen_height, tile_size, font_size=36, highscore_file="highscore.txt"):
def __init__(self, screen_width, screen_height, font_size=36, highscore_file="highscore.txt"):
self.highscore_file = highscore_file
self.highscore = self.load_highscore()
@@ -11,7 +12,6 @@ class Hud:
self.color = BrickColor.Red.value
self.screen_width = screen_width
self.screen_height = screen_height
self.tile_size = tile_size
self.reset()
@@ -56,24 +56,24 @@ class Hud:
# Score (top-left)
score_text = self.font.render(f"Score:", True, self.color)
score = self.font.render(f"{self.score}", True, self.color)
screen.blit(score_text, (self.tile_size / 2, self.tile_size))
screen.blit(score,(self.tile_size / 2, self.tile_size + 24))
screen.blit(score_text, (TILE_SIZE / 2, TILE_SIZE))
screen.blit(score,(TILE_SIZE / 2, TILE_SIZE + 24))
lines_text = self.font.render(f"Lines:", True, self.color)
lines = self.font.render(f"{self.lines}", True, self.color)
screen.blit(lines_text, (self.tile_size / 2, self.tile_size * 2 + 24))
screen.blit(lines, (self.tile_size / 2, self.tile_size * 3))
screen.blit(lines_text, (TILE_SIZE / 2, TILE_SIZE * 2 + 24))
screen.blit(lines, (TILE_SIZE / 2, TILE_SIZE * 3))
level_text = self.font.render(f"Level:", True, self.color)
level = self.font.render(f"{self.level}", True, self.color)
screen.blit(level_text, (self.tile_size / 2, self.tile_size * 4))
screen.blit(level, (self.tile_size / 2, self.tile_size * 4 + 24))
screen.blit(level_text, (TILE_SIZE / 2, TILE_SIZE * 4))
screen.blit(level, (TILE_SIZE / 2, TILE_SIZE * 4 + 24))
# Highscore (top-center)
highscore_text = self.font.render(f"High Score:", True, self.color)
highscore = self.font.render(f"{self.highscore}", True, self.color)
screen.blit(highscore_text, (self.tile_size / 2, self.tile_size * 5 + 24))
screen.blit(highscore, (self.tile_size / 2, self.tile_size * 6))
screen.blit(highscore_text, (TILE_SIZE / 2, TILE_SIZE * 5 + 24))
screen.blit(highscore, (TILE_SIZE / 2, TILE_SIZE * 6))
next_text = self.font.render("Next:", True, self.color)
screen.blit(next_text, (self.tile_size * 15, self.tile_size))
screen.blit(next_text, (TILE_SIZE * 15, TILE_SIZE))

View File

@@ -1,13 +1,16 @@
import pygame
import pygameControls as PC
import globals
globals.init()
from globals import GRID_WIDTH, GRID_HEIGHT, TILE_SIZE, BRICKS
import enums
from bricks import Brick, BRICKS, TILE_SIZE
from bricks import Brick
from random import randrange
from dropzone import DropZone
from dropnext import DropNext
from hud import Hud
__version__ = "0.0.4"
__version__ = "0.0.5"
# Constants
HAT_REPEAT_DELAY = 0 # milliseconds before first repeat
@@ -37,18 +40,18 @@ class Tetris:
self.screen_width, self.screen_height = (20 * TILE_SIZE), (20 * TILE_SIZE)
self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))
pygame.display.set_caption("Tetris " + __version__)
self.hud = Hud(self.screen_width, self.screen_height)
self.dropzone = DropZone(GRID_WIDTH, GRID_HEIGHT)
self.dropnext = DropNext(width = TILE_SIZE * 4, height = TILE_SIZE * 4)
self.current = Brick(brick = randrange(0, len(BRICKS)), state = enums.BrickState.Current)
print(self.current.layout)
print(self.current.shape)
print(self.current.color)
self.next = Brick(brick = randrange(0, len(BRICKS)))
print(self.next.layout)
print(self.next.shape)
print(self.next.color)
self.hud = Hud(self.screen_width, self.screen_height, TILE_SIZE)
self.dropzone = DropZone(TILE_SIZE, width = 10, height = 18)
self.dropnext = DropNext(width = TILE_SIZE * 4, height = TILE_SIZE * 4)
self.clock = pygame.time.Clock()
self.rumble_timer = pygame.time.get_ticks()
self.fall_speed = 1000 # in milliseconds
@@ -68,7 +71,7 @@ class Tetris:
self.hud.draw(self.screen)
self.dropzone.draw(self.screen)
self.dropzone.draw_brick(self.current.brick, self.current.location)
self.dropnext.draw(self.screen, TILE_SIZE)
self.dropnext.draw(self.screen)
self.dropnext.draw_block(self.next.brick)
self.handle_input()
@@ -118,6 +121,7 @@ class Tetris:
if self.current.direction == enums.BrickDirection.Dropped:
break
self.current.rotate()
self.dropzone.draw_brick(self.current.brick, self.current.location)
case pygame.K_RETURN:
if self.current.direction == enums.BrickDirection.Dropped:
break
@@ -134,17 +138,20 @@ class Tetris:
break
self.current.direction = enums.BrickDirection.Right
self.current.move_right()
self.dropzone.draw_brick(self.current.brick, self.current.location)
elif self.hat_x == -1:
if self.current.direction == enums.BrickDirection.Dropped:
break
self.current.direction = enums.BrickDirection.Left
self.current.move_left()
self.dropzone.draw_brick(self.current.brick, self.current.location)
case pygame.JOYBUTTONDOWN:
if event.button == 2:
if self.current.direction == enums.BrickDirection.Dropped:
break
self.current.rotate()
self.dropzone.draw_brick(self.current.brick, self.current.location)
elif event.button == 0:
if self.current.direction == enums.BrickDirection.Dropped:
break