Browse Source
fixed path reset rotation
fixed path reset rotation
21 changed files with 111 additions and 586 deletions
-
12project.godot
-
2scenes/lobby/lobby.tscn
-
2scenes/player/PathPlayerBase.tscn
-
6scenes/player/PathPlayerBot.tscn
-
6scenes/player/camera.tscn
-
3scenes/road/roadCornerLarge.tscn
-
2scenes/road/roadCornerLargeFlipped.tscn
-
2scenes/road/roadCornerLarger.tscn
-
2scenes/road/roadCornerLargerFlipped.tscn
-
2scenes/road/roadCornerSmall.tscn
-
2scenes/road/roadCornerSmallFlipped.tscn
-
208scripts/camera/camera_control.gd
-
296scripts/camera/camera_control_gui.gd
-
20scripts/game/game_state.gd
-
4scripts/game/preview.gd
-
4scripts/game/route.gd
-
41scripts/player/PathPlayerBase.gd
-
46scripts/player/PathPlayerBot.gd
-
2scripts/player/PathPlayerControls.gd
-
19scripts/player/PathPlayerWheelRotation.gd
-
10scripts/road/road.gd
@ -1,6 +1,6 @@ |
|||
[gd_scene load_steps=8 format=2] |
|||
|
|||
[ext_resource path="res://scripts/player/BasePathPlayer.gd" type="Script" id=1] |
|||
[ext_resource path="res://scripts/player/PathPlayerBase.gd" type="Script" id=1] |
|||
[ext_resource path="res://scripts/player/raceCar.gd" type="Script" id=2] |
|||
[ext_resource path="res://assets/raceCar/body.obj" type="ArrayMesh" id=3] |
|||
[ext_resource path="res://assets/raceCar/wheel.obj" type="ArrayMesh" id=4] |
@ -0,0 +1,6 @@ |
|||
[gd_scene load_steps=2 format=2] |
|||
|
|||
[ext_resource path="res://scripts/player/PathPlayerBot.gd" type="Script" id=1] |
|||
|
|||
[node name="PlayerControls" type="Spatial"] |
|||
script = ExtResource( 1 ) |
@ -1,6 +0,0 @@ |
|||
[gd_scene format=2] |
|||
|
|||
[node name="InterpolatedCamera" type="InterpolatedCamera"] |
|||
h_offset = 0.5 |
|||
v_offset = 0.5 |
|||
enabled = true |
@ -1,208 +0,0 @@ |
|||
# Licensed under the MIT License. |
|||
# Copyright (c) 2018 Jaccomo Lorenz (Maujoe) |
|||
|
|||
extends Camera |
|||
|
|||
# User settings: |
|||
# General settings |
|||
export var enabled = true setget set_enabled |
|||
export(int, "Visible", "Hidden", "Caputered, Confined") var mouse_mode = 2 |
|||
|
|||
# Mouslook settings |
|||
export var mouselook = true |
|||
export (float, 0.0, 1.0) var sensitivity = 0.5 |
|||
export (float, 0.0, 0.999, 0.001) var smoothness = 0.5 setget set_smoothness |
|||
export(NodePath) var privot setget set_privot |
|||
export var distance = 5.0 setget set_distance |
|||
export var rotate_privot = false |
|||
export var collisions = true setget set_collisions |
|||
export (int, 0, 360) var yaw_limit = 360 |
|||
export (int, 0, 360) var pitch_limit = 360 |
|||
|
|||
# Movement settings |
|||
export var movement = true |
|||
export (float, 0.0, 1.0) var acceleration = 1.0 |
|||
export (float, 0.0, 0.0, 1.0) var deceleration = 0.1 |
|||
export var max_speed = Vector3(1.0, 1.0, 1.0) |
|||
export var local = true |
|||
export var forward_action = "ui_up" |
|||
export var backward_action = "ui_down" |
|||
export var left_action = "ui_left" |
|||
export var right_action = "ui_right" |
|||
export var up_action = "ui_page_up" |
|||
export var down_action = "ui_page_down" |
|||
|
|||
# Gui settings |
|||
export var use_gui = true |
|||
export var gui_action = "ui_cancel" |
|||
|
|||
# Intern variables. |
|||
var _mouse_position = Vector2(0.0, 0.0) |
|||
var _yaw = 0.0 |
|||
var _pitch = 0.0 |
|||
var _total_yaw = 0.0 |
|||
var _total_pitch = 0.0 |
|||
|
|||
var _direction = Vector3(0.0, 0.0, 0.0) |
|||
var _speed = Vector3(0.0, 0.0, 0.0) |
|||
var _gui |
|||
|
|||
func _ready(): |
|||
_check_actions([forward_action, backward_action, left_action, right_action, gui_action, up_action, down_action]) |
|||
|
|||
if privot: |
|||
privot = get_node(privot) |
|||
else: |
|||
privot = null |
|||
|
|||
set_enabled(enabled) |
|||
|
|||
if use_gui: |
|||
_gui = preload("camera_control_gui.gd") |
|||
_gui = _gui.new(self, gui_action) |
|||
add_child(_gui) |
|||
|
|||
func _input(event): |
|||
if mouselook: |
|||
if event is InputEventMouseMotion: |
|||
_mouse_position = event.relative |
|||
|
|||
if movement: |
|||
if event.is_action_pressed(forward_action): |
|||
_direction.z = -1 |
|||
elif event.is_action_pressed(backward_action): |
|||
_direction.z = 1 |
|||
elif not Input.is_action_pressed(forward_action) and not Input.is_action_pressed(backward_action): |
|||
_direction.z = 0 |
|||
|
|||
if event.is_action_pressed(left_action): |
|||
_direction.x = -1 |
|||
elif event.is_action_pressed(right_action): |
|||
_direction.x = 1 |
|||
elif not Input.is_action_pressed(left_action) and not Input.is_action_pressed(right_action): |
|||
_direction.x = 0 |
|||
|
|||
if event.is_action_pressed(up_action): |
|||
_direction.y = 1 |
|||
if event.is_action_pressed(down_action): |
|||
_direction.y = -1 |
|||
elif not Input.is_action_pressed(up_action) and not Input.is_action_pressed(down_action): |
|||
_direction.y = 0 |
|||
|
|||
func _process(delta): |
|||
if privot: |
|||
_update_distance() |
|||
if mouselook: |
|||
_update_mouselook() |
|||
if movement: |
|||
_update_movement(delta) |
|||
|
|||
func _physics_process(delta): |
|||
# Called when collision are enabled |
|||
_update_distance() |
|||
if mouselook: |
|||
_update_mouselook() |
|||
|
|||
var space_state = get_world().get_direct_space_state() |
|||
var obstacle = space_state.intersect_ray(privot.get_translation(), get_translation()) |
|||
if not obstacle.empty(): |
|||
set_translation(obstacle.position) |
|||
|
|||
func _update_movement(delta): |
|||
var offset = max_speed * acceleration * _direction |
|||
|
|||
_speed.x = clamp(_speed.x + offset.x, -max_speed.x, max_speed.x) |
|||
_speed.y = clamp(_speed.y + offset.y, -max_speed.y, max_speed.y) |
|||
_speed.z = clamp(_speed.z + offset.z, -max_speed.z, max_speed.z) |
|||
|
|||
# Apply deceleration if no input |
|||
if _direction.x == 0: |
|||
_speed.x *= (1.0 - deceleration) |
|||
if _direction.y == 0: |
|||
_speed.y *= (1.0 - deceleration) |
|||
if _direction.z == 0: |
|||
_speed.z *= (1.0 - deceleration) |
|||
|
|||
if local: |
|||
translate(_speed * delta) |
|||
else: |
|||
global_translate(_speed * delta) |
|||
|
|||
func _update_mouselook(): |
|||
_mouse_position *= sensitivity |
|||
_yaw = _yaw * smoothness + _mouse_position.x * (1.0 - smoothness) |
|||
_pitch = _pitch * smoothness + _mouse_position.y * (1.0 - smoothness) |
|||
_mouse_position = Vector2(0, 0) |
|||
|
|||
if yaw_limit < 360: |
|||
_yaw = clamp(_yaw, -yaw_limit - _total_yaw, yaw_limit - _total_yaw) |
|||
if pitch_limit < 360: |
|||
_pitch = clamp(_pitch, -pitch_limit - _total_pitch, pitch_limit - _total_pitch) |
|||
|
|||
_total_yaw += _yaw |
|||
_total_pitch += _pitch |
|||
|
|||
if privot: |
|||
var target = privot.get_translation() |
|||
var offset = get_translation().distance_to(target) |
|||
|
|||
set_translation(target) |
|||
rotate_y(deg2rad(-_yaw)) |
|||
rotate_object_local(Vector3(1,0,0), deg2rad(-_pitch)) |
|||
translate(Vector3(0.0, 0.0, offset)) |
|||
|
|||
if rotate_privot: |
|||
privot.rotate_y(deg2rad(-_yaw)) |
|||
else: |
|||
rotate_y(deg2rad(-_yaw)) |
|||
rotate_object_local(Vector3(1,0,0), deg2rad(-_pitch)) |
|||
|
|||
func _update_distance(): |
|||
var t = privot.get_translation() |
|||
t.z -= distance |
|||
set_translation(t) |
|||
|
|||
func _update_process_func(): |
|||
# Use physics process if collision are enabled |
|||
if collisions and privot: |
|||
set_physics_process(true) |
|||
set_process(false) |
|||
else: |
|||
set_physics_process(false) |
|||
set_process(true) |
|||
|
|||
func _check_actions(actions=[]): |
|||
if OS.is_debug_build(): |
|||
for action in actions: |
|||
if not InputMap.has_action(action): |
|||
print('WARNING: No action "' + action + '"') |
|||
|
|||
func set_privot(value): |
|||
privot = value |
|||
# TODO: fix parenting. |
|||
# if privot: |
|||
# if get_parent(): |
|||
# get_parent().remove_child(self) |
|||
# privot.add_child(self) |
|||
_update_process_func() |
|||
|
|||
func set_collisions(value): |
|||
collisions = value |
|||
_update_process_func() |
|||
|
|||
func set_enabled(value): |
|||
enabled = value |
|||
if enabled: |
|||
Input.set_mouse_mode(mouse_mode) |
|||
set_process_input(true) |
|||
_update_process_func() |
|||
else: |
|||
set_process(false) |
|||
set_process_input(false) |
|||
set_physics_process(false) |
|||
|
|||
func set_smoothness(value): |
|||
smoothness = clamp(value, 0.001, 0.999) |
|||
|
|||
func set_distance(value): |
|||
distance = max(0, value) |
@ -1,296 +0,0 @@ |
|||
# Licensed under the MIT License. |
|||
# Copyright (c) 2018 Jaccomo Lorenz (Maujoe) |
|||
|
|||
extends Control |
|||
|
|||
# Constant Gui Settings |
|||
#******************************************************************************* |
|||
const GUI_POS = Vector2(10, 10) |
|||
const GUI_SIZE = Vector2(200, 0) |
|||
const DRAGGABLE = true |
|||
|
|||
const CUSTOM_BACKGROUND = false |
|||
const BACKGROUND_COLOR = Color(0.15, 0.17, 0.23, 0.75) |
|||
|
|||
const MAX_SPEED = 50 |
|||
#******************************************************************************* |
|||
|
|||
var camera |
|||
var shortcut |
|||
var node_list |
|||
var privot |
|||
var panel |
|||
|
|||
var mouse_over = false |
|||
var mouse_pressed = false |
|||
|
|||
func _init(camera, shortcut): |
|||
self.camera = camera |
|||
self.shortcut = shortcut |
|||
|
|||
func _ready(): |
|||
if camera.enabled: |
|||
set_process_input(true) |
|||
|
|||
# Create Gui |
|||
panel = PanelContainer.new() |
|||
panel.set_begin(GUI_POS) |
|||
panel.set_custom_minimum_size(GUI_SIZE) |
|||
|
|||
if CUSTOM_BACKGROUND: |
|||
var style = StyleBoxFlat.new() |
|||
style.set_bg_color(BACKGROUND_COLOR) |
|||
style.set_expand_margin_all(5) |
|||
panel.add_stylebox_override("panel", style) |
|||
|
|||
var container = VBoxContainer.new() |
|||
|
|||
var lbl_mouse = Label.new() |
|||
lbl_mouse.set_text("Mousemode") |
|||
|
|||
var mouse = OptionButton.new() |
|||
mouse.add_item("Visible") |
|||
mouse.add_item("Hidden") |
|||
mouse.add_item("Captured") |
|||
mouse.add_item("Confined") |
|||
mouse.select(camera.mouse_mode) |
|||
mouse.connect("item_selected",self,"_on_opt_mouse_item_selected") |
|||
|
|||
# Mouselook |
|||
var mouselook = CheckButton.new() |
|||
mouselook.set_text("Mouselook") |
|||
mouselook.set_toggle_mode(true) |
|||
mouselook.set_pressed(camera.mouselook) |
|||
mouselook.connect("toggled",self,"_on_btn_mouselook_toggled") |
|||
|
|||
var lbl_sensitivity = Label.new() |
|||
lbl_sensitivity.set_text("Sensitivity") |
|||
|
|||
var sensitivity = HScrollBar.new() |
|||
sensitivity.set_max(1) |
|||
sensitivity.set_value(camera.sensitivity) |
|||
sensitivity.connect("value_changed",self,"_on_hsb_sensitivity_value_changed") |
|||
|
|||
var lbl_smoothless = Label.new() |
|||
lbl_smoothless.set_text("Smoothness") |
|||
|
|||
var smoothness = HScrollBar.new() |
|||
smoothness.set_max(0.999) |
|||
smoothness.set_min(0.5) |
|||
smoothness.set_value(camera.smoothness) |
|||
smoothness.connect("value_changed",self,"_on_hsb_smoothness_value_changed") |
|||
|
|||
var lbl_privot = Label.new() |
|||
lbl_privot.set_text("Privot") |
|||
|
|||
privot = OptionButton.new() |
|||
privot.set_text("Privot") |
|||
_update_privots(privot) |
|||
privot.connect("item_selected",self,"_on_opt_privot_item_selected") |
|||
privot.connect("pressed",self,"_on_opt_privot_pressed") |
|||
|
|||
var btn_rot_privot = CheckButton.new() |
|||
btn_rot_privot.set_text("Rotate Privot") |
|||
btn_rot_privot.set_toggle_mode(true) |
|||
btn_rot_privot.set_pressed(camera.rotate_privot) |
|||
btn_rot_privot.connect("toggled",self,"_on_btn_rot_privot_toggled") |
|||
|
|||
var lbl_distance = Label.new() |
|||
lbl_distance.set_text("Distance") |
|||
|
|||
var distance = SpinBox.new() |
|||
distance.set_value(camera.distance) |
|||
distance.connect("value_changed",self,"_on_box_distance_value_changed") |
|||
|
|||
var lbl_yaw = Label.new() |
|||
lbl_yaw.set_text("Yaw Limit") |
|||
|
|||
var yaw = SpinBox.new() |
|||
yaw.set_max(360) |
|||
yaw.set_value(camera.yaw_limit) |
|||
yaw.connect("value_changed",self,"_on_box_yaw_value_changed") |
|||
|
|||
var lbl_pitch = Label.new() |
|||
lbl_pitch.set_text("Pitch Limit") |
|||
|
|||
var pitch = SpinBox.new() |
|||
pitch.set_max(360) |
|||
pitch.set_value(camera.pitch_limit) |
|||
pitch.connect("value_changed",self,"_on_box_pitch_value_changed") |
|||
|
|||
var collisions = CheckButton.new() |
|||
collisions.set_text("Collisions") |
|||
collisions.set_toggle_mode(true) |
|||
collisions.set_pressed(camera.collisions) |
|||
collisions.connect("toggled",self,"_on_btn_collisions_toggled") |
|||
|
|||
# Movement |
|||
var lbl_movement = Label.new() |
|||
lbl_movement.set_text("Movement") |
|||
|
|||
var movement = CheckButton.new() |
|||
movement.set_pressed(camera.movement) |
|||
movement.connect("toggled",self,"_on_btn_movement_toggled") |
|||
|
|||
var lbl_speed = Label.new() |
|||
lbl_speed.set_text("Max Speed") |
|||
|
|||
var speed = HScrollBar.new() |
|||
speed.set_max(MAX_SPEED) |
|||
speed.set_value(camera.max_speed.x) |
|||
speed.connect("value_changed",self,"_on_hsb_speed_value_changed") |
|||
|
|||
var lbl_acceleration = Label.new() |
|||
lbl_acceleration.set_text("Acceleration") |
|||
|
|||
var acceleration = HScrollBar.new() |
|||
acceleration.set_max(1.0) |
|||
acceleration.set_value(camera.acceleration) |
|||
acceleration.connect("value_changed", self, "_in_hsb_acceleration_value_changed") |
|||
|
|||
var lbl_deceleration = Label.new() |
|||
lbl_deceleration.set_text("Deceleration") |
|||
|
|||
var deceleration = HScrollBar.new() |
|||
deceleration.set_max(1.0) |
|||
deceleration.set_value(camera.deceleration) |
|||
deceleration.connect("value_changed", self, "_in_hsb_deceleration_value_changed") |
|||
|
|||
add_child(panel) |
|||
panel.add_child(container) |
|||
container.add_child(lbl_mouse) |
|||
container.add_child(mouse) |
|||
container.add_child(mouselook) |
|||
container.add_child(lbl_sensitivity) |
|||
container.add_child(sensitivity) |
|||
container.add_child(lbl_smoothless) |
|||
container.add_child(smoothness) |
|||
container.add_child(lbl_privot) |
|||
container.add_child(privot) |
|||
container.add_child(btn_rot_privot) |
|||
container.add_child(lbl_distance) |
|||
container.add_child(distance) |
|||
container.add_child(lbl_yaw) |
|||
container.add_child(yaw) |
|||
container.add_child(lbl_pitch) |
|||
container.add_child(pitch) |
|||
container.add_child(collisions) |
|||
container.add_child(lbl_movement) |
|||
container.add_child(movement) |
|||
container.add_child(lbl_speed) |
|||
container.add_child(speed) |
|||
container.add_child(lbl_acceleration) |
|||
container.add_child(acceleration) |
|||
container.add_child(lbl_deceleration) |
|||
container.add_child(deceleration) |
|||
|
|||
if DRAGGABLE: |
|||
panel.connect("mouse_entered", self, "_panel_entered") |
|||
panel.connect("mouse_exited", self, "_panel_exited") |
|||
container.connect("mouse_entered", self, "_panel_entered") |
|||
container.connect("mouse_exited", self, "_panel_exited") |
|||
|
|||
self.hide() |
|||
else: |
|||
set_process_input(false) |
|||
|
|||
func _input(event): |
|||
if event.is_action_pressed(shortcut): |
|||
if camera.enabled: |
|||
camera.enabled = false |
|||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) |
|||
self.show() |
|||
else: |
|||
camera.enabled = true |
|||
self.hide() |
|||
|
|||
if DRAGGABLE: |
|||
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT: |
|||
mouse_pressed = event.pressed |
|||
|
|||
elif event is InputEventMouseMotion and mouse_over and mouse_pressed: |
|||
panel.set_begin(panel.get_begin() + event.relative) |
|||
|
|||
func _update_privots(privot): |
|||
privot.clear() |
|||
privot.add_item("None") |
|||
node_list = _get_spatials_recusiv(get_tree().get_root(), [get_name(), camera.get_name()]) |
|||
|
|||
var size = node_list.size() |
|||
for i in range(0, size): |
|||
var node = node_list[i] |
|||
privot.add_item(node.get_name()) |
|||
if node == camera.privot: |
|||
privot.select(i+1) |
|||
|
|||
if not camera.privot: |
|||
privot.select(0) |
|||
|
|||
|
|||
func _get_spatials_recusiv(node, exceptions=[]): |
|||
var list = [] |
|||
for child in node.get_children(): |
|||
if not child.get_name() in exceptions: |
|||
if child is Spatial: |
|||
list.append(child) |
|||
if not child.get_children().empty(): |
|||
for subchild in _get_spatials_recusiv(child, exceptions): |
|||
list.append(subchild) |
|||
return list |
|||
|
|||
func _panel_entered(): |
|||
mouse_over = true |
|||
|
|||
func _panel_exited(): |
|||
mouse_over = false |
|||
|
|||
func _on_opt_mouse_item_selected(id): |
|||
camera.mouse_mode = id |
|||
|
|||
func _on_btn_mouselook_toggled(pressed): |
|||
camera.mouselook = pressed |
|||
|
|||
func _on_hsb_sensitivity_value_changed(value): |
|||
camera.sensitivity = value |
|||
|
|||
func _on_hsb_smoothness_value_changed(value): |
|||
camera.smoothness = value |
|||
|
|||
func _on_opt_privot_pressed(): |
|||
_update_privots(privot) |
|||
|
|||
func _on_opt_privot_item_selected(id): |
|||
if id > 0: |
|||
camera.privot = node_list[id-1] |
|||
else: |
|||
camera.privot = null |
|||
privot.select(id) |
|||
|
|||
func _on_btn_rot_privot_toggled(pressed): |
|||
camera.rotate_privot = pressed |
|||
|
|||
func _on_box_distance_value_changed(value): |
|||
camera.distance = value |
|||
|
|||
func _on_box_yaw_value_changed(value): |
|||
camera.yaw_limit = value |
|||
|
|||
func _on_box_pitch_value_changed(value): |
|||
camera.pitch_limit = value |
|||
|
|||
func _on_btn_collisions_toggled(pressed): |
|||
camera.collisions = pressed |
|||
|
|||
func _on_btn_movement_toggled(pressed): |
|||
camera.movement = pressed |
|||
|
|||
func _on_hsb_speed_value_changed(value): |
|||
camera.max_speed.x = value |
|||
camera.max_speed.y = value |
|||
camera.max_speed.z = value |
|||
|
|||
func _in_hsb_acceleration_value_changed(value): |
|||
camera.acceleration = value |
|||
|
|||
func _in_hsb_deceleration_value_changed(value): |
|||
camera.deceleration = value |
@ -0,0 +1,46 @@ |
|||
extends Spatial |
|||
|
|||
var player:PathPlayerBase |
|||
|
|||
var overspeed_rate:float = 0.8 |
|||
var underspeed_rate:float = 0.8 |
|||
|
|||
func _ready(): |
|||
randomize() |
|||
|
|||
func _physics_process(delta): |
|||
if is_network_master() && player != null: |
|||
if player.is_out: |
|||
if player.is_resetable: |
|||
player.reset() |
|||
else: |
|||
if player.get_road() != null: |
|||
var rate = randf() |
|||
var road = player.get_road() |
|||
var distance = player.follow.get_offset() |
|||
var speed = player.current_speed |
|||
var has_constrain = false |
|||
for index in range(road.speed_constrains.size()): |
|||
var constrain = road.speed_constrains[index] |
|||
if constrain.x <= distance && constrain.y >= distance: |
|||
has_constrain = true |
|||
if constrain.z > 0 && speed < constrain.z && rate > underspeed_rate: |
|||
player.current_speed += player.speed_factor |
|||
elif player.current_speed > 0 && rate > overspeed_rate: |
|||
player.current_speed -= player.speed_factor * player.brake_factor |
|||
if not has_constrain: |
|||
if player.current_speed <= player.MAX_SPEED && rate > underspeed_rate: |
|||
player.current_speed += player.speed_factor |
|||
elif player.current_speed > 0 && rate > overspeed_rate: |
|||
player.current_speed -= player.speed_factor * player.brake_factor |
|||
if player.current_speed < 0: |
|||
player.current_speed = 0 |
|||
|
|||
func set_player(path:String): |
|||
player = get_node(path) |
|||
|
|||
func set_overspeed_rate(new_overspeed_rate:float): |
|||
overspeed_rate = new_overspeed_rate |
|||
|
|||
func set_underspeed_rate(new_underspeed_rate:float): |
|||
underspeed_rate = new_underspeed_rate |
@ -1,19 +0,0 @@ |
|||
extends MeshInstance |
|||
|
|||
var old_rotation = 0 |
|||
|
|||
func _process(delta): |
|||
var parent_rotation = get_parent().get_parent().get_rotation_degrees().y |
|||
var rotation = (int(parent_rotation * 10) % 225 ) / 10 |
|||
|
|||
if parent_rotation < 0: |
|||
rotation *= -1 |
|||
|
|||
if rotation > old_rotation: |
|||
rotation += rotation - old_rotation |
|||
else: |
|||
rotation -= old_rotation - rotation |
|||
|
|||
old_rotation = rotation |
|||
|
|||
#set_rotation_degrees(Vector3(0,rotation,0)) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue