game saving like for real, bad guy movement, player damage, player death, ui with controls labels

This commit is contained in:
OddlyTimbot committed 2025-11-10 21:17:58 -05:00
1 parent d5c87727b9
commit 208d93f5b4
19 files changed
+521 -26

No files matched your search

+48 -3
View File
@@ -14,12 +14,18 @@ signal levelChangeSignal(level)
signal destroySignal(body)
signal playerDamagedSignal(health, maxHealth)
signal playerDeathSignal
signal gameSaveSignal(level, timeRemaining, playerHealth, enemiesDictionary)
signal gameLoadSignal(stash)
signal countDownSignal(timeRemaining)
signal coinUpdateSignal(remainingCoins)
var enemy:CharacterStats
var player:CharacterStats
var enemiesDict = {}
var playerCurrentHealth:int =0
var stashData={}
# Called when the node enters the scene tree for the first time.
func _ready():
@@ -33,9 +39,12 @@ func _ready():
timer.one_shot = false
timer.connect("timeout", secondCounter)
timer.start()
func secondCounter()->void:
timeAvailable -=1
countDownSignal.emit(timeAvailable)
if timeAvailable <=0:
print("YOu LOOSAE Baby!")
print(levels[currentLevel])
@@ -48,7 +57,12 @@ func reset()->void:
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass
if Input.is_action_just_pressed("save"):
print("save the game")
saveGame()
if Input.is_action_just_pressed("load"):
print("load the game")
loadGame()
func _on_trigger_fired(intent, body):
@@ -64,6 +78,7 @@ func _on_coin_collected(body, coin):
destroySignal.emit(coin)
func totalCoins(value):
coinUpdateSignal.emit(value)
if value == 0:
#you won
currentLevel +=1
@@ -82,11 +97,14 @@ func _on_slime_damage(_body, slime):
else:
print("Taking damage")
playerDamagedSignal.emit(playerCurrentHealth, player.starting_health)
func deathComplete()->void:
levelChangeSignal.emit(levels[currentLevel])
func totalEnemies(value):
print("GC knows total enemies "+str(value))
func addEnemyToLevel(slime)->void:
func addEnemyToLevel(slime, _stat=null)->void:
print("GC adding enemy")
var randDamage:int = randi() % 10
@@ -94,6 +112,11 @@ func addEnemyToLevel(slime)->void:
"health": enemy.health,
"damage": enemy.meleeDamage+randDamage
}
if _stat:
enemyStat = {
"health":_stat.health,
"damage":_stat.damage
}
enemiesDict[slime]= enemyStat
func bulletDamage(area,bullet)->void:
@@ -110,3 +133,25 @@ func bulletDamage(area,bullet)->void:
print("enemy damaged")
func removeEnemyFromLevel(slime)->void:
enemiesDict.erase(slime)
func saveGame()->void:
gameSaveSignal.emit(currentLevel, timeAvailable, playerCurrentHealth, enemiesDict)
func loadGame()->void:
if ResourceLoader.exists("res://scripts/rscs/level"+str(currentLevel)+"_gameSaveStats.tres"):
var saved_game:SaveObject = load("res://scripts/rscs/level"+str(currentLevel)+"_gameSaveStats.tres")
enemiesDict.clear()
#get from loaded game save
stashData = saved_game.gameSave
print("loading the game")
gameLoadSignal.emit(stashData)
func stashGame(stash)->void:
print("stashing game")
stashData = stash
var stashObject = SaveObject.new()
stashObject.gameSave=stashData
ResourceSaver.save(stashObject, "res://scripts/rscs/level"+str(currentLevel)+"_gameSaveStats.tres")
func playerHealth(value)->void:
playerCurrentHealth = value
+19 -2
View File
@@ -7,7 +7,7 @@ var direction:float = 0
@export var BUMP_POWER = 100
enum FaceDirection{LEFT, RIGHT}
var facing:FaceDirection = FaceDirection.RIGHT
enum State{IDLE,JUMP,FALLING,RUNNING,SHOVE}
enum State{IDLE,JUMP,FALLING,RUNNING,SHOVE,HURT,DEATH}
var current_state:State = State.IDLE
@onready var right_cast = $RightCast
@@ -24,16 +24,24 @@ var upJump:bool = false
@export var hard_gravity:float =1.5
@onready var player_graphic = $PlayerGraphic
signal playerDeathCompleteSignal
func _physics_process(delta):
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
handle_input()
if current_state != State.HURT:
handle_input()
handle_movement(delta)
update_states()
update_animation()
move_and_slide()
handle_collisions()
func handleDamage(_health,_maxHealth)->void:
current_state = State.HURT
func handleDeath()->void:
current_state = State.DEATH
func update_states()->void:
#Create a state machine
match current_state:
@@ -49,6 +57,7 @@ func update_states()->void:
current_state = State.RUNNING
State.RUNNING when velocity.x ==0:
current_state = State.IDLE
func update_animation()->void:
match current_state:
@@ -63,6 +72,10 @@ func update_animation()->void:
player_graphic.play("run")
State.SHOVE:
player_graphic.play("shove")
State.HURT:
player_graphic.play("hurt")
State.DEATH:
player_graphic.play("death")
func handle_input()->void:
# Handle jump.
@@ -152,3 +165,7 @@ func _on_animation_finished():
upJump=false
State.SHOVE:
current_state = State.IDLE
State.HURT:
current_state = State.IDLE
State.DEATH:
playerDeathCompleteSignal.emit()
+31
View File
@@ -0,0 +1,31 @@
[gd_resource type="Resource" script_class="SaveObject" load_steps=2 format=3 uid="uid://cl4l7yk43rbao"]
[ext_resource type="Script" uid="uid://ddp6q3gi13sw1" path="res://scripts/rscs/save_object.gd" id="1_a13pi"]
[resource]
script = ExtResource("1_a13pi")
gameSave = {
"coinsData": [Transform2D(1, 0, 0, 1.0000001, 435.00952, 343.5218), Transform2D(1, 0, 0, 1.0000001, 192.44662, 340.51724)],
"cratesData": [Transform2D(0.00016496716, -1.0015213, 1.0023261, 0.00016483471, 230.14476, 534.2836), Transform2D(-1.0023261, -6.868146e-05, 6.873665e-05, -1.0015213, 486.98053, 534.2846), Transform2D(1.0023259, -0.0007010149, 0.0007015782, 1.0015211, 353.81284, 342.28403)],
"enemiesData": [{
"damage": 7,
"health": 50,
"position": Transform2D(1, 0, 0, 1.0000001, 736.34125, 339.51575)
}, {
"damage": 8,
"health": 50,
"position": Transform2D(1, 0, 0, 1.0000001, 535.8805, 340.51724)
}, {
"damage": 8,
"health": 50,
"position": Transform2D(1, 0, 0, 1.0000001, 483.75943, 339.51572)
}, {
"damage": 10,
"health": 50,
"position": Transform2D(1, 0, 0, 1.0000001, 437.652, 339.51575)
}],
"playerData": {
"health": 67.0,
"position": Transform2D(1, 0, 0, 1.0000197, 397.92346, 341.94016)
}
}
+3
View File
@@ -0,0 +1,3 @@
class_name SaveObject extends Resource
@export var gameSave:Dictionary = {}
+1
View File
@@ -0,0 +1 @@
uid://ddp6q3gi13sw1
+1 -1
View File
@@ -7,5 +7,5 @@ script = ExtResource("1_ppipo")
health = 50
max_health = 50
starting_health = 50
meleeDamage = 5
meleeDamage = 25
metadata/_custom_type_script = "uid://oewo8kn4jbkl"
+102
View File
@@ -2,8 +2,15 @@ class_name SceneManager extends Node2D
var bullet = preload("res://scenes/bullet.tscn")
var grenade = preload("res://scenes/grenade.tscn")
var coinScene = preload("res://scenes/coin.tscn")
var crateScene = preload("res://scenes/crate.tscn")
var enemyScene = preload("res://scenes/slime.tscn")
@onready var coins = $"../Coins"
@onready var enemies = $"../Enemies"
@onready var player = $"../Player"
@onready var crates = $"../Crates"
@onready var ui = $"../CanvasLayer/ui"
var bulletArray = []
@@ -26,6 +33,15 @@ func buildLevel()->void:
#Wire up signals from Gamecontroller
Gamecontroller.levelChangeSignal.connect(changeScene)
Gamecontroller.destroySignal.connect(destroy)
Gamecontroller.gameSaveSignal.connect(saveGameByLevel)
Gamecontroller.gameLoadSignal.connect(loadGameByLevel)
Gamecontroller.playerDamagedSignal.connect(player.handleDamage)
Gamecontroller.playerDamagedSignal.connect(ui.healthUpdate)
Gamecontroller.playerDeathSignal.connect(player.handleDeath)
Gamecontroller.countDownSignal.connect(ui.timerUpdate)
Gamecontroller.coinUpdateSignal.connect(ui.coinUpdate)
player.playerDeathCompleteSignal.connect(Gamecontroller.deathComplete)
func updateEnemies()->void:
var totalEnemies = 0
@@ -88,3 +104,89 @@ func changeScene(level)->void:
func destroy(body)->void:
body.queue_free()
func loadGameByLevel(stash)->void:
print("load the game")
#get the player data from the stash
var playerData = stash.playerData
var coinsData = stash.coinsData
var cratesData = stash.cratesData
var enemiesData = stash.enemiesData
#get rid of any existing coins
if coins:
for coin in coins.get_children():
#remove the listeners
coin.tree_exited.disconnect(updateCoins)
coins.remove_child(coin)
coin.queue_free()
for trans in coinsData:
var coinObj:Coin = coinScene.instantiate()
coins.add_child(coinObj)
coinObj.transform = trans
updateCoins()
#crates
if crates:
for crate in crates.get_children():
crates.remove_child(crate)
crate.queue_free()
for crate in cratesData:
var crateObj:RigidBody2D = crateScene.instantiate()
crates.add_child(crateObj)
crateObj.transform = crate
#enemies
if enemies:
for enemy in enemies.get_children():
enemies.remove_child(enemy)
enemy.queue_free()
for enemy in enemiesData:
var enemyObj:Slime = enemyScene.instantiate()
enemies.add_child(enemyObj)
enemyObj.transform = enemy.position
Gamecontroller.addEnemyToLevel(enemyObj, enemy)
player.transform = playerData.position
#tell the game controller the players health
Gamecontroller.playerHealth(playerData.health)
func saveGameByLevel(currentLevel:int, timeAvailable:int, playerCurrentHealth:float, enemiesDict:Dictionary)->void:
print("Saving Game")
print(playerCurrentHealth)
print(player.transform)
var playerData={
"health":playerCurrentHealth,
"position":player.transform
}
# coin save info
var coinDataArray:Array
if coins:
for coin in coins.get_children():
print(coin.transform)
coinDataArray.push_front(coin.transform)
var crateDataArray:Array
if crates:
for crate in crates.get_children():
crateDataArray.push_front(crate.transform)
#enemies
var enemyDataArray:Array
for enemyKey in enemiesDict:
print("ENEMY FOUND")
print(enemyKey.transform)
print(enemiesDict[enemyKey].health)
print(enemiesDict[enemyKey].damage)
var enemy={
"position":enemyKey.transform,
"health":enemiesDict[enemyKey].health,
"damage":enemiesDict[enemyKey].damage
}
enemyDataArray.push_front(enemy)
var stash={
"playerData":playerData,
"coinsData": coinDataArray,
"cratesData": crateDataArray,
"enemiesData":enemyDataArray
}
Gamecontroller.stashGame(stash)
+18
View File
@@ -3,6 +3,7 @@ class_name Slime extends Area2D
@onready var left_cast = $LeftCast
@onready var right_down_cast = $RightDownCast
@onready var left_down_cast = $LeftDownCast
@onready var slime_graphic = $SlimeGraphic
var speed:int = 100
var direction = 1
@@ -15,6 +16,23 @@ func _ready():
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
#raycast detection
if not right_down_cast.is_colliding():
direction = -1
slime_graphic.flip_h = true
if not left_down_cast.is_colliding():
direction = 1
slime_graphic.flip_h = false
if right_cast.is_colliding() && not right_cast.get_collider() is Player:
direction = -1
slime_graphic.flip_h = true
if left_cast.is_colliding() && not left_cast.get_collider() is Player:
direction = 1
slime_graphic.flip_h = false
position.x += direction * speed * delta
+23
View File
@@ -0,0 +1,23 @@
class_name UI extends Control
@onready var health = $VBoxContainer/HBoxContainer/MarginContainer/health
@onready var timer = $VBoxContainer/HBoxContainer/MarginContainer2/timer
@onready var coins = $VBoxContainer/HBoxContainer/MarginContainer3/coins
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass
func healthUpdate(currentHealth, maxHealth):
health.text = "Health: "+str(currentHealth)
func timerUpdate(timeRemaining):
timer.text=str(timeRemaining)
func coinUpdate(coinsRemaining):
coins.text = "Coins: "+str(coinsRemaining)
+1
View File
@@ -0,0 +1 @@
uid://8ysbh26qa33o