MonoGame
← Integre o conteúdo ao seu jogo
MonoGame 3.8 · DesktopGL · C# / .NET
Comece exibindo uma frase. Este pequeno exemplo lê diretamente a exportação real do porto; ele ainda não é um sistema completo de diálogos. Depois, conecte os dados à interface do seu jogo.
1 · Prepare os arquivos e a cena
Comece com um projeto MonoGame DesktopGL. Coloque story.json em Content/ e copie-o como arquivo bruto para o diretório de saída (veja a configuração do projeto abaixo). Adicione ReadWelcome a Game1. No Content Pipeline Tool, crie um SpriteFont chamado DialogueFont, compile o conteúdo e carregue-o com Content.Load
story.json · Entenda os arquivos exportados
2 · Exiba o primeiro texto
<ItemGroup>
<None Update="Content/story.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>Adicione os campos SpriteFont _dialogueFont; e string _dialogueLine = ""; a Game1. Em LoadContent, use _dialogueFont = Content.Load
// Game1.cs: add using System.IO; using System.Text.Json; using System.Text;
// Place this method inside the existing Game1 class.
private string ReadWelcome(string locale)
{
using var stream = TitleContainer.OpenStream("Content/story.json");
using var document = JsonDocument.Parse(stream);
var content = document.RootElement.GetProperty("content");
const string id = "fd7b61a3-8233-4ba7-8f77-b88b119a91bf";
var message = content.GetProperty("texts").GetProperty(id).GetProperty("sourceMessage");
if (content.GetProperty("translations").TryGetProperty(locale, out var table)
&& table.TryGetProperty(id, out var translation))
message = translation.GetProperty("message");
var line = new StringBuilder();
foreach (var segment in message.GetProperty("segments").EnumerateArray())
{
if (segment.GetProperty("kind").GetString() != "text")
throw new InvalidDataException("Text-only example");
line.Append(segment.GetProperty("text").GetString());
}
return line.ToString();
}Resultado esperado: “Welcome to the harbour. I am Mira.” Com locale = "de" ou o parâmetro de idioma de: “Willkommen im Hafen. Ich bin Mira.” Se o idioma não estiver disponível, será usado o texto original. Este exemplo aceita segmentos de texto e não descarta placeholders silenciosamente.
3 · De uma frase a uma conversa
O ID de texto fixo acima serve para o primeiro teste. No seu jogo, escolha flowRef/entryRef em story-index.json, leia execution.entries[entryRef].nodeRef e depois execution.nodes[nodeRef]. O diálogo atual fornece text.textRef e speakerRef. A continuação depende do tipo de nó.
Nome e diálogo: SpriteBatch.DrawString entre Begin/End. Cuide da quebra de linha e dos caracteres disponíveis na fonte para textos longos. As áreas de resposta e a entrada de mouse e teclado pertencem ao jogo; preserve os IDs em vez de usar o texto traduzido. End: desative desenho e entrada com dialogueOpen = false, não com Game.Exit().
- Continue e End: siga as conexões e feche a caixa de texto
- Escolhas: ID da resposta, ordem e continuação selecionada
- Condições e variáveis: dez ou duas moedas de ouro
- Idioma: mesmos IDs, conteúdo resolvido novamente
- Command: entregar um item ou abrir uma loja
- Call/Return: entrar em uma sub-história e voltar
Examine as respostas e a verificação de ouro nesta linguagem
Leia os dados de uma escolha
Insira este trecho onde story estiver disponível após o carregamento (no RPG Maker: const story = $gameTemp.vnleExample.story;). Ele exibe IDs para conferência. Substitua a saída pelos seus botões de resposta. O trecho cobre as duas respostas do porto e a verificação de ouro seguinte; não é um interpretador genérico.
// Inside ReadWelcome while document is alive; inspect data before returning.
var nodes = document.RootElement.GetProperty("execution").GetProperty("nodes");
var choice = nodes.GetProperty("42edfff8-b8fe-46bf-ae0d-9e2347b6e726");
foreach (var idToken in choice.GetProperty("optionOrder").EnumerateArray())
{
string optionId = idToken.GetString();
var option = choice.GetProperty("options").GetProperty(optionId);
System.Console.WriteLine(optionId + " " + option.GetProperty("text").GetProperty("textRef").GetString());
}
var branch = nodes.GetProperty("c1c3c372-0a73-4cd0-851d-ede59d5709bb");
int gold = 10; // Repeat with 2.
int minimum = branch.GetProperty("condition").GetProperty("right").GetProperty("value").GetProperty("value").GetInt32();
var next = branch.GetProperty(gold >= minimum ? "whenTrue" : "whenFalse");
System.Console.WriteLine(next.GetProperty("nodeRef").GetString());
// Copy strings/values you need later before disposing JsonDocument.Com 10 moedas de ouro, next aponta para Pay five gold; com 2, para Not enough gold. No jogo, execute a verificação somente quando o caminho escolhido chegar a esse nó. Cada resposta tem sua própria continuação.
4 · Mapeie suas próprias imagens
Este trecho complementar espera um objeto de diálogo atual chamado node e os elementos de interface indicados nos comentários. Em C++ e MonoGame, speakerRef já foi lido como SpeakerId ou speakerId. A chave do mapeamento é o ID real da personagem Mira; o nome e a localização da imagem pertencem ao seu jogo. Insira as linhas nos locais indicados.
// Game1 class field, so both LoadContent and Draw can access it:
private readonly System.Collections.Generic.Dictionary<string, Texture2D> portraits = new();
// Inside LoadContent(): import/build mira.png as portraits/mira.
portraits["807b2957-7bab-4a28-83a4-1f3d1589bbc2"] = Content.Load<Texture2D>("portraits/mira");
// Inside a SpriteBatch Begin/End in Draw; speakerId comes from speakerRef:
if (portraits.TryGetValue(speakerId, out var portrait))
_spriteBatch.Draw(portrait, new Vector2(24, 120), Color.White);Resolva o nome do personagem por content.characters[speakerRef].nameTextRef, como faz com o texto do diálogo. Se faltar um mapeamento, o jogo deve ocultar o retrato anterior ou mostrar uma imagem substituta. As imagens não são selecionadas pelo idioma.
Use as referências de imagem da exportação completa
5 · Distribua os arquivos com o jogo
Não use Content.Load para carregar o JSON neste exemplo. TitleContainer abre o arquivo bruto; o csproj o copia. Compile SpriteFont e texturas pelo Content Pipeline. Comece pelo DesktopGL e verifique as outras plataformas separadamente.
Confira o resultado
- As saudações em inglês e alemão devem aparecer corretamente; um idioma indisponível deve usar o inglês.
- Ao implementar o fluxo, teste as duas respostas, 10 e 2 moedas de ouro, a volta da sub-história e End.
- Execute o jogo compilado fora da pasta do projeto. JSON, fontes e retratos também devem estar disponíveis ali.
Documentação oficial
Referências de API e configuração usadas nesta abordagem: