Add manual speed setting and write docstrings

This commit is contained in:
Nguyễn Gia Phong 2017-07-14 12:12:17 +07:00
parent 95f2fcd02c
commit 16434909f1
3 changed files with 47 additions and 24 deletions

View File

@ -3,11 +3,12 @@ Slacker
**Slacker** is a clone/parody of the popular arcade game *Stacker*, in which
you must stack blocks to the top of the screen in order to win the game. Boxes
will move back and forth at varying speeds. Press the spacebar to stop the
boxes and move on to the next row. Only boxes that have something underneath
them will be stacked. As the tower rises, the game will make your tower
thinner. You win a minor prize at the 10th level (the blocks change color), and
if you reach the 15th level, you will win the major prize. Good luck!
will move back and forth at varying speeds. Hit the switch (in this game it's
mapped to either Return or Space) to stop the boxes and move on to the next
row. Only boxes that have something underneath them will be stacked. As the
tower rises, the game will make your tower thinner. You win a minor prize at
the 10th level (the blocks change color), and if you reach the 15th level, you
will win the major prize. Good luck!
In the arcade version, credits are expensive (often $1 per play), but the
prizes are excellent (the one that I played let you choose between an iPod, a
@ -25,12 +26,18 @@ codebase, make it more similar to the arcade game and maybe add more features.
Control
-------
Space, Return
Return, Space
Start playing or place your stacking boxes.
Escape, ``q``
Return to intro screen or quit.
``1`` to ``9``
Set the speed of the game (default: 5).
``0``
Increase the number of blocks currently moving.
Credits
-------

View File

@ -6,7 +6,7 @@ with open('README.txt') as f:
setup(
name='slacker-game',
version='1.3.2',
version='2.0.0',
description='A clone of the arcade game Stacker',
long_description=long_description,
url='https://github.com/McSinyx/slacker-game',

View File

@ -26,18 +26,21 @@ from pygame.locals import *
class SlackerMissedTile:
"""SlackerMissedTile(x, y, time) => SlackerMissedTile
Slacker object for storing missed tiles.
"""
def __init__(self, x, y, time):
#self.x. self.y, self.time = x, y, time
self.x = x
self.y = y
self.time = time
self.x, self.y, self.time = x, y, time
def get_time_delta(self):
"""Return the duration the missed tile has been falling in."""
return (pygame.time.get_ticks() - self.time) / 125.0
class Slacker:
""""""
"""This class provides functions to run the game Slacker, a clone of
the popular arcade game Stacker.
"""
BOARD_SIZE = BOARD_WIDTH, BOARD_HEIGHT = 7, 15
SCREEN_SIZE = SCREEN_WIDTH, SCREEN_HEIGHT = 280, 600
TILE_SIZE = TILE_WIDTH, TILE_HEIGHT = 40, 40
@ -70,11 +73,13 @@ class Slacker:
self.missed_tiles = []
self.screen = pygame.display.set_mode(self.SCREEN_SIZE)
self.speed = self.LEVEL_SPEED[0]
self.speed_ratio = 1.0
self.width = self.MAX_WIDTH[0]
self.x = randint(0, self.BOARD_WIDTH - self.width)
self.y = self.BOARD_HEIGHT - 1
def draw_tile(self, x, y):
"""Draw the tile at position (x, y)."""
if self.game_state == self.LOSE:
if y < self.COLOR_CHANGE_Y:
color = self.TILE_COLOR_ALT_LOSE
@ -98,11 +103,8 @@ class Slacker:
pygame.draw.rect(self.screen, color, rect)
pygame.draw.rect(self.screen, self.BLACK, rect, 2)
def draw_background(self):
self.screen.blit(self.BG_IMAGES[self.game_state],
(0, 0, self.SCREEN_WIDTH, self.SCREEN_HEIGHT))
def draw_board(self):
"""Draw the board and the tiles inside."""
for x in range(self.BOARD_WIDTH):
for y in range(self.BOARD_HEIGHT):
if self.board[y][x]: self.draw_tile(x, y)
@ -125,7 +127,13 @@ class Slacker:
self.screen, color,
pygame.Rect(x + 2, y + 2, self.TILE_WIDTH - 3, self.TILE_HEIGHT - 3))
def draw_background(self):
"""Draw the background image according to current game_state."""
self.screen.blit(self.BG_IMAGES[self.game_state],
(0, 0, self.SCREEN_WIDTH, self.SCREEN_HEIGHT))
def update_screen(self):
"""Draw the whole screen and everything inside."""
if self.game_state == self.PLAYING:
self.draw_background()
self.draw_board()
@ -138,8 +146,9 @@ class Slacker:
pygame.display.flip()
def update_movement(self):
"""Update the direction the blocks are moving in."""
self.time = pygame.time.get_ticks()
if self.last_time + self.speed <= self.time:
if self.last_time + self.speed * self.speed_ratio <= self.time:
if not -self.width < self.x + self.direction < self.BOARD_WIDTH:
self.direction *= -1
self.x += self.direction
@ -148,6 +157,10 @@ class Slacker:
for x in range(self.BOARD_WIDTH)]
def key_hit(self):
"""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.
"""
if self.y < self.BOARD_HEIGHT - 1:
for x in range(max(0, self.x),
min(self.x + self.width, self.BOARD_WIDTH)):
@ -167,26 +180,27 @@ class Slacker:
self.direction = choice([1, -1])
self.level += 1
self.speed = self.LEVEL_SPEED[self.level]
self.width = min(self.width, self.MAX_WIDTH[self.level])
self.x = randint(0, self.BOARD_WIDTH - self.width)
self.y -= 1
def main_loop(self):
keep_running = True
while keep_running:
def main_loop(self, loop=True):
"""The main loop."""
while loop:
self.update_screen()
if self.game_state == self.INTRO:
for event in pygame.event.get():
if event.type == pygame.QUIT:
keep_running = False
loop = False
elif event.type == KEYDOWN:
if event.key in (K_RETURN, K_SPACE):
self.game_state = self.PLAYING
elif event.key in (K_ESCAPE, K_q):
keep_running = False
loop = False
elif self.game_state == self.PLAYING:
for event in pygame.event.get():
if event.type == pygame.QUIT:
keep_running = False
loop = False
elif event.type == KEYDOWN:
if event.key in (K_RETURN, K_SPACE):
self.key_hit()
@ -196,11 +210,13 @@ class Slacker:
elif event.key == K_F1 and self.width < self.BOARD_WIDTH:
self.x -= self.direction
self.width += 1
elif event.key in range(K_1, K_9 + 1):
self.speed_ratio = (K_9 - event.key + 1) / 5.0
self.update_movement()
elif self.game_state in (self.LOSE, self.WIN):
for event in pygame.event.get():
if event.type == pygame.QUIT:
keep_running = False
loop = False
elif event.type == KEYDOWN:
self.__init__()