示例#1
0
class SpritePatrol(State):
    def __init__(self, sprite, ai):
        super(SpritePatrol, self).__init__(cfg.SpriteState.PATROL)
        self.sprite = sprite
        self.ai = ai
        self.enter_timer = Timer()
        self.view_sensor_timer = Timer(ai.VIEW_SENSOR_TICK)


    def choose_a_backside_direction(self, current_direction):
        total = cfg.Direction.TOTAL
        opposite_direction = (current_direction + 4) % total
        return choice([(opposite_direction - 1) % total, opposite_direction,
            (opposite_direction + 1) % total])


    def enter(self, last_state):
        self.enter_timer.begin(gauss(self.ai.WALK_TIME_MU, self.ai.WALK_TIME_SIGMA))
        self.sprite.direction = self.choose_a_backside_direction(self.sprite.direction)

    
    def send_actions(self):
        if self.view_sensor_timer.is_begin():
            if self.view_sensor_timer.exceed():
                self.view_sensor_timer.begin()
                return (cfg.EnemyAction.LOOKOUT, cfg.EnemyAction.WALK)
            else:
                return (cfg.EnemyAction.WALK, )
        else:
            self.view_sensor_timer.begin()
            return (cfg.EnemyAction.WALK, )


    def check_conditions(self):
        sp = self.sprite
        if sp.brain.target is not None:
            sp.set_emotion(cfg.SpriteEmotion.ALERT)
            if sp.attacker.chance(sp.brain.target):
                #print "patrol to attack"
                return cfg.SpriteState.OFFENCE

            if happen(self.ai.PATROL_TO_CHASE_PROB):
                #print "patrol to chase"
                return cfg.SpriteState.CHASE

            return cfg.SpriteState.DEFENCE

        if sp.brain.interrupt:
            sp.brain.interrupt = False
            return cfg.SpriteState.STAY

        if self.enter_timer.exceed():
            return cfg.SpriteState.STAY


    def exit(self):
        self.enter_timer.clear()
示例#2
0
class SpriteStay(State):
    def __init__(self, sprite, ai):
        super(SpriteStay, self).__init__(cfg.SpriteState.STAY)
        self.sprite = sprite
        self.ai = ai
        self.enter_timer = Timer()
        self.view_sensor_timer = Timer(ai.VIEW_SENSOR_TICK)


    def enter(self, last_state):
        self.enter_timer.begin(gauss(self.ai.STAY_TIME_MU, self.ai.STAY_TIME_SIGMA))
        # turn for a random direction if the last state is the same "stay"
        if last_state and last_state.id == cfg.SpriteState.STAY \
            and happen(self.ai.STAY_CHANGE_DIRECTION_PROB):
            self.sprite.direction = choice(cfg.Direction.ALL)   # a random direction from "all"

        if happen(self.ai.EMOTION_SILENT_PROB):
            self.sprite.set_emotion(cfg.SpriteEmotion.SILENT)


    def send_actions(self):
        if self.view_sensor_timer.is_begin():
            if self.view_sensor_timer.exceed():
                self.view_sensor_timer.begin()
                return (cfg.EnemyAction.LOOKOUT, cfg.EnemyAction.STAND)
            else:
                return (cfg.EnemyAction.STAND, )
        else:
            self.view_sensor_timer.begin()
            return (cfg.EnemyAction.STAND, )


    def check_conditions(self):
        sp = self.sprite
        if sp.brain.target is not None:
            sp.set_emotion(cfg.SpriteEmotion.ALERT)
            # discover a target
            if happen(self.ai.STAY_TO_OFFENCE_PROB) and sp.attacker.chance(sp.brain.target):
                #print "to attack"
                return cfg.SpriteState.OFFENCE

            if happen(self.ai.STAY_TO_CHASE_PROB):
                return cfg.SpriteState.CHASE

            return cfg.SpriteState.DEFENCE

        if self.enter_timer.exceed():
            if happen(self.ai.STAY_TO_PATROL_PROB):
                #print "stay to patrol"
                return cfg.SpriteState.PATROL
            else:
                return cfg.SpriteState.STAY


    def exit(self):
        self.enter_timer.clear()
