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
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)
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)