...
This commit is contained in:
parent
d16160323c
commit
1e22d28754
34 changed files with 708 additions and 1822 deletions
3
MyObsidianVault/Godot/2D/Change editor language.md
Normal file
3
MyObsidianVault/Godot/2D/Change editor language.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#godot-editor
|
||||
Right upper corner in Menu selector window
|
||||
![[Pasted image 20240204164006.png]]
|
||||
0
MyObsidianVault/Godot/2D/Run project with F8.md
Normal file
0
MyObsidianVault/Godot/2D/Run project with F8.md
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
Sprite2D node
|
||||
|
||||
F => focus view on object
|
||||
|
||||
To get type information in code auto-completion, go to _Editor -> Editor Settings_, and in the _Text Editor -> Completion_ section, turn on the checkbox named _Add Type Hints_. You can also search for "type hints" in the search bar at the top of the window to find it quickly.
|
||||
|
||||
|
||||
`Vector2` values have a function named `angle()` that calculates and returns the vector's angle in radians. If we assign that to the ship's rotation, it will turn to face its move direction.
|
||||
|
||||
```gdscript
|
||||
var velocity = Vector2(480, -480)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
position += velocity * delta
|
||||
rotation = velocity.angle()
|
||||
````
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
https://school.gdquest.com/courses/learn_2d_gamedev_godot_4/to_space_and_beyond/taking_control
|
||||
|
||||
```gdscript
|
||||
extends Sprite2D
|
||||
var direction := Vector2(0,0)
|
||||
var max_speed := 600.0
|
||||
var velocity = Vector2(0, 0)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
|
||||
direction.x = Input.get_axis("move_left", "move_right")
|
||||
direction.y = Input.get_axis("move_up", "move_down")
|
||||
|
||||
if direction.length() > 1.0:
|
||||
direction = direction.normalized()
|
||||
|
||||
velocity = direction * max_speed
|
||||
position += velocity * delta
|
||||
if direction.length() > 0.0:
|
||||
rotation = velocity.angle()
|
||||
```
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
```python
|
||||
func _process(delta: float) -> void:
|
||||
var direction := Vector2(0, 0)
|
||||
direction.x = Input.get_axis("move_left", "move_right")
|
||||
direction.y = Input.get_axis("move_up", "move_down")
|
||||
|
||||
if direction.length() > 1.0:
|
||||
direction = direction.normalized()
|
||||
|
||||
if Input.is_action_just_pressed("boost"):
|
||||
max_speed = boost_speed
|
||||
get_node("Timer").start()
|
||||
|
||||
velocity = direction * max_speed
|
||||
position += velocity * delta
|
||||
|
||||
if direction.length() > 0.0:
|
||||
rotation = velocity.angle()
|
||||
```
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
```python
|
||||
extends Sprite2D
|
||||
var direction := Vector2(0,0)
|
||||
var max_speed := 300.0
|
||||
var velocity = Vector2(0, 0)
|
||||
var boost_speed := 1500.0
|
||||
var normal_speed := 300.0
|
||||
var desired_velocity := Vector2()
|
||||
var steering_factor := 10
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
var direction := Vector2(0, 0)
|
||||
direction.x = Input.get_axis("move_left", "move_right")
|
||||
direction.y = Input.get_axis("move_up", "move_down")
|
||||
|
||||
if direction.length() > 1.0:
|
||||
direction = direction.normalized()
|
||||
|
||||
if Input.is_action_just_pressed("boost"):
|
||||
max_speed = boost_speed
|
||||
get_node("Timer").start()
|
||||
|
||||
desired_velocity = max_speed * direction
|
||||
var steering = desired_velocity - velocity
|
||||
|
||||
velocity += steering * steering_factor * delta
|
||||
position += velocity * delta
|
||||
|
||||
if direction.length() > 0.0:
|
||||
rotation = velocity.angle()
|
||||
|
||||
|
||||
func _on_timer_timeout() -> void:
|
||||
max_speed = normal_speed
|
||||
```
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
```python
|
||||
extends Area2D
|
||||
|
||||
func _ready() -> void:
|
||||
area_entered.connect(_on_area_entered)
|
||||
|
||||
func _on_area_entered(area_that_entred: Area2D) -> void:
|
||||
queue_free()
|
||||
```
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
````python
|
||||
extends Area2D
|
||||
|
||||
var max_speed := 1200.0
|
||||
var velocity := Vector2(0, 0)
|
||||
var steering_factor := 3.0
|
||||
|
||||
var health := 10
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
area_entered.connect(_on_area_entered)
|
||||
# This call updates the health bar to match the health variable when the
|
||||
# game starts.
|
||||
set_health(health)
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
var direction := Vector2(0, 0)
|
||||
direction.x = Input.get_axis("move_left", "move_right")
|
||||
direction.y = Input.get_axis("move_up", "move_down")
|
||||
|
||||
if direction.length() > 1.0:
|
||||
direction = direction.normalized()
|
||||
|
||||
var desired_velocity := max_speed * direction
|
||||
var steering := desired_velocity - velocity
|
||||
velocity += steering * steering_factor * delta
|
||||
position += velocity * delta
|
||||
|
||||
if velocity.length() > 0.0:
|
||||
get_node("Sprite2D").rotation = velocity.angle()
|
||||
|
||||
|
||||
func set_health(new_health: int) -> void:
|
||||
health = new_health
|
||||
get_node("UI/HealthBar").value = health
|
||||
|
||||
|
||||
func _on_area_entered(area_that_entered: Area2D) -> void:
|
||||
set_health(health + 10)
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
https://school.gdquest.com/courses/learn_2d_gamedev_godot_4/telling_a_story/overview
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
```python
|
||||
var inventory: Array[Dictionary] = [
|
||||
{
|
||||
"name": "sword",
|
||||
"amount": 1,
|
||||
},
|
||||
{
|
||||
"name": "potion",
|
||||
"amount": 5,
|
||||
},
|
||||
{
|
||||
"name": "potion",
|
||||
"amount": 3,
|
||||
},
|
||||
{
|
||||
"name": "coins",
|
||||
"amount": 65,
|
||||
},
|
||||
]
|
||||
```
|
||||
[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```python
|
||||
var expressions := {
|
||||
"happy" : preload("res://assets/emotion_happy.png"),
|
||||
"regular" : preload("res://assets/emotion_regular.png"),
|
||||
"sad" : preload("res://assets/emotion_sad.png"),
|
||||
}
|
||||
|
||||
var dialogue_items: Array[Dictionary]= [
|
||||
{
|
||||
"expression": expressions["regular"],
|
||||
"text": "I'm learning about Arrays..."
|
||||
},
|
||||
{
|
||||
"expression": expressions["sad"],
|
||||
"text": "... and it is a little bit complicated."
|
||||
},
|
||||
{
|
||||
"expression": expressions["happy"],
|
||||
"text": "Let's see if I got it right: an array is a list of values!",
|
||||
},
|
||||
{
|
||||
"expression": expressions["regular"],
|
||||
"text": "Did I get it right? Did I?",
|
||||
},
|
||||
{
|
||||
"expression": expressions["happy"],
|
||||
"text": "Hehe! Bye bye~!",
|
||||
},
|
||||
]
|
||||
|
||||
func show_text() -> void:
|
||||
var current_item := dialogue_items[current_item_index]
|
||||
rich_text_label.text = current_item["text"]
|
||||
expression.texture = current_item["expression"]
|
||||
```
|
||||
|
|
@ -0,0 +1 @@
|
|||
A UI nodes' opacity is modified via the modulate property which controls the tinting of the node.
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
Tweens are created using a nodes' create_tween() method
|
||||
|
||||
|
||||
```python
|
||||
func slide_in() -> void:
|
||||
var tween := create_tween()
|
||||
tween.set_trans(Tween.TRANS_QUART)
|
||||
tween.set_ease(Tween.EASE_OUT)
|
||||
````
|
||||
|
||||
Running tweens in parallel via parallel method.
|
||||
Modulate controls tinting, subproperty a is for alpha, meaning a target visibilty of 100%
|
||||
```python
|
||||
tween.parallel().tween_property(body, "modulate:a", 1.0, 0.2)
|
||||
```
|
||||
|
||||
|
||||
Full tween method:
|
||||
```python
|
||||
func slide_in() -> void:
|
||||
var tween = create_tween()
|
||||
tween.set_trans(Tween.TRANS_QUART)
|
||||
tween.set_ease(Tween.EASE_OUT)
|
||||
body.position.x = 200.0
|
||||
tween.tween_property(body, "position:x", 0.0, 1.0) # Move x from 200 to 0
|
||||
body.modulate.a = 0.0 # UI node visibility = 0
|
||||
tween.parallel().tween_property(body, "modulate:a", 1.0, 1.0) # Animate visibility towards 100% (a=alpha)
|
||||
```
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
Nothing new here, just replacement of TextureRect images
|
||||
|
||||
```python
|
||||
extends Control
|
||||
|
||||
|
||||
var expressions := {
|
||||
"happy": preload ("res://assets/emotion_happy.png"),
|
||||
"regular": preload ("res://assets/emotion_regular.png"),
|
||||
"sad": preload ("res://assets/emotion_sad.png"),
|
||||
}
|
||||
|
||||
var bodies := {
|
||||
"sophia": preload ("res://assets/sophia.png"),
|
||||
"pink": preload ("res://assets/pink.png")
|
||||
}
|
||||
|
||||
|
||||
|
||||
## Data to display in the dialogue. Each dictionary in this array has three properties:
|
||||
##
|
||||
## - expression: a [code]Texture[/code] containing an expression
|
||||
## - text: a [code]String[/code] containing the text the character says
|
||||
## - character: a [code]Texture[/code] representing the character
|
||||
|
||||
var dialogue_items: Array[Dictionary] = [
|
||||
{
|
||||
"expression": expressions["regular"],
|
||||
"text": "I've been studying arrays and dictionaries lately.",
|
||||
"character": bodies["sophia"],
|
||||
},
|
||||
{
|
||||
"expression": expressions["regular"],
|
||||
"text": "Oh, nice. How has it been going?",
|
||||
"character": bodies["pink"],
|
||||
},
|
||||
{
|
||||
"expression": expressions["sad"],
|
||||
"text": "Well... it's a little complicated!",
|
||||
"character": bodies["sophia"],
|
||||
},
|
||||
{
|
||||
"expression": expressions["sad"],
|
||||
"text": "Oh!",
|
||||
"character": bodies["pink"],
|
||||
},
|
||||
{
|
||||
"expression": expressions["regular"],
|
||||
"text": "It sure takes time to click at first.",
|
||||
"character": bodies["pink"],
|
||||
},
|
||||
{
|
||||
"expression": expressions["happy"],
|
||||
"text": "If you keep at it, eventually, you'll get the hang of it!",
|
||||
"character": bodies["pink"],
|
||||
},
|
||||
{
|
||||
"expression": expressions["regular"],
|
||||
"text": "Mhhh... I see. I'll keep at it, then.",
|
||||
"character": bodies["sophia"],
|
||||
},
|
||||
{
|
||||
"expression": expressions["happy"],
|
||||
"text": "Thanks for the encouragement. Time to LEARN!!!",
|
||||
"character": bodies["sophia"],
|
||||
},
|
||||
]
|
||||
|
||||
var current_item_index := 0
|
||||
|
||||
@onready var rich_text_label: RichTextLabel = %RichTextLabel
|
||||
@onready var next_button: Button = %NextButton
|
||||
@onready var audio_stream_player: AudioStreamPlayer = %AudioStreamPlayer
|
||||
@onready var body: TextureRect = %Body
|
||||
@onready var expression_texture_rect: TextureRect = %Expression
|
||||
|
||||
func _ready() -> void:
|
||||
show_text()
|
||||
next_button.pressed.connect(advance)
|
||||
|
||||
|
||||
func show_text() -> void:
|
||||
# We first extract data for the current dialogue item and apply it to the UI
|
||||
# elements.
|
||||
var current_item := dialogue_items[current_item_index]
|
||||
rich_text_label.text = current_item["text"]
|
||||
expression_texture_rect.texture = current_item["expression"]
|
||||
body.texture = current_item["character"]
|
||||
|
||||
# We then hide the text and animate it appearing.
|
||||
rich_text_label.visible_ratio = 0.0
|
||||
var tween := create_tween()
|
||||
var text_appearing_duration: float = current_item["text"].length() / 30.0
|
||||
tween.tween_property(rich_text_label, "visible_ratio", 1.0, text_appearing_duration)
|
||||
|
||||
# We randomize the audio playback's start time to make it sound different
|
||||
# every time and play the sound until the text finishes displaying.
|
||||
var sound_max_length := audio_stream_player.stream.get_length() - text_appearing_duration
|
||||
var sound_start_position := randf() * sound_max_length
|
||||
audio_stream_player.play(sound_start_position)
|
||||
tween.finished.connect(audio_stream_player.stop)
|
||||
|
||||
# We animate the character sliding in.
|
||||
slide_in()
|
||||
|
||||
|
||||
## Advances the dialogue to the next item or quits the game if there are no more
|
||||
## items.
|
||||
func advance() -> void:
|
||||
current_item_index += 1
|
||||
if current_item_index == dialogue_items.size():
|
||||
get_tree().quit()
|
||||
else:
|
||||
show_text()
|
||||
|
||||
|
||||
|
||||
|
||||
## Animates the character sliding in.
|
||||
func slide_in() -> void:
|
||||
var slide_tween := create_tween()
|
||||
slide_tween.set_ease(Tween.EASE_OUT)
|
||||
body.position.x = get_viewport_rect().size.x / 7
|
||||
slide_tween.tween_property(body, "position:x", 0, 0.3)
|
||||
body.modulate.a = 0
|
||||
slide_tween.parallel().tween_property(body, "modulate:a", 1, 0.2
|
||||
```
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
ProjectProject Settings...Input Map
|
||||
Define action + button there
|
||||
![[Pasted image 20240713073756.png]]
|
||||
|
||||
Next, select a button, and open Shortcut section
|
||||
![[Pasted image 20240713073933.png]]
|
||||
|
||||
Click the <empty> Shortcut field, then select New Shortcut
|
||||
|
||||
|
||||
The `Shortcut` resource takes an array of inputs as its data because in case you'd want to trigger the same button with multiple different inputs or input actions.
|
||||
sadfs
|
||||
![[Pasted image 20240713074212.png]]
|
||||
|
||||
|
||||
|
||||
![[Pasted image 20240713074345.png]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Click on the created InputEventAction to expand it.
|
||||
![[Pasted image 20240713080012.png]]
|
||||
Set action to advance_text ( The action we created in the very first screenshot of this page)
|
||||
|
||||
![[Pasted image 20240713080125.png]]
|
||||
|
||||
Now all input defined for advance_text action will trigger the button.
|
||||
|
||||
|
||||
|
||||
Disabling button until tween finished
|
||||
```python
|
||||
func show_text() -> void:
|
||||
# We first extract data for the current dialogue item and apply it to the UI
|
||||
# elements.
|
||||
# ...
|
||||
next_button.disabled = true
|
||||
tween.finished.connect(func() -> void:
|
||||
next_button.disabled = false
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Note to self: It seems to be possible to connect an event to more than 1 function. Here the full function from the tutorial. Note the tween.connect re-use
|
||||
|
||||
```python
|
||||
func show_text() -> void:
|
||||
# We first extract data for the current dialogue item and apply it to the UI
|
||||
# elements.
|
||||
var current_item := dialogue_items[current_item_index]
|
||||
rich_text_label.text = current_item["text"]
|
||||
expression_texture_rect.texture = current_item["expression"]
|
||||
body.texture = current_item["character"]
|
||||
|
||||
# We then hide the text and animate it appearing.
|
||||
rich_text_label.visible_ratio = 0.0
|
||||
var tween := create_tween()
|
||||
var text_appearing_duration: float = current_item["text"].length() / 30.0
|
||||
tween.tween_property(rich_text_label, "visible_ratio", 1.0, text_appearing_duration)
|
||||
|
||||
# We randomize the audio playback's start time to make it sound different
|
||||
# every time and play the sound until the text finishes displaying.
|
||||
var sound_max_length := audio_stream_player.stream.get_length() - text_appearing_duration
|
||||
var sound_start_position := randf() * sound_max_length
|
||||
audio_stream_player.play(sound_start_position)
|
||||
tween.finished.connect(audio_stream_player.stop)
|
||||
|
||||
# We animate the character sliding in.
|
||||
slide_in()
|
||||
|
||||
# Finally, we disable the next button until the text finishes displaying.
|
||||
next_button.disabled = true
|
||||
tween.finished.connect(func() -> void:
|
||||
next_button.disabled = false
|
||||
)
|
||||
|
||||
```
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
```bbcode
|
||||
BBCode is a simple [b]markup language[/b] that is [i]supposed[/i] to be simpler than [b]HTML[/b].
|
||||
```
|
||||
|
||||
Examples
|
||||
```bbcode
|
||||
|
||||
[b]bold[/b]
|
||||
[i]italics[/i]
|
||||
[u]underline[/u]
|
||||
[s]strikethrough[/s]
|
||||
[url=https://godotengine.org]link[/url]
|
||||
|
||||
[shake]This text shakes[/shake] makes the text shake.
|
||||
[wave]This text is wavy[/wave] makes the text animate in a wave pattern.
|
||||
[tornado freq=1.0]This text is even more wavy[/tornado] makes the text rotate like leaves. The freq parameter controls the speed of the rotation.
|
||||
[rainbow val=0.8]This text is colored[/rainbow] tints the text and animates it using rainbow colors. The val parameter controls the saturation, that is to say, how intense the colors are.
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Works only with the `RichTextLabel` node, and needs to be activated for the node (performance reasons)
|
||||
|
||||
![[Pasted image 20240719083713.png]]
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
`HBoxContainer`
|
||||
`VBoxContainer`
|
||||
`GridContainer`
|
||||
|
||||
`Control`
|
||||
Anchors define corner position of a control node
|
||||
|
||||
TextureRect => Like Sprite2D, but for UI
|
||||
You can drag an asset file on top of the TextureRect
|
||||
![[Pasted image 20240615074811.png]]
|
||||
|
|
@ -0,0 +1 @@
|
|||
https://school.gdquest.com/courses/learn_2d_gamedev_godot_4/telling_a_story/first_ui_exploration
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
RichtextLabel
|
||||
TextureRect
|
||||
Button
|
||||
ColorRect
|
||||
AudioStreamPlayer
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
![[Pasted image 20240623095140.png]]![[Pasted image 20240623095146.png]]
|
||||
![[Pasted image 20240623095156.png]]
|
||||
.tres is text-based, recommnended and git-friendly
|
||||
|
||||
Theme Editor Overview: https://school.gdquest.com/courses/learn_2d_gamedev_godot_4/telling_a_story/all_theme_editor_areas
|
||||
|
||||
Beware of not working copy/paste in theme styles. Workaround is Make unique and saving / loding in new component
|
||||
|
||||
1.) Create Theme Resource
|
||||
2.) Modifiy
|
||||
3.) Assign to uppermost UI Control Node
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
https://school.gdquest.com/courses/learn_2d_gamedev_godot_4/telling_a_story/your_first_words
|
||||
|
||||
Scene Unique Nodes
|
||||
|
||||
`To mark a node as unique, right-click it in the _Scene_ dock and select _Access As Unique Name_ in the dropdown menu.`
|
||||
|
||||
![[Pasted image 20240625081421.png]]
|
||||
|
||||
Restriction: They can only be addressed from the scene their uniqueness is defined in.
|
||||
|
||||
`There's also an important limitation to this feature: nodes with a scene-unique name only exist in the scene they're marked in. For example, if we mark our `RichTextLabel` in the scene dialogue.tscn as unique, we can't reference it from another scene.
|
||||
|
||||
You also can't mark nodes instantiated at runtime as unique. That's why we learned the more general way of getting nodes first with `get_node()`.`
|
||||
|
||||
|
||||
Script shortcut:
|
||||
1.) Mark unique nodes
|
||||
2.) Drag and hold over script editor
|
||||
3.) Press and hold Ctrl
|
||||
4.) Release and see created initialization code
|
||||
|
||||
![[Pasted image 20240625081825.png]]
|
||||
|
||||
|
||||
|
||||
Quitting the game
|
||||
![[Pasted image 20240625083616.png]]
|
||||
`get_tree().quit()`
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
![[Pasted image 20240626083938.png]]
|
||||
|
||||
`Do you remember how to find the name of the property in code? You can hover over the property in the editor, and a tooltip will show you the code name.`
|
||||
|
||||
````
|
||||
## Draws the current text to the rich text element
|
||||
func show_text() -> void:
|
||||
var current_item := dialogue_items[current_item_index]
|
||||
rich_text_label.text = current_item
|
||||
rich_text_label.visible_ratio = 0.0 # <--rich
|
||||
````
|
||||
|
||||
````
|
||||
func show_text() -> void:
|
||||
# ...
|
||||
var tween := create_tween()
|
||||
var text_appearing_duration := 1.2
|
||||
tween.tween_property(rich_text_label, "visible_ratio", 1.0, text_appearing_duration)
|
||||
````
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
Generic:
|
||||
AudioStream
|
||||
Positional:
|
||||
AudioStream2D
|
||||
AudioStream3D
|
||||
|
||||
`
|
||||
```
|
||||
var text_appearing_duration = 1.2 # value is in seconds
|
||||
var sound_max_length := audio_stream_player.stream.get_length() - text_appearing_duration
|
||||
var sound_start_position := randf() * sound_max_length
|
||||
audio_stream_player.play(sound_start_position)
|
||||
tween.finished.connect(audio_stream_player.stop)
|
||||
|
||||
|
||||
```
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
```
|
||||
extends Control
|
||||
|
||||
## An array of strings. Each string contains the text we want the character to
|
||||
## say.
|
||||
var dialogue_items: Array[String] = [
|
||||
"I'm learning about Arrays...",
|
||||
"...and it is a little bit complicated.",
|
||||
"Let's see if I got it right: an array is a list of values!",
|
||||
"Did I get it right? Did I?",
|
||||
"Hehe! Bye bye~!",
|
||||
]
|
||||
## Holds the index of the currently displayed text
|
||||
var current_item_index := 0
|
||||
|
||||
@onready var rich_text_label: RichTextLabel = %RichTextLabel
|
||||
@onready var next_button: Button = %NextButton
|
||||
@onready var audio_stream_player: AudioStreamPlayer = %AudioStreamPlayer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
show_text()
|
||||
next_button.pressed.connect(advance)
|
||||
|
||||
## Draws the current text to the rich text element
|
||||
func show_text() -> void:
|
||||
var current_item := dialogue_items[current_item_index]
|
||||
rich_text_label.text = current_item
|
||||
# We animate the text appearing letter by letter.
|
||||
rich_text_label.visible_ratio = 0.0
|
||||
var tween := create_tween()
|
||||
var text_appearing_duration := 1.2
|
||||
tween.tween_property(rich_text_label, "visible_ratio", 1.0, text_appearing_duration)
|
||||
# This is where we play the audio. We randomize the audio playback's start
|
||||
# time to make it sound different every time.
|
||||
var sound_max_length := audio_stream_player.stream.get_length() - text_appearing_duration
|
||||
var sound_start_position := randf() * sound_max_length
|
||||
audio_stream_player.play(sound_start_position)
|
||||
# We stop the audio when the text finishes appearing.
|
||||
tween.finished.connect(audio_stream_player.stop)
|
||||
|
||||
func advance() -> void:
|
||||
current_item_index += 1
|
||||
# If we reached the end of the dialogue, we quit the game. Otherwise, we
|
||||
# show the next dialogue line.
|
||||
if current_item_index == dialogue_items.size():
|
||||
get_tree().quit()
|
||||
else:
|
||||
show_text()
|
||||
```
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
1. Arrange UI nodes in rows and columns using `Container` nodes.
|
||||
2. Change the texture of a `TextureRect` node programmatically.
|
||||
3. Map different image textures to different strings representing the expressions using [dictionaries](https://school.gdquest.com/glossary/dictionary).
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
```python
|
||||
button_sophia.pressed.connect(func() -> void:
|
||||
body.texture = bodies["sophia"]
|
||||
)
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
In this lesson, you will write the code to change the expressions of the characters when clicking the buttons.
|
||||
|
||||
Loading image at compile time (advantage of seeing error if file doesnt exist)
|
||||
```python
|
||||
var image := preload("res:://image.png")
|
||||
```
|
||||
|
||||
|
||||
Loading at runtime on demand:
|
||||
```python
|
||||
load("res:://image.png")
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Preloadingloading into a dictionary:
|
||||
```python
|
||||
var bodies := {
|
||||
"sophia": preload("res://assets/sophia.png"),
|
||||
"pink": preload("res://assets/pink.png")
|
||||
}
|
||||
```
|
||||
|
||||
Dont forget to multiselect + drag&drop assets into code editor, then multi-cursor correct using
|
||||
either Alt+Ctrl+Mouseclicks, or Alt+Shift+Cursor Up/Down
|
||||
|
||||
|
||||
*Setting TextureRect texture*
|
||||
```python
|
||||
func _ready() -> void:
|
||||
body.texture = bodies["pink"]
|
||||
expression.texture = expressions["happy"]
|
||||
```
|
||||
|
||||
|
||||
It's not mandatory to use square brackets to access dictionary values. You can also use the `.` operator. For example, writing `bodies["sophia"]` is equivalent to `bodies.sophia`.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
```python
|
||||
func create_button_pink() -> void:
|
||||
var button := Button.new()
|
||||
row_bodies.add_child(button)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
func create_buttons() -> void:
|
||||
for current_body: String in bodies:
|
||||
var button := Button.new()
|
||||
row_bodies.add_child(button)
|
||||
button.text = current_body.capitalize()
|
||||
button.pressed.connect(func()-> void:
|
||||
body.texture = bodies[current_body]
|
||||
)
|
||||
```
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
**Topics**:
|
||||
Control Nodes
|
||||
Label Node
|
||||
AudioStreamPlayer Node
|
||||
Arrays
|
||||
Dictionaries
|
||||
Dictionaries inside Arrays
|
||||
Theming
|
||||
Iterative Design
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
![[Pasted image 20240720081419.png]]
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
The goal: Going from linear dialogue display to integrating player choice
|
||||
|
||||
https://school.gdquest.com/courses/learn_2d_gamedev_godot_4/start_a_dialogue/refactoring_the_dialogue#preparing-to-update-the-dialogue-scene
|
||||
|
||||
Designing the interface to include choice buttons
|
||||
![[Pasted image 20240720075840.png]]
|
||||
|
||||
![[Pasted image 20240720080105.png]]
|
||||
|
||||
|
||||
Sizing examples:
|
||||
![[Pasted image 20240720081104.png]]
|
||||
18
MyObsidianVault/Godot/HTTP Requests/2024-12-22.md
Normal file
18
MyObsidianVault/Godot/HTTP Requests/2024-12-22.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
```python
|
||||
extends Control
|
||||
|
||||
@onready var http_request: HTTPRequest = $btn_login/HTTPRequest
|
||||
@onready var te_result: TextEdit = $te_result
|
||||
|
||||
var url = "https://meowfacts.herokuapp.com/"
|
||||
|
||||
func _on_btn_login_button_up() -> void:
|
||||
var headers = ["Content-Type: application/json"]
|
||||
http_request.request(url, headers, HTTPClient.Method.METHOD_GET)
|
||||
|
||||
func _on_http_request_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) -> void:
|
||||
var data = JSON.parse_string(body.get_string_from_utf8())
|
||||
te_result.text = data.data[0]
|
||||
```
|
||||
|
||||
![[Pasted image 20241222121529.png]]
|
||||
Loading…
Add table
Add a link
Reference in a new issue