diff --git a/files/pt-br/games/anatomy/index.html b/files/pt-br/games/anatomy/index.html deleted file mode 100644 index 2e23cfb8b18c8a..00000000000000 --- a/files/pt-br/games/anatomy/index.html +++ /dev/null @@ -1,338 +0,0 @@ ---- -title: Anatomia de um vídeo game -slug: Games/Anatomy -translation_of: Games/Anatomy ---- -
{{IncludeSubnav("/pt-BR/docs/Games")}}
- -Este artigo analisa a anatomia e o fluxo de trabalho do vídeo game médio de um ponto de vista técnico, em termos de como o loop principal deve ser executado. Isso ajuda os iniciantes da arena do desenvolvimento de jogos modernos a entender o que é necessário ao construir um jogo e como os padrões da web como o JavaScript se prestam como ferramentas. Os programadores de jogos experientes que são novos no desenvolvimento da web também podem se beneficiar.
-O objetivo de todo vídeo game é apresentar ao usuário uma situação, aceitar sua entrada, interpretar estes sinais em ações, e calcular uma nova situação resultante dessas ações. Jogos estão constantemente repetindo estes estágios, de novo e de novo, até alguma condição final ocorrer (como vencer, perder, ou sair para ir dormir). Não surpreendentemente, este padrão corresponde a como um mecanismo de jogo está programado.
- -As especificidades dependem do jogo.
- -Alguns jogos guiam este ciclo pela entrada do usuário. Imagine que você está desenvolvendo um "encontre as diferenças entre estas duas imagens similares". Esses jogos apresentam duas imagens ao usuário, eles aceitam seus cliques (ou toques), eles interpretam as entradas como um sucesso, falha, pausa, interação com o menu, etc., finalmente, eles calculam uma cena atualizada resultante dessas entradas. O ciclo do jogo é avançado pelas entradas do usuário e pela esperas até que ele as forneça. Isso é mais aproximado de um jogo baseado em turnos onde não há demanda de uma constante atualização a cada frame, somente quando o jogador reaje.
- -Outros jogos demandam controle sobre cada um dos menores intervalos de tempo possíveis. Os mesmos princípios acima aplicam-se com uma pequena diferença: cada frame de animação avança o ciclo e cada mudança na entrada do usuário é capturada no primeiro turno disponível. Este modelo uma vez por frame é implementado em algo chamado loop principal. Se o seu jogo é baseado em tempo, então essa será a autoridade a qual as suas simulações irão obedecer.
- -Mas o jogo pode não precisar de controle por frame. Seu game loop pode ser similar ao exemplo encontre as diferenças e basear-se em eventos de entrada. Ele pode requerer ambos, entrada e tempo simulado. Ele pode até mesmo ter um ciclo baseado em algo totalmente diferente.
- -JavaScript Moderno — como descrito nas próximas seções — felizmente, facilita o desenvolvimento de um loop principal "execute uma vez por frame". É claro, seu jogo será somente tão otimizado quando o fizer. Se parece que algo deveria estar ligado a um evento menos frequente, seria uma boa ideia implementá-lo fora do loop principal (mas não sempre).
- -JavaScript trabalaha melhor com eventos e chamadas de funções. Navegadores modernos esforçam-se para chamar métodos à medida que são necessários e ociosos (ou fazem suas outras tarefas) nos intervalos. É uma excelente ideia ligar seu código aos momentos apropriados a eles. Pense se a sua função realmente precisa ser chamada em um estrito intervalo de tempo, a cada frame, ou somente após algo acontecer. Ser mais específico com o navegador sobre quando a sua função precisa ser chamada permite que o navegador otimize essa chamada. Também, isso facilitará o seu trabalho.
- -Alguns códigos precisam ser rodados frame por frame, então por quê ligar essas funções a qualquer coisa que não seja a atualização de tela do navegador? Na web, {{ domxref("window.requestAnimationFrame()") }} será a base da maioria dos mais bem programados loops principais do tipo frame por frame.
Uma chamada de função deve ser passada dentro da função anterior quando a mesma for chamada. Esta chamdada de função será executada em um tempo adequado antes da próxima atualização de tela. Eis um exemplo de um loop principal simples:
window.main = function () { - window.requestAnimationFrame( main ); - - // Whatever your main loop needs to do. -}; - -main(); //Start the cycle.- -
Nota: Em cada método do main()
discutido aqui, nós agendamos uma nova requisição requestAnimationFrame
antes de executar o conteúdo de nosso loop. Isso não é por acidente, e é considerado boa prática. Chamando o próximo requestAnimationFrame
anteriormente garante que o navegador receba a chamada a tempo de planejar adequadamente, mesmo que seu frame atual falhe em sua (?VSync window?).
O trecho de código acima possui duas declarações. A primeira cria uma função como uma variável global chamada main()
. Esta função faz algum trabalho e também diz ao navegador para camá-la na próxima frame com window.requestAnimationFrame()
. A segunda declaração chama a função main()
, definida na primeira declaração. Pelo fato do main()
ser chamado uma vez na segunda declaração e cada chamada dele colocá-lo na lista de coisas a fazer na próxima frame, main()
é sincronizado com a sua taxa de frame.
É claro que esse loop não é perfeito. Antes de discutirmos maneiras de mudá-lo, deixe-nos discutir o que já está bem.
- -Cronometrando o loop principal para quando o navegador atualiza a tela o permite rodar o seu loop tão frequentemente quanto o navegador queira atualizar. Você tem controle sobre cada frame de animação. Isso é muito simples por que main()
é a única função em loop. Um jogo de primeira pessoa (ou um jogo similar) apresenta uma nova cena a cada frame. Você realmente não pode ser mais suave e receptivo do que isso.
Mas não assuma imediatamente que animações requerem controle frame por frame. Animações simples podem ser facilmente desenvolvidas até mesmo com aceleração-GPU, com animações CSS e com outras ferramentas inclusas no navegador. Existem muitas delas que farão sua vida mais fácil.
- -Existem dois problemas óbvios com nosso loop principal anterior: main()
polui o objeto {{ domxref("window") }}
(onde todas as variáveis globais são armazenadas) e o código de exemplo não nos permite parar o loop a menos que toda a aba seja fechada ou atualizada. Para o primeiro problema, se você quer que o loop principal apenas rode sem precisar de fácil acesso (direto) a ele, você pode criá-lo como uma Função Diretamente Invocada (Immediately-Invoked Function Expression - IIFE).
/* -* Starting with the semicolon is in case whatever line of code above this example -* relied on automatic semicolon insertion (ASI). The browser could accidentally -* think this whole example continues from the previous line. The leading semicolon -* marks the beginning of our new line if the previous one was not empty or terminated. -*/ - -;(function () { - function main() { - window.requestAnimationFrame( main ); - - // Your main loop contents. - } - - main(); // Start the cycle -})();- -
Quando o browser alcançar este IIFE, ele irá definir o seu próprio loop principal e imediatamente agenda-o para para o próximo frame. Ele não será anexado a nenhum objeto e main
(ou main()
para métodos) será um nome válido sem uso no resto da aplicação, livre para ser definido como outra coisa.
Nota: Na prática, é mais comum previnir o próximo requestAnimationFrame()
com uma declaração if
, no lugar de chamar cancelAnimationFrame()
.
Para o próximo problema, parando o loop principal, você precisará cancelar a chamada a main()
com window.cancelAnimationFrame()
. Você precisará passar para cancelAnimationFrame()
o token do ID dado pelo requestAnimationFrame()
quando ele foi chamado. Vamos assumir que as funções do seu jogo e variáveis estão construídas em um namespace que você chamou de MyGame
. Expandindo o nosso último exemplo, o loop principal ficaria parecido com isto:
/* -* Starting with the semicolon is in case whatever line of code above this example -* relied on automatic semicolon insertion (ASI). The browser could accidentally -* think this whole example continues from the previous line. The leading semicolon -* marks the beginning of our new line if the previous one was not empty or terminated. -* -* Let us also assume that MyGame is previously defined. -*/ - -;(function () { - function main() { - MyGame.stopMain = window.requestAnimationFrame( main ); - - // Your main loop contents. - } - - main(); // Start the cycle -})();- -
Nós temos agora uma variável declarada no namespace do nosso MyGame
, que nos chamamos de stopMain
, e que contém o ID retornado pela execução mais recente do requestAnimationFrame()
do nosso loop principal. Em algum ponto, nós podemos parar o loop principal pedindo ao browser para cancelar a requisição que corresponde ao nosso token.
window.cancelAnimationFrame( MyGame.stopMain );- -
A chave para programar loop principal, no JavaScript, é anexá-lo a qualquer evento que deve estar dirigindo sua ação e prestar atenção a como os diferentes sistemas envolvidos interagem entre si. Você poderá ter multiplos componentes dirigidos por multiplos diferentes tipos de eventos. Isto parece complexidade desnecessária mas pode ser só uma boa otimização (não necessária, é claro). O problema é que você não está programando um loop principal típico. No JavaScript, você está usando o loop principal do browser e está tentando fazê-lo efetivamente.
- -- -
Finalmente, no JavaScript, o browser está rodando o seu loop principal e o seu código existe em algum de seus estágios. As seções acima descrevem loops principais que tentam não eliminar o controle do navegador. Esses métodos principais anexam eles mesmos ao window.requestAnimationFrame()
, que pergunta ao browser por controle sobre o próximo frame. É responsabilidade do browser saber como relacionar esses requests ao loop principal. A especificação da W3C para o requestAnimationFrame não define realmente quando os browsers tem que executar os callbacks do requestAnimationFrame. Isto pode ser uma vantagem por que os fornecedores de browsers podem ter a liberdade de experimentar com as soluções que sintam que seja melhor e podem modifica-la com o passar do tempo.
Versões modernas do Firefox e Google Chrome (e provavelmente outros) tentam conectar os callbacks do requestAnimationFramea
a sua thread principal no primeiro intervalo de tempo de um frame. A thread principal portanto tenta fazer o seguinte:
- -
requestAnimationFrame
callbacks and invoke them.- -
Modern versions of Firefox and Google Chrome (and probably others) attempt to connect requestAnimationFrame
callbacks to their main thread at the very beginning of a frame's timeslice. The browser's main thread thus tries to look like the following:
requestAnimationFrame
callbacks and invoke them.You can think about developing realtime applications as having a budget of time to do work. All of the above steps must take place every 16-and-a-half milliseconds to keep up with a 60 Hz display. Browsers invoke your code as early as possible to give it maximum computation time. Your main thread will often start workloads that are not even on the main thread (such as rasterization or shaders in WebGL). Long calculations can be performed on a Web Worker or a GPU at the same time as the browser uses its main thread to manage garbage collection, its other tasks, or handle asynchronous events.
- -While we are on the topic of budgeting time, many web browsers have a tool called High Resolution Time. The {{ domxref("Date") }} object is no longer the recognised method for timing events because it is very imprecise and can be modified by the system clock. High Resolution Time, on the other hand, counts the number of milliseconds since navigationStart
(when the previous document is unloaded). This value is returned as a decimal number accurate to a thousandth of a millisecond. It is known as a {{ domxref("DOMHighResTimeStamp") }}
but, for all intents and purposes, consider it a floating point number.
Note: Systems (hardware or software) that are not capable of microsecond accuracy are allowed to provide millisecond accuracy as a minimum. They should provide 0.001ms accuracy if they are capable of it, however.
- -This value is not too useful alone, since it is relative to a fairly uninteresting event, but it can be subtracted from another timestamp to accurately and precisely determine how much time elapsed between those two points. To acquire one of these timestamps, you can call window.performance.now()
and store the result as a variable.
var tNow = window.performance.now(); -- -
Back to the topic of the main loop. You will often want to know when your main function was invoked. Because this is common, window.requestAnimationFrame()
always provides a DOMHighResTimeStamp
to callbacks as an argument when they are executed. This leads to another enhancement to our previous main loops.
/* -* Starting with the semicolon is in case whatever line of code above this example -* relied on automatic semicolon insertion (ASI). The browser could accidentally -* think this whole example continues from the previous line. The leading semicolon -* marks the beginning of our new line if the previous one was not empty or terminated. -* -* Let us also assume that MyGame is previously defined. -*/ - -;(function () { - function main( tFrame ) { - MyGame.stopMain = window.requestAnimationFrame( main ); - - // Your main loop contents. - // tFrame, from "function main ( tFrame )", is now a DOMHighResTimeStamp provided by rAF. - } - - main(); // Start the cycle -})();- -
Several other optimizations are possible and it really depends on what your game attempts to accomplish. Your game genre will obviously make a difference but it could even be more subtle than that. You could draw every pixel individually on a canvas or you could layer DOM elements (including multiple WebGL canvases with transparent backgrounds if you want) into a complex hierarchy. Each of these paths will lead to different opportunities and constraints.
- -You will need to make hard decisions about your main loop: how to simulate the accurate progress of time. If you demand per-frame control then you will need to determine how frequently your game will update and draw. You might even want update and draw to occur at different rates. You will also need to consider how gracefully your game will fail if the user's system cannot keep up with the workload. Let us start by assuming that you will handle user input and update the game state every time you draw. We will branch out later.
- -Note: Changing how your main loop deals with time is a debugging nightmare, everywhere. Think about your needs, carefully, before working on your main loop.
- -If your game can hit the maximum refresh rate of any hardware you support then your job is fairly easy. You can simply update, render, and then do nothing until VSync.
- -/* -* Starting with the semicolon is in case whatever line of code above this example -* relied on automatic semicolon insertion (ASI). The browser could accidentally -* think this whole example continues from the previous line. The leading semicolon -* marks the beginning of our new line if the previous one was not empty or terminated. -* -* Let us also assume that MyGame is previously defined. -*/ - -;(function () { - function main( tFrame ) { - MyGame.stopMain = window.requestAnimationFrame( main ); - - update( tFrame ); //Call your update method. In our case, we give it rAF's timestamp. - render(); - } - - main(); // Start the cycle -})();- -
If the maximum refresh rate cannot be reached, quality settings could be adjusted to stay under your time budget. The most famous example of this concept is the game from id Software, RAGE. This game removed control from the user in order to keep its calculation time at roughly 16ms (or roughly 60fps). If computation took too long then rendered resolution would decrease, textures and other assets would fail to load or draw, and so forth. This (non-web) case study made a few assumptions and tradeoffs:
- -Other methods of tackling the problem exist.
- -One common technique is to update the simulation at a constant frequency and then draw as much (or as little) of the actual frames as possible. The update method can continue looping without care about what the user sees. The draw method can view the last update and when it happened. Since draw knows when it represents, and the simulation time for the last update, it can predict a plausible frame to draw for the user. It does not matter whether this is more frequent than the official update loop (or even less frequent). The update method sets checkpoints and, as frequently as the system allows, the render method draws instants of time around them. There are many ways to separate the update method in web standards:
- -requestAnimationFrame
and update on a {{ domxref("window.setInterval") }} or {{ domxref("window.setTimeout") }}.
-
- requestAnimationFrame
and update on a setInterval
or setTimeout
in a Web Worker.
- requestAnimationFrame
and use it to poke a Web Worker containing the update method with the number of ticks to compute, if any.
- requestAnimationFrame
is called and does not pollute the main thread, plus you are not relying on old fashioned methods. Again, this is a bit more complex than the previous two options, and starting each update will be blocked until the browser decides to fire rAF callbacks.Each of these methods have similar tradeoffs:
- -A separate update and draw method could look like the following example. For the sake of demonstration, the example is based on the third bullet point, just without using Web Workers for readability (and, let's be honest, writeability).
- -Note: This example, specifically, is in need of technical review.
- -/* -* Starting with the semicolon is in case whatever line of code above this example -* relied on automatic semicolon insertion (ASI). The browser could accidentally -* think this whole example continues from the previous line. The leading semicolon -* marks the beginning of our new line if the previous one was not empty or terminated. -* -* Let us also assume that MyGame is previously defined. -* -* MyGame.lastRender keeps track of the last provided requestAnimationFrame timestamp. -* MyGame.lastTick keeps track of the last update time. Always increments by tickLength. -* MyGame.tickLength is how frequently the game state updates. It is 20 Hz (50ms) here. -* -* timeSinceTick is the time between requestAnimationFrame callback and last update. -* numTicks is how many updates should have happened between these two rendered frames. -* -* render() is passed tFrame because it is assumed that the render method will calculate -* how long it has been since the most recently passed update tick for -* extrapolation (purely cosmetic for fast devices). It draws the scene. -* -* update() calculates the game state as of a given point in time. It should always -* increment by tickLength. It is the authority for game state. It is passed -* the DOMHighResTimeStamp for the time it represents (which, again, is always -* last update + MyGame.tickLength unless a pause feature is added, etc.) -* -* setInitialState() Performs whatever tasks are leftover before the mainloop must run. -* It is just a generic example function that you might have added. -*/ - -;(function () { - function main( tFrame ) { - MyGame.stopMain = window.requestAnimationFrame( main ); - var nextTick = MyGame.lastTick + MyGame.tickLength; - var numTicks = 0; - - //If tFrame < nextTick then 0 ticks need to be updated (0 is default for numTicks). - //If tFrame = nextTick then 1 tick needs to be updated (and so forth). - //Note: As we mention in summary, you should keep track of how large numTicks is. - //If it is large, then either your game was asleep, or the machine cannot keep up. - if (tFrame > nextTick) { - var timeSinceTick = tFrame - MyGame.lastTick; - numTicks = Math.floor( timeSinceTick / MyGame.tickLength ); - } - - queueUpdates( numTicks ); - render( tFrame ); - MyGame.lastRender = tFrame; - } - - function queueUpdates( numTicks ) { - for(var i=0; i < numTicks; i++) { - MyGame.lastTick = MyGame.lastTick + MyGame.tickLength; //Now lastTick is this tick. - update( MyGame.lastTick ); - } - } - - MyGame.lastTick = performance.now(); - MyGame.lastRender = MyGame.lastTick; //Pretend the first draw was on first update. - MyGame.tickLength = 50; //This sets your simulation to run at 20Hz (50ms) - - setInitialState(); - main(performance.now()); // Start the cycle -})();- -
Another alternative is to simply do certain things less often. If a portion of your update loop is difficult to compute but insensitive to time, you might consider scaling back its frequency and, ideally, spreading it out into chunks throughout that lengthened period. An implicit example of this is found over at The Artillery Blog for Artillery Games, where they adjust their rate of garbage generation to optimize garbage collection. Obviously, cleaning up resources is not time sensitive (especially if tidying is more disruptive than the garbage itself).
- -This may also apply to some of your own tasks. Those are good candidates to throttle when available resources become a concern.
- -I want to be clear that any of the above, or none of them, could be best for your game. The correct decision entirely depends on the trade-offs that you are willing (and unwilling) to make. The concern is mostly with switching to another option. Fortunately, I do not have any experience with this but I have heard it is an excruciating game of Whack-a-Mole.
- -An important thing to remember for managed platforms, like the web, is that your loop may stop execution for significant periods of time. This could occur when the user unselects your tab and the browser sleeps (or slows) its requestAnimationFrame
callback interval. You have many ways to deal with this situation and this could depend on whether your game is single player or multiplayer. Some choices are:
Once your main loop has been developed and you have decided on a set of assumptions and tradeoffs which suit your game, it is now just a matter of using your decisions to calculate any applicable physics, AI, sounds, network synchronization, and whatever else your game may require.
diff --git a/files/pt-br/games/anatomy/index.md b/files/pt-br/games/anatomy/index.md new file mode 100644 index 00000000000000..e3b50629229a6b --- /dev/null +++ b/files/pt-br/games/anatomy/index.md @@ -0,0 +1,324 @@ +--- +title: Anatomia de um vídeo game +slug: Games/Anatomy +translation_of: Games/Anatomy +--- +{{GamesSidebar}} + +{{IncludeSubnav("/pt-BR/docs/Games")}} + +Este artigo analisa a anatomia e o fluxo de trabalho do vídeo game médio de um ponto de vista técnico, em termos de como o loop principal deve ser executado. Isso ajuda os iniciantes da arena do desenvolvimento de jogos modernos a entender o que é necessário ao construir um jogo e como os padrões da web como o JavaScript se prestam como ferramentas. Os programadores de jogos experientes que são novos no desenvolvimento da web também podem se beneficiar. + +## Apresentar, aceitar, interpretar, calcular, repetir + +O objetivo de todo vídeo game é **apresentar** ao usuário uma situação, **aceitar** sua entrada, **interpretar** estes sinais em ações, e **calcular** uma nova situação resultante dessas ações. Jogos estão constantemente repetindo estes estágios, de novo e de novo, até alguma condição final ocorrer (como vencer, perder, ou sair para ir dormir). Não surpreendentemente, este padrão corresponde a como um mecanismo de jogo está programado. + +As especificidades dependem do jogo. + +Alguns jogos guiam este ciclo pela entrada do usuário. Imagine que você está desenvolvendo um _"encontre as diferenças entre estas duas imagens similares"_. Esses jogos **apresentam** duas imagens ao usuário, eles **aceitam** seus cliques (ou toques), eles **interpretam** as entradas como um sucesso, falha, pausa, interação com o menu, etc., finalmente, eles **calculam** uma cena atualizada resultante dessas entradas. O ciclo do jogo é avançado pelas entradas do usuário e pela esperas até que ele as forneça. Isso é mais aproximado de um _jogo_ _baseado em turnos_ onde não há demanda de uma constante atualização a cada frame, somente quando o jogador reaje. + +Outros jogos demandam controle sobre cada um dos menores intervalos de tempo possíveis. Os mesmos princípios acima aplicam-se com uma pequena diferença: cada frame de animação avança o ciclo e cada mudança na entrada do usuário é capturada no primeiro turno disponível. Este modelo _uma vez por frame_ é implementado em algo chamado **loop principal.** Se o seu jogo é baseado em tempo, então essa será a autoridade a qual as suas simulações irão obedecer. + +Mas o jogo pode não precisar de controle por frame. Seu game loop pode ser similar ao exemplo _encontre as diferenças_ e basear-se em eventos de entrada. Ele pode requerer ambos, entrada e tempo simulado. Ele pode até mesmo ter um ciclo baseado em algo totalmente diferente. + +JavaScript Moderno — como descrito nas próximas seções — felizmente, facilita o desenvolvimento de um loop principal "execute uma vez por frame". É claro, seu jogo será somente tão otimizado quando o fizer. Se parece que algo deveria estar ligado a um evento menos frequente, seria uma boa ideia implementá-lo fora do loop principal (mas não sempre). + +## Contruindo um loop principal em JavaScript + +JavaScript trabalaha melhor com eventos e chamadas de funções. Navegadores modernos esforçam-se para chamar métodos à medida que são necessários e ociosos (ou fazem suas outras tarefas) nos intervalos. É uma excelente ideia ligar seu código aos momentos apropriados a eles. Pense se a sua função realmente precisa ser chamada em um estrito intervalo de tempo, a cada frame, ou somente após algo acontecer. Ser mais específico com o navegador sobre quando a sua função precisa ser chamada permite que o navegador otimize essa chamada. Também, isso facilitará o seu trabalho. + +Alguns códigos precisam ser rodados frame por frame, então por quê ligar essas funções a qualquer coisa que não seja a atualização de tela do navegador? Na web, `{{ domxref("window.requestAnimationFrame()") }} será a base da maioria dos mais bem programados loops principais do tipo frame por frame.` Uma chamada de função deve ser passada dentro da função anterior quando a mesma for chamada. Esta chamdada de função será executada em um tempo adequado antes da próxima atualização de tela. Eis um exemplo de um loop principal simples: + +``` +window.main = function () { + window.requestAnimationFrame( main ); + + // Whatever your main loop needs to do. +}; + +main(); //Start the cycle. +``` + +**Nota**: Em cada método do `main()` discutido aqui, nós agendamos uma nova requisição `requestAnimationFrame` antes de executar o conteúdo de nosso loop. Isso não é por acidente, e é considerado boa prática. Chamando o próximo `requestAnimationFrame` anteriormente garante que o navegador receba a chamada a tempo de planejar adequadamente, mesmo que seu frame atual falhe em sua (?VSync window?). + +O trecho de código acima possui duas declarações. A primeira cria uma função como uma variável global chamada `main()`. Esta função faz algum trabalho e também diz ao navegador para camá-la na próxima frame com `window.requestAnimationFrame()`. A segunda declaração chama a função `main()`, definida na primeira declaração. Pelo fato do `main()` ser chamado uma vez na segunda declaração e cada chamada dele colocá-lo na lista de coisas a fazer na próxima frame, `main()` é sincronizado com a sua taxa de frame. + +É claro que esse loop não é perfeito. Antes de discutirmos maneiras de mudá-lo, deixe-nos discutir o que já está bem. + +Cronometrando o loop principal para quando o navegador atualiza a tela o permite rodar o seu loop tão frequentemente quanto o navegador queira atualizar. Você tem controle sobre cada frame de animação. Isso é muito simples por que `main()` é a única função em loop. Um jogo de primeira pessoa (ou um jogo similar) apresenta uma nova cena a cada frame. Você realmente não pode ser mais suave e receptivo do que isso. + +Mas não assuma imediatamente que animações requerem controle frame por frame. Animações simples podem ser facilmente desenvolvidas até mesmo com aceleração-GPU, com animações CSS e com outras ferramentas inclusas no navegador. Existem muitas delas que farão sua vida mais fácil. + +## Construindo um loop principal _melhor_ em Javascript + +Existem dois problemas óbvios com nosso loop principal anterior: `main()` polui o objeto `{{ domxref("window") }}` (onde todas as variáveis globais são armazenadas) e o código de exemplo não nos permite _parar_ o loop a menos que toda a aba seja fechada ou atualizada. Para o primeiro problema, se você quer que o loop principal apenas rode sem precisar de fácil acesso (direto) a ele, você pode criá-lo como uma Função Diretamente Invocada (Immediately-Invoked Function Expression - IIFE). + +``` +/* +* Starting with the semicolon is in case whatever line of code above this example +* relied on automatic semicolon insertion (ASI). The browser could accidentally +* think this whole example continues from the previous line. The leading semicolon +* marks the beginning of our new line if the previous one was not empty or terminated. +*/ + +;(function () { + function main() { + window.requestAnimationFrame( main ); + + // Your main loop contents. + } + + main(); // Start the cycle +})(); +``` + +Quando o browser alcançar este IIFE, ele irá definir o seu próprio loop principal e imediatamente agenda-o para para o próximo frame. Ele não será anexado a nenhum objeto e `main` (ou `main()` para métodos) será um nome válido sem uso no resto da aplicação, livre para ser definido como outra coisa. + +Nota: Na prática, é mais comum previnir o próximo `requestAnimationFrame()` com uma declaração `if`, no lugar de chamar `cancelAnimationFrame()`. + +Para o próximo problema, parando o loop principal, você precisará cancelar a chamada a `main()` com `window.cancelAnimationFrame()`. Você precisará passar para `cancelAnimationFrame()` o token do ID dado pelo `requestAnimationFrame()` quando ele foi chamado. Vamos assumir que as funções do seu jogo e variáveis estão construídas em um namespace que você chamou de `MyGame`. Expandindo o nosso último exemplo, o loop principal ficaria parecido com isto: + +``` +/* +* Starting with the semicolon is in case whatever line of code above this example +* relied on automatic semicolon insertion (ASI). The browser could accidentally +* think this whole example continues from the previous line. The leading semicolon +* marks the beginning of our new line if the previous one was not empty or terminated. +* +* Let us also assume that MyGame is previously defined. +*/ + +;(function () { + function main() { + MyGame.stopMain = window.requestAnimationFrame( main ); + + // Your main loop contents. + } + + main(); // Start the cycle +})(); +``` + +Nós temos agora uma variável declarada no namespace do nosso `MyGame`, que nos chamamos de `stopMain`, e que contém o ID retornado pela execução mais recente do `requestAnimationFrame()` do nosso loop principal. Em algum ponto, nós podemos parar o loop principal pedindo ao browser para cancelar a requisição que corresponde ao nosso token. + +``` +window.cancelAnimationFrame( MyGame.stopMain ); +``` + +A chave para programar loop principal, no JavaScript, é anexá-lo a qualquer evento que deve estar dirigindo sua ação e prestar atenção a como os diferentes sistemas envolvidos interagem entre si. Você poderá ter multiplos componentes dirigidos por multiplos diferentes tipos de eventos. Isto parece complexidade desnecessária mas pode ser só uma boa otimização (não necessária, é claro). O problema é que você não está programando um loop principal típico. No JavaScript, você está usando o loop principal do browser e está tentando fazê-lo efetivamente. + +## Construindo um loop principal mais _otimizado_ no JavaScript + +Finalmente, no JavaScript, o browser está rodando o seu loop principal e o seu código existe em algum de seus estágios. As seções acima descrevem loops principais que tentam não eliminar o controle do navegador. Esses métodos principais anexam eles mesmos ao `window.requestAnimationFrame()`, que pergunta ao browser por controle sobre o próximo frame. É responsabilidade do browser saber como relacionar esses requests ao loop principal. A [especificação da W3C para o requestAnimationFrame](http://www.w3.org/TR/animation-timing/) não define realmente quando os browsers tem que executar os callbacks do requestAnimationFrame. Isto pode ser uma vantagem por que os fornecedores de browsers podem ter a liberdade de experimentar com as soluções que sintam que seja melhor e podem modifica-la com o passar do tempo. + +Versões modernas do Firefox e Google Chrome (e provavelmente outros) tentam conectar os callbacks do `requestAnimationFramea` a sua thread principal no primeiro intervalo de tempo de um frame. A thread principal portanto tenta fazer o seguinte: + +1. Começar uma nova frame (enquanto a anterior é tratada pela exibição). +2. Go through the list of `requestAnimationFrame` callbacks and invoke them. +3. Perform garbage collection and other per-frame tasks when the above callbacks stop controlling the main thread. +4. Sleep (unless an event interrupts the browser's nap) until the monitor is ready for your image ([VSync](http://www.techopedia.com/definition/92/vertical-sync-vsync)) and repeat. + +Modern versions of Firefox and Google Chrome (and probably others) _attempt_ to connect `requestAnimationFrame` callbacks to their main thread at the very beginning of a frame's timeslice. The browser's main thread thus _tries_ to look like the following: + +1. Start a new frame (while the previous frame is handled by the display). +2. Go through the list of `requestAnimationFrame` callbacks and invoke them. +3. Perform garbage collection and other per-frame tasks when the above callbacks stop controlling the main thread. +4. Sleep (unless an event interrupts the browser's nap) until the monitor is ready for your image ([VSync](http://www.techopedia.com/definition/92/vertical-sync-vsync)) and repeat. + +You can think about developing realtime applications as having a budget of time to do work. All of the above steps must take place every 16-and-a-half milliseconds to keep up with a 60 Hz display. Browsers invoke your code as early as possible to give it maximum computation time. Your main thread will often start workloads that are not even on the main thread (such as rasterization or shaders in WebGL). Long calculations can be performed on a Web Worker or a GPU at the same time as the browser uses its main thread to manage garbage collection, its other tasks, or handle asynchronous events. + +While we are on the topic of budgeting time, many web browsers have a tool called _High Resolution Time_. The {{ domxref("Date") }} object is no longer the recognised method for timing events because it is very imprecise and can be modified by the system clock. High Resolution Time, on the other hand, counts the number of milliseconds since `navigationStart` (when the previous document is unloaded). This value is returned as a decimal number accurate to a thousandth of a millisecond. It is known as a `{{ domxref("DOMHighResTimeStamp") }}` but, for all intents and purposes, consider it a floating point number. + +**Note**: Systems (hardware or software) that are not capable of microsecond accuracy are allowed to provide millisecond accuracy as a minimum. They should provide 0.001ms accuracy if they are capable of it, however. + +This value is not too useful alone, since it is relative to a fairly uninteresting event, but it can be subtracted from another timestamp to accurately and precisely determine how much time elapsed between those two points. To acquire one of these timestamps, you can call `window.performance.now()` and store the result as a variable. + +``` +var tNow = window.performance.now(); +``` + +Back to the topic of the main loop. You will often want to know when your main function was invoked. Because this is common, `window.requestAnimationFrame()` always provides a `DOMHighResTimeStamp` to callbacks as an argument when they are executed. This leads to another enhancement to our previous main loops. + +``` +/* +* Starting with the semicolon is in case whatever line of code above this example +* relied on automatic semicolon insertion (ASI). The browser could accidentally +* think this whole example continues from the previous line. The leading semicolon +* marks the beginning of our new line if the previous one was not empty or terminated. +* +* Let us also assume that MyGame is previously defined. +*/ + +;(function () { + function main( tFrame ) { + MyGame.stopMain = window.requestAnimationFrame( main ); + + // Your main loop contents. + // tFrame, from "function main ( tFrame )", is now a DOMHighResTimeStamp provided by rAF. + } + + main(); // Start the cycle +})(); +``` + +Several other optimizations are possible and it really depends on what your game attempts to accomplish. Your game genre will obviously make a difference but it could even be more subtle than that. You could draw every pixel individually on a canvas or you could layer DOM elements (including multiple WebGL canvases with transparent backgrounds if you want) into a complex hierarchy. Each of these paths will lead to different opportunities and constraints. + +## It is decision... time + +You will need to make hard decisions about your main loop: how to simulate the accurate progress of time. If you demand per-frame control then you will need to determine how frequently your game will update and draw. You might even want update and draw to occur at different rates. You will also need to consider how gracefully your game will fail if the user's system cannot keep up with the workload. Let us start by assuming that you will handle user input and update the game state every time you draw. We will branch out later. + +_**Note**:_ Changing how your main loop deals with time is a debugging nightmare, everywhere. Think about your needs, carefully, before working on your main loop. + +### What most browser games should look like + +If your game can hit the maximum refresh rate of any hardware you support then your job is fairly easy. You can simply update, render, and then do nothing until VSync. + +``` +/* +* Starting with the semicolon is in case whatever line of code above this example +* relied on automatic semicolon insertion (ASI). The browser could accidentally +* think this whole example continues from the previous line. The leading semicolon +* marks the beginning of our new line if the previous one was not empty or terminated. +* +* Let us also assume that MyGame is previously defined. +*/ + +;(function () { + function main( tFrame ) { + MyGame.stopMain = window.requestAnimationFrame( main ); + + update( tFrame ); //Call your update method. In our case, we give it rAF's timestamp. + render(); + } + + main(); // Start the cycle +})(); +``` + +If the maximum refresh rate cannot be reached, quality settings could be adjusted to stay under your time budget. The most famous example of this concept is the game from id Software, RAGE. This game removed control from the user in order to keep its calculation time at roughly 16ms (or roughly 60fps). If computation took too long then rendered resolution would decrease, textures and other assets would fail to load or draw, and so forth. This (non-web) case study made a few assumptions and tradeoffs: + +- Each frame of animation accounts for user input. +- No frame needs to be extrapolated (guessed) because each draw has its own update. +- Simulation systems can basically assume that each full update is \~16ms apart. +- Giving the user control over quality settings would be a nightmare. +- Different monitors input at different rates: 30 FPS, 75 FPS, 100 FPS, 120 FPS, 144 FPS, etc. +- Systems that are unable to keep up with 60 FPS lose visual quality to keep the game running at optimal speed (eventually it outright fails, if quality becomes too low.) + +### Other ways to handle variable refresh rate needs + +Other methods of tackling the problem exist. + +One common technique is to update the simulation at a constant frequency and then draw as much (or as little) of the actual frames as possible. The update method can continue looping without care about what the user sees. The draw method can view the last update and when it happened. Since draw knows when it represents, and the simulation time for the last update, it can predict a plausible frame to draw for the user. It does not matter whether this is more frequent than the official update loop (or even less frequent). The update method sets checkpoints and, as frequently as the system allows, the render method draws instants of time around them. There are many ways to separate the update method in web standards: + +- Draw on `requestAnimationFrame` and update on a {{ domxref("window.setInterval") }} or {{ domxref("window.setTimeout") }}. + + - This uses processor time even when unfocused or minimized, hogs the main thread, and is probably an artifact of traditional game loops (but it is simple.) + +- Draw on `requestAnimationFrame` and update on a `setInterval` or `setTimeout` in a [Web Worker](/pt-BR/docs/Web/Guide/Performance/Using_web_workers). + + - This is the same as above, except update does not hog the main thread (nor does the main thread hog it). This is a more complex solution, and might be too much overhead for simple updates. + +- Draw on `requestAnimationFrame` and use it to poke a Web Worker containing the update method with the number of ticks to compute, if any. + + - This sleeps until `requestAnimationFrame` is called and does not pollute the main thread, plus you are not relying on old fashioned methods. Again, this is a bit more complex than the previous two options, and _starting_ each update will be blocked until the browser decides to fire rAF callbacks. + +Each of these methods have similar tradeoffs: + +- Users can skip rendering frames or interpolate extra ones depending on their performance. +- You can count on all users updating non-cosmetic variables at the same constant frequency minus hiccups. +- Much more complicated to program than the basic loops we saw earlier. +- User input is completely ignored until the next update (even if the user has a fast device). +- The mandatory interpolation has a performance penalty. + +A separate update and draw method could look like the following example. For the sake of demonstration, the example is based on the third bullet point, just without using Web Workers for readability (and, let's be honest, writeability). + +_Note: This example, specifically, is in need of technical review\._ + +``` +/* +* Starting with the semicolon is in case whatever line of code above this example +* relied on automatic semicolon insertion (ASI). The browser could accidentally +* think this whole example continues from the previous line. The leading semicolon +* marks the beginning of our new line if the previous one was not empty or terminated. +* +* Let us also assume that MyGame is previously defined. +* +* MyGame.lastRender keeps track of the last provided requestAnimationFrame timestamp. +* MyGame.lastTick keeps track of the last update time. Always increments by tickLength. +* MyGame.tickLength is how frequently the game state updates. It is 20 Hz (50ms) here. +* +* timeSinceTick is the time between requestAnimationFrame callback and last update. +* numTicks is how many updates should have happened between these two rendered frames. +* +* render() is passed tFrame because it is assumed that the render method will calculate +* how long it has been since the most recently passed update tick for +* extrapolation (purely cosmetic for fast devices). It draws the scene. +* +* update() calculates the game state as of a given point in time. It should always +* increment by tickLength. It is the authority for game state. It is passed +* the DOMHighResTimeStamp for the time it represents (which, again, is always +* last update + MyGame.tickLength unless a pause feature is added, etc.) +* +* setInitialState() Performs whatever tasks are leftover before the mainloop must run. +* It is just a generic example function that you might have added. +*/ + +;(function () { + function main( tFrame ) { + MyGame.stopMain = window.requestAnimationFrame( main ); + var nextTick = MyGame.lastTick + MyGame.tickLength; + var numTicks = 0; + + //If tFrame < nextTick then 0 ticks need to be updated (0 is default for numTicks). + //If tFrame = nextTick then 1 tick needs to be updated (and so forth). + //Note: As we mention in summary, you should keep track of how large numTicks is. + //If it is large, then either your game was asleep, or the machine cannot keep up. + if (tFrame > nextTick) { + var timeSinceTick = tFrame - MyGame.lastTick; + numTicks = Math.floor( timeSinceTick / MyGame.tickLength ); + } + + queueUpdates( numTicks ); + render( tFrame ); + MyGame.lastRender = tFrame; + } + + function queueUpdates( numTicks ) { + for(var i=0; i < numTicks; i++) { + MyGame.lastTick = MyGame.lastTick + MyGame.tickLength; //Now lastTick is this tick. + update( MyGame.lastTick ); + } + } + + MyGame.lastTick = performance.now(); + MyGame.lastRender = MyGame.lastTick; //Pretend the first draw was on first update. + MyGame.tickLength = 50; //This sets your simulation to run at 20Hz (50ms) + + setInitialState(); + main(performance.now()); // Start the cycle +})(); +``` + +Another alternative is to simply do certain things less often. If a portion of your update loop is difficult to compute but insensitive to time, you might consider scaling back its frequency and, ideally, spreading it out into chunks throughout that lengthened period. An implicit example of this is found over at The Artillery Blog for Artillery Games, where they [adjust their rate of garbage generation](http://blog.artillery.com/2012/10/browser-garbage-collection-and-framerate.html) to optimize garbage collection. Obviously, cleaning up resources is not time sensitive (especially if tidying is more disruptive than the garbage itself). + +This may also apply to some of your own tasks. Those are good candidates to throttle when available resources become a concern. + +## Summary + +I want to be clear that any of the above, or none of them, could be best for your game. The correct decision entirely depends on the trade-offs that you are willing (and unwilling) to make. The concern is mostly with switching to another option. Fortunately, I do not have any experience with this but I have heard it is an excruciating game of Whack-a-Mole. + +An important thing to remember for managed platforms, like the web, is that your loop may stop execution for significant periods of time. This could occur when the user unselects your tab and the browser sleeps (or slows) its `requestAnimationFrame` callback interval. You have many ways to deal with this situation and this could depend on whether your game is single player or multiplayer. Some choices are: + +- Consider the gap "a pause" and skip the time. + + - You can probably see how this is problematic for most multiplayer games. + +- You can simulate the gap to catch up. + + - This can be a problem for long drops and/or complex updates. + +- You can recover the game state from a peer or the server. + + - This is ineffective if your peers or server are out-of-date too, or they don't exist because the game is single player and doesn't have a server. + +Once your main loop has been developed and you have decided on a set of assumptions and tradeoffs which suit your game, it is now just a matter of using your decisions to calculate any applicable physics, AI, sounds, network synchronization, and whatever else your game may require. diff --git a/files/pt-br/games/index.html b/files/pt-br/games/index.html deleted file mode 100644 index a088475e68be1e..00000000000000 --- a/files/pt-br/games/index.html +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Desenvolvimento de jogos -slug: Games -tags: - - Aplicativos - - Desenvolvimento de Jogos - - Gamedev - - Jogos Web - - Jogos em HTML5 - - Jogos em JavaScript -translation_of: Games ---- -Jogar é uma das atividades mais populares em computadores. Novas tecnologias aparecem, constantemente, para tornar possível o desenvolvimento de jogos melhores e mais poderosos, que podem ser executados em qualquer navegador compatível com os padrões web.
-Bem-vindas ao centro de desenvolvimento de jogos MDN! Nesta área da página oferecemos recursos para desenvolvedores web que querem dedicar-se a jogos. Você encontrará muitos tutoriais úteis e artigos técnicos no menu principal à sua esquerda - sinta-se livre para explorá-los.
- -Também incluímos uma seção de referências para que você possa, facilmente, encontrar informações sobre todas APIs mais usadas no desenvolvimento de jogos, acompanhadas de uma lista de ferramentas e engines úteis e, exemplos de jogos.
- -Nota: Você já deve ter um conhecimento básico sobre as principais tecnologias web — tais como HTML, CSS e Javascript — antes de tentar criar jogos web. A Área de aprendizado é o melhor para você, se você for completamente principiante.
-Se você é programador nativo (codifica jogos em C++ por exemplo) e tem interesse em levar os seus jogos para a Web, você deve aprender mais sobre a nossa ferramenta Emscripten — é uma LLVM para o compilador JavaScript que carrega bytecode LLVM (exemplo: código gerado do C/C++ usando Clang, ou de qualquer outra linguagem de programação) e compila esses bytecodes para asm.js, que pode rodar na Web.
- -Para começar, veja:
- -Para uma lista de exemplos de jogos web, veja a nossa página de exemplos. Também dê uma olhada em openwebgames.com para mais exemplos e recursos úteis!
-A web moderna rapidamente tem se tornado uma plataforma não só para criar jogos esplêndidos de alta qualidade, mas também para a distribuição desses mesmos jogos.
- -A gama de jogos que podem ser criados é compatível com as partes equivalentes de Desktop e contrapartes nativas de SO. Com modernas tecnologias da Web e um navegador recente, é perfeitamente possível fazer jogos impressionantes e de primeira qualidade para a Web. E não estamos falando de jogos de cartas simples ou de jogos sociais multijogadores que, nos tempos antigos, foram feitos usando Flash®. Estamos falando de FPS de ação 3D, RPGs e mais. Graças às melhorias de desempenho macias em tecnologia de compilação just-in-time de JavaScript e novas APIs, você pode construir jogos que são executados no navegador (ou em dispositivos com HTML5 como aqueles baseados no sistema operacional Firefox) sem compromissos.
- -Você pode realmente pensar na Web como uma melhor plataforma de destino para o seu jogo. Como gostamos de dizer , "A Web é a plataforma". Vamos dar uma olhada no núcleo da plataforma da Web:
- -Função | -Tecnologia | -
---|---|
Audio | -Web Audio API | -
Gráficos | -WebGL (OpenGL ES 2.0) | -
Entrada (Input) | -Touch events, Gamepad API, device sensors, WebRTC, Full Screen API, Pointer Lock API | -
Linguagem | -JavaScript (ou C/C++ usando Emscripten para compilar para JavaScript) | -
Rede | -WebRTC e/ou WebSockets | -
Armazenamento | -IndexedDB ou o "cloud" | -
Web | -HTML, CSS, SVG, Social API (e muito mais!) | -
Como desenvolvedor de jogos, seja individual ou um grande estúdio de jogos, você quer saber por que faz sentido ter como alvo a Web com o seu próximo projeto de jogo. Vejamos como a Web pode ajudá-lo.
- -Para as pessoas de tecnologia, vamos cavar as APIs que a Web traz à mesa que atendem aos desenvolvedores de jogos. Aqui está uma lista completa para dar uma amostra do que a Web pode fazer por você:
- -diff --git a/files/pt-br/games/introduction/index.md b/files/pt-br/games/introduction/index.md new file mode 100644 index 00000000000000..295197dd8a3bf3 --- /dev/null +++ b/files/pt-br/games/introduction/index.md @@ -0,0 +1,73 @@ +--- +title: Introdução ao desenvolvimento de jogos para a Web +slug: Games/Introduction +translation_of: Games/Introduction +--- +{{GamesSidebar}}{{IncludeSubnav("/pt-BR/docs/Games")}} + +A web moderna rapidamente tem se tornado uma plataforma não só para criar jogos esplêndidos de alta qualidade, mas também para a distribuição desses mesmos jogos. + +A gama de jogos que podem ser criados é compatível com as partes equivalentes de Desktop e contrapartes nativas de SO. Com modernas tecnologias da Web e um navegador recente, é perfeitamente possível fazer jogos impressionantes e de primeira qualidade para a Web. E não estamos falando de jogos de cartas simples ou de jogos sociais multijogadores que, nos tempos antigos, foram feitos usando Flash®. Estamos falando de FPS de ação 3D, RPGs e mais. Graças às melhorias de desempenho macias em tecnologia de compilação just-in-time de JavaScript e novas APIs, você pode construir jogos que são executados no navegador (ou em dispositivos com HTML5 como aqueles baseados no sistema operacional Firefox) sem compromissos. + +## A plataforma de jogo HTML5 + +Você pode realmente pensar na Web como uma melhor plataforma de destino para o seu jogo. Como gostamos de dizer , "A Web é a plataforma". Vamos dar uma olhada no núcleo da plataforma da Web: + +| Função | Tecnologia | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Audio** | [Web Audio API](/pt-BR/docs/Web/API/API_Web_Audio "/en-US/docs/Web_Audio_API") | +| **Gráficos** | [WebGL](/pt-BR/docs/Web/API/WebGL_API "/en-US/docs/WebGL") ([OpenGL ES](http://www.khronos.org/opengles/) 2.0) | +| **Entrada (Input)** | [Touch events](/pt-BR/docs/Web/Guide/Events/Touch_events "/en-US/docs/DOM/Touch_events"), [Gamepad API](/pt-BR/docs/API/Gamepad/Using_Gamepad_API), device sensors, [WebRTC](/pt-BR/docs/WebRTC), [Full Screen API](/pt-BR/docs/Web/API/Fullscreen_API "/en-US/docs/DOM/Using_fullscreen_mode"), [Pointer Lock API](/pt-BR/docs/Web/API/Pointer_Lock_API "/en-US/docs/WebAPI/Pointer_Lock") | +| **Linguagem** | [JavaScript](/pt-BR/docs/Web/JavaScript "/en-US/docs/JavaScript") (ou C/C++ usando [Emscripten](https://github.com/kripken/emscripten/wiki) para compilar para JavaScript) | +| **Rede** | [WebRTC](/pt-BR/docs/WebRTC) e/ou [WebSockets](/pt-BR/docs/WebSockets "/en-US/docs/WebSockets") | +| **Armazenamento** | [IndexedDB](/pt-BR/docs/IndexedDB "/en-US/docs/IndexedDB") ou o "cloud" | +| **Web** | [HTML](/pt-BR/docs/Web/HTML "/en-US/docs/HTML"), [CSS](/pt-BR/docs/Web/CSS "/en-US/docs/CSS"), [SVG](/pt-BR/docs/Web/SVG "/en-US/docs/SVG"), [Social API](/pt-BR/docs/api_social "/en-US/docs/Social_API") (e muito mais!) | + +## O caso de negócios + +Como desenvolvedor de jogos, seja individual ou um grande estúdio de jogos, você quer saber por que faz sentido ter como alvo a Web com o seu próximo projeto de jogo. Vejamos como a Web pode ajudá-lo. + +1. O alcance da Web é enorme; Está em toda parte. Jogos criados com HTML5 em smartphones, tablets, PCs e Smart TVs. +2. O marketing e a descoberta são melhorados. Você não está limitado a promover o seu aplicativo na loja de aplicativos de outra pessoa. Em vez disso, você pode anunciar e promover o seu jogo em toda a Web, bem como outros meios de comunicação, aproveitando a capacidade de compartilhamento inerente e compartilhamento da Web para alcançar novos clientes. +3. Você tem controle onde isso importa: Pagamentos. Você não precisa entregar mais de 30% de suas receitas para outra pessoa apenas porque seu jogo está em seu ecossistema. Em vez disso, carregue o que deseja e use qualquer serviço de processamento de pagamento que você gosta. +4. Novamente com mais controle, você pode atualizar seu jogo sempre que quiser. Não espera sem fôlego para aprovação, enquanto alguém escondido em outra empresa decide se a sua correção crítica de erros será ou não enviada hoje ou amanhã. +5. Controle suas análises! Em vez de confiar em outra pessoa para tomar todas as decisões sobre o que você precisa, você pode coletar o seu próprio -- ou escolha o terceiro que você gosta do melhor -- para coletar informações sobre suas vendas e o alcance do seu jogo. +6. Você consegue gerenciar seu relacionamento com o cliente de forma mais próxima, à sua maneira. Não há mais comentários do cliente filtrados através dos mecanismos limitados de uma loja de aplicativos. Participe com seus clientes da maneira que você quiser, sem intermediário. +7. Seus jogadores podem jogar seu jogo em qualquer lugar, a qualquer hora. Como a Web é onipresente, seus clientes podem verificar o status do seu jogo em seus telefones, tablets, laptops domésticos, desktops de trabalho ou qualquer outra coisa. + +## Tecnologias da Web para desenvolvedores de jogos + +Para as pessoas de tecnologia, vamos cavar as APIs que a Web traz à mesa que atendem aos desenvolvedores de jogos. Aqui está uma lista completa para dar uma amostra do que a Web pode fazer por você: + +- [Full Screen API](/pt-BR/docs/Web/API/Fullscreen_API "/en-US/docs/DOM/Using_fullscreen_mode") + - : Esta API simples permite que seu jogo ocupe toda a tela, imergindo assim o jogador em ação. +- [Gamepad API](/pt-BR/docs/API/Gamepad/Using_Gamepad_API) + - : Se você quiser que seus usuários possam usar gamepads ou outros controladores de jogos para trabalhar seu jogo, você precisará desta API. +- [HTML](/pt-BR/docs/Web/HTML "/en-US/docs/HTML") e [CSS](/pt-BR/docs/Web/CSS "/en-US/docs/CSS") + - : Juntas, essas duas tecnologias permitem que você possa criar, estilizar e definir a interface do usuário do seu jogo. Parte do HTML é o {{HTMLElement("canvas")}} elemento, que fornece uma maneira de fazer gráficos 2D. +- [HTML audio](/pt-BR/docs/Web/HTML/Element/Audio "/en-US/docs/HTML/Element/audio") + - : O {{HTMLElement("audio")}} elemento permite reproduzir facilmente efeitos sonoros e música. Se suas necessidades estão mais envolvidas, confira a [API Web Áudio](/pt-BR/docs/Web/API/API_Web_Audio) para obter poder real de processamento de áudio! +- [IndexedDB](/pt-BR/docs/IndexedDB "/en-US/docs/IndexedDB") + - : Uma poderosa API de armazenamento de dados para manter os dados do usuário em seu próprio computador ou dispositivo. Uma ótima maneira de salvar o estado do jogo e outras informações localmente, portanto não precisa ser baixado sempre que for necessário. Também é útil para ajudar a tornar o seu jogo jogável mesmo quando o usuário não está conectado à Web (como quando estão presos em um avião por horas a fio). +- [JavaScript](/pt-BR/docs/Web/JavaScript "/en-US/docs/JavaScript") + - : JavaScript, a linguagem de programação usada na Web, está sendo lançada rapidamente em navegadores modernos e cada vez mais rápido. Use seu poder para escrever o código do seu jogo, ou olhe para usar tecnologias como [Emscripten](https://github.com/kripken/emscripten/wiki) ou [Asm.js](http://asmjs.org/spec/latest/) para facilmente acessar seus jogos existentes. +- [Pointer Lock API](/pt-BR/docs/Web/API/Pointer_Lock_API "/en-US/docs/WebAPI/Pointer_Lock") + - : O Pointer Lock API permite bloquear o mouse ou outro dispositivo apontador na interface do seu jogo, de modo que, em vez do posicionamento absoluto do cursor, você receba deltas de coordenadas que lhe dê medidas mais precisas sobre o que o usuário está fazendo e evite que o usuário envie acidentalmente sua entrada para outro lugar. Falta de uma ação importante. +- [SVG](/pt-BR/docs/Web/SVG "/en-US/docs/SVG") (Scalable Vector Graphics) + + - : Permite criar gráficos vetoriais que se dimensionem sem problemas, independentemente do tamanho ou resolução da exibição do usuário. + +- [Typed Arrays](/pt-BR/docs/Web/JavaScript/Typed_arrays "/en-US/docs/JavaScript/Typed_arrays") + - : JavaScript typed arrays da acesso a dados binários em bruto a partir do JavaScript; Isso permite manipular texturas GL, dados de jogos ou qualquer outra coisa, mesmo que não esteja em formato nativo do JavaScript. +- [Web Audio API](/pt-BR/docs/Web/API/WebGL_API "/en-US/docs/Web_Audio_API") + - : Essa API para controlar a reprodução, síntese e manipulação de áudio a partir do código JavaScript, você pode criar efeitos de som incríveis, além de reproduzir e manipular música em tempo real. +- [WebGL](/pt-BR/docs/Web/API/WebGL_API "/en-US/docs/WebGL") + - : Permite criar 3D de alta performance, acelerado por hardware (e 2D) a partir de conteúdo da Web. Esta é uma implementação suportada pela Web de [OpenGL ES](http://www.khronos.org/opengles/) 2.0. +- [WebRTC](/pt-BR/docs/WebRTC) + - : O WebRTC (Real-Time Communications) API Dá-lhe o poder de controlar dados de áudio e vídeo, incluindo teleconferência e transmissão de outros dados de aplicativos de um lado a outro entre dois usuários. Quer que seus jogadores possam conversar um com o outro enquanto explodem monstros? Esta é a API para você. +- [WebSockets](/pt-BR/docs/WebSockets "/en-US/docs/WebSockets") + - : O WebSocket API permite conectar seu aplicativo ou site a um servidor para transmitir dados de um lado para o outro em tempo real. Perfeito para a ação de jogo multiplayer, serviços de bate-papo, e assim por diante. +- [Web Workers](/pt-BR/docs/DOM/Using_web_workers) + - : Os trabalhadores dão-lhe a capacidade de gerar threads de fundo executando seu próprio código JavaScript, para aproveitar os modernos processadores multi-core. +- [XMLHttpRequest](/pt-BR/docs/Web/API/XMLHttpRequest "/en-US/docs/DOM/XMLHttpRequest") e [File API](/pt-BR/docs/Web/API/File_and_Directory_Entries_API "/en-US/docs/DOM/File_API") + - : A combinação de XMLHttpRequest e o File API Permite enviar e receber qualquer tipo de dados que você deseja (não deixe o "XML" te jogar!) de um servidor da Web. Esta é uma ótima maneira de fazer qualquer coisa, desde o download de novos níveis de jogos e obras de arte para a transmissão de informações de status do jogo não real-time para frente e para trás. diff --git a/files/pt-br/games/introduction_to_html5_game_development/index.html b/files/pt-br/games/introduction_to_html5_game_development/index.html deleted file mode 100644 index d987e1b75b0d27..00000000000000 --- a/files/pt-br/games/introduction_to_html5_game_development/index.html +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: Introduction to HTML5 Game Development (summary) -slug: Games/Introduction_to_HTML5_Game_Development -tags: - - API - - Desenvolvimento Web - - Desenvolvimento mobile - - Firefox OS - - HTML5 - - JavaScript - - Jogos -translation_of: Games/Introduction_to_HTML5_Game_Development_(summary) -original_slug: Games/Introduction_to_HTML5_Game_Gevelopment_(summary) ---- -
Function | -Tecnologias | -
---|---|
Audio | -Web Audio API | -
Gráficos | -WebGL (OpenGL ES 2.0) | -
Entrada | -Touch events, Gamepad API, sensores de dispositivos, WebRTC, Full Screen API, Pointer Lock API | -
Linguagens | -JavaScript (ou C/C++ usando Emscripten para compilar o JavaScript) | -
Networking | -WebRTC e/ou WebSockets | -
Armazenamento | -IndexedDB ou a "nuvem" | -
Web | -HTML, CSS, SVG, Social API (e muito mais!) | -
diff --git a/files/pt-br/games/introduction_to_html5_game_development/index.md b/files/pt-br/games/introduction_to_html5_game_development/index.md new file mode 100644 index 00000000000000..8f043823d53ac9 --- /dev/null +++ b/files/pt-br/games/introduction_to_html5_game_development/index.md @@ -0,0 +1,69 @@ +--- +title: Introduction to HTML5 Game Development (summary) +slug: Games/Introduction_to_HTML5_Game_Development +tags: + - API + - Desenvolvimento Web + - Desenvolvimento mobile + - Firefox OS + - HTML5 + - JavaScript + - Jogos +translation_of: Games/Introduction_to_HTML5_Game_Development_(summary) +original_slug: Games/Introduction_to_HTML5_Game_Gevelopment_(summary) +--- +{{GamesSidebar}}{{IncludeSubnav("/en-US/docs/Games")}} + +## Vantagens + +1. Os Jogos criados com HTML5 funcionam em Smartphones, tablets, PCs e smart TVs. +2. Anuncie e promova seu jogo na Web, bem como em outros meios de comunicação. +3. Pagamentos. Carregue o que quiser e use o serviço de processamento de pagamento que desejar. +4. Atualize seu jogo sempre que quiser. +5. Colete suas próprias análises. +6. Conecte-se com seus clientes mais de perto. +7. Usuários podem jogar sempre que quiserem e quando quiserem. + +## Tecnologias da Web + +| **Function** | **Tecnologias** | +| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Audio** | [Web Audio API](/pt-BR/docs/Web_Audio_API) | +| **Gráficos** | [WebGL](/pt-BR/docs/WebGL) ([OpenGL ES](http://www.khronos.org/opengles/) 2.0) | +| **Entrada** | [Touch events](/pt-BR/docs/DOM/Touch_events), [Gamepad API](/pt-BR/docs/API/Gamepad/Using_Gamepad_API), sensores de dispositivos, [WebRTC](/pt-BR/docs/WebRTC), [Full Screen API](/pt-BR/docs/DOM/Using_fullscreen_mode), [Pointer Lock API](/pt-BR/docs/WebAPI/Pointer_Lock) | +| **Linguagens** | [JavaScript](/pt-BR/docs/JavaScript) (ou C/C++ usando [Emscripten](https://github.com/kripken/emscripten/wiki) para compilar o JavaScript) | +| **Networking** | [WebRTC](/pt-BR/docs/WebRTC) e/ou [WebSockets](/pt-BR/docs/WebSockets) | +| **Armazenamento** | [IndexedDB](/pt-BR/docs/IndexedDB) ou a "nuvem" | +| **Web** | [HTML](/pt-BR/docs/HTML), [CSS](/pt-BR/docs/CSS), [SVG](/pt-BR/docs/SVG), [Social API](/pt-BR/docs/Social_API) (e muito mais!) | + +- [Full Screen API](/pt-BR/docs/DOM/Using_fullscreen_mode) + - : gameplay de tela cheia +- [Gamepad API](/pt-BR/docs/API/Gamepad/Using_Gamepad_API) + - : Use gamepads ou outros controladores de jogos. +- [HTML](/pt-BR/docs/HTML) e [CSS](/pt-BR/docs/CSS) + - : Contrua, estilize e disponha a interface de usuário do seu jogo. +- [HTML audio](/pt-BR/docs/HTML/Element/audio) + - : Reproduza facilmente efeitos sonoros simples e música. +- [IndexedDB](/pt-BR/docs/IndexedDB) + - : Armazene os dados de usuário em seu próprio computador ou dispositivo. +- [JavaScript](/pt-BR/docs/JavaScript) + - : Linguagem de programação web rápida para escrever o código do seu jogo, para portar facilmente seus jogos existentes [Emscripten](https://github.com/kripken/emscripten/wiki) ou [Asm.js](http://asmjs.org/spec/latest/). +- [Pointer Lock API](/pt-BR/docs/WebAPI/Pointer_Lock) + - : Bloquei o mouse ou outro dispositivo apontador na interface do seu jogo. +- [SVG](/pt-BR/docs/SVG) (Gráficos Vetorias Escaláveis) + - : Crie gráficos vetoriais que sejam dimensionados sem problemas, independemente do tamanho ou da resolução da exibição do usuário. + +- [Typed Arrays](/pt-BR/docs/JavaScript/Typed_arrays) + - : Acessar dados binários brutos de dentro do JavaScript; Manipule texturas GL, dados de jogos ou qualquer outra coisa. +- [Web Audio API](/pt-BR/docs/Web_Audio_API) + - : Controle a reprodução, síntese e manipulação de aúdio em tempo real. +- [WebGL](/pt-BR/docs/WebGL) + - : Crie gráficos 2D e 3D acelerados por hardware de alto desempenho. [OpenGL ES](http://www.khronos.org/opengles/) 2.0. +- [WebRTC](/pt-BR/docs/WebRTC) + - : Comunicações em tempo real para controlar dados de aúdio e vídeo, incluindo teleconferência e transmissão de outros dados de aplicativos entre dois usuários, como bate-papo. +- [WebSockets](/pt-BR/docs/WebSockets) + - : Conecte seu aplicativo ou site a um servidor para transmitir dados em tempo real. Perfeito para ação de jogo multiplayer, serviços de bate-papo e assim por diante. +- [Web Workers](/pt-BR/docs/DOM/Using_web_workers) + - : Crie threads em segundo plano executando seu próprio código JavaScript para processadres multi-core. +- [XMLHttpRequest](/pt-BR/docs/DOM/XMLHttpRequest) e [File API](/pt-BR/docs/DOM/File_API) + - : Envie e receba quaisquer tipo de dados que você quiser de um servidor da Web, como baixar novos níveis de jogos e ilustrações para transmitir informações de status de jogos não em tempo real. diff --git a/files/pt-br/games/publishing_games/index.html b/files/pt-br/games/publishing_games/index.html deleted file mode 100644 index ff057595275c68..00000000000000 --- a/files/pt-br/games/publishing_games/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Publishing games -slug: Games/Publishing_games -tags: - - HTML5 - - JavaScript - - Jogos - - Monetização - - Promoção - - distribuição - - publicação -translation_of: Games/Publishing_games ---- -
Então você realizou um ou dois tutoriais e desenvolveu um jogo em HTML5 - isso é ótimo! Distribuição de jogos provém tudo o que você necessita saber para poder distribuir o seu jogo recém criado para o mundo — incluindo hospedagem online, submetendo para marketplaces aberto, e submetendo para marketplaces fechados como Google Play ou iOS App Store.
- -Desenvolver e terminar um jogo não é coisa fácil. Você precisa deixar claro ao mundo que você fez uma coisa interessante estar disponível, em que as pessoas irão se divertir jogando. Existem diversas técnicas de promover os jogos — muitos deles sendo de graça — então mesmo você passando por dificuldades e batalhando para que consiga se sustentar como um desenvolvedor indie com zero de orçamento você consegue fazer muita coisa para deixar as pessoas sabendo sobre o seu mais eletrizante jogo. Promover o jogo ajuda, e em muito, conseguir monetizar ele mais pra frente, então é importante que você faça de uma forma efetiva.
- -Quando você passa horas e horas construindo, publicando e promovendo o seu jogo, você vai considerar, em algum ponto, conseguir algum sustento financeiro com ele. Monetização de jogos é essencial para qualquer pessoa que considera o seu trabalho de desenvolvimento de jogos um esforço sério no caminho para se tornar um desenvolvedor de jogos independente, capaz de se sustentar, então leia mais e veja quais são as suas opções. A tecnologia está madura o suficiente; é apenas uma questão de escolher a melhor abordagem.
diff --git a/files/pt-br/games/publishing_games/index.md b/files/pt-br/games/publishing_games/index.md new file mode 100644 index 00000000000000..31189588626163 --- /dev/null +++ b/files/pt-br/games/publishing_games/index.md @@ -0,0 +1,26 @@ +--- +title: Publishing games +slug: Games/Publishing_games +tags: + - HTML5 + - JavaScript + - Jogos + - Monetização + - Promoção + - distribuição + - publicação +translation_of: Games/Publishing_games +--- +{{GamesSidebar}}Jogos em HTML5 possuem uma grande vantagem sobre jogos nativos em termos de publicação e distribuição — você possui a liberdade de distribuição, promoção e monetização do seu jogo na Web, ao invés de que cada versão ficará presa em uma única loja controlada por uma empresa. Você pode se beneficiar com a Web sendo realmenete multiplataforma. Essa série de artigos demonstra as opções que você têm quando for publicar e distribuir o se jogo, e ter algum retorno enquanto você espera para se tornar famoso. + +## Distribuição do jogo + +Então você realizou [um](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript) ou [dois tutoriais](/pt-BR/docs/Games/Workflows/2D_Breakout_game_Phaser) e desenvolveu um jogo em HTML5 - isso é ótimo! Distribuição de jogos provém tudo o que você necessita saber para poder distribuir o seu jogo recém criado para o mundo — incluindo hospedagem online, submetendo para marketplaces aberto, e submetendo para marketplaces fechados como Google Play ou iOS App Store. + +## Promovendo o jogo + +Desenvolver e terminar um jogo não é coisa fácil. Você precisa deixar claro ao mundo que você fez uma coisa interessante estar disponível, em que as pessoas irão se divertir jogando. Existem diversas técnicas de [promover os jogos ](/pt-BR/docs/Games/Publishing_games/Game_promotion)— muitos deles sendo de graça — então mesmo você passando por dificuldades e batalhando para que consiga se sustentar como um desenvolvedor indie com zero de orçamento você consegue fazer muita coisa para deixar as pessoas sabendo sobre o seu mais eletrizante jogo. Promover o jogo ajuda, e em muito, conseguir monetizar ele mais pra frente, então é importante que você faça de uma forma efetiva. + +## Monetização do jogo + +Quando você passa horas e horas construindo, publicando e promovendo o seu jogo, você vai considerar, em algum ponto, conseguir algum sustento financeiro com ele. [Monetização de jogos ](/pt-BR/docs/Games/Publishing_games/Game_monetization)é essencial para qualquer pessoa que considera o seu trabalho de desenvolvimento de jogos um esforço sério no caminho para se tornar um desenvolvedor de jogos independente, capaz de se sustentar, então leia mais e veja quais são as suas opções. A tecnologia está madura o suficiente; é apenas uma questão de escolher a melhor abordagem. diff --git a/files/pt-br/games/techniques/2d_collision_detection/index.html b/files/pt-br/games/techniques/2d_collision_detection/index.html deleted file mode 100644 index 2f785b681412f4..00000000000000 --- a/files/pt-br/games/techniques/2d_collision_detection/index.html +++ /dev/null @@ -1,192 +0,0 @@ ---- -title: Detecção de Colisão 2D -slug: Games/Techniques/2D_collision_detection -translation_of: Games/Techniques/2D_collision_detection ---- -{{IncludeSubnav("/en-US/docs/Games")}}
- -Algoritmos para detectar colisões em jogos 2D dependem do tipo de formas que podem colidir (por exemplo, retângulo para retângulo, retângulo para círculo, círculo para círculo). Geralmente, você terá uma forma genérica simples que abrange a entidade conhecida como "hitbox", portanto, mesmo que a colisão não seja perfeita, ela terá boa aparência e terá bom desempenho em várias entidades. Este artigo fornece uma revisão das técnicas mais comuns usadas para fornecer detecção de colisão em jogos 2D.
-Uma das formas mais simples de detecção de colisão é entre dois retângulos alinhados no eixo — ou seja, sem rotação. O algoritmo funciona garantindo que não haja nenhum espaço entre os 4 lados dos retângulos. Qualquer lacuna significa que uma colisão não existe.
- -var rect1 = {x: 5, y: 5, width: 50, height: 50} -var rect2 = {x: 20, y: 10, width: 10, height: 10} - -if (rect1.x < rect2.x + rect2.width && - rect1.x + rect1.width > rect2.x && - rect1.y < rect2.y + rect2.height && - rect1.y + rect1.height > rect2.y) { - // collision detected! -} - -// filling in the values => - -if (5 < 30 && - 55 > 20 && - 5 < 20 && - 55 > 10) { - // collision detected! -} -- -
<div id="cr-stage"></div> -<p>Mova o retângulo com as setas do teclado. Verde significa colisão, azul significa não-colisão.</p> -<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crafty/0.5.4/crafty-min.js"></script> -- -
Crafty.init(200, 200); - -var dim1 = {x: 5, y: 5, w: 50, h: 50} -var dim2 = {x: 20, y: 10, w: 60, h: 40} - -var rect1 = Crafty.e("2D, Canvas, Color").attr(dim1).color("red"); - -var rect2 = Crafty.e("2D, Canvas, Color, Keyboard, Fourway").fourway(2).attr(dim2).color("blue"); - -rect2.bind("EnterFrame", function () { - if (rect1.x < rect2.x + rect2.w && - rect1.x + rect1.w > rect2.x && - rect1.y < rect2.y + rect2.h && - rect1.h + rect1.y > rect2.y) { - // collision detected! - this.color("green"); - } else { - // no collision - this.color("blue"); - } -}); - --
{{ EmbedLiveSample('Rect_code', '700', '300', '', 'Games/Techniques/2D_collision_detection') }}
- - - -Outra forma simples para detecção de colisão é entre dois círculos. Esse algoritmo funciona tomando os pontos centrais dos dois círculos e garantindo que a distância entre os pontos centrais seja menor que os dois raios somados.
- -<div id="cr-stage"></div> -<p>Move the circle with arrow keys. Green means collision, blue means no collision.</p> -<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crafty/0.5.4/crafty-min.js"></script> -- -
#cr-stage { - position: static !important; - height: 200px !important; -} -- -
Crafty.init(200, 200); - -var dim1 = {x: 5, y: 5} -var dim2 = {x: 20, y: 20} - -Crafty.c("Circle", { - circle: function(radius, color) { - this.radius = radius; - this.w = this.h = radius * 2; - this.color = color || "#000000"; - - this.bind("Move", Crafty.DrawManager.drawAll) - return this; - }, - - draw: function() { - var ctx = Crafty.canvas.context; - ctx.save(); - ctx.fillStyle = this.color; - ctx.beginPath(); - ctx.arc( - this.x + this.radius, - this.y + this.radius, - this.radius, - 0, - Math.PI * 2 - ); - ctx.closePath(); - ctx.fill(); - ctx.restore(); - } -}); - -var circle1 = Crafty.e("2D, Canvas, Circle").attr(dim1).circle(15, "red"); - -var circle2 = Crafty.e("2D, Canvas, Circle, Fourway").fourway(2).attr(dim2).circle(20, "blue"); - -circle2.bind("EnterFrame", function () { - var dx = (circle1.x + circle1.radius) - (circle2.x + circle2.radius); - var dy = (circle1.y + circle1.radius) - (circle2.y + circle2.radius); - var distance = Math.sqrt(dx * dx + dy * dy); - - if (distance < circle1.radius + circle2.radius) { - // collision detected! - this.color = "green"; - } else { - // no collision - this.color = "blue"; - } -}); - - --
var circle1 = {radius: 20, x: 5, y: 5};
-var circle2 = {radius: 12, x: 10, y: 5};
-
-var dx = circle1.x - circle2.x;
-var dy = circle1.y - circle2.y;
-var distance = Math.sqrt(dx * dx + dy * dy);
-
-if (distance < circle1.radius + circle2.radius) {
- // collision detected!
-}
-
-
-{{ EmbedLiveSample('Playable_code', '700', '300', '', 'Games/Techniques/2D_collision_detection') }}
- - - -Este é um algoritmo de colisão que pode detectar uma colisão entre quaisquer dois polígonos *convexos*. É mais complicado implementar do que os métodos acima, mas é mais poderoso. A complexidade de um algoritmo como esse significa que precisaremos considerar a otimização de desempenho, abordada na próxima seção.
- -A implementação do SAT está fora do escopo desta página, portanto, veja os tutoriais recomendados abaixo:
- -Embora alguns desses algoritmos para detecção de colisão sejam simples o suficiente para serem calculados, pode ser um desperdício de ciclos testar todas as entidades com todas as outras entidades. Normalmente os jogos dividem a colisão em duas fases, ampla e estreita.
- -A fase ampla deve fornecer uma lista de entidades que *podem* estar colidindo. Isso pode ser implementado com uma estrutura de dados espacial que lhe dará uma ideia aproximada de onde a entidade existe e o que existe em torno dela. Alguns exemplos de estruturas de dados espaciais são Quad Trees, R-Trees ou um Spash Hashmap.
- -Quando você tem uma pequena lista de entidades para verificar, você vai querer usar um algoritmo de fase estreita (como os listados acima) para fornecer uma resposta certa sobre se há uma colisão ou não.
diff --git a/files/pt-br/games/techniques/2d_collision_detection/index.md b/files/pt-br/games/techniques/2d_collision_detection/index.md new file mode 100644 index 00000000000000..8553d0ed7d2ea1 --- /dev/null +++ b/files/pt-br/games/techniques/2d_collision_detection/index.md @@ -0,0 +1,180 @@ +--- +title: Detecção de Colisão 2D +slug: Games/Techniques/2D_collision_detection +translation_of: Games/Techniques/2D_collision_detection +--- +{{GamesSidebar}} + +{{IncludeSubnav("/en-US/docs/Games")}} + +Algoritmos para detectar colisões em jogos 2D dependem do tipo de formas que podem colidir (por exemplo, retângulo para retângulo, retângulo para círculo, círculo para círculo). Geralmente, você terá uma forma genérica simples que abrange a entidade conhecida como "hitbox", portanto, mesmo que a colisão não seja perfeita, ela terá boa aparência e terá bom desempenho em várias entidades. Este artigo fornece uma revisão das técnicas mais comuns usadas para fornecer detecção de colisão em jogos 2D. + +## Caixa delimitadora alinhada por eixo + +Uma das formas mais simples de detecção de colisão é entre dois retângulos alinhados no eixo — ou seja, sem rotação. O algoritmo funciona garantindo que não haja nenhum espaço entre os 4 lados dos retângulos. Qualquer lacuna significa que uma colisão não existe. + +```js +var rect1 = {x: 5, y: 5, width: 50, height: 50} +var rect2 = {x: 20, y: 10, width: 10, height: 10} + +if (rect1.x < rect2.x + rect2.width && + rect1.x + rect1.width > rect2.x && + rect1.y < rect2.y + rect2.height && + rect1.y + rect1.height > rect2.y) { + // collision detected! +} + +// filling in the values => + +if (5 < 30 && + 55 > 20 && + 5 < 20 && + 55 > 10) { + // collision detected! +} +``` + +```html hidden + +Mova o retângulo com as setas do teclado. Verde significa colisão, azul significa não-colisão.
+ +``` + +```js hidden +Crafty.init(200, 200); + +var dim1 = {x: 5, y: 5, w: 50, h: 50} +var dim2 = {x: 20, y: 10, w: 60, h: 40} + +var rect1 = Crafty.e("2D, Canvas, Color").attr(dim1).color("red"); + +var rect2 = Crafty.e("2D, Canvas, Color, Keyboard, Fourway").fourway(2).attr(dim2).color("blue"); + +rect2.bind("EnterFrame", function () { + if (rect1.x < rect2.x + rect2.w && + rect1.x + rect1.w > rect2.x && + rect1.y < rect2.y + rect2.h && + rect1.h + rect1.y > rect2.y) { + // collision detected! + this.color("green"); + } else { + // no collision + this.color("blue"); + } +}); +``` + +{{ EmbedLiveSample('Rect_code', '700', '300', '', 'Games/Techniques/2D_collision_detection') }} + +> **Nota:** [Outro exemplo sem o Canvas ou bibliotecas externas.](https://jsfiddle.net/jlr7245/217jrozd/3/) + +## Colisão Circular + +Outra forma simples para detecção de colisão é entre dois círculos. Esse algoritmo funciona tomando os pontos centrais dos dois círculos e garantindo que a distância entre os pontos centrais seja menor que os dois raios somados. + +```html hidden + +Move the circle with arrow keys. Green means collision, blue means no collision.
+ +``` + +```css hidden +#cr-stage { + position: static !important; + height: 200px !important; +} +``` + +```js hidden +Crafty.init(200, 200); + +var dim1 = {x: 5, y: 5} +var dim2 = {x: 20, y: 20} + +Crafty.c("Circle", { + circle: function(radius, color) { + this.radius = radius; + this.w = this.h = radius * 2; + this.color = color || "#000000"; + + this.bind("Move", Crafty.DrawManager.drawAll) + return this; + }, + + draw: function() { + var ctx = Crafty.canvas.context; + ctx.save(); + ctx.fillStyle = this.color; + ctx.beginPath(); + ctx.arc( + this.x + this.radius, + this.y + this.radius, + this.radius, + 0, + Math.PI * 2 + ); + ctx.closePath(); + ctx.fill(); + ctx.restore(); + } +}); + +var circle1 = Crafty.e("2D, Canvas, Circle").attr(dim1).circle(15, "red"); + +var circle2 = Crafty.e("2D, Canvas, Circle, Fourway").fourway(2).attr(dim2).circle(20, "blue"); + +circle2.bind("EnterFrame", function () { + var dx = (circle1.x + circle1.radius) - (circle2.x + circle2.radius); + var dy = (circle1.y + circle1.radius) - (circle2.y + circle2.radius); + var distance = Math.sqrt(dx * dx + dy * dy); + + if (distance < circle1.radius + circle2.radius) { + // collision detected! + this.color = "green"; + } else { + // no collision + this.color = "blue"; + } +}); +``` + +```js +var circle1 = {radius: 20, x: 5, y: 5}; +var circle2 = {radius: 12, x: 10, y: 5}; + +var dx = circle1.x - circle2.x; +var dy = circle1.y - circle2.y; +var distance = Math.sqrt(dx * dx + dy * dy); + +if (distance < circle1.radius + circle2.radius) { + // collision detected! +} +``` + +{{ EmbedLiveSample('Playable_code', '700', '300', '', 'Games/Techniques/2D_collision_detection') }} + +> **Nota:** [Aqui é outro exemplo sem o Canvas ou bibliotecas externas.](https://jsfiddle.net/jlr7245/teb4znk0/20/) + +## Teorema do eixo de separação + +Este é um algoritmo de colisão que pode detectar uma colisão entre quaisquer dois polígonos \*convexos\*. É mais complicado implementar do que os métodos acima, mas é mais poderoso. A complexidade de um algoritmo como esse significa que precisaremos considerar a otimização de desempenho, abordada na próxima seção. + +A implementação do SAT está fora do escopo desta página, portanto, veja os tutoriais recomendados abaixo: + +1. [Separating Axis Theorem (SAT) explanation](http://www.sevenson.com.au/actionscript/sat/) +2. [Collision detection and response](http://www.metanetsoftware.com/technique/tutorialA.html) +3. [Collision detection Using the Separating Axis Theorem](http://gamedevelopment.tutsplus.com/tutorials/collision-detection-using-the-separating-axis-theorem--gamedev-169) +4. [SAT (Separating Axis Theorem)](http://www.codezealot.org/archives/55) +5. [Separation of Axis Theorem (SAT) for Collision DDetection](http://rocketmandevelopment.com/blog/separation-of-axis-theorem-for-collision-detection/) + +## Performance de Colisão + +Embora alguns desses algoritmos para detecção de colisão sejam simples o suficiente para serem calculados, pode ser um desperdício de ciclos testar todas as entidades com todas as outras entidades. Normalmente os jogos dividem a colisão em duas fases, ampla e estreita. + +### Fase Larga + +A fase ampla deve fornecer uma lista de entidades que \*podem\* estar colidindo. Isso pode ser implementado com uma estrutura de dados espacial que lhe dará uma ideia aproximada de onde a entidade existe e o que existe em torno dela. Alguns exemplos de estruturas de dados espaciais são Quad Trees, R-Trees ou um Spash Hashmap. + +### Fase estreita + +Quando você tem uma pequena lista de entidades para verificar, você vai querer usar um algoritmo de fase estreita (como os listados acima) para fornecer uma resposta certa sobre se há uma colisão ou não. diff --git a/files/pt-br/games/techniques/3d_on_the_web/index.html b/files/pt-br/games/techniques/3d_on_the_web/index.html deleted file mode 100644 index c99bdcf99c54f3..00000000000000 --- a/files/pt-br/games/techniques/3d_on_the_web/index.html +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: Jogos 3D na WEB -slug: Games/Techniques/3D_on_the_web -tags: - - 3D - - Jogos - - graficos -translation_of: Games/Techniques/3D_on_the_web ---- -A melhor arma para desenvolver ótimas experiências em jogos na WEB é WebGL, que é renderizada em HTML {{htmlelement("canvas")}}. WebGL é, basicamente, uma OpenGL ES 2.0 para a Web — é uma API JavaScript que fornece ferramentas para construir animações ricas e, logicamente, jogos. Você pode gerar e renderizar gráficos dinâmicos em 3D com JavaScript acelerado por hardware.
- -A documentação e as especificações do projeto WebGL é mantida pelo Grupo Khronos, não o W3C como a maioria das APIs Web. O suporte nos navegadores modernos é muito bom, até mesmo em mobile, portanto você não terá que se preocupar muito com isso. Todos os navegadores comuns suportam WebGL e tudo mais que você precisar para que possa focar em otimizar o desempenho nos dispositivos que usar.
- -Há um esforço contínuo em liberar WebGL 2.0 (baseado na OpenGL ES 3.0) em um futuro próximo para, além de trazer muitas melhorias, também ajudar os desenvolvedores a construir jogos para a Web "moderna", usando hardware atual e poderoso.
- -O básico da teoria 3D gira em torno de formas representadas em um espaço 3D, que corresponde a um sistema de coordenadas usadas para calcular suas posições. Veja noss artigo Explicando a teoria 3D básica para todas as informações que você precisar
- -Você pode fazer muito mais com WebGL. Há alguns conceitos avançados que você deve se aprofundar e aprender mais — como shaders, detecção de colisão, ou o mais recente tópico em alta — realidade virtual na web.
- -É importante mencionar os shaders, que tem uma história separada por sí próprios. Shaders usam GLSL, uma "Linguagem de Sombreamento" OpenGL especial com sintaxe similar a C, que é executada diretamente pelos pipelines de gráficos. Podem ser divididos em Vertex Shaders e Fragment Shaders (ou Pixel Shaders) — o primeiro transforma as posições das formas em coordenadas reais de desenho 3D, enquanto o segundo calcula cores de renderização e outros atributos. Recomendamos fortemente que você veja o artigo GLSL Shaders para aprender mais sobre eles.
- -É difícil de imaginar um jogo sem detecção de colisão — nós sempre precisamos trabalhar com algo batendo em alguma outra coisa. Temos informações disponíveis para você aprender em:
- - - -O conceito de realidade virtual não é novo, mas está crescendo na web devido os avanços de hardware, tal como o Oculus Rift, e a (atualmente experimental) WebVR API para capturar informações de hardware via Realidade Virtual (RV) e tonaná-la acessível para uso em aplicações JavaScript. Para mais informações, leia WebVR — Realidade Virtual para a Web.
- -Também há o artigo Desenvolvendo uma demo básica com A-Frame que te mostra como é fácil construir ambientes 3D para realidade virtual usando o framework A-Frame.
- -Codificar WebGL diretamente é bem complexo, mas você vai querer se familiarizar com isso a longo prazo quando seus projetos avançarem (veja nossa documentação WebGL para começar). Para projetos do mundo real você provavelmente também usará um framework para acelerar o desenvolvimento e ajudar na administração do projeto em que estiver trabalhando. Usar um framework para jogos 3D também ajuda muito a otimizar o desempenho, assim você pode focar no desenvolvimento do jogo.
- -A biblioteca JavaScript 3D mais popular é Three.js, uma ferramenta multiuso que deixa técnicas 3D comuns mais simples de serem implementadas. Há outras bibliotecas de desenvolvimento de jogos populares e alguns frameworks que valem a pena serem checados também; A-Frame, PlayCanvas e Babylon.js estão entre os mais reconhecidos, com belas documentações, editores online e comunidades ativas.
- -A-Frame é um framework web para desenvolvimento 3D e experiências de RV. Visto mais afundo, é um framework three.js com um padrão componente-entidade declarativo, significando que podemos construir cenas apenas com HTML. Veja a página Desenvolvendo uma demo básica com A-Frame para o passo-a-passo da criação de uma demo.
- -Babylon.js é um dos mais populares motores de jogos 3D usados por desenvolvedores. Assim como qualquer outra biblioteca 3D, ela fornece funções integradas para te ajudar a implementar funcionalidades tridimensionais comuns mais rapidamente. Veja a página Desenvovlendo uma demo básica com Babylon.js para saber o básico de Babylon.js, incluindo configurações do ambiente de desenvolvimento, estruturar o HTML necessário e escrever o código JavaScript.
- -PlayCanvas é um popular motor de jogos 3D WebGL de código aberto no GitHub, com um editor acessível online e com boa documentação. Veja a página Desenvolvendo uma demo básica com PlayCanvas para detalhes mais avançados e encontrar outros artigos mostrando como usar a bilbioteca PlayCanvas e o editor online.
- -Three.js, assim como qualquer outra biblioteca, lhe fornece uma enorme vantagem: ao invés de escrever centenas de linhas do código WebGL para construir qualquer coisa interessante, te permite usar as funções auxiliares integradas para desenvolver o que quiser muito mais rápido e fácil. Veja a página Desenvolvendo uma demo básica com Three.js para o passo-a-passo da criação de uma demo.
- -Tanto Unity quanto Unreal podem exportar o seu jogo para WebGL com asm.js, então você estará livre para usar suas ferramentas e técnicas para desenvolvimento de jogos que serão exportados para a web.
- - - -Com esse artigo nós apenas arranhamos a superfície do que é possível fazer com as tecnologias disponíveis atualmente. Você pode desenvolver jogos imersivos, belos e rápidos na WEB usando WebGL, e as bibliotecas e frameworks construídos sobre ele.
- -Você pode encontrar todo o código fonte para esta série de demos no GitHub.
- -One of HTML5's main advantages as a game development platform is the ability to run on various platforms and devices. Streamlining cross device differences creates multiple challenges, not least when providing appropriate controls for different contexts. In this series of articles we will show you how you can approach building a game that can be played using touchscreen smartphones, mouse and keyboard, and also less common mechanisms such as gamepads.
- -We'll be using the Captain Rogers: Battle at Andromeda demo as an example.
- - - -Captain Rogers was created using the Phaser framework, the most popular tool for simple 2D game development in JavaScript right now, but it should be fairly easy to reuse the knowledge contained within these articles when building games in pure JavaScript or any other framework. If you're looking for a good introduction to Phaser, then check the 2D breakout game using Phaser tutorial.
- -In the following articles we will show how to implement various different control mechanisms for Captain Rogers to support different platforms — from touch on mobile, through keyboard/mouse/gamepad on desktop, to more unconventional ones like TV remote, shouting to or waving your hand in front of the laptop, or squeezing bananas.
- -Let's start with a quick overview of the game's folder structure, JavaScript files and in-game states, so we know what's happening where. The game's folders look like this:
- - - -As you can see there are folders for images, JavaScript files, fonts and sound effects. The src
folder contains the JavaScript files split as a separate states — Boot.js
, Preloader.js
, MainMenu.js
and Game.js
— these are loaded into the index file in this exact order. The first one initializes Phaser, the second preloads all the assets, the third one controls the main menu welcoming the player, and the fourth controls the actual gameplay.
Every state has its own default methods: preload()
, create()
, and update()
. The first one is needed for preloading required assets, create()
is executed once the state had started, and update()
is executed on every frame.
For example, you can define a button in the create()
function:
create: function() { - // ... - var buttonEnclave = this.add.button(10, 10, 'logo-enclave', this.clickEnclave, this); - // ... -} -- -
It will be created once at the start of the game, and will execute this.clickEnclave()
action assigned to it when clicked, but you can also use the mouse's pointer value in the update()
function to make an action:
update: function() { - // ... - if(this.game.input.mousePointer.isDown) { - // do something - } - // ... -} -- -
This will be executed whenever the mouse button is pressed, and it will be checked against the input's isDown
boolean variable on every frame of the game.
That should give you some understanding of the project structure. We'll be playing mostly with the MainMenu.js
and Game.js
files, and we'll explain the code inside the create()
and update()
methods in much more detail in later articles.
There's also a small online demo with full source code available on GitHub where the basic support for the control mechanisms described in the articles is implemented in pure JavaScript. It will be explained in the given articles themselves below, but you can play with it already, and use the code however you want for learning purposes.
- -JavaScript is the perfect choice for mobile gaming because of HTML5 being truly multiplatform; all of the following articles focus on the APIs provided for interfacing with different control mechanisms:
- -This page lists essential core techniques for anyone wanting to develop games using open web technologies.
- -These are the Ideas and Technique for game devlopment
-Asm.js é uma especificação que define um subconjunto de JavaScript que é altamente otimizável. Esta seção examina exatamente o que é permitido no subconjunto asm.js, que melhorias confere, Onde e como você pode fazer uso dele, e mais Principais recursos e exemplos.
-É muito pequeno estrita subconjunto de JavaScript, que permite que apenas coisas como `while`,` if`, números, chamado funções de nível superior, e outros meros constructos. Ele não permite que objetos, cordas, fechos, e basicamente qualquer coisa que requer a alocação heap. Asm.js se assemelha ao código C, em muitos aspectos, o objectivo é ainda válida JavaScript Chamada completamente que será executado em todos os motores atuais. Ele empurra motores de JS para otimizar este tipo de código e compiladores como emscripten Dá uma definição clara de que tipo de código para gerar. Vamos mostrar o que asm.js código se parece com e explicar como ele ajuda e como você pode usá-lo.
- -Este subconjunto de JavaScript já é altamente otimizado motores de JavaScript em Many fantasia usando Just-In-Time (JIT) compilação técnica. No entanto, através da definição de um padrão explícito podemos trabalhar com isso otimizando este tipo de código ainda mais e obter o máximo de desempenho como nós podemos sair dela. Ela torna mais fácil para colaborar através de vários motores de JS porque é fácil para falar e benchmark. A idéia é que este tipo de código de correr muito rápido em deveres Cada motor, e se isso não acontecer, é um bug e há uma motores de especificação claro que shoulds otimizar.
- -Ele aussi Torna mais fácil para as pessoas que escrevem compiladores que deseja gerar código de alto desempenho na Web. Podem consultar a especificação asm.js e sei que ele vai correr rápido Se eles aderem a asm.js padrões. Emscripten, um C / C ++ para compilador JavaScript, EMITE código asm.js para fazê-lo funcionar com desempenho quase nativo em vários navegadores.
- -Além disso, se um motor especialmente escolhe reconhecer asm.js código, há otimizações ainda mais que pode ser feito. Firefox é o único no navegador para fazer isso agora.
- -- -
asm.js é uma linguagem de programação intermediária. asm.js: tem uma taxa de perfomance muito previsível Porque é limitado a um subconjunto muito limitado de JavaScript que fornece inteiros única estritamente tipados, flutuadores, aritmética, chamadas de função, e montão acessos. As características de desempenho estão mais perto de código nativo do que a de JavaScript padrão. Usando um subconjunto de asm.js JavaScript já é suportado pelos principais navegadores web. Desde asm.js executado em um navegador fortemente depende do navegador e do hardware.
diff --git a/files/pt-br/games/tools/asm.js/index.md b/files/pt-br/games/tools/asm.js/index.md new file mode 100644 index 00000000000000..a98f2346bca630 --- /dev/null +++ b/files/pt-br/games/tools/asm.js/index.md @@ -0,0 +1,22 @@ +--- +title: asm.js +slug: Games/Tools/asm.js +translation_of: Games/Tools/asm.js +--- +{{GamesSidebar}}{{IncludeSubnav("/en-US/docs/Games")}} + +[Asm.js](http://asmjs.org/) é uma especificação que define um subconjunto de JavaScript que é altamente otimizável. Esta seção examina exatamente o que é permitido no subconjunto asm.js, que melhorias confere, Onde e como você pode fazer uso dele, e mais Principais recursos e exemplos. + +## O que é asm.js, exatamente? + +É muito pequeno estrita subconjunto de JavaScript, que permite que apenas coisas como \`while\`,\` if\`, números, chamado funções de nível superior, e outros meros constructos. Ele não permite que objetos, cordas, fechos, e basicamente qualquer coisa que requer a alocação heap. Asm.js se assemelha ao código C, em muitos aspectos, o objectivo é ainda válida JavaScript Chamada completamente que será executado em todos os motores atuais. Ele empurra motores de JS para otimizar este tipo de código e compiladores como emscripten Dá uma definição clara de que tipo de código para gerar. Vamos mostrar o que asm.js código se parece com e explicar como ele ajuda e como você pode usá-lo. + +Este subconjunto de JavaScript já é altamente otimizado motores de JavaScript em Many fantasia usando Just-In-Time (JIT) compilação técnica. No entanto, através da definição de um padrão explícito podemos trabalhar com isso otimizando este tipo de código ainda mais e obter o máximo de desempenho como nós podemos sair dela. Ela torna mais fácil para colaborar através de vários motores de JS porque é fácil para falar e benchmark. A idéia é que este tipo de código de correr muito rápido em deveres Cada motor, e se isso não acontecer, é um bug e há uma motores de especificação claro que shoulds otimizar. + +Ele aussi Torna mais fácil para as pessoas que escrevem compiladores que deseja gerar código de alto desempenho na Web. Podem consultar a especificação asm.js e sei que ele vai correr rápido Se eles aderem a asm.js padrões. Emscripten, um C / C ++ para compilador JavaScript, EMITE código asm.js para fazê-lo funcionar com desempenho quase nativo em vários navegadores. + +Além disso, se um motor especialmente escolhe reconhecer asm.js código, há otimizações ainda mais que pode ser feito. Firefox é o único no navegador para fazer isso agora. + +## Resumo linguagem asm.js + +asm.js é uma linguagem de programação intermediária. asm.js: tem uma taxa de perfomance muito previsível Porque é limitado a um subconjunto muito limitado de JavaScript que fornece inteiros única estritamente tipados, flutuadores, aritmética, chamadas de função, e montão acessos. As características de desempenho estão mais perto de código nativo do que a de JavaScript padrão. Usando um subconjunto de asm.js JavaScript já é suportado pelos principais navegadores web. Desde asm.js executado em um navegador fortemente depende do navegador e do hardware. diff --git a/files/pt-br/games/tools/index.html b/files/pt-br/games/tools/index.html deleted file mode 100644 index 5ba0dff1542185..00000000000000 --- a/files/pt-br/games/tools/index.html +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Ferramentas para o desenvolvimento de jogos -slug: Games/Tools -tags: - - Gecko - - Guia(2) - - JavaScript - - Jogos -translation_of: Games/Tools ---- -Nesta página você pode encontrar links para a nossa ferramenta de desenvolvimento de jogos, artigos, os quais eventualmente abrangem frameworks, compiladores, e ferramentas de debug.
-The Gecko profiler extension lets you profile your code to help figure out where your performance issues are so that you can make your game run at top speed
-A extensão Gecko profiler permite que você recorte seu código para ajudar a descobrir onde seus problemas de desempenho de modo a poder fazer o seu jogo executar em alta velocidade.
Como isso difere da depuração normal de aplicativos da web? Que ferramentas especializadas estão disponíveis? Um monte disso está sendo coberto pelo Will em ferramentas, mas aqui nós devemos fornecer um tipo de tutorial de prática para jogos de depuração toolchain, com links para coisas do Will:
-{{Next("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it")}}
- -In this step-by-step tutorial we create a simple MDN Breakout game written entirely in pure JavaScript and rendered on HTML5 {{htmlelement("canvas")}}.
- -Every step has editable, live samples available to play with so you can see what the intermediate stages should look like. You will learn the basics of using the {{htmlelement("canvas")}} element to implement fundamental game mechanics like rendering and moving images, collision detection, control mechanisms, and winning and losing states.
- -To get the most out of this series of articles you should already have basic to intermediate JavaScript knowledge. After working through this tutorial you should be able to build your own simple Web games.
- - - -All the lessons — and the different versions of the MDN Breakout game we are building together — are available on GitHub:
- -Starting with pure JavaScript is the best way to get a solid knowledge of web game development. After that, you can pick any framework you like and use it for your projects. Frameworks are just tools built with the JavaScript language; so even if you plan on working with them, it's good to learn about the language itself first to know what exactly is going on under the hood. Frameworks speed up development time and help take care of boring parts of the game, but if something is not working as expected, you can always try to debug that or just write your own solutions in pure JavaScript.
- -Note: If you are interested in learning about 2D web game development using a game library, consult this series' counterpart, 2D breakout game using Phaser.
-Note: This series of articles can be used as material for hands-on game development workshops. You can also make use of the Gamedev Canvas Content Kit based on this tutorial if you want to give a talk about game development in general.
-Ok, let's get started! Head to the first chapter— Create the Canvas and draw on it.
- -{{Next("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it")}}
diff --git a/files/pt-br/games/tutorials/2d_breakout_game_pure_javascript/index.md b/files/pt-br/games/tutorials/2d_breakout_game_pure_javascript/index.md new file mode 100644 index 00000000000000..30b0059f02225c --- /dev/null +++ b/files/pt-br/games/tutorials/2d_breakout_game_pure_javascript/index.md @@ -0,0 +1,52 @@ +--- +title: 2D breakout game using pure JavaScript +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript +tags: + - 2D + - Beginner + - Canvas + - Games + - JavaScript + - NeedsTranslation + - TopicStub + - Tutorial +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript +--- +{{GamesSidebar}}{{IncludeSubnav("/en-US/docs/Games")}} + +{{Next("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it")}} + +In this step-by-step tutorial we create a simple **MDN Breakout** game written entirely in pure JavaScript and rendered on HTML5 {{htmlelement("canvas")}}. + +Every step has editable, live samples available to play with so you can see what the intermediate stages should look like. You will learn the basics of using the {{htmlelement("canvas")}} element to implement fundamental game mechanics like rendering and moving images, collision detection, control mechanisms, and winning and losing states. + +To get the most out of this series of articles you should already have basic to intermediate [JavaScript](/en-US/Learn/Getting_started_with_the_web/JavaScript_basics) knowledge. After working through this tutorial you should be able to build your own simple Web games. + +![Gameplay screen from the game MDN Breakout where you can use your paddle to bounce the ball and destroy the brick field, with keeping the score and lives.](https://mdn.mozillademos.org/files/10383/mdn-breakout-gameplay.png) + +## Lesson details + +All the lessons — and the different versions of the [MDN Breakout game](http://breakout.enclavegames.com/lesson10.html) we are building together — are [available on GitHub](https://github.com/end3r/Canvas-gamedev-workshop): + +1. [Create the Canvas and draw on it](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it) +2. [Move the ball](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Move_the_ball) +3. [Bounce off the walls](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls) +4. [Paddle and keyboard controls](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls) +5. [Game over](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Game_over) +6. [Build the brick field](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Build_the_brick_field) +7. [Collision detection](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection) +8. [Track the score and win](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win) +9. [Mouse controls](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls) +10. [Finishing up](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Finishing_up) + +Starting with pure JavaScript is the best way to get a solid knowledge of web game development. After that, you can pick any framework you like and use it for your projects. Frameworks are just tools built with the JavaScript language; so even if you plan on working with them, it's good to learn about the language itself first to know what exactly is going on under the hood. Frameworks speed up development time and help take care of boring parts of the game, but if something is not working as expected, you can always try to debug that or just write your own solutions in pure JavaScript. + +> **Nota:** If you are interested in learning about 2D web game development using a game library, consult this series' counterpart, [2D breakout game using Phaser](/pt-BR/docs/Games/Workflows/2D_breakout_game_Phaser). + +> **Nota:** This series of articles can be used as material for hands-on game development workshops. You can also make use of the [Gamedev Canvas Content Kit](https://github.com/end3r/Gamedev-Canvas-Content-Kit) based on this tutorial if you want to give a talk about game development in general. + +## Next steps + +Ok, let's get started! Head to the first chapter— [Create the Canvas and draw on it](/pt-BR/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it). + +{{Next("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it")}} diff --git a/files/pt-br/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.html b/files/pt-br/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.html deleted file mode 100644 index 7916e81ba7fa87..00000000000000 --- a/files/pt-br/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.html +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: Move the ball -slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball -translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball ---- -{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}}
- -This is the 2nd step out of 10 of the Gamedev Canvas tutorial. You can find the source code as it should look after completing this lesson at Gamedev-Canvas-workshop/lesson2.html.
-Você já sabe como desenhar uma bola através do tópico anterior, então agora vamos seguir em frente. Tecnicamente, nos vamos estar pintando uma bola na tela, clareando e então pintando de novo em uma posição um pouco diferente a cada frame para dar a impressão de movimento — assim como os filmes se movimentam.
- -To keep constantly updating the canvas drawing on each frame, we need to define a drawing function that will run over and over again, with a different set of variable values each time to change sprite positions, etc. You can run a function over and over again using a JavaScript timing function such as {{domxref("WindowTimers.setInterval()", "setInterval()")}} or {{domxref("window.requestAnimationFrame()", "requestAnimationFrame()")}}.
- -Delete all the JavaScript you currently have inside your HTML file except for the first two lines, and add the following below them. The draw()
function will be executed within setInterval
every 10 miliseconds:
function draw() { - // drawing code -} -setInterval(draw, 10);- -
Thanks to the infinite nature of setInterval
the draw()
function will be called every 10 milliseconds forever, or until we stop it. Now, let's draw the ball — add the following inside your draw()
function:
ctx.beginPath(); -ctx.arc(50, 50, 10, 0, Math.PI*2); -ctx.fillStyle = "#0095DD"; -ctx.fill(); -ctx.closePath(); -- -
Try your updated code now — the ball should be repainted on every frame.
- -You won't notice the ball being repainted constantly at the moment, as it's not moving. Let's change that. First, instead of a hardcoded position at (50,50) we will define a starting point at the bottom center part of the Canvas in variables called x
and y
, then use those to define the position the circle is drawn at.
First, add the following two lines above your draw()
function, to define x
and y
:
var x = canvas.width/2; -var y = canvas.height-30; -- -
Next update the draw()
function to use the x and y variables in the {{domxref("CanvasRenderingContext2D.arc()","arc()")}} method, as shown in the following highlighted line:
function draw() { - ctx.beginPath(); - ctx.arc(x, y, 10, 0, Math.PI*2); - ctx.fillStyle = "#0095DD"; - ctx.fill(); - ctx.closePath(); -} -- -
Now comes the important part: we want to add a small value to x
and y
after every frame has been drawn to make it appear that the ball is moving. Let's define these small values as dx
and dy
and set their values to 2 and -2 respectively. Add the following below your x and y variable definitions:
var dx = 2; -var dy = -2; -- -
The last thing to do is to update x
and y
with our dx
and dy
variable on every frame, so the ball will be painted in the new position on every update. Add the following two new lines indicated below to your draw()
function:
function draw() { - ctx.beginPath(); - ctx.arc(x, y, 10, 0, Math.PI*2); - ctx.fillStyle = "#0095DD"; - ctx.fill(); - ctx.closePath(); - x += dx; - y += dy; -}- -
Save your code again and try it in your browser. This works ok, although it appears that the ball is leaving a trail behind it:
- - - -The ball is leaving a trail because we're painting a new circle on every frame without removing the previous one. Don't worry, because there's a method to clear canvas content: {{domxref("CanvasRenderingContext2D.clearRect()","clearRect()")}}. This method takes four parameters: the x and y coordinates of the top left corner of a rectangle, and the x and y coordinates of the bottom right corner of a rectangle. The whole area covered by this rectangle will be cleared of any content previously painted there.
- -Add the following highlighted new line to the draw()
function:
function draw() { - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.beginPath(); - ctx.arc(x, y, 10, 0, Math.PI*2); - ctx.fillStyle = "#0095DD"; - ctx.fill(); - ctx.closePath(); - x += dx; - y += dy; -} -- -
Save your code and try again, and this time you'll see the ball move without a trail. Every 10 milliseconds the canvas is cleared, the blue circle (our ball) will be drawn on a given position and the x
and y
values will be updated for the next frame.
We will be adding more and more commands to the draw()
function in the next few articles, so it's good to keep it as simple and clean as possible. Let's start by moving the ball drawing code to a separate function.
Replace the existing draw() function with the following two functions:
- -function drawBall() { - ctx.beginPath(); - ctx.arc(x, y, 10, 0, Math.PI*2); - ctx.fillStyle = "#0095DD"; - ctx.fill(); - ctx.closePath(); -} - -function draw() { - ctx.clearRect(0, 0, canvas.width, canvas.height); - drawBall(); - x += dx; - y += dy; -}- -
You can check the finished code for this article for yourself in the live demo below, and play with it to understand better how it works:
- -{{JSFiddleEmbed("https://jsfiddle.net/end3r/3x5foxb1/","","395")}}
- -Exercise: try changing the speed of the moving ball, or the direction it moves in.
-We've drawn our ball and gotten it moving, but it keeps disappearing off the edge of the canvas. In the third chapter we'll explore how to make it bounce off the walls.
- -{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}}
diff --git a/files/pt-br/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.md b/files/pt-br/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.md new file mode 100644 index 00000000000000..6fb020a96b35bc --- /dev/null +++ b/files/pt-br/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.md @@ -0,0 +1,143 @@ +--- +title: Move the ball +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball +--- +{{GamesSidebar}}{{IncludeSubnav("/en-US/docs/Games")}} + +{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}} + +This is the **2nd step** out of 10 of the [Gamedev Canvas tutorial](/pt-BR/docs/Games/Workflows/Breakout_game_from_scratch). You can find the source code as it should look after completing this lesson at [Gamedev-Canvas-workshop/lesson2.html](https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson02.html). + +Você já sabe como desenhar uma bola através do tópico anterior, então agora vamos seguir em frente. Tecnicamente, nos vamos estar pintando uma bola na tela, clareando e então pintando de novo em uma posição um pouco diferente a cada frame para dar a impressão de movimento — assim como os filmes se movimentam. + +## Defining a drawing loop + +To keep constantly updating the canvas drawing on each frame, we need to define a drawing function that will run over and over again, with a different set of variable values each time to change sprite positions, etc. You can run a function over and over again using a JavaScript timing function such as {{domxref("WindowTimers.setInterval()", "setInterval()")}} or {{domxref("window.requestAnimationFrame()", "requestAnimationFrame()")}}. + +Delete all the JavaScript you currently have inside your HTML file except for the first two lines, and add the following below them. The `draw()` function will be executed within `setInterval` every 10 miliseconds: + +```js +function draw() { + // drawing code +} +setInterval(draw, 10); +``` + +Thanks to the infinite nature of `setInterval` the `draw()` function will be called every 10 milliseconds forever, or until we stop it. Now, let's draw the ball — add the following inside your `draw()` function: + +```js +ctx.beginPath(); +ctx.arc(50, 50, 10, 0, Math.PI*2); +ctx.fillStyle = "#0095DD"; +ctx.fill(); +ctx.closePath(); +``` + +Try your updated code now — the ball should be repainted on every frame. + +## Making it move + +You won't notice the ball being repainted constantly at the moment, as it's not moving. Let's change that. First, instead of a hardcoded position at (50,50) we will define a starting point at the bottom center part of the Canvas in variables called `x` and `y`, then use those to define the position the circle is drawn at. + +First, add the following two lines above your `draw()` function, to define `x` and `y`: + +```js +var x = canvas.width/2; +var y = canvas.height-30; +``` + +Next update the `draw()` function to use the x and y variables in the {{domxref("CanvasRenderingContext2D.arc()","arc()")}} method, as shown in the following highlighted line: + +```js +function draw() { + ctx.beginPath(); + ctx.arc(x, y, 10, 0, Math.PI*2); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); +} +``` + +Now comes the important part: we want to add a small value to `x` and `y` after every frame has been drawn to make it appear that the ball is moving. Let's define these small values as `dx` and `dy` and set their values to 2 and -2 respectively. Add the following below your x and y variable definitions: + +```js +var dx = 2; +var dy = -2; +``` + +The last thing to do is to update `x` and `y` with our `dx` and `dy` variable on every frame, so the ball will be painted in the new position on every update. Add the following two new lines indicated below to your `draw()` function: + +```js +function draw() { + ctx.beginPath(); + ctx.arc(x, y, 10, 0, Math.PI*2); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + x += dx; + y += dy; +} +``` + +Save your code again and try it in your browser. This works ok, although it appears that the ball is leaving a trail behind it: + +![](https://mdn.mozillademos.org/files/10430/ball-trail.png) + +## Clearing the canvas before each frame + +The ball is leaving a trail because we're painting a new circle on every frame without removing the previous one. Don't worry, because there's a method to clear canvas content: {{domxref("CanvasRenderingContext2D.clearRect()","clearRect()")}}. This method takes four parameters: the x and y coordinates of the top left corner of a rectangle, and the x and y coordinates of the bottom right corner of a rectangle. The whole area covered by this rectangle will be cleared of any content previously painted there. + +Add the following highlighted new line to the `draw()` function: + +```js +function draw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.beginPath(); + ctx.arc(x, y, 10, 0, Math.PI*2); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + x += dx; + y += dy; +} +``` + +Save your code and try again, and this time you'll see the ball move without a trail. Every 10 milliseconds the canvas is cleared, the blue circle (our ball) will be drawn on a given position and the `x` and `y` values will be updated for the next frame. + +## Cleaning up our code + +We will be adding more and more commands to the `draw()` function in the next few articles, so it's good to keep it as simple and clean as possible. Let's start by moving the ball drawing code to a separate function. + +Replace the existing draw() function with the following two functions: + +```js +function drawBall() { + ctx.beginPath(); + ctx.arc(x, y, 10, 0, Math.PI*2); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); +} + +function draw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + drawBall(); + x += dx; + y += dy; +} +``` + +## Compare your code + +You can check the finished code for this article for yourself in the live demo below, and play with it to understand better how it works: + +{{JSFiddleEmbed("https://jsfiddle.net/end3r/3x5foxb1/","","395")}} + +Exercise: try changing the speed of the moving ball, or the direction it moves in. + +## Next steps + +We've drawn our ball and gotten it moving, but it keeps disappearing off the edge of the canvas. In the third chapter we'll explore how to make it [bounce off the walls](/pt-BR/docs/Games/Workflows/Breakout_game_from_scratch/Bounce_off_the_walls). + +{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}} diff --git a/files/pt-br/games/tutorials/index.html b/files/pt-br/games/tutorials/index.html deleted file mode 100644 index 90d1cb0790154f..00000000000000 --- a/files/pt-br/games/tutorials/index.html +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Tutorials -slug: Games/Tutorials -tags: - - Canvas - - Games - - JavaScript - - NeedsTranslation - - TopicStub - - Web - - Workflows -translation_of: Games/Tutorials ---- -This page contains multiple tutorial series that highlight different workflows for effectively creating different types of web games.
- -