use customized arcade.SpriteList class for each tetrominoes' sprites

This commit is contained in:
adrienmalin 2019-09-30 00:52:41 +02:00
parent 317af4a3a6
commit afcb919018
4 changed files with 86 additions and 80 deletions

View File

@ -98,6 +98,52 @@ TO PLAY
AGAIN""" AGAIN"""
class MinoSprites(arcade.SpriteList):
def __init__(self, matrix):
super().__init__()
self.matrix = matrix
def update_mino(self, mino, x, y, alpha):
mino.sprite.left = self.matrix.sprite.left + x*(mino.sprite.width-1)
mino.sprite.bottom = self.matrix.sprite.bottom + y*(mino.sprite.height-1)
mino.sprite.alpha = alpha
class MatrixSprites(MinoSprites):
def __init__(self, matrix):
super().__init__(matrix)
for y, line in enumerate(matrix):
for x, mino in enumerate(line):
if mino:
self.update_mino(mino, x, y, NORMAL_ALPHA)
self.append(mino.sprite)
class TetrominoSprites(MinoSprites):
def __init__(self, tetromino, matrix, alpha=NORMAL_ALPHA):
super().__init__(matrix)
self.tetromino = tetromino
path = MINOES_SPRITES_PATHS[tetromino.MINOES_COLOR]
self.alpha = alpha
for mino in tetromino:
mino.sprite = arcade.Sprite(path)
mino.sprite.alpha = alpha
self.append(mino.sprite)
def update(self):
alpha = (
PRELOCKED_ALPHA
if self.tetromino.prelocked
else self.alpha
)
for mino in self.tetromino:
coord = mino.coord + self.tetromino.coord
self.update_mino(mino, coord.x, coord.y, alpha)
class TetrArcade(TetrisLogic, arcade.Window): class TetrArcade(TetrisLogic, arcade.Window):
def __init__(self): def __init__(self):
@ -154,8 +200,7 @@ class TetrArcade(TetrisLogic, arcade.Window):
self.matrix.sprite.center_y = center_y self.matrix.sprite.center_y = center_y
self.matrix.sprite.left = int(self.matrix.sprite.left) self.matrix.sprite.left = int(self.matrix.sprite.left)
self.matrix.sprite.top = int(self.matrix.sprite.top) self.matrix.sprite.top = int(self.matrix.sprite.top)
self.matrix.minoes_sprites = arcade.SpriteList() self.matrix.sprites = MatrixSprites(self.matrix)
self.tetrominos_sprites = arcade.SpriteList()
self.stats_text = arcade.create_text( self.stats_text = arcade.create_text(
text = STATS_TEXT, text = STATS_TEXT,
color = TEXT_COLOR, color = TEXT_COLOR,
@ -177,55 +222,44 @@ class TetrArcade(TetrisLogic, arcade.Window):
def new_game(self): def new_game(self):
self.highlight_texts = [] self.highlight_texts = []
self.matrix.minoes_sprites = arcade.SpriteList() self.matrix.sprites = MatrixSprites(self.matrix)
super().new_game() super().new_game()
def load_next(self): def new_next(self):
super().load_next() super().new_next()
for tetromino in self.next: self.next[-1].sprites = TetrominoSprites(self.next[-1], self.matrix)
self.load_minoes(tetromino)
def new_current(self): def new_current(self):
super().new_current() super().new_current()
self.update_tetromino(self.current) self.ghost.sprites = TetrominoSprites(self.ghost, self.matrix, GHOST_ALPHA)
self.load_minoes(self.next[-1])
self.load_minoes(self.ghost, GHOST_ALPHA)
for tetromino in [self.current, self.ghost] + self.next: for tetromino in [self.current, self.ghost] + self.next:
self.update_tetromino(tetromino) tetromino.sprites.update()
self.reload_all_tetrominoes()
def move(self, movement, prelock=True): def move(self, movement, prelock=True):
moved = super().move(movement, prelock) moved = super().move(movement, prelock)
if moved or self.current.prelocked: if moved or self.current.prelocked:
for tetromino in (self.current, self.ghost): for tetromino in (self.current, self.ghost):
self.update_tetromino(tetromino) tetromino.sprites.update()
return moved return moved
def rotate(self, rotation): def rotate(self, rotation):
if super().rotate(rotation): rotated = super().rotate(rotation)
if rotated:
for tetromino in (self.current, self.ghost): for tetromino in (self.current, self.ghost):
self.update_tetromino(tetromino) tetromino.sprites.update()
return True return rotated
else:
return False
def swap(self): def swap(self):
super().swap() super().swap()
self.load_minoes(self.ghost, GHOST_ALPHA) self.ghost.sprites = TetrominoSprites(self.ghost, self.matrix, GHOST_ALPHA)
for tetromino in [self.held, self.current, self.ghost]: for tetromino in [self.held, self.current, self.ghost]:
if tetromino: if tetromino:
self.update_tetromino(tetromino) tetromino.sprites.update()
self.reload_all_tetrominoes()
def lock(self): def lock(self):
self.update_tetromino(self.current) self.current.sprites.update()
super().lock() super().lock()
self.matrix.minoes_sprites = arcade.SpriteList() self.matrix.sprites = MatrixSprites(self.matrix)
for y, line in enumerate(self.matrix):
for x, mino in enumerate(line):
if mino:
self.update_mino(mino, x, y, NORMAL_ALPHA)
self.matrix.minoes_sprites.append(mino.sprite)
def game_over(self): def game_over(self):
super().game_over() super().game_over()
@ -240,12 +274,13 @@ class TetrArcade(TetrisLogic, arcade.Window):
self.do_action(action) self.do_action(action)
def on_key_release(self, key, modifiers): def on_key_release(self, key, modifiers):
try: for key_or_modifier in (key, modifiers):
action = self.KEY_MAP[self.state][key] try:
except KeyError: action = self.KEY_MAP[self.state][key_or_modifier]
pass except KeyError:
else: pass
self.remove_action(action) else:
self.remove_action(action)
def show_text(self, text): def show_text(self, text):
self.highlight_texts.append(text) self.highlight_texts.append(text)
@ -263,8 +298,10 @@ class TetrArcade(TetrisLogic, arcade.Window):
if self.state in (State.PLAYING, State.OVER): if self.state in (State.PLAYING, State.OVER):
self.matrix.sprite.draw() self.matrix.sprite.draw()
self.matrix.minoes_sprites.draw() self.matrix.sprites.draw()
self.tetrominoes_sprites.draw() for tetromino in [self.held, self.current, self.ghost] + self.next:
if tetromino:
tetromino.sprites.draw()
arcade.render_text( arcade.render_text(
self.stats_text, self.stats_text,
@ -315,35 +352,6 @@ class TetrArcade(TetrisLogic, arcade.Window):
anchor_y = 'center' anchor_y = 'center'
) )
def load_minoes(self, tetromino, alpha=NORMAL_ALPHA):
path = MINOES_SPRITES_PATHS[tetromino.MINOES_COLOR]
tetromino.alpha = alpha
for mino in tetromino:
mino.sprite = arcade.Sprite(path)
mino.sprite.alpha = alpha
def reload_all_tetrominoes(self):
self.tetrominoes_sprites = arcade.SpriteList()
for tetromino in [self.held, self.current, self.ghost] + self.next:
if tetromino:
for mino in tetromino:
self.tetrominoes_sprites.append(mino.sprite)
def update_tetromino(self, tetromino):
alpha = (
PRELOCKED_ALPHA
if tetromino.prelocked
else tetromino.alpha
)
for mino in tetromino:
coord = mino.coord + tetromino.coord
self.update_mino(mino, coord.x, coord.y, alpha)
def update_mino(self, mino, x, y, alpha):
mino.sprite.left = self.matrix.sprite.left + x*(mino.sprite.width-1)
mino.sprite.bottom = self.matrix.sprite.bottom + y*(mino.sprite.height-1)
mino.sprite.alpha = alpha
def load_high_score(self): def load_high_score(self):
try: try:
with open(HIGH_SCORE_PATH, "r") as f: with open(HIGH_SCORE_PATH, "r") as f:

View File

@ -1,3 +1,3 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from .consts import NB_LINES, NB_COLS, NB_NEXT_PIECES from .consts import NB_LINES, NB_COLS, NB_NEXT
from .tetrislogic import TetrisLogic, State from .tetrislogic import TetrisLogic, State

View File

@ -5,7 +5,7 @@ from .utils import Coord
# Matrix # Matrix
NB_LINES = 20 NB_LINES = 20
NB_COLS = 10 NB_COLS = 10
NB_NEXT_PIECES = 5 NB_NEXT = 5
# Delays (seconds) # Delays (seconds)
LOCK_DELAY = 0.5 LOCK_DELAY = 0.5
@ -18,7 +18,7 @@ AUTOREPEAT_PERIOD = 0.010 # Official : 0.010
CURRENT_COORD = Coord(4, NB_LINES) CURRENT_COORD = Coord(4, NB_LINES)
NEXT_COORDS = [ NEXT_COORDS = [
Coord(NB_COLS+6, NB_LINES-4*n-3) Coord(NB_COLS+6, NB_LINES-4*n-3)
for n in range(NB_NEXT_PIECES) for n in range(NB_NEXT)
] ]
HELD_COORD = Coord(-7, NB_LINES-3) HELD_COORD = Coord(-7, NB_LINES-3)
HELD_I_COORD = Coord(-7, NB_LINES-3) HELD_I_COORD = Coord(-7, NB_LINES-3)

View File

@ -2,7 +2,7 @@
from .utils import Coord, Movement, Rotation, T_Spin, Line from .utils import Coord, Movement, Rotation, T_Spin, Line
from .tetromino import Tetromino from .tetromino import Tetromino
from .consts import ( from .consts import (
NB_LINES, NB_COLS, NB_NEXT_PIECES, NB_LINES, NB_COLS, NB_NEXT,
LOCK_DELAY, FALL_DELAY, LOCK_DELAY, FALL_DELAY,
AUTOREPEAT_DELAY, AUTOREPEAT_PERIOD, AUTOREPEAT_DELAY, AUTOREPEAT_PERIOD,
CURRENT_COORD, NEXT_COORDS, HELD_COORD, HELD_I_COORD CURRENT_COORD, NEXT_COORDS, HELD_COORD, HELD_I_COORD
@ -71,18 +71,17 @@ class TetrisLogic():
self.matrix.clear() self.matrix.clear()
for y in range(NB_LINES+3): for y in range(NB_LINES+3):
self.append_new_line_to_matrix() self.append_new_line_to_matrix()
self.load_next() self.next = []
for n in range(NB_NEXT):
self.new_next()
self.held = None self.held = None
self.state = State.PLAYING self.state = State.PLAYING
self.start(self.update_time, 1) self.start(self.update_time, 1)
self.new_level() self.new_level()
def load_next(self): def new_next(self):
self.next = [ self.next.append(Tetromino())
Tetromino()
for i in range(NB_NEXT_PIECES)
]
def append_new_line_to_matrix(self): def append_new_line_to_matrix(self):
self.matrix.append(Line(None for x in range(NB_COLS))) self.matrix.append(Line(None for x in range(NB_COLS)))
@ -104,7 +103,7 @@ class TetrisLogic():
self.current.coord = CURRENT_COORD self.current.coord = CURRENT_COORD
self.ghost = self.current.ghost() self.ghost = self.current.ghost()
self.move_ghost() self.move_ghost()
self.next.append(Tetromino()) self.new_next()
self.next[-1].coord = NEXT_COORDS[-1] self.next[-1].coord = NEXT_COORDS[-1]
for tetromino, coord in zip (self.next, NEXT_COORDS): for tetromino, coord in zip (self.next, NEXT_COORDS):
tetromino.coord = coord tetromino.coord = coord
@ -138,11 +137,10 @@ class TetrisLogic():
self.ghost.coord += Movement.DOWN self.ghost.coord += Movement.DOWN
def soft_drop(self): def soft_drop(self):
if self.move(Movement.DOWN): moved = self.move(Movement.DOWN)
if moved:
self.score += 1 self.score += 1
return True return moved
else:
return False
def hard_drop(self): def hard_drop(self):
while self.move(Movement.DOWN, prelock=False): while self.move(Movement.DOWN, prelock=False):