Type hint and nit whitespace
This commit is contained in:
parent
90372bc198
commit
d1fba2ffff
|
@ -7,7 +7,7 @@ module = 'slacker_game'
|
||||||
author = 'Nguyễn Gia Phong'
|
author = 'Nguyễn Gia Phong'
|
||||||
author-email = 'mcsinyx@disroot.org'
|
author-email = 'mcsinyx@disroot.org'
|
||||||
home-page = 'https://git.disroot.org/McSinyx/slacker-game'
|
home-page = 'https://git.disroot.org/McSinyx/slacker-game'
|
||||||
requires = ['pygame']
|
requires = ['pygame>=2.0.0.dev8']
|
||||||
description-file = 'README.rst'
|
description-file = 'README.rst'
|
||||||
classifiers = [
|
classifiers = [
|
||||||
'Development Status :: 4 - Beta',
|
'Development Status :: 4 - Beta',
|
||||||
|
|
|
@ -25,12 +25,14 @@ from importlib.resources import path
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from math import cos, pi
|
from math import cos, pi
|
||||||
from random import randrange
|
from random import randrange
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
with redirect_stdout(StringIO()): import pygame
|
with redirect_stdout(StringIO()): import pygame
|
||||||
from pygame import (K_0, K_1, K_9, K_ESCAPE, K_SPACE, KEYDOWN,
|
from pygame import (K_0, K_1, K_9, K_ESCAPE, K_SPACE, KEYDOWN,
|
||||||
QUIT, K_q, Rect, draw, event, image)
|
QUIT, K_q, Rect, draw, event, image)
|
||||||
from pygame.display import flip, set_caption, set_icon, set_mode
|
from pygame.display import flip, set_caption, set_icon, set_mode
|
||||||
from pygame.font import Font
|
from pygame.font import Font
|
||||||
|
from pygame.surface import Surface
|
||||||
from pygame.time import get_ticks
|
from pygame.time import get_ticks
|
||||||
|
|
||||||
TANGO = {'Butter': ((252, 233, 79), (237, 212, 0), (196, 160, 0)),
|
TANGO = {'Butter': ((252, 233, 79), (237, 212, 0), (196, 160, 0)),
|
||||||
|
@ -66,7 +68,9 @@ class SlackerTile:
|
||||||
Slacker object for storing tiles.
|
Slacker object for storing tiles.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, screen, x, y, state=1, missed_time=None):
|
def __init__(self, screen: Surface,
|
||||||
|
x: float, y: float, state: int = PLAYING,
|
||||||
|
missed_time: Optional[int] = None) -> None:
|
||||||
self.screen, self.x, self.y = screen, x, y
|
self.screen, self.x, self.y = screen, x, y
|
||||||
if state == LOSE:
|
if state == LOSE:
|
||||||
self.dim = 1
|
self.dim = 1
|
||||||
|
@ -77,23 +81,23 @@ class SlackerTile:
|
||||||
self.missed_time = missed_time
|
self.missed_time = missed_time
|
||||||
self.wiggle = state in (INTRO, WIN)
|
self.wiggle = state in (INTRO, WIN)
|
||||||
|
|
||||||
def get_xoffset(self, maxoffset, duration=820):
|
def get_xoffset(self, maxoffset: float, duration: int = 820) -> float:
|
||||||
"""Return the offset on x-axis to make the tile complete an cycle of
|
"""Return the offset on x-axis to make the tile complete an cycle of
|
||||||
wiggling oscillation in given duration (in milliseconds).
|
wiggling oscillation in given duration (in milliseconds).
|
||||||
"""
|
"""
|
||||||
if not self.wiggle: return 0
|
if not self.wiggle: return 0
|
||||||
return maxoffset * cos((get_ticks()/duration+self.y/BOARD_HEIGHT)*pi)
|
return maxoffset * cos((get_ticks()/duration+self.y/BOARD_HEIGHT)*pi)
|
||||||
|
|
||||||
def get_yoffset(self):
|
def get_yoffset(self) -> float:
|
||||||
"""Return the offset on y-axis when the tile is falling."""
|
"""Return the offset on y-axis when the tile is falling."""
|
||||||
if self.missed_time is None: return 0
|
if self.missed_time is None: return 0
|
||||||
return (get_ticks() - self.missed_time)**2 / 25000
|
return (get_ticks()-self.missed_time)**2 / 25000
|
||||||
|
|
||||||
def isfallen(self):
|
def isfallen(self) -> bool:
|
||||||
"""Return if the tile has fallen off the screen."""
|
"""Return if the tile has fallen off the screen."""
|
||||||
return self.y + self.get_yoffset() > BOARD_HEIGHT
|
return self.y + self.get_yoffset() > BOARD_HEIGHT
|
||||||
|
|
||||||
def draw(self, max_x_offset=2):
|
def draw(self, max_x_offset: float = 2.0) -> None:
|
||||||
"""Draw the tile."""
|
"""Draw the tile."""
|
||||||
if self.y < MAJOR:
|
if self.y < MAJOR:
|
||||||
color = COLOR_MAJOR
|
color = COLOR_MAJOR
|
||||||
|
@ -103,7 +107,7 @@ class SlackerTile:
|
||||||
(self.y+self.get_yoffset())*TILE_SIZE,
|
(self.y+self.get_yoffset())*TILE_SIZE,
|
||||||
TILE_SIZE, TILE_SIZE)
|
TILE_SIZE, TILE_SIZE)
|
||||||
draw.rect(self.screen, color[self.dim], rect)
|
draw.rect(self.screen, color[self.dim], rect)
|
||||||
draw.rect(self.screen, BG_COLOR, rect, TILE_SIZE // 11)
|
draw.rect(self.screen, BG_COLOR, rect, TILE_SIZE//11)
|
||||||
|
|
||||||
|
|
||||||
class Slacker:
|
class Slacker:
|
||||||
|
@ -111,42 +115,41 @@ class Slacker:
|
||||||
the popular arcade game Stacker.
|
the popular arcade game Stacker.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, restart=False):
|
def __init__(self, restart: bool = False) -> None:
|
||||||
self.exit_stack = ExitStack()
|
self.exit_stack = ExitStack()
|
||||||
self.font = self.data('VT323-Regular.ttf')
|
self.font = self.data('VT323-Regular.ttf')
|
||||||
self.board = [[False]*BOARD_WIDTH
|
self.board = [[False]*BOARD_WIDTH for h in range(BOARD_HEIGHT)]
|
||||||
for _ in range(BOARD_HEIGHT)]
|
|
||||||
self.game_state = PLAYING if restart else INTRO
|
self.game_state = PLAYING if restart else INTRO
|
||||||
self.falling_tiles = []
|
self.falling_tiles: List[SlackerTile] = []
|
||||||
self.speed = INIT_SPEED + randrange(5)
|
self.speed = INIT_SPEED + randrange(5)
|
||||||
self.speed_ratio = 1.0
|
self.speed_ratio = 1.0
|
||||||
self.width = MAX_WIDTH[-1]
|
self.width = MAX_WIDTH[-1]
|
||||||
self.y = BOARD_HEIGHT - 1
|
self.y = BOARD_HEIGHT - 1
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self) -> Slacker:
|
||||||
pygame.init()
|
pygame.init()
|
||||||
set_caption('Slacker')
|
set_caption('Slacker')
|
||||||
set_icon(image.load(self.data('icon.png')))
|
set_icon(image.load(self.data('icon.png')))
|
||||||
self.screen = set_mode(SCREEN_SIZE)
|
self.screen = set_mode(SCREEN_SIZE)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __exit__(self, *exc):
|
def __exit__(self, *exc) -> None:
|
||||||
pygame.quit()
|
pygame.quit()
|
||||||
self.exit_stack.close()
|
self.exit_stack.close()
|
||||||
|
|
||||||
def data(self, resource):
|
def data(self, resource: str) -> str:
|
||||||
"""Return a true filesystem path for specified resource."""
|
"""Return a true filesystem path for specified resource."""
|
||||||
return str(self.exit_stack.enter_context(
|
return str(self.exit_stack.enter_context(
|
||||||
path('slacker_game', resource)))
|
path('slacker_game', resource)))
|
||||||
|
|
||||||
def draw_text(self, string, height):
|
def draw_text(self, string: str, height: float):
|
||||||
"""Width-fit the string in the screen on the given height."""
|
"""Width-fit the string in the screen on the given height."""
|
||||||
font = Font(self.font, int(SCREEN_WIDTH*2.5/(len(string)+1)))
|
font = Font(self.font, int(SCREEN_WIDTH*2.5/(len(string)+1)))
|
||||||
text = font.render(string, False, COLOR_MINOR[0])
|
text = font.render(string, False, COLOR_MINOR[0])
|
||||||
self.screen.blit(text, ((SCREEN_WIDTH - text.get_width()) // 2,
|
self.screen.blit(text, ((SCREEN_WIDTH - text.get_width()) // 2,
|
||||||
int(SCREEN_HEIGHT * height)))
|
int(SCREEN_HEIGHT * height)))
|
||||||
|
|
||||||
def intro(self):
|
def intro(self) -> None:
|
||||||
"""Draw the intro screen."""
|
"""Draw the intro screen."""
|
||||||
for i in [(2, 2), (3, 2), (4, 2), (1.5, 3), (4.5, 3),
|
for i in [(2, 2), (3, 2), (4, 2), (1.5, 3), (4.5, 3),
|
||||||
(1.5, 4), (2, 5), (3, 5), (4, 5), (4.5, 6),
|
(1.5, 4), (2, 5), (3, 5), (4, 5), (4.5, 6),
|
||||||
|
@ -155,7 +158,7 @@ class Slacker:
|
||||||
if get_ticks() // 820 % 2:
|
if get_ticks() // 820 % 2:
|
||||||
self.draw_text('Press Spacebar', 0.75)
|
self.draw_text('Press Spacebar', 0.75)
|
||||||
|
|
||||||
def draw_board(self):
|
def draw_board(self) -> None:
|
||||||
"""Draw the board and the tiles inside."""
|
"""Draw the board and the tiles inside."""
|
||||||
for y, row in enumerate(self.board):
|
for y, row in enumerate(self.board):
|
||||||
for x, block in enumerate(row):
|
for x, block in enumerate(row):
|
||||||
|
@ -169,7 +172,7 @@ class Slacker:
|
||||||
else:
|
else:
|
||||||
ft.draw()
|
ft.draw()
|
||||||
|
|
||||||
def update_screen(self):
|
def update_screen(self) -> None:
|
||||||
"""Draw the whole screen and everything inside."""
|
"""Draw the whole screen and everything inside."""
|
||||||
self.screen.fill(BG_COLOR)
|
self.screen.fill(BG_COLOR)
|
||||||
if self.game_state == INTRO:
|
if self.game_state == INTRO:
|
||||||
|
@ -178,7 +181,7 @@ class Slacker:
|
||||||
self.draw_board()
|
self.draw_board()
|
||||||
flip()
|
flip()
|
||||||
|
|
||||||
def update_movement(self):
|
def update_movement(self) -> None:
|
||||||
"""Update the direction the blocks are moving in."""
|
"""Update the direction the blocks are moving in."""
|
||||||
speed = self.speed * self.speed_ratio
|
speed = self.speed * self.speed_ratio
|
||||||
positions = BOARD_WIDTH + self.width - 2
|
positions = BOARD_WIDTH + self.width - 2
|
||||||
|
@ -187,7 +190,7 @@ class Slacker:
|
||||||
self.board[self.y] = [0 <= x - self.x < self.width
|
self.board[self.y] = [0 <= x - self.x < self.width
|
||||||
for x in range(BOARD_WIDTH)]
|
for x in range(BOARD_WIDTH)]
|
||||||
|
|
||||||
def key_hit(self):
|
def key_hit(self) -> None:
|
||||||
"""Process the current position of the blocks relatively to the
|
"""Process the current position of the blocks relatively to the
|
||||||
ones underneath when user hit the switch, then decide if 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.
|
user will win, lose or go to the next level of the tower.
|
||||||
|
@ -212,7 +215,7 @@ class Slacker:
|
||||||
self.width = min(self.width, MAX_WIDTH[self.y])
|
self.width = min(self.width, MAX_WIDTH[self.y])
|
||||||
self.speed = MAX_SPEED + self.y*SPEED_DIFF + randrange(5)
|
self.speed = MAX_SPEED + self.y*SPEED_DIFF + randrange(5)
|
||||||
|
|
||||||
def handle_intro(self):
|
def handle_intro(self) -> bool:
|
||||||
"""Handle events in intro."""
|
"""Handle events in intro."""
|
||||||
for e in event.get():
|
for e in event.get():
|
||||||
if e.type == QUIT: return False
|
if e.type == QUIT: return False
|
||||||
|
@ -221,7 +224,7 @@ class Slacker:
|
||||||
if e.key == K_SPACE: self.game_state = PLAYING
|
if e.key == K_SPACE: self.game_state = PLAYING
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def handle_playing(self):
|
def handle_playing(self) -> bool:
|
||||||
"""Handle events in game."""
|
"""Handle events in game."""
|
||||||
for e in event.get():
|
for e in event.get():
|
||||||
if e.type == QUIT: return False
|
if e.type == QUIT: return False
|
||||||
|
@ -229,7 +232,7 @@ class Slacker:
|
||||||
if e.key == K_SPACE:
|
if e.key == K_SPACE:
|
||||||
self.key_hit()
|
self.key_hit()
|
||||||
elif e.key in (K_ESCAPE, K_q):
|
elif e.key in (K_ESCAPE, K_q):
|
||||||
self.__init__()
|
Slacker.__init__(self)
|
||||||
# Yes, these are cheats.
|
# Yes, these are cheats.
|
||||||
elif e.key == K_0:
|
elif e.key == K_0:
|
||||||
self.width += self.width < BOARD_WIDTH
|
self.width += self.width < BOARD_WIDTH
|
||||||
|
@ -238,14 +241,14 @@ class Slacker:
|
||||||
self.update_movement()
|
self.update_movement()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def handle_ending(self):
|
def handle_ending(self) -> bool:
|
||||||
"""Handle events in ending screens."""
|
"""Handle events in ending screens."""
|
||||||
for e in event.get():
|
for e in event.get():
|
||||||
if e.type == QUIT: return False
|
if e.type == QUIT: return False
|
||||||
if e.type == KEYDOWN: self.__init__(restart=True)
|
if e.type == KEYDOWN: Slacker.__init__(self, restart=True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def handle_events(self):
|
def handle_events(self) -> bool:
|
||||||
"""Handle queued events."""
|
"""Handle queued events."""
|
||||||
if self.game_state == INTRO: return self.handle_intro()
|
if self.game_state == INTRO: return self.handle_intro()
|
||||||
if self.game_state == PLAYING: return self.handle_playing()
|
if self.game_state == PLAYING: return self.handle_playing()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from slacker_game import Slacker
|
from slacker_game import Slacker
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main() -> None:
|
||||||
"""Run game."""
|
"""Run game."""
|
||||||
with Slacker() as slacker:
|
with Slacker() as slacker:
|
||||||
for i in iter(slacker.handle_events, False):
|
for i in iter(slacker.handle_events, False):
|
||||||
|
|
2
tox.ini
2
tox.ini
|
@ -7,9 +7,11 @@ isolated_build = True
|
||||||
deps =
|
deps =
|
||||||
flake8-builtins
|
flake8-builtins
|
||||||
isort
|
isort
|
||||||
|
mypy
|
||||||
commands =
|
commands =
|
||||||
flake8
|
flake8
|
||||||
isort . --check --diff
|
isort . --check --diff
|
||||||
|
mypy slacker_game
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore = E226, E701, E704, W503
|
ignore = E226, E701, E704, W503
|
||||||
|
|
Loading…
Reference in New Issue