From 7b5d84e662db9a7a67da1148fa12d7fc5117f7dd Mon Sep 17 00:00:00 2001 From: gemdude46 <> Date: Mon, 30 Jan 2023 08:56:47 +0000 Subject: [PATCH] Replay --- Scenes/DownhillAutoscroller.tscn | 9 +++- Scripts/PlayerRecorder.gd | 25 ++++++++++ Scripts/ReplayRecording.gd | 53 +++++++++++++++++++++ Scripts/Unit.gd | 6 +++ Scripts/Units/DownhillAutoscrollerPlayer.gd | 1 - Scripts/Units/FollowReplay.gd | 21 ++++++++ Sounds/Beep.wav.import | 4 +- Sounds/ski-67717.wav.import | 4 +- project.godot | 12 +++++ 9 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 Scripts/PlayerRecorder.gd create mode 100644 Scripts/ReplayRecording.gd create mode 100644 Scripts/Units/FollowReplay.gd diff --git a/Scenes/DownhillAutoscroller.tscn b/Scenes/DownhillAutoscroller.tscn index 6f2c6b4..99a23e8 100644 --- a/Scenes/DownhillAutoscroller.tscn +++ b/Scenes/DownhillAutoscroller.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=15 format=2] +[gd_scene load_steps=17 format=2] [ext_resource path="res://Tile Sets/SnowySlopes.tres" type="TileSet" id=1] [ext_resource path="res://Units/DownhillAutoscrollerPlayer.tscn" type="PackedScene" id=2] @@ -11,6 +11,8 @@ [ext_resource path="res://Sounds/sfx_jump_07-80241.mp3" type="AudioStream" id=9] [ext_resource path="res://Sounds/land2-43790.mp3" type="AudioStream" id=10] [ext_resource path="res://Sounds/ski-67717.wav" type="AudioStream" id=11] +[ext_resource path="res://Scripts/Units/FollowReplay.gd" type="Script" id=12] +[ext_resource path="res://Scripts/PlayerRecorder.gd" type="Script" id=13] [sub_resource type="Animation" id=3] resource_name = "InitialFade" @@ -114,11 +116,16 @@ position = Vector2( 91, -197 ) [node name="Camera2D" type="Camera2D" parent="Player"] offset = Vector2( 0, -15 ) +[node name="PlayerRecorder" type="Node" parent="Player"] +script = ExtResource( 13 ) + [node name="SpectatorCam" type="Camera2D" parent="."] offset = Vector2( 0, -15 ) [node name="Rival" parent="." instance=ExtResource( 6 )] position = Vector2( 91, -197 ) +script = ExtResource( 12 ) +unit_type = 0 [node name="CanvasLayer" type="CanvasLayer" parent="."] diff --git a/Scripts/PlayerRecorder.gd b/Scripts/PlayerRecorder.gd new file mode 100644 index 0000000..9e84843 --- /dev/null +++ b/Scripts/PlayerRecorder.gd @@ -0,0 +1,25 @@ +extends Node +class_name PlayerRecorder + +var replay: ReplayRecording +var this_frame: bool = true +var sprite: int = 0 +var player: DownhillAutoscrollerPlayer + +export var save_to: String + +func _ready(): + replay = ReplayRecording.new() + replay.time_per_frame = 1.0 / 30.0 + player = get_parent() + player.recorder = self + +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 diff --git a/Scripts/ReplayRecording.gd b/Scripts/ReplayRecording.gd new file mode 100644 index 0000000..ab942ae --- /dev/null +++ b/Scripts/ReplayRecording.gd @@ -0,0 +1,53 @@ +extends Object +class_name ReplayRecording + +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 positions[-1] + +func sprite(frame: int) -> int: + if frame < frames: + return sprites[frame] + else: + return sprites[-1] diff --git a/Scripts/Unit.gd b/Scripts/Unit.gd index 49b4669..1c054d2 100644 --- a/Scripts/Unit.gd +++ b/Scripts/Unit.gd @@ -35,6 +35,8 @@ var time_elapsed : float var is_flash : bool = false var flash_start_timestamp : float +var recorder: PlayerRecorder = null + # Called when the node enters the scene tree for the first time func _ready(): for action_num in Constants.UNIT_TYPE_ACTIONS[unit_type]: @@ -243,6 +245,10 @@ func set_sprite(sprite_class : int, index : int = 0): var true_index : int = index if true_index > len(node_list) - 1: true_index = 0 + + if recorder != null: + recorder.sprite = (index << 3) | sprite_class + var new_sprite : Node2D = node_list[true_index] if (is_flash): if int((time_elapsed - flash_start_timestamp) / Constants.FLASH_CYCLE) % 2 == 1: diff --git a/Scripts/Units/DownhillAutoscrollerPlayer.gd b/Scripts/Units/DownhillAutoscrollerPlayer.gd index d20e2d9..430d590 100644 --- a/Scripts/Units/DownhillAutoscrollerPlayer.gd +++ b/Scripts/Units/DownhillAutoscrollerPlayer.gd @@ -19,7 +19,6 @@ var jump_audiostream_player : AudioStreamPlayer var land_audiostream_player : AudioStreamPlayer var snow_audiostream_player : AudioStreamPlayer - func init_unit_w_scene(scene): .init_unit_w_scene(scene) hit_audiostream_player = scene.get_node("HitAudioStreamPlayer") diff --git a/Scripts/Units/FollowReplay.gd b/Scripts/Units/FollowReplay.gd new file mode 100644 index 0000000..3462e1c --- /dev/null +++ b/Scripts/Units/FollowReplay.gd @@ -0,0 +1,21 @@ +extends Unit + +var replay : ReplayRecording = null + +func process_unit(delta : float, time_elapsed : float): + self.time_elapsed = time_elapsed + + if replay != null: + 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) diff --git a/Sounds/Beep.wav.import b/Sounds/Beep.wav.import index bd13725..eb73235 100644 --- a/Sounds/Beep.wav.import +++ b/Sounds/Beep.wav.import @@ -17,5 +17,7 @@ force/max_rate=false force/max_rate_hz=44100 edit/trim=false edit/normalize=false -edit/loop=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 compress/mode=0 diff --git a/Sounds/ski-67717.wav.import b/Sounds/ski-67717.wav.import index ed6ae53..22b0978 100644 --- a/Sounds/ski-67717.wav.import +++ b/Sounds/ski-67717.wav.import @@ -17,5 +17,7 @@ force/max_rate=false force/max_rate_hz=44100 edit/trim=false edit/normalize=false -edit/loop=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 compress/mode=0 diff --git a/project.godot b/project.godot index 23cf4e8..ce1d86e 100644 --- a/project.godot +++ b/project.godot @@ -34,6 +34,16 @@ _global_script_classes=[ { "language": "GDScript", "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", "class": "Unit", "language": "GDScript", @@ -45,6 +55,8 @@ _global_script_class_icons={ "NPCExample": "", "NPCUnit": "", "Player": "", +"PlayerRecorder": "", +"ReplayRecording": "", "Unit": "" }