Пример #1
0
 def _fighting_tree(self, game):
             # 2. Updates character's fighting action state
     distance = (self.character.position - game.main_character.position).length
     
     # Check for hitting
     if distance < game.main_character.radius + 5 and \
            hit_detection(self.character, game.main_character): # FIX THIS WIRED CODE =S!
         self.fighting_state = F_STATE.hitting
     else:
         self.fighting_state = F_STATE.hold
         
     # Check for shooting (a.k.a. predicting physics)
     # Step 0. Simulate a bullet
     bullet = self.character.shoot()
     # Step 1. Get landing time of the bullet
     try:
         lt = (-bullet.velocity.y + \
               sqrt(bullet.velocity.y - 2 * GRAVITY.y * bullet.position.y)) / \
               GRAVITY.y
         # Step 2. Get position of impact
         pix = Vector3(bullet.position.x + bullet.velocity.x * lt,
                      0.,
                      bullet.position.z + bullet.velocity.z * lt)
         # Step 3. Intersects position of impact with target's radius
         bullet_trajectory = pix - self.character.position
         target_direction  = (game.main_character.position + \
                              self.character.velocity * lt) - \
                              self.character.position
         min_distance = target_direction - target_direction.projection(bullet_trajectory)
         if min_distance.length < self.character.radius and \
            target_direction.length < bullet_trajectory.length*13. and \
            abs(atan2(target_direction.x, target_direction.z) - \
            self.character.orientation) < pi/3:
             # We shoot!!
             self.fighting_state = F_STATE.shooting
             game.projectiles.append(bullet)
     except ValueError:
         pass
     if not self.fighting_state == F_STATE.hitting and not \
            self.fighting_state == F_STATE.shooting:
         self.fighting_state = F_STATE.hold
Пример #2
0
    def reset_velocity(self, game, obj=None, wall=False):
        """
        Solves tridimensional calculation of velocities after a collision.
        """
        if wall:
            if (self.acceleration * self.mass).length > 3500.:
                self.die()
                self.acceleration += GRAVITY * 2
            # Has to guess with which side are we hitting
            if game.stage.floor.area.collide_point(*self.area.center):
                # If my center is still on the stage
                if game.stage.floor.size - abs(self.area.center[0]) <= \
                   game.stage.floor.size - abs(self.area.center[1]):
                    # We are closer to an horizontal edge
                    self.velocity.x *= -1
                    self.hitting_acceleration.x *= -1
                else:
                    # We are closer to an vertical edge
                    self.velocity.z *= -1
                    self.hitting_acceleration.z *= -1
            else:
                # My center is out of the stage
                self.velocity *= -1
                self.hitting_acceleration *= -1
            return

        collision_axis = (self.position - obj.position).normalize()
        self_speed_x = self.velocity.dot(collision_axis)
        obj_speed_x  = obj.velocity.dot(collision_axis)
        linear_momentum = self_speed_x*self.mass + obj_speed_x*obj.mass
        vel_reflection  = self_speed_x - obj_speed_x

        # Find the elastic collision result
        # Find velocity components vectors according to the collision axis
        self_collision_vx = self.velocity.projection(collision_axis)
        self_collision_vy = self.velocity - self_collision_vx
        obj_collision_vx  = obj.velocity.projection(collision_axis)
        obj_collision_vy  = obj.velocity - obj_collision_vx
        # Resolve equation system.
        self_new_vx = (linear_momentum - obj.mass*vel_reflection) / \
                      (self.mass + obj.mass)
        obj_new_vx  = self_speed_x - obj_speed_x + self_new_vx
        # Gets the vectors
        try:
            self_new_vx = collision_axis.copy().set_length(abs(self_new_vx)) * \
                          (self_new_vx/abs(self_new_vx))
        except ZeroDivisionError:
            self_new_vx = Vector3()
        try:
            obj_new_vx = collision_axis.copy().set_length(abs(obj_new_vx)) * \
                         (obj_new_vx/abs(obj_new_vx)) 
        except ZeroDivisionError:
            obj_new_vx = Vector3()
        # Set new velocities
        self.velocity = self_collision_vy + self_new_vx
        obj.velocity  = obj_collision_vy + obj_new_vx

        # Check for hitting
        if self.hitting and hit_detection(self, obj):
            # If i'm really hitting the 'obj' character, we'll change its mass
            # to a fuzzy mass depending on its damage
            obj.energy -= self.hit_damage
            obj_hit_acc_length = obj.hitting_acceleration.length
            obj.hitting_acceleration = obj.velocity.copy()
            try:
                obj.hitting_acceleration.set_length(obj_hit_acc_length + \
                        self.hit_force / (obj.mass * (obj.energy / 100.)))
            except ZeroDivisionError:
                obj.hitting_acceleration.set_length(obj_hit_acc_length + \
                        self.hit_force / (obj.mass * 0.0001))

        if hasattr(obj, 'hitting') and obj.hitting and hit_detection(obj, self):
            # Same as the upper if.
            self.energy -= obj.hit_damage
            try:
                hit_acc_result = obj.hit_force / (self.mass * (self.energy / 100.))
            except ZeroDivisionError:
                hit_acc_result = obj.hit_force / (self.mass * 0.0001)
            self_hitted = True
        else:
            self_hitted = False

        hit_acc_length = self.hitting_acceleration.length
        self.hitting_acceleration += self.velocity
        if self_hitted:
            self.hitting_acceleration.set_length(hit_acc_length + hit_acc_result)
        else:
            self.hitting_acceleration.set_length(hit_acc_length)
