From 847670821d51dd809a98e86467f489aa99352ae8 Mon Sep 17 00:00:00 2001 From: Felipe M Date: Sat, 22 May 2021 18:33:00 +0200 Subject: [PATCH] SaveStation, save & load properly --- metroidvania/Levels/Level.gd | 10 +++ metroidvania/Levels/Level.tscn | 4 +- metroidvania/Levels/Level_00.tscn | 7 ++- metroidvania/Levels/Level_01.tscn | 8 ++- metroidvania/SaverLoader.gd | 7 ++- metroidvania/Scenes/Objects/SaveStation.gd | 7 +++ metroidvania/Scenes/Objects/SaveStation.tscn | 64 ++++++++++++++++++++ metroidvania/Scenes/Objects/Spikes.tscn | 1 + metroidvania/Scenes/Player/Player.gd | 7 ++- metroidvania/Scenes/Player/Player.tscn | 1 + metroidvania/Scenes/UI/StarMenu.tscn | 1 + metroidvania/Scenes/World/Camera.gd | 6 ++ metroidvania/Scenes/World/World.gd | 5 ++ metroidvania/Scenes/World/World.tscn | 8 +-- metroidvania/StarMenu.gd | 4 +- metroidvania/project.godot | 2 +- 16 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 metroidvania/Scenes/Objects/SaveStation.gd create mode 100644 metroidvania/Scenes/Objects/SaveStation.tscn diff --git a/metroidvania/Levels/Level.gd b/metroidvania/Levels/Level.gd index cc065ce..936b00a 100644 --- a/metroidvania/Levels/Level.gd +++ b/metroidvania/Levels/Level.gd @@ -6,3 +6,13 @@ func _ready(): var parent = get_parent() if parent is WORLD: parent.currentLevel = self + + +func save(): + var data = { + "filename": get_filename(), + "parent": get_parent().get_path(), + "position_x": position.x, + "position_y": position.y + } + return data diff --git a/metroidvania/Levels/Level.tscn b/metroidvania/Levels/Level.tscn index d21fe7a..ac86098 100644 --- a/metroidvania/Levels/Level.tscn +++ b/metroidvania/Levels/Level.tscn @@ -3,7 +3,9 @@ [ext_resource path="res://Levels/Level.gd" type="Script" id=1] [ext_resource path="res://Scenes/TileMap.tscn" type="PackedScene" id=2] -[node name="Level" type="Node2D"] +[node name="Level" type="Node2D" groups=[ +"Persists", +]] script = ExtResource( 1 ) [node name="TileMap" parent="." instance=ExtResource( 2 )] diff --git a/metroidvania/Levels/Level_00.tscn b/metroidvania/Levels/Level_00.tscn index 0027c90..e373f5d 100644 --- a/metroidvania/Levels/Level_00.tscn +++ b/metroidvania/Levels/Level_00.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=5 format=2] [ext_resource path="res://Levels/Level.tscn" type="PackedScene" id=1] [ext_resource path="res://Levels/Door.tscn" type="PackedScene" id=2] [ext_resource path="res://Levels/DoorConnections/00_link_01.tres" type="Resource" id=3] +[ext_resource path="res://Scenes/Objects/SaveStation.tscn" type="PackedScene" id=4] [node name="Level_00" instance=ExtResource( 1 )] @@ -13,3 +14,7 @@ tile_data = PoolIntArray( 0, 0, 4, 1, 0, 196609, 2, 0, 196609, 3, 0, 196609, 4, position = Vector2( 312, 144 ) connection = ExtResource( 3 ) new_level_path = "res://Levels/Level_01.tscn" + +[node name="SaveStation" parent="." index="2" instance=ExtResource( 4 )] +position = Vector2( 215, 160 ) +scale = Vector2( 0.998604, 1 ) diff --git a/metroidvania/Levels/Level_01.tscn b/metroidvania/Levels/Level_01.tscn index 77a0ee5..0f647c6 100644 --- a/metroidvania/Levels/Level_01.tscn +++ b/metroidvania/Levels/Level_01.tscn @@ -1,10 +1,11 @@ -[gd_scene load_steps=6 format=2] +[gd_scene load_steps=7 format=2] [ext_resource path="res://Levels/Door.tscn" type="PackedScene" id=1] [ext_resource path="res://Levels/Level.tscn" type="PackedScene" id=2] [ext_resource path="res://Levels/DoorConnections/00_link_01.tres" type="Resource" id=3] [ext_resource path="res://Levels/DoorConnections/01_99.tres" type="Resource" id=4] [ext_resource path="res://Scenes/Player/MissilesPowerup.tscn" type="PackedScene" id=5] +[ext_resource path="res://Scenes/Objects/SaveStation.tscn" type="PackedScene" id=6] [node name="Level_01" instance=ExtResource( 2 )] @@ -16,6 +17,9 @@ position = Vector2( 88, 144 ) connection = ExtResource( 4 ) new_level_path = "res://Levels/Level_99.tscn" +[node name="SaveStation" parent="OutDoor" index="2" instance=ExtResource( 6 )] +position = Vector2( -26, 16 ) + [node name="InDoor" parent="." index="2" instance=ExtResource( 1 )] position = Vector2( 8, 144 ) scale = Vector2( -1, 1 ) @@ -23,4 +27,4 @@ connection = ExtResource( 3 ) new_level_path = "res://Levels/Level_00.tscn" [node name="MissilesPowerup" parent="." index="3" instance=ExtResource( 5 )] -position = Vector2( 47, 146 ) +position = Vector2( 25, 146 ) diff --git a/metroidvania/SaverLoader.gd b/metroidvania/SaverLoader.gd index 904f4bb..f88ada6 100644 --- a/metroidvania/SaverLoader.gd +++ b/metroidvania/SaverLoader.gd @@ -2,6 +2,8 @@ extends Node const save_path = "user://savegame.save" +var is_loading = false + func save_game(): var save_game = File.new() save_game.open(save_path, File.WRITE) @@ -23,7 +25,10 @@ func load_game(): save_game.open(save_path, File.READ) while not save_game.eof_reached(): - var current_line = parse_json(save_game.get_line()) + var current_line = save_game.get_line() + if current_line == "": + continue + current_line = parse_json(current_line) if current_line != null: var newNode = load(current_line["filename"]).instance() get_node(current_line["parent"]).add_child(newNode, true) diff --git a/metroidvania/Scenes/Objects/SaveStation.gd b/metroidvania/Scenes/Objects/SaveStation.gd new file mode 100644 index 0000000..abeb4c6 --- /dev/null +++ b/metroidvania/Scenes/Objects/SaveStation.gd @@ -0,0 +1,7 @@ +extends StaticBody2D + +onready var animation = $Animation + +func _on_SaveArea_body_entered(body): + animation.play("Save") + SaverLoader.save_game() diff --git a/metroidvania/Scenes/Objects/SaveStation.tscn b/metroidvania/Scenes/Objects/SaveStation.tscn new file mode 100644 index 0000000..a28ae67 --- /dev/null +++ b/metroidvania/Scenes/Objects/SaveStation.tscn @@ -0,0 +1,64 @@ +[gd_scene load_steps=6 format=2] + +[ext_resource path="res://Assets/World/SaveStation.png" type="Texture" id=1] +[ext_resource path="res://Scenes/Objects/SaveStation.gd" type="Script" id=2] +[ext_resource path="res://Assets/UI/WhiteSquare.png" type="Texture" id=3] + +[sub_resource type="RectangleShape2D" id=1] +extents = Vector2( 8, 10 ) + +[sub_resource type="Animation" id=2] +resource_name = "Save" +length = 0.5 +step = 0.05 +tracks/0/type = "value" +tracks/0/path = NodePath("WhiteSpaceSprite:scale") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = false +tracks/0/keys = { +"times": PoolRealArray( 0, 0.25, 0.5 ), +"transitions": PoolRealArray( 1, 1, 1 ), +"update": 0, +"values": [ Vector2( 1e-05, 1.25 ), Vector2( 1, 1.25 ), Vector2( 1e-05, 1.25 ) ] +} +tracks/1/type = "value" +tracks/1/path = NodePath("WhiteSpaceSprite:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0, 0.5 ), +"transitions": PoolRealArray( 1, 1 ), +"update": 0, +"values": [ Vector2( 0, -25 ), Vector2( 0, -3 ) ] +} + +[node name="SaveStation" type="StaticBody2D"] +script = ExtResource( 2 ) + +[node name="WhiteSpaceSprite" type="Sprite" parent="."] +position = Vector2( 0, -25 ) +scale = Vector2( 1, 0.0625 ) +texture = ExtResource( 3 ) + +[node name="Sprite" type="Sprite" parent="."] +position = Vector2( 0, -24 ) +texture = ExtResource( 1 ) + +[node name="Collider" type="CollisionPolygon2D" parent="."] +polygon = PoolVector2Array( -13, 0, -9, -4, 9, -4, 13, 0 ) + +[node name="SaveArea" type="Area2D" parent="."] +collision_layer = 0 + +[node name="Collider" type="CollisionShape2D" parent="SaveArea"] +position = Vector2( 0, -14 ) +shape = SubResource( 1 ) + +[node name="Animation" type="AnimationPlayer" parent="."] +anims/Save = SubResource( 2 ) + +[connection signal="body_entered" from="SaveArea" to="." method="_on_SaveArea_body_entered"] diff --git a/metroidvania/Scenes/Objects/Spikes.tscn b/metroidvania/Scenes/Objects/Spikes.tscn index 85fd4b9..4153fb5 100644 --- a/metroidvania/Scenes/Objects/Spikes.tscn +++ b/metroidvania/Scenes/Objects/Spikes.tscn @@ -9,6 +9,7 @@ extents = Vector2( 8, 8 ) [node name="Spikes" type="Node2D"] [node name="Sprite" type="Sprite" parent="."] +z_index = 20 texture = ExtResource( 1 ) centered = false diff --git a/metroidvania/Scenes/Player/Player.gd b/metroidvania/Scenes/Player/Player.gd index 24a30fd..6b710f1 100644 --- a/metroidvania/Scenes/Player/Player.gd +++ b/metroidvania/Scenes/Player/Player.gd @@ -40,6 +40,7 @@ onready var muzzle = $Sprite/PlayerGun/Sprite/Muzzle onready var fireBulletTimer = $FireBulletTimer onready var blinkAnimator = $BlinkAnimator onready var powerupDetector = $PowerupDetector +onready var cameraFollow = $CameraFollow signal hit_door(door) @@ -50,6 +51,10 @@ func set_invincible(value): func _ready(): PlayerStats.connect("player_died", self, "_on_died") MainInstances.Player = self + call_deferred("assign_world_camera") + +func assign_world_camera(): + cameraFollow.remote_path = MainInstances.WorldCamera.get_path() func _exit_tree(): MainInstances.Player = null @@ -87,7 +92,7 @@ func _physics_process(delta): if Input.is_action_pressed("fire_missile") and fireBulletTimer.time_left == 0 and PlayerStats.missiles > 0 and PlayerStats.missiles_unlocked: fire_missile() - + func fire_bullet(): var bullet = Utils.instance_scene_on_main(PlayerBullet, muzzle.global_position) bullet.velocity = Vector2.RIGHT.rotated(playerGun.rotation) * bullet_speed diff --git a/metroidvania/Scenes/Player/Player.tscn b/metroidvania/Scenes/Player/Player.tscn index d65e3e9..5ff3cf2 100644 --- a/metroidvania/Scenes/Player/Player.tscn +++ b/metroidvania/Scenes/Player/Player.tscn @@ -130,6 +130,7 @@ script = ExtResource( 2 ) [node name="Sprite" type="Sprite" parent="."] position = Vector2( 0, -12 ) +z_index = 10 texture = ExtResource( 1 ) hframes = 12 frame = 11 diff --git a/metroidvania/Scenes/UI/StarMenu.tscn b/metroidvania/Scenes/UI/StarMenu.tscn index 377896e..945f93f 100644 --- a/metroidvania/Scenes/UI/StarMenu.tscn +++ b/metroidvania/Scenes/UI/StarMenu.tscn @@ -41,6 +41,7 @@ margin_right = 56.0 margin_bottom = 56.0 rect_min_size = Vector2( 56, 16 ) text = "Quit" + [connection signal="pressed" from="CenterContainer/VBoxContainer/StartButton" to="." method="_on_StartButton_pressed"] [connection signal="pressed" from="CenterContainer/VBoxContainer/LoadButton" to="." method="_on_LoadButton_pressed"] [connection signal="pressed" from="CenterContainer/VBoxContainer/QuitButton" to="." method="_on_QuitButton_pressed"] diff --git a/metroidvania/Scenes/World/Camera.gd b/metroidvania/Scenes/World/Camera.gd index f71eb7d..a716934 100644 --- a/metroidvania/Scenes/World/Camera.gd +++ b/metroidvania/Scenes/World/Camera.gd @@ -1,11 +1,17 @@ extends Camera2D +var MainInstances = ResourceLoader.MainInstances + var shake = 0 onready var timer = $Timer func _ready(): Events.connect("add_screenshake", self, "_on_Events_add_screenshake") + MainInstances.WorldCamera = self + +func _exit_tree(): + MainInstances.WorldCamera = null func _process(delta): offset_h = rand_range(-shake, shake) diff --git a/metroidvania/Scenes/World/World.gd b/metroidvania/Scenes/World/World.gd index b96acda..aa93acd 100644 --- a/metroidvania/Scenes/World/World.gd +++ b/metroidvania/Scenes/World/World.gd @@ -6,6 +6,11 @@ onready var currentLevel = $Level_00 func _ready(): VisualServer.set_default_clear_color(Color.black) + + if SaverLoader.is_loading: + SaverLoader.load_game() + SaverLoader.is_loading = false + MainInstances.Player.connect("hit_door", self, "_on_Player_hit_door") func _on_Player_hit_door(door): diff --git a/metroidvania/Scenes/World/World.tscn b/metroidvania/Scenes/World/World.tscn index 31454d6..cbac5f6 100644 --- a/metroidvania/Scenes/World/World.tscn +++ b/metroidvania/Scenes/World/World.tscn @@ -9,19 +9,19 @@ [node name="World" type="Node"] script = ExtResource( 3 ) +[node name="Camera" parent="." instance=ExtResource( 6 )] +position = Vector2( 9, 88 ) + [node name="Player" parent="." instance=ExtResource( 2 )] position = Vector2( 9, 96 ) [node name="CameraFollow" parent="Player" index="5"] remote_path = NodePath("../../Camera") -[node name="Camera" parent="." instance=ExtResource( 6 )] -position = Vector2( 9, 88 ) - [node name="UI" parent="." instance=ExtResource( 7 )] [node name="Level_00" parent="." instance=ExtResource( 1 )] -position = Vector2( -132, -35 ) +position = Vector2( -132, -32 ) [editable path="Player"] [editable path="Player/Hurtbox"] diff --git a/metroidvania/StarMenu.gd b/metroidvania/StarMenu.gd index 617a7d4..979694b 100644 --- a/metroidvania/StarMenu.gd +++ b/metroidvania/StarMenu.gd @@ -8,8 +8,8 @@ func _on_StartButton_pressed(): get_tree().change_scene("res://Scenes/World/World.tscn") func _on_LoadButton_pressed(): - # TODO: Savegames - pass + SaverLoader.is_loading = true + get_tree().change_scene("res://Scenes/World/World.tscn") func _on_QuitButton_pressed(): get_tree().quit() diff --git a/metroidvania/project.godot b/metroidvania/project.godot index 0218289..1814253 100644 --- a/metroidvania/project.godot +++ b/metroidvania/project.godot @@ -33,7 +33,7 @@ _global_script_class_icons={ [application] config/name="Metroidvania" -run/main_scene="res://Scenes/World/World.tscn" +run/main_scene="res://Scenes/UI/StarMenu.tscn" config/icon="res://icon.png" [autoload]