Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import pygame
- import random
- # Initialize pygame
- pygame.init()
- # Constants
- SCREEN_WIDTH, SCREEN_HEIGHT = 300, 600
- GRID_SIZE = 30
- COLUMNS, ROWS = SCREEN_WIDTH // GRID_SIZE, SCREEN_HEIGHT // GRID_SIZE
- WHITE = (255, 255, 255)
- BLACK = (0, 0, 0)
- FPS = 60
- FALL_SPEED = 500 # Tetromino falls every 500ms
- CEMENT_DELAY = 100 # Delay of 100ms before cementing
- # Tetromino shapes
- SHAPES = [
- [[1, 1, 1],
- [0, 1, 0]],
- [[0, 1, 1],
- [1, 1, 0]],
- [[1, 1, 0],
- [0, 1, 1]],
- [[1, 1],
- [1, 1]],
- [[1, 1, 1, 1]],
- [[1, 1, 1],
- [1, 0, 0]],
- [[1, 1, 1],
- [0, 0, 1]],
- ]
- class Tetromino:
- def __init__(self):
- self.shape = random.choice(SHAPES)
- self.x = COLUMNS // 2 - len(self.shape[0]) // 2
- self.y = 0
- self.hit_ground_time = None # Track when the piece first hits the ground
- def rotate(self):
- new_shape = [list(row) for row in zip(*self.shape[::-1])]
- if self.can_move(0, 0, new_shape):
- self.shape = new_shape
- def can_move(self, dx, dy, shape=None):
- shape = shape or self.shape
- for y, row in enumerate(shape):
- for x, cell in enumerate(row):
- if cell:
- new_x = self.x + x + dx
- new_y = self.y + y + dy
- if new_x < 0 or new_x >= COLUMNS or new_y >= ROWS or grid[new_y][new_x]:
- return False
- return True
- def move(self, dx, dy):
- if self.can_move(dx, dy):
- self.x += dx
- self.y += dy
- return True
- return False
- def cement(self):
- for y, row in enumerate(self.shape):
- for x, cell in enumerate(row):
- if cell:
- grid[self.y + y][self.x + x] = 1
- def create_grid():
- return [[0 for _ in range(COLUMNS)] for _ in range(ROWS)]
- def draw_grid(screen):
- for y, row in enumerate(grid):
- for x, cell in enumerate(row):
- if cell:
- pygame.draw.rect(screen, WHITE, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE), 0)
- def clear_lines():
- global grid
- new_grid = [row for row in grid if any(cell == 0 for cell in row)]
- lines_cleared = ROWS - len(new_grid)
- for _ in range(lines_cleared):
- new_grid.insert(0, [0] * COLUMNS)
- grid = new_grid
- return lines_cleared
- def main():
- global grid
- screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
- clock = pygame.time.Clock()
- grid = create_grid()
- tetromino = Tetromino()
- fall_time = 0
- cement_time = None # Timer for cementing the piece
- running = True
- while running:
- screen.fill(BLACK)
- # Game loop timing
- fall_time += clock.get_rawtime()
- clock.tick(FPS)
- # Automatically move the tetromino down based on fall speed
- if fall_time > FALL_SPEED:
- if not tetromino.move(0, 1): # If it can't move down
- if cement_time is None: # Start the cement timer if not already started
- cement_time = pygame.time.get_ticks()
- else:
- # If 100ms have passed since it hit the ground, cement the piece
- if pygame.time.get_ticks() - cement_time >= CEMENT_DELAY:
- tetromino.cement() # Cement the piece
- clear_lines() # Clear any full lines
- tetromino = Tetromino() # Spawn a new piece
- cement_time = None # Reset cement timer
- else:
- cement_time = None # Reset if it moved down successfully
- fall_time = 0
- # Handle events
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- running = False
- elif event.type == pygame.KEYDOWN:
- if event.key == pygame.K_LEFT:
- tetromino.move(-1, 0)
- elif event.key == pygame.K_RIGHT:
- tetromino.move(1, 0)
- elif event.key == pygame.K_DOWN:
- tetromino.move(0, 1)
- elif event.key == pygame.K_UP:
- tetromino.rotate()
- draw_grid(screen)
- # Draw current tetromino
- for y, row in enumerate(tetromino.shape):
- for x, cell in enumerate(row):
- if cell:
- pygame.draw.rect(screen, WHITE,
- ((tetromino.x + x) * GRID_SIZE,
- (tetromino.y + y) * GRID_SIZE,
- GRID_SIZE, GRID_SIZE), 0)
- pygame.display.flip()
- pygame.quit()
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement