Tuesday, January 30, 2024

Godot Resize

 This is not really an entry for the PS Vita, but since I want to make things that can be ported, the window resize feature is important. Many times you might want to write specific sizes no matter your targeted screen, however sometimes the default stretching could be useful. This entry is basically an image to show how to configure that:

On your Godot project settings, go to "display/window/stretch/mode" and select "viewport", example below:
 
 
You can configure the kind of resizing/stretching you want to make in the "Aspect" options, some will add black bars and others will stretch the image to fit the screen, chose the one you need for your project there:



Saturday, January 27, 2024

For the Puck

This entry is about the little things before aiming for the control of the puck. In our case, we have decided to use a raycast to check if the player is able to reach the puck, you can see the preparation below:


As you can see, the cast is masked to work only with the puck layer to avoid any confussion with the ground later. The raycast, in charge of this, is called "forThePuck", and it has the enable option checked, with bodies but not areas.

Once we've done that, it's time to make a sanity check before going all out with the puck control and shooting:
 
- Create a new boolean variable initialized at false, this will tell us if the player has the puck or not.
 
- Now write a function that uses the raycast to know if the puck is at player's reach.
 
- Then, finally we add code in the loop to manage the actions for "grabbing it" and "shooting it.
[The script below is only printing text to evaluate both situations, but we'll change that with proper methods in the next steps.]

```
extends RigidBody
# https://docs.godotengine.org/en/3.5/tutorials/physics/rigid_body.html

onready var raycast = get_node("RayCast") # collision layer 1, like anything else
onready var forThePuck = get_node("ForThePuck") # collision layer 2, only the puck
onready var hasPuck = false

func _integrate_forces(_state):
    var dir = Vector3()
    dir.x = Input.get_action_strength("ui_left") - Input.get_action_strength("ui_right")
    dir.z = Input.get_action_strength("ui_up") - Input.get_action_strength("ui_down")

    apply_central_impulse(dir.normalized() /10)

    # Jumping code.
    if on_ground() and Input.is_action_pressed("jump"):
        apply_central_impulse(Vector3(0,1,0))
        
    # Grab puck control
    if puck_on_sight() and !hasPuck:
        get_node("Label").text = "goal"
        hasPuck = true
    
    if !puck_on_sight():
        get_node("Label").text = ""
        hasPuck = false

# Test if there is a body below the player.
func on_ground():
    if raycast.is_colliding():
        return true

# Test if the puck is on sight
func puck_on_sight():
    if forThePuck.is_colliding():
        return true

```


Besisdes, we're going to change the code to display the direction of the player's movement, we had done that in the vehicle node and script.
This is better and less "hacky":
[Warning: the vehicle node wasn't really needed. We'll be cleaning that when we have the puck control done. Now, this new method (code), however, is valid for both.]

```
extends VehicleBody
# Hacky way to make the character look at directions without breaking movement

# Called when the node enters the scene tree for the first time.
func _ready():
    .get_node("WheelRequired").disabled = true
    set_disable_scale(true)

func _integrate_forces(state):
    var dir = Vector3()
    dir.x = Input.get_action_strength("ui_left") - Input.get_action_strength("ui_right")
    dir.z = Input.get_action_strength("ui_up") - Input.get_action_strength("ui_down")
    
    # look at aiming direction properly / still needs a few touches    
    look_at_from_position(get_global_transform().origin, dir , Vector3.UP)
```
 
 

Tuesday, January 23, 2024

Dungeons and Godots

 This is a fairly simple entry, but I wanted to have it here:

I made a character sheet for role playing games as a way to practice the GUI elements and to learn some parameters of the DnD sheet. I'm going to write below a few things to have into account when creating this kind of things in Godot, and also, for tips in some common mistakes that break projects and whose solutions are a nightmare to find, even when they are so simple.

To use a downloaded font (from PC) in TTF or any other format, create a new resource
https://forum.godotengine.org/t/how-do-you-bring-fonts-into-godot-3-0/29601/4
```
  1. Copy your TTF into your project folder
  2. You will see Godot import it as a DynamicFontData in the file browser
  3. In the inspector click on the “new resource” icon and create a new DynamicFont.
  4. In the Font category, click on Font data and choose your TTF
  5. Save the DynamicFont under the name you want (optional)
  6. You can now use this dynamic font where you want, change its size, spacing etc (without altering the original font).
```
And then, you can change the default font in project settings “custom font” property.

To create a toggle button, you need to add a 'check button', with this code below.
```
extends CheckButton

var show = false


func _on_VerTablaModificadores_toggled(_button_pressed):
    $Tabla.visible = !show # Muestra o esconde la tabla segun la variable
    show = !show    # Actualiza la variable acorde a la visibilidad de la imagen en pantalla

```

Use the signals in that node to make it work, 
 
 
For the illustration to change according to your Option Button, you need this code in your illustration's texture rect:
```
extends TextureRect
# Size: x400 y500
# Pos: x540 y20

# Declare member variables here. Examples:
onready var especie = get_parent().get_node("ClaseEspecie/Especie")

# 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):
    var selectedID = especie.get_selected_id()
    var ilustracion = "Ilustraciones/" + especie.get_item_text(selectedID) + ".png"
    texture = load(ilustracion)
 
```

This is the resulted sheet working:

 
Besides, you can find the code for this project freely available at:
With the release app to test if you have a 32 or 64 bits Windows, and a VPK for your PS Vita.

Tuesday, January 16, 2024

SaveData Godot

 Godot SaveLoad

We have a few entries about Godot, now we can learn about how to save/load configuration and data for our games/apps. Besides, I will leave a link to a debug demo in GitHub at the bottom of this entry for those who want to test things.

First, we need to have a scene for loading/saving data. Since we talked about that in previous entries, I will write briefly what you need to have done previously, but I won't go into details:

- A scene: saveLoad.tscn, to work on.
- background, to look cool. (this is optional)
- a nice BGM. (this is optional)
- a character sprite to move, we'll use its position for save/loading tests.
- a nice font, to print the position in screen. (you can omit this if you want to)

Once we have this, image below, we can start with our saveLoad steps.



For making this configuration, we are going to use this documentation: https://docs.godotengine.org/en/3.5/classes/class_configfile.html
Besides, we are basing our code in this video's example:
https://youtu.be/ygGaN1EOQEA?si=9BA3dC4FbtPyKojW

Now, we'll create a new script (saveConfig.gd) to make the save system separately, so we can use it globally and in any project.

For it to be accessed globally as a singleton, you have to go to:
Project > Projects settings


Here you have to go to the autoload label and then click folder icon to load your newly created script (saveConfig.gd).


Then, click on add


to see something like this


After that, it's time to write the code to handle the file where we are going to storage the data to save-load.

```
extends Node2D


var savePath = "res://SaveLoad_test/SaveState.cfg"
var conf = ConfigFile.new()
var loadResult = conf.load(savePath)


# Called when the node enters the scene tree for the first time.
func _ready():
    pass # Replace with function body.


func saveValue(section,key, savedData):
    conf.set_value(section,key,savedData)
    conf.save(savePath)
    
func loadValue(section,key, savedData):
    savedData = conf.get_value(section,key,savedData)
```


With the config code, we need the game to communicate with it to exchange the data. This is done within the game scene script.
```
extends Node2D


var ghostPos = Vector2(0,0)


func _physics_process(_delta):
    if Input.is_action_pressed("ui_start"):
        get_tree().change_scene("res://os_test.tscn")
        
    if Input.is_action_pressed("ui_loadButton"):
        SaveConfig.loadValue("values","ValueOne", ghostPos)
        get_node("KinematicBody2D").set_position(ghostPos)
        
    if Input.is_action_pressed("ui_saveButton"):
        ghostPos = get_node("KinematicBody2D").get_global_transform().origin
        SaveConfig.saveValue("values","ValueOne", ghostPos)

```


With that, you have a saving system done. Since the position saving uses a global variable, it needs a few fixes, but you get the idea, and this is enough for a testing scene.

Finally, as I said at the beginning of the entry, here's the GitHub with the full project:
https://github.com/Bunkai9448/GodotVitaSystemTest
Besides, if you go to the release page, you can try the current beta on your PS Vita.

Monday, January 15, 2024

Godot Audio

In the previous entry we learn about the HUI and GUI, now it's time to add sounds. Godot's documentation for audio can be found here: https://docs.godotengine.org/en/3.5/classes/class_audiostreamplayer.html#class-audiostreamplayer However, as always, I wanted an easy example to work on...

Since I mentioned https://godotengine.org/asset-library/asset/677 in the previous entry, I will be using those as the base for this example, but you can do the same in a clean new project without problems.

First you need to create an AudioStreamPlayer node (you will likely want it to be a child of a main node
to have modularity for future sounds). After that, go to your inspector panel and load your audio:

To do that, use Stream load (image below)


Once we have the node created and the audio load, it's time to create the script to work with. Attach/Create a script in the AudioStreamPlayer's parent node to control the reproduction. Don't worry about the code in this step, we'll do it later.

After that, it's time to make or repurpose a button to play the music. In this sample, we are repurposing the previous ChangeWindowTitle button (since those are values we don't see in the ps vita).
[If you are doing this in a new project, just create a node button and do this step using that button instead]
Go to the node's panel and connect (edit in our case):


Now select the node we have created for the audio, with the script (AudioTest in the image below):


Hint: You can change the name of the signal function, here we've used the old one to make it easier to follow.

The next step is writing the code for it:

```
extends Node


func _ready():
    pass # Replace with function body.

func _on_ChangeWindowTitle_pressed():
    if !$AudioStreamPlayer.playing:
        $AudioStreamPlayer.play()
    else:
        $AudioStreamPlayer.stop()    
    
```

And that's all for today.

Sunday, January 14, 2024

Godots HUI and GUI

 Human User Interface and Guide User Interface.

We all want a good display for menus (settings, shops, etc). In previous entries, I used simple list menus for everything, now it's time to go beyond that. Today I want to write a bit about how to make use of godot's "Control Gallery". ( https://godotengine.org/asset-library/asset/890 )

If we click on that link, and download the assets, we can see a demo like this:

However, it only displays the different buttons and make the animations of them, but they have no actual effect. So, the next step should be making something with them. To do that, we can go to the documentation here: https://docs.godotengine.org/en/stable/tutorials/ui/control_node_gallery.html
After many definitions, there's no actual examples of use, I'll try to fix that here with a mini guide:

First, we need to download the asset and open the project to understand how the visual effects of the buttons are done. We can see those are described in the inspector, on the right side of the window.


You might think that didn't require any explanation. Actually... we are going to use the node, to create a signal,
and that's at the same side of the window. We want to have both clearly differentiated, and that's a good way.

Now, for the main part of the entry, let's make the check button do an action:
    - Create a new script for your parent node. You'll be adding the actions there later. Example below,


    - Click into your selected button. (We'll use the check button, green arrow pointed to the left)
    - Go to the node panel and click to create/connect a new signal (green arrow pointed to the right)



    - This new function with the alarm is the code we want to edit for our purpose,

Example to change the running scene:
```
func _on_Button_pressed():
    get_tree().change_scene("res://SceneName.tscn")
```


A different example, to see the visual effects, is to attach a script to the node and edit its values:
[No need of the use of signals for this] (Here you have the code to update the icon progress bar)
```
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
    if value < 100:
        value = value + 1
    else:
        value = 0
```



That's all for today. I hope this helps to those who didn't know how to start working with them.

PS: Another nice assets and sample to work with that is: https://godotengine.org/asset-library/asset/677 Which also serves as a jumping point to create debugging programs, and system info tools. The documentation for those functions is in: https://docs.godotengine.org/en/3.5/classes/class_os.html). Besides, you might want to call a different script for non-existing OS functions, then you'll need https://docs.godotengine.org/en/3.5/tutorials/scripting/cross_language_scripting.html

PS: If you want to add keyboard/pad control for those buttons, you want to read this https://docs.godotengine.org/en/3.5/tutorials/ui/gui_navigation.html and use:

```
func _ready():
$StartButton.grab_focus()
```
You can watch an example here: https://youtu.be/Mx3iyz8AUAE?si=9BNS2JMtqqwqKXCf

PS2: For a video using scrollbars go to: https://youtu.be/PWP_zGEj4q8?si=WtZRGBvNpUF2VHr1