def update(self, dt): sent = False for event in self.event_bus.get_events(): if event.ty == EventType.COLLISION: player = None if event.data['first'] == self.entity: player = event.data['second'] elif event.data['second'] == self.entity: player = event.data['first'] if player != None and self.world.has_component( player, Tag) and "player" in self.world.component_for_entity( player, Tag).tags: self.event_bus.send.append( Event( { 'type': ActionEventType.SET_INFO, 'id': self.entity, 'text': "Descend", 'callback': self.descend, 'timeout': 0.2 }, EventType.ACTION)) sent = True if not sent: return self.event_bus.send.append( Event({ 'type': ActionEventType.DELETE_INFO, 'id': self.entity }, EventType.ACTION))
def spawn_bomb(self): if self.player.bomb_timer <= 0 and self.player.data.bombs > 0: original = self.player.data.bombs self.player.data.bombs -= 1 self.player.event_bus.send.append( Event( { 'type': PlayerEventType.BOMBS_CHANGED, 'original': original, 'amount': -1, 'new': self.player.data.bombs }, EventType.PLAYER)) self.player.bomb_timer = constants.BOMB_COOLDOWN bomb = self.player.world.create_entity_with( *loader.load("entity", "bomb")[0]) transform = self.player.world.component_for_entity(bomb, Transform) transform.position.x = self.player.transform.position.x transform.position.y = self.player.transform.position.y script = self.player.world.component_for_entity( bomb, ScriptComponent).script script.damage_data = self.player.data.get_explosion_damage( transform.position)
def hurt(self, amount, knockback): if self.hurt_cooldown > 0: return self.hurt_cooldown = constants.HURT_COOLDOWN original = self.data.health self.data.health -= amount if self.data.health <= 0: gameover = self.world.create_entity_with( *loader.load("entity", "gameover")[0]) script = self.world.component_for_entity(gameover, ScriptComponent).script script.player_pos = self.transform.position self.data = PlayerData() else: self.collision.velocity.x += knockback.x self.collision.velocity.y += knockback.y self.sound_hurt.play() self.event_bus.send.append( Event( { 'type': PlayerEventType.HEALTH_CHANGED, 'original': original, 'amount': amount, 'new': self.data.health }, EventType.PLAYER))
def update(self, dt): for event in self.event_bus.get_events(): if event.ty == EventType.PLAYER: if event.data['type'] == PlayerEventType.XP_ADDED: original_level = PlayerData.level_from_xp( event.data['original']) new_level = PlayerData.level_from_xp(event.data['new']) if original_level != new_level: self.event_bus.send.append( Event( { 'type': NotifyEventType.NOTIFY, 'time': 2, 'title': "Level Up", 'text': "Upgrades Available", 'sound_path': "player/level_up.wav" }, EventType.NOTIFY)) self.world.remove_component(self.entity, self.sprite) self.sprite = Sprite.new_text("Level " + str(new_level), (255, 255, 255), 14) self.world.add_component(self.entity, self.sprite) self.sprite._redraw = True self.transform.x = constants.WIDTH / 2 - self.sprite.bounds.width / 2
def start(self): self.player.event_bus.send.append( Event( { 'type': CameraEventType.FOLLOW, 'pos': self.player.transform.position, 'offset': pygame.math.Vector2(320 - 16, 200 - 16) }, EventType.CAMERA))
def update(self, dt): for ev in pygame.event.get(): if ev.type == pygame.QUIT: self.should_quit = True for entity, [event_component ] in self.world.get_components(EventComponent): if EventType.PYGAME in event_component.listen: event_component.send.append(Event(ev, EventType.PYGAME))
def start(self, entity, world): self.animation = world.component_for_entity(entity, AnimationSets) self.collision = world.component_for_entity(entity, CollisionComponent) self.event_bus = world.component_for_entity(entity, EventComponent) self.sprite = world.component_for_entity(entity, Sprite) self.transform = world.component_for_entity(entity, Transform) self.entity = entity self.world = world self.data.load() self.world.add_close_listener(entity, lambda: self.data.save()) self.event_bus.send.append( Event( { 'type': PlayerEventType.XP_ADDED, 'original': self.data.xp, 'amount': 0, 'new': self.data.xp }, EventType.PLAYER)) self.event_bus.send.append( Event( { 'type': PlayerEventType.HEALTH_CHANGED, 'original': self.data.health, 'amount': 0, 'new': self.data.health }, EventType.PLAYER)) self.event_bus.send.append( Event( { 'type': PlayerEventType.ARROWS_CHANGED, 'original': self.data.arrows, 'amount': 0, 'new': self.data.arrows }, EventType.PLAYER)) self.set_state(NeutralState(self))
def update(self, dt): if not self.waited: self.wait_counter += dt if self.wait_counter >= constants.GAMEOVER_DELAY + constants.GAMEOVER_SPIN + 1: self.waited = True self.event_bus.send.append( Event( { 'type': MusicEventType.PLAY, 'path': "gameover/gameover", 'id': constants.MUSIC_GAMEOVER }, EventType.MUSIC))
def update(self, dt): for event in self.event_bus.get_events(): if event.ty == EventType.CAVE: if event.data['type'] == CaveEventType.DESCEND: self.do_gen() self.event_bus.send.append( Event( { 'type': MusicEventType.POP, 'id': constants.MUSIC_BG, 'fade': True, 'fade_time': 1000 }, EventType.MUSIC))
def start(self, entity, world): self.entity = entity self.world = world self.event_bus = world.component_for_entity(entity, EventComponent) self.transform = world.component_for_entity(entity, Transform) self.event_bus.send.append( Event( { 'type': PlayerEventType.SET_POS, 'x': self.transform.position.x, 'y': self.transform.position.y }, EventType.PLAYER))
def die(self): if self.enemy._dead: return self.enemy.on_death() self.enemy._dead = True self.enemy.event_bus.send.append(Event({ 'type': PlayerEventType.ADD_XP, 'amount': self.enemy.xp_amount }, EventType.PLAYER, True)) poof_entity = self.enemy.world.create_entity_with(*loader.load("entity", "poof")[0]) poof_transform = self.enemy.world.component_for_entity(poof_entity, Transform) poof_transform.position = self.enemy.transform.position
def spawn_arrow(self): if self.player.data.arrows <= 0: return original = self.player.data.arrows self.player.data.arrows -= 1 self.player.event_bus.send.append( Event( { 'type': PlayerEventType.ARROWS_CHANGED, 'original': original, 'amount': -1, 'new': self.player.data.arrows }, EventType.PLAYER)) arrow_entity = loader.load_entities_into("arrow", self.world) animation = self.world.component_for_entity(arrow_entity, AnimationSets) script = self.world.component_for_entity(arrow_entity, ScriptComponent) transform = self.world.component_for_entity(arrow_entity, Transform) transform.position.x = self.transform.position.x transform.position.y = self.transform.position.y animation.current = "down" if self.dir == Direction.UP: animation.current = "up" transform.position.y -= 32 elif self.dir == Direction.LEFT: animation.current = "left" transform.position.x -= 32 elif self.dir == Direction.RIGHT: animation.current = "right" transform.position.x += 16 else: transform.position.y += 16 script.script.damage_data = self.damage_data script.script.dir = self.dir script.script.player = self.player
def on_event(self, event): if event.ty == EventType.COLLISION: if event.data['first'] == self.enemy.entity or event.data['second'] == self.enemy.entity: if event.data['first'] == self.enemy.entity: other_entity = event.data['second'] else: other_entity = event.data['first'] tag = self.enemy.world.component_for_entity(other_entity, Tag) if tag != None: if "weapon" in tag.tags: self.take_damage(other_entity) if "player" in tag.tags: self.enemy.event_bus.send.append(Event({ 'type': PlayerEventType.HURT, 'amount': self.enemy.attack_amount, 'knockback': self.enemy.damage_knockback }, EventType.PLAYER))
def start(self, entity, world): self.entity = entity self.world = world self.event_bus = world.component_for_entity(entity, EventComponent) for all_ent in world.get_all_entities(): if all_ent == self.entity: continue if world.has_component(all_ent, Tag): tag = world.component_for_entity(all_ent, Tag) if not "system" in tag.tags: world.delete_entity(all_ent) else: world.delete_entity(all_ent) self.event_bus.send.append( Event({'type': MusicEventType.CLEAR}, EventType.MUSIC)) self.create_player()
def update(self, dt): for event in self.event_bus.get_events(): if event.ty == EventType.COLLISION: other = None if event.data['first'] == self.entity: other = event.data['second'] elif event.data['second'] == self.entity: other = event.data['first'] if other != None: if self.world.has_component(other, Tag): tag = self.world.component_for_entity(other, Tag) if "player" in tag.tags: if not self.touched: self.touched = True self.event_bus.send.append( Event( { 'type': NotifyEventType.NOTIFY, 'time': 2, 'title': "Saved", 'text': "Game Saved" }, EventType.NOTIFY))
def update(self, dt): for event in self.event_bus.get_events(): if event.ty == EventType.MUSIC: if event.data['type'] == MusicEventType.PLAY: if self.cur_slot == None or event.data[ 'id'] != self.cur_slot.id: info = loader.load("music", event.data['path']) self.cur_slot = MusicSlot( event.data['id'], info, event.data.get('lifetime', None)) self.cur_slot.play() elif self.cur_slot != None and event.data[ 'id'] == self.cur_slot.id: if event.data.get('lifetime', None) != None: self.cur_slot.lifetime = event.data.get( 'lifetime', None) elif event.data['type'] == MusicEventType.PUSH: if self.cur_slot == None or event.data[ 'id'] != self.cur_slot.id: info = loader.load("music", event.data['path']) if self.cur_slot != None: self.cur_slot.stamp = pygame.mixer.music.get_pos() self.cur_slot = MusicSlot( event.data['id'], info, event.data.get('lifetime', None), self.cur_slot) self.cur_slot.play() elif self.cur_slot != None and event.data[ 'id'] == self.cur_slot.id: if event.data.get('lifetime', None) != None: self.cur_slot.lifetime = event.data.get( 'lifetime', None) elif event.data['type'] == MusicEventType.POP: self.stopping = True if event.data.get('fade', False): pygame.mixer.music.fadeout(event.data['fade_time']) else: pygame.mixer.music.stop() if self.cur_slot != None: self.cur_slot = self.cur_slot.prev if self.cur_slot != None: self.cur_slot.play() if self.cur_slot.stamp != None: pygame.mixer.music.rewind() pygame.mixer.music.set_pos( self.cur_slot.stamp / 1000) elif event.data['type'] == MusicEventType.CLEAR: pygame.mixer.music.stop() self.cur_slot = None elif event.ty == EventType.PYGAME: if event.data.type == 32: if self.cur_slot != None and not self.stopping: self.cur_slot.next() self.cur_slot.play() if self.stopping: self.stop_counter -= dt if self.stop_counter <= 0: self.stopping = False self.stop_counter = 1 else: self.stop_counter = 1 if self.cur_slot != None and self.cur_slot.lifetime != None: self.cur_slot.lifetime -= dt if self.cur_slot.lifetime <= 0: self.event_bus.send.append( Event({ 'type': MusicEventType.POP, 'id': self.cur_slot.id }, EventType.MUSIC))
def e_update(self, dt): for event in self.event_bus.get_events(): if event.ty == EventType.PLAYER: if event.data['type'] == PlayerEventType.PLAYER_MOVED: x = event.data['x'] y = event.data['y'] self.tracking = False self.tracking_x = x self.tracking_y = y elif event.ty == EventType.COLLISION: if event.data['first'] == self.entity or event.data[ 'second'] == self.entity: self.max_dir_counter = 0 if not self.tracking: self_x = self.transform.position.x self_y = self.transform.position.y x = self.tracking_x y = self.tracking_y if self_x > x - constants.MINIMOLDORM_RANGE and self_x < x + constants.MINIMOLDORM_RANGE and self_y > y - constants.MINIMOLDORM_RANGE and self_y < y + constants.MINIMOLDORM_RANGE: self.tracking = True self.event_bus.send.append( Event( { 'type': MusicEventType.PUSH, 'path': 'encounter/encounter', 'id': constants.MUSIC_ENCOUNTER, 'lifetime': 1 }, EventType.MUSIC)) if self.tracking: x = self.tracking_x y = self.tracking_y self_x = self.transform.position.x self_y = self.transform.position.y self.event_bus.send.append( Event( { 'type': MusicEventType.PUSH, 'path': 'encounter/encounter', 'id': constants.MUSIC_ENCOUNTER, 'lifetime': 3 }, EventType.MUSIC)) self.max_dir_counter = 0 if self_x > x + 4: self.dir_x = Direction.LEFT elif self_x < x - 4: self.dir_x = Direction.RIGHT else: self.dir_x = None if self_y > y + 4: self.dir_y = Direction.UP elif self_y < y - 4: self.dir_y = Direction.DOWN else: self.dir_y = None self.dir_counter += dt if self.dir_counter >= self.max_dir_counter: self.max_dir_counter = random.uniform( constants.MINIMOLDORM_ROTATE_MIN, constants.MINIMOLDORM_ROTATE_MAX) self.dir_counter = 0 if not self.tracking: self.dir_x = random.choice( [None, Direction(random.randrange(2, 4))]) self.dir_y = random.choice( [None, Direction(random.randrange(0, 2))]) aname = None if self.dir_y == None: if self.dir_x == Direction.LEFT: aname = "west" elif self.dir_x == Direction.RIGHT: aname = "east" elif self.dir_y == Direction.UP: if self.dir_x == None: aname = "north" elif self.dir_x == Direction.LEFT: aname = "northwest" elif self.dir_x == Direction.RIGHT: aname = "northeast" elif self.dir_y == Direction.DOWN: if self.dir_x == None: aname = "south" elif self.dir_x == Direction.LEFT: aname = "southwest" elif self.dir_x == Direction.RIGHT: aname = "southeast" if aname != None: self.animation.current = aname if self.dir_x != None and self.dir_y != None: self.damage_knockback = pygame.math.Vector2( self.dir_x.to_vector(constants.MINIMOLDORM_SPEED).x * 10, self.dir_y.to_vector(constants.MINIMOLDORM_SPEED).y * 10) if self.dir_x != None: self.collision.velocity.x += self.dir_x.to_vector( constants.MINIMOLDORM_SPEED).x if self.dir_y != None: self.collision.velocity.y += self.dir_y.to_vector( constants.MINIMOLDORM_SPEED).y
def descend(self): self.event_bus.send.append( Event({'type': CaveEventType.DESCEND}, EventType.CAVE, True)) return True
def update(self, dt): self.player.collision.velocity += self.player.facer.get_movement() self.player.animation.current = self.player.facer.get_animation() if self.player.facer.is_moving(): self.step_timer += dt if self.step_timer >= 0.35: self.step_timer = 0 self.step_sound.play() else: self.step_timer = 0 if self.player.collision.velocity.x != 0 or self.player.collision.velocity.y != 0: self.player.event_bus.send.append( Event( { 'type': CameraEventType.FOLLOW, 'pos': self.player.transform.position, 'offset': pygame.math.Vector2(320 - 16, 200 - 16) }, EventType.CAMERA)) self.player.event_bus.send.append( Event( { 'type': PlayerEventType.PLAYER_MOVED, 'x': self.player.transform.position.x, 'y': self.player.transform.position.y }, EventType.PLAYER)) keys_pressed = pygame.key.get_pressed() if keys_pressed[pygame.K_w] or ( self.player.joystick != None and self.player.joystick.get_axis(1) > 0.2): if not self.player.facer.contains(Direction.UP): self.player.facer.hold(Direction.UP) else: self.player.facer.release(Direction.UP) if keys_pressed[pygame.K_s] or ( self.player.joystick != None and self.player.joystick.get_axis(1) < -0.2): if not self.player.facer.contains(Direction.DOWN): self.player.facer.hold(Direction.DOWN) else: self.player.facer.release(Direction.DOWN) if keys_pressed[pygame.K_a] or ( self.player.joystick != None and self.player.joystick.get_axis(0) < -0.2): if not self.player.facer.contains(Direction.LEFT): self.player.facer.hold(Direction.LEFT) else: self.player.facer.release(Direction.LEFT) if keys_pressed[pygame.K_d] or ( self.player.joystick != None and self.player.joystick.get_axis(0) > 0.2): if not self.player.facer.contains(Direction.RIGHT): self.player.facer.hold(Direction.RIGHT) else: self.player.facer.release(Direction.RIGHT)
def generate(self): # TODO gen = Generator(32, 32) basicmap = gen.create_dungeon() yield tilemap = [0 for i in range(len(basicmap))] for y in range(0, 32): for x in range(0, 32): if gen.get_tile(x, y) == 1: tilemap[x + y * 32] = -1 continue n = gen.get_tile(x, y - 1) ne = gen.get_tile(x + 1, y - 1) e = gen.get_tile(x + 1, y) se = gen.get_tile(x + 1, y + 1) s = gen.get_tile(x, y + 1) sw = gen.get_tile(x - 1, y + 1) w = gen.get_tile(x - 1, y) nw = gen.get_tile(x - 1, y - 1) sprite_number = 0 if n == 0: sprite_number += 1 if ne == 0: sprite_number += 2 if e == 0: sprite_number += 4 if se == 0: sprite_number += 8 if s == 0: sprite_number += 16 if sw == 0: sprite_number += 32 if w == 0: sprite_number += 64 if nw == 0: sprite_number += 128 tilemap[x + y * 32] = tilemappings.get(sprite_number) yield populator = Populator(tilemap, 32, 32) tilemap = populator.populate(5, True) yield tile_mappings = loader.load("data", "tiles") for y in range(0, 32): for x in range(0, 32): tile_type = type(tilemap[x + y * 32]) if tile_type == int: if tilemap[x + y * 32] > -1: collision = CollisionComponent( size=pygame.math.Vector2(16, 16), solid=True) sprite = loader.load("sprite", "bricks") transform = Transform(position=pygame.math.Vector2( x * 16 * 2, y * 16 * 2), scale=pygame.math.Vector2(2, 2)) sprite.start = tilemap[x + y * 32] sprite.end = sprite.start + 1 self.world.create_entity_with(collision, sprite, transform) else: chance_list = tile_mappings[tilemap[x + y * 32]] weights = list( map(lambda x: x.get('chance', 1), chance_list)) choice = random.choices(chance_list, weights) entity_path = choice[0]['entity'] entities = loader.load("entity", entity_path) for components in entities: for component in components: if type(component) == Transform: component.position.x = x * 16 * 2 component.position.y = y * 16 * 2 component.scale.x = 2 component.scale.y = 2 self.world.create_entity_with(*components) yield floor_sprite = loader.load("sprite", "tiles/floor").repeated(32, 32) floor_transform = Transform(scale=pygame.math.Vector2(2, 2), layer=-1) self.world.create_entity_with(floor_sprite, floor_transform) yield self.event_bus.send.append( Event( { 'type': CameraEventType.SET_BOUNDS, 'x': 0, 'y': 0, 'width': 16 * 2 * 32, 'height': 16 * 2 * 32 + 80 }, EventType.CAMERA)) self.event_bus.send.append( Event( { 'type': MusicEventType.PLAY, 'path': "background/background", 'id': constants.MUSIC_BG }, EventType.MUSIC)) raise StopIteration
def update(self, dt): import math bodies = [ Body(entity, collision, transform) for entity, [collision, transform] in self.world.get_components( CollisionComponent, Transform) ] if len(bodies) < 1: return quad_tree = QuadTree(bodies, 4) for body in bodies: body.collision.velocity.x *= body.collision.friction body.collision.velocity.y *= body.collision.friction if abs(body.collision.velocity.x) < 0.5: body.collision.velocity.x = 0 if abs(body.collision.velocity.y) < 0.5: body.collision.velocity.y = 0 if abs(body.collision.velocity.x) > body.collision.max_speed: body.collision.velocity.x = math.copysign( body.collision.max_speed, body.collision.velocity.x) if abs(body.collision.velocity.y) > body.collision.max_speed: body.collision.velocity.y = math.copysign( body.collision.max_speed, body.collision.velocity.y) if body.collision.velocity.x != 0 or body.collision.velocity.y != 0 or body.collision.persistent: prev_x = body.transform.position.x prev_y = body.transform.position.y sent = [] body.transform.position.x += body.collision.velocity.x * dt for other_body in quad_tree.collide(body): self.event_bus.send.append( Event( { 'first': body.entity, 'second': other_body.entity }, EventType.COLLISION)) sent.append(other_body.entity) if body.collision.solid and other_body.collision.solid: body.transform.position.x = prev_x body.collision.velocity.x = 0 body.transform.position.y += body.collision.velocity.y * dt for other_body in quad_tree.collide(body): if not other_body.entity in sent: self.event_bus.send.append( Event( { 'first': body.entity, 'second': other_body.entity }, EventType.COLLISION)) if body.collision.solid and other_body.collision.solid: body.transform.position.y = prev_y body.collision.velocity.y = 0
def update(self, dt): for event in self.event_bus.get_events(): if event.ty == EventType.PLAYER: if event.data['type'] == PlayerEventType.SET_POS: self.transform.position.x = event.data['x'] self.transform.position.y = event.data['y'] self.event_bus.send.append( Event( { 'type': CameraEventType.FOLLOW, 'pos': self.transform.position, 'offset': pygame.math.Vector2( 320 - 16, 200 - 16) }, EventType.CAMERA)) elif event.data['type'] == PlayerEventType.ADD_XP: original = self.data.xp self.data.add_xp(event.data['amount']) self.event_bus.send.append( Event( { 'type': PlayerEventType.XP_ADDED, 'original': original, 'amount': event.data['amount'], 'new': self.data.xp }, EventType.PLAYER)) elif event.data['type'] == PlayerEventType.HURT: self.hurt( event.data['amount'], event.data.get('knockback', pygame.math.Vector2(0, 0))) elif event.ty == EventType.COLLISION: other = None if event.data['first'] == self.entity: other = event.data['second'] elif event.data['second'] == self.entity: other = event.data['first'] if other != None: if self.world.has_component(other, Tag): tag = self.world.component_for_entity(other, Tag) if "drop" in tag.tags: script = self.world.component_for_entity( other, ScriptComponent).script drop_info = script.drop if drop_info.ty == DropType.ARROW: amount = drop_info.data['amount'] original = self.data.arrows self.data.arrows += amount self.event_bus.send.append( Event( { 'type': PlayerEventType.ARROWS_CHANGED, 'original': original, 'amount': amount, 'new': self.data.arrows }, EventType.PLAYER)) self.sound_pickup_arrow.play() script.collected() self.state.on_event(event) self.state.update(dt) self.hurt_cooldown -= dt if self.hurt_cooldown < 0: self.hurt_cooldown = 0 self.sprite.visible = True if self.hurt_cooldown > 0: self.hurt_blinker += dt if self.hurt_blinker >= constants.HURT_BLINK: self.hurt_blinker = 0 self.sprite.visible = not self.sprite.visible if self.bomb_timer > 0: self.bomb_timer -= dt