added documentation on how to damage enemies
This commit is contained in:
parent
6df4178596
commit
78b038c405
@ -31,11 +31,14 @@ Our goals for UI:
|
|||||||
* Create Container nodes (vbox and hbox)
|
* Create Container nodes (vbox and hbox)
|
||||||
* Use a MarginContainer node to wrap our UI nodes
|
* Use a MarginContainer node to wrap our UI nodes
|
||||||
|
|
||||||
|
## Custom Resources
|
||||||
|
|
||||||
Exercise 1: Use a custom resource to track the player health.
|
Exercise 1: Use a custom resource to track the player health.
|
||||||
|
|
||||||
First create a script to use as the basis for the custom resource.
|
First create a script to use as the basis for the custom resource. This script will include any relevant data we might want to keep track of for characters in our game.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
class_name CharacterStats extends Resource
|
class_name CharacterStats extends Resource
|
||||||
|
|
||||||
@export var max_health:int = 100
|
@export var max_health:int = 100
|
||||||
@ -44,14 +47,18 @@ class_name CharacterStats extends Resource
|
|||||||
|
|
||||||
@export var meleeDamage:int = 10
|
@export var meleeDamage:int = 10
|
||||||
@export var rangeDamage:int = 8
|
@export var rangeDamage:int = 8
|
||||||
```
|
|
||||||
|
|
||||||
Second, create a custom resource that extends CharacterStats. Assign health and damage values as you wish.
|
```
|
||||||
|
Once the base class is created, custom resources are used to fill in specifics. In this case we can create custom resources for the player and the slime bad guys.
|
||||||
|
|
||||||
|
Create a custom resource called `playerstats` that extends `CharacterStats`. Assign health and damage values as you wish through the Godot UI.
|
||||||
|
|
||||||
In `gamecontroller` load in the player resource at the `ready` function.
|
In `gamecontroller` load in the player resource at the `ready` function.
|
||||||
|
|
||||||
`player = load("res://scripts/res/playerStats.tres")`
|
`player = load("res://scripts/res/playerStats.tres")`
|
||||||
|
|
||||||
|
You can also load in the slime resource if you have created that.
|
||||||
|
|
||||||
This will be used for all the data related to the player.
|
This will be used for all the data related to the player.
|
||||||
|
|
||||||
1. In the `reset` function, return the player to full health.
|
1. In the `reset` function, return the player to full health.
|
||||||
@ -125,7 +132,7 @@ Lastly we can update our listener function that knows when animations have compl
|
|||||||
```
|
```
|
||||||
State.HURT:
|
State.HURT:
|
||||||
current_state = State.IDLE
|
current_state = State.IDLE
|
||||||
State.DEATH:
|
State.DEATH:
|
||||||
deathComplete.emit()
|
deathComplete.emit()
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -138,5 +145,69 @@ if current_state != State.HURT and current_state != State.DEATH:
|
|||||||
handle_input()
|
handle_input()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Creating a UI
|
||||||
|
|
||||||
|
A good UI is a reflection of all the data in the game controller, and we have some good data to work with now. This includes:
|
||||||
|
|
||||||
|
* Number of coins collected
|
||||||
|
* Player health
|
||||||
|
* Number of crates remaining
|
||||||
|
* Time remaining
|
||||||
|
* Level number
|
||||||
|
|
||||||
|
With the way we have set our architecture, getting this information to the UI is simply a matter of wiring up listeners in the `SceneManager`.
|
||||||
|
|
||||||
|
As an example, we could start with the time remaining.
|
||||||
|
|
||||||
|
The process to hook this up looks like this:
|
||||||
|
|
||||||
|
1. Create a custom signal in the Gamecontroller
|
||||||
|
2. Create a handler function in the UI
|
||||||
|
3. In the SceneManager, connect the custom signal to the handler.
|
||||||
|
4. Send out the custom signal in the Gamecontroller
|
||||||
|
|
||||||
|
## Damaging Bad Guys (or anything)
|
||||||
|
|
||||||
|
While we have only one player character, we have many bad guys.
|
||||||
|
|
||||||
|
As our player runs around, they will damage various enemies at various times. How can the Gamecontroller keep track of it all?
|
||||||
|
|
||||||
|
The answer is to use a collection called a Dictionary.
|
||||||
|
|
||||||
|
This function is added to the Gamecontroller:
|
||||||
|
|
||||||
|
```
|
||||||
|
func addEnemyToLevel(enemy):
|
||||||
|
#assign a health using the enemy as a key
|
||||||
|
var enemyStat = {
|
||||||
|
"health": slime.health,
|
||||||
|
"damage": slime.meleeDamage
|
||||||
|
}
|
||||||
|
enemiesDict[enemy] = enemyStat
|
||||||
|
```
|
||||||
|
|
||||||
|
At the SceneManager, we call this function to assign every bad guy into the dictionary.
|
||||||
|
|
||||||
|
```
|
||||||
|
if enemies:
|
||||||
|
for obj in enemies.get_children():
|
||||||
|
if obj is Slime:
|
||||||
|
obj.playerDamageSignal.connect(Gamecontroller._on_player_damage)
|
||||||
|
Gamecontroller.addEnemyToLevel(obj)
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we can update our function in the Gamecontroller that knows when a bullet makes contact.
|
||||||
|
|
||||||
|
```
|
||||||
|
func bulletDamage(body, bullet):
|
||||||
|
print("Game controller knows about bullet hit")
|
||||||
|
if body is Slime:
|
||||||
|
enemiesDict[body]["health"] -= player.rangeDamage
|
||||||
|
if enemiesDict[body]["health"] <=0:
|
||||||
|
destroySignal.emit(body)
|
||||||
|
enemiesDict.erase(body)
|
||||||
|
```
|
||||||
|
|
||||||
|
With this set up, we can now track the health of individual bad guys in the level, and we can damage them based on the attack strength of our player!
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user