Compare commits
No commits in common. "a7be9cd657faab769389fdb69158d160d938dd54" and "4439da747fe86dca43590be0639038e9c6829c85" have entirely different histories.
a7be9cd657
...
4439da747f
Binary file not shown.
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=20 format=2]
|
[gd_scene load_steps=18 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://Tile Sets/SnowySlopes.tres" type="TileSet" id=1]
|
[ext_resource path="res://Tile Sets/SnowySlopes.tres" type="TileSet" id=1]
|
||||||
[ext_resource path="res://Units/DownhillAutoscrollerPlayer.tscn" type="PackedScene" id=2]
|
[ext_resource path="res://Units/DownhillAutoscrollerPlayer.tscn" type="PackedScene" id=2]
|
||||||
|
@ -14,8 +14,6 @@
|
||||||
[ext_resource path="res://Fonts/squares/squares.tres" type="DynamicFont" id=12]
|
[ext_resource path="res://Fonts/squares/squares.tres" type="DynamicFont" id=12]
|
||||||
[ext_resource path="res://Scripts/InGameUI.gd" type="Script" id=13]
|
[ext_resource path="res://Scripts/InGameUI.gd" type="Script" id=13]
|
||||||
[ext_resource path="res://Fonts/squares/squares_big.tres" type="DynamicFont" id=14]
|
[ext_resource path="res://Fonts/squares/squares_big.tres" type="DynamicFont" id=14]
|
||||||
[ext_resource path="res://Scripts/Units/FollowReplay.gd" type="Script" id=15]
|
|
||||||
[ext_resource path="res://Scripts/PlayerRecorder.gd" type="Script" id=16]
|
|
||||||
|
|
||||||
[sub_resource type="Animation" id=3]
|
[sub_resource type="Animation" id=3]
|
||||||
resource_name = "InitialFade"
|
resource_name = "InitialFade"
|
||||||
|
@ -123,17 +121,11 @@ position = Vector2( 91, -197 )
|
||||||
offset = Vector2( 0, -15 )
|
offset = Vector2( 0, -15 )
|
||||||
smoothing_speed = 7.0
|
smoothing_speed = 7.0
|
||||||
|
|
||||||
[node name="PlayerRecorder" type="Node" parent="Player"]
|
|
||||||
script = ExtResource( 16 )
|
|
||||||
save_to = "res://Replays/ReplayOutput.dat"
|
|
||||||
|
|
||||||
[node name="SpectatorCam" type="Camera2D" parent="."]
|
[node name="SpectatorCam" type="Camera2D" parent="."]
|
||||||
offset = Vector2( 0, -15 )
|
offset = Vector2( 0, -15 )
|
||||||
|
|
||||||
[node name="Rival" parent="." instance=ExtResource( 6 )]
|
[node name="Rival" parent="." instance=ExtResource( 6 )]
|
||||||
position = Vector2( 91, -197 )
|
position = Vector2( 91, -197 )
|
||||||
script = ExtResource( 15 )
|
|
||||||
replay_file = "res://Replays/Rival.dat"
|
|
||||||
|
|
||||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||||
script = ExtResource( 13 )
|
script = ExtResource( 13 )
|
||||||
|
|
|
@ -16,6 +16,7 @@ export var target_time : float
|
||||||
export var defeat_cutscene : String
|
export var defeat_cutscene : String
|
||||||
export var victory_cutscene : String
|
export var victory_cutscene : String
|
||||||
const Constants = preload("res://Scripts/Constants.gd")
|
const Constants = preload("res://Scripts/Constants.gd")
|
||||||
|
const Unit = preload("res://Scripts/Unit.gd")
|
||||||
const UNIT_DIRECTORY = {
|
const UNIT_DIRECTORY = {
|
||||||
Constants.UnitType.CIRNO: preload("res://Units/DownhillAutoscrollerNPCCirno.tscn"),
|
Constants.UnitType.CIRNO: preload("res://Units/DownhillAutoscrollerNPCCirno.tscn"),
|
||||||
Constants.UnitType.SANAE: preload("res://Units/DownhillAutoscrollerNPCSanae.tscn"),
|
Constants.UnitType.SANAE: preload("res://Units/DownhillAutoscrollerNPCSanae.tscn"),
|
||||||
|
@ -63,24 +64,22 @@ var rng = RandomNumberGenerator.new()
|
||||||
func _ready():
|
func _ready():
|
||||||
MusicController.play_kyouko_snow()
|
MusicController.play_kyouko_snow()
|
||||||
|
|
||||||
units.append($Player)
|
units.append(get_node("Player"))
|
||||||
player = units[0]
|
player = units[0]
|
||||||
player.init_unit_w_scene(self)
|
player.init_unit_w_scene(self)
|
||||||
player_cam = $Player/Camera2D
|
player_cam = player.get_node("Camera2D")
|
||||||
player_cam.make_current()
|
player_cam.make_current()
|
||||||
player_cam.offset_v = camera_v_offset
|
player_cam.offset_v = camera_v_offset
|
||||||
|
|
||||||
units.append($Rival)
|
units.append(get_node("Rival"))
|
||||||
$Rival.init_unit_w_scene(self)
|
get_node("Rival").init_unit_w_scene(self)
|
||||||
|
|
||||||
stage_env = load("res://Scripts/StageEnvironment.gd").new(self)
|
stage_env = load("res://Scripts/StageEnvironment.gd").new(self)
|
||||||
$Player/Camera2D.make_current()
|
player.get_node("Camera2D").make_current()
|
||||||
for spawning_key in spawning:
|
for spawning_key in spawning:
|
||||||
spawning_map[spawning_key] = null
|
spawning_map[spawning_key] = null
|
||||||
|
|
||||||
find_node("PitTransitionPlayer").play("InitialFade")
|
find_node("PitTransitionPlayer").play("InitialFade")
|
||||||
|
|
||||||
target_time = $Rival.replay.length()
|
|
||||||
|
|
||||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
|
@ -108,10 +107,6 @@ func _process(delta):
|
||||||
|
|
||||||
if not race_over and player.pos.x >= finish_x_pos:
|
if not race_over and player.pos.x >= finish_x_pos:
|
||||||
race_over = true
|
race_over = true
|
||||||
|
|
||||||
if is_instance_valid(player.recorder):
|
|
||||||
player.recorder.save()
|
|
||||||
|
|
||||||
if time_elapsed_in_race > target_time:
|
if time_elapsed_in_race > target_time:
|
||||||
# lost race
|
# lost race
|
||||||
get_tree().change_scene("res://Scenes/" + defeat_cutscene + ".tscn")
|
get_tree().change_scene("res://Scenes/" + defeat_cutscene + ".tscn")
|
||||||
|
|
|
@ -21,16 +21,18 @@ var timer : RichTextLabel
|
||||||
func _ready():
|
func _ready():
|
||||||
scene = get_node("/root/Scene")
|
scene = get_node("/root/Scene")
|
||||||
player = get_node("/root/Scene/Player")
|
player = get_node("/root/Scene/Player")
|
||||||
speedometer = $Speedometer
|
speedometer = get_node("Speedometer")
|
||||||
timer = $Timer
|
timer = get_node("Timer")
|
||||||
boost_label = $BoostLabel
|
boost_label = get_node("BoostLabel")
|
||||||
|
|
||||||
|
|
||||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
speedometer.text = " %d MPH" % scene.player_speed_mph
|
speedometer.text = str(floor(scene.player_speed_mph)) + " MPH"
|
||||||
|
|
||||||
timer.text = (" %05.2f" % scene.time_elapsed_in_race).replace(".", ":")
|
var dec_value : int = floor((scene.time_elapsed_in_race - floor(scene.time_elapsed_in_race))
|
||||||
|
* 100)
|
||||||
|
timer.text = str(floor(scene.time_elapsed_in_race)) + ":" + str(dec_value)
|
||||||
|
|
||||||
if player.get_current_action() == Constants.UnitCurrentAction.SPINNING:
|
if player.get_current_action() == Constants.UnitCurrentAction.SPINNING:
|
||||||
flash_boost = false
|
flash_boost = false
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
extends Node
|
|
||||||
class_name PlayerRecorder
|
|
||||||
|
|
||||||
var replay: ReplayRecording
|
|
||||||
var this_frame: bool = true
|
|
||||||
var sprite: int = 0
|
|
||||||
var player: Node
|
|
||||||
var scene: Node
|
|
||||||
|
|
||||||
export var save_to: String
|
|
||||||
export var enabled: bool
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
if not enabled:
|
|
||||||
queue_free()
|
|
||||||
|
|
||||||
replay = ReplayRecording.new()
|
|
||||||
replay.time_per_frame = 1.0 / 30.0
|
|
||||||
player = get_parent()
|
|
||||||
player.recorder = self
|
|
||||||
scene = player.get_parent()
|
|
||||||
|
|
||||||
func _process(_delta):
|
|
||||||
if this_frame:
|
|
||||||
this_frame = false
|
|
||||||
replay.positions.append(player.pos)
|
|
||||||
replay.sprites.append(sprite)
|
|
||||||
replay.frames += 1
|
|
||||||
|
|
||||||
else:
|
|
||||||
this_frame = true
|
|
||||||
|
|
||||||
func save():
|
|
||||||
replay.save_to_uri(save_to)
|
|
||||||
queue_free()
|
|
|
@ -1,58 +0,0 @@
|
||||||
extends Object
|
|
||||||
class_name ReplayRecording
|
|
||||||
|
|
||||||
const TAPER: float = 7.0
|
|
||||||
|
|
||||||
var time_per_frame: float
|
|
||||||
var frames: int = 0
|
|
||||||
|
|
||||||
var positions: Array
|
|
||||||
var sprites: Array
|
|
||||||
|
|
||||||
func load_from(file: File):
|
|
||||||
time_per_frame = file.get_real()
|
|
||||||
frames = file.get_32()
|
|
||||||
positions = []
|
|
||||||
sprites = []
|
|
||||||
|
|
||||||
for _i in range(frames):
|
|
||||||
var x: float = file.get_real()
|
|
||||||
var y: float = file.get_real()
|
|
||||||
positions.append(Vector2(x, y))
|
|
||||||
sprites.append(file.get_8())
|
|
||||||
|
|
||||||
func load_from_uri(uri: String):
|
|
||||||
var file: File = File.new()
|
|
||||||
file.open(uri, File.READ)
|
|
||||||
load_from(file)
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
func save_to(file: File):
|
|
||||||
file.store_real(time_per_frame)
|
|
||||||
file.store_32(frames)
|
|
||||||
|
|
||||||
for i in range(frames):
|
|
||||||
file.store_real(positions[i].x)
|
|
||||||
file.store_real(positions[i].y)
|
|
||||||
file.store_8(sprites[i])
|
|
||||||
|
|
||||||
func save_to_uri(uri: String):
|
|
||||||
var file: File = File.new()
|
|
||||||
file.open(uri, File.WRITE)
|
|
||||||
save_to(file)
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
func position(frame: int) -> Vector2:
|
|
||||||
if frame < frames:
|
|
||||||
return positions[frame]
|
|
||||||
else:
|
|
||||||
return lerp(positions[-2], positions[-1], 2 + TAPER * atan((frame - frames) / TAPER))
|
|
||||||
|
|
||||||
func sprite(frame: int) -> int:
|
|
||||||
if frame < frames:
|
|
||||||
return sprites[frame]
|
|
||||||
else:
|
|
||||||
return sprites[-1]
|
|
||||||
|
|
||||||
func length() -> float:
|
|
||||||
return time_per_frame * frames
|
|
|
@ -35,8 +35,6 @@ var time_elapsed : float
|
||||||
var is_flash : bool = false
|
var is_flash : bool = false
|
||||||
var flash_start_timestamp : float
|
var flash_start_timestamp : float
|
||||||
|
|
||||||
var recorder: PlayerRecorder = null
|
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time
|
# Called when the node enters the scene tree for the first time
|
||||||
func _ready():
|
func _ready():
|
||||||
for action_num in Constants.UNIT_TYPE_ACTIONS[unit_type]:
|
for action_num in Constants.UNIT_TYPE_ACTIONS[unit_type]:
|
||||||
|
@ -238,22 +236,13 @@ func handle_idle():
|
||||||
else:
|
else:
|
||||||
set_sprite(Constants.SpriteClass.JUMP, 1)
|
set_sprite(Constants.SpriteClass.JUMP, 1)
|
||||||
|
|
||||||
func set_sprite(sprite_class: int, index: int = 0, ignore_bad_values: bool = false):
|
func set_sprite(sprite_class : int, index : int = 0):
|
||||||
if ignore_bad_values:
|
|
||||||
if not(unit_type in Constants.UNIT_SPRITES) or not(sprite_class in Constants.UNIT_SPRITES[unit_type]):
|
|
||||||
return
|
|
||||||
|
|
||||||
assert(unit_type in Constants.UNIT_SPRITES)
|
assert(unit_type in Constants.UNIT_SPRITES)
|
||||||
assert(sprite_class in Constants.UNIT_SPRITES[unit_type])
|
assert(sprite_class in Constants.UNIT_SPRITES[unit_type])
|
||||||
|
|
||||||
var node_list = sprite_class_nodes[sprite_class]
|
var node_list = sprite_class_nodes[sprite_class]
|
||||||
var true_index : int = index
|
var true_index : int = index
|
||||||
if true_index > len(node_list) - 1:
|
if true_index > len(node_list) - 1:
|
||||||
true_index = 0
|
true_index = 0
|
||||||
|
|
||||||
if is_instance_valid(recorder):
|
|
||||||
recorder.sprite = (index << 3) | sprite_class
|
|
||||||
|
|
||||||
var new_sprite : Node2D = node_list[true_index]
|
var new_sprite : Node2D = node_list[true_index]
|
||||||
if (is_flash):
|
if (is_flash):
|
||||||
if int((time_elapsed - flash_start_timestamp) / Constants.FLASH_CYCLE) % 2 == 1:
|
if int((time_elapsed - flash_start_timestamp) / Constants.FLASH_CYCLE) % 2 == 1:
|
||||||
|
|
|
@ -19,6 +19,7 @@ var jump_audiostream_player : AudioStreamPlayer
|
||||||
var land_audiostream_player : AudioStreamPlayer
|
var land_audiostream_player : AudioStreamPlayer
|
||||||
var snow_audiostream_player : AudioStreamPlayer
|
var snow_audiostream_player : AudioStreamPlayer
|
||||||
|
|
||||||
|
|
||||||
func init_unit_w_scene(scene):
|
func init_unit_w_scene(scene):
|
||||||
.init_unit_w_scene(scene)
|
.init_unit_w_scene(scene)
|
||||||
hit_audiostream_player = scene.get_node("HitAudioStreamPlayer")
|
hit_audiostream_player = scene.get_node("HitAudioStreamPlayer")
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
extends Unit
|
|
||||||
|
|
||||||
var replay : ReplayRecording = null
|
|
||||||
|
|
||||||
export var replay_file: String
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
._ready()
|
|
||||||
replay = ReplayRecording.new()
|
|
||||||
replay.load_from_uri(replay_file)
|
|
||||||
|
|
||||||
|
|
||||||
func process_unit(delta : float, time_elapsed : float):
|
|
||||||
self.time_elapsed = time_elapsed
|
|
||||||
|
|
||||||
if replay != null and replay.time_per_frame > 0:
|
|
||||||
handle_replay(time_elapsed)
|
|
||||||
|
|
||||||
func handle_replay(at_time: float):
|
|
||||||
var frame: int = int(at_time / replay.time_per_frame)
|
|
||||||
var subframe: float = (at_time / replay.time_per_frame) - frame
|
|
||||||
|
|
||||||
pos = lerp(replay.position(frame), replay.position(frame + 1), subframe)
|
|
||||||
|
|
||||||
var sprite: int = replay.sprite(frame)
|
|
||||||
var index: int = sprite >> 3
|
|
||||||
sprite &= 7
|
|
||||||
|
|
||||||
set_sprite(sprite, index, true)
|
|
|
@ -17,7 +17,5 @@ force/max_rate=false
|
||||||
force/max_rate_hz=44100
|
force/max_rate_hz=44100
|
||||||
edit/trim=false
|
edit/trim=false
|
||||||
edit/normalize=false
|
edit/normalize=false
|
||||||
edit/loop_mode=0
|
edit/loop=false
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=0
|
compress/mode=0
|
||||||
|
|
|
@ -17,7 +17,5 @@ force/max_rate=false
|
||||||
force/max_rate_hz=44100
|
force/max_rate_hz=44100
|
||||||
edit/trim=false
|
edit/trim=false
|
||||||
edit/normalize=false
|
edit/normalize=false
|
||||||
edit/loop_mode=0
|
edit/loop=false
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=0
|
compress/mode=0
|
||||||
|
|
|
@ -34,16 +34,6 @@ _global_script_classes=[ {
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://Scripts/Units/Player.gd"
|
"path": "res://Scripts/Units/Player.gd"
|
||||||
}, {
|
}, {
|
||||||
"base": "Node",
|
|
||||||
"class": "PlayerRecorder",
|
|
||||||
"language": "GDScript",
|
|
||||||
"path": "res://Scripts/PlayerRecorder.gd"
|
|
||||||
}, {
|
|
||||||
"base": "Object",
|
|
||||||
"class": "ReplayRecording",
|
|
||||||
"language": "GDScript",
|
|
||||||
"path": "res://Scripts/ReplayRecording.gd"
|
|
||||||
}, {
|
|
||||||
"base": "Area2D",
|
"base": "Area2D",
|
||||||
"class": "Unit",
|
"class": "Unit",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
|
@ -55,8 +45,6 @@ _global_script_class_icons={
|
||||||
"NPCExample": "",
|
"NPCExample": "",
|
||||||
"NPCUnit": "",
|
"NPCUnit": "",
|
||||||
"Player": "",
|
"Player": "",
|
||||||
"PlayerRecorder": "",
|
|
||||||
"ReplayRecording": "",
|
|
||||||
"Unit": ""
|
"Unit": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue