class Game: width = 10 height = 20 pause = False start = True BLACK = (0, 0, 0) WHITE = (255, 255, 255) GRAY = (190, 190, 190) GREEN = (0, 255, 0) RED = (255, 0, 0) def drawBoard(self, screen, board, width, height): for y in range(self.height): for x in range(self.width): if self.board[y][x]: pygame.draw.rect(self.screen, self.board[y][x].color, (40 * x, 40 * y, 40, 40)) def __init__(self): pygame.init() self.size = (self.width * 40 + 400, self.height * 40) self.screen = pygame.display.set_mode(self.size) pygame.display.set_caption("Tetris") self.clock = pygame.time.Clock() self.continueGame = True self.steps = 0 def setUpBoard(self): self.gameover = False self.board = Board(self.width, self.height) d = True self.pieceSelect = ['T', 'L', 'I', 'J', 'O', 'S', 'Z'] self.p = Piece(self.width, self.height, random.choice(self.pieceSelect), self.board) self.p.genBoard() self.pNext = Piece(self.width, self.height, random.choice(self.pieceSelect), self.board) self.pNext.genBoard() # for x in range(10): # p.moveDown() self.board.addCellsTemp(self.p) self.done = False self.pNext = Piece(self.width, self.height, random.choice(self.pieceSelect), self.board) self.pNext.genBoard() def shouldGameTick(self, step): level = self.board.level if level == 0 or level == 1: if step % 48 == 0 and step != 0: return True elif level == 1: if step % 43 == 0 and step != 0: return True elif level == 2: if step % 38 == 0 and step != 0: return True elif level == 3: if step % 33 == 0 and step != 0: return True elif level == 4: if step % 28 == 0 and step != 0: return True elif level == 5: if step % 23 == 0 and step != 0: return True elif level == 6: if step % 18 == 0 and step != 0: return True elif level == 7: if step % 13 == 0 and step != 0: return True elif level == 8: if step % 8 == 0 and step != 0: return True elif level == 9: if step % 6 == 0 and step != 0: return True elif level <= 12: if step % 5 == 0 and step != 0: return True elif level <= 15: if step % 4 == 0 and step != 0: return True elif level <= 18: if step % 3 == 0 and step != 0: return True elif level <= 28: if step % 2 == 0 and step != 0: return True else: return True def moveDown(self): if not self.board.checkIfSet(self.p): self.p.moveDown() self.board.addCellsTemp(self.p) else: self.board.addCells(self.p) self.gameover = self.board.checkIfGameOver() self.board.checkCompleteRows() self.p = self.pNext self.pNext = Piece(self.width, self.height, random.choice(self.pieceSelect), self.board) self.pNext.genBoard() self.board.addCellsTemp(self.p) while not self.shouldGameTick(self.steps): self.steps += 1 self.steps += 1 def hardDrop(self): while not self.board.checkIfSet(self.p): self.p.moveDown() self.board.addCellsTemp(self.p) self.board.addCells(self.p) self.gameover = self.board.checkIfGameOver() if self.gameover: x = 1 self.board.checkCompleteRows() self.p = self.pNext self.pNext = Piece(self.width, self.height, random.choice(self.pieceSelect), self.board) self.pNext.genBoard() self.board.addCellsTemp(self.p) while not self.shouldGameTick(self.steps): self.steps += 1 self.steps += 1 def mainLoop(self): while self.continueGame: self.setUpBoard() self.gameLoop() # Close the window and quit. pygame.quit() def gameLoop(self): self.steps = 0 while not self.done: hardDrop = False for event in pygame.event.get(): if event.type == pygame.QUIT: self.done = True self.continueGame = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: self.done = True self.continueGame = False if event.key == pygame.K_r: self.done = True if not (self.pause or self.gameover or self.start): if event.key == pygame.K_LEFT: self.p.move(1) self.board.addCellsTemp(self.p) if event.key == pygame.K_RIGHT: self.p.move(0) self.board.addCellsTemp(self.p) if event.key == pygame.K_UP: self.p.rotate() self.board.addCellsTemp(self.p) if event.key == pygame.K_DOWN: self.moveDown() if event.key == pygame.K_SPACE: self.hardDrop() hardDrop = True if event.key == pygame.K_p: self.pause = not self.pause if event.key == pygame.K_SPACE: self.start = False # --- Game logic should go here if not (self.pause or self.gameover or self.start): if self.shouldGameTick(self.steps) and not hardDrop: self.moveDown() # --- Drawing code should go here if self.pause: self.screen.fill(self.WHITE) elif self.start: self.screen.fill(self.GRAY) else: self.screen.fill(self.BLACK) pygame.draw.rect( self.screen, (66, 79, 159), (self.width * 40, 0, self.width * 40 + 200, self.height * 40)) self.drawBoard(self.screen, self.board, self.width, self.height) self.board.drawGUI(self.screen, self.pNext) if self.start: self.board.drawTitle(self.screen) elif self.pause: self.board.drawGUI(self.screen, self.pNext) if self.pause: self.board.drawPause(self.screen) elif self.gameover: self.board.drawGameover(self.screen) # --- Go ahead and update the screen with what we've drawn. pygame.display.flip() # --- Limit to 60 frames per second self.clock.tick(60) self.steps += 1
class Tetris: def __init__(self): self.pygame_screen = None self.clock = None self.font = None self.piece = None self.squares = [] self.particles = [] self.outer_squares = [] self.drops_per_second = 6 self.frames_per_second = 30 self.score = 0 self.lines = 0 self.high_score = int(open("files/highscore.txt", "r").read()) self.background = pygame.image.load('files/images/background4.jpg') self.game_running = True self.setup() def setup(self): pygame.init() pygame.font.init() self.pygame_screen = pygame.display.set_mode((582, 785)) self.clock = pygame.time.Clock() self.font = pygame.font.Font('files/fonts/arial.ttf', 45) def splash_screens(self): self.splash_screen() self.start_screen() def start_game(self): self.game_loop() def splash_screen(self): frame_counter = 0 self.pygame_screen.blit(pygame.image.load('files/images/splash.jpg'), (0, 0)) while frame_counter < 30 and self.game_running: frame_counter += 1 for event in pygame.event.get(): if event.type == pygame.QUIT: self.game_running = False pygame.display.update() self.clock.tick(self.frames_per_second) def start_screen(self): space_pressed = False while not space_pressed and self.game_running: self.pygame_screen.blit( pygame.image.load('files/images/background5.jpg'), (0, 0)) self.pygame_screen.blit( pygame.image.load('files/images/startButton.png'), (231, 360)) for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: space_pressed = True elif event.type == pygame.QUIT: self.game_running = False pygame.display.update() self.clock.tick(self.frames_per_second) def game_loop(self): frame_counter = 1 self.create_floor() self.create_walls() self.new_piece() while self.game_running: for event in pygame.event.get(): if event.type == pygame.QUIT: self.game_running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT or event.key == pygame.K_a: self.move_piece_sideways('left') if event.key == pygame.K_RIGHT or event.key == pygame.K_d: self.move_piece_sideways('right') if event.key == pygame.K_UP or event.key == pygame.K_w: self.rotate_piece() if event.key == pygame.K_DOWN or event.key == pygame.K_s: self.move_piece_down() if event.key == pygame.K_SPACE: self.drop_piece() if frame_counter % (self.frames_per_second / self.drops_per_second) == 0: self.move_piece_down() frame_counter += 1 self.blit_everything() pygame.display.update() self.clock.tick(self.frames_per_second) def create_floor(self): for col in range(10): self.outer_squares.append(Square(None, 8, col, 18)) def create_walls(self): for row in range(-1, 18): self.outer_squares.append(Square(None, 8, -1, row)) for row in range(-1, 18): self.outer_squares.append(Square(None, 8, 10, row)) def new_piece(self): self.piece = Piece(self.pygame_screen) def move_piece_down(self): if self.can_piece_move_down(): self.piece.move_down() return True else: self.piece_collide() return False def move_piece_sideways(self, direction): if self.can_piece_move_sideways(direction): self.piece.move_sideways(direction) def can_piece_move_down(self): for piece_square in self.piece.get_squares(): for board_square in self.squares + self.outer_squares: if piece_square.get_column() == board_square.get_column( ) and piece_square.get_row() + 1 == board_square.get_row(): return False return True def can_piece_move_sideways(self, direction): if direction == 'right': direction_number = 1 else: direction_number = -1 for piece_square in self.piece.get_squares(): for board_square in self.squares + self.outer_squares: if piece_square.get_column( ) + direction_number == board_square.get_column( ) and piece_square.get_row() == board_square.get_row(): return False return True def rotate_piece(self): new_squares = self.can_rotate_piece() if new_squares is not False: self.piece.rotate(new_squares) def can_rotate_piece(self): new_squares = self.piece.get_rotate_squares() for piece_square in new_squares: for board_square in self.squares + self.outer_squares: if (piece_square.get_column(), piece_square.get_row()) == (board_square.get_column(), board_square.get_row()): return False return new_squares def piece_collide(self): if self.did_lose(): self.ask_play_again() else: self.squares += self.piece.get_squares() self.check_line_win() self.new_piece() def blit_everything(self): self.pygame_screen.blit(self.background, (0, 0)) self.piece.blit() for square in self.squares: square.blit() self.blit_scores() self.blit_particles() def blit_particles(self): index = 0 for i in range(len(self.particles)): particle = self.particles[index] particle.blit() if not particle.blit(): del self.particles[index] else: index += 1 def check_line_win(self): row_dictionary = {} for square in self.squares: square_row = square.get_row() if square_row in row_dictionary: row_dictionary[square_row] += 1 else: row_dictionary[square_row] = 1 win_count = 0 for row in sorted(row_dictionary): # row_dictionary[row] = 10 #always win if row_dictionary[row] == 10: win_count += 1 self.add_particles(row) self.delete_row(row) self.drop_rows_down(row) if win_count > 0: self.lines += win_count self.add_to_score(win_count) def add_particles(self, line): for square in self.squares: if square.get_row() == line: for row in range(2): for col in range(15): self.particles.append( Particle(self.pygame_screen, col, row, line, 5)) def delete_row(self, row): index = 0 for i in range(len(self.squares)): square = self.squares[index] if square.get_row() == row: del self.squares[index] else: index += 1 def drop_rows_down(self, start): for square in self.squares: if square.get_row() < start: square.move_down() def drop_piece(self): while self.move_piece_down(): pass def add_to_score(self, win_count): new_score = 0 for i in range(win_count): new_score += ((i + 1) * 10) self.score += new_score if self.score > self.high_score: self.high_score = self.score open("files/highscore.txt", "w").write(str(self.high_score)) def blit_scores(self): block = self.font.render(str(self.lines), True, (0, 0, 0)) rect = block.get_rect() rect.center = (510, 250) self.pygame_screen.blit(block, rect) block = self.font.render(str(self.score), True, (0, 0, 0)) rect = block.get_rect() rect.center = (510, 350) self.pygame_screen.blit(block, rect) block = self.font.render(str(self.high_score), True, (0, 0, 0)) rect = block.get_rect() rect.center = (510, 465) self.pygame_screen.blit(block, rect) def did_lose(self): for square in self.piece.get_squares(): if square.get_row() < 0: return True return False def ask_play_again(self): space_pressed = False while not space_pressed and self.game_running: self.pygame_screen.blit( pygame.image.load('files/images/playAgainButton.png'), (231, 360)) for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: space_pressed = True self.reset_game() elif event.type == pygame.QUIT: self.game_running = False pygame.display.update() self.clock.tick(self.frames_per_second) def reset_game(self): self.piece = None self.squares = [] self.score = 0 self.lines = 0 self.new_piece()