|
|
|
@ -17,8 +17,7 @@
|
|
|
|
|
|
|
|
|
|
"""A clone of the arcade game Stacker""" |
|
|
|
|
|
|
|
|
|
__version__ = '2.1.0' |
|
|
|
|
__all__ = ['Slacker'] |
|
|
|
|
from __future__ import annotations |
|
|
|
|
|
|
|
|
|
from contextlib import ExitStack, redirect_stdout |
|
|
|
|
from importlib.resources import path |
|
|
|
@ -35,6 +34,8 @@ from pygame.font import Font
|
|
|
|
|
from pygame.surface import Surface |
|
|
|
|
from pygame.time import get_ticks |
|
|
|
|
|
|
|
|
|
__version__ = '2.1.1' |
|
|
|
|
|
|
|
|
|
TANGO = {'Butter': ((252, 233, 79), (237, 212, 0), (196, 160, 0)), |
|
|
|
|
'Orange': ((252, 175, 62), (245, 121, 0), (206, 92, 0)), |
|
|
|
|
'Chocolate': ((233, 185, 110), (193, 125, 17), (143, 89, 2)), |
|
|
|
@ -82,8 +83,10 @@ class SlackerTile:
|
|
|
|
|
self.wiggle = state in (INTRO, WIN) |
|
|
|
|
|
|
|
|
|
def get_xoffset(self, maxoffset: float, duration: int = 820) -> float: |
|
|
|
|
"""Return the offset on x-axis to make the tile complete an cycle of |
|
|
|
|
wiggling oscillation in given duration (in milliseconds). |
|
|
|
|
"""Return the offset on x-axis for wiggling oscillation. |
|
|
|
|
|
|
|
|
|
The oscillation's cycle can be specified |
|
|
|
|
in milliseconds as duration. |
|
|
|
|
""" |
|
|
|
|
if not self.wiggle: return 0 |
|
|
|
|
return maxoffset * cos((get_ticks()/duration+self.y/BOARD_HEIGHT)*pi) |
|
|
|
@ -111,9 +114,7 @@ class SlackerTile:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Slacker: |
|
|
|
|
"""This class provides functions to run the game Slacker, a clone of |
|
|
|
|
the popular arcade game Stacker. |
|
|
|
|
""" |
|
|
|
|
"""Game object.""" |
|
|
|
|
|
|
|
|
|
def __init__(self, restart: bool = False) -> None: |
|
|
|
|
self.exit_stack = ExitStack() |
|
|
|
@ -191,20 +192,22 @@ class Slacker:
|
|
|
|
|
for x in range(BOARD_WIDTH)] |
|
|
|
|
|
|
|
|
|
def key_hit(self) -> None: |
|
|
|
|
"""Process the current position of the blocks relatively to the |
|
|
|
|
ones underneath when user hit the switch, then decide if the |
|
|
|
|
user will win, lose or go to the next level of the tower. |
|
|
|
|
"""Handle block-stacking event. |
|
|
|
|
|
|
|
|
|
Process the current position of the blocks, relative to the ones |
|
|
|
|
underneath when user hit the switch, then decide if the user |
|
|
|
|
will win, lose or go to the next level of the tower. |
|
|
|
|
""" |
|
|
|
|
if self.y < BOARD_HEIGHT - 1: |
|
|
|
|
for x in range(max(0, self.x), |
|
|
|
|
min(self.x + self.width, BOARD_WIDTH)): |
|
|
|
|
# If there isn't any block underneath |
|
|
|
|
if not self.board[self.y + 1][x]: |
|
|
|
|
# Get rid of the block not standing on solid ground |
|
|
|
|
self.board[self.y][x] = False |
|
|
|
|
# Then, add that falling block to falling_tiles |
|
|
|
|
self.falling_tiles.append(SlackerTile( |
|
|
|
|
self.screen, x, self.y, missed_time=get_ticks())) |
|
|
|
|
min(self.x+self.width, BOARD_WIDTH)): |
|
|
|
|
if self.board[self.y + 1][x]: continue |
|
|
|
|
# If there isn't any block underneath, |
|
|
|
|
# get rid of the block not standing on solid ground |
|
|
|
|
self.board[self.y][x] = False |
|
|
|
|
# Then, add that falling block to falling_tiles |
|
|
|
|
self.falling_tiles.append(SlackerTile( |
|
|
|
|
self.screen, x, self.y, missed_time=get_ticks())) |
|
|
|
|
self.width = sum(self.board[self.y]) |
|
|
|
|
if not self.width: |
|
|
|
|
self.game_state = LOSE |
|
|
|
|