<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Como Programar Jogos · Game Developer</title><link>https://gamedeveloper.com.br/categories/como-programar-jogos/</link><description>Como Programar Jogos · Desenvolvimento de jogos por Bruno Cicanci</description><generator>Hugo</generator><language>pt-BR</language><copyright>© 2009–2026 Game Developer por Bruno Cicanci. Todos os direitos reservados.</copyright><lastBuildDate>Sun, 13 Jul 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://gamedeveloper.com.br/categories/como-programar-jogos/rss.xml" rel="self" type="application/rss+xml"/><item><title>SDL3 com Visual Studio, git submodule, e GitHub Workflow</title><link>https://gamedeveloper.com.br/sdl3-git-submodule-github-workflow/</link><guid>https://gamedeveloper.com.br/sdl3-git-submodule-github-workflow/</guid><pubDate>Sun, 13 Jul 2025 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Após minha graduação em Ciência da Computação, iniciei uma pós-graduação em Produção e Programação de Jogos com o objetivo de mudar minha carreira e entrar na indústria de jogos. Isso foi em 2009, e uma das primeiras ferramentas de desenvolvimento de jogos que tive contato foi o SDL2, onde fiz o meu primeiro projeto de game com SDL e C++ em uma disciplina da pós-graduação. De lá pra cá utilizei o SDL em diversos projetos, principalmente game jams e para aprender a programar homebrew para Nintendo DS e PSP, e sempre foi um framework fácil de usar e bem completo para jogos 2D.&#10;</description><content:encoded>&lt;p&gt;Após minha graduação em Ciência da Computação, iniciei uma pós-graduação em Produção e Programação de Jogos com o objetivo de mudar minha carreira e entrar na indústria de jogos. Isso foi em 2009, e uma das primeiras ferramentas de desenvolvimento de jogos que tive contato foi o SDL2, onde fiz o meu &lt;a href="https://gamedeveloper.com.br/primeiro-projeto-de-game-com-sdl-e-c/" &gt;primeiro projeto de game com SDL e C++&lt;/a&gt; em uma disciplina da pós-graduação. De lá pra cá utilizei o &lt;a href="https://www.libsdl.org/" target="_blank" rel="noreferrer"&gt;SDL&lt;/a&gt; em diversos projetos, principalmente game jams e para aprender a programar &lt;a href="https://gamedeveloper.com.br/hello-world-no-nintendo-ds/" &gt;homebrew para Nintendo DS&lt;/a&gt; e PSP, e sempre foi um framework fácil de usar e bem completo para jogos 2D.&lt;/p&gt;&#10;&lt;p&gt;Criar um projeto novo utilizando Visual Studio e configurar o SDL2 era um pouco mais trabalhoso, e inclusive &lt;a href="https://gamedeveloper.com.br/hello-world-sdl-visual-studio/" &gt;escrevi este tutorial&lt;/a&gt; pra mim mesmo por que eu sempre esquecia de algum passo. Alguns meses atrás, o SDL3 foi oficialmente lançado, e trouxe algumas mudanças para simplificar o desenvolvimento de jogos e sua configuração. Neste post vou mostrar como criar um projeto novo no Visual Studio, adicionar o SDL3 como uma dependência usando &lt;code&gt;git submodule&lt;/code&gt;, configurar o projeto para compilar um &lt;em&gt;Hello World&lt;/em&gt;, e como automatizar builds em cada commit utilizando &lt;em&gt;GitHub Workflows&lt;/em&gt;.&lt;/p&gt;&#10;&#10;&lt;h2 class="relative group"&gt;SDL como dependência usando git submodule&#10; &lt;div id="sdl-como-dependência-usando-git-submodule" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#sdl-como-depend%c3%aancia-usando-git-submodule" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;A parte mais importante de todo este post é este primeiro passo, pois aqui vamos configurar o projeto como um repositório &lt;a href="https://git-scm.com/" target="_blank" rel="noreferrer"&gt;git&lt;/a&gt; e adicionar o &lt;a href="https://github.com/libsdl-org/SDL" target="_blank" rel="noreferrer"&gt;SDL3&lt;/a&gt; como um &lt;a href="https://git-scm.com/book/en/v2/Git-Tools-Submodules" target="_blank" rel="noreferrer"&gt;submodule&lt;/a&gt;. Existem diversos conteúdos muito bons sobre git, então não vou alongar muito com uma introdução, e vamos direto ao ponto. Caso não tenha git na sua máquina, você pode &lt;a href="https://git-scm.com/downloads" target="_blank" rel="noreferrer"&gt;instalar aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;Primeiro, precisamos criar um repositório local. Os comandos abaixo são os mesmos em qualquer sistema operacional, mas como vamos utilizar o Visual Studio neste tutorial, pode assumir que estou utilizando Windows. Criei um novo diretório no seu computador com o nome &lt;code&gt;HelloWorldSDL3&lt;/code&gt;. Após criar o diretório, abra o prompt de comandos do Windows (&lt;em&gt;cmd&lt;/em&gt; ou &lt;em&gt;power shell&lt;/em&gt;), nave até a nova pasta criada e, dentro dela, execute o comando abaixo:&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;Este commando vai criar uma pasta invisível chamada &lt;code&gt;.git&lt;/code&gt;. Caso algum erro aconteça, como comando não encontrado, certifique-se que o git foi instalado e está adicionado no &lt;code&gt;path&lt;/code&gt; do Windows. Em seguida, vamos adicionar o repositório do SDL como um submodule usando os comandos abaixo:&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;submodule&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;libsdl-org&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;SDL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;git&lt;/span&gt; &lt;span class="n"&gt;SDL&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;Este comando vai adicionar um arquivo &lt;code&gt;.gitmodules&lt;/code&gt; com uma referência do SDL no repositório local, e baixar o projeto em uma pasta chamada SDL. Se tudo der certo, seu diretório deverá estar com esta estrutura abaixo:&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;HelloWorldSDL3/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── .git/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── SDL/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── .gitmodules&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;Neste momento você pode criar um repositório no &lt;a href="https://github.com/" target="_blank" rel="noreferrer"&gt;GitHub&lt;/a&gt; (necessário criar uma conta gratuita se não tiver). No meu exemplo abaixo, estou criando um repositório público com o nome &lt;code&gt;hello-world-sdl&lt;/code&gt;, e não selecionei nenhuma opção para inicializar o repositório com algum arquivo.&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2025/05/github-repository.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;Depois de criar o repositório, volte para o prompt de comandos e digite os seguintes comandos (substitua &lt;code&gt;USERNAME&lt;/code&gt; pelo seu usuário no github):&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;commit&lt;/span&gt; &lt;span class="n"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SDL submodule&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;branch&lt;/span&gt; &lt;span class="n"&gt;-M&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;remote&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;USERNAME&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;hello-world&lt;/span&gt;&lt;span class="n"&gt;-sdl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;git&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;push&lt;/span&gt; &lt;span class="n"&gt;-u&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;E, após executar os comandos acima com sucesso, o seu repositório estará parecido com o meu na imagem abaixo:&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2025/05/github-push.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;Isso é tudo que precisamos por agora, mas vamos voltar ao github no final deste post para configurar a automação de compilação no GitHub Workflow.&lt;/p&gt;&#10;&#10;&lt;h2 class="relative group"&gt;Criação de um projeto no Visual Studio&#10; &lt;div id="criação-de-um-projeto-no-visual-studio" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#cria%c3%a7%c3%a3o-de-um-projeto-no-visual-studio" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;O SDL3 tem uma documentação bem simples e fácil de seguir. A configuração do projeto no Visual Studio pode ser vista &lt;a href="https://github.com/libsdl-org/SDL/blob/main/docs/INTRO-visualstudio.md" target="_blank" rel="noreferrer"&gt;aqui&lt;/a&gt;, porém vou adicionar os passos em português abaixo com algumas modificações que fiz.&lt;/p&gt;&#10;&lt;p&gt;A principal diferença é que, ao invés de fazer o download do código fonte, nós vamos usar o submodule que configuramos no passo anterior em nosso repositório git.&lt;/p&gt;&#10;&#10;&lt;h3 class="relative group"&gt;Novo projeto no Visual Studio&#10; &lt;div id="novo-projeto-no-visual-studio" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#novo-projeto-no-visual-studio" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h3&gt;&#10;&lt;p&gt;O Visual Studio 2022 (ou mais novo) pode ser baixado &lt;a href="https://visualstudio.microsoft.com/" target="_blank" rel="noreferrer"&gt;aqui&lt;/a&gt;, e a versão &lt;em&gt;Community&lt;/em&gt; é gratuita para desenvolvedores solo, uso acadêmico, ou projetos &lt;em&gt;open source&lt;/em&gt;. Siga os passos do instalador e lembre de marcar as opções para adicionar &lt;em&gt;Desktop Development with C++&lt;/em&gt; (você também pode marcar as opções de Unity e game development mas não são necessárias para o SDL).&lt;/p&gt;&#10;&lt;p&gt;Depois de instalado, selecione a opção &lt;em&gt;Create a new project&lt;/em&gt; e procure por &lt;em&gt;Empty Project&lt;/em&gt; com C++, como na imagem abaixo. Se você não estiver vendo essa opção, volte no instalador e veja se as opções de suporte ao C++ foram instaladas no Visual Studio.&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2025/05/vs_cpp_empty_project.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;Após selecionar &lt;em&gt;Empty Project&lt;/em&gt; com C++, na próxima janela digite &lt;code&gt;HelloGame&lt;/code&gt; em &lt;em&gt;Project name&lt;/em&gt;, e no campo &lt;em&gt;Location&lt;/em&gt; selecione o caminho em que está o repositório que criamos no início deste post. As configurações do novo projeto devem estar iguais a imagem abaixo.&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2025/05/vs_hello_game.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;Depois de criar o novo projeto no Visual Studio, esta é a estrutura do nosso repositório atualizada:&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;HelloWorldSDL3/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── .git/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── HelloGame/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── SDL/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── .gitmodules&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&#10;&lt;h3 class="relative group"&gt;Adicionando código&#10; &lt;div id="adicionando-código" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#adicionando-c%c3%b3digo" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h3&gt;&#10;&lt;p&gt;Agora que temos um projeto em branco, vamos adicionar um arquivo de C++ e configurar o projeto para utilizar o SDL que está no mesmo diretório. É importante adicionar um arquivo de código fonte em C++ antes de continuar por que isso vai habilitar as opções que vamos configurar mais pra frente.&lt;/p&gt;&#10;&lt;p&gt;Clique com o botão direito no projeto &lt;em&gt;HelloGame&lt;/em&gt; e, em seguida, selecione a opção &lt;em&gt;Add | New Item...&lt;/em&gt; e digite &lt;code&gt;main.cpp&lt;/code&gt;. No novo arquivo criado, copie e cole o código abaixo. Não se preocupe com os erros de compilação agora, nós ainda vamos configurar o projeto para localizar o SDL e poder compilar com sucesso.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define SDL_MAIN_USE_CALLBACKS 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;SDL3/SDL.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;SDL3/SDL_main.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;SDL_Window&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;SDL_Renderer&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_AppResult&lt;/span&gt; &lt;span class="nf"&gt;SDL_AppInit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;appstate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;SDL_CreateWindowAndRenderer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello World&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_WINDOW_MAXIMIZED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Couldn&amp;#39;t create window and renderer: %s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_GetError&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;SDL_APP_FAILURE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;SDL_APP_CONTINUE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_AppResult&lt;/span&gt; &lt;span class="nf"&gt;SDL_AppEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;appstate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_Event&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;SDL_EVENT_KEY_DOWN&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;SDL_EVENT_QUIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;SDL_APP_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;SDL_APP_CONTINUE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_AppResult&lt;/span&gt; &lt;span class="nf"&gt;SDL_AppIterate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;appstate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Hello World!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;4.0f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_GetRenderOutputSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_SetRenderScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;SDL_strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_SetRenderDrawColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_RenderClear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_SetRenderDrawColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_RenderDebugText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_RenderPresent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;SDL_APP_CONTINUE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SDL_AppQuit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;appstate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_AppResult&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;O código acima é uma variação do &lt;a href="https://github.com/libsdl-org/SDL/blob/main/docs/hello.c" target="_blank" rel="noreferrer"&gt;hello.c&lt;/a&gt; disponibilizado no repositório do SDL. As mudanças que fiz foram mudar a extensão para &lt;code&gt;.cpp&lt;/code&gt;, remover os comentários para não ficar tão longo aqui, e configurar a janela usando &lt;code&gt;SDL_WINDOW_MAXIMIZED&lt;/code&gt; (modo janela) ao invés do original que criava a janela em modo tela cheia.&lt;/p&gt;&#10;&#10;&lt;h3 class="relative group"&gt;Adicionando SDL como dependência&#10; &lt;div id="adicionando-sdl-como-dependência" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#adicionando-sdl-como-depend%c3%aancia" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h3&gt;&#10;&lt;p&gt;Agora vamos adicionar o SDL no Visual Studio junto com o nosso projeto. Para isso, clique com o botão direito na &lt;em&gt;Solution 'HelloGame'&lt;/em&gt;, selecione &lt;em&gt;Add | Existing Project&lt;/em&gt; e, na nova janela navegue até &lt;code&gt;SDL/VisualC/SDL&lt;/code&gt; (dentro do nosso repositório), e selecione o arquivo &lt;em&gt;SDL.vcxproj&lt;/em&gt;. Depois de adicionar o projeto SDL junto ao nosso projeto HelloGame, você deve ter a estrutura abaixo no Visual Studio:&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2025/05/vs_solution_exporer.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;O próximo passo agora é adicionar o SDL como uma referência no projeto HelloGame. Cliquei com o botão direito no projeto &lt;em&gt;HelloGame&lt;/em&gt;, selecione &lt;em&gt;Add | Reference...&lt;/em&gt; e, na nova janela, selecione o projeto SDL e clique em &lt;em&gt;OK&lt;/em&gt;. Isso vai garantir que o nosso projeto use o SDL como uma dependência para compilar o código.&lt;/p&gt;&#10;&lt;p&gt;Por fim, vamos adicionar os &lt;em&gt;headers&lt;/em&gt; do SDL na configuração do nosso projeto. Para isso, clique com o botão direto no projeto &lt;em&gt;HelloGame&lt;/em&gt; e selecione a opção &lt;em&gt;Properties&lt;/em&gt;. Na nova janela, mude o filtro acima para &lt;code&gt;All Configurations&lt;/code&gt; e &lt;code&gt;All Platforms&lt;/code&gt; (se já não estiver assim). Em seguida, expanda a opção &lt;em&gt;C/C++&lt;/em&gt; no menu da esquerda, selecione &lt;em&gt;General&lt;/em&gt;, e no primeiro campo &lt;em&gt;Additional Include Directories&lt;/em&gt;, selecione &lt;em&gt;Edit&lt;/em&gt; e adicione o caminho &lt;code&gt;SDL/includes&lt;/code&gt; (dentro do nosso repositório).&lt;/p&gt;&#10;&lt;p&gt;A imagem baixo mostra como a configuração deste janela deve estar depois dos passos acima:&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2025/05/vs_settings.webp"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;h3 class="relative group"&gt;Rodando o projeto&#10; &lt;div id="rodando-o-projeto" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#rodando-o-projeto" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h3&gt;&#10;&lt;p&gt;Se tudo deu certo, agora basta rodar o projeto no Visual Studio utilizando o botão play verde ou pressionando F5, e você deverá ver a tela abaixo:&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2025/05/sdk_hello_game.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;Caso encontre algum erro, dê uma revisada nos passos anteriores e compare as imagens que adicionei no post para ajudar. Se mesmo assim tiver dúvidas ou problemas, deixe um comentário que tentarei ajudar assim que possível.&lt;/p&gt;&#10;&lt;p&gt;Nós temos um repositório configurado no GitHub com o SDL adicionado como uma dependência e também o nosso projeto configurado para rodar no Visual Studio. O próximo passo agora é um extra, mas que com certeza vai ajudar o desenvolvimento ao médio e longo prazo.&lt;/p&gt;&#10;&#10;&lt;h2 class="relative group"&gt;Automação com GitHub Workflow&#10; &lt;div id="automação-com-github-workflow" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#automa%c3%a7%c3%a3o-com-github-workflow" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;Automação é algo muito comum e essencial em empresas, não só em jogos. A automação pode ser desde rodar alguns testes unitários, compilar o projeto, e até rodar o jogo em um teste pré-definido. Para isso, muitas vezes precisamos de outras máquinas ou até servidores dedicados a rodar nosso projeto sempre que precisar de um teste, ou até mesmo a cada alteração.&lt;/p&gt;&#10;&lt;p&gt;É ai que entra o &lt;a href="https://docs.github.com/en/actions/concepts/workflows-and-actions/about-workflows" target="_blank" rel="noreferrer"&gt;GitHub Workflow&lt;/a&gt;, onde podemos automatizar muita coisa no nosso repositório utilizando servidores Windows, Linux e macOS do GitHub. Existem alguns &lt;a href="https://docs.github.com/en/actions/concepts/overview/usage-limits-billing-and-administration" target="_blank" rel="noreferrer"&gt;limites&lt;/a&gt;, mas mesmo uma conta gratuita tem o suficiente para bastante coisa em projetos pequenos e até médios. Você também pode registrar uma máquina sua como servidor e não se preocupar com limites (já fiz isso com um raspberry pi e funcionou bem para projetos pequenos!).&lt;/p&gt;&#10;&lt;p&gt;Não vou entrar em muitos detalhes sobre o GitHub Workflow em si, por que é algo muito grande e complexo de explicar tudo, mas recomendo dar uma olhada na documentação e pesquisar sobre também.&lt;/p&gt;&#10;&lt;p&gt;Para adicionar suporte a automação em nosso projeto, precisamos apenas adicionar um arquivo no repositório. No repositório, cria uma nova pasta &lt;code&gt;.github&lt;/code&gt; e outra pasta dentro dela chamada &lt;code&gt;workflows&lt;/code&gt;. Dentro da pasta &lt;code&gt;workflows&lt;/code&gt;, adicione um novo arquivo chamado &lt;code&gt;msbuild.yml&lt;/code&gt;. Seu repositório deve estar assim:&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;HelloWorldSDL3/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── .git/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── .github/workflows/msbuild.yml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── HelloGame/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── SDL/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── .gitmodules&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;Por fim, abra o arquivo &lt;code&gt;msbuild.yml&lt;/code&gt; em qualquer editor e copie e cole o conteúdo abaixo:&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;MSBuild&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;push&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;branches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;main&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pull_request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;branches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;main&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;SOLUTION_FILE_PATH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./HelloGame&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;BUILD_CONFIGURATION&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Release&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;read&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;windows-latest&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;actions/checkout@v4&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;submodules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;recursive&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Add MSBuild to PATH&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;microsoft/setup-msbuild@v1.0.2&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Restore NuGet packages&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;working-directory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{env.GITHUB_WORKSPACE}}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nuget restore ${{env.SOLUTION_FILE_PATH}}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Build&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;working-directory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{env.GITHUB_WORKSPACE}}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Upload a Build Artifact&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;actions/upload-artifact@v4.6.2&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hellogame-x64-release&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./HelloGame/x64/Release/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;O arquivo acima parece um pouco confuso, mas se você ler cada linha vai começar a fazer sentido:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Este &lt;em&gt;workflow&lt;/em&gt; roda quando commits forem adicionados no branch &lt;code&gt;main&lt;/code&gt; ou quando tiver um &lt;em&gt;pull request&lt;/em&gt; para ele.&lt;/li&gt;&#10;&lt;li&gt;O nosso &lt;em&gt;env&lt;/em&gt; está configurado com o caminho do projeto &lt;code&gt;HelloGame&lt;/code&gt; e a build &lt;code&gt;Release&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;O &lt;em&gt;job&lt;/em&gt; vai rodar em máquinas &lt;code&gt;windows&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Estamos utilizando &lt;code&gt;msbuild&lt;/code&gt; para compilar o projeto pela linha de comando (já que é um servidor sem interface).&lt;/li&gt;&#10;&lt;li&gt;Depois de compilar, a build do jogo vai ficar arquivada como um artefato deste workflow.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Assim que adicionarmos esse arquivo no repositório e fizermos um commit para o branch &lt;code&gt;main&lt;/code&gt;, este &lt;em&gt;workflow&lt;/em&gt; vai rodar em gerar uma build que podemos baixar e testar, e vai estar no menu &lt;code&gt;Actions&lt;/code&gt; do repositório no GitHub.&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2025/05/github-workflow.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;Além disso, é possível ver todo o processo de compilação e os &lt;em&gt;logs&lt;/em&gt; do servidor. Caso algum erro aconteça, é lá que você vai entender o por que.&lt;/p&gt;&#10;&#10;&lt;h2 class="relative group"&gt;Conclusão&#10; &lt;div id="conclusão" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#conclus%c3%a3o" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;Este post demorou um pouco mais do que planejei para escrever, e ficou mais longo do que imaginei, mas acho que no fim é uma boa introdução de como criar um projeto novo usando SDL3, configurar o Visual Studio, e ainda como usar git submodule e GitHub Workflows para automação.&lt;/p&gt;&#10;&lt;p&gt;Tudo que fiz neste post pode ser visto no meu repositório público &lt;a href="https://github.com/cicanci/hello-world-sdl3" target="_blank" rel="noreferrer"&gt;hello-worlds-sdl3&lt;/a&gt;. Fique a vontade para usar este repositório como um template ou base para o seu projeto, este é um dos motivos que fiz para mim mesmo.&lt;/p&gt;&#10;&lt;p&gt;Muito obrigado se você leu até o final, e espero que tenha sido útil. Qualquer dúvida, problemas no passo-a-passo, ou sugestões deixe um comentário abaixo.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/categories/como-programar-jogos.webp" medium="image"/></item><item><title>Hello World usando SDL no Visual Studio</title><link>https://gamedeveloper.com.br/hello-world-sdl-visual-studio/</link><guid>https://gamedeveloper.com.br/hello-world-sdl-visual-studio/</guid><pubDate>Sun, 21 Mar 2021 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>A SDL é uma biblioteca para desenvolvimento de jogos cross-platform com código aberto que existe desde 1998. Diversos jogos foram publicados utilizando SDL, como por exemplo, Half-Life 2, Left 4 Dead 2, Dying Light, Factorio, FTL, entre muitos outros. Sua linguagem de programação principal é C e C++, porém existem alguns bindings que permitem programar em outras linguagens como C#, Go, Lua, Rust e Python. Por ser "apenas" uma biblioteca, não possui uma interface gráfica como a Unity ou Unreal. Neste post vou demonstrar o passo a passo para criar um projeto utilizando o Visual Studio no Windows.&#10;</description><content:encoded>&lt;p&gt;A &lt;a href="https://libsdl.org/" target="_blank" rel="noreferrer"&gt;SDL&lt;/a&gt; é uma biblioteca para desenvolvimento de jogos &lt;em&gt;cross-platform&lt;/em&gt; com &lt;a href="https://github.com/libsdl-org/SDL" target="_blank" rel="noreferrer"&gt;código aberto&lt;/a&gt; que existe desde 1998. Diversos jogos foram publicados utilizando SDL, como por exemplo, Half-Life 2, Left 4 Dead 2, Dying Light, Factorio, FTL, entre muitos outros. Sua linguagem de programação principal é C e C++, porém existem alguns &lt;a href="https://libsdl.org/languages.php" target="_blank" rel="noreferrer"&gt;bindings&lt;/a&gt; que permitem programar em outras linguagens como C#, Go, Lua, Rust e Python. Por ser &amp;quot;apenas&amp;quot; uma biblioteca, não possui uma interface gráfica como a Unity ou Unreal. Neste post vou demonstrar o passo a passo para criar um projeto utilizando o Visual Studio no Windows.&lt;/p&gt;&#10;&lt;p&gt;Para começar &lt;a href="https://libsdl.org/download-2.0.php" target="_blank" rel="noreferrer"&gt;faça o download&lt;/a&gt; do &lt;em&gt;runtime binaries&lt;/em&gt; da sua plataforma. Se você está utilizando Windows 10, pode fazer download da versão 64-bit Windows. Também é possível utilizar o código fonte, mas o runtime binaries é o suficiente para iniciar um projeto. Para referência, a versão da SDL utilizada é 2.0.14.&lt;/p&gt;&#10;&#10;&lt;h4 class="relative group"&gt;Configuração no Visual Studio&#10; &lt;div id="configuração-no-visual-studio" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#configura%c3%a7%c3%a3o-no-visual-studio" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h4&gt;&#10;&lt;p&gt;Estou utilizando o Visual Studio 2019 Community Edition que pode ser &lt;a href="https://visualstudio.microsoft.com/" target="_blank" rel="noreferrer"&gt;baixado aqui&lt;/a&gt;. Apesar das imagens abaixo serem da versão 2019 a configuração é a mesma em outras versões do Visual Studio.&lt;/p&gt;&#10;&lt;p&gt;Após realizar o &lt;a href="https://libsdl.org/download-2.0.php" target="_blank" rel="noreferrer"&gt;download da SDL&lt;/a&gt; faça a extração em algum local do seu computador &lt;strong&gt;sem espaços&lt;/strong&gt; no nome dos diretórios. Eu gosto de colocar meus projetos em &lt;code&gt;C:\Projects&lt;/code&gt; e qualquer biblioteca ou dependência (como os arquivos da SDL) em &lt;code&gt;C:\Dev&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;Vamos criar um projeto novo do tipo &lt;em&gt;Console App&lt;/em&gt;. Este projeto vai ter apenas um arquivo &lt;em&gt;cpp&lt;/em&gt;, onde vamos adicionar o código do Hello World. O nome deste arquivo não importa, mas gosto de renomeá-lo para &lt;code&gt;main.cpp&lt;/code&gt;.&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2021/03/vs-new-project-sdl.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;Com o projeto criado basta clicar com o botão direito no &lt;em&gt;Project&lt;/em&gt; (dentro da &lt;em&gt;Solution&lt;/em&gt;) e selecionar a última opção chamada &lt;em&gt;Properties&lt;/em&gt;. A seguir iremos adicionar o caminho para as pastas &lt;code&gt;include&lt;/code&gt; e &lt;code&gt;lib\x64&lt;/code&gt; em &lt;em&gt;VC++ Directories&lt;/em&gt;, e as libs &lt;code&gt;SDL2.lib&lt;/code&gt; e &lt;code&gt;SDL2main.lib&lt;/code&gt; em &lt;em&gt;Linker/Input&lt;/em&gt;, conforme as imagens abaixo. Lembre-se de selecionar &lt;em&gt;All Platforms&lt;/em&gt; antes de iniciar a configuração.&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2021/03/vs-sdl-include.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2021/03/vs-sdl-libs.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2021/03/vs-link-sdl-libs.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;Por fim, precisamos copiar o arquivo &lt;code&gt;SDL2.dll&lt;/code&gt; que está em &lt;code&gt;lib\x64&lt;/code&gt; para dentro do projeto, junto com o nosso arquivo &lt;em&gt;cpp&lt;/em&gt;. Esta é a última etapa para configurar o Visual Studio e compilar o projeto com a SDL.&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2021/03/sdk-dll.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;Como realizamos toda a configuração utilizando a &lt;code&gt;lib\x64&lt;/code&gt; lembre de selecionar &lt;code&gt;x64&lt;/code&gt; na Visual Studio antes de compilar e executar o projeto.&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2021/03/vs-build-x64.webp"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;h4 class="relative group"&gt;Hello World&#10; &lt;div id="hello-world" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#hello-world" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h4&gt;&#10;&lt;p&gt;Um projeto com SDL segue uma sequência bem definida de métodos, os quais devem ser executados para que tudo funcione corretamente. O código abaixo é a base que iremos utilizar, contendo a importação do SDL, o tamanho da tela e da imagem que vamos exibir e o método principal da aplicação. Este código não faz nada, mas pode ser executado para testar se a SDL está configurada corretamente no projeto do Visual Studio.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;SDL.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define WINDOW_WIDTH 640&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define WINDOW_HEIGHT 480&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define IMAGE_WIDTH 256&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define IMAGE_HEIGHT 256&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;Os trechos de código a seguir estão dentro do método &lt;code&gt;main()&lt;/code&gt;. Em primeiro lugamos vamos inicializar a SDL e verificar se foi inicializada com sucesso. Caso algum erro seja retornado, iremos exibir a mensagem de erro no console utilizando &lt;code&gt;SDL_Log()&lt;/code&gt; e finalizar a aplicação. Mais detalhes do método de &lt;a href="https://wiki.libsdl.org/SDL_Init" target="_blank" rel="noreferrer"&gt;inicialização aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SDL_Init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SDL_INIT_EVERYTHING&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;SDL_Init Error: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_GetError&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;A seguir criaremos nossa &lt;em&gt;Window&lt;/em&gt; onde o jogo será exibido. No código abaixo, a janela será criada no centro da tela com o tamanho definido anteriormente, e o título &lt;em&gt;Hello World SDL2&lt;/em&gt;. Você pode &lt;a href="https://wiki.libsdl.org/SDL_CreateWindow" target="_blank" rel="noreferrer"&gt;ver aqui&lt;/a&gt; todos os parâmetro em detalhes.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_Window&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SDL_CreateWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello World SDL2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_WINDOWPOS_CENTERED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_WINDOWPOS_CENTERED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WINDOW_WIDTH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WINDOW_HEIGHT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_WINDOW_SHOWN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;SDL_CreateWindow Error: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_GetError&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;O último item necessário para terminarmos a inicialização da SDL é o &lt;em&gt;Renderer&lt;/em&gt;, responsável por &amp;quot;desenhar&amp;quot; na tela criada anteriormente. Os detalhes da criação do renderer podem ser &lt;a href="https://wiki.libsdl.org/SDL_CreateRenderer" target="_blank" rel="noreferrer"&gt;vistos aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_Renderer&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SDL_CreateRenderer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_RENDERER_ACCELERATED&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;SDL_CreateRenderer Error: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_GetError&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;Com a SDL inicializada e a window e o renderer criados, podemos desenhar uma imagem na tela. O código abaixo carrega uma imagem no formato &lt;code&gt;BMP&lt;/code&gt; e a exibe no centro da tela. Primeiro criamos uma &lt;em&gt;surface&lt;/em&gt; para então criar a &lt;em&gt;texture&lt;/em&gt;. Com a textura criada, podemos remover a surface da memória (a texture será removida só no final da aplicação). O &lt;code&gt;SDL_Rect&lt;/code&gt; possui as coordenadas onde a imagem será desenhada e seu tamanho, considerando que o ponto de origem da imagem é no seu centro. Por fim, desenhamos a texture na tela utilizando o &lt;code&gt;SDL_Render&lt;/code&gt;.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_Surface&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SDL_LoadBMP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;image.bmp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;SDL_LoadBMP Error: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_GetError&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_Texture&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;texture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SDL_CreateTextureFromSurface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texture&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;SDL_CreateTextureFromSurface Error: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_GetError&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_FreeSurface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_Rect&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;WINDOW_WIDTH&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.5f&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;IMAGE_WIDTH&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.5f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;WINDOW_HEIGHT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.5f&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;IMAGE_HEIGHT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.5f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IMAGE_WIDTH&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IMAGE_HEIGHT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_RenderClear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_RenderCopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;texture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_RenderPresent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;Todo esse código acontece antes do &lt;em&gt;main loop&lt;/em&gt;, ou seja, será executado apenas uma vez. A imagem do exemplo será desenhada apenas uma vez na tela e, como no loop abaixo não tem outra chamada para o &lt;code&gt;SDL_Render&lt;/code&gt;, ela continuará desenhada até o fim. Este loop é usado apenas para ler o &lt;em&gt;input&lt;/em&gt; do jogador e sair do loop se a janela for fechada.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SDL_Event&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SDL_PollEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;SDL_QUIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;Quando o jogador fechar a tela e o jogo sair do loop vamos finalizar a SDL. Para isso tiramos tudo que foi alocado da memória, como texture, renderer e window. E por fim finalizamos a SDL.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_DestroyTexture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texture&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_DestroyRenderer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_DestroyWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SDL_Quit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;Assim temos nosso &lt;em&gt;Hello World&lt;/em&gt; com uma imagem desenhada na tela. &lt;a href="https://gist.github.com/cicanci/b54715298ab55dff2fbcd0ca3829d13b" target="_blank" rel="noreferrer"&gt;A class completa pode ser vista neste gist&lt;/a&gt;. Se tiver alguma dúvida sobre os métodos e objetos da SDL acesse a &lt;a href="https://wiki.libsdl.org/" target="_blank" rel="noreferrer"&gt;documentação da biblioteca&lt;/a&gt;, a qual contem bastante informação e exemplos práticos.&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2021/03/hello-world-sdl.webp"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;h4 class="relative group"&gt;Cuidados&#10; &lt;div id="cuidados" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#cuidados" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h4&gt;&#10;&lt;p&gt;Pelo tamanho do post é possível ver que desenhar uma simples imagem na tela exige uma boa quantidade de código. Enquanto na Unity, isso pode ser feito praticamente arrastando uma imagem para dentro da engine, com a SDL tudo é mais &amp;quot;manual&amp;quot;. Isso pode dar mais trabalho, mas também da mais controle ao programador. Por isso, é preciso prestar atenção para não fazer algo errado sem perceber.&lt;/p&gt;&#10;&lt;p&gt;Quando estava criando este exemplo para o post, percebi que o simples fato de desenhar uma imagem na tela estava utilizando &lt;strong&gt;97%&lt;/strong&gt; da minha GPU (o que é um absurdo). Notei que meu erro foi executar os métodos &lt;code&gt;SDL_RenderClear()&lt;/code&gt;, &lt;code&gt;SDL_RenderCopy()&lt;/code&gt; e &lt;code&gt;SDL_RenderPresent()&lt;/code&gt; a cada loop (é um exagero para uma imagem estática).&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2021/03/bad-gpu.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;Movendo as chamadas destes métodos para fora do loop, a utilização da GPU caiu para &lt;strong&gt;1%&lt;/strong&gt;. Existem algumas técnicas para controlar melhor o &lt;em&gt;main loop&lt;/em&gt; e o &lt;em&gt;frame rate&lt;/em&gt;, assim como desenhar apenas quando a imagem mudar de posição, entre outras possibilidades. O que me pegou de surpresa foi a &lt;a href="https://wiki.libsdl.org/SDL_CreateRenderer" target="_blank" rel="noreferrer"&gt;própria documentação ter este exemplo&lt;/a&gt;, de uma imagem estática sendo desenhada todo frame.&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2021/03/good-gpu.webp"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;h4 class="relative group"&gt;Conclusão&#10; &lt;div id="conclusão" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#conclus%c3%a3o" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h4&gt;&#10;&lt;p&gt;Trabalhar com a SDL é um pouco lento no início até ter a base do jogo pronta, depois disso é a programação do jogo em si. É mais complicado do que utilizar a Unity e C#, por exemplo, com uma curva de aprendizado bem maior. Porém, é bem recompensador e importante aprender a programar (e programar jogos) em um &amp;quot;nível mais baixo&amp;quot; do que em uma engine que já te dá tudo pronto e você não vê muito bem o que acontece por trás do seu script.&lt;/p&gt;&#10;&lt;p&gt;O código completo está disponível &lt;a href="https://gist.github.com/cicanci/b54715298ab55dff2fbcd0ca3829d13b" target="_blank" rel="noreferrer"&gt;neste link&lt;/a&gt;. Caso queira se aprofundar, recomendo olhar a &lt;a href="https://wiki.libsdl.org" target="_blank" rel="noreferrer"&gt;documentação oficial&lt;/a&gt;. &lt;a href="https://www.parallelrealities.co.uk/tutorials/" target="_blank" rel="noreferrer"&gt;Este site&lt;/a&gt; também possui bons exemplos de programação de jogos com SDL.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2021/03/hello-world-sdl.webp" medium="image"/></item><item><title>Cursos e tutoriais para aprender a programar jogos</title><link>https://gamedeveloper.com.br/cursos-tutoriais-programacao-jogos/</link><guid>https://gamedeveloper.com.br/cursos-tutoriais-programacao-jogos/</guid><pubDate>Sun, 03 Jan 2021 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Já escrevi algumas vezes sobre cursos e tutoriais para aprender a programar jogos, porém é sempre bom relembrar este assunto com novas referências para quem está começando hoje. Então, decidi escrever um post bem simples e direto com recomendações, para diferentes níveis de conhecimento, combinando aprendizado em programação, inglês e desenvolvimento de jogos.&#10;</description><content:encoded>&lt;p&gt;Já escrevi algumas vezes sobre cursos e tutoriais para aprender a programar jogos, porém é sempre bom relembrar este assunto com novas referências para quem está começando hoje. Então, decidi escrever um post bem simples e direto com recomendações, para diferentes níveis de conhecimento, combinando aprendizado em programação, inglês e desenvolvimento de jogos.&lt;/p&gt;&#10;&lt;p&gt;O conteúdo deste post são recomendações pessoais, baseadas na minha experiência e com certeza não são as únicas opções disponíveis no mercado. Não adicionei cursos acadêmicos, apenas cursos livres e sites com tutoriais.&lt;/p&gt;&#10;&#10;&lt;h3 class="relative group"&gt;Conhecimento Básico ou Nenhum&#10; &lt;div id="conhecimento-básico-ou-nenhum" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#conhecimento-b%c3%a1sico-ou-nenhum" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h3&gt;&#10;&lt;p&gt;Se você está começando a estudar desenvolvimento de jogos, seja por hobby ou para entrar na indústria de jogos, é bom começar do básico e com conteúdo de qualidade. Nenhum destes cursos substitui uma formação acadêmica, que eu recomendo fazer, porém são complementares para entender como é desenvolver um jogo, ou para ter um primeiro contato e validar se é algo que realmente quer investir como carreira.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Alura&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;É um serviço de cursos online com excelente conteúdo para quem quer aprender a programar, ou até expandir seus conhecimentos. É um serviço pago, mas que o conteúdo vale cada centavo investido, já que a plataforma conta com mais de 1242 cursos até o momento. Confira os &lt;a href="https://www.alura.com.br/cursos-online-programacao/jogos" target="_blank" rel="noreferrer"&gt;cursos de desenvolvimento de jogos&lt;/a&gt; disponíveis. E não se preocupe se sentir que não está pronto para iniciar direto com programação de jogos, é possível começar a aprender com alguns &lt;a href="https://www.alura.com.br/cursos-online-programacao" target="_blank" rel="noreferrer"&gt;cursos de programação&lt;/a&gt; para se familiarizar um pouco, antes de partir para games. &lt;a href="https://www.alura.com.br" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Udemy&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Se você ainda não tem certeza que é isso que quer estudar, talvez seja interessante ter um primeiro contato com um curso livre no Udemy, que possui &lt;a href="https://www.udemy.com/courses/development/game-development/" target="_blank" rel="noreferrer"&gt;cursos de desenvolvimento de jogos&lt;/a&gt; muito bons em português ou com legenda disponível. Lembre sempre de verificar se o curso está disponível em português ou se existem legendas, além de verificar os comentários dos alunos sobre o curso desejado. &lt;a href="https://www.udemy.com" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&#10;&lt;h3 class="relative group"&gt;Conhecimento Intermediário à Avançado&#10; &lt;div id="conhecimento-intermediário-à-avançado" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#conhecimento-intermedi%c3%a1rio-%c3%a0-avan%c3%a7ado" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h3&gt;&#10;&lt;p&gt;Para quem já tem um conhecimento prévio em programação e inglês, porém não necessariamente um conhecimento de programação de jogos, existem excelentes conteúdos disponíveis gratuitamente. Neste ponto é importante focar em uma &lt;strong&gt;game engine&lt;/strong&gt;, como a Unity ou a Unreal. Com exceção do site da Unreal, todos os links abaixo são sobre Unity, já que é a game engine que trabalho há anos e tenho mais referências para indicar. Este conteúdo também é indicado para quem já teve um primeiro contato com desenvolvimento de games e quer se aprofundar mais.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Unreal Online Learning&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;No site &lt;a href="https://www.unrealengine.com/en-US/onlinelearning-courses" target="_blank" rel="noreferrer"&gt;oficial da Unreal Engine&lt;/a&gt; existe uma boa quantidade de tutoriais para aprender a desenvolver jogos utilizando esta tecnologia, seja através de C++ ou Blueprints. Existem tutoriais para todo nível de conhecimento, porém é necessário um conhecimento prévio em inglês para poder aproveitar melhor os cursos. O &lt;a href="https://www.youtube.com/c/UnrealEngine/featured" target="_blank" rel="noreferrer"&gt;canal no YouTube da Unreal&lt;/a&gt; também possui muito conteúdo bom, recomendo seguir. &lt;a href="https://www.unrealengine.com/en-US/onlinelearning-courses" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Unity Learn&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;A Unity também tem o seu portal de tutoriais e cursos, o &lt;a href="https://learn.unity.com" target="_blank" rel="noreferrer"&gt;Unity Learn&lt;/a&gt;, que ficou totalmente gratuito no início do ano passado. Já fiz vários cursos disponíveis e não canso de recomendar esta plataforma para todos que queiram aprender a fazer jogos com Unity ou aprimorar seus conhecimentos na engine. O &lt;a href="https://www.youtube.com/c/unity/featured" target="_blank" rel="noreferrer"&gt;canal no YouTube da Unity&lt;/a&gt; também é um ótimo lugar para encontrar mais conteúdo sobre a engine. &lt;a href="https://learn.unity.com" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Brackeys&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Infelizmente, este canal deixou de produzir conteúdo desde o final do ano passado, com os criadores anunciando que vão focar em novos projetos. Porém, ainda existe muito conteúdo bom neste canal para estudar. &lt;a href="https://www.youtube.com/c/Brackeys/featured" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Code Monkey&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Com vídeos curtos e objetivos, o Code Monkey explica muito bem como fazer algo bem específico na Unity. O canal tem crescido bastante, com tutoriais cada vez melhores e atuais. &lt;a href="https://www.youtube.com/c/CodeMonkeyUnity/featured" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Game Dev Guide&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Este canal também possui vídeos curtos e objetivos, com excelente explicações, mas com uma frequência de postagem menor. &lt;a href="https://www.youtube.com/c/GameDevGuide/featured" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Infallible Code&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Por fim, um canal que conheci a pouco tempo, com alguns vídeos bem interessantes. O autor realiza lives com frequência discutindo assuntos bem relevantes, vale conferir. &lt;a href="https://www.youtube.com/channel/UCTjnCCcuIbrprhOiaDJxxHA" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&#10;&lt;h3 class="relative group"&gt;Conhecimento Avançado e Específico&#10; &lt;div id="conhecimento-avançado-e-específico" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#conhecimento-avan%c3%a7ado-e-espec%c3%adfico" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h3&gt;&#10;&lt;p&gt;Com um nível avançado em programação, desenvolvimento de jogos e entendimento de conteúdos em inglês, começa a surgir uma necessidade de se especializar em determinado assunto. Na minha opinião, é difícil um curso de desenvolvimento de jogos ser para um público avançado, uma vez que a base necessária para desenvolver um jogo já existe. Assim, faz mais sentido para mim aprender e recomendar técnicas diferentes, assuntos específicos e palestras sobre o desenvolvimento de grandes jogos.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;GDC&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;A Game Developers Conference (GDC) é um evento anual que reúne profissionais da indústria do mundo todo com palestras e workshops sobre técnicas e tecnologias utilizadas para o desenvolvimento de jogos. O evento conta com palestras desde postmortems até soluções bem inovadores utilizadas na geração atual de consoles. Mesmo que boa parte do conteúdo seja com base em game engines restritas, é possível abstrair e ter boas ideias para implementar em seu próprio projeto, ou aprender como um determinado desafio técnico foi solucionado. &lt;a href="https://www.youtube.com/c/Gdconf/featured" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Sebastian Lague&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Descobri este canal recentemente e fiquei impressionado com os tutoriais. O Sebastian explica um pouco rápido, mas é possível aprender muita coisa sobre shader e técnicas avançadas para desenvolvimento de jogos na Unity. Alguns destaques são as playlists sobre geração procedural de planetas e simulação de ecossistemas, além de muito conteúdo sobre matemática aplicada em programação de jogos. &lt;a href="https://www.youtube.com/c/SebastianLague/featured" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;AI and Games&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Se a especialização que você procura é em Inteligência Artificial, este canal tem muitos vídeos que vão te abrir os olhos para como determinadas técnicas são implementadas em jogos. &lt;a href="https://www.youtube.com/c/AIGamesSeries/featured" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The Cherno&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;O Cherno faz vídeos sobre C++, OpenGL e tem uma série mostrando como desenvolver uma game engine do zero. Mesmo que não seja seu interesse criar uma game engine, este conhecimento é excelente para saber o que acontece por trás do seu código. &lt;a href="https://www.youtube.com/c/TheChernoProject/featured" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Game Maker's Toolkit&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Um canal bem grande sobre game design. Seus vídeos dissecam mecânicas e sistemas implementados em jogos, com discussões desde geração de números aleatórios e até o que torna uma Inteligência Artificial boa para um game. &lt;a href="https://www.youtube.com/c/MarkBrownGMT/featured" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Game Brain&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Este canal é mais focado em game design e discussões sobre como alguns problemas foram resolvidos em determinados jogos. Apesar de não ter programação, seu conteúdo é bem técnico. &lt;a href="https://www.youtube.com/c/GameBrainOfficial/featured" target="_blank" rel="noreferrer"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&#10;&#10;&lt;h3 class="relative group"&gt;O que mais posso fazer para aprender?&#10; &lt;div id="o-que-mais-posso-fazer-para-aprender" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#o-que-mais-posso-fazer-para-aprender" aria-label="Âncora"&gt;#&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h3&gt;&#10;&lt;p&gt;Jogos. Desenvolva jogos sempre que puder. Busque inspirações em outros jogos ou em coisas que você gosta e tem interesse, sempre mostre seu projeto e peça feedback para você saber onde deve melhorar. Lembre-se que &lt;a href="https://gamedeveloper.com.br/voce-ja-fez-um-jogo/" &gt;você deve fazer um jogo para alguém jogar&lt;/a&gt;, e não deixar escondido no seu computador.&lt;/p&gt;&#10;&lt;p&gt;Tem mais alguma dica de curso ou tutoriais que quer recomendar? Deixe um comentário aqui no post.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2021/01/cambridge.webp" medium="image"/></item><item><title>Como ser um programador de jogos</title><link>https://gamedeveloper.com.br/como-ser-um-programador-de-jogos/</link><guid>https://gamedeveloper.com.br/como-ser-um-programador-de-jogos/</guid><pubDate>Wed, 27 Jan 2016 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Há pouco mais de 2 anos comecei uma série de posts sobre como ser um programador de jogos, e cada semana tratei um assunto relacionado a como começar uma carreira como programador na indústria de games. Fiz 32 posts nesta série e acabei não escrevendo mais posts há quase 1 ano nesta categoria por que os assuntos para iniciantes foram diminuindo e eu acabei ficando sem tempo para posts semanais.&#10;</description><content:encoded>&lt;p&gt;Há pouco mais de 2 anos comecei uma série de posts sobre como ser um programador de jogos, e cada semana tratei um assunto relacionado a como começar uma carreira como programador na indústria de games. Fiz 32 posts nesta série e acabei não escrevendo mais posts há quase 1 ano nesta categoria por que os assuntos para iniciantes foram diminuindo e eu acabei ficando sem tempo para posts semanais.&lt;/p&gt;&#10;&lt;p&gt;Decidi fazer este post para reunir a lista com os 32 posts em apenas um lugar. Muitas vezes recebo emails de pessoas que estão querendo começar na área, e um dos links que sempre envio é o da categoria &lt;a href="https://gamedeveloper.com.br/categories/como-programar-jogos/" &gt;Como Começar&lt;/a&gt;. Porém, acredito que todos links em um único post devem ser mais úteis e fáceis de consultar.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-pre-requisitos/" &gt;#01 Pré-requisitos&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-hello-world/" &gt;#02 Hello World&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-engine-vs-framework/" &gt;#03 Engine vs Framework&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-primeiro-jogo/" &gt;#04 Primeiro jogo&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-cursos/" &gt;#05 Cursos&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-livros/" &gt;#06 Livros&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-concursos/" &gt;#07 Concursos e Game Jams&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-playground/" &gt;#08 Playground&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-prototipos/" &gt;#09 Protótipos&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-codigos-opensource/" &gt;#10 Códigos Open Source&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/programar-sem-ter-a-arte-final/" &gt;#11 Programar sem ter a Arte Final&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-para-que-serve-um-maker/" &gt;#12 Para que serve um Maker&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/delta-time/" &gt;#13 Delta Time&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/game-analytics/" &gt;#14 Dados analíticos do jogo&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/teste-com-jogadores/" &gt;#15 Teste com jogadores&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/game-design-document/" &gt;#16 Game Design Document&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/parallax/" &gt;#17 Parallax&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/voce-ja-fez-um-jogo/" &gt;#18 Você já fez um jogo?&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/gerenciamento-do-seu-tempo/" &gt;#19 Gerenciamento do seu tempo&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/jogue-bastante-mas-jogos-diferentes/" &gt;#20 Jogue bastante, mas jogos diferentes&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/pixel-perfect/" &gt;#21 Pixel Perfect&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/boas-praticas-para-animacoes-2d/" &gt;#22 Boas práticas para animações 2D&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/feedback-de-acoes-para-o-jogador/" &gt;#23 Feedback de ações para o jogador&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/200-mecanicas-de-gameplay/" &gt;#24 200 mecânicas de gameplay&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/definicao-de-prioridade-de-tarefas/" &gt;#25 Definição de prioridade de tarefas&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/transformando-jogo-em-produto/" &gt;#26 Transformando jogo em produto&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/por-onde-comecar-programar/" &gt;#27 Por onde começar a programar&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/mantenha-tudo-simples/" &gt;#28 Mantenha tudo simples&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/avaliando-um-framework/" &gt;#29 Avaliando um Framework&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/programando-com-estilo/" &gt;#30 Programando com estilo&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://gamedeveloper.com.br/design-patterns/" &gt;#31 Design Patterns&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Olhando os 32 posts aqui até parecem capítulos de um livro, e a ideia inicial dessa série era ser um pequeno guia com informações úteis para quem estiver começando na área. Diferente dos últimos posts desta série, não vou prometer que vou voltar a postar nesta categoria toda semana, mas prometo que vou tentar continuar ou pelo menos atualizar os assuntos tratados anteriormente com novos posts e novas informações.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Recomendação da semana&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Esta semana finalmente assisti uma série de ficção científica incrível chamada &lt;a href="http://www.imdb.com/title/tt0303461/" target="_blank" rel="noreferrer"&gt;Firefly&lt;/a&gt;. Nesta série a civilização humana desenvolveu uma tecnologia que transforma outros planetas e luas em lugares similares a Terra, permitindo a expansão pelo espaço. O interessante desta série é que não existem máquinas com inteligência artificial avançada e muito menos alienígenas, apenas humanos e naves.  É possível aplicar essa mesma ideia em games, usando jogabilidades comuns porém com diferentes abordagens.&lt;/p&gt;&#10;&lt;p&gt; &lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2016/01/como-ser-prog-jogos.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Design Patterns</title><link>https://gamedeveloper.com.br/design-patterns/</link><guid>https://gamedeveloper.com.br/design-patterns/</guid><pubDate>Mon, 23 Mar 2015 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Este é um assunto complicado até para quem decorou todos design patterns possíveis e imagináveis em programação. Por mais que existem muitos por ai, poucos são utilizados no dia-a-dia, e muitas vezes por falta de conhecimento.&#10;</description><content:encoded>&lt;p&gt;Este é um assunto complicado até para quem decorou todos &lt;a href="http://en.wikipedia.org/wiki/Software_design_pattern" title="Design Patterns" target="_blank" rel="noreferrer"&gt;design patterns&lt;/a&gt; possíveis e imagináveis em programação. Por mais que existem muitos por ai, poucos são utilizados no dia-a-dia, e muitas vezes por falta de conhecimento.&lt;/p&gt;&#10;&lt;p&gt;Antes de começar a trabalhar com jogos eu imaginava que muitos design patterns eram utilizados nos jogos, afinal são programas bem complexos e grandes. Porém, o que eu aprendi é que nem sempre é necessário utilizar todas as técnicas possíveis só para dizer que utilizou.&lt;/p&gt;&#10;&lt;p&gt;Em praticamente todos jogos que trabalhei na &lt;a href="http://glu.com" title="Glu" target="_blank" rel="noreferrer"&gt;Glu&lt;/a&gt; e na &lt;a href="http://ea.com" title="EA" target="_blank" rel="noreferrer"&gt;EA&lt;/a&gt; o design pattern mais utilizado era sempre o &lt;a href="http://en.wikipedia.org/wiki/Singleton_pattern" title="Singleton" target="_blank" rel="noreferrer"&gt;Singleton&lt;/a&gt;. Praticamente todas as classes que não eram objectos ou entidades tinham este padrão implementado que tem como objetivo expor uma variável estática para acessar todo conteúdo da classe.&lt;/p&gt;&#10;&lt;p&gt;É claro que aqui e ali se via alguns outros design patterns, como &lt;a href="http://en.wikipedia.org/wiki/Factory_method_pattern" title="Factory" target="_blank" rel="noreferrer"&gt;Factory&lt;/a&gt; e &lt;a href="http://en.wikipedia.org/wiki/Prototype_pattern" title="Prototype" target="_blank" rel="noreferrer"&gt;Prototype&lt;/a&gt;, mas o mais utilizado sem dúvidas era o Singleton, por que funciona muito bem quando você precisa acessar conteúdos de outras classes. É importante conhecer alguns design patterns mais utilizados, mas também saber onde e quando utilizar.&lt;/p&gt;&#10;&lt;p&gt;Não adianta implementar todos design patterns só para falar que utilizou todos se os demais programadores da equipe (ou futuros programadores) não vão manter tudo funcionando, principalmente por falta de conhecimento. Por isso é muito importante conhecer bem os mais utilizados e pelo menos saber onde utilizar. Para estudar mais sobre design patterns eu recomendo os 3 livros abaixo:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="http://www.amazon.com/Game-Programming-Patterns-Robert-Nystrom/dp/0990582906/ref=sr_1_1?ie=UTF8&amp;amp;qid=1427148769&amp;amp;sr=8-1&amp;amp;keywords=game&amp;#43;design&amp;#43;patterns" title="Amazon" target="_blank" rel="noreferrer"&gt;Game Programming Patterns&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612/ref=sr_1_1?ie=UTF8&amp;amp;qid=1427149751&amp;amp;sr=8-1&amp;amp;keywords=design&amp;#43;patterns" title="Amazon" target="_blank" rel="noreferrer"&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=sr_1_1?ie=UTF8&amp;amp;qid=1427149756&amp;amp;sr=8-1&amp;amp;keywords=code&amp;#43;complete" title="Amazon" target="_blank" rel="noreferrer"&gt;Code Complete: A Practical Handbook of Software Construction&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Este livro possui uma &lt;a href="http://gameprogrammingpatterns.com/contents.html" target="_blank" rel="noreferrer"&gt;Game Programming Patterns&lt;/a&gt; (o autor começou o link na internet e depois publico a versão impressa). Obrigado Gabriel Sussumu por lembrar deste link nos comentários!&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;UPDATE 1:&lt;/strong&gt; Links de mais conteúdo de Design Patterns em jogos enviado pelo leitor Fernando Mondo:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://sofiaia.wordpress.com/2008/07/11/maquina-de-estados/" target="_blank" rel="noreferrer"&gt;FSM (Máquina de Estados) em jogos RTS&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="http://gamedevelopment.tutsplus.com/tutorials/using-the-composite-design-pattern-for-an-rpg-attributes-system--gamedev-243" target="_blank" rel="noreferrer"&gt;Composite em jogos RPG&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="http://www.cse.lehigh.edu/~munoz/CSE348/classes/" target="_blank" rel="noreferrer"&gt;Site Universidade da Pennsylvania&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;UPDATE 2:&lt;/strong&gt; Reescrevi algumas partes do texto para tentar expressar melhor minha opinião.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2015/03/post32.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Programando com estilo</title><link>https://gamedeveloper.com.br/programando-com-estilo/</link><guid>https://gamedeveloper.com.br/programando-com-estilo/</guid><pubDate>Tue, 17 Mar 2015 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Faz um bom tempo desde que escrevi o último post desta série, mas agora pretendo voltar com a frequência de 1 post por semana sobre como como ser um programador de jogos. Por mais que o título seja sobre programação, muitas dicas já apresentadas são úteis para todas as áreas.&#10;</description><content:encoded>&lt;p&gt;Faz um bom tempo desde que escrevi o último post desta série, mas agora pretendo voltar com a frequência de 1 post por semana sobre como como ser um programador de jogos. Por mais que o título seja sobre programação, muitas dicas já apresentadas são úteis para todas as áreas.&lt;/p&gt;&#10;&lt;p&gt;Programar com estilo não é escrever um código enquanto salta de um avião e fazer ele compilar com sucesso antes de abrir o paraquedas, mas sim programar seguindo um estilo ou um padrão que deixe o código mais organizado e fácil de entender para outros programadores.&lt;/p&gt;&#10;&lt;p&gt;A primeira vez que li um documento sobre padronização de código foi enquanto trabalhava na &lt;a href="http://ea.com" title="EA" target="_blank" rel="noreferrer"&gt;EA&lt;/a&gt;. Era um documento bem completo sobre melhores práticas de programação em C/C++ para deixar o código organizado e bem escrito para qualquer desenvolver trabalhar sem problemas.&lt;/p&gt;&#10;&lt;p&gt;Muitas empresas de tecnologia tem este tipo de documento, porém poucas publicam na internet. Neste post reuni alguns muito interessantes para se estudar e que são públicos.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="http://google-styleguide.googlecode.com/svn/trunk/cppguide.html" title="Google" target="_blank" rel="noreferrer"&gt;Google C++ Style Guide&lt;/a&gt; (dica do &lt;a href="http://nullonerror.org/" title="Rodrigo Delduca" target="_blank" rel="noreferrer"&gt;Rodrigo Delduca&lt;/a&gt;)&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#ZgotmplZ" title="Id Software"&gt;Id Software Coding Style Conventions&lt;/a&gt; (usado no DOOM 3)&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/airbnb/javascript" title="Airbnb" target="_blank" rel="noreferrer"&gt;Airbnb JavaScript Style Guide&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style" title="Mozilla" target="_blank" rel="noreferrer"&gt;Mozilla Coding Style&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Vale a pela ler antes de programar, e se for o caso procure algo voltado para a linguagem de programação que você está utilizando no momento. E você, conhece algum guia que faltou aqui?&lt;/p&gt;&#10;&lt;p&gt;Veja todos os posts desta série &lt;a href="https://gamedeveloper.com.br/categories/como-programar-jogos/" title="Como ser um programador de jogos"&gt;clicando aqui&lt;/a&gt;!&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2015/03/post31.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Avaliando um framework</title><link>https://gamedeveloper.com.br/avaliando-um-framework/</link><guid>https://gamedeveloper.com.br/avaliando-um-framework/</guid><pubDate>Thu, 26 Jun 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Existem muitos frameworks para jogos na internet, e cada vez mais estão sendo lançados para diversas plataformas. Por isso, é importante saber o que um framework deve ter e o que deve ser testado, antes de escolher a tecnologia errada e descobrir isso tarde demais para mudar.&#10;</description><content:encoded>&lt;p&gt;Existem muitos frameworks para jogos na internet, e cada vez mais estão sendo lançados para diversas plataformas. Por isso, é importante saber o que um framework deve ter e o que deve ser testado, antes de escolher a tecnologia errada e descobrir isso tarde demais para mudar.&lt;/p&gt;&#10;&lt;p&gt;Os itens abaixo foram baseados em necessidades que tive (e não foram atendidas) quando desenvolvi o &lt;a href="https://gamedeveloper.com.br/fim-do-tcc-da-pos-graduacao-oniro/" title="Oniro"&gt;TCC da minha pós-graduação&lt;/a&gt;. O framework que eu usei foi uma escolha tão errada que ele falha em quase todos os itens abaixo, mas era tarde demais para mudar.&lt;/p&gt;&#10;&lt;p&gt;Por isso, vale a pena perder um tempo no começo do projeto avaliando se o framework escolhido realmente serve para o que você quer fazer, e também se funciona bem, para não te deixar na mão.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Possui alguma biblioteca de física? Se não, existe alguma recomendada pelos criadores do framework que funciona bem em conjunto?&lt;/li&gt;&#10;&lt;li&gt;Consegue trabalhar com sprite sheets ou apenas imagens separadas?&lt;/li&gt;&#10;&lt;li&gt;É necessário muitas linhas de código para carregar e desenhar algo na tela?&lt;/li&gt;&#10;&lt;li&gt;Possui suporte para eventos de entrada (teclado, mouse, touch, etc)?&lt;/li&gt;&#10;&lt;li&gt;No caso de 3D, quais são as compressões de textura que tem suporte?&lt;/li&gt;&#10;&lt;li&gt;Existe um site/forum para tirar dúvidas? Algo feito para a comunidade de desenvolvedores que usa a tecnologia?&lt;/li&gt;&#10;&lt;li&gt;O framework é atualizado constantemente?&lt;/li&gt;&#10;&lt;li&gt;Possui um roadmap de futuras atualizações? Eles são abertos a sugestões?&lt;/li&gt;&#10;&lt;li&gt;Pode ser utilizado em mais de uma plataforma?&lt;/li&gt;&#10;&lt;li&gt;Se for pago, existe uma versão trial para testes?&lt;/li&gt;&#10;&lt;li&gt;Possui suporte a redes sociais, publicidade e pagamento (para comprar itens no jogo com dinheiro de verdade)? Se não, aceita algum framework externo?&lt;/li&gt;&#10;&lt;li&gt;Em quais sistemas operacionais e IDEs (visual studio, xcode, eclipse, etc) funciona?&lt;/li&gt;&#10;&lt;li&gt;O framework é famoso e já foi utilizado em jogos publicados?&lt;/li&gt;&#10;&lt;li&gt;É fácil de debugar e entender os problemas?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Isso tudo é bem genérico, e é claro que depende do tipo de jogo que você está desenvolvendo. Mas, mesmo se não usar algo no início do projeto, é bom saber se o framework tem suporte a uma determinada funcionalidade, ou seu jogo não será flexível. Existe mais algum ponto que vale a pena ser verificado antes de escolher um framework? Comente abaixo!&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/06/post30.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Mantenha tudo simples</title><link>https://gamedeveloper.com.br/mantenha-tudo-simples/</link><guid>https://gamedeveloper.com.br/mantenha-tudo-simples/</guid><pubDate>Mon, 12 May 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Esta semana li este comentário que me inspirou a escrever este post, que é a frase famosa “Keep it simple, stupid”, algo como “Mantenha simples, idiota” em tradução literal.&#10;</description><content:encoded>&lt;p&gt;Esta semana li &lt;a href="http://programmers.stackexchange.com/questions/25276/why-is-cleverness-considered-harmful-in-programming-by-some-people/25281#25281" title="Comentário" target="_blank" rel="noreferrer"&gt;este comentário&lt;/a&gt; que me inspirou a escrever este post, que é a frase famosa “Keep it simple, stupid”, algo como “Mantenha simples, idiota” em tradução literal.&lt;/p&gt;&#10;&lt;p&gt;Muitas vezes buscamos programar a melhor solução possível para um problema, mas muitas vezes o problema não requer uma solução complicada. Por exemplo, não é necessário programar um algoritmo de ordenação complexo para ordenar uma lista que sempre será pequena, neste caso vale a pena usar algo mais simples.&lt;/p&gt;&#10;&lt;p&gt;O &lt;a href="http://en.wikipedia.org/wiki/Brian_Kernighan" title="Brian" target="_blank" rel="noreferrer"&gt;Brian Kernighan&lt;/a&gt;, explicou a frase “Keep it simples, stupid” da seguinte forma: debugar um código é duas vezes mais complexo do que escrevê-lo. Sendo assim, se você escrever o melhor código possível, você mesmo não será capaz de debugá-lo. Faz sentindo, não?&lt;/p&gt;&#10;&lt;blockquote&gt;&lt;p&gt;“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”&lt;/p&gt;&#10;&lt;p&gt;Brian Kernighan&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;Quanto maior for a complexidade, mais difícil será entender algum bug no código. Por isso, mantenha seu código com baixa complexidade e sempre pense em como debugar enquanto programa, isso ajuda a identificar problemas e prevenir código complexos.&lt;/p&gt;&#10;&lt;p&gt;Uma dica para simplificar um código é quebra-lo em métodos e funções, pois assim você deixa o código reusável e mais simples de entender e debugar. Existem outras formas de simplificar um código, está é uma das mais básicas e usadas.&lt;/p&gt;&#10;&lt;p&gt;Outra dica é ler livros que ensinam programar e também boas práticas, como &lt;a href="http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=sr_1_1?ie=UTF8&amp;amp;qid=1399925218&amp;amp;sr=8-1&amp;amp;keywords=code&amp;#43;complete" title="Code Complete" target="_blank" rel="noreferrer"&gt;Code Complete&lt;/a&gt; e &lt;a href="http://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876/ref=sr_1_1?ie=UTF8&amp;amp;qid=1399925256&amp;amp;sr=8-1&amp;amp;keywords=effective&amp;#43;c%2B%2B" title="Effective C&amp;#43;&amp;#43;" target="_blank" rel="noreferrer"&gt;Effective C++&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Dicas do leitor Lucas Oliveira:&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="http://www.poodr.com/" target="_blank" rel="noreferrer"&gt;Practical Object-Oriented Design in Ruby by Sandi Metz&lt;/a&gt;&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/05/post29.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Por onde começar a programar um jogo</title><link>https://gamedeveloper.com.br/por-onde-comecar-programar/</link><guid>https://gamedeveloper.com.br/por-onde-comecar-programar/</guid><pubDate>Fri, 02 May 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Muita gente se perde na hora de começar a programar um jogo, e independente do tamanho do projeto pode ser realmente uma tarefa difícil saber por onde começar.&#10;</description><content:encoded>&lt;p&gt;Muita gente se perde na hora de começar a programar um jogo, e independente do tamanho do projeto pode ser realmente uma tarefa difícil saber por onde começar.&lt;/p&gt;&#10;&lt;p&gt;A melhor alternativa é sempre começar pela mecânica principal do jogo, quebrando ela em &lt;a href="https://gamedeveloper.com.br/definicao-de-prioridade-de-tarefas/" title="Tarefas"&gt;tarefas menores&lt;/a&gt;. Por exemplo, em um jogo onde um personagem movimenta-se pela tela, a primeira coisa que deve ser programada é este personagem. Antes mesmo de pensar em atacar, sistema de níveis, inimigos, e qualquer outra coisa, o jogador deve poder movimentar o personagem.&lt;/p&gt;&#10;&lt;p&gt;A partir disso, você pode criar um &lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-playground/" title="Playground"&gt;nível de playground&lt;/a&gt; para poder testar o comportamento do personagem com diversas opções no cenário do jogo. Isso é apenas um exemplo, pois esta abordagem pode variar de acordo com o tipo do jogo, mas no geral é sempre bom começar pela mecânica principal, e trabalhar nela até ficar bem polida.&lt;/p&gt;&#10;&lt;p&gt;Em jogos de puzzle, por exemplo, a primeira coisa a ser programada são os movimentos que o jogador pode fazer para resolver um puzzle, antes mesmo de programar o puzzle. Com os movimentos bem definidos e testados, programar os diferentes puzzles ficará mais fácil.&lt;/p&gt;&#10;&lt;p&gt;Algumas coisas que escrevi neste post já foram apresentadas nesta série &lt;a href="https://gamedeveloper.com.br/categories/como-programar-jogos/" title="Como começar"&gt;Como ser um programador de jogos&lt;/a&gt;, vale a pena conferir os posts anteriores por que tem muita coisa legal e útil para começar.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/05/post28.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Transformando jogo em produto</title><link>https://gamedeveloper.com.br/transformando-jogo-em-produto/</link><guid>https://gamedeveloper.com.br/transformando-jogo-em-produto/</guid><pubDate>Wed, 23 Apr 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Um game nasce de uma idéia ou um conceito, que então é validado com um protótipo, para depois tornar-se em algo jogável. Porém, esse “algo jogável” pode ser tecnicamente perfeito e, mesmo assim, não agradar aos jogadores. Nesse caso, a culpa não é da equipe de desenvolvimento, e sim de quem pensou na sua idéia sem tratá-la como um produto.&#10;</description><content:encoded>&lt;p&gt;Um game nasce de uma idéia ou um conceito, que então é validado com um protótipo, para depois tornar-se em algo jogável. Porém, esse “algo jogável” pode ser tecnicamente perfeito e, mesmo assim, não agradar aos jogadores. Nesse caso, a culpa não é da equipe de desenvolvimento, e sim de quem pensou na sua idéia sem tratá-la como um produto.&lt;/p&gt;&#10;&lt;p&gt;Para um jogo tornar-se um produto é necessário pensar em alguns detalhes antes (ou enquanto) o protótipo é desenvolvido, pois não basta o jogo ser bem feito e divertido se existe muita concorrência de jogos similares. Para transformar o jogo em um produto, deve-se montar um tipo de plano de negócio com foco em lançamento de produtos, e para isso deve-se levar em conta os seguintes itens:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Público-Alvo:&lt;/strong&gt; Quem vai jogar o seu jogo? Onde você vai encontrar o seu público-alvo? Como você vai fazê-lo jogador?&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Plataforma:&lt;/strong&gt; Em qual plataforma você quer lançar o seu jogo? A ideia é viável na plataforma escolhida? Como funciona a publicação de um jogo nessa plataforma?&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Mercado:&lt;/strong&gt; As pessoas vão querer jogar o seu jogo? A plataforma escolhida é viável? O mercado está saturado para o tipo de jogo que você quer fazer?&lt;/li&gt;&#10;&lt;li&gt;**Concorrência **Quais empresas e quais jogos são seus concorrentes diretos e indiretos? Quais jogos são similares em algumas funcionalidades?&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Diferenciais:&lt;/strong&gt; Por que as pessoas vão querer jogar o eu jogo ao invés dos jogos concorrentes? Por que um investidor colocaria dinheiro em seu projeto?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Basicamente, esses são os pontos iniciais para transformar um jogo em produto. Apenas com esse tipo de análise de negócio será possível descobrir se o seu jogo terá chances de ser um sucesso ou não. É algo simples de fazer, não demora muito, e pode te deixar rico ou frustrado (para então tentar de novo!).&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Dica do leitor Lucas Oliveira:&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Business_Model_Canvas" target="_blank" rel="noreferrer"&gt;Modelo Canvas para plano de negócio&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://canvanizer.com" target="_blank" rel="noreferrer"&gt;Site para montar um Canvas&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Dica do Martin Luenendonk, do site &lt;a href="https://roadtofunding.com" target="_blank" rel="noreferrer"&gt;STARTUP FUNDRAISING&lt;/a&gt;:&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://roadtofunding.com/investment-readiness-level/" target="_blank" rel="noreferrer"&gt;Investment Readiness Level Guide: How to Boost Your Startup’s Attractiveness to Venture Capital Investors using the Business Model Canvas&lt;/a&gt;&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/04/post27.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Definição de prioridade de tarefas</title><link>https://gamedeveloper.com.br/definicao-de-prioridade-de-tarefas/</link><guid>https://gamedeveloper.com.br/definicao-de-prioridade-de-tarefas/</guid><pubDate>Wed, 09 Apr 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Assim como em qualquer projeto, existem tarefas e elas necessitam de prioridade para você saber quais são mais importantes e urgentes. No desenvolvimento de um jogo, muitas vezes as tarefas podem ter dependência com outras áreas, como arte ou som, porém mesmo com dependências podemos definir prioridades nas tarefas.&#10;</description><content:encoded>&lt;p&gt;Assim como em qualquer projeto, existem tarefas e elas necessitam de prioridade para você saber quais são mais importantes e urgentes. No desenvolvimento de um jogo, muitas vezes as tarefas podem ter dependência com outras áreas, como arte ou som, porém mesmo com dependências podemos definir prioridades nas tarefas.&lt;/p&gt;&#10;&lt;p&gt;Podemos olhar para elas pensando exclusivamente na programação, assim você saberá o que deve ser programado primeiro. Por exemplo, não adianta fazer a programação do movimento de um personagem sem antes ter um personagem na tela. Algumas tarefas podem ser difíceis de priorizar, pois muitas podem ter a mesma dependência básica. Por exemplo, com o personagem na tela você pode fazer ele andar, atacar, pular, correr, etc, mas essas tarefas podem não dizer claramente quais são as mais importantes.&lt;/p&gt;&#10;&lt;p&gt;Para saber o que é mais importante na hora de programar, devemos olhar para o nosso objetivo. Se queremos fazer o personagem lutar, fazer ele se movimentar é mais importante do que fazer ele interagir com portas, por exemplo. Por isso, muitas vezes as tarefas são derivadas de uma tarefa maior, que na verdade é um requisito do jogo, uma mecânica, uma jogabilidade, uma feature, entre outras coisas. É importante também manter o foco, pois se o objetivo é ver o personagem lutar, não é necessário criar todo o nível nestas tarefa, pois o foco dela é jogabilidade.&lt;/p&gt;&#10;&lt;p&gt;A seguir está um exemplo de uma tarefa quebrada em outras menores, e (ordenado por prioridade sempre que possível). Através do exemplo abaixo, podemos ter uma idéia de por que uma tarefa tem mais prioridade do que a outra. Se ajudar, você podem também adicionar números nas tarefas e marcar o nome de qual tarefa é dependente dela, mas isso não é necessário se um objetivo tiver mais ou menos o mesmo tamanho que o exemplo. Se for muito maior do que isso, ele precisa ser quebrado em menores antes de definir as tarefas.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Objetivo&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Movimentar o personagem através de um controle de touch na tela&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Tarefas&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Desenhar jogador na tela (apenas uma imagem)&lt;/li&gt;&#10;&lt;li&gt;Desenhar botões na tela (cima, baixo, esquerda e direita)&lt;/li&gt;&#10;&lt;li&gt;Capturar o input do jogador nos botões&lt;/li&gt;&#10;&lt;li&gt;Mover o personagem de acordo com o input&lt;/li&gt;&#10;&lt;li&gt;Definir uma velocidade de movimento&lt;/li&gt;&#10;&lt;li&gt;Substituir a imagem do jogador por animações para todas direções&lt;/li&gt;&#10;&lt;li&gt;Alterar a imagem dos botões quando ele for pressionado&lt;/li&gt;&#10;&lt;li&gt;Testar a jogabilidade e refinar até ficar boa e constante&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Uma boa dica é utilizar ferramentas como o &lt;a href="http://trello.com" title="Trello" target="_blank" rel="noreferrer"&gt;Trello&lt;/a&gt; para organizar as tarefas. &lt;a href="https://gamedeveloper.com.br/gerenciamento-do-seu-tempo/" title="Gerenciamento de Tempo"&gt;Este post&lt;/a&gt; é legal para saber mais sobre o Trello e outras ferramentas e técnicas para organização do tempo, que podem ser úteis na organização das tarefas do projeto.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/04/post26.webp" medium="image"/></item><item><title>Como ser um programador de jogos: 200 mecânicas de gameplay</title><link>https://gamedeveloper.com.br/200-mecanicas-de-gameplay/</link><guid>https://gamedeveloper.com.br/200-mecanicas-de-gameplay/</guid><pubDate>Wed, 26 Mar 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Você consegue pensar em várias mecânicas de gameplay diferentes? Conseguiria definir o conceito de mais de 200 diferentes? No site Squidi.net atualmente estão listadas 200 exemplos de mecânica de gameplay diferentes, que podem ser utilizadas livremente por qualquer pessoa. Seu objetivo é chegar em 300 conceitos diferentes.&#10;</description><content:encoded>&lt;p&gt;Você consegue pensar em várias mecânicas de gameplay diferentes? Conseguiria definir o conceito de mais de 200 diferentes? No site Squidi.net atualmente estão listadas 200 exemplos de mecânica de gameplay diferentes, que podem ser utilizadas livremente por qualquer pessoa. Seu objetivo é chegar em 300 conceitos diferentes.&lt;/p&gt;&#10;&lt;p&gt;Pra que serve isso? O trabalho de um Game Designer é criar mecânicas e validá-las com protótipos de gameplay, pra garantir que o jogo seja divertido. Nesse site existem diversos exemplo muito bons e bem explicados de mecânicas diferentes, que podem ser misturadas ou até gerar novas idéias. É como se fosse um repositório de idéias genéricas de gameplay.&lt;/p&gt;&#10;&lt;p&gt;Isso também é útil para programadores e artistas, pois ao ler sobre como uma mecânica funciona, você também entenderá o trabalho necessário para implementá-la, tanto na parte de código quando na parte de arte. Está sem idéias? Dê uma olhada no site, e novos jogos irão surgir na sua cabeça!&lt;/p&gt;&#10;&lt;p&gt;Site: &lt;a href="http://www.squidi.net/three/index.php" target="_blank" rel="noreferrer"&gt;http://www.squidi.net/three/index.php&lt;/a&gt;&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/03/post25.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Feedback de ações para o jogador</title><link>https://gamedeveloper.com.br/feedback-de-acoes-para-o-jogador/</link><guid>https://gamedeveloper.com.br/feedback-de-acoes-para-o-jogador/</guid><pubDate>Wed, 19 Mar 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Uma das coisas mais frustrantes para um jogador é fazer uma ação no jogo e não ter um feedback do próprio jogo informando se a ação foi realizada, ou se ele fez algo errado.&#10;</description><content:encoded>&lt;p&gt;Uma das coisas mais frustrantes para um jogador é fazer uma ação no jogo e não ter um feedback do próprio jogo informando se a ação foi realizada, ou se ele fez algo errado.&lt;/p&gt;&#10;&lt;p&gt;É importante para um bom gameplay fornecer ao jogador um feedback para cada ação, para deixar claro se ação foi realizada com sucesso ou não.&lt;/p&gt;&#10;&lt;p&gt;O feedback pode ser uma mensagem de texto, um ícone na tela ou simplesmente um som. Fornecer um feedback das ações é um detalhe que deixa o jogo mais profissional, e evita o jogador de se sentir perdido ou irritado.&lt;/p&gt;&#10;&lt;p&gt;Este tipo de recurso faz parte do design de interface do jogo, pois deve ser prevista uma área para exibir o feedback para o jogador (caso seja um aviso gráfico). Um exemplo de feedback é a mensagem do windows quando você tenta apagar algo, ele pergunta se você realmente quer apagar:&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2016/06/messagebox.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;No caso de jogos, pode ser exibido uma outra mensagem informando que a ação foi realizada com sucesso (ou não). Pode parecer chato sempre querer confirmar ações, mas isso é menos chato para o jogador do que perder algo importante no jogo por falta deste recurso.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/03/post24.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Boas práticas para animações 2D</title><link>https://gamedeveloper.com.br/boas-praticas-para-animacoes-2d/</link><guid>https://gamedeveloper.com.br/boas-praticas-para-animacoes-2d/</guid><pubDate>Wed, 05 Mar 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Um artista costuma fazer a animação completa de um determinado sprite, porém nem sempre será necessário utilizar todos os frames da animação para causar o mesmo efeito.&#10;</description><content:encoded>&lt;p&gt;Um artista costuma fazer a animação completa de um determinado sprite, porém nem sempre será necessário utilizar todos os frames da animação para causar o mesmo efeito.&lt;/p&gt;&#10;&lt;p&gt;Mesmo com sprites detalhados, nem sempre a animação precisa ter muitos frames. Por exemplo, se você reparar em um jogo de luta 2D, a animação dos golpes normais (chute e soco) é muito rápida, praticamente um frame de antecipação e um do golpe. Muitos frames mostrando o golpe em detalhes vai pesar na memória, não será percebido no jogo e vai precisar de mais trabalho do artista.&lt;/p&gt;&#10;&lt;p&gt;Na imagem abaixo do jogo Street Fighter II, do Super Nintendo, podemos ver o que foi dito acima. Os dois primeiros frames são a antecipação, o frame do meio é o golpe, e os dois últimos frames é o feedback para o jogador após o golpe. Você pode conferir a spritesheet completa do Ken &lt;a href="http://www.spriters-resource.com/fullview/5572/" title="Ken" target="_blank" rel="noreferrer"&gt;clicando aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2016/06/Screen-Shot-2015-10-22-at-10-17-41-AM.webp"&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;Em jogos que possuem animações rápidas, quanto menos detalhes tiver é melhor. O importante é focar no que a animação deve passar, como a sensação de um golpe rápido em um jogo de luta. Vale mais a pena investir em detalhes do que em mais frames, assim o jogo fica mais bonito, menos pesado e será possível ver toda animação sem desperdiçar frames.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/03/post23.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Pixel Perfect</title><link>https://gamedeveloper.com.br/pixel-perfect/</link><guid>https://gamedeveloper.com.br/pixel-perfect/</guid><pubDate>Wed, 26 Feb 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Uma das dúvidas mais comuns no desenvolvimento de jogos para dispositivos móveis é qual a melhor maneira para que o jogo se adapte em várias resoluções, e uma das técnicas mais usadas é a chamada Pixel Perfect, que consiste em utilizar a PPI do aparelho como base para isto.&#10;</description><content:encoded>&lt;p&gt;Uma das dúvidas mais comuns no desenvolvimento de jogos para dispositivos móveis é qual a melhor maneira para que o jogo se adapte em várias resoluções, e uma das técnicas mais usadas é a chamada Pixel Perfect, que consiste em utilizar a PPI do aparelho como base para isto.&lt;/p&gt;&#10;&lt;p&gt;Neste post vou explicar como está técnica funciona usando como base os aparelhos da Apple com iOS. No Android e Windows Phone é a mesma coisa, porém eles possuem mais variações de PPI, por isso dá um pouco mais de trabalho. Aqui não vou explicar como identificar a DPI de um aparelho, e sim o uso da técnica. Lembrando que isto funciona apenas para jogos em 2D, pois em 3D é outra história.&lt;/p&gt;&#10;&lt;p&gt;PPI significa Pixels Per Inch, ou seja, é o número de pixels por polegada. Isto é literalmente o número de pixels que são exibidos em uma polegada da tela, quanto maior mais detalhes se o tamanho da tela for grande também. Algumas pessoas chama isso também de DPI, que significa Dots Per Inch, ou seja, pontos por polegada. Esta atribuição é incorreta quando falamos de aparelhos digitais, pois esta medida é usada em impressões. Porém, é bem comum chamar PPI de DPI, o próprio Google chama esta medida de DPI no Android, então acostume-se a ouvir ambos.&lt;/p&gt;&#10;&lt;p&gt;Primeiro, vamos analizar a resolução e o PPI dos aparelhos da Apple. No Android a DPI é classificada como MDPI, HDPI, XHDPI, entre outros. Não vou entrar nos detalhes de classificação, pois o importante neste técnica é o valor da PPI/DPI. No caso do Android, você pode encontrar &lt;a href="http://developer.android.com/guide/practices/screens_support.html" title="DPI" target="_blank" rel="noreferrer"&gt;mais detalhes aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;blockquote&gt;&lt;p&gt;iPhone 3G/3GS 320x480 163 ppi&lt;/p&gt;&#10;&lt;p&gt;iPhone 4/4S 640×960 326 ppi&lt;/p&gt;&#10;&lt;p&gt;iPhone 5/5C/5S 640×1136 326 ppi&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;A PPI do iPhone 3, assim como a resolução da sua tela, é exatamente a metade da PPI do iPhone 4 e de sua tela também. Por ser exatamente metade, isto significa que se você usar uma imagem do tamanho do iPhone 4 com resize no iPhone 3, ela ficará “perfeita”, e dai vem o termo Pixel Perfect. Isto só funciona quando a PPI (ou DPI) possui esta proporção de ser metade, então nestes casos você pode usar uma imagem maior com resize para um tamanho menor sem perder a qualidade e definição.&lt;/p&gt;&#10;&lt;p&gt;No caso do iPhone 5 temos um problema, embora sua PPI seja a mesma do iPhone 4, o tamanho da sua tela é diferente e não é proporcional, pois a largura é a mesma e a altura é diferente. Uma imagem no tamanho do iPhone 5 ficará cortada no iPhone 4, pois apesar da mesma DPI não é possível fazer o resize sem perder qualidade. Isto se aplica ao iPhone 3 também, que também tem a metade da PPI do iPhone 5, mas não tem a metade da resolução. Assim, a imagem ficará distorcida.&lt;/p&gt;&#10;&lt;p&gt;Estes são dois exemplos levando em conta apenas imagens com o tamanho da tela do aparelho, sendo que funciona do iPhone 4 para o iPhone 3, mas não funciona do iPhone 5 para os demais. Neste caso, muitos desenvolvedores criam uma imagem para o iPhone 5 e uma para o iPhone 4, que é usada também no iPhone 3.&lt;/p&gt;&#10;&lt;p&gt;Porém, para imagens que não ocupam a tela inteira como botões ou sprites, a mesma imagem usada no iPhone 5 pode ser usada no iPhone 4 sem resize, e usada no iPhone 3 com resize mas sem perder a qualidade e definição graças a PPI. Basicamente, a regra geral é esta:&lt;/p&gt;&#10;&lt;blockquote&gt;&lt;p&gt;Para imagens com o tamanho da tela:&lt;br&gt;&#10;– Resize só funciona sem perder a qualidade se os aparelhos tiverem a PPI/DPI e o tamanho da tela proporcionais.&lt;/p&gt;&#10;&lt;p&gt;Para imagens menores:&lt;br&gt;&#10;– Resize funciona baseado apenas na PPI/DPI, o tamanho da tela pode influenciar apenas o posicionamento dos itens na tela.&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;Já utilizei esta técnica algumas vezes quando trabalhei na &lt;a href="http://glu.com" title="Glu" target="_blank" rel="noreferrer"&gt;Glu Mobile&lt;/a&gt; e na &lt;a href="http://ea.com" title="EA" target="_blank" rel="noreferrer"&gt;Electronic Arts&lt;/a&gt;. O jogo que mais usei isto foi o &lt;a href="http://www.ea.com/scrabble-paid-ipad?intcmp=EACom_scrabbleipad_update_0313" title="Scrabble" target="_blank" rel="noreferrer"&gt;Scrabble&lt;/a&gt;, para &lt;a href="https://play.google.com/store/apps/details?id=com.ea.game.scrabblemattel_bv" title="Android" target="_blank" rel="noreferrer"&gt;Android&lt;/a&gt; e &lt;a href="https://itunes.apple.com/br/app/scrabble/id311691366?mt=8" title="iOS" target="_blank" rel="noreferrer"&gt;iOS&lt;/a&gt;. Todo seu layout é baseado na PPI/DPI do aparelho, e as imagens são usadas de acordo com esta classificação. Neste jogo o layout do tablet é diferente do smartphone, então não tivemos problemas com a PPI/DPI e resolução destes aparelhos, o que ajudou bastante no resultado final.&lt;/p&gt;&#10;&lt;p&gt;Espero ter conseguido explicar direito esta técnica, ela é bem simples de usar e um pouco complicada de explicar. Lembre-se que este exemplo foi feito para os modelos de iPhone, que é o mais simples de todos. Aparelhos Android geralmente dão mais problemas por causa da fragmentação e falta de padrões por parte dos fabricantes, mas não é impossível fazer uso do Pixel Perfect da mesma maneira. Qualquer dúvida, fique a vontade para perguntar nos comentários abaixo!&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/02/post22.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Jogue bastante, mas jogos diferentes</title><link>https://gamedeveloper.com.br/jogue-bastante-mas-jogos-diferentes/</link><guid>https://gamedeveloper.com.br/jogue-bastante-mas-jogos-diferentes/</guid><pubDate>Wed, 12 Feb 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Muita gente acha quem trabalha com games fica jogando o dia inteiro. Isto é verdade, jogamos muito o projeto em que trabalhamos, mas também precisamos jogar outras coisas para ter novas ideias.&#10;</description><content:encoded>&lt;p&gt;Muita gente acha quem trabalha com games fica jogando o dia inteiro. Isto é verdade, jogamos muito o projeto em que trabalhamos, mas também precisamos jogar outras coisas para ter novas ideias.&lt;/p&gt;&#10;&lt;p&gt;É incrível como, com o passar o tempo, quanto mais você desenvolve games, mais seu olhar fica atento a detalhes em um jogo. Não estou falando disso no sentido de falar mal de um jogo ou ficar achando defeitos, mas sim no sentido de aprender observando o jogo.&lt;/p&gt;&#10;&lt;p&gt;Por exemplo, você pode estar desenvolvendo um jogo em que uma determinada mecânica da jogabilidade não está muito boa. Neste caso, você pode jogar jogos que tenham a mecânica parecida e tentar entender como o seu problema foi resolvido neste jogo. Este é um dos benefícios de jogar tentando entender como o jogo foi feito, mas existem outras formas de aprender com games.&lt;/p&gt;&#10;&lt;p&gt;Jogar tipos diferentes de jogos, que você normalmente não está acostumado, pode te ajudar muito a aprender novas mecânicas de jogabilidade e até ter novas ideias para interface e HUD. É possível aprender e ter ideias para seus próprios projetos jogando desde games AAA hardcore para consoles até jogos sociais de Facebook e mobile. Mesmo que você não goste do jogo, ou não seja o seia tipo de jogo, jogue para extrair novas experiências que você pode proporcionar aos seus jogadores.&lt;/p&gt;&#10;&lt;p&gt;Se você quer aprender mesmo observando outros jogos, tente fazer isto: pegue um jogo que você não gosta e acha que tem muitos defeitos e tente melhorá-lo. Você irá, pelo menos, analisar o jogo, escrever um &lt;a href="https://gamedeveloper.com.br/game-design-document/" title="GDD"&gt;GDD&lt;/a&gt; para definir o game design e programar um &lt;a href="https://gamedeveloper.com.br/como-ser-um-programador-de-jogos-prototipos/" title="Protótipo"&gt;protótipo&lt;/a&gt; para validar a jogabilidade. Se realmente você conseguiu melhorar o jogo seu aprendizado foi muito grande durante o processo. Basicamente, não critique se você não puder fazer melhor.&lt;/p&gt;&#10;&lt;p&gt;Não esqueça também de aprender com os famosos glitches, como no vídeo abaixo. Tentar entender uma mecânica para aproveitar em uma ideia é algo simples comparado com tentar entender como um determinado glitch acontece e por que.&lt;/p&gt;&#10;&lt;p&gt;&lt;iframe style="width: 100%" height="400" src="https://www.youtube.com/embed/sotqQFRUeHE" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/02/post20.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Gerenciamento do seu tempo</title><link>https://gamedeveloper.com.br/gerenciamento-do-seu-tempo/</link><guid>https://gamedeveloper.com.br/gerenciamento-do-seu-tempo/</guid><pubDate>Wed, 22 Jan 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Sem dúvidas um dos principais problemas que a maioria dos desenvolvedores enfrentam é a falta de tempo para se dedicar em um projeto, mas isso o pode ser amenizado com umas dicas para otimizar seu tempo.&#10;</description><content:encoded>&lt;p&gt;Sem dúvidas um dos principais problemas que a maioria dos desenvolvedores enfrentam é a falta de tempo para se dedicar em um projeto, mas isso o pode ser amenizado com umas dicas para otimizar seu tempo.&lt;/p&gt;&#10;&lt;p&gt;Tudo que esta escrito neste post eu aprendi com o tempo e experiência. Algumas coisas deram certo pra mim e algumas para outras pessoas, por isso a melhor dica que posso dar é tentar sempre encontrar alguma forma de melhorar o uso do seu tempo, pois sem isso você já está perdendo um tempo que poderia estar trabalhando no seu jogo.&lt;/p&gt;&#10;&lt;p&gt;Uma das primeiras coisas que testei foi a técnica Pomodoro (&lt;a href="http://pomodorotechnique.com/" title="Pomodoro" target="_blank" rel="noreferrer"&gt;Pomodoro Technique&lt;/a&gt;), que consiste em se concentrar por um tempo e depois descansar alguns minutos. Por exemplo, você pode trabalhar sem parar por 25 minutos e depois faz uma pausa de 5 minutos para fazer o que quiser, e depois continue repetindo este ciclo várias vezes. O tempo de descanso pode variar, mas o de trabalho não.&lt;/p&gt;&#10;&lt;p&gt;Existem várias maneiras de usar esta técnica, a minha preferida é esta extensão para o Chrome chamada &lt;a href="https://chrome.google.com/webstore/detail/strict-workflow/cgmnfnmlficgeijcalkgnnkigkefkbhd" title="Strict" target="_blank" rel="noreferrer"&gt;Strict Workflow&lt;/a&gt;. Ele conta o tempo de trabalho e descanso e também bloqueia seu acesso a sites que você quiser durante os 25 minutos. Eu, pessoalmente, não consegui me adaptar para trabalhar usando esta técnica, pois as vezes estou concentrado e não quero parar meu tempo para descansar. Porém, para estudar funciona muito bem.&lt;/p&gt;&#10;&lt;p&gt;Outra forma de organizar seu tempo é criando uma lista de tarefas e colocando prazos. Esta parte é muito importante, coloque prazos e planeje sua semana. Eu utilizo o &lt;a href="http://www.any.do/" title="Any.Do" target="_blank" rel="noreferrer"&gt;Any.Do&lt;/a&gt;, que é um aplicativo mobile com uma extensão para Chrome também. Nele listo as tarefas que tenho que fazer e coloco datas e alarmes para me lembrar. Funciona muito bem para tarefas do dia-a-dia que você tem que lembrar e fazer, mas para trabalhar eu prefiro usar outra coisa.&lt;/p&gt;&#10;&lt;p&gt;Eu senti uma necessidade de organizar os posts do blog, porém o Any.Do não funcionou na maneira que eu queria para isto. Então, decidi usar o &lt;a href="https://www.google.com/calendar/" title="Calendar" target="_blank" rel="noreferrer"&gt;Google Calendar&lt;/a&gt;, e até hoje funciona muito bem. Eu planejo os posts todas as semanas, e me cobro para escrever e postar nos dias certos. Se você acompanha o blog há um tempo pode perceber que nos útimos meses eu comecei a postar com muito mais frequência, e foi graças a minha organização no Google Calendar.&lt;/p&gt;&#10;&lt;p&gt;No trabalho também utilizo o Google Calendar para colocar prazos de cada projeto, mas não das tarefas relacionadas ao projeto em si.Lembre-se que neste post não estou falando em organização de projetos, que utilizo outros recursos como o &lt;a href="https://trello.com/" title="Trello" target="_blank" rel="noreferrer"&gt;Trello&lt;/a&gt;. Estou falando de como eu organizo meu tempo e minhas tarefas no dia para conseguir fazer tudo que preciso e quero. O foco é muito importante para que todo seu planejamento dê certo, e você precisa estar motivado para conseguir realizar todas as suas terefas.&lt;/p&gt;&#10;&lt;p&gt;Para meus projetos pessoais eu geralmente sou mais produtivo a noite, porém as vezes chego cansado do trabalho e sem vontade de fazer outra coisa. Nessa hora eu busco me distrair um pouco jogando ou assistindo algo, e depois eu começo a trabalhar. Isso funciona muito bem para mim, principalmente com jogos, pois eu perco até o sono. O único problema é que as vezes você pode acabar jogando até tarde e esquece de trabalhar, mas isso não é algo ruim se acontecer  as vezes, afinal a gente merece descansar também!&lt;/p&gt;&#10;&lt;p&gt;No final de semana eu durmo até tarde, vou passear, jogo, assisto séries e filmes e tento trabalhar em meus projetos pessoais, porém sem a cobrança que me faço durante a semana. Por isso, sempre fazemos estas coisas juntos, mesmo que cada um tenha que fazer algo diferente. E funciona muito bem, pois a companhia dela é demais todos os dias =)&lt;/p&gt;&#10;&lt;p&gt;Por mim, nada disso funciona sem um elemento primordial: Música! Eu só consigo me concentrar com música, por isso uso no escritório um fone gigante que isola o som externo (este aqui da Philips), é muito bom e recomendo! Eu geralmente ouvia trilha sonora de filmes e jogos no Youtube (procure por OST), até fiz &lt;a href="https://www.youtube.com/playlist?list=PLIDWyOQe6ONs0eHCTvs7Rok0pr5TcP3xY" title="Playlist" target="_blank" rel="noreferrer"&gt;esta playlist&lt;/a&gt; com algumas que mais gostei, mas agora estou ouvindo tudo no &lt;a href="http://www.rdio.com/" title="Rdio" target="_blank" rel="noreferrer"&gt;rdio&lt;/a&gt;, que é fantástico. O vídeo abaixo é uma coletânea de músicas épicas, este é o meu preferido da minha playlist.&lt;/p&gt;&#10;&lt;p&gt;&lt;iframe style="width: 100%" height="400" src="https://www.youtube.com/embed/WU7SGn0MeP0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;&#10;&lt;p&gt;Outra coisa que faço para otimizar meu tempo é tentar fazer coisas em qualquer lugar. Por exemplo, eu leio e respondo emails no caminho para o trabalho. Quando estou em algum lugar esperando uso meu tablet para escrever algum post ou organizar minhas terafas. Quando preciso me concentrar, mas não aguento ficar em casa ou no escritório, vou para um café e levo meu tablet. Também leio bastante notícias da indústria e livros de fantasia para relaxar, quando não estou jogando no celular ou no tablet.&lt;/p&gt;&#10;&lt;p&gt;Existem muitas outras ferramentas para organizar seu tempo, e muitas técnicas para te manter focado. O que escrevi aqui é o que funciona comigo, mas para você pode ser diferente. Se tiver alguma recomendação fique a vontade para postar nos comentários. É importante focar, mas também saiba aproveitar os momentos para relaxar e não deixe de fazer as coisas que você tem vontade.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/01/post19.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Você já fez um jogo?</title><link>https://gamedeveloper.com.br/voce-ja-fez-um-jogo/</link><guid>https://gamedeveloper.com.br/voce-ja-fez-um-jogo/</guid><pubDate>Wed, 15 Jan 2014 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Em primeiro lugar, peço desculpas por não ter postado nesta série nas últimas semanas. Mas agora eu voltarei a publicar semanalmente, toda quarta-feira, e no primeiro post deste ano começo com a pergunta: você já fez um jogo?&#10;</description><content:encoded>&lt;p&gt;Em primeiro lugar, peço desculpas por não ter postado nesta série nas últimas semanas. Mas agora eu voltarei a publicar semanalmente, toda quarta-feira, e no primeiro post deste ano começo com a pergunta: você já fez um jogo?&lt;/p&gt;&#10;&lt;p&gt;Quase todo mundo que fala que já fez um jogo, na verdade nunca fez um jogo. Fazer um jogo envolve criar o conceito, desenvolver e publicar para o mundo conhecer seu projeto e jogar. E, infelizmente, muitas pessoas não chegam a publicar seu jogo. Quando eu falo publicar, não é necessariamente vender o jogo em alguma loja virtual. Publicar é apenas tornar público, ou seja, colocar em algum site um link para as pessoas baixarem e compartilhar esta informação com seus amigos.&lt;/p&gt;&#10;&lt;p&gt;Geralmente, o principal objetivo em desenvolver um jogo é divertir as pessoas. Existem diversos livros como o &lt;a href="http://jnsilva.ludicum.org/Huizinga_HomoLudens.pdf" title="Homo Ludens" target="_blank" rel="noreferrer"&gt;Homo Ludens&lt;/a&gt; e &lt;a href="https://gamedeveloper.com.br/regras-do-jogo-editora-blucher/" title="Regras do Jogo"&gt;Regras do Jogo&lt;/a&gt; que falam da importância dos jogos na sociedade, e não há nada mais satisfatório do que ver uma pessoa jogando algo que você desenvolveu. É por isso que entrei nesta área, e é isso que me deixa apaixonado em criar jogos e experiências para as pessoas fugirem da sua realidade e se divertirem.&lt;/p&gt;&#10;&lt;p&gt;Não faz sentido fazer um jogo e não divulgar para todos jogarem. Você pode fazer diversos jogos, mas uma pessoa que fez e publicou um único jogo tem um diferencial maior que o seu para trabalhar em uma empresa de jogos. Publicar um jogo também é tornar seu portifólio público, e se você quer trabalhar com jogos isto é essencial. Não importa se você acha que não vai fazer dinheiro com o seus primeiros jogos, você tem que publicar para começar a receber feedback das pessoas e validar se você está indo para o caminho certo.&lt;/p&gt;&#10;&lt;p&gt;Portanto, se você desenvolveu jogos e não publicou nenhum deles, você &lt;strong&gt;NÃO&lt;/strong&gt; fez um jogo. E isso vale para toda forma de arte, se você não divulgar o que você faz para as pessoas verem e darem seu feedback, você não pode se considerar um artista. Não seja tímido e não tenha vergonha, mostre para o mundo seu trabalho, e então você poderá falar que faz jogos.&lt;/p&gt;&#10;&lt;p&gt;O meu portfólio está desatualizado desde que terminei a minha pós-graduação em 2010, então lá não estão os jogos que desenvolvi na &lt;a href="http://glu.com" title="Glu" target="_blank" rel="noreferrer"&gt;Glu Mobile&lt;/a&gt;, &lt;a href="http://ea.com" title="EA" target="_blank" rel="noreferrer"&gt;Electronic Arts&lt;/a&gt; e freelances. Em breve vou montar uma página nova para mostrar todos os jogos que participei do desenvolvimento, mas por enquanto vocês podem ver o meu &lt;a href="https://cicanci.com" title="Portfolio" target="_blank" rel="noreferrer"&gt;portfólio aqui&lt;/a&gt;.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2014/01/post181.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Parallax</title><link>https://gamedeveloper.com.br/parallax/</link><guid>https://gamedeveloper.com.br/parallax/</guid><pubDate>Wed, 18 Dec 2013 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>Praticamente todo jogo em 2D com visão lateral, seja o Super Mario Bros ou Mortal Kombat, possui um cenário de fundo. Este cenário não é estático, pois precisa dar a impressão de que realmente existe algo “vivo” no fundo do jogo, e que complementa a fase.&#10;</description><content:encoded>&lt;p&gt;Praticamente todo jogo em 2D com visão lateral, seja o Super Mario Bros ou Mortal Kombat, possui um cenário de fundo. Este cenário não é estático, pois precisa dar a impressão de que realmente existe algo “vivo” no fundo do jogo, e que complementa a fase.&lt;/p&gt;&#10;&lt;p&gt;Para que o fundo mude de acordo com a movimentação do personagem, utilizando a técnica chamada de &lt;a href="http://en.wikipedia.org/wiki/Parallax_scrolling" title="Wiki" target="_blank" rel="noreferrer"&gt;Parallax Scrolling&lt;/a&gt;, que consiste em movimentar a imagem do fundo de acordo com a movimentação do personagem, porém mais lento para dar a impressão de profundidade. Um dos detalhes mais interessantes do Parallax Scrolling é que quando mais imagens com velocidade de movimento diferente houverem no fundo da fase, maior será a sensação de profundidade.&lt;/p&gt;&#10;&lt;p&gt;O exemplo abaixo é um pseudo-código baseado na &lt;a href="http://www.cocos2d-x.org/" title="cocos2d-x" target="_blank" rel="noreferrer"&gt;cocos2d-x&lt;/a&gt; que mostra como podemos implementar esta técnica, utilizando três imagens diferentes (podem ser várias imagens, depende da profundidade e detalhes que você quer).&lt;/p&gt;&#10;&lt;p&gt;Iniciamos as variáveis com cada imagem. Devemos ter atenção na hora de adicionar as imagens, pois na cocos2d essa ordem influência na ordem que a imagem será desenhada na tela. Neste caso queremos o pSky atrás, e as demais imagens na sua frente.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;CCSprite&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pSky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CCSprite&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;sky.webp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;addChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pSky&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;CCSprite&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pMountain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CCSprite&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;mountain.webp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;addChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pMountain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;CCSprite&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pGround&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CCSprite&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ground.webp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;addChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pGround&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;Depois de inicializar e posicionar as imagens nos lugares corretos (com o setPosition()), vem a parte da movimentação. Vamos imaginar que temos duas variáveis que nos dizem para qual lado o jogador está se movimentando, assim vamos fazer o Parallax ir para o lado correto. Também vamos imaginar que já existe uma variável com o sprite do jogadar inicializada.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pPlayerMoveRight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pSky&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ccp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pSky&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pSky&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pMountain&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ccp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pMountain&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;10.0f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pMountain&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pGround&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ccp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pGround&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;100.0f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pGround&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pPlayer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ccp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pPlayer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;100.0f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pPlayer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pPlayerMoveLeft&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pSky&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ccp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pSky&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pSky&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pMountain&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ccp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pMountain&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;10.0f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pMountain&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pGround&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ccp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pGround&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;100.0f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pGround&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pPlayer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ccp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pPlayer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;100.0f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pPlayer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;Repare que o valor da movimentação do pSky é bem menor do que os demais. Isso influencia na velocidade do movimento, pois o que está mais afastado deve se mover mais lentamente para dar a impressão de profundidade. O resultado é que o céu irá se movimentar bem devagar, pois está mais longe, depois a montanha irá se movimentar um pouco mais rápido, mas ainda lenta por estar longe também, e o chão irá se movimentar na mesma velocidade que o jogador.&lt;/p&gt;&#10;&lt;p&gt;&lt;figure&gt;&#10; &lt;img&#10; class="my-0 rounded-md"&#10; loading="lazy"&#10; decoding="async"&#10; fetchpriority="low"&#10; alt=""&#10; src="https://gamedeveloper.com.br/images/2013/12/image008.gif" title="Parallax"&gt;&#10;&lt;/figure&gt;&#10;&lt;br&gt;&#10;Esta técnica pode ser utilizada em praticamente qualquer jogo 2D com visão lateral, seja de aventura, corrida, luta, ou qualquer outro estilo. Alguns jogos com visão lateral e gráficos 3D (o que chamamos também de 2.5D) utilizam essa técnica com modelos ao invés de imagens, o que aumenta a profundidade. Um exemplo é o &lt;a href="http://trine-thegame.com/site/" title="Trine" target="_blank" rel="noreferrer"&gt;Trine&lt;/a&gt;, que possui jogabilidade 2D com gráficos 3D, e podemos ver claramente o Parallax feito com modelos 3D no video abaixo.&lt;/p&gt;&#10;&lt;p&gt;&lt;iframe style="width: 100%" height="400" src="https://www.youtube.com/embed/LXdwRmiZam4" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;&#10;&lt;p&gt;Mais informações sobre o Parallax Scrolling e fonte das imagens na &lt;a href="http://en.wikipedia.org/wiki/Parallax_scrolling" title="Wiki" target="_blank" rel="noreferrer"&gt;Wikipedia&lt;/a&gt;.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2013/12/post17.webp" medium="image"/></item><item><title>Como ser um programador de jogos: Game Design Document</title><link>https://gamedeveloper.com.br/game-design-document/</link><guid>https://gamedeveloper.com.br/game-design-document/</guid><pubDate>Wed, 11 Dec 2013 00:00:00 +0000</pubDate><category>Como Programar Jogos</category><description>O Game Design Document (GDD), é um documento escrito pelo Game Designer para os programadores e artistas entenderem sua visão da mecânica do jogo. Este documento é muito importante, mas infelizmente é tão ignorado quanto o próprio Game Designer.&#10;</description><content:encoded>&lt;p&gt;O Game Design Document (GDD), é um documento escrito pelo Game Designer para os programadores e artistas entenderem sua visão da mecânica do jogo. Este documento é muito importante, mas infelizmente é tão ignorado quanto o próprio Game Designer.&lt;/p&gt;&#10;&lt;p&gt;Muita gente acha que o GDD é praticamente a mesma coisa que a especificação técnica que um analista de sistemas escrever &lt;del&gt;depois&lt;/del&gt; antes da equipe começar a fazer o projeto. Ambos são documentos que devem ser escritos antes do desenvolvimento do projeto, porém o GDD não é definitivo e pode ter constantes mudanças, pois algumas coisa no jogo podem não sair como foi esperado, e neste caso mudanças são necessárias.&lt;/p&gt;&#10;&lt;p&gt;Nas primeiras fases do desenvolvimento, enquanto a equipe está trabalhando no protótipo junto com o Game Designer, ele está escrevendo o GDD e definindo todas as mecânicas e features do jogo. Pode ser que após o término do protótipo, usado para apenas para validar a mecânica básica do jogo, muita coisa tenha mudado, e o Game Designer deve manter o GDD sempre atualizado, e sempre pedir para a equipe acompanhar as atualizações.&lt;/p&gt;&#10;&lt;p&gt;Na Glu Mobile, todo GDD é uma página na wiki interna, e todo mundo da empresa tem acesso para ler e conhecer mais sobre os jogos. É muito legal este tipo de documento por ser uma página onde todos podem editar e ver as alterações, as vezes mais prático do que compartilhar um o GDD usando o Google Drive ou Dropbox, por exemplo. Eu achava muito legal, e passava horas lendo o GDD de outros projetos!&lt;/p&gt;&#10;&lt;p&gt;Compartilhar um documento funciona bem neste caso, pois geralmente a equipe não vai editá-lo, irão apenas visualizar seu conteúdo, por isso não é normal acontecer problemas de mais de uma pessoa editar ao mesmo tempo. Independente da maneira que você irá fazer o GDD, faça e sempre avise a equipe que nova alterações foram feitas, não espere que todo mundo irá sempre ler este arquivo para ver se algo mudou. Mesmo tendo um documento, é bom conversar sobre seu conteúdo em reuniões, para ter certeza de que todos entenderam a visão do Game Designer.&lt;/p&gt;&#10;&lt;p&gt;A organização do documento é algo que não tem um padrão, mas existem diversas sugestões. Meu modelo favorito é o apresentado pelo Scott Rogers, no livro &lt;a href="https://gamedeveloper.com.br/level-up-game-design/" title="Livro"&gt;Level Up: Um guia para o design de grande jogos&lt;/a&gt;. Quando fiz meu TCC na pós-graduação em games, o &lt;a href="https://gamedeveloper.com.br/fim-do-tcc-da-pos-graduacao-oniro/" title="Oniro"&gt;jogo Oniro&lt;/a&gt;, usei o modelo do livro &lt;a href="http://www.amazon.com/Game-Design-Workshop-Playcentric-Innovative/dp/0240809742/ref=sr_1_1?ie=UTF8&amp;amp;qid=1386786435&amp;amp;sr=8-1&amp;amp;keywords=Game&amp;#43;Design&amp;#43;Workshop" title="Livro" target="_blank" rel="noreferrer"&gt;Game Design Workshop&lt;/a&gt;, da Tracy Fullerton, e você pode baixar o GDD que escrevi &lt;a href="https://gamedeveloper.com.br/downloads/GDD_Oniro_BrunoCicanci.pdf" rel="nofollow"&gt;clicando aqui&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;Existem diversos modelos de GDD espalhados por ai, porém vale lembrar que nada em um modelo de GDD é obrigatório ou deve ser usado sempre. Você deve analisar estes modelos e ver o que se adapta melhor ao seu jogo, e preencher apenas estes itens. Se algum item do GDD não será usado, ou não faz sentido manter, remova do seu documento para deixar tudo mais organizado e apenas com informações úteis. Não adianta escrever 100 páginas se a equipe não vai ler, por isso existem dicas legais no livro do Scott Rogers para fazer uma versão menor para facilitar a apresentação da ideia do jogo.&lt;/p&gt;&#10;&lt;p&gt;A partir do GDD, também, o produtor ou o próprio Game Designer pode criar a lista de tarefas de cada área, o que facilita muito o processo de desenvolvimento. Em muitas empresas é comum programadores e artistas ajudarem o Game Designer no começo do documento, principalmente apontando as limitações técnicas da ideia antes de começar a fazer ou durante o desenvolvimento do protótipo.&lt;/p&gt;&#10;&lt;p&gt;Como em qualquer equipe, para qualquer projeto, a chave do sucesso é uma boa comunicação entre todos os membros de forma clara e transparente. Não tenha medo de compartilhar o GDD com a equipe, ele não deve ser um segredo guardo apenas para o Game Designer.&lt;/p&gt;</content:encoded><media:content url="https://gamedeveloper.com.br/images/2013/12/post16.webp" medium="image"/></item></channel></rss>