コード例 #1
0
    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()
コード例 #2
0
ファイル: dog.py プロジェクト: shelsoloa/AgentObie
    def update(self):
        temp_x = self.x
        temp_y = self.y
        cx, cy = self.center

        players = self.container.get_group('player')

        target = None
        target_distance = None
        target_visible = False
        tcx, tcy = (0, 0)

        # Aggro closest player
        for player in players:
            temp_distance = self.distance_from(player)
            if target_distance is None or temp_distance < target_distance:
                target = player
                target_distance = temp_distance
                tcx, tcy = target.center

        # Visibility
        target_distance
        if target_distance <= Dog.AGGRO_RADIUS:
            if target_distance <= Dog.AGGRO_RADIUS:
                target_visible = True
            # Bite
            if self.collides(target, self.x, self.y) and \
               self.state != Dog.STATE_STUNNED:
                self.bite(target)

        # Update state
        if self.state == Dog.STATE_STANDARD:
            # Movement
            if solid_below(self, temp_x + self.width * self.facing_x, temp_y) and not \
               self.collides_solid(temp_x + self.width * self.facing_x, self.y):
                self.velocity_x = Dog.SPEED_WALK * self.facing_x
            else:
                self.velocity_x = 0
                self.facing_x *= -1

            # Detect player
            if target_visible:
                self.change_state(Dog.STATE_AGGRO)

        elif self.state == Dog.STATE_AGGRO:
            if target_distance > Dog.AGGRO_RADIUS:
                if not self.aggro_timer.tick():
                    self.change_state(Dog.STATE_STANDARD)
                self.velocity_x = 0
            else:
                self.aggro_timer.reset()

                x_dist = abs(cx - tcx)
                if x_dist > (self.width / 2):
                    x_dist = cx - tcx
                    if x_dist < 0:
                        self.facing_x = 1
                    else:
                        self.facing_x = -1

                    if solid_below(self, temp_x + self.width * self.facing_x,
                                   temp_y):
                        self.velocity_x = Dog.SPEED_RUN * self.facing_x
                    else:
                        self.velocity_x = 0
                else:
                    self.velocity_x = 0

        elif self.state == Dog.STATE_STUNNED:
            self.stun_timer -= 1
            if self.stun_timer <= 0:
                self.state = Dog.STATE_STANDARD

        # Finalize
        if self.velocity_y < MAX_GRAVITY:
            self.velocity_y += GRAVITY

        temp_x += self.velocity_x
        temp_y += self.velocity_y

        c, self.x, self.y, self.velocity_x, self.velocity_y = \
            collision_resolution(self, temp_x, temp_y)
コード例 #3
0
    def update(self):
        temp_x = self.x
        temp_y = self.y
        player = self.container.get_name('player')
        distance_from_player = self.distance_from(player)
        pcx, pcy = player.center

        # All ladders that are below this entity are treated as solids in this
        # update. They are reverted back to this prior state at the end of the
        # update.
        altered_ladders = [
            l for l in self.container.get_group('ladder')
            if l.y >= self.y + self.height
        ]
        for l in altered_ladders:
            l._temp_soldier_solid = l.solid
            l.solid = True

        # Calculate player_visible
        player_visible = False
        view_obstructions = self.container.get_group('opaque')
        if distance_from_player <= 64 and not player.invisible and \
           player.state != Player.STATE_HIDDEN:
            if self.collides(player, self.x, self.y):
                player_visible = True
            else:
                opp = self.y - pcy
                adj = pcx - self.x
                angle = math.degrees(math.atan2(opp, adj))

                if angle < 0:
                    angle = 360 + angle

                sight_range = angle_from_facing(self.facing_x, self.facing_y)

                if sight_range <= angle <= sight_range + 60:
                    player_visible = \
                        raycast(self.x, self.y, pcx, pcy, view_obstructions)
                if sight_range + 60 >= 360:
                    angle = 360 - angle
                    if sight_range <= angle <= sight_range + 60:
                        player_visible = \
                            raycast(self.x, self.y, pcx, pcy, view_obstructions)

        if self.state == Soldier.STATE_IDLE:
            # TODO turn around, check behind you
            if player_visible:
                self.change_state(Soldier.STATE_ALERT, spotted=(pcx, pcy))

        elif self.state == Soldier.STATE_PATROL:
            if player_visible:
                self.change_state(Soldier.STATE_ALERT, spotted=(pcx, pcy))

            elif self.wait_timer > 0:
                self.wait_timer -= 1
                if self.wait_timer <= 0:
                    self.facing_x *= -1
            else:
                if solid_below(self, temp_x, temp_y):
                    tx = temp_x + self.width * self.facing_x
                    if self.collides_solid(tx, self.y) or \
                       not solid_below(self, tx, temp_y):
                        self.velocity_x = 0
                        self.wait_timer = 60
                    else:
                        if self.slowed:
                            self.velocity_x = Soldier.SPEED_SLOW * self.facing_x
                        else:
                            self.velocity_x = Soldier.SPEED * self.facing_x

        elif self.state == Soldier.STATE_ALERT:
            target_distance = 0
            if player_visible:
                self.alert_timer = Soldier.ALERT_TIMER
                target_distance = Soldier.AGGRO_DISTANCE
                self.spotted_at = (pcx, pcy)
            else:
                if self.alert_timer == Soldier.ALERT_TIMER:
                    # Player just went out of sight, therefore look where they
                    # would be. ie where they are this frame
                    self.spotted_at = (pcx, pcy)

                self.alert_timer -= 1
                if self.alert_timer <= 0:
                    self.change_state(Soldier.STATE_PATROL)
                    return
                target_distance = 12

            target = self.spotted_at

            # Compute facing angle
            opp = self.y - target[1]
            adj = target[0] - self.x
            player_angle = math.degrees(math.atan2(opp, adj))
            if player_angle < 0:
                player_angle = 360 + player_angle
            self.facing_x, self.facing_y = facing_from_angle(player_angle)

            dist_x_target = abs(self.center_x - target[0])
            # diff_y_target = self.center_y - target[1]

            # MOVEMENT
            if dist_x_target > target_distance:
                tx = temp_x + self.width * self.facing_x
                if solid_below(self, tx, temp_y) and not \
                   self.collides_solid(tx, self.y):
                    if self.slowed:
                        self.velocity_x = Soldier.SPEED_SLOW * self.facing_x
                    else:
                        self.velocity_x = Soldier.SPEED_ALERT * self.facing_x
                else:
                    self.wait_timer = 60
                    # self.facing_x *= -1
                    self.velocity_x = 0
            else:
                self.velocity_x = 0

            # ACTION
            if self.slowed:
                self.attack_timer -= 0.25
            else:
                self.attack_timer -= 1

            if self.attack_timer <= 0 and player_visible:
                self.shoot(self.x, self.y, self.facing_x, self.facing_y)

        elif self.state == Soldier.STATE_STUNNED:
            self.stun_timer -= 1
            if self.stun_timer <= 0:
                self.stun_timer = 0
                self.state = Soldier.STATE_PATROL

        # GRAVITY
        if self.velocity_y < MAX_GRAVITY:
            self.velocity_y += GRAVITY

        # ADVANCE
        temp_x += self.velocity_x
        temp_y += self.velocity_y

        # FINALIZE
        c, self.x, self.y, self.velocity_x, self.velocity_y = \
            collision_resolution(self, temp_x, temp_y)

        # Undo solid ladders
        for l in altered_ladders:
            l.solid = l._temp_soldier_solid
            del l._temp_soldier_solid
コード例 #4
0
    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()