Godot is able to do much more than Scratch, but some things that were simple in Scratch are more complicated in Godot. This guide is intended to help with those things. Most of these Godot codes should behave the same way they do in Scratch, but ultimately it will be best not to try and do everything the same way you did it in Scratch. There are usually a lot of different ways to achieve the same result in Godot – which one to use depends on your specific project. So, these are just suggestions.
|
position += 10*transform.x |
|
rotation_degrees += 15 |
|
rotation_degrees -= 15 |
|
position = Vector2(randf() * 1024, randf() * 600) |
|
position = get_global_mouse_position() |
|
position = $"../Sprite".position |
|
position = Vector2(0,0) |
|
You can set up a glider in the script using this code: signal glide_completed var velocity = Vector2.ZERO var glide_time = 0 func _process(delta): position += delta*velocity glide_time -= delta if glide_time < 0: velocity = Vector2.ZERO emit_signal("glide_completed") And then put the code below in func _ready() to glide 1 secs to a random position:
glide_time = 1 velocity = (Vector2(randf() * 1024, randf() * 600) - position) / glide_time yield(self,"glide_completed") |
|
For this to work, you first need to set up the glider (see above). glide_time = 1 velocity = (get_global_mouse_position() - position) / glide_time yield(self,"glide_completed") |
|
For this to work, you first need to set up the glider (see above). glide_time = 1 velocity = ($"../Sprite".position - position) / glide_time yield(self,"glide_completed") |
|
For this to work, you first need to set up the glider (see above). glide_time = 1 velocity = (Vector2(0,0) - position) / glide_time yield(self,"glide_completed") |
|
rotation_degrees = 90 |
|
rotation = position.direction_to(get_global_mouse_position()).angle() |
|
rotation = position.direction_to($"../Sprite".position).angle() |
|
position.x += 10 |
|
position.x = 0 |
|
position.y += 10 |
|
position.y = 0 |
|
if position.x < 0 or position.x > 1024: transform.x.x *= -1 if position.y < 0 or position.y > 600: transform.x.y *= -1 |
|
Make the moving object a RemoteTransform2D and have the Sprite node separate. In the Inspector for the RemoteTransform2D, choose the Sprite as Remote Path. In Update, uncheck Rotation and Scale. This code goes in the process method for the moving object: get_node(remote_path).flip_h = (get_node(remote_path).rotation_degrees > 90) |
|
Make the moving object a RemoteTransform2D and have the Sprite node separate. In the Inspector for the RemoteTransform2D, choose the Sprite as Remote Path. In Update, uncheck Rotation and Scale. |
|
Make the moving object a RemoteTransform2D and have the Sprite node separate. In the Inspector for the RemoteTransform2D, choose the Sprite as Remote Path. In Update, uncheck Scale. |
|
position.x |
|
position.y |
|
rotation_degrees |
|
Add a Label as a child node, resize and position it as desired. $Label.text = "Hello!" yield(get_tree().create_timer(2), "timeout") $Label.text = "" |
|
Add a Label as a child node, resize and position it as desired. $Label.text = "Hello!" |
|
You could follow the instructions above for say. To get a picture (like a speech bubble) behind the text, you need a TextureRect or ColorRect which you can show() and hide() in your code. Godot is also able to print messages to the output log: print("Hmm...") |
|
|
|
texture = load("costume2.png") |
|
Use an AnimatedSprite instead of a normal Sprite. In the Inspector, set Frames to New SpriteFrames, then click on SpriteFrames to edit it. Drag images into the Animation Frames area. You can set the animation Speed and choose whether or not it will Loop (repeat again and again). If you want the animation to start when the game starts, make sure to tick the Playing box in the Inspector. You can have more than one animation, each with its own name and frames. frame = (frame + 1) % frames.get_frame_count("default") |
|
get_tree().change_scene("backdrop1.tscn") Switching scenes in Godot isn’t exactly like switching backdrop in Scratch. Most importantly, the objects from the first scene will disappear and the objects from the second scene will appear. To make an object stay, right click the node and choose Save Branch as Scene. Then remove it from the scene and instead add it to the AutoLoad list (Project menu, Project Settings, AutoLoad tab, click the folder icon, then click Add). |
|
|
|
scale *= 10 / (scale.x * texture.get_width()) + 1 |
|
scale = Vector2(1,1) |
|
modulate.s = 1 modulate.h = wrapf(25 / 200.0 + modulate.h, 0, 1) |
|
modulate.a = clamp(modulate.a - 25 / 100.0, 0, 1) |
|
modulate.s = 0 |
|
modulate.a = 1 |
|
modulate = Color.white |
|
show() |
|
hide() |
|
You can do this by setting z_index to a higher number than all the other nodes in the scene (but never higher than 4096). |
|
You can do this by setting z_index to a lower number than all the other nodes in the scene (but never lower than -4096). |
|
z_index += 1 |
|
z_index -= 1 |
|
frame |
|
texture.resource_path |
|
Scenes in Godot don’t have numbers |
|
get_tree().current_scene.filename |
|
scale.x * texture.get_width() |
|
Add an AudioStreamPlayer node to the scene. In the inspector, load an audio resource as its Stream. stream.loop = false play() yield(self,"finished") |
|
Add an AudioStreamPlayer node to the scene. In the inspector, load an audio resource as its Stream. stream.loop = false play() |
|
You will need to do this for each AudioStreamPlayer stop() |
|
pitch_scale *= pow(1.06, 10 * 0.1) |
|
Use an AudioStreamPlayer2D instead of an ordinary AudioStreamPlayer position.x += 10 * (max_distance/100.0) |
|
pitch_scale = pow(1.06, 0 * 0.1) |
|
Use an AudioStreamPlayer2D instead of an ordinary AudioStreamPlayer position.x = 0 * (max_distance/100.0) + 512 |
|
Just do both of the lines above. |
|
volume_db = linear2db(clamp(db2linear(volume_db) - 10 / 100.0, 0, 1)) |
|
volume_db = linear2db( 50 / 100.0 ) |
|
100*db2linear(volume_db) |
|
func _ready(): |
|
func _input(event): if event is InputEventKey and event.pressed and event.scancode == KEY_SPACE: |
|
Add an Area2D as a child node of the sprite, and add a CollisionShape2D as a child node of the Area2D. In the Inspector, choose the correct shape, then in the viewport move and/or resize it to fit the sprite. Select the Area2D node, then in the Node tab, double-click the input_event signal and choose the sprite. func _on_Area2D_input_event(viewport, event, shape_idx): if event is InputEventMouseButton and event.pressed: |
|
This code will work for any objects that are not AutoLoad scenes: func _ready(): if (get_tree().current_scene.filename == "res://backdrop1.tscn"): |
|
Click Audio at the bottom of the screen, click Add Bus, click M to mute the new bus, then add a SpectrumAnalyzer effect. Add an AudioStreamPlayer node to the scene, set its Stream to New AudioStreamMicrophone, and tick Autoplay. Enable Audio Input in the Audio section of Project Settings (Project menu, Project Settings, General tab, click Audio in the list on the left then make sure Enable Audio Input is ticked). signal loudness_updated var loudness = 0 onready var bus_ei = AudioServer.get_bus_effect_instance(1, 0) func _process(delta): var AudioServer.get_bus_effect_instance(1, 0) loudness = clamp(1000*bus_ei.get_magnitude_for_frequency_range(0,10000)[0],0,100) And then put the code below in func _ready() to wait until the loudness is greater than 10:
while (loudness <= 10): yield(self, "loudness_updated") |
|
You can set up a timer in the script using this code:
signal timer_updated var timer = 0 func _process(delta): timer += delta emit_signal("timer_updated") And then put the code below in func _ready() to wait until the timer reaches 10:
while (timer <= 10): yield(self, "timer_updated") |
|
In the script for the object sending the message, define the signal: signal message1 Select the object that will send the message. In the Node tab, double-click the signal name and then choose the object that will be receiving the message. This will add the correct code to your script, which looks something like this: func _on_Sprite_message1(): |
|
emit_signal("message1") |
|
Godot doesn’t do this. |
|
In func _ready or func _input, you can use this code:
yield(get_tree().create_timer(1), "timeout") But _process runs many times per second so you need to use a timer variable to choose which code to skip when it runs:
var timer = 0 func _process(delta): if timer > 0: timer -= delta else: |
|
for n in 10: |
|
You can use _process for this because it runs many times per second:
func _process(delta): But yield doesn’t work in _process, so it’s harder to pause the code. If you want to easily pause code, use _ready:
signal forever func _ready(): while true: yield(self, "forever") And then your repeating code goes under the above code. For this to work, set up your _process like this:
func _process(delta): emit_signal("forever") |
|
if … : |
|
Godot also has elif (stands for “else if”) which you can put as many times as you like between the if and else. if … : else: |
|
Instead of stopping the loop when a condition is met, Godot keeps repeating as long as the condition is still met. while … : |
|
|
|
There are various options depending which method you want to stop. Call on each object you want to stop it for. set_process(false) set_process_input(false) |
|
|
|
|
|
func _ready(): |
|
get_parent().add_child(self.duplicate()) |
|
get_parent().add_child($"../Sprite".duplicate()) |
|
queue_free() |
|
Add an Area2D as a child node of the sprite, and add a CollisionShape2D as a child node of the Area2D. In the Inspector, choose the correct shape, then in the viewport move and/or resize it to fit the sprite. This code is actually all on one line but has been shown across multiple lines because there’s not enough space. if get_world_2d().direct_space_state.intersect_point(get_global_mouse_position(), 32, [], 2147483647, true, true).size() - get_world_2d().direct_space_state.intersect_point(get_global_mouse_position(), 32, [$Area2D], 2147483647, true, true).size() > 0: |
|
Godot doesn’t do this, but you could put Area2D objects along the edges of the screen and test whether touching those. |
|
Both sprites need to have Area2D and a CollisionShape2D or CollisionPolygon2D. if $Area2D.overlaps_area($"../Sprite/Area2D"): |
|
Godot doesn’t do this. Instead, put nodes in groups (use the Node tab next to Inspector) and check that. var overlapping_group = false for area in $Area2D.get_overlapping_areas(): if area.is_in_group("wall"): overlapping_group = true break if overlapping_group: |
|
Godot doesn’t do this. |
|
position.distance_to(get_global_mouse_position()) |
|
position.distance_to($"../Sprite".get_global_mouse_position()) |
|
Add a LineEdit, and resize and position it as desired. Then set it as invisible by clicking the eye icon. $"../LineEdit".placeholder_text = "What’s your name?" $"../LineEdit".show() yield($"../LineEdit", "text_entered") $"../LineEdit".hide() |
|
$"../LineEdit".text |
|
if Input.is_key_pressed(KEY_SPACE): |
|
if Input.is_mouse_button_pressed(BUTTON_LEFT): |
|
get_global_mouse_position().x |
|
get_global_mouse_position().y |
|
Add an Area2D as a child node of the sprite, and add a CollisionShape2D as a child node of the Area2D. In the Inspector, choose the correct shape, then in the viewport move and/or resize it to fit the sprite. Select the Area2D node, then in the Node tab, double-click the input_event signal and choose the sprite. var draggable = true var dragging = false func _on_Area2D_input_event(viewport, event, shape_idx): if event is InputEventMouseButton and event.pressed and draggable: dragging = true func _unhandled_input(event): if event is InputEventMouseButton and not event.pressed: dragging = false if dragging and event is InputEventMouseMotion: position += event.relative |
|
draggable = false |
|
For this to work, you first need to set up the loudness (see the Events section). loudness |
|
For this to work, you first need to set up the timer (see the Events section). timer |
|
For this to work, you first need to set up the timer (see the Events section). timer = 0 |
|
$"../Sprite".position.x |
|
OS.get_datetime().year |
|
OS.get_unix_time()/86400.0 - 10957 |
|
This only works in Windows. For Linux or MacOS, use OS.get_environment("USER") OS.get_environment("USERNAME") |
|
+ |
|
- |
|
* |
|
/ |
|
First, set up a random generator: var rng = RandomNumberGenerator.new() Then this will produce a random number: randi_range(1, 10) |
|
> 50 |
|
< 50 |
|
== 50 |
|
and You can also use && |
|
or You can also use || |
|
not You can also use ! |
|
"apple" + " " + "banana" |
|
Godot starts counting from 0 rather than 1. So the first letter is letter [0], the second one is [1], and so on. "apple"[0] |
|
"apple".length() |
|
"a" in "apple" |
|
% |
|
round(…) |
|
abs(…) |
|
var |
|
my_variable |
|
my_variable = 0 |
|
my_variable += 1 |
|
Add a Label node to the scene, then resize and position it as desired. In func _process for your sprite include this: $"../Label".text = str(my_variable) |
|
$"../Label".hide() |
|
An array (list) can be made by putting values between square bracket, separated by commas. For example: var my_list = ["apple", "banana", "carrot"] |
|
my_list.push_back("thing") |
|
Godot starts counting from 0 rather than 1. So the first item is item 0, the second one is item 1, and so on. my_list.remove(0) You can also erase the item from the list without knowing where it is in the list. my_list.erase("apple") |
|
my_list.clear() |
|
Godot starts counting from 0 rather than 1. So to insert the item at the start, use 0, to insert after the first item, use 1. my_list.insert(0, "thing") |
|
Godot starts counting from 0 rather than 1. So to replace the item at the start, use 0, to replace the second item, use 1. my_list.remove(0) my_list.insert(0, "thing") |
|
Godot starts counting from 0 rather than 1. So the first item is item 0, the second one is item 1, and so on. my_list[0] |
|
The result will be -1 if thing is not in the list. my_list.find("thing") |
|
my_list.size() |
|
my_list.has("thing") |
|
Add an ItemList to the scene, tick Auto Height, then resize and position as desired. In func _process include this: $"../ItemList".clear() for item in my_list: $"../ItemList".add_item(item) |
|
$"../ItemList".hide() |
|
These are called functions in Godot. The brackets are used to choose the parameters (inputs) for the function. Include an = next to the parameter to set what it will be if no value is given when the function is used. For example: func my_function(param1, param2=1): return param1+param2 The above code creates the function. Then to call (run) the function, use its name, for example this would produce 2: my_function(1) |