Пример #3
0
    def reset_velocity(self, game, obj=None, wall=False):
        """
        Solves tridimensional calculation of velocities after a collision.
        """
        if wall:
            if (self.acceleration * self.mass).length > 3500.:
                self.die()
                self.acceleration += GRAVITY * 2
            # Has to guess with which side are we hitting
            if game.stage.floor.area.collide_point(*self.area.center):
                # If my center is still on the stage
                if game.stage.floor.size - abs(self.area.center[0]) <= \
                   game.stage.floor.size - abs(self.area.center[1]):
                    # We are closer to an horizontal edge
                    self.velocity.x *= -1
                    self.hitting_acceleration.x *= -1
                else:
                    # We are closer to an vertical edge
                    self.velocity.z *= -1
                    self.hitting_acceleration.z *= -1
            else:
                # My center is out of the stage
                self.velocity *= -1
                self.hitting_acceleration *= -1
            return

        collision_axis = (self.position - obj.position).normalize()
        self_speed_x = self.velocity.dot(collision_axis)
        obj_speed_x = obj.velocity.dot(collision_axis)
        linear_momentum = self_speed_x * self.mass + obj_speed_x * obj.mass
        vel_reflection = self_speed_x - obj_speed_x

        # Find the elastic collision result
        # Find velocity components vectors according to the collision axis
        self_collision_vx = self.velocity.projection(collision_axis)
        self_collision_vy = self.velocity - self_collision_vx
        obj_collision_vx = obj.velocity.projection(collision_axis)
        obj_collision_vy = obj.velocity - obj_collision_vx
        # Resolve equation system.
        self_new_vx = (linear_momentum - obj.mass*vel_reflection) / \
                      (self.mass + obj.mass)
        obj_new_vx = self_speed_x - obj_speed_x + self_new_vx
        # Gets the vectors
        try:
            self_new_vx = collision_axis.copy().set_length(abs(self_new_vx)) * \
                          (self_new_vx/abs(self_new_vx))
        except ZeroDivisionError:
            self_new_vx = Vector3()
        try:
            obj_new_vx = collision_axis.copy().set_length(abs(obj_new_vx)) * \
                         (obj_new_vx/abs(obj_new_vx))
        except ZeroDivisionError:
            obj_new_vx = Vector3()
        # Set new velocities
        self.velocity = self_collision_vy + self_new_vx
        obj.velocity = obj_collision_vy + obj_new_vx

        # Check for hitting
        if self.hitting and hit_detection(self, obj):
            # If i'm really hitting the 'obj' character, we'll change its mass
            # to a fuzzy mass depending on its damage
            obj.energy -= self.hit_damage
            obj_hit_acc_length = obj.hitting_acceleration.length
            obj.hitting_acceleration = obj.velocity.copy()
            try:
                obj.hitting_acceleration.set_length(obj_hit_acc_length + \
                        self.hit_force / (obj.mass * (obj.energy / 100.)))
            except ZeroDivisionError:
                obj.hitting_acceleration.set_length(obj_hit_acc_length + \
                        self.hit_force / (obj.mass * 0.0001))

        if hasattr(obj, 'hitting') and obj.hitting and hit_detection(
                obj, self):
            # Same as the upper if.
            self.energy -= obj.hit_damage
            try:
                hit_acc_result = obj.hit_force / (self.mass *
                                                  (self.energy / 100.))
            except ZeroDivisionError:
                hit_acc_result = obj.hit_force / (self.mass * 0.0001)
            self_hitted = True
        else:
            self_hitted = False

        hit_acc_length = self.hitting_acceleration.length
        self.hitting_acceleration += self.velocity
        if self_hitted:
            self.hitting_acceleration.set_length(hit_acc_length +
                                                 hit_acc_result)
        else:
            self.hitting_acceleration.set_length(hit_acc_length)