10 Commits

Author SHA1 Message Date
363a89a590 V0.4 Exploding lines 2019-10-06 23:11:51 +02:00
f9c1fe4688 remove no longer necessary const 2019-10-06 18:19:14 +02:00
a0a414db14 particules! 2019-10-06 17:59:27 +02:00
4522ac1d4b rename refresh update 2019-10-06 13:42:37 +02:00
e3e05e87d7 replace mp3 by ogg 2019-10-06 12:57:01 +02:00
82f2b74e68 fix build-requirements.txt 2019-10-06 12:02:59 +02:00
504ebf8e51 reset held piece's minoes coord 2019-10-06 11:16:08 +02:00
4452eb821c refresh on update 2019-10-06 11:12:51 +02:00
e041a8118a refresh ghost on hold 2019-10-06 10:59:31 +02:00
0db5dd4d0d move up held in next pieces 2019-10-06 10:57:45 +02:00
16 changed files with 71 additions and 46 deletions

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import sys
import random
try:
import arcade
@ -26,18 +27,19 @@ from tetrislogic import TetrisLogic, Color, Phase, Coord, I_Tetrimino, Movement
# Matrix
LINES = 20
COLLUMNS = 10
NEXT_PIECES = 5
NEXT_PIECES = 6
# Delays (seconds)
LOCK_DELAY = 0.5
FALL_DELAY = 1
AUTOREPEAT_DELAY = 0.300
AUTOREPEAT_PERIOD = 0.010
PARTICULE_ACCELERATION = 1.1
# Piece init coord
MATRIX_PIECE_COORD = Coord(4, LINES)
NEXT_PIECES_COORDS = [Coord(COLLUMNS + 4, LINES - 4 * n - 3) for n in range(COLLUMNS)]
HELD_PIECE_COORD = Coord(-5, LINES - 3)
NEXT_PIECES_COORDS = [Coord(COLLUMNS + 4, LINES - 4 * n) for n in range(NEXT_PIECES)]
HELD_PIECE_COORD = Coord(-5, LINES)
# Window
WINDOW_WIDTH = 800
@ -73,10 +75,8 @@ RESOURCES_DIR = os.path.join(PROGRAM_DIR, "resources")
IMAGES_DIR = os.path.join(RESOURCES_DIR, "images")
WINDOW_BG_PATH = os.path.join(IMAGES_DIR, "bg.jpg")
MATRIX_BG_PATH = os.path.join(IMAGES_DIR, "matrix.png")
HELD_BG_PATH = os.path.join(IMAGES_DIR, "held.png")
NEXT_BG_PATH = os.path.join(IMAGES_DIR, "next.png")
MINOES_SPRITES_PATH = os.path.join(IMAGES_DIR, "minoes.png")
Color.PRELOCKED = 7
Color.LOCKED = 7
MINOES_COLOR_ID = {
Color.BLUE: 0,
Color.CYAN: 1,
@ -85,7 +85,7 @@ MINOES_COLOR_ID = {
Color.ORANGE: 4,
Color.RED: 5,
Color.YELLOW: 6,
Color.PRELOCKED: 7,
Color.LOCKED: 7,
}
TEXTURES = arcade.load_textures(
MINOES_SPRITES_PATH,
@ -128,10 +128,10 @@ class MinoSprite(arcade.Sprite):
self.alpha = alpha
self.window = window
self.append_texture(TEXTURES[mino.color])
self.append_texture(TEXTURES[Color.PRELOCKED])
self.append_texture(TEXTURES[Color.LOCKED])
self.set_texture(0)
def refresh(self, x, y, texture=0):
def update(self, x, y, texture=0):
self.scale = self.window.scale
size = MINO_SIZE * self.scale
self.left = self.window.matrix.bg.left + x * size
@ -143,7 +143,7 @@ class MinoesSprites(arcade.SpriteList):
def resize(self, scale):
for sprite in self:
sprite.scale = scale
self.refresh()
self.update()
class TetrominoSprites(MinoesSprites):
@ -155,23 +155,23 @@ class TetrominoSprites(MinoesSprites):
mino.sprite = MinoSprite(mino, window, alpha)
self.append(mino.sprite)
def refresh(self, texture=NORMAL_TEXTURE):
def update(self, texture=NORMAL_TEXTURE):
for mino in self.tetromino:
coord = mino.coord + self.tetromino.coord
mino.sprite.refresh(coord.x, coord.y, texture)
mino.sprite.update(coord.x, coord.y, texture)
class MatrixSprites(MinoesSprites):
def __init__(self, matrix):
super().__init__()
self.matrix = matrix
self.refresh()
self.update()
def refresh(self):
def update(self):
for y, line in enumerate(self.matrix):
for x, mino in enumerate(line):
if mino:
mino.sprite.refresh(x, y)
mino.sprite.update(x, y)
def remove_line(self, y):
for mino in self.matrix[y]:
@ -212,12 +212,9 @@ class TetrArcade(TetrisLogic, arcade.Window):
self.bg = arcade.Sprite(WINDOW_BG_PATH)
self.matrix.bg = arcade.Sprite(MATRIX_BG_PATH)
self.matrix.bg.alpha = MATRIX_BG_ALPHA
self.held.bg = arcade.Sprite(HELD_BG_PATH)
self.held.bg.alpha = BAR_ALPHA
self.next.bg = arcade.Sprite(NEXT_BG_PATH)
self.next.bg.alpha = BAR_ALPHA
self.matrix.sprites = MatrixSprites(self.matrix)
self.on_resize(self.init_width, self.init_height)
self.exploding_minoes = [None for y in range(LINES)]
if self.play_music:
try:
@ -373,39 +370,55 @@ AGAIN""".format(
self.show_text("LEVEL\n{:n}".format(level))
def on_generation_phase(self, matrix, falling_piece, ghost_piece, next_pieces):
matrix.sprites.refresh()
matrix.sprites.update()
falling_piece.sprites = TetrominoSprites(falling_piece, self)
ghost_piece.sprites = TetrominoSprites(ghost_piece, self, GHOST_ALPHA)
next_pieces[-1].sprites = TetrominoSprites(next_pieces[-1], self)
for piece, coord in zip(next_pieces, NEXT_PIECES_COORDS):
piece.coord = coord
piece.sprites.refresh()
def on_falling_phase(self, falling_piece, ghost_piece):
falling_piece.sprites.refresh()
ghost_piece.sprites.refresh()
def on_lock_phase(self, locked_piece):
locked_piece.sprites.refresh(texture=LOCKED_TEXTURE)
def on_locked(self, matrix, locked_piece):
for mino in locked_piece:
matrix.sprites.append(mino.sprite)
def on_line_remove(self, matrix, y):
line_textures = tuple(TEXTURES[mino.color] for mino in matrix[y])
self.exploding_minoes[y] = arcade.Emitter(
center_xy=(matrix.bg.left, matrix.bg.bottom + (y + 0.5) * MINO_SIZE),
emit_controller=arcade.EmitBurst(COLLUMNS),
particle_factory=lambda emitter: arcade.LifetimeParticle(
filename_or_texture=random.choice(line_textures),
change_xy=arcade.rand_in_rect(
(-COLLUMNS * MINO_SIZE, -4 * MINO_SIZE),
2 * COLLUMNS * MINO_SIZE,
5 * MINO_SIZE,
),
lifetime=1,
center_xy=arcade.rand_on_line((0, 0), (matrix.bg.width, 0)),
scale=self.scale,
alpha=NORMAL_ALPHA,
change_angle=2,
mutation_callback=self.speed_up_particule,
),
)
matrix.sprites.remove_line(y)
def speed_up_particule(self, particule):
particule.change_x *= PARTICULE_ACCELERATION
particule.change_y *= PARTICULE_ACCELERATION
def on_pattern_phase(self, pattern_name, pattern_score, nb_combo, combo_score):
if pattern_score:
self.show_text("{:s}\n{:n}".format(pattern_name, pattern_score))
if combo_score:
self.show_text("COMBO x{:n}\n{:n}".format(nb_combo, combo_score))
def on_hold(self, held_piece):
def on_hold(self, held_piece, falling_piece, ghost_piece):
held_piece.coord = HELD_PIECE_COORD
if type(held_piece) == I_Tetrimino:
held_piece.coord += Movement.LEFT
held_piece.sprites.refresh()
ghost_piece.sprites = TetrominoSprites(ghost_piece, self, GHOST_ALPHA)
def pause(self):
super().pause()
@ -455,8 +468,6 @@ AGAIN""".format(
if self.phase not in (Phase.STARTING, Phase.PAUSED):
self.matrix.bg.draw()
self.held.bg.draw()
self.next.bg.draw()
self.matrix.sprites.draw()
for tetromino in [
@ -504,6 +515,10 @@ AGAIN""".format(
anchor_x="right",
)
for exploding_minoes in self.exploding_minoes:
if exploding_minoes:
exploding_minoes.draw()
highlight_text = {
Phase.STARTING: self.start_text,
Phase.FALLING: self.highlight_texts[0] if self.highlight_texts else "",
@ -545,14 +560,6 @@ AGAIN""".format(
self.matrix.bg.left = int(self.matrix.bg.left)
self.matrix.bg.top = int(self.matrix.bg.top)
self.held.bg.scale = self.scale
self.held.bg.right = self.matrix.bg.left
self.held.bg.top = self.matrix.bg.top
self.next.bg.scale = self.scale
self.next.bg.left = self.matrix.bg.right
self.next.bg.top = self.matrix.bg.top
self.matrix.sprites.resize(self.scale)
for tetromino in [
@ -569,7 +576,7 @@ AGAIN""".format(
crypted_high_score = f.read()
super().load_high_score(crypted_high_score)
except:
self.high_score = 0
self.stats.high_score = 0
def save_high_score(self):
try:
@ -612,6 +619,17 @@ High score could not be saved:
arcade.unschedule(_task)
arcade.schedule(_task, period)
def update(self, delta_time):
for piece in [self.held.piece, self.matrix.ghost] + self.next.pieces:
if piece:
piece.sprites.update()
if self.matrix.piece:
texture = LOCKED_TEXTURE if self.phase == Phase.LOCK else NORMAL_TEXTURE
self.matrix.piece.sprites.update(texture=texture)
for exploding_minoes in self.exploding_minoes:
if exploding_minoes:
exploding_minoes.update()
def on_close(self):
self.save_high_score()
if self.music:

View File

@ -1 +1,2 @@
arcade cx-freeze
arcade
cx-freeze

Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
resources/musics/2-!!!.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -29,7 +29,7 @@ options = {
}
setup(
name="TetrArcade",
version="0.3",
version="0.4",
description="Tetris clone",
author="AdrienMalin",
executables=[executable],

View File

@ -23,7 +23,7 @@ for i in range(22):
game.on_draw()
game.lock_phase()
game.hold()
game.matrix.sprites.refresh()
game.matrix.sprites.update()
game.on_draw()
while game.phase != Phase.OVER:
game.hard_drop()

View File

@ -79,6 +79,7 @@ class Stats:
def __init__(self):
self._score = 0
self.high_score = 0
self.time = 0
def new_game(self, level):
@ -175,6 +176,7 @@ class TetrisLogic:
pass
def generation_phase(self):
self.phase = Phase.GENERATION
self.matrix.piece = self.next.pieces.pop(0)
self.next.pieces.append(Tetromino())
self.matrix.piece.coord = self.MATRIX_PIECE_COORD
@ -273,16 +275,19 @@ class TetrisLogic:
self.stop(self.fall)
self.matrix.piece, self.held.piece = self.held.piece, self.matrix.piece
self.on_hold(self.held.piece)
for mino, coord in zip(self.held.piece, self.held.piece.MINOES_COORDS):
mino.coord = coord
if self.matrix.piece:
self.matrix.piece.coord = self.MATRIX_PIECE_COORD
self.matrix.ghost = self.matrix.piece.ghost()
self.on_hold(self.held.piece, self.matrix.piece, self.matrix.ghost)
self.falling_phase()
else:
self.generation_phase()
self.on_hold(self.held.piece, self.matrix.piece, self.matrix.ghost)
def on_hold(self, held_piece):
def on_hold(self, held_piece, falling_piece, ghost_piece):
pass
def pattern_phase(self):

View File

@ -42,6 +42,7 @@ class Color:
class Phase:
STARTING = "STARTING"
GENERATION = "GENERATION"
FALLING = "FALLING"
LOCK = "LOCK"
PATTERN = "PATTERN"