Creating your first script

Nesta lição, você irá programar seu primeiro script para fazer o ícone do Godot girar em círculos usando GDScript. Como nós mencionamos na introdução, assumimos que você tem os fundamentos de programação. O código em C# equivalente será incluído em outra aba para conveniência.

../../_images/scripting_first_script_rotating_godot.gif

Ver também

Para aprender mais sobre GDScript, suas palavras-chave, e sua sintaxe, vá para a referência GDScript.

Ver também

To learn more about C#, head to the C# basics page.

Configuração do projeto

Crie um novo projeto para começar do zero. Seu projeto deve conter uma imagem: o ícone Godot, que costumamos usar para prototipagem na comunidade.

Nós precisamos criar um nó de Sprite para mostrá-lo no jogo. No painel de cena, clique em "Outro Nó".

../../_images/scripting_first_script_click_other_node.png

Digite "Sprite" na barra de pesquisa para filtrar os nós e clique duas vezes no Sprite para criar o nó.

../../_images/scripting_first_script_add_sprite_node.png

Sua aba de cena agora deve ter apenas um nó Sprite.

../../_images/scripting_first_script_scene_tree.png

Um nó Sprite precisa de uma textura para mostrá-lo. No inspetor na direita, você pode ver que a propriedade Texture diz "[vazio]". Para mostrar o ícone do Godot, clique e arraste o arquivo icon.png do painel de Arquivos para o slot de Texture.

../../_images/scripting_first_script_setting_texture.png

Nota

Você pode criar nós Sprite automaticamente arrastando e soltando imagens no viewport.

../../_images/scripting_first_script_dragging_sprite.png

E então, clique e arraste o ícone no viewport para centralizá-lo na visualização do jogo.

../../_images/scripting_first_script_centering_sprite.png

Creating a new script

Para criar e anexar um novo script para o nosso nó, clique com botão direito no Sprite no painel de cena e selecione "Adicionar Script".

../../_images/scripting_first_script_attach_script.png

The Attach Node Script window appears. It allows you to select the script's language and file path, among other options.

Mude o modelo do Padrão para Vazio para começar com um arquivo vazio. Deixe as outras opções no padrão e clique em Criar para criar o script.

../../_images/scripting_first_script_attach_node_script.png

O espaço de trabalho do script deve aparecer com o seu novo arquivo Sprite.gd aberto com a seguinte linha de código:

extends Sprite

Todo arquivo GDScript é implicitamente uma classe. A palavra-chave extends``define qual classe este script herda ou estende. Neste caso, é o ``Sprite, significa que nosso script terá acesso a todas as propriedades e funções do nó Sprite, incluindo as classes que a estende, como Node2D, CanvasItem, e Node.

Nota

No GDScript, se você omitir a linha com a palavra-chave extends, sua classe vai implicitamente estender Reference, que o Godot usa para gerenciar a memória do seu aplicativo.

Propriedades herdadas inclui as que você pode ver no painel Inspetor, que nem o texture do nosso nó.

Nota

By default, the Inspector displays a node's properties in "Title Case", with capitalized words separated by a space. In GDScript code, these properties are in "snake_case", which is lowercase with words separated by an underscore.

You can hover any property's name in the Inspector to see a description and its identifier in code.

Hello, world!

Our script currently doesn't do anything. Let's make it print the text "Hello, world!" to the Output bottom panel to get started.

Add the following code to your script:

func _init():
    print("Hello, world!")

Let's break it down. The func keyword defines a new function named _init. This is a special name for our class's constructor. The engine calls _init() on every object or node upon creating it in memory, if you define this function.

Nota

GDScript is an indent-based language. The tab at the start of the line that says print() is necessary for the code to work. If you omit it or don't indent a line correctly, the editor will highlight it in red and display the following error message: "Indented block expected".

Save the scene if you haven't already, then press F6 (Cmd + R on macOS) to run it. Look at the Output bottom panel that expands. It should display "Hello, world!".

../../_images/scripting_first_script_print_hello_world.png

Delete the _init() function, so you're only left with the line extends Sprite.

Turning around

It's time to make our node move and rotate. To do so, we're going to add two member variables to our script: the movement speed in pixels per second and the angular speed in radians per second.

var speed = 400
var angular_speed = PI

Member variables sit near the top of the script, after any "extends" lines, but before functions. Every node instance with this script attached to it will have its own copy of the speed and angular_speed properties.

Nota

Angles in Godot work in radians by default, but you have built-in functions and properties available if you prefer to calculate angles in degrees instead.

To move our icon, we need to update its position and rotation every frame in the game loop. We can use the _process() virtual function of the Node class. If you define it in any class that extends the Node class, like Sprite, Godot will call the function every frame and pass it an argument named delta, the time elapsed since the last frame.

Nota

Games work by rendering many images per second, each called a frame, and they do so in a loop. We measure the rate at which a game produces images in Frames Per Second (FPS). Most games aim for 60 FPS, although you might find figures like 30 FPS on slower mobile devices or 90 to 240 for virtual reality games.

The engine and game developers do their best to update the game world and render images at a constant time interval, but there are always small variations in frame render times. That's why the engine provides us with this delta time value, making our motion independent of our framerate.

At the bottom of the script, define the function:

func _process(delta):
    rotation += angular_speed * delta

The func keyword defines a new function. After it, we have to write the function's name and arguments it takes in parentheses. A colon ends the definition, and the indented blocks that follow are the function's content or instructions.

Nota

Notice how _process(), like _init(), starts with a leading underscore. By convention, Godot's virtual functions, that is to say, built-in functions you can override to communicate with the engine, start with an underscore.

The line inside the function, rotation += angular_speed * delta, increments our sprite's rotation every frame. Here, rotation is a property inherited from the class Node2D, which Sprite extends. It controls the rotation of our node and works with radians.

Dica

In the code editor, you can ctrl-click on any built-in property or function like position, rotation, or _process to open the corresponding documentation in a new tab.

Run the scene to see the Godot icon turn in-place.

../../_images/scripting_first_script_godot_turning_in_place.gif

Moving forward

Let's now make the node move. Add the following two lines to the _process() function, ensuring the new lines are indented the same way as the one before them.

var velocity = Vector2.UP.rotated(rotation) * speed

position += velocity * delta

As we already saw, the var keyword defines a new variable. If you put it at the top of the script, it defines a property of the class. Inside a function, it defines a local variable: it only exists within the function's scope.

We define a local variable named velocity, a 2D vector representing both a direction and a speed. To make the node move forward, we start from the Vector2 class's constant Vector2.UP, a vector pointing up, and rotate it by calling the Vector2.rotated() method. This expression, Vector2.UP.rotated(rotation), is a vector pointing forward relative to our icon. Multiplied by our speed property, it gives us a velocity we can use to move the node forward.

We add velocity * delta to the node's position to move it. The position itself is of type Vector2, a built-in type in Godot representing a 2D vector.

Run the scene to see the Godot head run in circles.

../../_images/scripting_first_script_rotating_godot.gif

Nota

Moving a node like that does not take into account colliding with walls or the floor. In Seu primeiro jogo 2D, you will learn another approach to moving objects while detecting collisions.

Our node currently moves by itself. In the next part Listening to player input, we'll use player input to control it.

Complete script

Here is the complete Sprite.gd file for reference.

extends Sprite

var speed = 400
var angular_speed = PI


func _process(delta):
    rotation += angular_speed * delta

    var velocity = Vector2.UP.rotated(rotation) * speed

    position += velocity * delta