Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
working on 2 players throwing and catching to each other
- Loading branch information
1 parent
a9d8738
commit abf93ef
Showing
11 changed files
with
349 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,191 @@ | ||
extends Spatial | ||
extends KinematicBody | ||
|
||
export var max_speed = 8 | ||
export var acceleration = 10 | ||
export var deceleration = 10 | ||
export var MAX_ANGLE_WITHOUT_STOPPING = 60 | ||
export var AT_DESTINATION_DISTANCE = 0.1 | ||
export var DISC_CATCHING_DISTANCE = 5 | ||
|
||
var current_direction = Vector3(1, 0, 0) | ||
var current_velocity = Vector3(-1, 0, 0) | ||
var desired_direction = Vector3(0, 0, -1) | ||
var desired_destination = Vector3(0, 0, -1) | ||
|
||
enum PLAYER_STATE { | ||
IDLE, | ||
RUNNING, | ||
WITH_DISC, | ||
THROWING | ||
} | ||
var right_hand | ||
var disc | ||
var skeleton | ||
var wrist_rest_position | ||
var animation_player | ||
var selected_marker | ||
var has_disc | ||
var is_selected | ||
var disc_calculator | ||
var current_state | ||
|
||
var debug_starting_time | ||
|
||
# Signal to attach the disc to the throwers arm | ||
signal thrower_arm_position(transform) | ||
# Signal to start throw | ||
signal throw_animation_complete() | ||
|
||
func _ready(): | ||
var animation_player = self.get_node('AnimationPlayer') | ||
animation_player.get_animation('Forehand').set_loop(true) | ||
animation_player.play('Forehand') | ||
self.animation_player = self.get_node('AnimationPlayer') | ||
self.selected_marker = self.get_node('SelectedMarker') | ||
self.disc_calculator = load('DiscCalculator.gd').new() | ||
self.animation_player.get_animation('Idle').set_loop(true) | ||
self.animation_player.get_animation('ArmatureAction').set_loop(true) | ||
self.animation_player.play('Idle') | ||
self.skeleton = self.get_node('Armature').get_node('Skeleton') | ||
self.right_hand = self.skeleton.find_bone('Wrist.R') | ||
self.wrist_rest_position = self.skeleton.get_bone_transform(right_hand) | ||
self.animation_player.connect('animation_finished', self, 'handle_animation_completion') | ||
self.current_state = PLAYER_STATE.IDLE | ||
|
||
func _physics_process(delta): | ||
if self.current_state == PLAYER_STATE.RUNNING: | ||
if self.check_if_at_destination(): | ||
pass | ||
self.recalculate_current_velocity(delta) | ||
self.move_and_slide(self.current_velocity, Vector3(0, -1, 0)) | ||
self.check_if_at_disc() | ||
if self.current_velocity.length() > 1.0: | ||
self.animation_player.play('ArmatureAction') | ||
|
||
func set_disc(disc): | ||
self.disc = disc | ||
|
||
func check_if_at_destination(): | ||
return self.translation.distance_to(self.desired_destination) < self.AT_DESTINATION_DISTANCE | ||
|
||
func check_if_at_disc(): | ||
print(self.translation.distance_to(self.disc.translation)) | ||
if self.translation.distance_to(self.disc.path_follow.translation) < self.AT_DESTINATION_DISTANCE: | ||
print('at disc') | ||
self.catch_disc() | ||
|
||
func catch_disc(): | ||
self.disc.throw_is_complete() | ||
self.disc.translation = self.translation | ||
self.has_disc = true | ||
self.current_velocity = Vector3(0, 0, 0) | ||
self.current_state = PLAYER_STATE.WITH_DISC | ||
|
||
func recalculate_current_velocity(delta): | ||
# If we are running in desired direction, accelerate to max_speed | ||
# Otherwise, depending on the angle change, | ||
# 0-60: Maintain the component of speed along that direction. | ||
# >60: decelerate to 0, and change to desired direction | ||
var change_of_angle = abs(rad2deg(self.current_direction.angle_to(self.desired_direction))) | ||
if change_of_angle < self.MAX_ANGLE_WITHOUT_STOPPING: | ||
self.current_velocity = self.current_velocity.project(self.desired_direction) | ||
self.current_direction = self.desired_direction | ||
if self.current_velocity.length() < self.max_speed: | ||
self.current_velocity += self.current_direction*self.acceleration*delta | ||
if self.current_velocity.length() > self.max_speed: | ||
self.current_velocity = self.current_direction*max_speed | ||
else: | ||
# !AnimationHook - Chopstop / sliding | ||
self.current_velocity -= self.current_direction*self.deceleration * delta | ||
if self.current_velocity.normalized() != self.current_direction: | ||
self.current_velocity = Vector3(0, 0, 0) | ||
self.run_to_world_point(self.desired_destination) | ||
self.current_direction = self.desired_direction | ||
|
||
func set_desired_direction(dir): | ||
self.desired_direction = dir.normalized() | ||
# TODO (22 May 2019 sam): Figure out where the rotation should be changed | ||
rotation.y = atan2(desired_direction.x, desired_direction.z) | ||
|
||
func _process(delta): | ||
var global_transform = self.skeleton.get_bone_transform(right_hand) | ||
func update_arm_position(): | ||
var global_transform = self.skeleton.get_bone_global_pose(right_hand) | ||
self.emit_signal('thrower_arm_position', global_transform) | ||
|
||
func start_throw_animation(throw_data): | ||
# TODO (30 May 2019 sam): Don't like this very much. The signal shouldn't be | ||
# directly connected to this method. See what the better way of doing this would be. | ||
if self.has_disc: | ||
self.animation_player.play(throw_data['throw'], -1, 3.0, false) | ||
self.has_disc = false | ||
|
||
func handle_animation_completion(anim_name): | ||
if anim_name == 'Forehand' or anim_name == 'Backhand': | ||
self.emit_signal('throw_animation_complete') | ||
if anim_name != 'Idle': | ||
self.animation_player.play('Idle') | ||
|
||
func set_selected(): | ||
self.is_selected = true | ||
self.selected_marker.visible = true | ||
|
||
func set_deselected(): | ||
self.is_selected = false | ||
self.selected_marker.visible = false | ||
|
||
func run_to_world_point(destination): | ||
self.desired_destination = destination | ||
var dir = destination - self.translation | ||
self.set_desired_direction(dir) | ||
self.debug_starting_time = OS.get_ticks_msec() | ||
self.current_state = PLAYER_STATE.RUNNING | ||
|
||
func disc_is_thrown(curve, throw_details): | ||
if self.current_state == PLAYER_STATE.RUNNING: | ||
var attack_point = self.calculate_attack_point(curve, throw_details) | ||
self.run_to_world_point(attack_point) | ||
|
||
func calculate_attack_point(curve, throw_details): | ||
# We take different points along the flight of the disc, and measure the | ||
# time that the disc would take to get there, as well as the time that the | ||
# player would take to get there. Whichever point has the least difference | ||
# between the two, that is the attack point, and the player looks to catch | ||
# the disc there. | ||
# TODO (28 May 2019 sam): When calculating this point, we also need to see | ||
# if it falls within some radius (is it really catchable at that point). This | ||
# also requires us to constrain running to directions with y=0, and also figure | ||
# out how to add jumping into this calculation, both with regards to skying and | ||
# laying out. | ||
var number_of_samples = 9 | ||
var best_point = -1 | ||
var best_time_difference = pow(10, 10) | ||
for i in range(number_of_samples): | ||
var time_sample = (i+1) * throw_details['time'] / number_of_samples | ||
var offset_sample = self.disc_calculator.get_disc_offset(time_sample, throw_details['time'], throw_details['max_speed'], throw_details['min_speed']) | ||
var sample_point = curve.interpolate_baked(offset_sample * curve.get_baked_length()) | ||
var time_to_point = self.get_time_to_point(sample_point, self.translation, self.current_direction, self.current_velocity) | ||
if abs(time_to_point - time_sample) < best_time_difference: | ||
best_time_difference = abs(time_to_point-time_sample) | ||
best_point = sample_point | ||
return best_point | ||
|
||
func get_time_to_point(point, pos, dir, vel): | ||
# Get the time it would take to move to a certain point | ||
# For further details, refer to `recalculate_current_velocity` | ||
# We use the pos, dir and vel here so that we can be a little recursive | ||
var direction_to_point = (point - pos).normalized() | ||
var change_of_angle = abs(rad2deg(dir.angle_to(direction_to_point))) | ||
if change_of_angle < 1 and vel.length() != 0: | ||
return point.distance_to(pos) / vel.length() | ||
if change_of_angle < MAX_ANGLE_WITHOUT_STOPPING: | ||
var initial_velocity = vel.project(direction_to_point) | ||
if initial_velocity.length() < self.max_speed: | ||
# calculate time to reach max speed, and position at that time | ||
var time_to_max = (self.max_speed-initial_velocity.length()) / self.acceleration | ||
var distance_to_max = (pow(self.max_speed, 2) - pow(vel.length(), 2)) / (2*self.acceleration) | ||
var pos_at_max = pos + direction_to_point*(distance_to_max) | ||
return time_to_max + self.get_time_to_point(point, pos_at_max, direction_to_point, self.max_speed*direction_to_point) | ||
else: | ||
# Chopstop / sliding | ||
var time_to_stop = (vel.length()) / self.deceleration | ||
var distance_to_stop = (-pow(vel.length(), 2)) / (2*self.deceleration) | ||
var pos_at_stop = pos + dir*(distance_to_stop) | ||
var new_dir = (point-pos_at_stop).normalized() | ||
return time_to_stop + self.get_time_to_point(point, pos_at_stop, new_dir, Vector3(0, 0, 0)) | ||
|
Oops, something went wrong.