示例#3
0
class SpriteDefence(State):
    def __init__(self, sprite, ai):
        super(SpriteDefence, self).__init__(cfg.SpriteState.DEFENCE)
        self.sprite = sprite
        self.ai = ai
        self.enter_timer = Timer()
        #self.action_to_do = cfg.EnemyAction.STAND


    def enter(self, last_state):
        self.enter_timer.begin(gauss(self.ai.DEFENCE_TIME_MU, self.ai.DEFENCE_TIME_SIGMA))
        sp = self.sprite
        sp.direction = cal_face_direct(sp.pos.as_tuple(), sp.brain.target.pos.as_tuple())
        #if sp.hp_status == cfg.HpStatus.DANGER and happen(self.ai.DEFENCE_BACKWARD_PROB):
        #    self.action_to_do = cfg.EnemyAction.BACKWARD
        #else:
        #    self.action_to_do = cfg.EnemyAction.STAND


    def send_actions(self):
        return (cfg.EnemyAction.STAND, )
        #return (self.action_to_do, )


    def check_conditions(self):
        sp = self.sprite
        if self.enter_timer.exceed():
            if happen(self.ai.DEFENCE_TO_OFFENCE_PROB) and sp.attacker.chance(sp.brain.target):
                return cfg.SpriteState.OFFENCE

            distance_to_target = sp.pos.get_distance_to(sp.brain.target.pos)
            if happen(self.ai.DEFENCE_TO_CHASE_PROB) and distance_to_target <= self.ai.CHASE_RANGE :
                return cfg.SpriteState.CHASE

            if distance_to_target > self.ai.CHASE_RANGE:
                sp.brain.target = None
                return cfg.SpriteState.STAY

            return cfg.SpriteState.DEFENCE

        else:
            sp.direction = cal_face_direct(sp.pos.as_tuple(), sp.brain.target.pos.as_tuple())


    def exit(self):
        self.enter_timer.clear()
示例#4
0
class SpriteOffence(State):
    def __init__(self, sprite, ai):
        super(SpriteOffence, self).__init__(cfg.SpriteState.OFFENCE)
        self.sprite = sprite
        self.ai = ai
        self.enter_timer = Timer()


    def enter(self, last_state):
        sp = self.sprite
        sp.brain.persistent = True
        sp.direction = cal_face_direct(sp.pos.as_tuple(), sp.brain.target.pos.as_tuple())
        self.enter_timer.begin(gauss(self.ai.OFFENCE_GO_DELAY_TIME_MU, self.ai.OFFENCE_GO_DELAY_TIME_SIGMA))


    def send_actions(self):
        if not self.enter_timer.exceed():
            # add delay time for attack
            return (cfg.EnemyAction.STAND, )

        sp = self.sprite
        return (cfg.EnemyAction.ATTACK, ) if sp.brain.persistent else (cfg.EnemyAction.STAND, )


    def check_conditions(self):
        sp = self.sprite
        if sp.brain.persistent:
            return 

        if sp.attacker.chance(sp.brain.target):
            return cfg.SpriteState.OFFENCE

        if happen(self.ai.OFFENCE_TO_CHASE_PROB):
            return cfg.SpriteState.CHASE

        return cfg.SpriteState.DEFENCE


    def exit(self):
        self.enter_timer.clear()
        self.sprite.brain.persistent = False
示例#5
0
class SpriteChase(State):
    def __init__(self, sprite, ai, waypoints):
        super(SpriteChase, self).__init__(cfg.SpriteState.CHASE)
        self.sprite = sprite
        self.ai = ai
        self.pathfinder = pathfinding.Astar(sprite, waypoints)
        self.steerer = Steerer(sprite)
        self.enter_timer = Timer()
        self.target_move_threshold = sfg.WayPoint.STEP_WIDTH * 4


    def enter(self, last_state):
        sp = self.sprite
        if last_state and last_state.id in (cfg.SpriteState.STAY, cfg.SpriteState.PATROL):
            # discover hero right now, record the time for action delay
            self.enter_timer.begin(self.ai.CHASE_GO_DELAY_TIME)

        sp.direction = cal_face_direct(sp.pos.as_tuple(), sp.brain.target.pos.as_tuple())
        sp.brain.destination = sp.brain.target.pos.copy()
        path = self.pathfinder.find(sp.brain.destination.as_tuple(), sfg.WayPoint.STEP_WIDTH * 2)
        self.steerer.init(path)


    def send_actions(self):
        if self.enter_timer.is_begin() and not self.enter_timer.exceed():
            # delay chase action for a more real effect
            return (cfg.EnemyAction.STAND, )

        if self.steerer.is_ok:
            self.steerer.run()
            if not self.steerer.is_end:
                return (cfg.EnemyAction.STEER, )

        return (cfg.EnemyAction.STAND, )


    def check_conditions(self):
        sp = self.sprite

        if happen(self.ai.CHASE_TO_OFFENCE_PROB) and sp.attacker.chance(sp.brain.target):
            #print "to attack"
            return cfg.SpriteState.OFFENCE

        if (not self.steerer.is_ok) or happen(self.ai.CHASE_TO_DEFENCE_PROB):
            return cfg.SpriteState.DEFENCE

        distance_to_target = sp.pos.get_distance_to(sp.brain.target.pos)
        if distance_to_target <= self.ai.CHASE_RANGE:
            target_move = sp.brain.destination.get_distance_to(sp.brain.target.pos)
            if target_move > self.target_move_threshold or self.steerer.is_end:
                #print "chase to chase"
                return cfg.SpriteState.CHASE
        else:
            # lose target
            #print "lose target"
            sp.brain.target = None
            sp.set_emotion(cfg.SpriteEmotion.CHAOS)
            return cfg.SpriteState.STAY


    def exit(self):
        self.sprite.brain.destination = None
        self.enter_timer.clear()