image

Bootcamps ilimitados + curso de inglês para sempre

80
%OFF
Article image
Arthur Silva
Arthur Silva04/06/2024 14:44
Compartilhe
Microsoft 50 Anos - Prompts InteligentesRecomendados para vocêMicrosoft 50 Anos - Prompts Inteligentes

Gerando Números Aleatórios no Godot Engine

  • #Godot

Gerar números aleatórios é essencial em muitos jogos e apps. Pense em como criar comportamentos imprevisíveis para inimigos, distribuir itens aleatoriamente, ou qualquer outra situação onde você queira um pouco de sorte envolvida. O Godot facilita muito a geração desses números aleatórios. Neste artigo, vamos explorar algumas formas de fazer isso no Godot.

Introdução

O Godot possui uma classe chamada `RandomNumberGenerator` que facilita a geração de números aleatórios. Esta classe contém funções específicas para gerar números aleatórios e será o foco deste artigo.

As funções da `RandomNumberGenerator` podem ser chamadas diretamente na maioria dos scripts criados em GDScript. No entanto, caso você queira um maior controle ou esteja utilizando um script que não herda das classes nativas do Godot, essa classe pode ser instanciada da seguinte forma:

var rng = RandomNumberGenerator.new()

Você pode definir uma semente (seed) para o gerador de números aleatórios se quiser garantir que os resultados sejam reproduzíveis.

rng.randomize() 

ou, para a classe global, apenas

randomize() 

Esta função configura uma semente baseada no tempo, utilizando a hora atual do sistema. A semente é um valor inicial que determina a sequência de números aleatórios gerados. Se você usar a mesma semente, obterá a mesma sequência de números aleatórios.

Números Inteiros

Para gerar um número inteiro aleatório no Godot, você pode usar duas funções: `randi` e `randi_range`.

- `randi()`: Esta função retorna um número natural de 32 bits, ou seja, um número entre 0 e 4.294.967.295. É uma solução simples para gerar números iniciando em zero.

- `randi_range(int from, int to)`: Esta função é ideal quando você precisa que o valor inicial não seja zero. Nela, você especifica os valores inicial (`from`) e final (`to`) do intervalo de números que deseja sortear.

extends Node

func _ready():
 # Opcional: Definindo uma semente (seed) para o gerador
 randomize()

 # Gerando um número inteiro aleatório entre 0 e 10 com randi
 var random_int = randi() % 11
 print("Número inteiro aleatório entre 0 e 10: ", random_int )

 # Gerando um número inteiro aleatório entre 0 e 10 com randi_range
 var random_int_range = randi_range(0, 10)
 print("Número inteiro aleatório entre 0 e 10: ", random_int_range )

 # Gerando um número inteiro aleatório entre 15 e 65 com randi_range
 var random_int_range_2 = randi_range(15, 65)
 print("Número inteiro aleatório entre 15 e 65: ", random_int_range_2 )

Números de Ponto Flutuante

Assim como nos números inteiros, o Godot fornece duas funções para gerar números aleatórios de ponto flutuante: `randf` e `randf_range`.

- `randf()`: Esta função retorna um número no intervalo de 0.0 a 1.0. É uma solução simples para gerar números começando em zero.

- `randf_range(float from, float to)`: Esta é a função para quando você precisa que o valor inicial não seja zero. Nela, você especifica os valores inicial (`from`) e final (`to`) do intervalo de números que deseja sortear.

extends Node

func _ready():

 # Gerando um número de ponto flutuante aleatório entre 0 e 10 com randf
 var random_float = randf() * 10
 print("Número de ponto flutuante aleatório entre 0 e 10: ", random_float)

 # Gerando um número de ponto flutuante aleatório entre 1.5 e 6.5 com randf_range
 var random_float_range = randf_range(1.5, 6.5)
 print("Número de ponto flutuante aleatório entre 1.5 e 6.5: ", random_float_range)

Distribuição normal

Outra opção fornecida pelo Godot é a função randfn. Ela retorna um número aleatório com distribuição normal, utilizando a transformação de Box-Muller, onde é possível definir a média e o desvio padrão. Esse tipo de distribuição é comumente conhecido como distribuição Gaussiana.

Aleatoriedade ponderada

Aleatoriedade ponderada é uma ferramenta muito útil, porém, o Godot não oferece nativamente uma maneira de atribuir pesos às opções a serem sorteadas. Exceto pela função 'randfn', que atribui um peso maior às opções centrais, nas funções rand*, cada número tem a mesma probabilidade de ser escolhido.

Este é um problema amplamente reconhecido, e vou apresentar uma solução simples utilizando as funções mencionadas anteriormente.

extends Node

func weight_rand(weigths: Array[float]) -> int:

 # Soma os valores do vetor
 var total = weigths.reduce(func(a: float, b: float): return a + b)

 # Verifica o tamanho do vetor 
 var size = weigths.size()

 # Gera um número aleatório
 var random = randf() * total

 # Retorna o índice referente ao valor gerado
 var cumulative_weight = 0.0
 for index in size:
     cumulative_weight += weights[index]

     # Verifica se o número atende às condições
     if random <= cumulative_weight:
         return index

 # Retorna o último índice caso o valor aleatório ultrapasse o limite
 return weights.size() - 1


func _ready():
 # Vetor dos itens a serem sorteados
 var items = [‘gold’, ’meat’, ‘bone’, ‘potion’]
 var item_chance = [5, 3, 1.5, 0.5] 
 var random_index = weight_rand(item_chance)
 print("O item escolhido foi: ", items[random_index])

Explicando o exemplo

A função `weight_rand` recebe um array de pesos (`weights`) como entrada e retorna um índice correspondente ao item sorteado.

Para calcular a soma dos valores do vetor, recorremos à função reduce, que simplifica os valores de um vetor a um único número, baseado em uma função fornecida. Aqui, empregamos uma função anônima que aceita dois números e os soma, resultando na soma total dos valores do vetor. Essa abordagem nos permite obter a soma de maneira dinâmica, independentemente do tamanho ou dos valores dos elementos no vetor.

Essa soma representa o nosso total de 100%. Dessa forma, `randf() * total` fornece um valor aleatório entre 0 e o total (a soma dos valores do vetor).

No loop, iteramos sobre cada item do vetor e verificamos se o número aleatório gerado é menor ou igual à soma dos pesos até aquele item. Se for, retornamos o índice do item. Caso contrário, continuamos para o próximo item.

É importante ressaltar que todos os itens devem ter pesos positivos. Se houver algum erro e não for possível encontrar o valor correto, a função retorna o índice do último item.

Conclusão

Gerar números aleatórios no Godot é uma tarefa simples e poderosa graças à classe `RandomNumberGenerator`. Esta classe oferece uma excelente base que você pode expandir para atender a demandas mais complexas em seus projetos de jogos. Com a capacidade de personalizar a distribuição de números aleatórios e até mesmo implementar sorteios ponderados, você tem um grande controle sobre o aspecto da aleatoriedade em seu jogo, proporcionando uma experiência única e envolvente para seus jogadores.

Fontes:

Manual Godot

Imagem do banner

Compartilhe
Recomendados para você
Microsoft 50 Anos - Prompts Inteligentes
Microsoft 50 Anos - GitHub Copilot
Microsoft 50 Anos - Computação em Nuvem com Azure
Comentários (0)
Recomendados para vocêMicrosoft 50 Anos - Prompts Inteligentes