Intial commit
This commit is contained in:
67
client/Scripts/Component/Speaker.gd
Normal file
67
client/Scripts/Component/Speaker.gd
Normal file
@ -0,0 +1,67 @@
|
||||
extends Node
|
||||
|
||||
signal updated_text
|
||||
signal finished_text
|
||||
signal message_list_empty
|
||||
|
||||
func speak(message):
|
||||
spoken_text = ""
|
||||
for character in message:
|
||||
soundQueue.append(character)
|
||||
play_audio()
|
||||
|
||||
var message_list = []
|
||||
func speak_lines(list_of_messages : Array = []):
|
||||
message_list = message_list + list_of_messages
|
||||
if len(message_list) > 0:
|
||||
speak(message_list.pop_front())
|
||||
else:
|
||||
emit_signal("message_list_empty")
|
||||
|
||||
var audio_player : AudioStreamPlayer
|
||||
var speaking_timer : Timer
|
||||
var speaker = "default"
|
||||
var soundQueue = []
|
||||
var spoken_text = ""
|
||||
var playing_speech = false
|
||||
export var voice_pitch : float = 1
|
||||
|
||||
func play_audio():
|
||||
playing_speech = true
|
||||
if not audio_player:
|
||||
audio_player = AudioStreamPlayer.new()
|
||||
add_child(audio_player)
|
||||
if not speaking_timer:
|
||||
speaking_timer = Timer.new()
|
||||
speaking_timer.connect("timeout", self, "play_audio")
|
||||
add_child(speaking_timer)
|
||||
|
||||
audio_player.pitch_scale = voice_pitch
|
||||
|
||||
if len(soundQueue) > 0:
|
||||
var letter = soundQueue.pop_front()
|
||||
var audio_file = "res://Assets/Sfx/Speakers/" + speaker + ".wav"
|
||||
var track : AudioStream
|
||||
|
||||
spoken_text = spoken_text + letter
|
||||
emit_signal("updated_text")
|
||||
|
||||
if letter in " ,-'\"\n":
|
||||
speaking_timer.start(0.05)
|
||||
return
|
||||
elif letter in ".!":
|
||||
speaking_timer.start(0.15)
|
||||
return
|
||||
elif File.new().file_exists(audio_file):
|
||||
track = load(audio_file)
|
||||
audio_player.stream = track
|
||||
audio_player.play()
|
||||
speaking_timer.start(track.get_length())
|
||||
else:
|
||||
print("No sound for: " + str(speaker))
|
||||
else:
|
||||
playing_speech = false
|
||||
emit_signal("finished_text")
|
||||
|
||||
func del_obj(obj):
|
||||
obj.queue_free()
|
76
client/Scripts/Component/StorySpeaker.gd
Normal file
76
client/Scripts/Component/StorySpeaker.gd
Normal file
@ -0,0 +1,76 @@
|
||||
extends "res://Scripts/Component/Speaker.gd"
|
||||
|
||||
const Story_Reader_Class = preload("res://addons/EXP-System-Dialog/Reference_StoryReader/EXP_StoryReader.gd")
|
||||
const story_file = preload("res://Assets/Stories/english_story.tres")
|
||||
var story_reader = Story_Reader_Class.new()
|
||||
|
||||
var gui
|
||||
|
||||
var nid : int = 1
|
||||
var did : int
|
||||
var choices : int = 1
|
||||
var selected_choice : int = -1
|
||||
export var speaker_name = ""
|
||||
|
||||
|
||||
func _ready():
|
||||
story_reader.read(story_file)
|
||||
|
||||
connect("updated_text", self, "_on_text_update")
|
||||
connect("finished_text", self, "_on_finish_text")
|
||||
|
||||
func _on_finish_text():
|
||||
gui.show_choices()
|
||||
|
||||
func _on_text_update():
|
||||
gui.set_dialog(spoken_text, speaker_name)
|
||||
|
||||
func start_dialog(record : String):
|
||||
start_dialog_did(story_reader.get_did_via_record_name(record))
|
||||
|
||||
func start_dialog_did(dialog_id : int):
|
||||
gui = get_node("/root/World/GUI")
|
||||
|
||||
nid = 1
|
||||
did = dialog_id
|
||||
|
||||
process_message(story_reader.get_text(did, nid))
|
||||
|
||||
func has_next_node():
|
||||
return story_reader.has_slot(did, nid, 0)
|
||||
|
||||
func process_message(message):
|
||||
gui.clear_choices()
|
||||
selected_choice = -1
|
||||
choices = message.count("<choice>")
|
||||
if choices > 0:
|
||||
var i = 0
|
||||
var last = ""
|
||||
while i < choices:
|
||||
var start = message.find("<choice>")
|
||||
var end = message.find("</choice>")
|
||||
if start != -1 and end != -1:
|
||||
var choice_text = message.substr( start+len("<choice>"), end-start-len("</choice>")+1 )
|
||||
if choice_text == last:
|
||||
printerr("Choice in did " + str(did) + ", nid " + str(nid) + " not closed!")
|
||||
break
|
||||
else:
|
||||
gui.add_choice(self, i, choice_text)
|
||||
message = message.replace("<choice>"+choice_text+"</choice>", "")
|
||||
i = i + 1
|
||||
|
||||
speak(message)
|
||||
|
||||
func _on_choice(decision):
|
||||
move_dialog_forward(decision)
|
||||
|
||||
func move_dialog_forward(decision = 0):
|
||||
if has_next_node():
|
||||
nid = story_reader.get_nid_from_slot(did, nid, decision)
|
||||
process_message(story_reader.get_text(did, nid))
|
||||
else:
|
||||
gui.finish_dialog()
|
||||
|
||||
func _process(delta):
|
||||
if(Input.is_action_just_pressed("ui_accept") and choices == 0 and playing_speech == false):
|
||||
move_dialog_forward(0)
|
59
client/Scripts/Entities/Fader.gd
Normal file
59
client/Scripts/Entities/Fader.gd
Normal file
@ -0,0 +1,59 @@
|
||||
extends ColorRect
|
||||
|
||||
signal fade_complete
|
||||
|
||||
export var fade_on_start : bool = false
|
||||
export var start_with_fade_in : bool = true
|
||||
export var fade_time : float = 1
|
||||
|
||||
func _ready():
|
||||
|
||||
if fade_on_start:
|
||||
# Fade on start, if enabled
|
||||
fade(fade_time, start_with_fade_in)
|
||||
else:
|
||||
# Retain visibility
|
||||
if self.visible:
|
||||
modulate.a = 1
|
||||
else:
|
||||
modulate.a = 0
|
||||
|
||||
self.show()
|
||||
|
||||
var timePassed = 0 #Current amount of time spend displaying te
|
||||
const CHECK_LENGTH = 0.05 #Interval to check for updates
|
||||
var timeNeeded = 0 #Time it takes to fade out
|
||||
var fadeTimer #Timer object
|
||||
|
||||
var fading_in = false
|
||||
|
||||
func fade(seconds, fade_in = false):
|
||||
fading_in = fade_in
|
||||
|
||||
# Set timer values
|
||||
timeNeeded = seconds
|
||||
timePassed = 0
|
||||
|
||||
# Create timer if needed
|
||||
if(!fadeTimer):
|
||||
fadeTimer = Timer.new()
|
||||
add_child(fadeTimer)
|
||||
fadeTimer.connect("timeout", self, "on_fade_timeout")
|
||||
|
||||
# Start fader with tick speed of `CHECK_LENGTH`
|
||||
fadeTimer.start(CHECK_LENGTH)
|
||||
|
||||
func on_fade_timeout():
|
||||
timePassed += CHECK_LENGTH
|
||||
|
||||
# Set modulate
|
||||
if fading_in:
|
||||
modulate.a = 1 - abs(timePassed/timeNeeded)
|
||||
else:
|
||||
modulate.a = abs(timePassed/timeNeeded)
|
||||
|
||||
if(timePassed >= timeNeeded):
|
||||
fadeTimer.stop()
|
||||
emit_signal("fade_complete")
|
||||
else:
|
||||
fadeTimer.start(CHECK_LENGTH)
|
7
client/Scripts/Entities/NPCs/IntroScientist.gd
Normal file
7
client/Scripts/Entities/NPCs/IntroScientist.gd
Normal file
@ -0,0 +1,7 @@
|
||||
extends "res://Scripts/Component/StorySpeaker.gd"
|
||||
|
||||
func _ready():
|
||||
start_dialog("intro_science")
|
||||
|
||||
func _on_interact():
|
||||
start_dialog("intro_science_followup")
|
59
client/Scripts/Entities/Player.gd
Normal file
59
client/Scripts/Entities/Player.gd
Normal file
@ -0,0 +1,59 @@
|
||||
extends KinematicBody2D
|
||||
|
||||
# Environment variables
|
||||
export var baseGravity : float = 9.8
|
||||
|
||||
# Player movment variables
|
||||
export var maxMoveVelocity : float = 300
|
||||
export var moveAcceleration : float = 15
|
||||
export var moveFriction : float = 45
|
||||
export var jumpVelocity : float = -150
|
||||
|
||||
var moveMotion : float = 0 # Player Input ( <- & -> )
|
||||
var motion : Vector2 = Vector2(0,0) # Player's current velocity
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
|
||||
# Gravity
|
||||
motion.y += baseGravity
|
||||
if is_on_floor():
|
||||
motion.y = 0
|
||||
|
||||
user_input()
|
||||
|
||||
# Apply velocity limits
|
||||
moveMotion = clamp(moveMotion, -maxMoveVelocity, maxMoveVelocity)
|
||||
|
||||
# Apply velocity to frame
|
||||
motion.x = moveMotion
|
||||
animation_manager(moveMotion)
|
||||
move_and_slide(motion, Vector2(0,-1))
|
||||
|
||||
|
||||
func user_input():
|
||||
if(Input.is_action_pressed("ui_left")):
|
||||
moveMotion -= moveAcceleration
|
||||
if(Input.is_action_pressed("ui_right")):
|
||||
moveMotion += moveAcceleration
|
||||
|
||||
if(is_on_floor() and Input.is_action_just_pressed("ui_up")):
|
||||
motion.y = jumpVelocity
|
||||
|
||||
if is_on_floor() and (!Input.is_action_pressed("ui_left") and !Input.is_action_pressed("ui_right")):
|
||||
if moveMotion > 0:
|
||||
moveMotion = clamp(moveMotion - moveFriction, 0, moveMotion)
|
||||
elif moveMotion < 0:
|
||||
moveMotion = clamp(moveMotion + moveFriction, moveMotion, 0)
|
||||
|
||||
func animation_manager(motion : float):
|
||||
|
||||
if moveMotion > 0:
|
||||
$AnimationPlayer.playback_speed = abs(motion)/200
|
||||
$AnimationPlayer.play("RunRight")
|
||||
elif moveMotion < 0:
|
||||
$AnimationPlayer.playback_speed = abs(motion)/200
|
||||
$AnimationPlayer.play("RunLeft")
|
||||
else:
|
||||
$AnimationPlayer.playback_speed = 1
|
||||
$AnimationPlayer.play("Idle")
|
51
client/Scripts/Singletons/IntroManager.gd
Normal file
51
client/Scripts/Singletons/IntroManager.gd
Normal file
@ -0,0 +1,51 @@
|
||||
extends "res://Scripts/Component/Speaker.gd"
|
||||
|
||||
|
||||
var Story_Reader_Class = preload("res://addons/EXP-System-Dialog/Reference_StoryReader/EXP_StoryReader.gd")
|
||||
var story_reader = Story_Reader_Class.new()
|
||||
|
||||
|
||||
var loading_game : bool = false
|
||||
var audio_clip_player : AudioStreamPlayer
|
||||
var audio_clip_one = preload("res://Assets/Sfx/intro/loading.wav")
|
||||
var audio_clip_two = preload("res://Assets/Sfx/intro/processed.wav")
|
||||
|
||||
var story_nid = 1
|
||||
const STORY_DID = 2
|
||||
|
||||
|
||||
|
||||
func _ready():
|
||||
var file = load("res://Assets/Stories/english_story.tres")
|
||||
story_reader.read(file)
|
||||
|
||||
|
||||
audio_clip_player = AudioStreamPlayer.new()
|
||||
add_child(audio_clip_player)
|
||||
|
||||
connect("updated_text", self, "update_text")
|
||||
|
||||
speak(story_reader.get_text(STORY_DID, story_nid))
|
||||
|
||||
func update_text():
|
||||
$CanvasLayer/Control/Label.text = spoken_text
|
||||
|
||||
func _process(delta):
|
||||
if(Input.is_action_just_pressed("ui_accept") and playing_speech == false):
|
||||
if story_reader.has_nid(STORY_DID, story_nid + 1):
|
||||
story_nid = story_nid + 1
|
||||
speak(story_reader.get_text(STORY_DID, story_nid))
|
||||
else:
|
||||
$CanvasLayer/Control/Label.text = ""
|
||||
if not loading_game:
|
||||
start_load_game()
|
||||
|
||||
func start_load_game():
|
||||
loading_game = true
|
||||
$"/root/MusicManager".stop_music()
|
||||
audio_clip_player.stream = audio_clip_one
|
||||
audio_clip_player.connect("finished", self, "_load_next_scene")
|
||||
audio_clip_player.play()
|
||||
|
||||
func _load_next_scene():
|
||||
get_tree().change_scene("res://Scenes/World.scn")
|
18
client/Scripts/Singletons/MusicManager.gd
Normal file
18
client/Scripts/Singletons/MusicManager.gd
Normal file
@ -0,0 +1,18 @@
|
||||
extends AudioStreamPlayer
|
||||
|
||||
var main_player : AudioStreamPlayer
|
||||
var looping : bool = false
|
||||
|
||||
func _ready():
|
||||
main_player = self
|
||||
|
||||
func play_music(song, loop=true):
|
||||
var audio_file = "res://Assets/Music/" + song + ".ogg"
|
||||
if File.new().file_exists(audio_file):
|
||||
var track = load(audio_file)
|
||||
looping = loop
|
||||
main_player.stream = track
|
||||
main_player.play()
|
||||
|
||||
func stop_music():
|
||||
main_player.stop()
|
6
client/Scripts/Singletons/TitleManager.tres.gd
Normal file
6
client/Scripts/Singletons/TitleManager.tres.gd
Normal file
@ -0,0 +1,6 @@
|
||||
extends Node
|
||||
|
||||
func _ready():
|
||||
$"/root/MusicManager".play_music("Dystopian/Dystopian")
|
||||
$Environment/AnimationPlayer.playback_speed = 0.25
|
||||
$Environment/AnimationPlayer.play("Floating")
|
17
client/Scripts/Singletons/WorldManager.gd
Normal file
17
client/Scripts/Singletons/WorldManager.gd
Normal file
@ -0,0 +1,17 @@
|
||||
extends Node
|
||||
|
||||
var audio_player : AudioStreamPlayer
|
||||
var gui_manager
|
||||
|
||||
#$"/root/MusicManager".play_music("Dystopian/The Protagonist")
|
||||
|
||||
func _ready():
|
||||
gui_manager = $GUI
|
||||
audio_player = AudioStreamPlayer.new()
|
||||
add_child(audio_player)
|
||||
$CanvasLayer/ColorRect.show()
|
||||
play_sound(preload("res://Assets/Sfx/intro/processed.wav"))
|
||||
|
||||
func play_sound(audio_stream):
|
||||
audio_player.stream = audio_stream
|
||||
audio_player.play()
|
33
client/Scripts/Systems/GameGui.gd
Normal file
33
client/Scripts/Systems/GameGui.gd
Normal file
@ -0,0 +1,33 @@
|
||||
extends CanvasLayer
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
func set_dialog(message, speaker=""):
|
||||
$Dialog.show()
|
||||
$Dialog/Textbox/Speaker.text = speaker
|
||||
$Dialog/Textbox/Body.text = message
|
||||
|
||||
func finish_dialog():
|
||||
$Dialog.hide()
|
||||
|
||||
func clear_choices():
|
||||
$Dialog/Choices.hide()
|
||||
for i in range($Dialog/Choices.get_child_count()):
|
||||
$Dialog/Choices.get_child(i).queue_free()
|
||||
|
||||
func add_choice(speaker : Node, choice_id : int, choice_text : String):
|
||||
var button = Button.new()
|
||||
button.text = choice_text
|
||||
button.connect("button_down", speaker, "_on_choice", [choice_id])
|
||||
$Dialog/Choices.add_child(button)
|
||||
|
||||
func show_choices():
|
||||
$Dialog/Choices.show()
|
31
client/Scripts/Systems/TitleButtons.gd
Normal file
31
client/Scripts/Systems/TitleButtons.gd
Normal file
@ -0,0 +1,31 @@
|
||||
extends Node
|
||||
|
||||
var audio_player : AudioStreamPlayer
|
||||
var audio_clip = preload("res://Assets/Sfx/button_press.wav")
|
||||
|
||||
|
||||
func _ready():
|
||||
audio_player = AudioStreamPlayer.new()
|
||||
add_child(audio_player)
|
||||
audio_player.stream = audio_clip
|
||||
|
||||
$StartButton.connect("button_down", self, "_on_button_press", ["start"])
|
||||
$QuitButton.connect("button_down", self, "_on_button_press", ["quit"])
|
||||
$CreditsButton.connect("button_down", self, "_on_button_press", ["credits"])
|
||||
$OptionsButton.connect("button_down", self, "_on_button_press", ["options"])
|
||||
$BugButton.connect("button_down", self, "_on_button_press", ["bug"])
|
||||
|
||||
|
||||
func _on_button_press(button):
|
||||
audio_player.play()
|
||||
match(button):
|
||||
"start":
|
||||
get_tree().change_scene("res://Scenes/Intro.scn")
|
||||
"quit":
|
||||
get_tree().quit(0)
|
||||
"credits":
|
||||
get_parent().get_parent().get_node("CreditsDialog").popup_centered()
|
||||
"options":
|
||||
get_parent().get_parent().get_node("OptionsDialog").popup_centered()
|
||||
"bug":
|
||||
OS.shell_open("https://github.com/josephbmanley")
|
Reference in New Issue
Block a user