This commit is contained in:
Adrien MALINGREY 2019-10-08 22:31:05 +02:00
parent 5ed15da4ed
commit 4df3c6c9ba
3 changed files with 47 additions and 45 deletions

View File

@ -38,6 +38,7 @@ FALL_DELAY = 1
AUTOREPEAT_DELAY = 0.300 AUTOREPEAT_DELAY = 0.300
AUTOREPEAT_PERIOD = 0.010 AUTOREPEAT_PERIOD = 0.010
PARTICULE_ACCELERATION = 1.1 PARTICULE_ACCELERATION = 1.1
EXPLOSION_ANIMATION = 1
# Piece init coord # Piece init coord
MATRIX_PIECE_COORD = Coord(4, LINES) MATRIX_PIECE_COORD = Coord(4, LINES)
@ -176,11 +177,13 @@ class MinoSprite(arcade.Sprite):
self.set_texture(0) self.set_texture(0)
def update(self, x, y): def update(self, x, y):
self.scale = self.window.scale size = MINO_SIZE * self.window.scale
size = MINO_SIZE * self.scale
self.left = self.window.matrix.bg.left + x * size self.left = self.window.matrix.bg.left + x * size
self.bottom = self.window.matrix.bg.bottom + y * size self.bottom = self.window.matrix.bg.bottom + y * size
def fall(self, lines_cleared):
self.bottom -= MINO_SIZE * self.window.scale * lines_cleared
class MinoesSprites(arcade.SpriteList): class MinoesSprites(arcade.SpriteList):
def resize(self, scale): def resize(self, scale):
@ -206,14 +209,12 @@ class TetrominoSprites(MinoesSprites):
def set_texture(self, texture): def set_texture(self, texture):
for mino in self.tetromino: for mino in self.tetromino:
mino.sprite.set_texture(texture) mino.sprite.set_texture(texture)
self.update()
class MatrixSprites(MinoesSprites): class MatrixSprites(MinoesSprites):
def __init__(self, matrix): def __init__(self, matrix):
super().__init__() super().__init__()
self.matrix = matrix self.matrix = matrix
self.update()
def update(self): def update(self):
for y, line in enumerate(self.matrix): for y, line in enumerate(self.matrix):
@ -221,12 +222,12 @@ class MatrixSprites(MinoesSprites):
if mino: if mino:
mino.sprite.update(x, y) mino.sprite.update(x, y)
def remove_line(self, y): def remove_lines(self, lines_to_remove):
for y in lines_to_remove:
for mino in self.matrix[y]: for mino in self.matrix[y]:
if mino: if mino:
self.remove(mino.sprite) self.remove(mino.sprite)
class TetrArcade(TetrisLogic, arcade.Window): class TetrArcade(TetrisLogic, arcade.Window):
"""Tetris clone with arcade GUI library""" """Tetris clone with arcade GUI library"""
@ -392,7 +393,7 @@ AGAIN""".format(
def on_new_game(self, matrix, next_pieces): def on_new_game(self, matrix, next_pieces):
self.highlight_texts = [] self.highlight_texts = []
matrix.sprites = MatrixSprites(self.matrix) self.matrix.sprites = MatrixSprites(matrix)
for piece in next_pieces: for piece in next_pieces:
piece.sprites = TetrominoSprites(piece, self) piece.sprites = TetrominoSprites(piece, self)
@ -412,12 +413,18 @@ AGAIN""".format(
next_pieces[-1].sprites = TetrominoSprites(next_pieces[-1], self) next_pieces[-1].sprites = TetrominoSprites(next_pieces[-1], self)
for piece, coord in zip(next_pieces, NEXT_PIECES_COORDS): for piece, coord in zip(next_pieces, NEXT_PIECES_COORDS):
piece.coord = coord piece.coord = coord
for piece in [falling_piece, ghost_piece] + next_pieces:
piece.sprites.update()
def on_falling_phase(self, falling_piece): def on_falling_phase(self, falling_piece, ghost_piece):
falling_piece.sprites.set_texture(Texture.NORMAL) falling_piece.sprites.set_texture(Texture.NORMAL)
falling_piece.sprites.update()
ghost_piece.sprites.update()
def on_locked(self, falling_piece): def on_locked(self, falling_piece, ghost_piece):
falling_piece.sprites.set_texture(Texture.LOCKED) falling_piece.sprites.set_texture(Texture.LOCKED)
falling_piece.sprites.update()
ghost_piece.sprites.update()
def on_locks_down(self, matrix, falling_piece): def on_locks_down(self, matrix, falling_piece):
falling_piece.sprites.set_texture(Texture.NORMAL) falling_piece.sprites.set_texture(Texture.NORMAL)
@ -425,6 +432,10 @@ AGAIN""".format(
matrix.sprites.append(mino.sprite) matrix.sprites.append(mino.sprite)
def on_animate_phase(self, matrix, lines_to_remove): def on_animate_phase(self, matrix, lines_to_remove):
if not lines_to_remove:
return
self.timer.cancel(self.clean_particules)
for y in lines_to_remove: for y in lines_to_remove:
line_textures = tuple(TEXTURES[mino.color] for mino in matrix[y]) line_textures = tuple(TEXTURES[mino.color] for mino in matrix[y])
self.exploding_minoes[y] = arcade.Emitter( self.exploding_minoes[y] = arcade.Emitter(
@ -437,22 +448,20 @@ AGAIN""".format(
2 * COLLUMNS * MINO_SIZE, 2 * COLLUMNS * MINO_SIZE,
5 * MINO_SIZE, 5 * MINO_SIZE,
), ),
lifetime=0.2, lifetime=EXPLOSION_ANIMATION,
center_xy=arcade.rand_on_line((0, 0), (matrix.bg.width, 0)), center_xy=arcade.rand_on_line((0, 0), (matrix.bg.width, 0)),
scale=self.scale, scale=self.scale,
alpha=NORMAL_ALPHA, alpha=NORMAL_ALPHA,
change_angle=2, change_angle=2,
mutation_callback=self.speed_up_particule,
), ),
) )
self.timer.postpone(self.clean_particules, EXPLOSION_ANIMATION)
def speed_up_particule(self, particule): def clean_particules(self):
particule.change_x *= PARTICULE_ACCELERATION self.exploding_minoes = [None for y in range(LINES)]
particule.change_y *= PARTICULE_ACCELERATION
def on_eliminate_phase(self, matrix, lines_to_remove): def on_eliminate_phase(self, matrix, lines_to_remove):
for y in lines_to_remove: matrix.sprites.remove_lines(lines_to_remove)
matrix.sprites.remove_line(y)
def on_completion_phase(self, pattern_name, pattern_score, nb_combo, combo_score): def on_completion_phase(self, pattern_name, pattern_score, nb_combo, combo_score):
if pattern_score: if pattern_score:
@ -464,6 +473,7 @@ AGAIN""".format(
held_piece.coord = HELD_PIECE_COORD held_piece.coord = HELD_PIECE_COORD
if type(held_piece) == I_Tetrimino: if type(held_piece) == I_Tetrimino:
held_piece.coord += Movement.LEFT held_piece.coord += Movement.LEFT
held_piece.sprites.update()
def on_pause(self): def on_pause(self):
self.state = State.PAUSED self.state = State.PAUSED
@ -640,13 +650,6 @@ High score could not be saved:
) )
def update(self, delta_time): def update(self, delta_time):
for piece in [
self.held.piece,
self.matrix.piece,
self.matrix.ghost,
] + self.next.pieces:
if piece:
piece.sprites.update()
for exploding_minoes in self.exploding_minoes: for exploding_minoes in self.exploding_minoes:
if exploding_minoes: if exploding_minoes:
exploding_minoes.update() exploding_minoes.update()

View File

@ -29,8 +29,6 @@ game.lock_phase()
game.hold() game.hold()
game.update(0) game.update(0)
game.on_draw() game.on_draw()
game.matrix.sprites.update()
game.on_draw()
while game.state != State.OVER: while game.state != State.OVER:
game.hard_drop() game.hard_drop()
game.on_draw() game.on_draw()

View File

@ -255,17 +255,14 @@ class TetrisLogic:
self.timer.cancel(self.locks_down) self.timer.cancel(self.locks_down)
self.matrix.piece.locked = False self.matrix.piece.locked = False
self.timer.postpone(self.lock_phase, self.stats.fall_delay) self.timer.postpone(self.lock_phase, self.stats.fall_delay)
self.on_falling_phase(self.matrix.piece) self.on_falling_phase(self.matrix.piece, self.matrix.ghost)
def on_falling_phase(self, falling_piece): def on_falling_phase(self, falling_piece, ghost_piece):
pass pass
def lock_phase(self): def lock_phase(self):
self.move(Movement.DOWN) self.move(Movement.DOWN)
def on_locked(self, falling_piece):
pass
def move(self, movement, rotated_coords=None, lock=True): def move(self, movement, rotated_coords=None, lock=True):
potential_coord = self.matrix.piece.coord + movement potential_coord = self.matrix.piece.coord + movement
potential_minoes_coords = rotated_coords or ( potential_minoes_coords = rotated_coords or (
@ -283,12 +280,15 @@ class TetrisLogic:
self.falling_phase() self.falling_phase()
else: else:
self.matrix.piece.locked = True self.matrix.piece.locked = True
self.on_locked(self.matrix.piece) self.on_locked(self.matrix.piece, self.matrix.ghost)
self.timer.reset(self.locks_down, self.stats.lock_delay) self.timer.reset(self.locks_down, self.stats.lock_delay)
return True return True
else: else:
return False return False
def on_locked(self, falling_piece, ghost_piece):
pass
def rotate(self, spin): def rotate(self, spin):
rotated_coords = tuple(mino.coord @ spin for mino in self.matrix.piece) rotated_coords = tuple(mino.coord @ spin for mino in self.matrix.piece)
for rotation_point, liberty_degree in enumerate( for rotation_point, liberty_degree in enumerate(
@ -343,22 +343,23 @@ class TetrisLogic:
else: else:
t_spin = T_Spin.NONE t_spin = T_Spin.NONE
# Clear complete lines # Complete lines
self.lines_to_remove = [] lines_to_remove = []
for y, line in reversed(list(enumerate(self.matrix))): for y, line in reversed(list(enumerate(self.matrix))):
if all(mino for mino in line): if all(mino for mino in line):
self.lines_to_remove.append(y) lines_to_remove.append(y)
lines_cleared = len(self.lines_to_remove)
lines_cleared = len(lines_to_remove)
if lines_cleared: if lines_cleared:
self.stats.lines_cleared += lines_cleared self.stats.lines_cleared += lines_cleared
# Animate phase # Animate phase
self.on_animate_phase(self.matrix, self.lines_to_remove) self.on_animate_phase(self.matrix, lines_to_remove)
# Eliminate phase # Eliminate phase
self.on_eliminate_phase(self.matrix, self.lines_to_remove) self.on_eliminate_phase(self.matrix, lines_to_remove)
for y in self.lines_to_remove: for y in lines_to_remove:
self.matrix.pop(y) self.matrix.pop(y)
self.matrix.append_new_line() self.matrix.append_new_line()