use customized arcade.SpriteList class for each tetrominoes' sprites
This commit is contained in:
parent
317af4a3a6
commit
afcb919018
138
tetrarcade.py
138
tetrarcade.py
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
@ -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):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user