Replays in game

This commit is contained in:
gemdude46 2023-01-30 10:12:53 +00:00
parent 09c9809e94
commit 5031122edd
8 changed files with 59 additions and 29 deletions

BIN
Replays/Rival.dat Normal file

Binary file not shown.

View File

@ -1,8 +1,4 @@
<<<<<<< HEAD [gd_scene load_steps=20 format=2]
[gd_scene load_steps=17 format=2]
=======
[gd_scene load_steps=18 format=2]
>>>>>>> e02aaa26c207234404f2d1f585dca170392fddfe
[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]
@ -18,6 +14,8 @@
[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"
@ -126,15 +124,16 @@ offset = Vector2( 0, -15 )
smoothing_speed = 7.0 smoothing_speed = 7.0
[node name="PlayerRecorder" type="Node" parent="Player"] [node name="PlayerRecorder" type="Node" parent="Player"]
script = ExtResource( 13 ) 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( 12 ) script = ExtResource( 15 )
unit_type = 0 replay_file = "res://Replays/Rival.dat"
[node name="CanvasLayer" type="CanvasLayer" parent="."] [node name="CanvasLayer" type="CanvasLayer" parent="."]
script = ExtResource( 13 ) script = ExtResource( 13 )

View File

@ -16,7 +16,6 @@ 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"),
@ -64,23 +63,25 @@ var rng = RandomNumberGenerator.new()
func _ready(): func _ready():
MusicController.play_kyouko_snow() MusicController.play_kyouko_snow()
units.append(get_node("Player")) units.append($Player)
player = units[0] player = units[0]
player.init_unit_w_scene(self) player.init_unit_w_scene(self)
player_cam = player.get_node("Camera2D") player_cam = $Player/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(get_node("Rival")) units.append($Rival)
get_node("Rival").init_unit_w_scene(self) $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.get_node("Camera2D").make_current() $Player/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):
# visual effects # visual effects
@ -107,6 +108,10 @@ 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")

View File

@ -21,18 +21,16 @@ 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 = get_node("Speedometer") speedometer = $Speedometer
timer = get_node("Timer") timer = $Timer
boost_label = get_node("BoostLabel") boost_label = $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 = str(floor(scene.player_speed_mph)) + " MPH" speedometer.text = " %d MPH" % scene.player_speed_mph
var dec_value : int = floor((scene.time_elapsed_in_race - floor(scene.time_elapsed_in_race)) timer.text = (" %05.2f" % scene.time_elapsed_in_race).replace(".", ":")
* 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

View File

@ -4,17 +4,23 @@ class_name PlayerRecorder
var replay: ReplayRecording var replay: ReplayRecording
var this_frame: bool = true var this_frame: bool = true
var sprite: int = 0 var sprite: int = 0
var player: DownhillAutoscrollerPlayer var player: Node
var scene: Node
export var save_to: String export var save_to: String
export var enabled: bool
func _ready(): func _ready():
if not enabled:
queue_free()
replay = ReplayRecording.new() replay = ReplayRecording.new()
replay.time_per_frame = 1.0 / 30.0 replay.time_per_frame = 1.0 / 30.0
player = get_parent() player = get_parent()
player.recorder = self player.recorder = self
scene = player.get_parent()
func _process(delta): func _process(_delta):
if this_frame: if this_frame:
this_frame = false this_frame = false
replay.positions.append(player.pos) replay.positions.append(player.pos)
@ -23,3 +29,7 @@ func _process(delta):
else: else:
this_frame = true this_frame = true
func save():
replay.save_to_uri(save_to)
queue_free()

View File

@ -1,6 +1,8 @@
extends Object extends Object
class_name ReplayRecording class_name ReplayRecording
const TAPER: float = 7.0
var time_per_frame: float var time_per_frame: float
var frames: int = 0 var frames: int = 0
@ -13,7 +15,7 @@ func load_from(file: File):
positions = [] positions = []
sprites = [] sprites = []
for i in range(frames): for _i in range(frames):
var x: float = file.get_real() var x: float = file.get_real()
var y: float = file.get_real() var y: float = file.get_real()
positions.append(Vector2(x, y)) positions.append(Vector2(x, y))
@ -44,10 +46,13 @@ func position(frame: int) -> Vector2:
if frame < frames: if frame < frames:
return positions[frame] return positions[frame]
else: else:
return positions[-1] return lerp(positions[-2], positions[-1], 2 + TAPER * atan((frame - frames) / TAPER))
func sprite(frame: int) -> int: func sprite(frame: int) -> int:
if frame < frames: if frame < frames:
return sprites[frame] return sprites[frame]
else: else:
return sprites[-1] return sprites[-1]
func length() -> float:
return time_per_frame * frames

View File

@ -238,15 +238,20 @@ 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): func set_sprite(sprite_class: int, index: int = 0, ignore_bad_values: bool = false):
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 recorder != null: if is_instance_valid(recorder):
recorder.sprite = (index << 3) | sprite_class recorder.sprite = (index << 3) | sprite_class
var new_sprite : Node2D = node_list[true_index] var new_sprite : Node2D = node_list[true_index]

View File

@ -2,10 +2,18 @@ extends Unit
var replay : ReplayRecording = null 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): func process_unit(delta : float, time_elapsed : float):
self.time_elapsed = time_elapsed self.time_elapsed = time_elapsed
if replay != null: if replay != null and replay.time_per_frame > 0:
handle_replay(time_elapsed) handle_replay(time_elapsed)
func handle_replay(at_time: float): func handle_replay(at_time: float):
@ -18,4 +26,4 @@ func handle_replay(at_time: float):
var index: int = sprite >> 3 var index: int = sprite >> 3
sprite &= 7 sprite &= 7
set_sprite(sprite, index) set_sprite(sprite, index, true)