def __init__(self, x, y): peachy.Entity.__init__(self) peachy.geo.Rect.__init__(self, x, y, Player.WIDTH, Player.HEIGHT_STANDARD) self.name = 'player' self.group = 'player liftable' self.facing_x = 1 self.velocity_x = 0 self.velocity_y = 0 self.state = Player.STATE_STANDARD self.state_args = {} self.sprite = PC().resources.get_resource_by_name('ObieSprite') self.sprite.play('IDLE') self.walking_sound = PC().resources.get_resource_by_name( 'FootstepSound') self.gadget = gadgets.Gadget(self, '') self.invisible = False self.obtained_keys = [] self.key_count = 0 self.order = 1
def render(self): peachy.graphics.set_color(0, 0, 0) peachy.graphics.draw_rect(0, 0, PC().canvas_width, PC().canvas_height) font = peachy.graphics.font() x_align = 64 peachy.graphics.set_color(255, 255, 255) peachy.graphics.draw_text("AGENT OBIE", x_align, 150) peachy.graphics.draw_text("ALPHA - BUILD 4", x_align, 166) highlight_width = 0 for selection in range(len(self.selections)): text = self.selections[selection] _, _, text_width, text_height = font.get_rect(text) if text_width + 8 > highlight_width: highlight_width = text_width + 8 for selection in range(len(self.selections)): text = self.selections[selection] # _, _, text_width, text_height = font.get_rect(text) y = (PC().canvas_height / 2) + (selection * 24) peachy.graphics.set_color(255, 255, 255) if selection == self.current_selection: peachy.graphics.draw_rect(x_align - 4, y - 2, highlight_width, text_height + 6) peachy.graphics.set_color(0, 0, 0) peachy.graphics.draw_text(text, x_align, y)
def advance(self): # Create actors obie = Obie(50, PC().canvas_width / 4) obie.sprite.play('RUN') message = Message( ["Looks like Agent Obie will have dialogue...", "How exciting!"], obie.x - 16, 42, obie) self.actors.append(obie) # Show actor yield from wait_for_input() dx = message.x + Message.BOX_WIDTH - 16 obie.move_to(dx, obie.y, 2000) message.move_to(dx - Message.BOX_WIDTH / 2, message.y, 2000) self.messages.append(message) # Show message yield from wait_for_message(message) yield from wait_for_actor(obie) yield from wait_for_input() self.messages.remove(message) obie.move_to(PC().canvas_width / 2, obie.y, 1500) yield from wait_for_actor(obie) yield from wait(1000) yield
def stage_from_string(name): name = name.lower() if name == 'pier': return Pier(PC().get_world('game')) elif name == 'sewer': return Sewer(PC().get_world('game')) else: logging.warning('STAGE NOT FOUND %s' % (name))
def display(self): player = self.container.get_name('player') HEIGHT = 64 y = 0 if player.y + player.height < HEIGHT: y = PC().canvas_height - HEIGHT peachy.graphics.set_color(0, 30, 60) peachy.graphics.draw_rect(0, y, PC().canvas_width, HEIGHT) peachy.graphics.set_color(255, 255, 255) peachy.graphics.draw_message(self.message, 8, y + 8)
def enter(self): PC().resources.activate_bundle('PierResources') if self.background is None or self.foreground is None: self._init_scenery() self.player = Player(96, 180) self.load_tmx('stage/pier_01.tmx')
def update(self): if peachy.utils.Key.pressed('p'): self.world.change_state(STATE_MAIN) self.world.room.resume() elif peachy.utils.Key.pressed('up'): if self.selected > 0: self.selected -= 1 elif peachy.utils.Key.pressed('down'): if self.selected < len(self.options) - 1: self.selected += 1 elif peachy.utils.Key.pressed('enter'): if self.selected == 0: # Resume self.world.change_state(STATE_MAIN) elif self.selected == 1: # Show options return elif self.selected == 2: # Main Menu PC().change_world('main') elif self.selected == 3: # Exit PC().quit()
def render(self): peachy.graphics.set_color_hex('#040404') peachy.graphics.draw_rect(0, 0, PC().canvas_width, PC().canvas_height) peachy.graphics.set_color_hex('#000055') for x in range(-9, int(PC().canvas_width / 2), 16): peachy.graphics.draw_line(x, 0, x, PC().canvas_height / 2) for y in range(-8, int(PC().canvas_height / 2), 16): peachy.graphics.draw_line(0, y, PC().canvas_width, y) super().render()
def update(self): if Key.pressed('F1'): PC().toggle_fullscreen() if Key.pressed('up'): self.current_selection -= 1 if Key.pressed('down'): self.current_selection += 1 if self.current_selection < 0: self.current_selection = 0 elif self.current_selection > 2: self.current_selection = 2 if Key.pressed('enter'): if self.current_selection == PLAY: w = PC().change_world("game") w.init_new_game() elif self.current_selection == EXIT: PC().quit() if Key.pressed('escape'): PC().quit()
def _init_scenery(self): RM = PC().resources self.background = ParallaxBG(480, 240) self.background.create_layer( RM.get_resource_by_name('PierBackground_Clouds'), peachy.geo.Point(-0.5, 0), True, False) self.background.create_layer( RM.get_resource_by_name('PierBackground'), peachy.geo.Point(-0.1, 0), True, False) self.background.create_layer( RM.get_resource_by_name('PierForeground_Clouds'), peachy.geo.Point(-0.5, 0), True, False) self.foreground_timer = peachy.utils.Counter( 0, 8, enable_repeat=True, enable_pingpong=True, step=0.05) self.foreground = RM.get_resource_by_name('PierForeground_Water')
def enter(self): print("INI") super().enter() self.add(Soldier(PC().canvas_width / 3, 100)) self.add(Solid(75, 150, PC().canvas_width / 2 - 150, 32)).visible = True
class Player(peachy.Entity, peachy.geo.Rect): SPEED = 0.75 SPEED_FAST = 2.5 SPEED_SLOW = 0.5 JUMP_FORCE = 2.5 STATE_STANDARD = 'standard' STATE_CLIMBING = 'climb' STATE_CROUCHING = 'crouch' STATE_DEAD = 'dead' STATE_HIDDEN = 'hidden' STATE_LEDGEGRAB = 'ledge-grab' STATE_PUSHING = 'push' WIDTH = 8 HEIGHT_STANDARD = 12 HEIGHT_CROUCH = 8 def __init__(self, x, y): peachy.Entity.__init__(self) peachy.geo.Rect.__init__(self, x, y, Player.WIDTH, Player.HEIGHT_STANDARD) self.name = 'player' self.group = 'player liftable' self.facing_x = 1 self.velocity_x = 0 self.velocity_y = 0 self.state = Player.STATE_STANDARD self.state_args = {} self.sprite = PC().resources.get_resource_by_name('ObieSprite') self.sprite.play('IDLE') self.walking_sound = PC().resources.get_resource_by_name( 'FootstepSound') self.gadget = gadgets.Gadget(self, '') self.invisible = False self.obtained_keys = [] self.key_count = 0 self.order = 1 def change_gadget(self, gadget_name): self.gadget.stop() self.gadget = gadgets.from_name(gadget_name, self) def change_state(self, state, **kwargs): self.state_args = kwargs self.walking_sound.stop() if self.gadget.name != gadgets.InvisibilityCloak.NAME or \ self.gadget.state != gadgets.Gadget.STATE_ACTIVE: self.invisible = False if state == Player.STATE_STANDARD: diff_height = self.height - Player.HEIGHT_STANDARD self.y += diff_height self.height = Player.HEIGHT_STANDARD elif state == Player.STATE_CLIMBING: handle = kwargs['handle'] if kwargs['vertical']: self.x = handle.x - (handle.x % 8) else: self.y = handle.y self.velocity_x = 0 self.velocity_y = 0 elif state == Player.STATE_CROUCHING: diff_height = self.height - Player.HEIGHT_CROUCH self.y += diff_height self.velocity_y = 0 self.height = Player.HEIGHT_CROUCH elif state == Player.STATE_DEAD: self.velocity_x = 0 self.velocity_y = 0 elif state == Player.STATE_HIDDEN: hiding_spot = kwargs['hiding_spot'] self.invisible = True if self.x < hiding_spot.x: self.x = hiding_spot.x if self.x + self.width >= hiding_spot.x + hiding_spot.width: self.x = hiding_spot.x + hiding_spot.width - self.width self.velocity_x = 0 self.velocity_y = 0 elif state == Player.STATE_LEDGEGRAB: ledge = kwargs['ledge'] self.y = ledge.y self.height = Player.HEIGHT_STANDARD self.velocity_x = 0 self.velocity_y = 0 self.state = state def kill(self, cause): # TODO play Player death animation if cause.member_of('bullet'): print('SHOT DEAD') elif cause.member_of('dog'): print('GOT BIT') elif cause.member_of('pitfall'): print('YOU FELL TO YOUR DEATH') else: print('DEAD') self.gadget.stop() self.change_state(Player.STATE_DEAD) def render(self): flip_x = self.facing_x == -1 self.order = 1 if self.invisible: if self.state == Player.STATE_HIDDEN: self.sprite.play('HIDDEN', flip_x) self.order = -1 else: if self.velocity_x != 0: self.sprite.play('INVISIBLE_RUN', flip_x) else: self.sprite.play('INVISIBLE', flip_x) elif self.state == Player.STATE_STANDARD: if self.velocity_y == 0 and not solid_below(self, self.x, self.y): self.sprite.play('JUMP', flip_x) elif self.velocity_y < 0: self.sprite.play('JUMP', flip_x) elif self.velocity_y > 0: self.sprite.play('FALL', flip_x) elif self.velocity_x != 0: self.sprite.play('RUN', flip_x) else: self.sprite.play('IDLE', flip_x) elif self.state == Player.STATE_CLIMBING: if self.state_args['vertical']: if self.velocity_y != 0: self.sprite.play('CLIMB_LADDER') self.sprite.resume() else: self.sprite.play('CLIMB_LADDER') self.sprite.pause() else: graphics.set_color(125, 125, 125) graphics.draw_entity_rect(self) self.gadget.render() return elif self.state == Player.STATE_CROUCHING: if self.velocity_x != 0: self.sprite.play('CRAWL', flip_x) else: self.sprite.play('CROUCH', flip_x) elif self.state == Player.STATE_LEDGEGRAB: self.sprite.play('HANG', flip_x) elif self.state == Player.STATE_PUSHING: self.sprite.play('PUSH', flip_x) else: # Default graphics.set_color(125, 125, 125) graphics.draw_entity_rect(self) self.gadget.render() return self.sprite.render(self.x, self.y) self.gadget.render() def update(self): temp_x = self.x temp_y = self.y has_solid_below = solid_below(self, self.x, self.y) # Key polling keydown_up = Key.down('up') keydown_down = Key.down('down') keydown_left = Key.down('left') keydown_right = Key.down('right') keydown_run = False # Key.down('lshift') keypressed_up = Key.pressed('up') keypressed_down = Key.pressed('down') keypressed_left = Key.pressed('left') keypressed_right = Key.pressed('right') keypressed_jump = Key.pressed('space') keypressed_gadget = Key.pressed('x') if self.state == Player.STATE_STANDARD: # Run/Walk if keydown_left == keydown_right: self.velocity_x = 0 self.walking_sound.stop() else: if keydown_left: if keydown_run: self.velocity_x = -Player.SPEED_FAST else: self.velocity_x = -Player.SPEED self.facing_x = -1 if keydown_right: if keydown_run: self.velocity_x = Player.SPEED_FAST else: self.velocity_x = Player.SPEED self.facing_x = 1 # Play walking sound effect if has_solid_below: self.walking_sound.play(-1) else: self.walking_sound.stop() # Push block block = peachy.collision.collides_group( self.container, 'block', self.at_point(temp_x + self.velocity_x, self.y)) if len(block) == 1 and has_solid_below: block = block[0] block_temp_x = block.x + self.velocity_x if not peachy.collision.collides_solid( self.container, block.at_point(block_temp_x, block.y)): self.change_state(Player.STATE_PUSHING, block=block) if self.x < block.x: self.x = block.x - self.width else: self.x = block.x + block.width return # Jump if keypressed_jump and has_solid_below: self.velocity_y = -Player.JUMP_FORCE # Wall Grab if self.velocity_y < 4 and self.velocity_y > 0: climb_wall = [] if keydown_left: climb_wall = solid_left(self, self.x, self.y) if keydown_right: climb_wall = solid_right(self, self.x, self.y) ledge = None for wall in climb_wall: if wall.y - self.y < 3 and not wall.member_of('block'): if self.y <= wall.y: ledge = wall else: ledge = None if ledge is not None: test = Rect(self.x, ledge.y - Player.HEIGHT_CROUCH, self.width, Player.HEIGHT_CROUCH) test.container = self.container if test.x + test.width <= ledge.x: test.x = ledge.x elif test.x >= ledge.x + ledge.width: test.x = ledge.x + ledge.width - test.width if not collides_solid(self.container, test): self.change_state(Player.STATE_LEDGEGRAB, ledge=ledge) return # Interact if keydown_up: interactables = collides_group(self.container, 'interact', self) for interact in interactables: if interact.member_of('rope'): vertical = False if interact.width == 0: vertical = True elif interact.height == 0: vertical = False self.change_state(Player.STATE_CLIMBING, handle=interact, vertical=vertical) interact.attach(self) return elif interact.member_of('ladder'): self.x = interact.x self.change_state(Player.STATE_CLIMBING, handle=interact, vertical=True) return elif keypressed_up: if interact.member_of('button'): interact.press() elif interact.member_of('door'): if self.gadget.state == gadgets.Gadget.STATE_ACTIVE: self.gadget.cancel() interact.enter() elif interact.member_of('lever'): interact.pull() elif interact.member_of('hiding-spot'): self.change_state(Player.STATE_HIDDEN, hiding_spot=interact) return elif interact.member_of('message-box'): interact.activate() return # Climb down ladder if keypressed_down: ladder = collides_group(self.container, 'ladder', self.at_point(self.x, self.y + 1)) if ladder: ladder = ladder[0] if self.y + self.height < ladder.y + ladder.height: self.x = ladder.x if self.y < ladder.y: self.y = ladder.y self.change_state(Player.STATE_CLIMBING, handle=ladder, vertical=True) return # Pickup if keypressed_up: pickups = collides_group(self.container, 'pickup', self) for pickup in pickups: if pickup.member_of('gadget'): self.change_gadget(pickup.gadget) elif pickup.member_of('key'): self.obtained_keys.append(pickup.tag) self.key_count += 1 pickup.destroy() # Crouching if keypressed_down and has_solid_below: self.change_state(Player.STATE_CROUCHING) return # Gravity if self.velocity_y < config.MAX_GRAVITY: self.velocity_y += config.GRAVITY elif self.state == Player.STATE_CLIMBING: if keypressed_jump: self.velocity_y = -Player.JUMP_FORCE self.change_state(Player.STATE_STANDARD) return handle = self.state_args['handle'] vertical = self.state_args['vertical'] if vertical: if keydown_up == keydown_down: self.velocity_y = 0 else: if keydown_up: if self.y > handle.y: self.velocity_y = -Player.SPEED_SLOW else: self.velocity_y = 0 if handle.member_of('ladder'): self.y = handle.y - self.height self.change_state(Player.STATE_STANDARD) return if keydown_down: if self.y + self.height < handle.y + handle.height: self.velocity_y = Player.SPEED_SLOW else: self.velocity_y = 0 self.change_state(Player.STATE_STANDARD) return else: if keypressed_down: self.change_state(Player.STATE_STANDARD) return if keydown_left == keydown_right: self.velocity_x = 0 else: if keydown_left: if self.x > handle.x: self.velocity_x = -Player.SPEED_SLOW else: self.velocity_x = 0 if keydown_right: if self.x + self.width < handle.x + handle.width: self.velocity_x = Player.SPEED_SLOW else: self.velocity_x = 0 elif self.state == Player.STATE_CROUCHING: if keydown_left == keydown_right: self.velocity_x = 0 else: if keydown_left: self.velocity_x = -Player.SPEED_SLOW self.facing_x = -1 if keydown_right: self.velocity_x = Player.SPEED_SLOW self.facing_x = 1 # attempt to grab ledge when crawling off one tx = self.velocity_x + self.x if not solid_below(self, tx, self.y): ledges = solid_below(self, self.x, self.y) try: ledge = ledges[0] if self.velocity_x > 0: test = Rect(ledge.x + ledge.width, ledge.y, self.width, Player.HEIGHT_STANDARD) else: test = Rect(ledge.x - self.width, ledge.y, self.width, Player.HEIGHT_STANDARD) test.container = self.container if not collides_solid(self.container, test): self.x = test.x self.facing_x *= -1 self.change_state(Player.STATE_LEDGEGRAB, ledge=ledge) return except IndexError: pass attempt_stand = False if keypressed_jump and has_solid_below: self.velocity_y = -Player.JUMP_FORCE attempt_stand = True if not keydown_down: attempt_stand = True if attempt_stand: self.height = Player.HEIGHT_STANDARD temp_y = self.y - \ abs(Player.HEIGHT_STANDARD - Player.HEIGHT_CROUCH) if collides_solid(self.container, self.at_point(self.x, temp_y)): self.height = Player.HEIGHT_CROUCH temp_y = self.y self.velocity_y = 0 else: self.state = Player.STATE_STANDARD self.y = temp_y self.height = Player.HEIGHT_STANDARD if collides_solid(self.container, self.at_point(temp_x, temp_y)): self.height = Player.HEIGHT_CROUCH else: self.state = Player.STATE_STANDARD elif self.state == Player.STATE_HIDDEN: if keypressed_up or keypressed_left or keypressed_right: self.change_state(Player.STATE_STANDARD) elif self.state == Player.STATE_LEDGEGRAB: # Climb up ledge if keypressed_up or keypressed_left or keypressed_right: ledges = None if keydown_up: try: ledges = solid_left(self, self.x, self.y) assert ledges[0].y == self.y except (AssertionError, IndexError): ledges = solid_right(self, self.x, self.y) elif keydown_left: ledges = solid_left(self, self.x, self.y) elif keydown_right: ledges = solid_right(self, self.x, self.y) try: ledge = ledges[0] assert ledge.y == self.y test = peachy.geo.Rect(self.x, ledge.y - Player.HEIGHT_CROUCH, self.width, Player.HEIGHT_CROUCH) test.container = self.container if test.x + test.width <= ledge.x: test.x = ledge.x elif test.x >= ledge.x + ledge.width: test.x = ledge.x + ledge.width - test.width if not collides_solid(self.container, test): self.change_state(Player.STATE_CROUCHING) self.x = test.x self.y = test.y return except (AssertionError, IndexError): pass # Let go of ledge if keypressed_left and not solid_left(self, self.x, self.y) or \ keypressed_right and not solid_right(self, self.x, self.y) or \ keypressed_down: self.state = Player.STATE_STANDARD if keypressed_jump: self.state = Player.STATE_STANDARD self.velocity_y = -Player.JUMP_FORCE elif self.state == Player.STATE_PUSHING: block = self.state_args['block'] if self.x > block.x and keydown_left: self.velocity_x = -Player.SPEED_SLOW elif self.x < block.x and keydown_right: self.velocity_x = Player.SPEED_SLOW else: self.change_state(Player.STATE_STANDARD) return if keypressed_jump: self.velocity_y = -Player.JUMP_FORCE self.change_state(Player.STATE_STANDARD) return test_x = temp_x + self.velocity_x if not rect_rect(self.at_point(test_x, self.y), block): self.change_state(Player.STATE_STANDARD) return block_temp_x = block.x + self.velocity_x if not collides_solid(self.container, block.at_point(block_temp_x, block.y)): block.x = block_temp_x # GADGET if self.state != Player.STATE_DEAD: if keypressed_gadget and self.gadget.name: self.gadget.use() # ADVANCE temp_x += self.velocity_x temp_y += self.velocity_y # LOCKED DOOR lock = collides_group(self.container, 'locked-door', self.at_point(temp_x, temp_y)) if lock: lock = lock[0] if self.key_count > 0: self.key_count -= 1 self.container.unlocked_doors.append(lock.tag) lock.destroy() # FINALIZE c, self.x, self.y, self.velocity_x, self.velocity_y = \ collision_resolution(self, temp_x, temp_y) self.gadget.update()
def render(self): self.world.render_room() draw_text = peachy.graphics.draw_text # Because 80 line cap # Draw blur peachy.graphics.set_color(0, 0, 0, 125) peachy.graphics.draw_rect(0, 0, PC().canvas_width, PC().canvas_height) # Draw border border_height = PC().canvas_height / 8 peachy.graphics.set_color(0, 0, 0) peachy.graphics.draw_rect(0, 0, PC().canvas_width, border_height) peachy.graphics.draw_rect(0, PC().canvas_height - border_height, PC().canvas_width, border_height) # Draw window pause_rect = Rect(PC().canvas_width / 3, PC().canvas_height / 3, PC().canvas_width / 3, PC().canvas_height / 3) peachy.graphics.set_color(0, 0, 0) peachy.graphics.draw_rect(*pause_rect.ls()) peachy.graphics.set_color(15, 56, 87) peachy.graphics.draw_rect(*pause_rect.ls(), thickness=2) # Draw information peachy.graphics.set_color(210, 210, 210) draw_text('||| PAUSE |||', pause_rect.center_x, pause_rect.y + 48, center=True) peachy.graphics.set_color(125, 125, 125) draw_text(self.world.room.pause_menu_name, pause_rect.center_x, pause_rect.y + 84, center=True) gadget_name = self.world.room.player.gadget.name if gadget_name == '': gadget_name = 'NONE' gadget_name = '%-6s' % gadget_name draw_text('GADGET ... ' + gadget_name, pause_rect.center_x, pause_rect.y + 100, center=True) draw_text(' KEYS ... ' + '%-6s' % str(self.world.room.player.key_count), pause_rect.center_x, pause_rect.y + 116, center=True) # Draw options peachy.graphics.set_color(210, 210, 210) for i in range(0, len(self.options)): text = self.options[i] if i == self.selected: text = ' ' + text peachy.graphics.set_color(35, 76, 107) else: peachy.graphics.set_color(210, 210, 210) y = pause_rect.center_y + 8 + 24 * i draw_text(text, pause_rect.x + 48, y)
def update(self): if peachy.utils.Key.pressed('escape'): PC().quit() if peachy.utils.Key.pressed('F1'): PC().toggle_fullscreen() super().update()
def update(self): player = self.container.get_name('player') if player and self.collides(player, self.x, self.y): PC().world.set_checkpoint() self.checked = True self.old = False
def exit(self): PC().resources.deactivate_bundle('PierResources') # Release resources self.background = None self.foreground = None
def enter(self): super().enter() self.add(Dog(PC().canvas_width / 3, 100)) self.add(Solid(75, 150, PC().canvas_width / 2 - 150, 32)).visible = True