Last active
February 4, 2017 19:58
-
-
Save sirex/9a2c5c03ec60bc296715f0955d329b71 to your computer and use it in GitHub Desktop.
Crane app for kids buit using pygame.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# http://bebras.lt/wp-content/uploads/2016/09/Darbas-kranu.pdf | |
import collections | |
import pygame as game | |
Vector = collections.namedtuple('Vector', 'x, y') | |
size = width, height = 320, 130 | |
black = game.Color('black') | |
grey = game.Color('grey') | |
green = game.Color('green') | |
def ascii2img(ascii, width=10, height=10): | |
images = [] | |
lines = ascii.strip().splitlines() | |
header = lines[0] | |
lines = lines[1:] | |
for y, line in enumerate(lines): | |
line = line.strip() | |
for i, row in enumerate(line.split('|')[1:-1]): | |
if len(images) < i + 1: | |
images.append([]) | |
image = images[i] | |
for x, v in enumerate(row): | |
if v == '#': | |
image.append([x * width, y * height, width, height]) | |
surfaces = [] | |
for image, header in zip(images, header.split('+')[1:-1]): | |
w = len(header) * width | |
h = len(lines) * height | |
surface = game.Surface([w, h]) | |
surface.fill(grey) | |
for rect in image: | |
game.draw.rect(surface, black, rect) | |
surfaces.append(surface) | |
return surfaces | |
class Crane(game.sprite.Sprite): | |
images = ''' | |
+-------+-------+ | |
| # | # | | |
| # | # | | |
| # | # | | |
| # | # | | |
| # | # | | |
| # | # | | |
| # | # | | |
| # | # | | |
| # | # | | |
|#######| ##### | | |
|# #| # # | | |
|# #| # # | | |
''' | |
def __init__(self, platform): | |
super().__init__() | |
self.platform = platform | |
self.box = None | |
self.images = ascii2img(self.images) | |
self.state = 0 | |
self.pos = Vector(0, 0) | |
self.image = self.images[self.state] | |
self.rect = self.image.get_rect() | |
self.rect.x = 30 | |
self.rect.y = -70 | |
def update(self): | |
self.image = self.images[self.state] | |
def up(self): | |
if self.pos.y > 0: | |
self.pos = Vector(self.pos.x, self.pos.y - 1) | |
self.rect.y = -70 | |
def down(self): | |
if self.pos.y <= 1: | |
self.pos = Vector(self.pos.x, self.pos.y + 1) | |
if self.platform.places[self.pos.x]: | |
self.rect.bottom = self.platform.places[self.pos.x][-1].rect.top + 20 | |
else: | |
self.rect.bottom = height - 20 | |
def right(self): | |
if self.pos.x <= 3: | |
self.pos = Vector(self.pos.x + 1, self.pos.y) | |
self.rect.x += 80 | |
def left(self): | |
if self.pos.x > 0: | |
self.pos = Vector(self.pos.x - 1, self.pos.y) | |
self.rect.x -= 80 | |
def grab(self): | |
self.state = 1 | |
self.box = self.platform.grab(self.pos.x) | |
def drop(self): | |
self.state = 0 | |
if self.box: | |
self.platform.drop(self.box, self.pos.x) | |
self.box = None | |
class Box(game.sprite.Sprite): | |
def __init__(self, font, name): | |
super().__init__() | |
self.image = game.Surface([30, 30]) | |
self.text = font.render(name, True, black) | |
self.rect = self.image.get_rect() | |
game.draw.rect(self.image, green, [0, 0, 30, 30]) | |
def update(self, screen): | |
screen.blit(self.image, self.rect) | |
screen.blit(self.text, ( | |
self.rect.x + self.text.get_width() // 2, | |
self.rect.y + self.text.get_height() // 2 - 14, | |
)) | |
class Platform(game.sprite.Sprite): | |
def __init__(self, n=3): | |
self.n = n | |
self.places = [[] for i in range(n)] | |
def grab(self, position): | |
if self.places[position]: | |
return self.places[position].pop() | |
def drop(self, box, position): | |
self.places[position].append(box) | |
class World(game.sprite.Sprite): | |
def __init__(self, screen, font): | |
super().__init__() | |
self.screen = screen | |
self.font = font | |
self.platform = Platform() | |
self.crane = Crane(self.platform) | |
def draw(self): | |
# Background | |
self.screen.fill(grey) | |
# Crane | |
self.crane.update() | |
self.screen.blit(self.crane.image, self.crane.rect) | |
if self.crane.box: | |
self.crane.box.rect.x = self.crane.rect.x + 20 | |
self.crane.box.rect.y = self.crane.rect.bottom - 20 | |
self.crane.box.update(self.screen) | |
# Platform | |
for x, place in enumerate(self.platform.places): | |
for y, box in enumerate(place): | |
box.rect.x = 50 + x * 80 | |
box.rect.y = height - 40 - y * 30 | |
box.update(self.screen) | |
# Top of the crane | |
game.draw.rect(self.screen, black, [0, 0, width, 10]) | |
def main(): | |
game.init() | |
screen = game.display.set_mode(size) | |
screen.fill(grey) | |
font = game.font.SysFont('Ubuntu', 24) | |
world = World(screen, font) | |
world.platform.drop(Box(font, 'A'), 0) | |
world.platform.drop(Box(font, 'B'), 1) | |
world.draw() | |
game.display.flip() | |
commandmap = { # noqa | |
'aukštyn': world.crane.up, | |
'žemyn': world.crane.down, | |
'dešinėn': world.crane.right, | |
'kairėn': world.crane.left, | |
'sugriebti': world.crane.grab, | |
'paleisti': world.crane.drop, | |
} | |
# import itertools | |
commands = iter([ # noqa | |
'žemyn', | |
'sugriebti', | |
'aukštyn', | |
'dešinėn', | |
'dešinėn', | |
'žemyn', | |
'paleisti', | |
'aukštyn', | |
'kairėn', | |
'žemyn', | |
'sugriebti', | |
'aukštyn', | |
'kairėn', | |
'žemyn', | |
'paleisti', | |
'aukštyn', | |
'dešinėn', | |
'dešinėn', | |
'žemyn', | |
'sugriebti', | |
'aukštyn', | |
'kairėn', | |
'žemyn', | |
'paleisti', | |
'aukštyn', | |
]) | |
while True: | |
for event in game.event.get(): | |
if event.type == game.QUIT: | |
game.quit() | |
return | |
if event.type == game.KEYDOWN and event.key in (game.K_ESCAPE, game.K_q): | |
game.quit() | |
return | |
command = next(commands, None) | |
if command: | |
print(command, flush=True) | |
commandmap[command]() | |
game.time.wait(500) | |
world.draw() | |
game.display.flip() | |
else: | |
game.time.wait(500) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment