Meu primeiro contato com a programação foi com a criação de jogos. Na época, eu não sabia muito sobre como funcionava o mundo da criação de jogos, quem diria da programação. Mas com o tempo, meu conhecimento na programação evoluiu enquanto a de desenvolver jogos ficou de lado. Foi só depois de muito tempo que voltei a explorar o mundo dos jogos e a desenvolver pequenos joguinhos de teste onde movimentava um personagem, criava uns objetos ali e aqui e então mostrava tudo na tela.
A verdade é que o assunto de desenvolvimento de jogos é complexo, não é apenas criar objetos na tela, mas também fazê-los parecerem críveis de que são mais do que simples código, o grande problema e dilema é que para um programador, visualizar seu código além da lógica básica pode ser mais difícil do que parece ser. Por isso, quando desenvolvi o meu livro sobre criação de jogos, eu coloquei Python e a Raylib como o primeiro contato de um programador e um iniciante com o mundo dos jogos. Mas existe um motivo tanto pessoal quanto motivacional por trás dessa escolha.
Criar jogos deve ser divertido
Quando eu fiz essa escolha, eu decidi olhar para o que mais chama atenção em criar um jogo: a diversão. Ninguém quer um jogo que não seja minimamente divertido, e foi nisso que foquei. Esse protótipo da foto foi apenas eu me divertindo enquanto escrevia um código onde uma tecla criava blocos e a outra removia, enquanto na criação eu poderia mover o bloco para qualquer lugar.
Sim, pode dizer que é uma ideia tosca e sem graça do ponto de vista de um jogador, mas é o mínimo produto viável, ou MVP, de qualquer outro projeto que seja levado a sério. É em conceitos simples assim que foi criado jogos maiores, como o Minecraft. E ao longo do meu treino e aprendizado com a Raylib e outras bibliotecas de criação de jogos, como Macroquad e PyGame, eu criei um protótipo de um jogo baseado em voxels, assim como o Minecraft.
Mas e a Godot?
A Godot Engine é um motor (Engine do inglês para o português). O que difere é as capacidades que a Godot tem por cima da Raylib, Macroquad, PyGame, entre outros. Essas outras ferramentas são bibliotecas, ou frameworks, onde uma base já foi estabelecida e você só precisa coordenar essa base em direção ao seu projeto.
Frameworks e game engine própria
A ideia é que você não vai precisar escrever linha por linha uma função para desenhar um quadrado na tela, você apenas vai desenhar o quadrado com seu framework preferido. O framework cuida de se comunicar com a placa de vídeo e transferir dados para ela enquanto você se preocupa com o tema e as funcionalidades do seu jogo.
Existe uma piada no X que compartilhei um tempo atrás que retrata essa ideia. Muitos optam sim por criar seu próprio framework para seus jogos, mas isso custa tempo e aprendizado que muita das vezes não vai ser tão necessário assim.
Game devs depois de 17 semanas trabalhando na sua própria game engine
![]()
Vou ser sincero, criar uma “game engine” é uma experiência e tanto, assim como utilizar Linux no dia a dia, mas ambos demandam o mesmo tempo e dedicação para fazer uma simples configuração. E olha que eu gosto de Linux! Não confundam minhas palavras, mas acho muito prático as ferramentas que o Windows tem que o Linux simplesmente não tem, fora que hoje em dia tem WSL que é uma mão na roda dos desenvolvedores que precisam do Linux.
Onde a Godot se destaca!
Mas quando se trata de criar jogos, uma game engine pronta se destaca porque de uma forma ou de outra, você fará o mesmo trabalho que a game engine faz a longo prazo. É claro, fica bem mais complexo quando você eleva um game para o âmbito da game engine, mas o conceito geral continua simples, ainda mais com a Godot. Vejamos alguns exemplos:
1. A Godot usa um sistema baseado em nós
Isso quer dizer que cada objeto do nosso jogo possui um processamento individual de suas características e funções. Podemos pegar um exemplo do meu livro sobre desenvolvimento de jogos no qual criamos o Pong:
from pyray import *
import random
init_window(800, 450, "Pong")
# Propriedades
player_speed = 5
p1_pos_x = 10
p1_pos_y = 225 - 20
p2_pos_x = 780
p2_pos_y = 225 - 20
p1_score = 0
p2_score = 0
ball_pos_x = 400
ball_pos_y = 225
ball_radius = 10
ball_speed = random.randrange(5, 10)
ball_dir_x = random.uniform(-1, 1)
ball_dir_y = random.uniform(-1, 1)
set_target_fps(60)
# Rotina do jogo
while not window_should_close():
# Controles
if is_key_down(KeyboardKey.KEY_S):
p1_pos_y += player_speed
elif is_key_down(KeyboardKey.KEY_W):
p1_pos_y -= player_speed
if is_key_down(KeyboardKey.KEY_DOWN):
p2_pos_y += player_speed
elif is_key_down(KeyboardKey.KEY_UP):
p2_pos_y -= player_speed
# Bola
if ball_pos_y >= 450 or ball_pos_y <= 0:
ball_dir_y = -ball_dir_y
if check_collision_recs(
Rectangle(ball_pos_x, ball_pos_y, ball_radius, ball_radius),
Rectangle(p1_pos_x, p1_pos_y, 10, 40),
) or check_collision_recs(
Rectangle(ball_pos_x, ball_pos_y, ball_radius, ball_radius),
Rectangle(p2_pos_x, p2_pos_y, 10, 40),
):
ball_dir_x = -ball_dir_x
ball_dir_y = random.uniform(-1, 1)
ball_speed = random.randrange(5, 10)
ball_pos_x += int(ball_dir_x * ball_speed)
ball_pos_y += int(ball_dir_y * ball_speed)
if ball_pos_x > 820:
p1_score += 1
ball_pos_x = 400
ball_pos_y = 225
ball_speed = random.randrange(5, 10)
ball_dir_x = random.uniform(-1, 1)
ball_dir_y = random.uniform(-1, 1)
elif ball_pos_x < -10:
p2_score += 1
ball_pos_x = 400
ball_pos_y = 225
ball_speed = random.randrange(5, 10)
ball_dir_x = random.uniform(-1, 1)
ball_dir_y = random.uniform(-1, 1)
# Renderização
begin_drawing()
clear_background(BLACK)
draw_rectangle(
p1_pos_x,
p1_pos_y,
10,
40,
WHITE
)
draw_rectangle(
p2_pos_x,
p2_pos_y,
10,
40,
WHITE
)
draw_rectangle(
ball_pos_x,
ball_pos_y,
ball_radius,
ball_radius,
WHITE
)
draw_text(f"{p1_score}", 340, 10, 40, WHITE)
draw_text(f"{p2_score}", 440, 10, 40, WHITE)
end_drawing()
close_window()
Perceba que nesse projeto acima colocamos todas as propriedades dentro de um único arquivo, já na Godot, poderíamos colocar as diferentes propriedades em cada um dos objetos. A estrutura da nossa cena ficaria mais ou menos assim:
- Node2D (Cena Principal)
- PaddleP1 (CharacterBody2D)
- PaddleP2 (CharacterBody2D)
- Ball (CharacterBody2D)
Cada um com seu próprio script. Vamos dar uma olhada no script do Paddle do Player 1, que também funciona como script para o Player 2! Vejamos:
# Paddle.gd
extends KinematicBody2D
@export var speed = 300
@export var player_number = 1 # Define se é o Player 1 ou 2
func _process(delta):
if player_number == 1:
if Input.is_action_pressed("p1_up"):
move_local_y(-speed * delta)
if Input.is_action_pressed("p1_down"):
move_local_y(speed * delta)
elif player_number == 2:
if Input.is_action_pressed("p2_up"):
move_local_y(-speed * delta)
if Input.is_action_pressed("p2_down"):
move_local_y(speed * delta)
Com esse código, tudo fica mais organizado. Tanto a velocidade quanto a identificação se tornam propriedades, recursos que são editáveis direto do editor, sem precisar alterar o código. E você pode fazer com que essa propriedade seja diferente para cada cena, criando modos de jogo diferentes.
Vamos ver outro exemplo com a bola:
# Ball.gd
extends KinematicBody2D
var speed = Vector2(200, 200)
func _ready():
reset_ball()
func _process(delta):
position += speed * delta
# Colisão com as bordas superior e inferior
if position.y <= 0 or position.y >= 450:
speed.y = -speed.y
func reset_ball():
position = Vector2(400, 225)
speed = Vector2(randf_range(-200, 200), randf_range(-200, 200))
Tanto a bola como os jogadores tem seu próprio script que é executado durante a execução do jogo. Não é mais aquela bagunça de um script só! Além disso, como pode ver, existe outra característica que a Godot faz bem.
2. Cada nó possui sua própria lógica base
Outra economia que temos é a colisão da bola com o jogador e vice versa. Usando o nó KinematicBody2D, a Godot gerenciará a lógica de colisão por nós, e poderíamos até mesmo fazer isso com a bola adicionando o nó StaticBody2D e um CollisionShape dentro desse nó para indicar onde ficam as bordas da tela e até onde a bola pode ir.
Além disso, podemos usar um Sprite2D para desenhar tanto a bola quanto os jogadores. Sim, ainda precisamos de uma imagem para fazer isso, mas é muito mais simples do que desenhar utilizando código.
Mesmo que você seja uma pessoa um tanto teimosa com relação a isso, a Godot também permite que você desenhe diretamente do código e gerencie outras propriedades através de um node só, o que não é nada ruim, pois existem diferentes necessidades para diferentes jogos. Dê uma olhada na documentação (Em inglês).
3. Editor visual para cenas
Caso você esteja planejando criar jogos com mundos estáticos, fases e outros recursos, muito provavelmente você vai querer um editor para gerenciar onde cada objeto estará na cena. Isso é diferente no caso de jogos que possui mundos procedurais ou fases simples, mas jogos com grandes podem necessitar de um editor de fases, e com o editor da Godot, você pode fazer isso e muito mais!
Você pode criar cutscenes com nodes como Path2D e AnimationPlayer, gerenciar diálogos com plugins, criar fases complexas com inimigos, itens e muitos outros posicionados da forma como deseja, etc.
No geral, foi por isso que me apaixonei na Godot, e a próxima versão do meu livro vai sim trazer um pouco desse mundo para os iniciantes. Mas pode ficar calmo! A longo prazo, vamos aprender as coisas por partes, desde o conceito de nós até nossa própria implementação da mesma. E quem sabe… criar um jogo como o meu, né? 😉
Aliás, falando dele…
Ginodian: Star Heroes (A sequência de Ginodian: Base Defender)
Já faz um tempo que criei meu primeiro jogo, porque não uma sequência? 🤭
Embora Ginodian: Base Defender não tenha recebido oficialmente uma história, com Ginodian: Star Heroes, ambos os jogos recebem uma história de fundo que será contada em detalhes em breve!
Após a humanidade ascender aos céus para fugir de uma grande calamidade na Terra, séculos se passaram e os humanos e outras raças alienígenas criaram suas relações, seja de inimizade ou de aliança. Ginodian: Star Heroes acompanhará a história de Jack Grawler, um mercenário criminoso que faz qualquer coisa por dinheiro, junto de sua tripulação, Tico Magnum e Cass Sparrow, além de Geany Solaris, uma prisioneira com um objetivo nobre.
Você pode baixar e jogar Ginodian: Base Defender na Gamejolt. Você também pode acompanhar o desenvolvimento e as atualizações de Ginodian: Star Heroes também na Gamejolt!
Mas por que terceiro jogo?
Recentemente eu criei um jogo apenas como piada usando Python, porém não vou revelar que jogo é, você poderá ver o jogo no meu perfil, se encontrá-lo! 🤫
Conclusão
Com tudo que falamos até aqui, concluímos algumas coisas:
- Criar um jogo é difícil, mas não impossível;
- Game Engines facilitam muito o trabalho de criar um jogo, mas ao mesmo tempo pode demandar um tempo para aprender;
- Frameworks dão grande liberdade para criar um jogo, mas o produto mínimo viável pode demandar mais tempo para criar e desenvolver, dependendo da ideia que você quer desenvolver.
Mesmo assim, espero que nenhuma dessas coisas atrapalhem você ou eu de criar aquilo que sonhamos em criar, e espero que em breve, possamos falar mais sobre game dev nos próximos posts! 😊
Comentários
Você precisa estar logado para comentar.