Mercurial > gain
changeset 0:24875859393b draft
Initial commitw
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Sun, 28 Apr 2019 22:55:40 +0200 |
| parents | |
| children | e88a8f6d354b |
| files | digits.png gain.py hall-floor.png hall.png room-floor.png room.png sprites.png yard-floor.png yard.png |
| diffstat | 9 files changed, 281 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gain.py Sun Apr 28 22:55:40 2019 +0200 @@ -0,0 +1,281 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +import pygame +import math + + +def load_sprites(filename, width=64): + image = pygame.image.load(filename).convert_alpha() + w, h = image.get_size() + count = w // width + return [image.subsurface((x * width, 0, width, h)) for x in xrange(count)] + + +def distance(a, b): + return math.sqrt((a.sx - b.sx)**2 + ((a.sy - b.sy)*2)**2) + + +class Score(pygame.sprite.Sprite): + def __init__(self): + super(Score, self).__init__() + self.value = 0 + self.image = pygame.Surface((12 * 5, 22)) + self.rect = self.image.get_rect() + self.digits = load_sprites("digits.png", 12) + self.render() + + def render(self): + self.image.fill((255, 255, 255, 255)) + for x, c in enumerate("%05d" % self.value): + self.image.blit(self.digits[ord(c)-ord("0")], (x*12, 0)) + + def update(self, game): + pass + + +class Thing(pygame.sprite.Sprite): + def __init__(self, frame, x, y): + super(Thing, self).__init__() + self.image = sprite_images[frame] + self.rect = self.image.get_rect() + self.sx = x + self.sy = y + self.rect.midbottom = x, y + + def act(self, game): + pass + + +class Lever(Thing): + def __init__(self, x, y): + super(Lever, self).__init__(3, x, y + 1) + self.timeout = 0 + + def act(self, game): + if not self.timeout: + self.image = sprite_images[4] + self.timeout = 6 + game.sprites.add(Coin(self.sx, self.sy - 1)) + game.score.value += 1 + game.score.render() + + def update(self, game): + if self.timeout: + self.timeout -= 1 + if not self.timeout: + self.image = sprite_images[3] + +class Coin(Thing): + def __init__(self, x, y): + super(Coin, self).__init__(5, x, y) + self.sx = x + self.sy = y + self.sz = 0 + self.dz = 5 + + def update(self, game): + self.dz -= 1 + self.sz += self.dz * 4 + if self.dz < 0: + self.sz = 0 + self.kill() + self.rect.midbottom = ( + self.sx, + self.sy - self.sz + ) + +class Mob(Thing): + def __init__(self, frame, x, y): + super(Mob, self).__init__(frame, x, y) + self.sx = x + self.sy = y + self.sz = 0 + self.dz = 3 + + def update(self, game): + self.dz -= 1 + self.sz += self.dz + if self.sz < 0: + self.sz = 0 + self.dz = -self.dz + self.rect.midbottom = ( + self.sx, + self.sy - self.sz + ) + +class ExitRoom(Exception): + def __init__(self, room): + self.room = room + +def get_keys(game): + keys = pygame.key.get_pressed() + ret = keys + while keys[pygame.K_SPACE]: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + raise SystemExit() + keys = pygame.key.get_pressed() + game.clock.tick() + return ret + + +class PlayerCharacter(Mob): + def __init__(self, x, y): + super(PlayerCharacter, self).__init__(0, x, y) + + def update(self, game): + sx, sy = self.sx, self.sy + keys = get_keys(game) + if keys[pygame.K_UP]: + sy -= 4 + elif keys[pygame.K_DOWN]: + sy += 4 + if keys[pygame.K_LEFT]: + sx -= 8 + elif keys[pygame.K_RIGHT]: + sx += 8 + if keys[pygame.K_SPACE]: + for sprite in game.sprites: + if distance(self, sprite) < 48: + sprite.act(game) + for exit in game.room.exits: + if distance(self, exit) < 32: + self.sx = exit.tx + self.sy = exit.ty + raise ExitRoom(exit.room()) + try: + if game.room.floor.get_at((sx, sy - 10)) == (0, 0, 0): + self.sx = sx + self.sy = sy + elif game.room.floor.get_at((self.sx, sy - 10)) == (0, 0, 0): + self.sy = sy + elif game.room.floor.get_at((sx, self.sy - 10)) == (0, 0, 0): + self.sx = sx + except IndexError: + pass + super(PlayerCharacter, self).update(game) + + +class Shadow(pygame.sprite.DirtySprite): + def __init__(self, mob): + super(Shadow, self).__init__() + self.image = sprite_images[1] + self.mob = mob + self.rect = self.image.get_rect() + + def update(self, game): + new = ( + self.mob.sx, + self.mob.sy, + ) + if self.rect.midbottom != new: + self.rect.midbottom = new + self.dirty = True + + +class Sprites(pygame.sprite.RenderUpdates): + def sprites(self): + return sorted(self.spritedict.keys(), + key=lambda sprite: getattr(sprite, "sy", 0)) + +class Exit(object): + def __init__(self, x, y, room, tx, ty): + self.sx = x + self.sy = y + self.room = room + self.tx = tx + self.ty = ty + + +class Room(object): + def __init__(self, background_file, floor_file): + self.floor = pygame.image.load(floor_file) + self.background = pygame.image.load(background_file).convert() + self.exits = [] + + def enter(self, game): + game.display.blit(self.background, (0, 0)) + pygame.display.update() + + +class StartRoom(Room): + def __init__(self): + super(StartRoom, self).__init__("room.png", "room-floor.png") + self.exits = [ + Exit(380, 390, HallRoom, 654, 195), + ] + + def enter(self, game): + super(StartRoom, self).enter(game) + machine_thing = Thing(2, 300, 500) + machine_lever = Lever(300, 500) + game.sprites.add(machine_thing) + game.sprites.add(machine_lever) + + +class HallRoom(Room): + def __init__(self): + super(HallRoom, self).__init__("hall.png", "hall-floor.png") + self.exits = [ + Exit(654, 180, StartRoom, 380, 400), + Exit(350, 330, YardRoom, 360, 440), + ] + + +class YardRoom(Room): + def __init__(self): + super(YardRoom, self).__init__("yard.png", "yard-floor.png") + self.exits = [ + Exit(350, 440, HallRoom, 350, 330), + ] + + +class Game(object): + def __init__(self): + global sprite_images + + self.display = pygame.display.set_mode((800, 600)) + self.clock = pygame.time.Clock() + sprite_images = load_sprites("sprites.png") + self.p1_mob = PlayerCharacter(600, 450) + self.p1_shadow = Shadow(self.p1_mob) + self.score = Score() + self.room = StartRoom() + + def explore(self, room): + self.room = room + self.shadows = pygame.sprite.RenderUpdates( + self.p1_shadow, + self.score, + ) + self.sprites = Sprites( + self.p1_mob, + ) + self.room.enter(self) + while True: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + raise SystemExit() + self.shadows.clear(self.display, self.room.background) + self.sprites.clear(self.display, self.room.background) + self.sprites.update(self) + self.shadows.update(self) + dirty = [] + dirty.extend(self.shadows.draw(self.display)) + dirty.extend(self.sprites.draw(self.display)) + pygame.display.update(dirty) + self.clock.tick(12) + + def run(self): + next_room = StartRoom() + while True: + try: + self.explore(next_room) + except ExitRoom as exit: + next_room = exit.room + + +if __name__ == "__main__": + Game().run()
