diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
commit | 1109132f09d75da9a28b649c7677bb6ce07c40c0 (patch) | |
tree | 0dd8b084480983cf9f9680e8aedb92782a921b13 /files/es/games | |
parent | 4b1a9203c547c019fc5398082ae19a3f3d4c3efe (diff) | |
download | translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.gz translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.bz2 translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.zip |
initial commit
Diffstat (limited to 'files/es/games')
38 files changed, 3907 insertions, 0 deletions
diff --git a/files/es/games/anatomy/index.html b/files/es/games/anatomy/index.html new file mode 100644 index 0000000000..799f31f931 --- /dev/null +++ b/files/es/games/anatomy/index.html @@ -0,0 +1,325 @@ +--- +title: Anatomy of a video game +slug: Games/Anatomy +tags: + - Bucle + - JavaScript + - juegos +translation_of: Games/Anatomy +--- +<div>{{GamesSidebar}}</div><p>{{IncludeSubnav("/en-US/docs/Games")}}</p> + +<div class="summary"> +<p><span class="seoSummary">Este artículo es un vistazo a la anatomía y flujo de trabajo del videojuego medio desde un punto de vista técnico, en términos de cómo debería funcionar el bucle principal. Ayuda a los principiantes del desarrollo moderno de videojuegos a entender lo que hace falta al construir un juego y cómo los estándares web como JavaScript se prestan como herramientas. Los programadores de juegos experimentados que sean novatos en el desarrollo web también se pueden beneficiar.</span></p> +</div> + +<h2 id="Presentar_aceptar_traducir_calcular_repetir">Presentar, aceptar, traducir, calcular, repetir</h2> + +<p>El objetivo de todo videojuego es <strong>presentar</strong> al usuario una situación, <strong>aceptar</strong> su entrada, <strong>traducir</strong> esas señales a acciones, y <strong>calcular</strong> una nueva situación a partir de esos actos. Los juegos están iterando continuamente por estas etapas, una y otra vez, hasta que ocurre alguna condición final (como ganas, perder, o salirse para ir a la cama). De forma poco sorpresiva, este patrón corresponde a cómo se programa el motor de un juego.</p> + +<p>Los detalles dependen del juego.</p> + +<p>Algunos juegos dirigen este ciclo con la entrada del usuario. Imagina que estás desarrollando un juego del tipo <em>"encuentra las diferencias entre estas dos imágenes similares"</em>. Estos juegos <strong>presentan</strong> dos imágenes al usuario; <strong>aceptan</strong> sus clics (o toques); <strong>interpretan</strong> la entrada como éxito, fallo, pausa, interacción del menú, etc; y finalmente, calculan una escena actualizada resultante de esa entrada. El bucle del juego avanza con la entrada del usuario, y se queda en espera hasta que ésta se produce. Esto es más bien un enfoque basado por turnos que no requiere una actualización constante cada frame, sólo cuando el jugador reacciona.</p> + +<p>Otros juegos requieren control sobre cada uno de los más pequeños aspectos posibles. Se aplican los mismos principios de antes, con una ligera variación: cada frame de la animación hace progresar el ciclo, y cualquier cambio en la entrada del usuario se captura en el primer turno disponible. Este modelo de <em>una-vez-por-frame</em> se implementa en algo llamado <strong>bucle principal</strong>. Si el bucle de tu juego está basado en tiempo, éste será una ley a la que se tendrán que atener tus simulaciones.</p> + +<p>Pero puede no necesitar de un control <em>por-frame</em>. El bucle de tu juego podría ser similar al ejemplo de <em>encuentra las diferencias</em>, y basarse en las entradas del usuario. Podría necesitar tanto entradas como tiempo simulado. Podría incluso estar totalmente basado en algo diferente.</p> + +<p>Por suerte, el JavaScript moderno (que se describe en las siguientes secciones) hace sencillo desarrollar un bucle principal eficiente, tipo <em>ejecutar-una-vez-por-frame</em>. Por supuesto, estará tan optimizado como tú lo hagas. Si algo parece que debería ir acoplado a un evento más infrecuente, suele ser una buena idea (aunque no siempre) sacarlo fuera del bucle principal.</p> + +<h2 id="Crear_un_bucle_principal_en_JavaScript">Crear un bucle principal en JavaScript</h2> + +<p>JavaScript funciona mejor con eventos y funciones callback. Los navegadores modernos se esfuerzan en invocar los métodos sólo en cuanto se necesita, y reposar (o hacer otras tareas) en los intervalos. Es una idea excelente añadir tu código a los momentos apropiados. Considera si tu función necesita de verdad ser invocada en un intervalo estricto de tiempo, a cada frame, o sólo cuando haya ocurrido alguna otra cosa. Especificándole al navegador cuándo tiene que ser invocada tu función le permite optimizarla. Además, probablemente haga tu trabajo más fácil.</p> + +<p>Algún código necesita ejecutarse frame a frame, así que ¿por qué añadir esa función a cualquier otra cosa que al planificador de redibulado del navegador? En la web, <code>{{ domxref("window.requestAnimationFrame()") }} </code>será la base de la mayoría de bucles principales frame-a-frame bien programados. Al invocarla, hay que pasarle una función callback. Esa función callback se ejecutará en el momento apropiado antes del próximo redibujado. Aquí hay un ejemplo de un bucle principal sencillo:</p> + +<pre>window.main = function () { + window.requestAnimationFrame( main ); + + // Lo que sea que tenga que hacer tu bucle principal +}; + +main(); // Empezar el ciclo</pre> + +<p><strong>Note</strong>: In each of the <code>main()</code> methods discussed here, we schedule a new <code>requestAnimationFrame</code> before performing our loop contents. That is not by accident and it is considered best practice. Calling the next <code>requestAnimationFrame</code> early ensures the browser receives it on time to plan accordingly even if your current frame misses its VSync window.</p> + +<p>The above chunk of code has two statements. The first statement creates a function as a global variable called <code>main()</code>. This function does some work and also tells the browser to call itself next frame with <code>window.requestAnimationFrame()</code>. The second statement calls the <code>main()</code> function, defined in the first statement. Because <code>main()</code> is called once in the second statement and every call of it places itself in the queue of things to do next frame, <code>main()</code> is synchronized to your framerate.</p> + +<p>Of course this loop is not perfect. Before we discuss ways to change it, let us discuss what it already does well.</p> + +<p>Timing the main loop to when the browser paints to the display allows you to run your loop as frequently as the browser wants to paint. You are given control over each frame of animation. It is also very simple because <code>main()</code> is the only function getting looped. A First Person Shooter (or a similar game) presents a new scene once every frame. You cannot really get more smooth and responsive than that.</p> + +<p>But do not immediately assume animations require frame-by-frame control. Simple animations can be easily performed, even GPU-accelerated, with CSS animations and other tools included in the browser. There are a lot of them and they will make your life easier.</p> + +<h2 id="Building_a_better_main_loop_in_Javascript">Building a <em>better</em> main loop in Javascript</h2> + +<p>There are two obvious issues with our previous main loop: <code>main()</code> pollutes the <code>{{ domxref("window") }}</code> object (where all global variables are stored) and the example code did not leave us with a way to <em>stop</em> the loop unless the whole tab is closed or refreshed. For the first issue, if you want the main loop to just run and you do not need easy (direct) access to it, you could create it as an Immediately-Invoked Function Expression (IIFE).</p> + +<pre>/* +* 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 +})();</pre> + +<p>When the browser comes across this IIFE, it will define your main loop and immediately queue it for the next frame. It will not be attached to any object and <code>main</code> (or <code>main()</code> for methods) will be a valid unused name in the rest of the application, free to be defined as something else.</p> + +<p>Note: In practice, it is more common to prevent the next requestAnimationFrame() with an if-statement, rather than calling cancelAnimationFrame().</p> + +<p>For the second issue, stopping the main loop, you will need to cancel the call to <code>main()</code> with <code>{{ domxref("window.cancelAnimationFrame()") }}</code>. You will need to pass <code>cancelAnimationFrame()</code> the ID token given by <code>requestAnimationFrame()</code> when it was last called. Let us assume that your game's functions and variables are built on a namespace that you called <code>MyGame</code>. Expanding our last example, the main loop would now look like:</p> + +<pre>/* +* 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 +})();</pre> + +<p>We now have a variable declared in our <code>MyGame</code> namespace, which we call <code>stopMain</code>, that contains the ID returned from our main loop's most recent call to <code>requestAnimationFrame()</code>. At any point, we can stop the main loop by telling the browser to cancel the request that corresponds to our token.</p> + +<pre>window.cancelAnimationFrame( MyGame.stopMain );</pre> + +<p>The key to programming a main loop, in JavaScript, is to it attach to whatever event should be driving your action and pay attention to how the different systems involved interplay. You may have multiple components driven by multiple different types of events. This feels like unnecessary complexity but it might just be good optimization (not necessarily, of course). The problem is that you are not programming a typical main loop. In Javascript, you are using the browser's main loop and you are trying to do so effectively.</p> + +<h2 id="Building_a_more_optimized_main_loop_in_JavaScript">Building a <em>more</em> <em>optimized</em> main loop in JavaScript</h2> + +<p>Ultimately, in JavaScript, the browser is running its own main loop and your code exists in some of its stages. The above sections describe main loops which try not to wrestle away control from the browser. These main methods attach themselves to <code>window.requestAnimationFrame()</code>, which asks the browser for control over the upcoming frame. It is up to the browser how to relate these requests to their main loop. The <a href="http://www.w3.org/TR/animation-timing/">W3C spec for requestAnimationFrame</a> does not really define exactly when the browsers must perform the requestAnimationFrame callbacks. This can be a benefit because it leaves browser vendors free to experiment with the solutions that they feel are best and tweak it over time.</p> + +<p>Modern versions of Firefox and Google Chrome (and probably others) <em>attempt</em> to connect <code>requestAnimationFrame</code> callbacks to their main thread at the very beginning of a frame's timeslice. The browser's main thread thus <em>tries</em> to look like the following:</p> + +<ol> + <li>Start a new frame (while the previous frame is handled by the display).</li> + <li>Go through the list of <code>requestAnimationFrame</code> callbacks and invoke them.</li> + <li>Perform garbage collection and other per-frame tasks when the above callbacks stop controlling the main thread.</li> + <li>Sleep (unless an event interrupts the browser's nap) until the monitor is ready for your image (<a href="http://www.techopedia.com/definition/92/vertical-sync-vsync">VSync</a>) and repeat.</li> +</ol> + +<p>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.</p> + +<p>While we are on the topic of budgeting time, many web browsers have a tool called <em>High Resolution Time</em>. 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 <code>navigationStart</code> (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 <code>{{ domxref("DOMHighResTimeStamp") }}</code> but, for all intents and purposes, consider it a floating point number.</p> + +<p><strong>Note</strong>: 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.</p> + +<p>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 <code>window.performance.now()</code> and store the result as a variable.</p> + +<pre>var tNow = window.performance.now(); +</pre> + +<p>Back to the topic of the main loop. You will often want to know when your main function was invoked. Because this is common, <code>window.requestAnimationFrame()</code> always provides a <code>DOMHighResTimeStamp</code> to callbacks as an argument when they are executed. This leads to another enhancement to our previous main loops.</p> + +<pre>/* +* 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 +})();</pre> + +<p>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.</p> + +<h2 id="It_is_decision..._time">It is decision... time</h2> + +<p>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.</p> + +<p><em><strong>Note</strong>: </em>Changing how your main loop deals with time is a debugging nightmare, everywhere. Think about your needs, carefully, before working on your main loop.</p> + +<h3 id="What_most_browser_games_should_look_like">What most browser games should look like</h3> + +<p>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.</p> + +<pre>/* +* 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 +})();</pre> + +<p>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:</p> + +<ul> + <li>Each frame of animation accounts for user input.</li> + <li>No frame needs to be extrapolated (guessed) because each draw has its own update.</li> + <li>Simulation systems can basically assume that each full update is ~16ms apart.</li> + <li>Giving the user control over quality settings would be a nightmare.</li> + <li>Different monitors input at different rates: 30 FPS, 75 FPS, 100 FPS, 120 FPS, 144 FPS, etc.</li> + <li>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.)</li> +</ul> + +<h3 id="Other_ways_to_handle_variable_refresh_rate_needs">Other ways to handle variable refresh rate needs</h3> + +<p>Other methods of tackling the problem exist.</p> + +<p>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:</p> + +<ul> + <li>Draw on <code>requestAnimationFrame</code> and update on a {{ domxref("window.setInterval") }} or {{ domxref("window.setTimeout") }}. + + <ul> + <li>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.)</li> + </ul> + </li> + <li>Draw on <code>requestAnimationFrame</code> and update on a <code>setInterval</code> or <code>setTimeout</code> in a <a href="/en-US/docs/Web/Guide/Performance/Using_web_workers">Web Worker</a>. + <ul> + <li>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.</li> + </ul> + </li> + <li>Draw on <code>requestAnimationFrame</code> and use it to poke a Web Worker containing the update method with the number of ticks to compute, if any. + <ul> + <li>This sleeps until <code>requestAnimationFrame</code> 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 <em>starting</em> each update will be blocked until the browser decides to fire rAF callbacks.</li> + </ul> + </li> +</ul> + +<p>Each of these methods have similar tradeoffs:</p> + +<ul> + <li>Users can skip rendering frames or interpolate extra ones depending on their performance.</li> + <li>You can count on all users updating non-cosmetic variables at the same constant frequency minus hiccups.</li> + <li>Much more complicated to program than the basic loops we saw earlier.</li> + <li>User input is completely ignored until the next update (even if the user has a fast device).</li> + <li>The mandatory interpolation has a performance penalty.</li> +</ul> + +<p>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).</p> + +<p><em>Note: This example, specifically, is in need of technical review.</em></p> + +<pre>/* +* 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 +})();</pre> + +<p>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 <a href="http://blog.artillery.com/2012/10/browser-garbage-collection-and-framerate.html">adjust their rate of garbage generation</a> to optimize garbage collection. Obviously, cleaning up resources is not time sensitive (especially if tidying is more disruptive than the garbage itself).</p> + +<p>This may also apply to some of your own tasks. Those are good candidates to throttle when available resources become a concern.</p> + +<h2 id="Summary">Summary</h2> + +<p>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.</p> + +<p>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 <code>requestAnimationFrame</code> 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:</p> + +<ul> + <li>Consider the gap "a pause" and skip the time. + <ul> + <li>You can probably see how this is problematic for most multiplayer games.</li> + </ul> + </li> + <li>You can simulate the gap to catch up. + <ul> + <li>This can be a problem for long drops and/or complex updates.</li> + </ul> + </li> + <li>You can recover the game state from a peer or the server. + <ul> + <li>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.</li> + </ul> + </li> +</ul> + +<p>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.</p> diff --git a/files/es/games/herramients/asm.js/index.html b/files/es/games/herramients/asm.js/index.html new file mode 100644 index 0000000000..bd41ed70a3 --- /dev/null +++ b/files/es/games/herramients/asm.js/index.html @@ -0,0 +1,29 @@ +--- +title: asm.js +slug: Games/Herramients/asm.js +tags: + - JavaScript + - asm.js +translation_of: Games/Tools/asm.js +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<div class="summary"> +<p><span class="seoSummary"><a href="http://asmjs.org/">Asm.js</a> es un subconjunto de JavaScript que es altamente optimizable. Este artículo analiza exactamente lo que está permitido en el subconjunto asm.js, las mejoras que confiere, donde y cómo puedo utilizarlo, y otros recursos y ejemplos.</span></p> +</div> + +<h2 id="¿Qué_es_asm.js_exactamente">¿Qué es asm.js exactamente?</h2> + +<p>Es un subconjunto muy pequeño y estricto de JavaScript que solo permite cosas como `while`, `if`, números, funciones con nombres de nivel superior y otras construcciones simples. No permite objetos, cadenas, cierres y básicamente cualquier cosa que requiera una asignación de la pila. El código asm.js se parece al lenguaje de programación "C" en muchos aspectos, pero es JavaScript completamente válido que se ejecuta en todos los motores actuales. Impulsa los motores JS para optimizar este tipo de código, y le da a los compiladores como Emscripten una definición clara de qué tipo de código generar. A continuación, mostraremos cómo es un código asm.js y explicaremos cómo le ayuda y cómo puede usarlo.</p> + +<p>Este subconjunto de JavaScript ya está altamente optimizado en muchos motores de JavaScript que utilizan técnicas de compilación Just-In-Time (JIT) sofisticadas. Sin embargo, al definir un estándar tan explícito, podemos trabajar en la optimización de este tipo de código aún más y obtener el máximo rendimiento posible. Facilita la colaboración en múltiples motores JS porque es fácil de comparar. La idea es que este tipo de código se ejecute muy rápido en cada motor, y si no lo hace, es que hay un error y es un claro mensaje de que los motores deben optimizarse.</p> + +<p>También facilita la tarea de las personas que escriben compiladores que desean generar código de alto rendimiento en la web. Pueden consultar las especificaciones de asm.js para saber que se ejecutará rápidamente si se adhieren a los patrones de asm.js. Emscripten, un compilador de C/C++ a JavaScript, genera código asm.js para que funcione con un rendimiento casi nativo en varios navegadores.</p> + +<p>Además, si un motor elige reconocer especialmente código asm.js, se pueden realizar aún más optimizaciones. Firefox es el único navegador que hace esto ahora.</p> + +<h2 id="Resumen_del_lenguaje_asm.js">Resumen del lenguaje asm.js</h2> + +<p>asm.js es un lenguaje de programación intermedio. Tiene una tasa de rendimiento muy predecible porque está limitada a un subconjunto extremadamente restringido de JavaScript que proporciona solo enteros, números en coma flotante, aritmética, llamadas a funciones y accesos de pila de tipo estricto. Las características de rendimiento son más cercanas al código nativo que las de JavaScript estándar. El uso del subconjunto de JavaScript asm.js ya es compatible con los principales navegadores web. Como asm.js se ejecuta en un navegador, depende en gran medida del navegador y del hardware.</p> diff --git a/files/es/games/herramients/index.html b/files/es/games/herramients/index.html new file mode 100644 index 0000000000..e09812b07d --- /dev/null +++ b/files/es/games/herramients/index.html @@ -0,0 +1,46 @@ +--- +title: Herramientas para desarrolladores de juegos +slug: Games/Herramients +tags: + - NeedsContent + - NeedsTranslation + - aplicaciones + - juegos +translation_of: Games/Tools +--- +<div>{{GamesSidebar}}</div><div class="summary"> + <p><span class="seoSummary">En esta pagina puedes encontrar enlaces a nuestros articulos de desarrollo de juegos, que enventualmente apuenta a cubrir frameworks, compiladores y herramientas de depuracion.</span></p> +</div> +<dl> + <dt> + <a href="/en-US/docs/Games/Tools/asm.js">asm.js</a></dt> + <dd> + asm.js es una subconjunto muy limitado del lenguaje Javascript que puede ser en gran medida optimizado y correr en modo compilador <em>ahead-of-time</em> (AOT) para un mejor rendimiento que el rendimiento tipico de JavaScript. Este es, por supuesto, bueno para juegos.</dd> + <dt> + <a href="https://github.com/kripken/emscripten/wiki" title="https://github.com/kripken/emscripten/wiki">Emscripten</a></dt> + <dd> + <p>Un compilador <em>LLVM</em> a JavaScript; con Emscripten, tu puedes compilar C++ y otros lenguajes que se pueden compilar a<em> LLVM</em> y luego a JavaScript de alto rendimiento. Es una buena herramiente para portar aplicaciones a la Web! Aqui hay un <a href="https://github.com/kripken/emscripten/wiki/Tutorial">util tutorial sobre Emscripten</a> disponible en la wiki. Estamos <a href="/en-US/docs/Emscripten">mirando cubrir Emscripten en su propia seccion de MDN</a>.</p> + </dd> + <dt> + <a href="https://addons.mozilla.org/en-us/firefox/addon/gecko-profiler/" title="https://addons.mozilla.org/en-us/firefox/addon/gecko-profiler/">Gecko profiler</a></dt> + <dd> + <em>Gecko profiler</em> es una extension que te permite perfilar tu codigo para ayudar donde tienes errores de rendimiento, asi puedes hacer que tu juego corra a velocidad maxima.</dd> + <dt> + <a href="/en-US/docs/Games/Tools/Engines_and_tools">Motores de juegos y herramientas</a></dt> + <dd> + Una lista de motores, plantillas y tecnologias utiles para los desarrolladores de juegos.</dd> + <dt> + <a href="/en-US/docs/Mozilla/Projects/Shumway">Shumway</a></dt> + <dd> + <em>Shumway</em> es un renderizador para Adobe Flash construido completamente con JavaScript, WebGL, entre otros, haciendo una brecha entre Flash y los estandares Web. Este articulo muestra como hacer uso de Shumway y como contribuir arreglos y errores al proyecto.</dd> + <dt> + Cadena de herramientas para desarrollar y depurar juegos</dt> + <dd> + Como difieren de depurar una Web app normal? Que herramientas especializadas estan disponibles? Un lote de esto va a ser cubierto por Will en <a href="/en-US/docs/Tools">herramientas</a>, pero aqui te vamos a proveer una cadena de herramientas practicas para depurar juegos con links a las cosas de Will: + <ul> + <li>Basic tools overview</li> + <li><a href="/en-US/docs/Tools/Shader_Editor">Shader editor</a></li> + <li>Performance tools (still in production, estimated early 2014)</li> + </ul> + </dd> +</dl> diff --git a/files/es/games/index.html b/files/es/games/index.html new file mode 100644 index 0000000000..29eba5c52f --- /dev/null +++ b/files/es/games/index.html @@ -0,0 +1,74 @@ +--- +title: Desarrollo de Videojuegos +slug: Games +tags: + - Apps + - Games + - NeedsContent + - TopicStub + - aplicaciones + - juegos +translation_of: Games +--- +<div>{{GamesSidebar}}</div> + +<div class="summary"> +<p>Jugar es una de las actividades más populares en las computadoras. Constantemente aparecen nuevas tecnologías para desarrollar juegos mejores y más potentes que pueden iniciarse en cualquier navegador web compatible con los estándares.</p> +</div> + +<div class="column-container"> +<div class="column-half"> +<h2 id="Introducción_de_los_juegos_para_la_Web">Introducción de los juegos para la Web</h2> + +<dl> + <dt><a href="/en-US/docs/Games/Introduction" title="/en-US/docs/Games/Introduction">Introducción al desarrollo de juegos para la Web</a></dt> + <dd>Una introducción a las tecnologías útiles para los desarrolladores de juegos y cómo iniciarse a desarrollar juegos usando tecnologías Web. Este artículo también examina el negocio de crear juegos para la Web.</dd> + <dt><a href="/en-US/docs/Games/Anatomy_of_a_vIdeo_game">Anatomía de un videojuego</a></dt> + <dd>¿Qué es un videojuego en realidad?. Aquí hay ciertas partes que son comunes entre los juegos (aunque no lo parezca). Este artículo busca explicar conceptos como los <em>main loops</em> en un contexto completamente general. Cuando se enfoca lo hace hacia los estándares Web.</dd> + <dt><a href="/en-US/docs/Web/Apps/Developing/Games/Special_considerations">Consideraciones especiales para desarrolladores de videojuegos</a></dt> + <dd>Este artículo del Centro de Aplicaciones examina brevemente las cosas que necesitas considerar específicamente cuando intentas crear un juego que correrá como una <em>open web app</em>.</dd> +</dl> + +<h2 id="Recursos_externos">Recursos externos</h2> + +<dl> + <dt><a href="http://buildnewgames.com/">Build New Games</a></dt> + <dd>Un sitio colaborativo con un largo número de tutoriales de desarrollo de Open Web Game.</dd> + <dt><a href="http://creativejs.com/">Creative JS</a></dt> + <dd>Un colección impresionante de técnicas y experimentos de JavaScript , No específica para los juegos, pero útil.</dd> + <dt><a href="http://gameprogrammingpatterns.com/">Game programming patterns</a></dt> + <dd>Un libro en línea, escrito por Bob Nystrom, que discute patrones de programación en el contexto de desarrollo de videojuegos con el objetivo de ayudar a los desarrolladores de videojuegos a producir código más efectivo y eficiente.</dd> + <dt><a href="http://blog.artillery.com/">Artillery blog</a></dt> + <dd>La compañía de videojuegos HTML5 Artillery tiene algunos artículos útiles en su blog.</dd> +</dl> +</div> + +<div class="column-half"> +<h2 id="Temas_de_desarrollo_de_Videojuegos">Temas de desarrollo de Videojuegos</h2> + +<dl> + <dt><a href="/en-US/docs/Games/Tools">Herramientas</a></dt> + <dd>Esta sección cubre las herramientas disponibles para facilitar la creación de experiencias de juego eficaces en la Web, como los frameworks, compiladores, como Emscripten y herramientas de depuración. Explica el núcleo de conceptos detrás de cada uno dándote una base sólida para trabajar.</dd> + <dt><a href="/en-US/docs/Games/Techniques">Técnicas</a></dt> + <dd>Esta sección contiene muchos artículos tratando técnicas esenciales para el desarrollo de videojuegos, como la física, detección de colisión, animación, 3D, guardado de datos, y mucho más.</dd> + <dt><a href="/en-US/docs/Games/Workflows">Flujo de trabajo</a></dt> + <dd>Esta sección incluye múltiples casos de estudio, obteniendo las herramientas básicas y técnicas cubiertas por encima y aplicar éstas a la creación de videojuegos asombrosos. Hay algo para ti aquí, si eres un desarrollador Web experimentado queriendo escribir videojuegos 2D o 3D, un desarrollador de C++ buscando portar juegos nativos a la Web o un desarrollador móvil buscando ayuda para escribir mejores juegos móviles.</dd> +</dl> + +<h2 id="Demos">Demos</h2> + +<dl> + <dt><a href="/en-US/demos/detail/bananabread" title="/en-US/demos/detail/bananabread">BananaBread</a></dt> + <dd>Un multijugador <em>shooter</em> 3D de primera persona desarrollado usando Emscripten, WebGL, y WebRTC.</dd> + <dt><a href="/en-US/docs/Web/Apps/Tutorials/Games/Serpent_game">Serpent game</a></dt> + <dd>Esta Open Web App es un juego simple basado en el clásico juego "Snake". Usa la plantilla <a class="external" href="https://github.com/mozilla/WebGameStub">WebGameStub</a>, que puede ayudarte a crear rápidamente un juego para la Web.</dd> + <dt><a href="https://hacks.mozilla.org/2013/12/monster-madness-creating-games-on-the-web-with-emscripten/">Monster Madness</a></dt> + <dd>Un juego en línea multijugador <em>shooter</em> basado en WebGL y asm.js, desarrollado por Nom Nom Games y Trendy entertainment.</dd> + <dd></dd> +</dl> +</div> +</div> + +<div class="note"> +<p><strong><span id="result_box" lang="es"><span class="hps">Tenga en cuenta que</span> <span class="hps">estamos manteniendo</span> <span class="hps">un registro de</span> <span class="hps">los trabajos en curso</span> <span class="hps">sobre la documentación</span></span> en nuesta <strong>página</strong> <a href="/en-US/docs/Games/Doc_Status">Estado de la Documentación de Desarrollo de Videojuegos</a>. Si quieres ayudar a contribuir <strong><strong>para la documentación de desarrollo de videojuegos, <strong><strong>por favor, ¡busque en esta <strong><strong>página <strong><strong>para ver qué trabajo necesita hacerse!.</strong></strong></strong></strong></strong></strong></strong></strong></strong></p> +</div> diff --git a/files/es/games/introduccion/index.html b/files/es/games/introduccion/index.html new file mode 100644 index 0000000000..b19ea1a61e --- /dev/null +++ b/files/es/games/introduccion/index.html @@ -0,0 +1,167 @@ +--- +title: Introduccion para desarrollo de juegos para la Web +slug: Games/Introduccion +tags: + - Firefox OS + - juegos + - moviles +translation_of: Games/Introduction +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<div>La Web rapidamente se ha convertido en una plataforma viable no solo para crear impresionantes juegos de alta calidad, sino también para distruibuirlos.</div> + +<div></div> + +<div>El rango de juegos que pueden ser creados está a la par tanto de los juegos de escritorio como de SO nativos (Android, iOS). Con tecnologias Web modernas y un navegador reciente es totalmente posible hacer juegos de primera categoria para la Web. Y no estamos hablando sobre simples juegos de cartas o juegos sociales multijugadores que en tiempos anteriores se podian hacer con Flash®. Estamos hablando sobre juegos 3D <em>shooters</em> de accion, RPGs, y más. Gracias a las masivas mejoras de rendimiento en <a href="/en-US/docs/JavaScript" title="/en-US/docs/JavaScript">JavaScript</a> con tecnologia de compilación <em>just-in-time</em> y nuevas APIs, se pueden construir juegos que pueden correr en el navegador (o en dispositivos <a href="/en-US/docs/HTML/HTML5" title="/en-US/docs/HTML/HTML5">HTML5</a> como <a href="/en-US/docs/Mozilla/Firefox_OS" title="/en-US/docs/Mozilla/Firefox_OS">Firefox OS</a>) sin problemas.</div> + +<h2 id="La_plataforma_de_juegos_HTML5">La plataforma de juegos HTML5</h2> + +<p>Puedes pensar en la Web como una mejor opción de plataforma para desarrollar tu juego. Como nos gusta decir, "la Web es la plataforma". Hechemos un vistazo al nucleo de la plataforma Web:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Funcion</th> + <th scope="col">Tecnología</th> + </tr> + </thead> + <tbody> + <tr> + <td><strong>Audio</strong></td> + <td><a href="/es/docs/Web_Audio_API" title="/en-US/docs/Web_Audio_API">Web Audio API</a></td> + </tr> + <tr> + <td><strong>Graficos</strong></td> + <td><a href="/es/docs/WebGL" title="/en-US/docs/WebGL">WebGL</a> (<a href="http://www.khronos.org/opengles/" title="http://www.khronos.org/opengles/">OpenGL ES</a> 2.0)</td> + </tr> + <tr> + <td><strong>Entrada</strong></td> + <td><a href="/es/docs/DOM/Touch_events" title="/en-US/docs/DOM/Touch_events">Touch events</a>, <a href="/en-US/docs/API/Gamepad/Using_Gamepad_API" title="/en-US/docs/API/Gamepad/Using_Gamepad_API">Gamepad API</a>, device sensors, <a href="/es/docs/Web/API/WebRTC_API" title="/en-US/docs/WebRTC">WebRTC</a>, <a href="/es/docs/DOM/Using_fullscreen_mode" title="/en-US/docs/DOM/Using_fullscreen_mode">Full Screen API</a>, <a href="/es/docs/WebAPI/Pointer_Lock" title="/en-US/docs/WebAPI/Pointer_Lock">Pointer Lock API</a></td> + </tr> + <tr> + <td><strong>Lenguaje</strong></td> + <td><a href="/es/docs/JavaScript" title="/en-US/docs/JavaScript">JavaScript</a> (o C/C++ usando <a href="https://github.com/kripken/emscripten/wiki" title="https://github.com/kripken/emscripten/wiki">Emscripten</a> para compilar a JavaScript)</td> + </tr> + <tr> + <td><strong>Redes</strong></td> + <td><a href="/es/docs/WebRTC" title="/en-US/docs/WebRTC">WebRTC</a> and/or <a href="/es/docs/WebSockets" title="/en-US/docs/WebSockets">WebSockets</a></td> + </tr> + <tr> + <td><strong>Almacenamiento</strong></td> + <td><a href="/es/docs/IndexedDB" title="/en-US/docs/IndexedDB">IndexedDB</a> o la "nube"</td> + </tr> + <tr> + <td><strong>Web</strong></td> + <td><a href="/es/docs/HTML" title="/en-US/docs/HTML">HTML</a>, <a href="/es/docs/CSS" title="/en-US/docs/CSS">CSS</a>, <a href="/es/docs/SVG" title="/en-US/docs/SVG">SVG</a>, <a href="/es/docs/Social_API" title="/en-US/docs/Social_API">Social API</a> (y mucho más!)</td> + </tr> + </tbody> +</table> + +<h2 id="El_caso_de_Exito">El caso de Exito</h2> + +<div>Como un desarrollador de juegos, de forma individual o como un gran studio de juegos, tu quieres por que tiene sentido apuntar a la Web como tu práximo proyecto de juego. Veamos como la Web puede ayudarte.</div> + +<div></div> + +<ol> + <li> + <div><span class="notranslate">El alcance de la Web es enorme;</span> <span class="notranslate"> está en todas partes.</span> <span class="notranslate"> Los juegos construidos con HTML5 funcionan en smartphones, tablets, PCs y Smart TVs.</span></div> + </li> + <li><span class="notranslate">Se mejoran la comercialización y la detección.</span> <span class="notranslate"> No estás limitado a promocionar tu aplicación en la tienda de aplicaciones de otra persona.</span> <span class="notranslate"> En su lugar, puede anunciar y promover su juego en toda la Web, así como en otros medios, aprovechando la inherente capacidad de enlace y capacidad de compartir de la Web para llegar a nuevos clientes.</span></li> + <li><span class="notranslate">Usted tiene control donde importa: Pagos.</span> <span class="notranslate"> Usted no tiene que entregar más del 30% de sus ingresos a otra persona sólo porque su juego está en su ecosistema.</span> <span class="notranslate"> En su lugar, cargue lo que quiera y utilice cualquier servicio de procesamiento de pagos que le guste.</span></li> + <li><span class="notranslate">Una vez más con más control, puedes actualizar tu juego cuando quieras.</span> <span class="notranslate"> No hay que esperar sin aliento para la aprobación, mientras que alguien oculto dentro de otra empresa decide si su solución de error crítico se enviará hoy o mañana.</span></li> + <li><span class="notranslate">¡Controla tus análisis!</span> <span class="notranslate"> En lugar de confiar en otra persona para tomar todas las decisiones sobre qué analítica necesita, puede recoger su propia o elegir la tercera parte que más le guste para recopilar información sobre sus ventas y el alcance de su juego.</span></li> + <li><span class="notranslate">Usted consigue manejar su relación del cliente más de cerca, en su propia manera.</span> <span class="notranslate"> No más tener comentarios de los clientes filtrados a través de los mecanismos limitados de una tienda de aplicaciones.</span> <span class="notranslate"> Involucrarse con sus clientes de la manera que desee, sin un intermediario.</span></li> + <li><span class="notranslate">Sus jugadores pueden jugar su juego en cualquier lugar, en cualquier momento.</span> <span class="notranslate"> Debido a que la Web es omnipresente, sus clientes pueden comprobar el estado de su juego en sus teléfonos, tabletas, computadoras portátiles domésticas, sus escritorios de trabajo o cualquier otra cosa.</span></li> +</ol> + +<h2 class="highlight-spanned" id="Tecnologías_web_para_desarrolladores_de_juegos_Edit"><span class="highlight-span"><span class="notranslate">Tecnologías web para desarrolladores de juegos</span> </span><a class="button section-edit only-icon" href="https://developer.mozilla.org/es/docs/Games/Introduccion$edit#Web_technologies_for_game_developers" rel="nofollow, noindex"><span>Edit</span></a></h2> + +<p><span class="notranslate">Para la gente de tecnología, vamos a cavar en las API que la Web aporta a la mesa que atienden a los desarrolladores de juegos. Esta es una lista exhaustiva para darle una muestra de lo que la Web puede hacer por usted:</span></p> + +<div class="twocolumns"> +<dl> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web/API/Fullscreen_API" title="/ Es-ES / docs / DOM / Using_fullscreen_mode">API de pantalla completa</a></span></dt> + <dd><span class="notranslate">Esta sencilla API permite que su juego se haga cargo de toda la pantalla, sumergiendo al jugador en acción.</span></dd> + <dt><span class="notranslate"><a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/en-US/docs/API/Gamepad/Using_Gamepad_API&usg=ALkJrhhV6r_1Mvu6SOpsoQgHhJElOIWX7g" title="/ Es-ES / docs / API / Gamepad / Using_Gamepad_API">API de Gamepad</a></span></dt> + <dd><span class="notranslate">Si desea que sus usuarios puedan usar gamepads u otros controladores de juego para trabajar su juego, necesitará esta API.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web/HTML" title="/ Es-US / docs / HTML">HTML</a> y <a href="https://developer.mozilla.org/es/docs/Web/CSS" title="/ Es-ES / docs / CSS">CSS</a></span></dt> + <dd><span class="notranslate">Juntas, estas dos tecnologías le permiten construir, diseñar y diseñar la interfaz de usuario de su juego.</span> <span class="notranslate"> Parte de HTML es el elemento <a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/es/docs/HTML/Elemento/canvas&usg=ALkJrhhVmlLNFuUPIZvH_teRdETdIbBebw" title="Este artículo aún no se ha escrito. ¡Considere contribuir!"><code><canvas></code></a> , que proporciona una forma de hacer gráficos 2D.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web/HTML/Elemento/audio" title="/ Es-ES / docs / HTML / Elemento / audio">Audio HTML</a></span></dt> + <dd><span class="notranslate">El elemento <a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/es/docs/HTML/Elemento/audio&usg=ALkJrhjtX6Px9Gu7gkcd0fdLB1gVGNTqZQ" title="Este artículo aún no se ha escrito. ¡Considere contribuir!"><code><audio></code></a> te permite reproducir fácilmente efectos de sonido y música sencillos.</span> <span class="notranslate"> Si sus necesidades están más involucradas, echa un vistazo a la <a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/en-US/docs/Web_Audio_API&usg=ALkJrhgCQeHzpAri8qJ00kmc9rNqYXZzHg" title="/ Es-ES / docs / Web_Audio_API">API de audio web</a> para obtener potencia de procesamiento de audio real.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/IndexedDB-840092-dup" title="/ Es-US / docs / IndexedDB">IndexedDB</a></span></dt> + <dd><span class="notranslate">Una poderosa API de almacenamiento de datos para mantener los datos del usuario en su propio ordenador o dispositivo.</span> <span class="notranslate"> Una gran manera de guardar el estado del juego y otra información localmente para que no tenga que ser descargado cada vez que sea necesario.</span> <span class="notranslate"> También es útil para ayudar a que su juego sea jugable incluso cuando el usuario no está conectado a la Web (por ejemplo, cuando están atrapados en un avión durante horas y horas ...).</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web/JavaScript" title="/ Es-ES / docs / JavaScript">JavaScript</a></span></dt> + <dd><span class="notranslate">JavaScript, el lenguaje de programación utilizado en la Web, está ardiendo rápido en los navegadores modernos y cada vez más rápido.</span> <span class="notranslate"> Usa su poder para escribir el código para tu juego, o mira usando tecnologías como <a class="external external-icon" href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://github.com/kripken/emscripten/wiki&usg=ALkJrhhAf0czxz7h2rDyV_JV7PSlfap69g" title="Https://github.com/kripken/emscripten/wiki">Emscripten</a> o <a class="external external-icon" href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=http://asmjs.org/spec/latest/&usg=ALkJrhh9WXUvKAZKrbEzyZxr8nWhmVHYfw" title="Http://asmjs.org/spec/latest/">Asm.js</a> para portar fácilmente tus juegos existentes.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/WebAPI/Pointer_Lock" title="/ Es-ES / docs / WebAPI / Pointer_Lock">API de bloqueo de puntero</a></span></dt> + <dd><span class="notranslate">La API de Bloqueo de Puntero le permite bloquear el ratón u otro dispositivo señalador dentro de la interfaz de su juego para que en lugar de posicionamiento absoluto del cursor reciba deltas de coordenadas que le den medidas más precisas de lo que el usuario está haciendo e impide que el usuario envíe accidentalmente su entrada En algún otro lugar, por lo tanto falta una acción importante.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web/SVG" title="/ Es-ES / docs / SVG">SVG</a> (Gráficos Vectoriales Escalables)</span></dt> + <dd><span class="notranslate">Permite crear gráficos vectoriales que se escalan sin problemas, independientemente del tamaño o la resolución de la pantalla del usuario.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Vectores_tipados" title="/ Es-US / docs / JavaScript / Typed_arrays">Matrices Arrays</a></span></dt> + <dd><span class="notranslate">Los arrays tipados en JavaScript le dan acceso a datos binarios sin procesar desde JavaScript;</span> <span class="notranslate"> Esto le permite manipular texturas GL, datos de juego, o cualquier otra cosa, incluso si no está en un formato JavaScript nativo.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web_Audio_API" title="/ Es-ES / docs / Web_Audio_API">API de audio web</a></span></dt> + <dd><span class="notranslate">Esta API para controlar la reproducción, síntesis y manipulación de audio a partir de código JavaScript le permite crear efectos de sonido impresionantes, así como jugar y manipular música en tiempo real.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web/API/WebGL_API" title="/ Es-ES / docs / WebGL">WebGL</a></span></dt> + <dd><span class="notranslate">Permite crear gráficos 3D (y 2D) acelerados por hardware de alto rendimiento a partir del contenido Web.</span> <span class="notranslate"> Se trata de una implementación Web de <a class="external external-icon" href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=http://www.khronos.org/opengles/&usg=ALkJrhj7Pnj9FaaR-5oxI5CJw3N2i05Ngw" title="Http://www.khronos.org/opengles/">OpenGL ES</a> 2.0.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web/API/WebRTC_API" title="/ En-US / docs / WebRTC">WebRTC</a></span></dt> + <dd><span class="notranslate">La API WebRTC (Comunicaciones en tiempo real) le permite controlar los datos de audio y vídeo, incluyendo la teleconferencia y la transmisión de otros datos de la aplicación entre dos usuarios.</span> <span class="notranslate"> ¿Quieren que sus jugadores puedan hablar entre sí mientras explotan monstruos?</span> <span class="notranslate"> Esta es la API para usted.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web/API/WebSockets_API" title="/ Es-ES / docs / WebSockets">WebSockets</a></span></dt> + <dd><span class="notranslate">La API de WebSocket le permite conectar su aplicación o sitio a un servidor para transmitir datos de un lado a otro en tiempo real.</span> <span class="notranslate"> Perfecto para la acción de juego multijugador, servicios de chat, y así sucesivamente.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web/Guide/Performance/Usando_web_workers" title="/ Es-ES / docs / DOM / Using_web_workers">Trabajadores de la Web</a></span></dt> + <dd><span class="notranslate">Los trabajadores le dan la posibilidad de generar hilos de fondo que ejecutan su propio código JavaScript, para aprovechar los modernos procesadores multi-núcleo.</span></dd> + <dt><span class="notranslate"><a href="https://developer.mozilla.org/es/docs/Web/API/XMLHttpRequest" title="/ Es-US / docs / DOM / XMLHttpRequest">XMLHttpRequest</a> y <a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/en-US/docs/DOM/File_API&usg=ALkJrhjS1RWLb9XbCcHs-KcDniPTbC4fcw" title="/ Es-US / docs / DOM / File_API">API de archivos</a></span></dt> + <dd><span class="notranslate">La combinación de XMLHttpRequest y la API de archivos le permiten enviar y recibir cualquier tipo de datos que desee (no deje que el "XML" te lance!) Desde un servidor Web.</span> <span class="notranslate"> Esta es una gran manera de hacer cualquier cosa desde la descarga de nuevos niveles de juego y obras de arte a la transmisión de información de estado de juego en tiempo no real de ida y vuelta.</span></dd> +</dl> +</div> + +<aside class="helpful-survey" id="helpful-survey"> +<p><span class="notranslate">¿Te resultó útil este artículo?</span></p> + +<div class="helpful-survey-content"> +<div class="helpful-survey-buttons"></div> +</div> +</aside> + +<div class="column-half wiki-column text-content" id="wiki-content"> +<article id="wikiArticle"> +<aside class="helpful-survey" id="helpful-survey"> +<div class="helpful-survey-content"> +<div class="helpful-survey-thankyou"><span class="notranslate">Gracias</span></div> +</div> +</aside> +</article> + +<div class="wiki-block contributors"> +<h2 class="offscreen" id="Etiquetas_y_colaboradores_del_documento"><span class="notranslate">Etiquetas y colaboradores del documento</span></h2> + +<div class="tag-attach-list contributors-sub"><span class="notranslate"><strong>Etiquetas:</strong></span> + +<ul class="tags tags-small"> + <li><span class="notranslate"><a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/es/docs/tag/Firefox%2520OS&usg=ALkJrhiMz60hq0NctaBY3vvrFB_d0qOW4A" rel="nofollow, noindex">Firefox OS</a></span></li> + <li><span class="notranslate"><a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/es/docs/tag/juegos&usg=ALkJrhgDjdxSwGCqqR9onHjg5aeHWXOtZQ" rel="nofollow, noindex">Juegos</a></span></li> + <li><span class="notranslate"><a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/es/docs/tag/moviles&usg=ALkJrhh4FtxUHYR70IVPrUF4PGeh5CrfcA" rel="nofollow, noindex">Moviles</a></span></li> +</ul> +</div> + +<div class="contributors-sub"><span class="notranslate"><strong>Colaboradores en esta página:</strong> <a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/es/profiles/Albizures&usg=ALkJrhgWRBfS71scMhWnz4J-PjnFKsFIBA">Albizures</a> , <a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/es/profiles/atlas7jean&usg=ALkJrhgzALymuEYfsd8CnptuoTY4OCPMWw">atlas7jean</a></span></div> + +<div class="contributors-sub"><span class="notranslate"><strong>Última actualización por:</strong> <a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/es/profiles/Albizures&usg=ALkJrhgWRBfS71scMhWnz4J-PjnFKsFIBA">Albizures</a> ,</span> <time datetime="2014-10-16T13:58:46-07:00"> <span class="notranslate"> 16 oct.</span> <span class="notranslate"> 2014 13:58:46</span> </time></div> +</div> +</div> + +<div class="column-strip wiki-column" id="wiki-left"> +<nav class="zone-subnav-container"> +<div class="subnav" id="Subnav"> +<ol class="accordion"> + <li class="toggleable"><span class="notranslate"><a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/es/docs/Games/Introduccion&usg=ALkJrhiT8uSw5K2TSW051FTS2G9ftOFnZQ#">Introducción</a></span></li> + <li class="toggleable"><span class="notranslate"><a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/es/docs/Games/Introduccion&usg=ALkJrhiT8uSw5K2TSW051FTS2G9ftOFnZQ#">API para el desarrollo de juegos</a></span></li> + <li class="toggleable"><span class="notranslate"><a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/en-US/docs/Games/Techniques&usg=ALkJrhjTEqvKzu-maArgaCVGov9Q1DC62g">Técnicas</a></span></li> + <li class="toggleable"><span class="notranslate"><a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/en-US/docs/Games/Tutorials&usg=ALkJrhi4A0KaxMCbPvV5D8_zjT3bnOfGaA">Tutoriales</a></span></li> + <li class="toggleable"><span class="notranslate"><a href="https://translate.googleusercontent.com/translate_c?depth=1&hl=es&rurl=translate.google.com&sl=auto&sp=nmt4&tl=es&u=https://developer.mozilla.org/en-US/docs/Games/Publishing_games&usg=ALkJrhgQiYOYtL4GRD4H7y3qveRGSfUqvg">Publicar juegos</a></span></li> +</ol> +</div> +</nav> +</div> diff --git a/files/es/games/introducción_al_desarrollo_de_juegos_html5_(resumen)/index.html b/files/es/games/introducción_al_desarrollo_de_juegos_html5_(resumen)/index.html new file mode 100644 index 0000000000..dcbaca6422 --- /dev/null +++ b/files/es/games/introducción_al_desarrollo_de_juegos_html5_(resumen)/index.html @@ -0,0 +1,108 @@ +--- +title: Introducción al desarrollo de juegos HTML5 (resumen) +slug: Games/Introducción_al_desarrollo_de_juegos_HTML5_(resumen) +tags: + - Firefox OS + - HTML5 + - Móvil + - juegos +translation_of: Games/Introduction_to_HTML5_Game_Development_(summary) +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<div> +<h2 id="Ventajas" style="line-height: 30px;">Ventajas</h2> + +<ol> + <li><span class="seoSummary">Los juegos hechos con HTML5 funcionan en smartphones, tabletas, PCs y Smart TVs.</span></li> + <li>Anuncia y promociona tu juego en toda la web, así como en otros medios.</li> + <li>Pagos. Carga lo que quieras y usa el servicio de procesamiento de pagos que desees.</li> + <li><span class="seoSummary">Actualiza tu juego cuando quieras.</span></li> + <li>¡Colecciona tus propios análisis!</li> + <li>Conécta con tus clientes más de cerca.</li> + <li><span class="seoSummary">Los jugadores pueden jugar el juego en cualquier lugar, en cualquier momento.</span></li> +</ol> + +<h2 id="Tecnologías_Web" style="line-height: 30px;">Tecnologías Web</h2> +</div> + +<div> </div> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col" style="text-align: left;"><strong>Funcionalidad</strong></th> + <th scope="col" style="text-align: left;"><strong>Tecnología</strong></th> + </tr> + </thead> + <tbody> + <tr> + <td><strong>Audio</strong></td> + <td><a href="/en-US/docs/Web_Audio_API" title="/en-US/docs/Web_Audio_API">Web Audio API</a></td> + </tr> + <tr> + <td><strong>Graphics</strong></td> + <td><a href="/en-US/docs/WebGL" title="/en-US/docs/WebGL">WebGL</a> (<a href="http://www.khronos.org/opengles/" title="http://www.khronos.org/opengles/">OpenGL ES</a> 2.0)</td> + </tr> + <tr> + <td><strong>Input</strong></td> + <td><a href="/en-US/docs/DOM/Touch_events" title="/en-US/docs/DOM/Touch_events">Touch events</a>, <a href="/en-US/docs/API/Gamepad/Using_Gamepad_API" title="/en-US/docs/API/Gamepad/Using_Gamepad_API">Gamepad API</a>, sensores del dispositivo, <a href="/en-US/docs/WebRTC" title="/en-US/docs/WebRTC">WebRTC</a>, <a href="/en-US/docs/DOM/Using_fullscreen_mode" title="/en-US/docs/DOM/Using_fullscreen_mode">Full Screen API</a>, <a href="/en-US/docs/WebAPI/Pointer_Lock" title="/en-US/docs/WebAPI/Pointer_Lock">Pointer Lock API</a></td> + </tr> + <tr> + <td><strong>Language</strong></td> + <td><a href="/en-US/docs/JavaScript" title="/en-US/docs/JavaScript">JavaScript</a> (o C/C++ usando <a href="https://github.com/kripken/emscripten/wiki" title="https://github.com/kripken/emscripten/wiki">Emscripten</a> para compilar a JavaScript)</td> + </tr> + <tr> + <td><strong>Networking</strong></td> + <td><a href="/en-US/docs/WebRTC" title="/en-US/docs/WebRTC">WebRTC</a> y/o <a href="/en-US/docs/WebSockets" title="/en-US/docs/WebSockets">WebSockets</a></td> + </tr> + <tr> + <td><strong>Storage</strong></td> + <td><a href="/en-US/docs/IndexedDB" title="/en-US/docs/IndexedDB">IndexedDB</a> o la "nube"</td> + </tr> + <tr> + <td><strong>Web</strong></td> + <td><a href="/en-US/docs/HTML" title="/en-US/docs/HTML">HTML</a>, <a href="/en-US/docs/CSS" title="/en-US/docs/CSS">CSS</a>, <a href="/en-US/docs/SVG" title="/en-US/docs/SVG">SVG</a>, <a href="/en-US/docs/Social_API" title="/en-US/docs/Social_API">Social API</a> (¡y muchos más!)</td> + </tr> + </tbody> +</table> + +<div class="twocolumns"> +<dl> + <dt><a href="/en-US/docs/DOM/Using_fullscreen_mode" title="/en-US/docs/DOM/Using_fullscreen_mode">Full Screen API</a></dt> + <dd>Juego de pantalla completa.</dd> + <dt><a href="/en-US/docs/API/Gamepad/Using_Gamepad_API" title="/en-US/docs/API/Gamepad/Using_Gamepad_API">Gamepad API</a></dt> + <dd>Utiliza gamepads u otros controladores de juego.</dd> + <dt><a href="/en-US/docs/HTML" title="/en-US/docs/HTML">HTML</a> y <a href="/en-US/docs/CSS" title="/en-US/docs/CSS">CSS</a></dt> + <dd>Crea, diseña y diseña la interfaz de usuario de tu juego.</dd> + <dt><a href="/en-US/docs/HTML/Element/audio" title="/en-US/docs/HTML/Element/audio">HTML audio</a></dt> + <dd>Juega fácilmente efectos de sonido simples y música.</dd> + <dt><a href="/en-US/docs/IndexedDB" title="/en-US/docs/IndexedDB">IndexedDB</a></dt> + <dd>Almacena los datos del usuario en tu propio ordenador o dispositivo.</dd> + <dt><a href="/en-US/docs/JavaScript" title="/en-US/docs/JavaScript">JavaScript</a></dt> + <dd>Rápido lenguaje de programación web para escribir el código de tu juego.<br> + Para portar fácilmente tus juegos existentes en <a href="https://github.com/kripken/emscripten/wiki" title="https://github.com/kripken/emscripten/wiki">Emscripten</a> o <a href="http://asmjs.org/spec/latest/" title="http://asmjs.org/spec/latest/">Asm.js</a></dd> + <dt><a href="/en-US/docs/WebAPI/Pointer_Lock" title="/en-US/docs/WebAPI/Pointer_Lock">Pointer Lock API</a></dt> + <dd>Bloquea el ratón u otro dispositivo señalador dentro de la interfaz de tu juego.</dd> + <dt><a href="/en-US/docs/SVG" title="/en-US/docs/SVG">SVG</a> (Scalable Vector Graphics)</dt> + <dd>Cree gráficos vectoriales que se escalan sin problemas, independientemente del tamaño o la resolución de la pantalla del usuario.</dd> + <dt><a href="/en-US/docs/JavaScript/Typed_arrays" title="/en-US/docs/JavaScript/Typed_arrays">Typed Arrays</a></dt> + <dd>Accede a datos binarios sin procesar desde JavaScript; Manipula texturas GL, datos de juegos, o cualquier otra cosa.</dd> + <dt><a href="/en-US/docs/Web_Audio_API" title="/en-US/docs/Web_Audio_API">Web Audio API</a></dt> + <dd>Controla la reproducción, síntesis y manipulación del audio en tiempo real.</dd> + <dt><a href="/en-US/docs/WebGL" title="/en-US/docs/WebGL">WebGL</a></dt> + <dd>Cree gráficos 3D (y 2D) acelerados por hardware y de alto rendimiento. <a href="http://www.khronos.org/opengles/" title="http://www.khronos.org/opengles/">OpenGL ES</a> 2.0.</dd> + <dt><a href="/en-US/docs/WebRTC" title="/en-US/docs/WebRTC">WebRTC</a></dt> + <dd>Las comunicaciones en tiempo real para controlar los datos de audio y video, incluidas las teleconferencias y la transmisión de datos de otras aplicaciones entre dos usuarios, como el chat.</dd> + <dt><a href="/en-US/docs/WebSockets" title="/en-US/docs/WebSockets">WebSockets</a></dt> + <dd>Conecte tu aplicación o sitio a un servidor para transmitir datos de un lado a otro en tiempo real. Perfecto para la acción de juegos multijugador, servicios de chat, etc.</dd> + <dt><a href="/en-US/docs/DOM/Using_web_workers" title="/en-US/docs/DOM/Using_web_workers">Web Workers</a></dt> + <dd>Genere hilos de fondo ejecutando tu propio código JavaScript para procesadores multi-core.</dd> + <dt><a href="/en-US/docs/DOM/XMLHttpRequest" title="/en-US/docs/DOM/XMLHttpRequest">XMLHttpRequest</a> y <a href="/en-US/docs/DOM/File_API" title="/en-US/docs/DOM/File_API">File API</a></dt> + <dd>Envía y recibe cualquier tipo de información que desees desde un servidor web, como descargar nuevos niveles de juego y material gráfico para transmitir información de estado del juego en tiempo no real.</dd> +</dl> +</div> + +<p> </p> diff --git a/files/es/games/publishing_games/game_distribution/index.html b/files/es/games/publishing_games/game_distribution/index.html new file mode 100644 index 0000000000..c7f57b87be --- /dev/null +++ b/files/es/games/publishing_games/game_distribution/index.html @@ -0,0 +1,140 @@ +--- +title: Distrbución de juegos +slug: Games/Publishing_games/Game_distribution +tags: + - CocoonIO + - Distribución + - Distribución de juegos para móviles + - HTML5 + - JavaScript + - Juego de azar + - Phonegap + - Publicación de un juego + - Tiendas web + - juego + - juegos +translation_of: Games/Publishing_games/Game_distribution +--- +<div>{{GamesSidebar}}</div> + +<p class="summary">Has seguido un tutorial o dos y creado un juego de HTLM5 — eso es genial. Este artículo cubre todo lo que necesitas saber sobre las formas en que puedes distribuir tu juego recién creado al mundo. Esto incluye alojarlo tu mismo en línea, enviarlo a mercados abiertos, y enviándolo a aplicaciones cerradas como Google Play o iOS App Store.</p> + +<h2 id="Beneficios_de_HTML5_sobre_nativo">Beneficios de HTML5 sobre nativo</h2> + +<p>Construir juegos con HTML5 te da ventajas, como:</p> + +<h3 id="Felicidad_multiplataforma">Felicidad multiplataforma</h3> + +<p>La tecnología en si es multiplataforma, por lo que puedes escribir el código una vez y apuntarle a múltiples dispositivos. Esto puede ir desde teléfonos inteligentes o tabletas de gama baja, portátiles y ordenadores de escritorio, a smart TVs, relojes o incluso una nevera si puede manejar un navegador lo suficientemente moderno.</p> + +<p>No necesitas tener equipos separados para trabajar en el mismo título que le apunta a diferentes plataformas, con solo una base de código para preocuparse. Puedes invertir más tiempo y dinero en <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion">Promociones</a> y <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_monetization">Monetizar</a>.</p> + +<h3 id="Actualizaciones_instantáneas">Actualizaciones instantáneas</h3> + +<p>No tienes que esperar varios días para tener el código de tus juegos actualizado. Si tus usuarios encuentran fallas, puedes solucionarlas rápidamente, actualizando el sistema y el juego en tu servidor para proporcionar a los jugadores el código actualizado casi al instante.</p> + +<h3 id="Distribución_directa_de_enlaces_y_reproducción_instantánea">Distribución directa de enlaces y reproducción instantánea</h3> + +<p>No tienes que decirle a la gente que busque tu juego en una tienda de aplicaciones con juegos HTML5. Puedes simplemente enviarles un enlace directo con acceso al juego, en el que pueden hacer click para jugar de inmediato sin necesidad de utilizar complementos de terceros o descargar e instalar un paquete grande. Tienes que tener en cuenta que descargar el juego seguramente lleva un poco de tiempo dependiendo del tamaño del juego y de la velocidad de la red. En cualquier caso, es mucho más fácil promocionar el juego si puedes conducir el tráfico directamente a donde tu quieras y no tener que estar saltando muchas trabas.</p> + +<h2 id="Escritorio_vs_móvil">Escritorio vs móvil</h2> + +<p>La gran mayoría del tráfico en el que estamos interesados — gente jugando en HTML5 — viene de los dispositivos móviles entonces eso es algo en lo que te tienes que enfocar si quieres tener éxito. En los dispositivos móviles la tecnología HTML5 realmente puede brillar y mostrar sus ventajas. No hay Flash, y HTML5 es completamente una multiplataforma.</p> + +<p>Intentar competir directamente con los juegos de escritorio es muy difícil. Puedes poner tus juegos de HTML5 en la misma área (ver {{anch("Native desktop")}}, later on) y deberías, porque es bueno diversificar las plataformas que soporta, pero tienes que recordar que los desarrolladores de juegos de escritorio tienen años de experiencia, grandes herramientas y canales sólidos de distribución. Muchos juegos de HTML5 le apuntarán a diferentes segmentos del mercado que los juegos de escritorio nativos, por ejemplo, juegos simples para pasar el tiempo mientras estás en movimiento en lugar de grandes experiencias de inmersión. Tales juegos, están normalmente diseñados para ser jugados con dos, o incluso un dedo, así puedes sujetar el dispositivo, jugar al juego y ser capaz de usar la segunda mano para lo que necesites.</p> + +<p>Dicho esto, las plataformas de escritorio pueden utilizarse para la distribución con bastante facilidad con la disponibilidad de wrappers que te pueden ayudar a preparar las compilaciones nativas de tu juego, mira {{anch("Packaging games")}}. También es recomendable probar los controles de escritorio para tus juegos incluso si tu enfoque está en los dispositivos móviles. Los jugadores disfrutaran de tus juegos en cualquier plataforma disponible, y el escritorio es una de ellas. Además, es generalmente más fácil construir y probar el juego primero en escritorio, y luego pasar a probarlo en los dispositivos móviles.</p> + +<h2 id="Publicando_el_juego">Publicando el juego</h2> + +<p>Hay tres opciones principales cuando quieres publicar un juego:</p> + +<ul> + <li>Self-hosting</li> + <li> Editores</li> + <li>Tiendas</li> +</ul> + +<p>Recuerda que el nombre de tu juego debería ser lo suficientemente exclusivo para ser promovido rápidamente más adelante, pero también lo suficientemente adictivo, para que la gente no se olvide de él.</p> + +<h3 id="Self-hosting">Self-hosting</h3> + +<p>Si eres un desarrollador de interfaces, es posible que sepas que hacer. Un juego de HTML5 es solo otra página web. Puedes actualizarla desde un servidor remoto, obtener un nombre de dominio atractivo y hostearlo tu mismo.</p> + +<p> Si quieres ganar dinero del desarrollo de juegos, deberás asegurar el código fuente de una manera u otra contra personas que podrían fácilmente cogerlo y venderlo como propio. Puedes concatenar y minimizar el código para hacerlo más pequeño y afearlo, así es mucho más difícil hacer ingeniería inversa en tu juego. Otra buena medida para tomar es proporcionar una demo online si estas planeando empaquetarlo y venderlo en una tienda cerrada como iTunes o Steam.</p> + +<p>Si estás trabajando en un proyecto paralelo solo por diversión, entonces dejar el código fuente abierto beneficiará a quienes deseen aprender de lo que has creado. Ni siquiera tienes que preocuparte por buscar un proveedor de alojamiento, ya que es posible <a href="http://dev.end3r.com/2014/02/host-your-html5-games-on-github-pages/">hostear juego en las páginas de GitHub</a>. Obtendrás alojamiento gratuito, control de versiones y posibles colaboraciones si tu proyecto es lo suficientemente interesante.</p> + +<h3 id="Editores_y_portales">Editores y portales</h3> + +<p>Como el nombre lo indica, los editores pueden manejar la publicación de tu juego por ti. Si debe ir de esa manera o no, depende de cuál sea tu plan para distribuir el juego: ¿Quieres venderlo donde sea posible, o quieres restringir su presencia a aquellos que han comprado una <a href="https://developer.mozilla.org/en-US/docs/Games/Publishing_games/Game_monetization">licencia exclusiva</a>? Tu decides. Considera varias opciones, experimenta y saca conclusiones. Los editores se explicarán con más detalle en el artículo de <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_monetization/">monetización</a>.</p> + +<p>También hay portales independientes que recogen juegos interesantes como <a href="http://html5games.com/">HTML5Games.com</a>, <a href="http://www.marketjs.com/">MarketJS.com</a> o <a href="http://clay.io/">Clay.io </a>donde puedes mandar tus juegos y obtendrás algo de promoción natural debido al gran tráfico que esos sitios atraen. Algunos de estos toman tus archivos y los hostean en sus servidores, mientras que otros solo enlazan a su sitio web o insertan tu juego en su sitio. Tal exposición solo puede proporcionar <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion/">promoción</a> para tu juego, o si tienes anuncios en el juego (u otra opción de conseguir dinero) también puede ofrecer monetización.</p> + +<h3 id="Tiendas_web_y_nativas">Tiendas web y nativas</h3> + +<p>También puedes subir y publicar tu juego directamente en diferentes tipos de tiendas, o mercados. Para hacerlo, tendrás que prepararlo y empaquetarlo en un formato de compilación específico para cada ecosistema de aplicaciones al que deseas orientarlo. Consulta {{anch("Marketplaces — distribution platforms")}} para más detalles de qué tipos de mercados están disponibles.</p> + +<h2 id="Mercados—_Plataformas_de_distribución">Mercados— Plataformas de distribución</h2> + +<p>Veamos cuáles son las opciones disponibles con respecto a los mercados/tiendas disponibles para diferentes plataformas y sistemas operativos.</p> + +<div class="note"> +<p><strong>Nota</strong>: Estas son las plataformas de distribución más populares, pero esto no quiere decir que sean la única opción. En lugar de intentar sumar tu juego a los miles de otros en la tienda de iOS, también puedes intentar encontrar un nicho y promocionar directamente al público que esté interesado en tus juegos. Tu creatividad es crítica aquí.</p> +</div> + +<h3 id="Tiendas_web">Tiendas web</h3> + +<p>Las mejores plataformas para juegos HTML5 son las tiendas basadas en la web. Es fácil <a href="http://code.tutsplus.com/tutorials/preparing-for-firefox-os--mobile-18515">preparar un juego para estas tiendas, </a>puesto que tal acción implica poca o ninguna modificación del juego en sí — normalmente, es suficiente añadir un archivo de manifiesto que contenga la información necesaria en un paquete comprimido que incluya todos los recursos.</p> + +<ul> + <li><a href="https://chrome.google.com/webstore/">La tienda web de Chrome</a> también es una opción atractiva — nuevamente, tener un archivo de manifiesto listo, comprimir tu juego y completar el formulario de envío en línea es todo lo que se requiere.</li> + <li><a href="http://www.tizenstore.com/">Tizen</a> también está dando un gran valor a las aplicaciones de soporte escritas en JavaScript. Su tienda es otra opción válida.</li> +</ul> + +<h3 id="Tiendas_de_aplicaciones_móviles_nativas">Tiendas de aplicaciones móviles nativas</h3> + +<p>Cuando se trata del mercado de aplicaciones móviles, están la Apple App Store para iOS, Google Play para Android y el resto de la competencia. Las tiendas nativas ya están llenas de desarrolladores establecidos que venden grandes juegos, por lo que debes ser talentoso y tener suerte para que te vean.</p> + +<ul> + <li>La iOS App Store es bastante difícil de acceder, ya que hay requisitos muy estrictos que los juegos deben cumplir, y tendrás que esperar una semana o dos para ser aceptado. Además, es la tienda móvil más prometedora, con cientos de miles de aplicaciones, así que es extremadamente difícil destacar entre la multitud.</li> + <li>Google Play tiene unos requisitos menos estrictos, así que la tienda está contaminada con juegos de baja calidad. Aún así es bastante difícil que uno se haga notar, ya que la cantidad de aplicaciones enviadas diariamente es enorme. Aquí también es más difícil ganar dinero — la mayoría de los juegos de pago de iOS se publican como juegos gratuitos en Android, con monetización proveniente de compras en la aplicación(IAPS) y anuncios.</li> + <li>Otras tiendas para plataformas móviles nativas como Windows Phone or Blackberry están trabajando duro para obtener un pedazo del pastel, y están muy por detrás de la competencia. Puede ser bueno enviar tu juego allí, ya que será mucho más fácil que la gente se de cuenta de él.</li> +</ul> + +<p>Si estas buscando más información sobre los diferentes tipos de tiendas de aplicaciones, puedes consultar la <a href="https://en.wikipedia.org/wiki/List_of_mobile_software_distribution_platforms">lista de plataformas de distribución de software móvil</a> en este artículo de Wikipedia.</p> + +<h3 id="Escritorio_nativo">Escritorio nativo</h3> + +<p>Para ampliar tu audiencia, también puedes revisar el ecosistema de escritorio con sus juegos HTML5 — solamente recuerda que todos los juegos populares AAA toman la mayor parte de la cuota del mercado, y piensa cuidadosamente si esto se adapta a tu estrategia. Para que funcione correctamente en escritorios debe funcionar en los tres sistemas operativos: Windows, Mac OS y Linux. La mayor tienda de escritorio para juegos es definitivamente <a href="http://steamcommunity.com/">Steam</a> — desarrolladores indie pueden acceder a Steam a través del programa <a href="https://steamcommunity.com/greenlight/">Greenlight</a>. Recuerda que tu mismo tienes que lidiar con los problemas multiplataforma cargando versiones separadas para diferentes plataformas.</p> + +<p>Después de que hayas cubierto Steam, hay un montón de rumores alrededor de iniciativas como <a href="http://www.humblebundle.com/">Humble Bundle </a>donde los juegos indie más populares se presentan a un público más amplio. Es más como una excelente oportunidad de promoción que una forma de ganar mucho dinero, sin embargo, los precios pagados por los juegos en un paquete generalmente son bastante bajos.</p> + +<h2 id="Juegos_de_empaquetado">Juegos de empaquetado</h2> + +<p>La web es la primera y la mejor opción para juegos de HTML5, pero si quieres buscar una audiencia más amplia y distribuir tu juego en un ecosistema cerrado, todavía puedes hacerlo empaquetándolo.</p> + +<p>Lo bueno es que no necesitas muchos equipos separados trabajando en el mismo juego para diferentes plataformas — puedes construirlo una vez y usar herramientas como <a href="/en-US/docs/">Phonegap</a> o<a href="/en-US/docs/"> CocoonIO </a>para empaquetar el juego en tiendas nativas. Los paquetes resultantes suelen ser bastante fiables, pero todavía deberias probarlos y estar atento a pequeños problemas o errores que solucionar.</p> + +<h3 id="Herramientas_disponibles">Herramientas disponibles</h3> + +<p>Hay varias herramientas para elegir dependiendo de tus habilidades, marcos preferidos o plataformas de destino. Se trata de elegir la mejor herramienta para tu tarea particular.</p> + +<ul> + <li><a href="http://phonegap.com/">Phonegap</a> — basado en Cordova, esta es la herramienta más popular para construir/empaquetar apps de JavaScript para plataformas nativas.</li> + <li><a href="http://cocoon.io/">CocoonIO</a> — La herramienta más popular específicamente para la construcción de juegos HTML5 para múltiples tiendas nativas. Tiene sus propias optimizaciones de rendimiento para juegos representados en Canvas y es compatible con muchos marcos de juego.</li> + <li><a href="http://impactjs.com/ejecta">Ejecta</a> — una herramienta específicamente para empaquetar juegos creados con el marco <a href="http://impactjs.com/"> ImpactJS</a> para iOS, construido por el autor ImpactJS. Proporciona una integración perfecta con ImpactJS, pero solo es compatible con un solo framework y tienda de aplicaciones.</li> + <li><a href="http://nwjs.io/">NW.js</a> — formalmente conocido como Node-Webkit, esta es la primera opción cuando se trata de construir un juego de escritorio que funcione en Windows, Mac y Linux. Las distribuciones se empaquetan con el motor WebKit para proporcionar representación en cualquier plataforma.</li> +</ul> + +<p>Otras herramientas alternativas son:</p> + +<ul> + <li><a href="https://software.intel.com/en-us/intel-xdk">Intel XDK</a> — una alternativa emocionante, similar a CocoonIO.</li> + <li><a href="http://electron.atom.io/">Electron</a> — conocido como Atom Shell — es una herramienta de código abierto y multiplataforma de GitHub.</li> + <li><a href="http://manifoldjs.com/">Manifold.js</a> — esta herramienta es del equipo de Microsotf que puede crear distribuciones nativas de juegos HTML5 desde iOS, Android, y Windows.</li> +</ul> + +<h2 id="Resumen">Resumen</h2> + +<p>La distribución es el camino para dar acceso al mundo a tu juego. Hay muchas opciones disponibles y no hay una única respuesta en cuanto a cuál es la mejor. Cuando publiques el juego es momento de enfocarse en la <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion/">promoción</a> — dejar que la gente sepa que tu juego existe. Sin promoción, ni siquiera serían capaces de aprender y jugar con él.</p> diff --git a/files/es/games/publishing_games/index.html b/files/es/games/publishing_games/index.html new file mode 100644 index 0000000000..78d4c80917 --- /dev/null +++ b/files/es/games/publishing_games/index.html @@ -0,0 +1,32 @@ +--- +title: Publicación de juegos +slug: Games/Publishing_games +tags: + - Games + - HTML5 + - JavaScript + - Monetization + - NeedsTranslation + - Promotion + - Publicacion + - TopicStub + - distribution + - juegos + - publishing +translation_of: Games/Publishing_games +--- +<div>{{GamesSidebar}}</div> + +<p class="summary">Los juegos desarrollados en HTML5 tienen una gran ventaja sobre los nativos en términos de publicación y distribución: tienen la libertad de distribución, promoción y monetización de su juego en la Web, en lugar de que cada versión esté restringida a una única tienda controlada por una empresa. Pueden, beneficiándose de la web, ser verdaderamente multiplataforma. Esta serie de artículos analiza las opciones que tienes a la hora de publicar y distribuir tu juego, y ganar algo con él mientras esperas que se haga famoso.</p> + +<h2 id="Distribución">Distribución</h2> + +<p>Así que has seguido un <a href="/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript">tutorial</a> o <a href="/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">dos</a> y has creado un juego HTML5. ¡Genial! La <a href="/en-US/docs/Games/Publishing_games/Game_distribution"> distribución de juegos</a> proporciona todo lo que se necesita saber sobre las formas en que puede distribuir su juego recién creado, incluido hospedarlo en línea, enviarlo a mercados abiertos y enviarlo a sitios cerrados como GooglePlay o iOS App Store.</p> + +<h2 id="Promoción">Promoción</h2> + +<p>Desarrollar y terminar el juego no es suficiente. Tienes que hacerle saber al mundo que has hecho disponible algo interesante, que la gente disfrutará jugando. Existen muchas técnicas de <a href="/en-US/docs/Games/Publishing_games/Game_promotion">promoción de juegos</a> , muchas de ellas gratuitas, por lo que incluso si estás luchando por ganarte la vida como un desarrollador independiente con presupuesto limitado, aún puedes hacer mucho para que la gente sepa acerca de tu nuevo juego. Promocionar el juego también ayuda a monetizarlo más tarde, por lo que es importante hacerlo con eficacia.</p> + +<h2 id="Monetización">Monetización</h2> + +<p>Cuando dedicas tiempo a desarrollar, publicar y promocionar un juego, llega un punto en el que considerarás ganar dinero con él. La <a href="/en-US/docs/Games/Publishing_games/Game_monetization">monetización</a> del juego es esencial para cualquier persona que considere que su trabajo de desarrollo es un esfuerzo serio en el camino de convertirse en un desarrollador independiente capaz de ganarse la vida, así que siga leyendo y vea cuáles son sus opciones. La tecnología es lo suficientemente madura; Es solo cuestión de elegir el enfoque correcto.</p> diff --git a/files/es/games/publishing_games/monetización_de_los_juegos/index.html b/files/es/games/publishing_games/monetización_de_los_juegos/index.html new file mode 100644 index 0000000000..1549b222da --- /dev/null +++ b/files/es/games/publishing_games/monetización_de_los_juegos/index.html @@ -0,0 +1,100 @@ +--- +title: Monetización de videojuegos +slug: Games/Publishing_games/Monetización_de_los_juegos +tags: + - HTLM5 + - JavaScript + - Licencias + - anuncios + - juegos + - marca + - monetización +translation_of: Games/Publishing_games/Game_monetization +--- +<div>{{GamesSidebar}}</div> + +<p class="summary">Cuando empleas tu tiempo en crear un juego, <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_distribution">distribuirlo </a>y <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion">promocionarlo </a>deberías considerar ganar un poco de dinero con ello. Si tu trabajo es un esfuerzo serio en tu camino para ser un desarrollador independiente de juegos capaz de ganarse la vida, sigue leyendo y verás cuales son tus opciones. La tecnología es lo suficientemente madura; ahora es cuestión de elegir el enfoque adecuado.</p> + +<h2 id="Juegos_de_pago">Juegos de pago</h2> + +<p>Lo primero, la opción más obvia que probablemente venga a tu mente, podría ser vender los juegos de la forma en que se realiza para grandes títulos AAA ---- con un precio fijado por adelantado. Aunque el mercado digital es clave y no necesitas imprimir portadas y sacar tu juego en una tienda física, para ganar un dinero decente vendiendo tus juegos con un precio fijo, tienes que invertir tu tiempo y dinero en marketing. Solo con los mejores juegos se recupera o gana más de lo que costo hacerlo, y necesitas un montón de suerte para ello.</p> + +<p>Cuanto ganes por tu jugo depende del mercado, la calidad de tu juego y otros tantos pequeños factores. Un título de arcade para iOS puede venderse por 0,99 USD, pero un juego de escritorio estilo RPG más largo, en Steam, puede venderse por 20 USD; ambos precios están bien. Tienes que seguir el mercado y tu propia investigación --- aprender rápido de tus errores es importante.</p> + +<h2 id="Compras_en_la_aplicación">Compras en la aplicación</h2> + +<p>En lugar de que la gente pague por tu juego por adelantado, puedes ofrecer un juego de forma gratuita con compras dentro de la aplicación. En este caso, el juego puede ser adquirido sin gastarse un centavo --- dar el juego a los jugadores, pero ofreciendo monedas del juego, bonus extra o beneficios por dinero real. Ejemplos específicos pueden ser, incluir bonus de nivel, mejores armas o hechizos, o volver a llenar la energía necesaria para jugar. Diseñar un buen sistema de compras en la aplicación es un arte propio.</p> + +<p>Recuerda que necesitas miles de descargas de tu juego para hacer efectivas/rentables las compras en la aplicación --- solo una pequeña parte de los jugadores pagará por las compras en la aplicación. ¿Cómo de pequeña? Varía, pero alrededor de una persona por cada mil es aproximadamente la media. Cuantas más personas jueguen a tu juego, mayor será la probabilidad de que alguien pague, o sea que tus beneficios dependen en gran medida de tus actividades de <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion">promoción.</a></p> + +<h3 id="Freemium">Freemium</h3> + +<p>Los juegos que ofrecen compras en el juego, a menudo se refieren a <strong>freemium </strong>--- un juego freemium puede ser adquirido y jugado gratis, pero puedes pagar por características extra (premium), bienes virtuales u otros beneficios. La palabra en sí, adquirió una connotación negativa después de que las grandes compañías se centraran en crear juegos, cuyo objetivo principal era ganar el máximo dinero posible de los jugadores, en lugar de proporcionar una experiencia divertida. Los peores casos fueron cuando podías utilizar dinero real para obtener ventajas sobre otros jugadores, o cuando restringían el acceso a las siguientes etapas del juego, a menos que los jugadores pagaran. El término "pagar para ganar" fue acuñado y este enfoque no gustó a muchos jugadores y desarrolladores. Si quieres implementar compras dentro del juego asegúrate de que intenten añadir valor al juego con algo que los jugadores disfruten, en lugar de sacarlo y luego cobrarlo.</p> + +<h3 id="Complementos_y_DLCs">Complementos y DLCs</h3> + +<p> </p> + +<p>Los complementos y el contenido descargable son una buena manera de proporcionar un valor extra a un juego ya lanzado, pero recuerda que tendrás que ofrecer contenido decente y entretenido para atraer a la gente a comprarlo. Un conjunto totalmente nuevo de niveles con nuevos personajes, armas e historia es un buen material para DLC, pero para tener suficientes ventas el juego en sí debe ser popular, o de lo contrario no habrá jugadores interesados en gastar su dinero duramente ganado. eso.</p> + +<p>En lugar de vender activamente los juegos, también puede intentar obtener un ingreso pasivo: mostrar anuncios y confiar en actividades anteriores relacionadas con la <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion">promoción</a> de su juego puede ser beneficioso, pero su juego debe ser adictivo, lo cual no es tan fácil como parece. Todavía necesitas planearlo, y en algún momento también necesitarás un poco de suerte. Si su juego se vuelve viral y la gente comienza a compartirlo, puede obtener muchas descargas y dinero de los anuncios.</p> + +<p>Hay muchas compañías que ofrecen sistemas de publicidad: usted se registra y les permite mostrar anuncios a cambio de un porcentaje de las ganancias. Se dice que Google AdSense es el más efectivo, pero no está diseñado para juegos y es una práctica bastante mala usarlo para ese propósito. En lugar de arriesgarse a que se cierre su cuenta y se bloquee todo el dinero, intente utilizar los portales habituales de gamedev como <a href="https://www.leadbolt.com/">LeadBolt. </a>Ofrecen sistemas fáciles de implementar para mostrar los anuncios en sus juegos y dividir las ganancias con usted.</p> + +<p>Los anuncios de video son cada vez más populares, especialmente en forma de pre-roll: se muestran al principio de su juego mientras aún se está cargando. Y sobre el tema de dónde colocar los anuncios en tu juego, realmente depende de ti. Debería ser lo más sutil posible para no molestar demasiado a los jugadores, pero lo suficientemente visible como para hacerles clic o al menos tomar nota. Adición de anuncios entre sesiones de juego en juego sobre pantallas es un enfoque popular.</p> + +<p> </p> + +<h2 id="Licencias">Licencias</h2> + +<p>Hay un enfoque que puede funcionar como un modelo de monetización por sí mismo, y es vendiendo licencias para la distribución de tu juego. Existen más y más portales interesados en enseñar tu juego en sus páginas web. Ellos siguen varias estrategias para ganar dinero, gracias a tus juegos, pero no te tienes que preocuparte sobre eso, ya que la venta de la licencia suele ser un contrato único. Tu consigues el dinero y ellos pueden ser creativos con el uso de tu juego para hacer dinero con él.</p> + +<p>Encontrar editores puede ser difícil la primera vez --- intenta buscarlos en los foros <a href="http://www.html5gamedevs.com/">HTML5 Gamedevs</a>. Si eres bien conocido, los editores llegarán a ti. La mayoria de las ofertas se realizan a través de correos electrónicos cuando se habla con una persona dedicada en el lado del editor. Algunos editores de sitios web tienen esa información a la vista, mientras que para contactar con otros editores es más difícil. Cuando busques un editor intenta ser amable e ir directo al grano --- son gente ocupada.</p> + +<h3 id="Licencias_exclusivas">Licencias exclusivas</h3> + +<p>La licencia exclusiva es un tipo de licencia para un editor --- has creado un juego y vendes todos sus derechos a una única entidad junto con los derechos para redistribuirla ---- <a href="http://www.softgames.de/">Softgames</a> es un ejemplo de tal editor. No puedes vender el juego otra vez de ninguna forma mientras que el editor tenga los derechos --- esto es por lo que las ofertas exclusivas valen mucho dinero. ¿Cuánto exactamente? Depende de la calidad del juego, el género, el editor, y otros tantos factores, pero habitualmente puede estar entre los 2000 y 5000 USD. Un vez que vendiste una licencia exclusiva puedes olvidarte de promocionar ese juego en particular, ya que no ganarás más dinero con él, así que acepta tal oferta solo si estas seguro de que es lo suficientemente rentable.</p> + +<h3 id="Licencias_no_exclusivas">Licencias no exclusivas</h3> + +<p>Este enfoque es menos estricto --- puedes vender una misma licencia a varios editores. Este es el enfoque más popular entre os editores nuevos (y los editores están apareciendo constantemente), puedes vender tus juegos con unos términos no exclusivos. Recuerda que con esta licencia el editor no puede redistribuirlo más --- a menudo se le llama un acuerdo de sitio cerrado cuando compran el derecho de publicar el juego en su propio portal. El coste normal de una licencia no exclusiva esta alrededor de 500 USD.</p> + +<h3 id="Subscripciones">Subscripciones</h3> + +<p>También hay una opción para obtener un dinero pasivo mensual, a través de un acuerdo de subscripción. En lugar de obtener un único pago, puedes obtener pequeños pagos de dinero por juego, por mes --- puede estar entorno a 20-50 USD por mes, por juego. Normalmente depende de ti, si quieres ganar todo el dinero en un solo pago o ganarlo por meses. Recuerda que puede ser cancelado, o sea que no es una solución que funcione indefinidamente.</p> + +<h3 id="Ingresos_por_publicidad">Ingresos por publicidad</h3> + +<p>Puedes implementar anuncios en tu juego tu mismo e intentar encontrar el tráfico adecuado para ganar un poco de dinero, pero también puedes hacer un acuerdo de reparto de ingresos con un editor. Los editores se encargarán de dirigir el tráfico y de dividir los beneficios --- habitualmente los acuerdos son de 70/30% o 50/50%, ganado por mes.</p> + +<p>Recuerda que muchos nuevos editores de baja calidad querrán coger tu juego con ingresos por anuncios, en lugar de licencia, porque será más barato para ellos y podrías terminar con beneficios de 2 USD por juego por trato completado. Ten cuidado cuando contrates con nuevos editores --- algunas veces es mejor reducir el coste de la licencia a un editor conocido, en lugar de que te defraude un nuevo editor por más dinero.</p> + +<p>Los editores cogen tus juegos para la participación en los beneficios, y/o licenciar podrá requerir implementar sus propias APIs, lo cual dará un trabajo extra, asi que considera eso en tu precio final.</p> + +<h3 id="Marca">Marca</h3> + +<p>Puedes vender los derechos de usar tu juego para la marca, o hacerlo tu mismo. En el primer caso, es casi como una licencia no exclusiva, pero el cliente normalmente compra derechos para el código e implementarán sus propios gráficos. En el segundo caso, es como un trato independiente, pero estas reutilizando el código y añadiendo gráficos proporcionados por los clientes, algunas veces implementándolos como ellos te enseñen. Por ejemplo, si tu tienes un juego donde un jugador golpea los artículos de comida, podrías cambiar la comida a los productos del cliente para darles publicidad. Los precios en este modelo varían mucho dependiendo de la marca, cliente, y las horas que le eches.</p> + +<h2 id="Otras_estrategias_de_monetización_no_enfocadas_al_juego">Otras estrategias de monetización no enfocadas al juego</h2> + +<p>Hay otros caminos en los que puedes ganar dinero cuando haces juegos HTML5, y ni siquiera tiene que estar relacionado con el juego.</p> + +<h3 id="Venta_de_recursos">Venta de recursos</h3> + +<p>Si eres un diseñador gráfico, puedes vender los bienes de los juegos que has creado, o algo completamente nuevo exclusivamente para ese propósito en tiendas online como <a href="http://market.envato.com/">Envato Market</a>. No es mucho, pero si eres un diseñador conocido, puede ser una forma de ganar un dinero extra.</p> + +<h3 id="Escribir_artículos_y_tutoriales">Escribir artículos y tutoriales</h3> + +<p>Es posible escribir artículos sobre tus juegos y que te paguen por ello. La promoción del juego y la monetización al mismo tiempo es un ganar-ganar, y si no abusas de ello con muchos anuncios, los lectores disfrutarán leyendo los artículos y aprenderán una o dos cosas. Si te enfocas en compartir el conocimiento primero y usas tus juegos solo como ejemplos, estará bien. Visita <a href="http://gamedevelopment.tutsplus.com/">Tuts+ Game Development</a> o sitios web similares para tener oportunidades donde escribir artículos.</p> + +<h3 id="Mercancías">Mercancías</h3> + +<p>Puedes vender camisetas, <a href="https://www.stickermule.com/user/1070634890/stickers">pegatinas</a> o otros objetos --- algunos desarrolladores ganan más dinero con las mercancías que con sus propios juegos, pero solo funciona en juegos muy populares y reconocidos, como Angry Birds. Todavía, puede ser otra forma de ganar un poco de dinero. Cuanto más diversificados sean tus ingresos, mejor será tu estabilidad comercial.</p> + +<h3 id="Donaciones">Donaciones</h3> + +<p>Cuando todo lo demás falla puedes intentar poner un botón de donaciones en la página de tu juego y pedir apoyo de la comunidad. Algunas veces funciona, pero solo si el jugador te conoce y siente que te ayudará. Este es el porque de que manejar cuidadosamente la comunidad es tan importante. Funcionó con la competición de <a href="http://js13kgames.com/">js13kGames</a> --- todos los participantes obtuvieron una camiseta gratis, y algunos incluso dieron unos cuantos dólares para ayudarlo a seguir funcionado en los próximos años.</p> + +<h2 id="Resumen">Resumen</h2> + +<p>Hay muchas maneras de ganar dinero --- todo lo que se aplica al mundo de los juegos AAA "normalmente" puede ser, más o menos, aplicable a los juegos casuales HTML5. Sin embargo, también podrías enfocarte en vender licencias, hacer marcas, o ganar unos beneficios compartidos de los anuncios. Depende totalmente de ti, que camino vas a seguir.</p> diff --git a/files/es/games/techniques/2d_collision_detection/index.html b/files/es/games/techniques/2d_collision_detection/index.html new file mode 100644 index 0000000000..e4d66bf13f --- /dev/null +++ b/files/es/games/techniques/2d_collision_detection/index.html @@ -0,0 +1,181 @@ +--- +title: 2D collision detection +slug: Games/Techniques/2D_collision_detection +tags: + - 2D + - Deteccion de colision + - JavaScript + - juegos +translation_of: Games/Techniques/2D_collision_detection +--- +<div>{{GamesSidebar}}</div><p>{{IncludeSubnav("/en-US/docs/Games")}}</p> + +<div class="summary"> +<p>Algoritmos para detectar la colision en juegos de 2D depende del tipo de formas con las que queramos colisionar (Ej.: Rectangulo, Circulo). Generalmente tendras una forma simple que cubre la "hitbox" (caja de colision), por lo tanto la colision no sera perfecta pixel a pixel, pero ira bien, en rendimiento. Este articulo cubre la mayoria de las tecnicas utilizadas para la colision para juegos en 2D.</p> +</div> + +<h2 id="Hitbox_alineada_con_las_cordenadas">Hitbox alineada con las cordenadas</h2> + +<p>Una de las formas mas sencillas es entre dos rectangulos que esten alineados con las cordenas, es decir, sin rotacion. El algoritmo funciona de manera que detecta si hay un agujero en alguno de los 4 lados del rectangulo. Si en un lado no hay un agujero, significa de que hay una colision.</p> + +<pre class="brush: 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.height + rect1.y > rect2.y) { + // ¡colision detectada! +} + +// reemplazando los valores => + +if (5 < 30 && + 55 > 20 && + 5 < 20 && + 55 > 10) { + // ¡colision detecteda! +} +</pre> + +<div class="hidden"> +<h5 id="Rect_code">Rect code</h5> + +<pre class="brush: html"><div id="cr-stage"></div> +<p>Mueve los rectangulos. Azul = no colision. Verde = colision</p> +<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crafty/0.5.4/crafty-min.js"></script> +</pre> + +<pre class="brush: js">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"); + } +}); + +</pre> +</div> + +<p> </p> + +<p>{{ EmbedLiveSample('Rect_code', '700', '300', '', 'Games/Techniques/2D_collision_detection') }}</p> + +<h2 id="Colision_circular">Colision circular</h2> + +<p>Otra colision simple es entre dos circulos. Funciona con los centros de los dos circulos y calculando la distancia entre los dos.</p> + +<div class="hidden"> +<h6 id="Playable_code">Playable code</h6> + +<pre class="brush: html"><div id="cr-stage"></div> +<p>Mueve el circulo con las flechas. Verde = colision. Azul = no colision</p> +<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crafty/0.5.4/crafty-min.js"></script> +</pre> + +<pre class="brush: css">#cr-stage { + position: static !important; + height: 200px !important; +} +</pre> + +<pre class="brush: js">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"; + } +}); + + +</pre> +</div> + +<pre class="brush: js"><code>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! +}</code> +</pre> + +<p>{{ EmbedLiveSample('Playable_code', '700', '300', '', 'Games/Techniques/2D_collision_detection') }}</p> + +<p><strong>Note</strong>: <a href="https://jsfiddle.net/jlr7245/teb4znk0/20/">Here is another example without Canvas or external libraries.</a></p> + +<h2 id="El_teorema_de_separar_los_ejes">El teorema de separar los ejes</h2> + +<p>Esto es un algoritmo que detecta la colision entre dos poligonos convexos. Ya que es complejo, se necesitara mejorar el rendimiento (explicado en la siguiente seccion). </p> + +<h2 id="Mejorar_el_rendimiento_de_las_colisiones">Mejorar el rendimiento de las colisiones</h2> + +<p>Algunos algoritmos son sencillos de calcular, en cambio otros no. Normalmente los juegos, se dividen en dos fases: "Broad" y "Narrow".</p> + +<h3 id="Broad_Phase">Broad Phase</h3> + +<p>Esta fase consiste en conseguir una lista de todas las cosas con las que se puede colisionar. Puede ser implementado con una estructura de datos que recoge que objetos hay alrededor de nuestro objeto.</p> + +<h3 id="Narrow_Phase">Narrow Phase</h3> + +<p>Cuando tienes una lista pequeña, ya puedes detectar colision con un algoritmo.</p> diff --git a/files/es/games/techniques/3d_on_the_web/index.html b/files/es/games/techniques/3d_on_the_web/index.html new file mode 100644 index 0000000000..3944c617c6 --- /dev/null +++ b/files/es/games/techniques/3d_on_the_web/index.html @@ -0,0 +1,113 @@ +--- +title: 3D games on the Web +slug: Games/Techniques/3D_on_the_web +tags: + - Games + - Graphics + - NeedsContent + - NeedsExample + - NeedsTranslation + - TopicStub + - WebGL + - WebVR + - three.js +translation_of: Games/Techniques/3D_on_the_web +--- +<div>{{GamesSidebar}}</div><p class="summary">For rich gaming experiences on the Web the weapon of choice is WebGL, which is rendered on HTML {{htmlelement("canvas")}}. WebGL is basically an OpenGL ES 2.0 for the Web — it's a JavaScript API providing tools to build rich interactive animations and of course also games. You can generate and render dynamic 3D graphics with JavaScript that is hardware accelerated.</p> + +<h2 id="Documentation_and_browser_support">Documentation and browser support</h2> + +<p>The <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a> project documentation and specification is maintained by the <a href="https://www.khronos.org/">Khronos Group</a>, not the W3C as with most of the Web APIs. Support on modern browsers is very good, even on mobile, so you don't have to worry about that too much. The main browsers are all supporting WebGL and all you need to focus on is optimizing the performance on the devices you use.</p> + +<p>There's an ongoing effort on releasing WebGL 2.0 (based on OpenGL ES 3.0) in the near future, which will bring many improvements and will help developers build games for the modern Web using current, powerful hardware.</p> + +<h2 id="Explaining_basic_3D_theory">Explaining basic 3D theory</h2> + +<p>The basics of 3D theory centers around shapes represented in a 3D space, with a coordinate system being used to calculate their positions. See our <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Basic_theory">Explaining basic 3D theory</a> article for all the information you need.</p> + +<h2 id="Advanced_concepts">Advanced concepts</h2> + +<p>You can do a lot more with WebGL. There are some advanced concepts which you should dive into and learn more about — like shaders, collision detection, or the latest hot topic — virtual reality on the web.</p> + +<h3 id="Shaders">Shaders</h3> + +<p>It's worth mentioning shaders, which are a separate story on their own. Shaders use GLSL, a special OpenGL Shading Language with syntax similar to C that is executed directly by the graphics pipeline. They can be split into Vertex Shaders and Fragment Shaders (or Pixel Shaders) — the former transforms shape positions to real 3D drawing coordinates, while the latter computes rendering colors and other attributes. You should definitely check out <a href="/en-US/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders">GLSL Shaders</a> article to learn more about them.</p> + +<h3 id="Collision_Detection">Collision Detection</h3> + +<p>It's hard to imagine a game without the collision detection — we always need to work out when something is hitting something else. We have information available for your to learn from:</p> + +<ul> + <li><a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D collision detection</a></li> + <li><a href="/en-US/docs/Games/Techniques/3D_collision_detection">3D collision detection</a></li> +</ul> + +<h3 id="WebVR">WebVR</h3> + +<p>The concept of virtual reality is not new, but it's storming onto the web thanks to hardware advancements such as the <a href="https://www.oculus.com/en-us/rift/">Oculus Rift</a>, and the (currently experimental) <a href="/en-US/docs/Web/API/WebVR_API">WebVR API</a> for capturing information form VR hardware and making it available for use in JavaScript applications. For more, read <a href="/en-US/docs/Games/Techniques/3D_on_the_web/WebVR">WebVR — Virtual Reality for the Web</a>.</p> + +<p>There's also the <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_A-Frame">Building up a basic demo with A-Frame</a> article showing you how easy it is to build 3D environments for virtual reality using the <a href="http://aframe.io/">A-Frame</a> framework.</p> + +<h2 id="The_rise_of_libraries_and_frameworks">The rise of libraries and frameworks</h2> + +<p>Coding raw WebGL is fairly complex, but you'll want to get to grips with it in the long run, as your projects get more advanced (see our <a href="/en-US/docs/Web/API/WebGL_API">WebGL documentation</a> to get started.) For real world projects you'll probably also make use of a framework to speed up development and help you manage the project you're working on. Using a framework for 3D games also helps optimize the performance as a lot is taken care of by the tools you use, so you can focus on building the game itself.</p> + +<p>The most popular JavaScript 3D library is <a href="http://threejs.org/">Three.js</a>, a multi-purpose tool that makes common 3D techniques simpler to implement. There are other popular game development libraries and frameworks worth checking too; <a href="https://aframe.io">A-Frame</a>, <a href="https://playcanvas.com/">PlayCanvas</a> and <a href="http://www.babylonjs.com/">Babylon.js</a> are among the most recognizable ones with rich documentation, online editors and active communities.</p> + +<h3 id="Building_up_a_basic_demo_with_A-Frame">Building up a basic demo with A-Frame</h3> + +<p>A-Frame is a web framework for building 3D and VR experiences. Under the hood, it is a three.js framework with a declarative entity-component pattern, meaning we can build scenes with just HTML. See the <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_A-Frame">Building up a basic demo with A-Frame</a> subpage for the step-by-step process of creating the demo.</p> + +<h3 id="Building_up_a_basic_demo_with_Babylon.js">Building up a basic demo with Babylon.js</h3> + +<p><span class="seosummary">Babylon.js is one of the most popular 3D game engines used by developers. As with any other 3D library it provides built-in functions to help you implement common 3D functionality more quickly. See the <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Babylon.js">Building up a basic demo with Babylon.js</a> subpage for the basics of using Babylon.js, including setting up a development environment, structuring the necessary HTML, and writing the JavaScript code.</span></p> + +<h3 id="Building_up_a_basic_demo_with_PlayCanvas">Building up a basic demo with PlayCanvas</h3> + +<p>PlayCanvas is a popular 3D WebGL game engine open sourced on GitHub, with an editor available online and good documentation. See the <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_PlayCanvas">Building up a basic demo with PlayCanvas</a> subpage for high level details, and further articles showing how to create demos using the PlayCanvas library, and the online editor.</p> + +<h3 id="Building_up_a_basic_demo_with_Three.js">Building up a basic demo with Three.js</h3> + +<p>Three.js, as any other library, gives you a huge advantage: instead of writing hundreds of lines of WebGL code to build anything interesting you can use built-in helper functions to do it a lot easier and faster. See the <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">Building up a basic demo with Three.js</a> subpage for the step-by-step process of creating the demo.</p> + +<h3 id="Other_tools">Other tools</h3> + +<p>Both <a href="http://unity3d.com/">Unity</a> and <a href="https://www.unrealengine.com/">Unreal</a> can export your game to <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a> with <a href="/en-US/docs/Games/Tools/asm.js">asm.js</a>, so you're free to use their tools and techniques to build games that will be exported to the web.</p> + +<p><img alt="" src="http://end3r.github.io/MDN-Games-3D/A-Frame/img/shapes.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p> + +<h2 id="Where_to_go_next">Where to go next</h2> + +<p>With this article we just scratched the surface of what's possible with currently available technologies. You can build immersive, beautiful and fast 3D games on the Web using WebGL, and the libraries and frameworks build on top of it.</p> + +<h3 id="Source_code">Source code</h3> + +<p>You can find all the source code for this series <a href="http://end3r.github.io/MDN-Games-3D/">demos on GitHub</a>.</p> + +<h3 id="APIs">APIs</h3> + +<ul> + <li><a href="/en-US/docs/Web/API/Canvas_API">Canvas API</a></li> + <li><a href="/en-US/docs/Web/API/WebGL_API">WebGL API</a></li> + <li><a href="/en-US/docs/Web/API/WebVR_API">WebVR API</a></li> +</ul> + +<h3 id="Frameworks">Frameworks</h3> + +<ul> + <li><a href="http://threejs.org/">Three.js</a></li> + <li><a href="https://github.com/WhitestormJS/whs.js">Whitestorm.js</a> (based on Three.js)</li> + <li><a href="https://playcanvas.com/">PlayCanvas</a></li> + <li><a href="http://www.babylonjs.com/">Babylon.js</a></li> + <li><a href="http://aframe.io/">A-Frame</a></li> +</ul> + +<h3 id="Tutorials">Tutorials</h3> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">Building up a basic demo with Three.js</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Whitestorm.js">Building up a basic demo with Whitestorm.js</a></li> + <li><a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_PlayCanvas">Building up a basic demo with PlayCanvas</a></li> + <li><a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Babylon.js">Building up a basic demo with Babylon.js</a></li> + <li><a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_A-Frame">Building up a basic demo with A-Frame</a></li> +</ul> diff --git a/files/es/games/techniques/index.html b/files/es/games/techniques/index.html new file mode 100644 index 0000000000..66edeebd82 --- /dev/null +++ b/files/es/games/techniques/index.html @@ -0,0 +1,32 @@ +--- +title: Techniques for game development +slug: Games/Techniques +tags: + - Games + - Guide + - NeedsTranslation + - TopicStub +translation_of: Games/Techniques +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<div class="summary"> +<p><span class="seoSummary">This page lists essential core techniques for anyone wanting to develop games using open web technologies.</span></p> +</div> + +<dl> + <dt><a href="/en-US/docs/Games/Techniques/Async_scripts">Using async scripts for asm.js</a></dt> + <dd>Especially when creating medium to large-sized games, async scripts are an essential technique to take advantage of, so that your game's JavaScript can be compiled off the main thread and be cached for future game running, resulting in a significant performance improvement for your users. This article explains how.</dd> + <dt><a href="/en-US/docs/Apps/Developing/Optimizing_startup_performance" title="/en-US/docs/Apps/Developing/Optimizing_startup_performance">Optimizing startup performance</a></dt> + <dd>How to make sure your game starts up quickly, smoothly, and without appearing to lock up the user's browser or device.</dd> + <dt><a href="/en-US/docs/Games/WebRTC_data_channels" title="/en-US/docs/Games/WebRTC_data_channels">Using WebRTC peer-to-peer data channels</a></dt> + <dd>In addition to providing support for audio and video communication, WebRTC lets you set up peer-to-peer data channels to exchange text or binary data actively between your players. This article explains what this can do for you, and shows how to use libraries that make this easy.</dd> + <dt><a href="/en-US/docs/Games/Techniques/Efficient_animation_for_web_games">Efficient animation for web games</a></dt> + <dd>This article covers techniques and advice for creating efficient animation for web games, with a slant towards supporting lower end devices such as mobile phones. We touch on CSS transitions and CSS animations, and JavaScript loops involving {{ domxref("window.requestAnimationFrame") }}.</dd> + <dt><a href="/en-US/docs/Games/Techniques/Audio_for_Web_Games">Audio for Web Games</a></dt> + <dd>Audio is an important part of any game — it adds feedback and atmosphere. Web-based audio is maturing fast, but there are still many browser differences to negotiate. This article provides a detailed guide to implementing audio for web games, looking at what works currently across as wide a range of platforms as possible.</dd> + <dt><a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D collision detection</a></dt> + <dd>A concise introduction to collision detection in 2D games.</dd> + <dt><a href="/en-US/docs/Games/Techniques/Tilemaps">Tilemaps</a></dt> + <dd>Tiles are a very popular technique in 2D games for building the game world. These articles provide an introduction to tilemaps and how to implement them with the Canvas API.</dd> +</dl> diff --git a/files/es/games/techniques/webrtc_data_channels/index.html b/files/es/games/techniques/webrtc_data_channels/index.html new file mode 100644 index 0000000000..28687789d9 --- /dev/null +++ b/files/es/games/techniques/webrtc_data_channels/index.html @@ -0,0 +1,93 @@ +--- +title: WebRTC data channels +slug: Games/Techniques/WebRTC_data_channels +translation_of: Games/Techniques/WebRTC_data_channels +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{SeeCompatTable}}</p> + +<p>La API <a href="/en-US/docs/WebRTC" title="/en-US/docs/WebRTC">WebRTC</a> (Web Real-Time Communications - Comunicaciones WEB en tiempo real) es principalmente conocida por dar soporte en las comunicaciones de audio y video; sin embargo también ofrece canales de datos punto a punto. Este artículo explica más sobre esto y te muestra como usar librerias para implementar canales de datos en tu juego.</p> + +<h2 id="¿Qué_es_un_canal_de_datos">¿Qué es un canal de datos?</h2> + +<p>Un canal de datos WebRTC te permite enviar texto o datos binarios a través de una conexión activa a un punto. En el contexto de un juego, esto permite a los jugadores enviarse datos entre ellos, ya sea por chat de texto o por información de estado del juego. Los canales de datos vienen en dos sentidos.</p> + +<p>Los <strong>canales fiables</strong> garantizan que los mensajes que envíes lleguen al otro interlocutor y en el mismo orden en que se enviaron. Esto es análogo a un socket TCP.</p> + +<p>Los <strong>canales no confiables</strong> no ofrecen tales garantías; no se garantiza que los mensajes lleguen en un orden particular y, de hecho, no se garantiza que lleguen. Esto es análogo a un socket UDP.</p> + +<p>Tenemos <a href="/en-US/docs/WebRTC" title="/en-US/docs/WebRTC">documentación sobre WebRTC</a>. Este artículo, sin embargo, aprovechará algunas bibliotecas que pueden ayudar a trivializar el trabajo, y demostrará formas de usar la abstracción para evitar las diferencias de implementación entre los navegadores. Con suerte, por supuesto, esas diferencias se desvanecerán en el tiempo.</p> + +<h2 id="Usando_la_libreria_p2p">Usando la libreria p2p</h2> + +<p>Una biblioteca que puede usar es la biblioteca <a href="https://github.com/js-platform/p2p" title="https://github.com/js-platform/p2p">p2p</a>. Esta biblioteca proporciona una API simple para crear conexiones entre puntos y configurar transmisiones y canales de datos. También hay un componente de servidor intermediario y un agente hospedado que puedes usar en lugar de tener que configurar uno.</p> + +<div class="note"> +<p><strong>Nota:</strong> Continuaremos agregando contenido aquí pronto; hay algunos problemas de organización por resolver.</p> +</div> + +<h2 id="Compatibilidad_de_navegadores">Compatibilidad de navegadores</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>23 {{ property_prefix("webkit") }}</td> + <td>22 {{ property_prefix("moz") }}</td> + <td>{{ CompatNo() }}</td> + <td>12</td> + <td>{{ CompatUnknown() }}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatNo() }}</td> + <td>29 {{ property_prefix("webkit") }}</td> + <td>25 {{ property_prefix("moz") }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatUnknown() }}</td> + </tr> + </tbody> +</table> +</div> + +<div class="originaldocinfo"> +<h2 id="Original_Document_Information" name="Original_Document_Information">Original Document Information</h2> + +<ul> + <li>Author(s): Alan Kligman</li> + <li>Source Article: <a href="https://hacks.mozilla.org/2013/03/webrtc-data-channels-for-great-multiplayer/" title="https://hacks.mozilla.org/2013/03/webrtc-data-channels-for-great-multiplayer/">WebRTC Data Channels for Great Multiplayer</a></li> + <li>Other Contributors: Robert Nyman</li> + <li>Copyright Information: Alan Kligman, 2013</li> +</ul> +</div> + +<p> </p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/animations_and_tweens/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/animations_and_tweens/index.html new file mode 100644 index 0000000000..4528f0c95f --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/animations_and_tweens/index.html @@ -0,0 +1,117 @@ +--- +title: Animaciones e interpolaciones +slug: Games/Tutorials/2D_breakout_game_Phaser/Animations_and_tweens +tags: + - 2D + - Animacion + - Canvas + - Interpolaciones + - JavaScript + - Phaser + - Principiante + - Tutorial + - juegos +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Animations_and_tweens +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Extra_lives", "Games/Workflows/2D_Breakout_game_Phaser/Buttons")}}</p> + +<div class="summary"> +<p>Este es el paso <strong>14</strong> de 16 del tutorial <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser</a>. Puedes encontrar el código fuente tal y cómo quedaría al completar la lección en <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson14.html">Gamedev-Phaser-Content-Kit/demos/lesson14.html</a>.</p> +</div> + +<p>Para hacer el juego más vistoso y vivo, podemos usar animaciones e interpolaciones. Esto provocará una experencia de juego mejor y más entretenida. Exploraremos cómo implementar animaciones e interpolaciones Phaser en nuestro juego.</p> + +<h2 id="Animaciones">Animaciones</h2> + +<p>En Phaser, las animaciones implican tomar una hoja de sprites externa y mostrar los sprites de forma secuencial. Como ejemplo, haremos que una bola se tambalee cuando toque algo.</p> + +<p>En primer lugar toma la hoja de sprites de Github y guardala en el directorio <code>/img</code>.</p> + +<p>A continuación, cargaremos la hoja de cálculo : coloca la siguiente linea en la parte inferior de su función <code>preload()</code>:</p> + +<pre class="brush: js">game.load.spritesheet('ball', 'img/wobble.png', 20, 20); +</pre> + +<p>En lugar de cargar una sola imagen de la bola, podemos cargar toda la hoja de cálculo, una colección de imágenes diferentes. Mostraremos los sprites de forma secuencial para crear la ilusión de animación. Los dos parámetros adicionales del método <code>spritesheet()</code> determinan el ancho y la altura de cada fotograma en el archivo de spritesheet dado, indicando al programa cómo cortarlo para obtener los marcos individuales.</p> + +<h2 id="Cargando_la_animación">Cargando la animación</h2> + +<p>A continuación ve a tu función create(), encuentra la linea que carga el sprite de la bola, y debajo coloca la linea que llama a <code>animations.add()</code> que se muestra a continuación:</p> + +<pre class="brush: js">ball = game.add.sprite(50, 250, 'ball'); +ball.animations.add('wobble', [0,1,0,2,0,1,0,2,0], 24); +</pre> + +<p>Para añadir una animación al objeto usaremos el método <code>animations.add()</code>, que contiene los siguientes parámetros:</p> + +<ul> + <li>El nombre que elegimos para la animación.</li> + <li>Una matriz que define el orden en que se muestran los cuadros durante la animación. Si miras de nuevo la imagen <code>wobble.png</code>, verás que hay tres marcos. Phaser extrae estos y almacena las referencias en una matriz: posiciones 0,1, y 2. La matriz anterior dice que estamos mostrando los fotogramas 0, luego 1, después 0, etc.</li> + <li>La tasa de frames, en fps. Ya que estamos ejecutando la animación en 24fps y hay 9 cuadros, la animación se mostrará tres veces por segundo.</li> +</ul> + +<h2 id="Aplicando_la_animación_cuando_la_pelota_golpea_el_remo">Aplicando la animación cuando la pelota golpea el remo</h2> + +<p>En la llamada al método <code>arcade.collide()</code> que maneja la colisión entre la pelota y la paleta (la primera linea dentro de <code>update()</code>, ver abajo) podemos agregar un parámetro adicional que especifica una función que se ejecutará cada vez que ocurra la colisión, de la misma manera que la función <code>ballHitBrick()</code>. Actualiza la primera linea dentro de <code>update()</code> como se muestra a continuación:</p> + +<pre class="brush: js">function update() { + game.physics.arcade.collide(ball, paddle, ballHitPaddle); + game.physics.arcade.collide(ball, bricks, ballHitBrick); + paddle.x = game.input.x || game.world.width*0.5; +} +</pre> + +<p>Luego podemos crear la función <code>ballHitPaddle()</code> (con <code>ball</code> y <code>paddle</code> como parámetros por defecto), reproduciendo la animación de oscilación cuando se llama. Añade la función justo antes de la etiqueta de cierre <code></script></code>:</p> + +<pre class="brush: js">function ballHitPaddle(ball, paddle) { + ball.animations.play('wobble'); +} +</pre> + +<p>La animación se muestra cada vez que la pelota golpea la paleta. También puedes agregar la llamada a <code>animations.play()</code> dentro de la función <code>ballHitBrick()</code>, si crees que el juego se verá mejor.</p> + +<h2 id="Interpolaciones">Interpolaciones</h2> + +<p>Mientras que las animaciones reproducen sprites externos secuencialmente, las interpolaciones animan suavemente las propiedades de un objeto en el mundo del juego como el ancho o la opacidad.</p> + +<p>Agreguemos una interpolación a nuestro juego para hacer que los ladrillos desaparezcan suavemente cuando son golpeados por la pelota. Ve a la función <code>ballhitBrick()</code>, busca la linea <code>brick.kill();</code> , y reemplazala por lo siguiente:</p> + +<pre class="brush: js">var killTween = game.add.tween(brick.scale); +killTween.to({x:0,y:0}, 200, Phaser.Easing.Linear.None); +killTween.onComplete.addOnce(function(){ + brick.kill(); +}, this); +killTween.start(); +</pre> + +<p>Veamos esto para que puedas saber lo que está pasando:</p> + +<ol> + <li>Al definir una nueva interpolación, debes especificar qué propiedad se interpolará; en nuestro caso, en lugar de ocultar los ladrillos instantáneamente cuando la bola los golpea, haremos que su ancho y altura se ajusten a cero, por lo que desaparecerán. Al final usamos el método, <code>add.tween()</code>, especificando <code>brick.scale</code> como el argumento, ya que esto es lo que queremos interpolar.</li> + <li>El método <code>to()</code> define el estado del objeto al final de la interpolación. Toma un objeto que contenga los valores finales deseados del parámetro elegido (la escala toma un valor de escala, 1 es 100% del tamaño, 0 es 0% del tamaño, etc.), el tiempo de interpolación en milisegundos y el tipo de interpolación.</li> + <li>También añadiremos el controlador de eventos opcional <code>onComplete</code>, que define una función que se ejecutará cuando finalice la interpolación.</li> + <li>Lo último que debe hacer es iniciar la interpolación de inmediato utilizando <code>start()</code>.</li> +</ol> + +<p>Esa es la versión expandida de la definición de interpolación, pero también podemos usar la sintaxis abreviada:</p> + +<pre class="brush: js">game.add.tween(brick.scale).to({x:2,y:2}, 500, Phaser.Easing.Elastic.Out, true, 100); +</pre> + +<p>Esta interpolación duplicará la escala del ladrillo en medio segundo con el uso de Elastic easing, se iniciará automáticamente, y tendrá un retardo de 100 milisegundos.</p> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Puedes comprobar el código final de esta lección en la demo de abajo, y probarlo para entender mejor cómo funciona:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/9o4pakrb/","","400")}}</p> + +<h2 id="Próximos_pasos">Próximos pasos</h2> + +<p>Las animaciones y las interpolaciones se ven muy bien, pero podemos agregar más a nuestro juego. En la siguiente lección veremos cómo manejar los botones.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Extra_lives", "Games/Workflows/2D_Breakout_game_Phaser/Buttons")}}</p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/botones/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/botones/index.html new file mode 100644 index 0000000000..672d7528a6 --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/botones/index.html @@ -0,0 +1,106 @@ +--- +title: Botones +slug: Games/Tutorials/2D_breakout_game_Phaser/Botones +tags: + - 2D + - Botones + - JavaScript + - Lienzo + - Phaser + - Principiante + - Tutorial + - juegos +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Buttons +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens", "Games/Workflows/2D_Breakout_game_Phaser/Randomizing_gameplay")}}</p> + +<div class="summary"> +<p>Este es el <strong>paso 15 </strong>de 16 del tutorial <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser</a>. Puedes encontrar el código fuente como debería quedar después de completar el tutorial en <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson15.html">Gamedev-Phaser-Content-Kit/demos/lesson15.html</a>.</p> +</div> + +<p><span class="seoSummary">En lugar de comenzar el juego de inmediato, podemos dejar la decisión en el jugador añadiendo un botón de Inicio que pueda pulsar. Vamos a investigar cómo hacerlo.</span></p> + +<h2 id="Variables_nuevas">Variables nuevas</h2> + +<p>Necesitamos una variable para almacenar un valor booleano que represente si el juego se está jugando actualmente o no, y otra para representar a nuestro botón. Añade las siguientes lineas a tu declaración de variables:</p> + +<pre class="brush: js">var playing = false; +var startButton; +</pre> + +<h2 id="Cargando_el_botón_de_spritesheet">Cargando el botón de spritesheet</h2> + +<p>Podemos cargar el botón de spritesheet de la misma manera que cargamos la animación del movimiento de la pelota. Añade lo siguiente al botón de la función <code>preload()</code>:</p> + +<pre class="brush: js">game.load.spritesheet('button', 'img/button.png', 120, 40); +</pre> + +<p>El marco de un solo botón mide 120 pixels de ancho y 40 pixels de alto.</p> + +<p>También se debe tomar el botón de spritesheet de <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/img/button.png">Github</a>, y guardarlo en el directorio <code>/img</code>.</p> + +<h2 id="Añadiendo_el_botón_al_juego">Añadiendo el botón al juego</h2> + +<p>Para añadir el botón al juego usaremos el método <code>add.button</code>. Añade las siguientes lineas del botón a la función <code>create()</code>:</p> + +<pre class="brush: js">startButton = game.add.button(game.world.width*0.5, game.world.height*0.5, 'button', startGame, this, 1, 0, 2); +startButton.anchor.set(0.5); +</pre> + +<p>Los parámetros del método <code>button()</code> son los siguientes:</p> + +<ul> + <li>Las coordenadas x e y del botón.</li> + <li>El nombre del elemento gráfico que se mostrará en el botón.</li> + <li>Una función de callback que se ejecutará cuando se presione el botón.</li> + <li>Una referencia a <code>this</code> para especificar el contexto de ejecución.</li> + <li>Los marcos que usaremos para los eventos <em>over</em>, <em>out</em> and <em>down</em>.</li> +</ul> + +<div class="note"> +<p><strong>Nota</strong>: El evento over es igual al hover, out es cuando el puntero se mueve fuera del botón y down cuando el botón es presionado.</p> +</div> + +<p>Ahora necesitamos definir la función <code>startGame()</code> referenciada en el siguiente código:</p> + +<pre class="brush: js">function startGame() { + startButton.destroy(); + ball.body.velocity.set(150, -150); + playing = true; +} +</pre> + +<p>Cuando se presiona el botón, se borra el botón, se establecen la velocidad inicial de la pelota y la variable <code>playing</code> a <code>true</code>.</p> + +<p>Para terminar con esta sección, vuelve a la función <code>create()</code>, encuentra la linea <code>ball.body.velocity.set(150, -150);</code>, y bórrala. Solo queremos que la pelota se mueva cuando se presione el botón, no antes.</p> + +<h2 id="Mantener_la_paleta_inmóvil_antes_de_que_comience_el_juego">Mantener la paleta inmóvil antes de que comience el juego</h2> + +<p>Funciona como se esperaba, pero aún podemos mover la paleta cuando el juego aún no ha comenzado, lo que parece un poco tonto. Para impedir esto, podemos aprovechar la variable <code>playing</code> y hacer que la paleta solo se mueva cuando el juego haya empezado. Para hacer esto, ajustamos la función <code>update()</code> así:</p> + +<pre class="brush: js">function update() { + game.physics.arcade.collide(ball, paddle, ballHitPaddle); + game.physics.arcade.collide(ball, bricks, ballHitBrick); + if(playing) { + paddle.x = game.input.x || game.world.width*0.5; + } +} +</pre> + +<p>De esta manera la paleta es inamovible hasta que todo esté cargado y preparado, pero sí cuando el juego actual comience.</p> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Puedes comprobar el código acabado en esta lección en la demo de abajo, y jugar para entender mejor cómo funciona:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/1rpj71k4/","","400")}}</p> + +<h2 id="Siguientes_pasos">Siguientes pasos</h2> + +<p>La última cosa que haremos en esta serie de artículos es hacer el juego más interesante añadiendo algo de aleatorización a la forma en la que la pelota rebota con la paleta.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens", "Games/Workflows/2D_Breakout_game_Phaser/Randomizing_gameplay")}}</p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/collision_detection/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/collision_detection/index.html new file mode 100644 index 0000000000..e2fa08acf6 --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/collision_detection/index.html @@ -0,0 +1,61 @@ +--- +title: Collision detection +slug: Games/Tutorials/2D_breakout_game_Phaser/Collision_detection +tags: + - 2D + - Deteccion de colision + - JavaScript + - Lienzo + - Phaser + - Principiante + - Tutorial + - juegos +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Collision_detection +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field", "Games/Workflows/2D_Breakout_game_Phaser/The_score")}}</p> + +<div class="summary"> +<p>Este es el paso<strong> 10 </strong>de un total de 16, del tutorial de <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser.</a> Puedes encontrar el código fuente tal y cómo queda al completar la lección en <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson10.html">Gamedev-Phaser-Content-Kit/demos/lesson10.html</a>.</p> +</div> + +<p><span class="seoSummary">Ahora en el próximo desafío: la detección de colisiones entre la bola y los ladrillos. Por suerte, podemos usar el motor de física para verificar las colisiones no solo entre objetos individuales (como la pelota y la paleta), sino también entre un objeto y el grupo.</span></p> + +<h2 id="Detección_de_colisión_ladrillobola">Detección de colisión ladrillo/bola</h2> + +<p>El motor de físicas hace que todo sea mucho más fácil - solo necesitamos agregar dos simples fragmentos de código. Primero, añade una nueva línea dentro de la función <code>update()</code> que verifique la detección de las colisiones entre la bola y los ladrillos, como se muestra a continuación:</p> + +<pre class="brush: js">function update() { + game.physics.arcade.collide(ball, paddle); + game.physics.arcade.collide(ball, bricks, ballHitBrick); + paddle.x = game.input.x || game.world.width*0.5; +} +</pre> + +<p>La posición de la bola se calcula contra las posiciones de todos los ladrillos del grupo. El tercer parámetro opcional es la función que se ejecuta cuando se produce una colisión: <code>ballHitBrick()</code>. Crea esta nueva función en la parte inferior de tu código, justo antes de la etiqueta de cierre <code></script></code>, como sigue:</p> + +<pre class="brush: js">function ballHitBrick(ball, brick) { + brick.kill(); +} +</pre> + +<p>¡Y ya está! Vuelve a cargar el código, y verás que la nueva detección de colisión funciona correctamente.</p> + +<p>Gracias a Phaser, se pasan dos parámetros a la función: el primero es la bola, que definimos explícitamente en el método de colisión, y el segundo es el único bloque del grupo de ladrillos con el que la bola está colisionando. Dentro de la función, eliminamos el bloque en cuestión de la pantalla ejecutando el método<code>kill()</code> en él.</p> + +<p>Seguro que esperarabas tener que escribir muchos más cálculos para implementar la detección de colisiones cuando se utiliza<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection"> JavaScript</a> puro. Esa es la belleza de usar el marco: puedes dejar un montón de código aburrido a Phaser, y enfocarte en las partes más divertidas e interesantes de hacer un juego.</p> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Puedes consultar el código terminado para esta lección en la demo que aparece a continuación, y jugar con él para comprender mejor cómo funciona:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/wwneakwf/","","400")}}</p> + +<h2 id="Próximos_pasos">Próximos pasos</h2> + +<p>Podemos golpear los ladrillos y eliminarlos, lo cual sería una buena adición al juego. Sería incluso mejor contar los ladrillos destruidos incrementando la puntuación como resultado.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field", "Games/Workflows/2D_Breakout_game_Phaser/The_score")}}</p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/extra_lives/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/extra_lives/index.html new file mode 100644 index 0000000000..83811d20e2 --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/extra_lives/index.html @@ -0,0 +1,127 @@ +--- +title: Extra lives +slug: Games/Tutorials/2D_breakout_game_Phaser/Extra_lives +tags: + - 2D + - JavaScript + - Lienzo + - Lona + - Phaser + - Principiante + - Tutorial + - Vidas + - juegos +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Extra_lives +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Win_the_game", "Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens")}}</p> + +<div class="summary"> +<p>Este es el paso <strong>número 13</strong> de 16 del tutorial <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser</a>. Puedes encontrar el código fuente tal y cómo queda al completar la lección en <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson13.html">Gamedev-Phaser-Content-Kit/demos/lesson13.html</a>.</p> +</div> + +<p><span class="seoSummary">Podemos hacer que el juego sea divertido por más tiempo añadiendo vidas. En este artículo implementaremos un sistema de vidas, para que el jugador pueda seguir jugando hasta que haya perdido tres vidas, no solo una.</span></p> + +<h2 id="Nuevas_variables">Nuevas variables</h2> + +<p>Añade las siguientes líneas debajo de las ya existentes en tú código:</p> + +<pre class="brush: js">var lives = 3; +var livesText; +var lifeLostText; +</pre> + +<p>Estas almacenarán las vidas, el texto que muestra el número de vidas restante, y el texto que se muestra en pantalla cuando el jugador pierde todas sus vidas.</p> + +<h2 id="Definiendo_las_nuevas_etiquetas_de_texto">Definiendo las nuevas etiquetas de texto</h2> + +<p>Definir los textos es parecido a algo que ya hicimos en la lección de la <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/The_score"> puntuación</a>. Añade las siguientes líneas debajo de la definición de <code>scoreText</code> dentro de la función <code>create()</code>:</p> + +<pre class="brush: js">livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, { font: '18px Arial', fill: '#0095DD' }); +livesText.anchor.set(1,0); +lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', { font: '18px Arial', fill: '#0095DD' }); +lifeLostText.anchor.set(0.5); +lifeLostText.visible = false; +</pre> + +<p>Los objetos <code>livesText</code> y <code>lifeLostText</code> se parecen mucho al <code>scoreText</code> — definen una posición en la pantalla, el texto actual a mostrar, y el estilo de la fuente. El primero está anclado en el borde superior derecho para alinearse con la pantalla y el segundo está centrado, ambos usan <code>anchor.set()</code>.</p> + +<p>El texto <code>lifeLostText</code> se mostrará solamente cuando se pierda la vida, así que su visibilidad al principio será <code>false</code>.</p> + +<h3 id="Haciendo_nuestro_estilo_de_texto_DRY">Haciendo nuestro estilo de texto DRY</h3> + +<p>Cómo probablemente hayas notado, estamos usando el mismo estilo para los tres textos: <code>scoreText</code>, <code>livesText</code> y <code>lifeLostText</code>. Si quisiéramos cambiar el tamaño de la fuente o el color tendríamos que hacerlo en muchos lugares. Para hacer eso más fácil de mantener en el futuro podemos crear una variable separada que almacenará nuestro estilo, la llamaremos <code>textStyle</code> y la colocaremos después de las definiciones de los textos:</p> + +<pre class="brush: js">textStyle = { font: '18px Arial', fill: '#0095DD' }; +</pre> + +<p>Ahora podemos usar esta variable para dar estilo a nuestros textos — actualiza tú código para que cada una de las múltiples instancias de estilo de tú texto sean reemplazadas por la variable:</p> + +<pre class="brush: js">scoreText = game.add.text(5, 5, 'Points: 0', textStyle); +livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, textStyle); +livesText.anchor.set(1,0); +lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', textStyle); +lifeLostText.anchor.set(0.5); +lifeLostText.visible = false; +</pre> + +<p>De esta manera cambiando la fuente en una variable aplicará los cambios en todos los sitios donde se esté usando.</p> + +<h2 id="El_código_de_manejo_de_vidas">El código de manejo de vidas</h2> + +<p>Para implementar las vidas en nuestro juego, primero cambiaremos la función de bote de la pelota por el evento <code>onOutOfBounds</code>.En lugar de ejecutar una función anónima y mostrar un mensaje de alerta :</p> + +<pre class="brush: js"><s>ball.events.onOutOfBounds.add(function(){ + alert('Game over!'); + location.reload(); +}, this);</s> +</pre> + +<p>Vamos a asignar una nueva función llamada <code>ballLeaveScreen</code>; borra el manejador de evento anterior (mostrado arriba) y sustitúyelo por la siguiente línea:</p> + +<pre class="brush: js">ball.events.onOutOfBounds.add(ballLeaveScreen, this); +</pre> + +<p>Queremos decrementar el número de vidas cada vez que la pelota abandone el lienzo.Añade la definición de la función <code>ballLeaveScreen()</code> al final de tu código :</p> + +<pre class="brush: js">function ballLeaveScreen() { + lives--; + if(lives) { + livesText.setText('Lives: '+lives); + lifeLostText.visible = true; + ball.reset(game.world.width*0.5, game.world.height-25); + paddle.reset(game.world.width*0.5, game.world.height-5); + game.input.onDown.addOnce(function(){ + lifeLostText.visible = false; + ball.body.velocity.set(150, -150); + }, this); + } + else { + alert('You lost, game over!'); + location.reload(); + } +} +</pre> + +<p>En lugar de mostrar el mensaje de alerta cuando pierdes una vida, primero quitaremos una vida del número actual y comprobaremos que no sea cero. Si lo es, quiere decir que el jugador tiene todavía algunas vidas y puede continuar jugando — verá el mensaje de pérdida de vida, las posiciones de la pelota y la paleta se reiniciarán en la pantalla y en la siguiente entrada (click o toque) el mensaje se ocultará y la pelota comenzará a moverse de nuevo.</p> + +<p>Cuando el número de vidas disponibles alcanza el cero, el juego termina y se muestra un mensaje de "game over".</p> + +<h2 id="Eventos">Eventos</h2> + +<p>Probablemente hayas notado las llamadas a los métodos <code>add()</code> y <code>addOnce()</code> en los dos bloques de código de arriba y te hayas preguntado en qué se diferencian. La diferencia es que el método <code>add()</code> vincula la función dada y hace que se ejecute cada vez que se produce el evento, mientras que <code>addOnce()</code> es útil cuando deseas que la función enlazada se ejecute solo una vez y luego se desvincule para que no se ejecute otra vez. En nuestro caso, en cada evento <code>outOfBounds</code> el <code>ballLeaveScreen</code> se ejecutará, pero cuando la pelota abandona la pantalla solo queremos quitar el mensaje de la pantalla una sola vez.</p> + +<h2 id="Compare_tu_código">Compare tu código</h2> + +<p>Puedes consultar el código terminado de esta lección en la demo de abajo, y jugar para entender mejor cómo funciona:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/yk1c5n0b/","","400")}}</p> + +<h2 id="Próximos_pasos">Próximos pasos</h2> + +<p>Las vidas hacen el juego más indulgente — si pierdes una vida, todavía tienes dos más con las que continuar jugando. Ahora expandiremos la apariencia del juego añadiendo <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens">animaciones e interpolaciones</a>.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Win_the_game", "Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens")}}</p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/game_over/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/game_over/index.html new file mode 100644 index 0000000000..1b948ac63e --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/game_over/index.html @@ -0,0 +1,55 @@ +--- +title: Game over +slug: Games/Tutorials/2D_breakout_game_Phaser/Game_over +tags: + - 2D + - Canvas + - JavaScript + - Principiante + - Tutorial + - game over + - juego + - juego terminado +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Game_over +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls", "Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field")}}</p> + +<div class="summary"> +<p>Este es el paso numero <strong>ocho </strong>de los 16 del tutorial de <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser</a>. Puedes encontrar el código fuente de como debería verse, después de haber completado esta lección en <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson08.html">Gamedev-Phaser-Content-Kit/demos/lesson08.html</a>.</p> +</div> + +<p>Para hacer el juego más interesante podemos introducir la habilidad de perder --- si no golpeas la pelota antes de que alcance el borde inferior de la pantalla, se acabará el juego.</p> + +<h2 id="Cómo_perder">Cómo perder</h2> + +<p>Para proporcionar la habilidad de perder, deberemos inhabilitar las bolas que colisionen con el borde inferior de la pantalla. Añade el siguiente código dentro de la función <code>create()</code>; justo después de definir los atributos de las bolas está bien:</p> + +<pre class="brush: js">game.physics.arcade.checkCollision.down = false; +</pre> + +<p>Esto hará que a las tres paredes(arriba, izquierda y derecha) les rebote la bola, pero la cuarta pared (abajo) desaparecerá, dejando que la bola caiga fuera de la pantalla si la pala no lo alcanza. Necesitamos una forma de detectar esto y actuar en consecuencia. Añade las siguientes lineas justo debajo de la nueva linea, añadida anteriormente:</p> + +<pre class="brush: js">ball.checkWorldBounds = true; +ball.events.onOutOfBounds.add(function(){ + alert('Game over!'); + location.reload(); +}, this); +</pre> + +<p>Añadiendo esas lineas conseguiremos que la bola compruebe los límites de su mundo(en nuestro caso la pantalla) y ejecute la función vinculada al evento <code>onOutOfBounds</code>. Cuando hagas click en el mensaje de alerta resultante, la página se reseteará, asi podrás jugar otra vez.</p> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Puedes comprobar el código final para esta lección en la demo de abajo, y jugar con ello para entender mejor como funciona:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/436bckb7/","","400")}}</p> + +<h2 id="Siguientes_pasos">Siguientes pasos</h2> + +<p>Ahora el juego básico está hecho, hagamos mas interesante el caso introduciendo ladrillos para romper --- es hora de <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field">construir el campo de ladrillos</a>.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls", "Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field")}}</p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/index.html new file mode 100644 index 0000000000..5d539b7442 --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/index.html @@ -0,0 +1,63 @@ +--- +title: 2D breakout game using Phaser +slug: Games/Tutorials/2D_breakout_game_Phaser +tags: + - 2D + - Beginner + - Canvas + - Games + - JavaScript + - NeedsTranslation + - Phaser + - TopicStub + - Tutorial +translation_of: Games/Tutorials/2D_breakout_game_Phaser +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{Next("Games/Workflows/2D_Breakout_game_Phaser/Initialize_the_framework")}}</p> + +<p class="summary">In this step-by-step tutorial we create a simple mobile <strong>MDN Breakout</strong> game written in JavaScript, using the <a href="http://phaser.io/">Phaser</a> framework.</p> + +<p>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 Phaser framework to implement fundamental game mechanics like rendering and moving images, collision detection, control machanisms, framework-specific helper functions, animations and tweens, and winning and losing states.</p> + +<p>To get the most out of this series of articles you should already have basic to intermediate <a href="/en-US/Learn/Getting_started_with_the_web/JavaScript_basics">JavaScript</a> knowledge. After working through this tutorial you should be able to build your own simple Web games with Phaser.</p> + +<p><img alt="Gameplay screen from the game MDN Breakout created with Phaser where you can use your paddle to bounce the ball and destroy the brick field, with keeping the points and lives." src="https://mdn.mozillademos.org/files/11323/mdn-breakout-phaser.png" style="display: block; height: 320px; margin: 0px auto; width: 480px;"></p> + +<h2 id="Lesson_details">Lesson details</h2> + +<p>All the lessons — and the different versions of the <a href="https://end3r.github.io/Gamedev-Phaser-Content-Kit/demos/lesson16.html">MDN Breakout game</a> we are building together — are <a href="https://end3r.github.io/Gamedev-Phaser-Content-Kit/demos/">available on GitHub</a>:</p> + +<ol> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Initialize_the_framework">Initialize the framework</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Scaling">Scaling</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen">Load the assets and print them on screen</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Move_the_ball">Move the ball</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Physics">Physics</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Bounce_off_the_walls">Bounce off the walls</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls">Player paddle and controls</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Game_over">Game over</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field">Build the brick field</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Collision_detection">Collision detection</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/The_score">The score</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Win_the_game">Win the game</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Extra_lives">Extra lives</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens">Animations and tweens</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Buttons">Buttons</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Randomizing_gameplay">Randomizing gameplay</a></li> +</ol> + +<p>As a note on learning paths — starting with pure JavaScript is the best way to get a solid knowledge of web game development. If you are not already familiar with pure JavaScript game development, we'd suggest that you first work through this series' counterpart, <a href="/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript">2D breakout game using pure JavaScript</a>.</p> + +<p>After that, you can pick any framework you like and use it for your projects; we've chosen Phaser as it is a good solid framework, with a good support and community available, and a good set of plugins. Frameworks speed up development time and help take care of the boring parts, allowing you to concentrate on the fun stuff. However, frameworks are not always perfect, so if something unexpected happens or you want to write some functionality that the framework doesn't provide, you'll need some pure JavaScript knowledge.</p> + +<div class="note"> +<p><strong>Note</strong>: This series of articles can be used as material for hands-on game development workshops. You can also make use of the <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit">Gamedev Phaser Content Kit</a> based on this tutorial if you want to give a talk about game development with Phaser.</p> +</div> + +<h2 id="Next_steps">Next steps</h2> + +<p>Ok, let's get started! Head to the first part of the series — <a href="/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Initialize_the_framework">Initialize the framework</a>.</p> + +<p>{{Next("Games/Workflows/2D_Breakout_game_Phaser/Initialize_the_framework")}}</p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/initialize_the_framework/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/initialize_the_framework/index.html new file mode 100644 index 0000000000..efa8dc6cd9 --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/initialize_the_framework/index.html @@ -0,0 +1,81 @@ +--- +title: Inicializar el framework +slug: Games/Tutorials/2D_breakout_game_Phaser/Initialize_the_framework +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Initialize_the_framework +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser", "Games/Workflows/2D_Breakout_game_Phaser/Scaling")}}</p> + +<div class="summary"> +<p>Este es el primero de los 16 tutoriales para aprender a usar <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser</a>. Luego de completar este tutorial, puede encontrar el código fuente de esta sección en <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson01.html">Gamedev-Phaser-Content-Kit/demos/lesson01.html</a>.</p> +</div> + +<p><span class="seoSummary">Antes de que podamos comenzar a escribir la funcionalidad del juego, necesitamos crear una estructura básica para procesarlo. Esto podemos hacerlo usando HTML — el framework de Phaser va a generar el elemento {{htmlelement("canvas")}} requerido.</span></p> + +<h2 id="El_HTML_del_juego">El HTML del juego</h2> + +<p>La estructura del elemento HTML es bastante simple, ya que el juego va ser renderizado por completo en el elemento {{htmlelement("canvas")}} generado por el framework. Utilizando su editor de texto favorito, cree un nuevo documento HTML, guárdelo como <code>index.html</code>, en una ubicación sensata y agregue el siguiente código:</p> + +<pre class="brush: html"><!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <title>Gamedev Phaser Workshop - lesson 01: Initialize the framework</title> + <style>* { padding: 0; margin: 0; }</style> + <script src="js/phaser.min.js"></script> +</head> +<body> +<script> + var game = new Phaser.Game(480, 320, Phaser.AUTO, null, { + preload: preload, create: create, update: update + }); + function preload() {} + function create() {} + function update() {} +</script> +</body> +</html> +</pre> + +<h2 id="Descargando_el_código_de_Phaser">Descargando el código de Phaser</h2> + +<p>A continuación, necesitamos pasar por el proceso de descargar el código fuente de Phaser y aplicarlo a nuestro documento HTML.</p> + +<ol> + <li>Ir a la página de descarga del <a href="http://phaser.io/download/stable">Phaser download page</a>.</li> + <li>Elegir la opción que mas le convenga — Recomendaría la opción <em>min.js</em> ya que mantiene el codigo más pequeño, y es poco probable que tenga que pasar por el código fuente de todos modos.</li> + <li>Guarde el código Phaser dentro de un directorio<code>/js</code> en la misma ubicación que su archivo <code>index.html</code>.</li> + <li>Actualice el valor <code>src</code> del primer elemento {{htmlelement("script")}} como se muestra arriba.</li> +</ol> + +<h2 id="Caminando_a_través_de_lo_que_tenemos_hasta_ahora">Caminando a través de lo que tenemos hasta ahora</h2> + +<p>En este punto, tenemos un <code>charset</code> definido, {{htmlelement("title")}} y algunos CSS básicos en el encabezado para restablecer el <code>margin</code> y el <code>padding</code>. También tenemos un elemento {{htmlelement("script")}} para aplicar el código fuente del Phaser a la página. El cuerpo contiene un segundo elemento {{htmlelement("script")}}, donde vamos a escribir el codigo JavaScript para renderizar el juego y controlarlo.</p> + +<p>El elemento {{htmlelement("canvas")}} es generado automaticamente por el framework. Estamos inicializandolo creando un nuevo objeto <code>Phaser.Game</code> y asignandolo a la variable del juego. Los parametros son:</p> + +<ul> + <li>El ancho y el alto para configurar el {{htmlelement("canvas")}}.</li> + <li>El método de renderizado. Las otras tres opciones son <code>AUTO</code>, <code>CANVAS</code> y <code>WEBGL</code>. Podemos establecer uno de los dos últimos explícitamente o usar <code>AUTO</code> para dejar que Phaser decida cuál usar. Usualmente usa WebGL si está disponible en el navegador, volviendo a Canvas 2D si no es así.</li> + <li>El <code>id</code> del {{htmlelement("canvas")}} se utilizará para renderizar si ya existe en la pagina (hemos especificado null porque queremos que Phaser cree el suyo propio).</li> + <li>Los nombres que se usarán para las tres funciones claves del Phaser que cargan e incian el juego, y actualizan el bucle del juego en cada fotograma; usaremos los mismos nombres para mantenerlo limpio. + <ul> + <li><code>preload</code> se encargará de precargar los assets</li> + <li><code>create</code> se ejecuta una vez cuando todo está cargado y listo</li> + <li><code>update</code> se ejecuta en cada fotograma.</li> + </ul> + </li> +</ul> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Aquí está el código fuente completo de la primera lección, ejecutándose en un JSFiddle:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/h6cwzv2b/","","400")}}</p> + +<h2 id="Pasos_siguientes">Pasos siguientes</h2> + +<p>Ahora hemos configurado el HTML básico y aprendido un poco sobre la inicialización de Phaser, continuemos con la segunda lección y aprendamos sobre <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Scaling">scaling</a>.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser", "Games/Workflows/2D_Breakout_game_Phaser/Scaling")}}</p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/move_the_ball/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/move_the_ball/index.html new file mode 100644 index 0000000000..c211b0512d --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/move_the_ball/index.html @@ -0,0 +1,51 @@ +--- +title: Move the ball +slug: Games/Tutorials/2D_breakout_game_Phaser/Move_the_ball +tags: + - 2D + - Emocionante + - JavaScript + - Lienzo + - Phaser + - Principiante + - Tutorial + - juegos +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Move_the_ball +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen", "Games/Workflows/2D_Breakout_game_Phaser/Physics")}}</p> + +<div class="summary"> +<p>Este es el <strong>4º </strong>paso sobre 16 del tutorial <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser</a>. Puedes encontrar el código fuente tal y como quedaría al completar la lección en <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson04.html">Gamedev-Phaser-Content-Kit/demos/lesson04.html</a>.</p> +</div> + +<p><span class="seoSummary">Tenemos a nuestra pelota azul pintada en la pantalla, pero sin hacer nada — Estaría bien hacerla moverse de algún modo. Este artículo muestra como hacerlo.</span></p> + +<h2 id="Actualizando_la_posición_de_la_pelota_en_cada_marco">Actualizando la posición de la pelota en cada marco</h2> + +<p>¿Recuerdas la función <code>update()</code> y su definición? El código del interior del cuadro se ejecuta en cada cuadro, así que ese es el mejor lugar para colocar el código que actualiza la posición de la pelota en la pantalla. Añade las siguientes lineas a la función <code>update()</code>, como se muestra a continuación:</p> + +<pre class="brush: js">function update() { + ball.x += 1; + ball.y += 1; +} +</pre> + +<p>El código de arriba incrementa en 1 las propiedades <code>x</code> e <code>y</code> , las cuales representan las coordenadas de la pelota en el lienzo, en cada cuadro. Vuelve a cargar el index.html y deberías ver la pelota rodando a través de la pantalla.</p> + +<h2 id="Compara_tú_código">Compara tú código</h2> + +<p>Puedes comprobar el código terminado de esta lección en la demo de abajo, y jugar para entender mejor cómo funciona:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/g1cfp0vv/","","400")}}</p> + +<h2 id="Próximos_pasos">Próximos pasos</h2> + +<p>El siguiente paso es añadir una detección básica de colisión, para que la pelota pueda rebotar con las paredes.Esto nos llevará unas cuántas líneas de código — un paso significativamente más complejo que lo que hemos visto hasta ahora especialmente si queremos añadir la paleta y colisiones con los ladrillos — pero afortunadamente Phaser nos permite hacerlo de una forma mucho más sencilla que si lo quisieramos hacer usando JavaScript puro.</p> + +<p>En cualquier caso, antes de hacer todo esto debemos introducir los motores de Física de Phaser y hacer un poco de trabajo de configuración.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen", "Games/Workflows/2D_Breakout_game_Phaser/Physics")}}</p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/rebotar_en_las_paredes/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/rebotar_en_las_paredes/index.html new file mode 100644 index 0000000000..0276d5dc7f --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/rebotar_en_las_paredes/index.html @@ -0,0 +1,51 @@ +--- +title: Rebotar en las paredes +slug: Games/Tutorials/2D_breakout_game_Phaser/Rebotar_en_las_paredes +tags: + - 2D + - Canvas + - JavaScript + - Phaser + - Principiante + - Tutorial + - fuerte + - juegos +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Bounce_off_the_walls +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Physics", "Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls")}}</p> + +<div class="summary"> +<p>Este es el <strong>paso 6</strong> de 16 del <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">tutorial de Gamedev Phaser</a>. Puedes encontrar el código fuente como debería verse después de completar esta lección en <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson06.html">Gamedev-Phaser-Content-Kit/demos/lesson06.html</a>.</p> +</div> + +<p>Ahora que las físicas han sido introducidas,<span class="seoSummary">podemos empezar a implementar la detección de colisión en el juego — </span>primero miraremos las paredes<span class="seoSummary">.</span></p> + +<h2 id="Rebotando_en_las_fronteras_del_mundo">Rebotando en las fronteras del mundo</h2> + +<p>La forma más fácil de hacer que nuestra bola rebote en las paredes es decirle al marco que queremos tratar los límites del elemento {{htmlelement("canvas")}} como paredes y no dejar que la pelota pase por ellos. En Phaser esto se puede puede lograr usando la propiedad <code>collideWorldsBound</code>. Añade esta linea justo después de la llamada al método <code>game.physics.enable()</code> existente:</p> + +<pre class="brush: js">ball.body.collideWorldBounds = true; +</pre> + +<p>Ahora la bola se detendrá en el borde de la pantalla en lugar de desaparecer, pero no rebota. Para que esto ocurra tenemos que configurar su rebote. Añade la siguiente línea debajo de la anterior:</p> + +<pre class="brush: js">ball.body.bounce.set(1); +</pre> + +<p>Intenta recargar index.html otra vez — ahora deberías ver la pelota rebotando en todas las paredes y moviéndose dentro del área del lienzo.</p> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Puedes consultar el código terminado para esta lección en la demostración en vivo a continuación, y jugar con él para comprender mejor cómo funciona:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/dcw36opz/","","400")}}</p> + +<h2 id="Próximos_pasos">Próximos pasos</h2> + +<p>Esto está empezando a parecerse más a un juego ahora, Pero no podemos controlarlo de ninguna manera — es hora de que introduzacamos <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls">reproductor de paletas y controles</a>.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Physics", "Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls")}}</p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/scaling/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/scaling/index.html new file mode 100644 index 0000000000..bec5641a07 --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/scaling/index.html @@ -0,0 +1,56 @@ +--- +title: Scaling +slug: Games/Tutorials/2D_breakout_game_Phaser/Scaling +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Scaling +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Initialize_the_framework", "Games/Workflows/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen")}}</p> + +<div class="summary"> +<p>Este es el <strong>2do paso</strong> de los 16 del tutorial <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser tutorial</a>. Puede encontrar el código fuente como debería verse luego de completar esta lección en <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson02.html">Gamedev-Phaser-Content-Kit/demos/lesson02.html</a>.</p> +</div> + +<p><span class="seoSummary">Scaling se refiere a como el lienzo del juego se escalará en diferentes tamaños de pantalla. Podemos hacer que la escala del juego se ajuste automáticamente a cualquier tamaño de pantalla durante la etapa de precarga por lo que no debemos preocuparnos más tarde.</span></p> + +<h2 id="El_objeto_scale_de_Phaser">El objeto scale de Phaser</h2> + +<p>Hay un objeto especial <code>scale</code> disponible en Phaser con algunos métodos prácticos y propiedades disponibles. Actualice su función <code>preload()</code> existente de la siguiente manera:</p> + +<pre class="brush: js">function preload() { + game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL; + game.scale.pageAlignHorizontally = true; + game.scale.pageAlignVertically = true; +} +</pre> + +<p><code>scaleMode</code> tiene algunas opciones diferentes disponibles para ver como se puede escalar el Canvas (lienzo):</p> + +<ul> + <li><code>NO_SCALE</code> — nada está escalado.</li> + <li><code>EXACT_FIT</code> — escala el lienzo para llenar todo el espacio disponible tanto vertical como horizontalmente, sin conservar la relación de aspecto.</li> + <li><code>SHOW_ALL</code> — escala el lienzo, pero mantiene intacta la relación de aspecto, por lo que las imagenes no se verán sesgadas como en el modo anterior. Puede haber franjas negras visibles en los bordes de la pantalla, pero podemos vivir con eso.</li> + <li><code>RESIZE</code> — creates the canvas with the same size as the available width and height, so you have to place the objects inside your game dynamically; this is more of an advanced mode.</li> + <li><code>USER_SCALE</code> — le permite tener una escala dinámica personalizada, calculando el tamaño, la escala y la relación por su cuenta; de nuevo, esto es mas un modo avanzado. </li> +</ul> + +<p>Las otras dos lineas de código en la función <code>preload()</code> son responsables de alinear el elemento canvas horizontal y verticalmente, por lo que siempre se centra en la pantalla independientemente del tamaño.</p> + +<h2 id="Agregar_un_color_de_fondo_de_lienzo_personalizado">Agregar un color de fondo de lienzo personalizado</h2> + +<p>También podemos agregar un color de fondo personalizado a nuestro lienzo, por lo que no se mantendrá negro. El objeto <code>stage</code> tiene una propiedad <code>backgroundColor</code> para este propósito, que podemos establecer usando la sintaxis de definición de color de CSS. Agregue la siguiente línea debajo de las otras tres que agregó anteriormente:</p> + +<pre class="brush: js">game.stage.backgroundColor = '#eee'; +</pre> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Puedes verificar el código final de esta lección en la demostración en vivo a continuación, y jugar con la misma para entender mejor como trabaja:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/6a64vecL/","","400")}}</p> + +<h2 id="Pasos_siguientes">Pasos siguientes</h2> + +<p>Ahora que hemos configurado el escalamiento de nuestro juego, continuemos con la tercera lección y descubramos cómo <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen">cargar los assets e imprimirlos en la pantalla</a>.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Initialize_the_framework", "Games/Workflows/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen")}}</p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/the_score/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/the_score/index.html new file mode 100644 index 0000000000..77c688cc77 --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/the_score/index.html @@ -0,0 +1,78 @@ +--- +title: The score +slug: Games/Tutorials/2D_breakout_game_Phaser/The_score +tags: + - 2D + - JavaScript + - Lienzo + - Phaser + - Principiantes + - Puntuación + - Tutorial + - juegos +translation_of: Games/Tutorials/2D_breakout_game_Phaser/The_score +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Collision_detection", "Games/Workflows/2D_Breakout_game_Phaser/Win_the_game")}}</p> + +<div class="summary"> +<p>Este es el paso <strong>11</strong><strong>º </strong>de 16 del tutorial de <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser</a>. Puedes encontrar el código fuente tal y como quedaría al completar la lección en <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson11.html">Gamedev-Phaser-Content-Kit/demos/lesson11.html</a>.</p> +</div> + +<p><span class="seoSummary">Tener puntuación puede hacer el juego más interesante — puedes intentar batir tu mejor puntuación, a la de tus amigos. En este artículo añadiremos un sistema de puntuación al juego.</span></p> + +<p>Usaremos una variable separada para almacenar la puntuación y el método <code>text()</code> de Phaser para mostrarla en la pantalla.</p> + +<h2 id="Nuevas_variables">Nuevas variables</h2> + +<p>Añade dos nuevas variables justo después de la definición de las anteriores:</p> + +<pre class="brush: js">// ... +var scoreText; +var score = 0; +</pre> + +<h2 id="Añadir_el_texto_de_puntuación_a_la_pantalla_del_juego">Añadir el texto de puntuación a la pantalla del juego</h2> + +<p>Ahora añade esta línea al final de la función <code>create()</code>:</p> + +<pre class="brush: js">scoreText = game.add.text(5, 5, 'Points: 0', { font: '18px Arial', fill: '#0095DD' }); +</pre> + +<p>El método <code>text()</code> puede tomar cuatro parámetros:</p> + +<ul> + <li>Las coordenadas x e y dónde escribir el texto.</li> + <li>El texto que se mostrará.</li> + <li>El estilo de la fuente con la que se representará el texto.</li> +</ul> + +<p>El último parámetro se parece mucho a los estilos de CSS. En nuestro caso, el texto de la puntuación será azul, con un tamaño de 18 pixeles y usará como estilo de fuente Arial.</p> + +<h2 id="Actualizar_el_juego_cuando_los_ladrillos_se_han_destruido">Actualizar el juego cuando los ladrillos se han destruido</h2> + +<p>Incrementaremos el número de puntos cada vez que la pelota golpee en un ladrillo y actualizaremos el <code>scoreText</code> para mostrar la puntuación actual. Esto, lo podremos hacer usando el método <code>setText()</code> — añade las dos siguientes líneas a la función<code> ballHitBrick()</code>:</p> + +<pre class="brush: js">function ballHitBrick(ball, brick) { + brick.kill(); + score += 10; + scoreText.setText('Points: '+score); +} +</pre> + +<p>Eso es todo por ahora — recarga tu <code>index.html</code> y comprueba que la puntuación se actualiza por cada golpe al ladrillo.</p> + +<h2 id="Compare_su_código">Compare su código</h2> + +<p>Puede comprobar el código terminado de esta lección en la demo que aparece a continuación, y jugar para entender mejor cómo funciona el juego:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/n8o6rhrf/","","400")}}</p> + +<h2 id="Próximos_pasos">Próximos pasos</h2> + +<p>Ya tenemos un sistema de puntuación, pero para qué sirve jugar y mantener la puntuación si no se puede ganar. Veremos cómo podemos añadir la victoria, permitiendonos así ganar el juego.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Collision_detection", "Games/Workflows/2D_Breakout_game_Phaser/Win_the_game")}}</p> diff --git a/files/es/games/tutorials/2d_breakout_game_phaser/win_the_game/index.html b/files/es/games/tutorials/2d_breakout_game_phaser/win_the_game/index.html new file mode 100644 index 0000000000..06b45f5b2b --- /dev/null +++ b/files/es/games/tutorials/2d_breakout_game_phaser/win_the_game/index.html @@ -0,0 +1,60 @@ +--- +title: Win the game +slug: Games/Tutorials/2D_breakout_game_Phaser/Win_the_game +tags: + - 2D + - JavaS + - Lienzo + - Phaser + - Principiante + - Tutorial + - ganando +translation_of: Games/Tutorials/2D_breakout_game_Phaser/Win_the_game +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/The_score", "Games/Workflows/2D_Breakout_game_Phaser/Extra_lives")}}</p> + +<div class="summary"> +<p>Este es el paso <strong>12º </strong>del tutorial 16 de <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser</a>. Puedes encontrar el código fuente tal y como queda al completar el tutorial en <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson12.html">Gamedev-Phaser-Content-Kit/demos/lesson12.html</a>.</p> +</div> + +<p><span class="seoSummary">Implementar las victorias en nuestro juego es fácil: si destruyes todos los ladrillos, ganas.</span></p> + +<h2 id="¿Cómo_ganar">¿Cómo ganar?</h2> + +<p>Añade el siguiente código a la función <code>ballHitBrick()</code>:</p> + +<pre class="brush: js">function ballHitBrick(ball, brick) { + brick.kill(); + score += 10; + scoreText.setText('Points: '+score); + + var count_alive = 0; + for (i = 0; i < bricks.children.length; i++) { + if (bricks.children[i].alive == true) { + count_alive++; + } + } + if (count_alive == 0) { + alert('You won the game, congratulations!'); + location.reload(); + } +} +</pre> + +<p>Recorremos los ladrillos del grupo usando <code>bricks.children</code>, verificando la vida de cada uno con el método <code>.alive() </code>. Si no quedan más ladrillos con vida, mostramos un mensaje de victoria, reiniciando el juego una vez que la alerta desaparezca.</p> + +<h2 id="Compare_su_código">Compare su código</h2> + +<p>Puedes comprobar el código terminado de esta lección en la siguiente demo, y jugar para entender mejor cómo funciona:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/u8waa4Lx/1/","","400")}}</p> + +<h2 id="Próximos_pasos">Próximos pasos</h2> + +<p>Ganar y perder están implementados, por lo que la jugabilidad de nuestro juego está terminada. Ahora añadiremos algo extra — vamos a dar al jugador tres vidas en lugar de una.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/The_score", "Games/Workflows/2D_Breakout_game_Phaser/Extra_lives")}}</p> diff --git a/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/bounce_off_the_walls/index.html b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/bounce_off_the_walls/index.html new file mode 100644 index 0000000000..d168aa0102 --- /dev/null +++ b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/bounce_off_the_walls/index.html @@ -0,0 +1,101 @@ +--- +title: Rebota en las paredes +slug: Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Bounce_off_the_walls +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls +--- +<div>{{GamesSidebar}}</div><div> +<p>{{IncludeSubnav("/es/docs/Games")}}</p> +</div> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Mueve_la_bola", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Control_pala_y_teclado")}}</p> + +<div class="summary"> +<p>Este es el tercer paso de 10 del <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">tutorial Canvas para el desarrollo de juegos</a>. Puedes encontrar el código fuente y pegarle un vistazo después de completar esta lección <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson03.html">Gamedev-Canvas-workshop/lesson3.html</a>.</p> +</div> + +<p><span class="seoSummary">Es agradable ver nuestra bola moviéndose, pero desaparece rápidamente de la pantalla, limitando la diversión que podemos tener con ella. Para superar esto, implementaremos una detección de colisión muy simple (que se explicará <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Collision_detection">más adelante</a> con más detalle) para hacer que la pelota rebote en los cuatro bordes del Canvas.</span></p> + +<h2 id="Detección_de_colisión_simple">Detección de colisión simple</h2> + +<p>Para detectar la colisión verificamos si la bola está tocando (chocando con) la pared y si es así, cambiaremos la dirección de su movimiento en consecuencia.</p> + +<p>Para facilitar los cálculos, definamos una variable llamada <code>ballRadius</code> que mantendrá el radio del círculo dibujado y se utilizará para los cálculos. Añade esto a tu código, en algún lugar por debajo de las declaraciones de variables existentes:</p> + +<pre class="brush: js">var ballRadius = 10;</pre> + +<p>Ahora actualice la línea que dibuja la bola dentro de la funcion drawBall() a esto:</p> + +<pre class="brush: js">ctx.arc(x, y, ballRadius, 0, Math.PI*2);</pre> + +<h3 id="Rebotando_arriba_y_abajo">Rebotando arriba y abajo</h3> + +<p>Hay cuatro paredes para rebotar la pelota - vamos a centrarnos en la de arriba en primer lugar. Tendremos que comprobar, en cada fotograma, si la pelota está tocando el borde superior del Canvas - si es así, invertiremos el movimiento de la bola para que empiece a moverse en la dirección opuesta y se mantenga dentro de los límites visibles. Recordando que el sistema de coordenadas comienza desde la parte superior izquierda, podemos llegar a algo como esto:</p> + +<pre class="brush: js">if(y + dy < 0) { + dy = -dy; +}</pre> + +<p>Si el valor de y de la posición de la bola es menor que cero, cambie la dirección del movimiento en el eje y, estableciéndolo igual a sí mismo, invertido. Si la pelota se movía hacia arriba con una velocidad de 2 píxeles por fotograma, ahora se moverá "arriba" con una velocidad de -2 píxeles, lo que en realidad equivale a bajar a una velocidad de 2 píxeles por fotograma.</p> + +<p>El código anterior se ocuparía de que la pelota rebote desde el borde superior, así que ahora vamos a pensar en el borde inferior:</p> + +<pre class="brush: js">if(y + dy > canvas.height) { + dy = -dy; +}</pre> + +<p>Si la posición y de la pelota es mayor que la altura del canvas (recuerde que contamos los valores y desde la parte superior izquierda, de modo que el borde superior empieza en 0 y el borde inferior está en 480 píxeles, la altura del canvas), entonces rebota del borde inferior invirtiendo el movimiento del eje y como antes.</p> + +<p>Podríamos fusionar esas dos sentencias en una para ahorrar código:</p> + +<pre class="brush: js">if(y + dy > canvas.height || y + dy < 0) { + dy = -dy; +}</pre> + +<p>Si cualquiera de las dos afirmaciones es verdadera, invierte el movimiento de la pelota.</p> + +<h3 id="Rebotando_en_la_izquierda_y_derecha">Rebotando en la izquierda y derecha</h3> + +<p>Tenemos el borde superior e inferior cubiertos, así que pensemos en los de izquierda y derecha. Es muy similar en realidad, todo lo que tienes que hacer es repetir las declaraciones de x en lugar de y:</p> + +<pre class="brush: js">if(x + dx > canvas.width || x + dx < 0) { + dx = -dx; +} + +if(y + dy > canvas.height || y + dy < 0) { + dy = -dy; +}</pre> + +<p>En este punto, debe insertar el bloque de código anterior en la función draw(), justo antes de la llave de cierre.</p> + +<h3 id="¡La_pelota_sigue_desapareciendo_en_la_pared!">¡La pelota sigue desapareciendo en la pared!</h3> + +<p>Prueba tu código en este punto, y te quedarás impresionado - ¡ahora tenemos una pelota que rebotó en los cuatro bordes del canvas! Pero tenemos otro problema sin embargo - cuando la bola golpea cada pared se hunde en ella levemente antes de cambiar la dirección:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10432/ball-in-wall.png" style="display: block; height: 320px; margin: 0px auto; width: 480px;"></p> + +<p>Esto es porque estamos calculando el punto de colisión de la pared y el centro de la bola, mientras que deberíamos hacerlo por su circunferencia. La bola debe rebotar justo después de que toca la pared, no cuando ya está a medio camino en la pared, así que vamos a ajustar nuestras declaraciones un poco para incluir eso. Actualice el último código que agregó, a esto:</p> + +<pre class="brush: js">if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) { + dx = -dx; +} +if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) { + dy = -dy; +}</pre> + +<p>Cuando la distancia entre el centro de la bola y el borde de la pared es exactamente igual que el radio de la pelota, cambiará la dirección del movimiento. Restando el radio de un ancho del eje y añadiéndolo al otro nos da la impresión de una adecuada detección de colisiones - la pelota rebota de las paredes como debería hacerlo.</p> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Chequea el código acabado para esta parte con el tuyo, y juega:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/redj37dc/","","370")}}</p> + +<div class="note"> +<p><strong>Ejercicio</strong>: cambia el color de la bola a un color al azar, cada vez que golpea una pared.</p> +</div> + +<h2 id="Siguientes_pasos">Siguientes pasos</h2> + +<p>Ahora hemos llegado al punto donde nuestra pelota se mueve y permanece en el tablero de juego. En el capítulo cuarto, veremos la implementación del control de una pala - vea <a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Control_pala_y_teclado">Control de Pala y teclado</a>.</p> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Mueve_la_bola", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Control_pala_y_teclado")}}</p> diff --git a/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/construye_grupo_bloques/index.html b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/construye_grupo_bloques/index.html new file mode 100644 index 0000000000..99c944764b --- /dev/null +++ b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/construye_grupo_bloques/index.html @@ -0,0 +1,126 @@ +--- +title: Construye el muro de ladrillos +slug: Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Construye_grupo_bloques +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Build_the_brick_field +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/es/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Fin_del_juego", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Deteccion_colisiones")}}</p> + +<div class="summary"> +<p>Este es el sexto<strong> paso de 10 del</strong> <a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro">Tutorial del Lienzo (Canvas) para desarrollar juegos (Gamedev Canvas Tutorial)</a>. Puedes encontrar el código fuente como debería quedar tras completar esta lección en <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson06.html">Gamedev-Canvas-workshop/lesson6.html</a>.</p> +</div> + +<p>Hemos cambiado la mecánica del juego y ahora ya podemos perder.<span class="seoSummary"> Esto es genial porque significa que el juego finalmente se comporta como un juego. Sin embargo, pronto resultará aburrido si todo lo que puedes conseguir es hacer rebotar la pelota en las paredes y en la pala. Lo que el juego necesitamos es romper ladrillos con la bola. Ahora vamos a dibujar los ladrillos.</span></p> + +<h2 id="Declarar_e_inicializar_las_variables_de_los_ladrillos">Declarar e inicializar las variables de los ladrillos</h2> + +<p>El propósito principal de esta lección consiste en escribir unas pocas líneas de código para los ladrillos, utilizando un bucle anidado que recorra una matriz bidimensional. Pero, antes, necesitamos preparar unas variables que definan la información sobre los ladrillos, como su ancho y alto, filas y columnas, etc. Añade estas líneas a tu programa, debajo de las otras variables que has definido antes:</p> + +<pre class="brush: js">var brickRowCount = 3; +var brickColumnCount = 5; +var brickWidth = 75; +var brickHeight = 20; +var brickPadding = 10; +var brickOffsetTop = 30; +var brickOffsetLeft = 30;</pre> + +<p>Aquí hemos definido el número de filas (Row) y columnas (Column) de ladrillos, su ancho (Width) y alto (Height), el hueco entre los ladrillos para que no se toquen (Padding), y un margen superior (Top) e izquierdo (Left) para que no se dibujen tocando los bordes.</p> + +<p>Guardaremos nuestros ladrillos en una matriz bidimensional que contendrá las columnas (c) de los ladrillos. Cada columna contendrá, a su vez, toda la fila (r) de ladrillos. Cada ladrillo se va a representar con un objeto con las posiciones "x" e "y" en las que se dibujará. Añade esto detrás de las definiciones de las variables:</p> + +<pre class="brush: js">var bricks = []; +for(c=0; c<brickColumnCount; c++) { + bricks[c] = []; + for(r=0; r<brickRowCount; r++) { + bricks[c][r] = { x: 0, y: 0 }; + } +}</pre> + +<p>El código anterior pasará por las filas y las columnas y creará los ladrillos. TEN EN CUENTA que esos objetos que representan a los ladrillos también se utilizarán para detectar colisiones más adelante.</p> + +<p>Por si no lo terminas de entender... bricks[0][0] es el primer ladrillo (columna 0, fila 0) y se dibujará en "x" 0 e "y" 0. El siguiente ladrillo será el brick[0][1] (columna 0, fila 1) y se dibujará también en (0,0). Así, continuaremos hasta el final de la primera columna, que será el ladrillo bricks[0][2] porque hay 3 filas, de la 0 a la 2. Terminará así el bucle de dentro y seguirá el de fuera, valiendo ahora la "c" 1. Seguiremos recorriendo bricks[] hasta llegar a bricks[2][4], que es el último ladrillo.</p> + +<h2 id="Dibujar_los_bloques">Dibujar los bloques</h2> + +<p>Ahora vamos a crear una función para recorrer todos los bloques de la matriz y dibujarlos en la pantalla:</p> + +<pre class="brush: js">function drawBricks() { + for(c=0; c<brickColumnCount; c++) { + for(r=0; r<brickRowCount; r++) { + bricks[c][r].x = 0; + bricks[c][r].y = 0; + ctx.beginPath(); + ctx.rect(0, 0, brickWidth, brickHeight); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + } + } +} +</pre> + +<p>Viene a ser lo mismo de antes, sólo que hemos añadido ctx.rect() para dibujar un rectángulo por cada ladrillo, además de otras llamadas a funciones para que, efectivamente, se dibuje el rectángulo.</p> + +<p>Cada ladrillo se dibujará en la posición (0, 0), tendrá un ancho brickWidth y un alto de brickHeight.</p> + +<p>Estupendo pero... ¡estamos dibujando todos los ladrillos en el mismo sitio! ¡Eso no puede ser!</p> + +<p>Vamos a calcular en qué posición "x" e "y" se tiene que dibujar cada ladrillo así:</p> + +<pre class="brush: js">var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft; +var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop; +</pre> + +<p>El primer ladrillo se dibujará arriba a la izquierda, concretamente en (brickoffsetLeft, brickOffsetTop), porque c y r valen 0.</p> + +<p>El siguiente ladrillo (columna 0, fila 1) se dibujará más abajo.</p> + +<p>Intenta hacer tú mismo los cálculos y verás cómo cada ladrillo de la misma columna se dibujará más abajo o más arriba según en qué fila se encuentre.</p> + +<p>También verás cómo cada ladrillo de la misma fila se dibujará más a la izquierda o a la derecha según en qué columna se encuentre.</p> + +<p>Vamos a terminar la función drawBricks() para que quede así:</p> + +<pre class="brush: js">function drawBricks() { + for(c=0; c<brickColumnCount; c++) { + for(r=0; r<brickRowCount; r++) { + var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft; + var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop; + bricks[c][r].x = brickX; + bricks[c][r].y = brickY; + ctx.beginPath(); + ctx.rect(brickX, brickY, brickWidth, brickHeight); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + } + } +}</pre> + +<h2 id="Dibujar_los_bloques_(ahora_sí)">Dibujar los bloques (ahora sí)</h2> + +<p>Lo estamos haciendo muy bien, pero si has probado te habrás dado cuenta de que no se dibuja nada. ¿Qué es lo que falla?</p> + +<p>Pues, sencillamente, que tenemos definida la función drawBricks() pero no la llamamos desde ningún sitio.</p> + +<p>Añade drawBricks() dentro de draw(), justo antes de drawBall ():</p> + +<pre class="brush: js">drawBricks(); +</pre> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Compara tu código con este:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/kundan333/myd4vbwg/2/","","320")}}</p> + +<div class="note"> +<p>Ejercicio: Prueba a cambiar el número de bloques por fila o columna, o sus posiciones (utiliza las variables que definiste al principio de este capítulo).</p> +</div> + +<h2 id="Pasos_siguientes">Pasos siguientes</h2> + +<p>¡Así que ahora tenemos ladrillos! Un gran avance pero... la pelota no los rompe, simplemente los atraviesa. En el siguiente capítulo lo arreglaremos: <a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Deteccion_colisiones">Detección de colisiones</a>.</p> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Fin_del_juego", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Deteccion_colisiones")}}</p> diff --git a/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/control_pala_y_teclado/index.html b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/control_pala_y_teclado/index.html new file mode 100644 index 0000000000..81403423c7 --- /dev/null +++ b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/control_pala_y_teclado/index.html @@ -0,0 +1,130 @@ +--- +title: Control de la pala y el teclado +slug: Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Control_pala_y_teclado +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/es/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Bounce_off_the_walls", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Fin_del_juego")}}</p> + +<div class="summary"> +<p>Este es el cuarto de los 10 pasos del <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Tutorial de Canvas para el desarrollo de juegos</a>. Puedes encontrar el código fuente como debería quedar después de completar la lección en <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson04.html">Gamedev-Canvas-workshop/lesson4.html</a>.</p> +</div> + +<p> </p> + +<p><span class="seoSummary">La bola está rebotando en las paredes libremente y puedes estar mirándola toda la vida, pero, ahora mismo, no hay interactividad. ¡No es un juego si no puedes controlarlo! Vamos a añadirle la interacción del usuario: una paleta.</span></p> + +<h2 id="Definir_una_paleta_para_golpear_la_bola">Definir una paleta para golpear la bola</h2> + +<p>Necesitamos una paleta para golpear la bola. Empezamos por definir variables para conseguirlo. Añade las variables siguientes en la parte de arriba de tu código, junto a las que ya tenías:</p> + +<pre class="brush: js">var paddleHeight = 10; +var paddleWidth = 75; +var paddleX = (canvas.width-paddleWidth)/2;</pre> + +<p>paddleHeight servirá para definir la altura de la paleta, paddleWidth la anchura y paddleX la posición en el eje X en la que empieza a dibujarse. Definimos una función que dibujará la paleta en la pantalla. Añade este código justo después de la función <code>drawBall()</code>:</p> + +<pre class="brush: js">function drawPaddle() { + ctx.beginPath(); + ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); +}</pre> + +<h2 id="Permitir_que_el_usuario_controle_la_paleta">Permitir que el usuario controle la paleta</h2> + +<p>Podemos dibujar la paleta donde queramos, pero debería responder a las acciones del usuario. Ha llegado la hora de implementar algunos controles de teclado. Vamos a necesitar:</p> + +<ul> + <li>Dos variables para guardar la información sobre si se ha pulsado el botón izquierdo o el derecho.</li> + <li>Dos funciones (event listeners) que respondan a los eventos <code>keydown</code> y <code>keyup</code> (pulsar tecla, liberar tecla). Queremos que se ejecute algún código para manejar la paleta cuando se pulsen los botones.</li> + <li>Dos funciones que manejen los eventos <code>keydown</code> y <code>keyup</code> que se ejecutarán cuando se pulsen los botones.</li> + <li>La habilidad de mover la paleta a la izquierda y a la derecha</li> +</ul> + +<p>Empezaremos por definir las variables que nos dirán si se ha pulsado un botón. Añade estas líneas donde has definido las demás variables:</p> + +<pre class="brush: js">var rightPressed = false; +var leftPressed = false;</pre> + +<p>Las dos las inicializamos con el valor <code>false</code> porque al principio no están pulsados los botones. Para "escuchar" las pulsaciones de las teclas necesitamos definir dos "escuchadores de eventos" (event listeners). Añade las líneas siguientes justo antes de <code>setInterval()</code> al final de tu código:</p> + +<pre class="brush: js">document.addEventListener("keydown", keyDownHandler, false); +document.addEventListener("keyup", keyUpHandler, false);</pre> + +<p>Cuando ocurra el evento <code>keydown</code> al pulsar cualquier tecla del teclado, la función <code>keyDownHandler()</code> se ejecutará. Cuando se liberará la tecla pulsada, se ejecutará la función <code>keyUpHandler()</code>. Añade esto después de las líneas del <code>addEventListener()</code> que acababas de escribir:</p> + +<pre class="brush: js">function keyDownHandler(e) { + if(e.keyCode == 39) { + rightPressed = true; + } + else if(e.keyCode == 37) { + leftPressed = true; + } +} + +function keyUpHandler(e) { + if(e.keyCode == 39) { + rightPressed = false; + } + else if(e.keyCode == 37) { + leftPressed = false; + } +}</pre> + +<p>Cuando pulsamos una tecla se ejecuta keyDownHandler(e), que pone en la variable "e" los datos que necesitamos. Efectivamente, e.keyCode nos va a decir qué tecla se ha pulsado. Si vale 37 es porque se ha pulsado la "flecha izquierda" del teclado. El código 39 representa a la "flecha derecha".</p> + +<p>Pues bien, cuando se pulsará la "flecha izquierda" pondremos leftPressed a true.</p> + +<p>Cuando se liberará la "flecha izquierda" pondremos leftPressed a false.</p> + +<p>De igual forma procederá el programa con la "flecha derecha", detectando el código 39 y dando los valores oportunos a la variable rightPressed.</p> + +<h3 id="La_lógica_del_movimiento_de_la_paleta">La lógica del movimiento de la paleta</h3> + +<p>Ya tenemos las variables que contienen la información sobre las teclas pulsadas, los escuchadores de eventos y las funciones relevantes. Ahora vamos a ocuparnos del código que utilizará todo eso y moverá la paleta en la pantalla. Dentro de la función <code>draw()</code> comprobaremos si está pulsada la flecha izquierda o la derecha cada vez que se dibuje un fotograma. Nuestro código podría tener este aspecto:</p> + +<pre class="brush: js">if(rightPressed) { + paddleX += 7; +} +else if(leftPressed) { + paddleX -= 7; +}</pre> + +<p>Si se pulsa la flecha izquierda, la paleta se moverá 7 píxeles a la izquierda. Si se pulsa la flecha derecha, se moverá 7 píxeles a la derecha. Aunque esto funciona bien, la paleta desaparece en los laterales del terreno de juego si mantenemos pulsada una tecla demasiado tiempo. Podemos mejorar esto para que se mueva dentro de los límites del canvas, cambiando el código así:</p> + +<pre class="brush: js">if(rightPressed && paddleX < canvas.width-paddleWidth) { + paddleX += 7; +} +else if(leftPressed && paddleX > 0) { + paddleX -= 7; +}</pre> + +<p>La posición paddleX que estamos utilizando variará entre 0 para la lado izquierdo y <code style="font-style: normal; font-weight: normal;">canvas.width-paddleWidth</code> para el lado derecho, que es justo lo que queremos.</p> + +<p>Añade el código anterior dentro de la función <code>draw(), al final</code>, justo antes de la llave que cierra.</p> + +<p>Lo único que nos falta por hacer es llamar a la función <code>drawPaddle()</code> desde dentro de la función <code>draw()</code> para que dibuje la paleta dentro en la pantalla. Añade la línea siguiente dentro de <code>draw(), justo antes de la línea que llama a la función</code> <code>drawBall()</code>:</p> + +<pre class="brush: js">drawPaddle(); +</pre> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Aquí está el código que funciona, para que lo compares con el tuyo:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/tgn3zscj/","","320")}}</p> + +<div class="note"> +<p><strong>Ejercicio</strong>: haz que la paleta se mueva más deprisa o más despacio, o cambia su tamaño.</p> +</div> + +<h2 id="Pasos_siguientes">Pasos siguientes</h2> + +<p>Ahora mismo tenemos algo que parece un juego. El único problema es que todo lo que puedes hacer es golpear la bola con la paleta toda la vida (en realidad, ni siquiera la golpeas). Todo esto cambiará en el quinto capítulo, <a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Fin_del_juego">Fin del juego</a>, cuando añadiremos un estado de "Game Over".</p> + +<div> </div> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Bounce_off_the_walls", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Fin_del_juego")}}</p> diff --git a/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/controles_raton/index.html b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/controles_raton/index.html new file mode 100644 index 0000000000..65e32f0ac2 --- /dev/null +++ b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/controles_raton/index.html @@ -0,0 +1,53 @@ +--- +title: Controles del ratón +slug: Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Controles_raton +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Mouse_controls +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Track_the_score_and_win", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Terminando")}}</p> + +<div class="summary"> +<p>Este es el noveno paso de 10 del <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">tutorial Canvas para el desarrollo de juegos</a>. Puedes encontrar el código y pegarle un vistazo después de completar esta lección <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson09.html">Gamedev-Canvas-workshop/lesson9.html</a>.</p> +</div> + +<p>El juego en sí está terminado, así que ahora vamos a pulirlo. Ya le hemos puesto el control del teclado y ahora le añadiremos el control del ratón<span class="seoSummary">.</span></p> + +<h2 id="Detectar_el_movimiento_del_ratón">Detectar el movimiento del ratón</h2> + +<p>Detectar el movimiento del ratón es más fácil que detectar las pulsaciones de las teclas. Todo lo que necesitamos es un añadir "escuchador" al evento {{event("mousemove")}}.Añade esta línea destrás de los otros "listeners", justo debajo del evento <code>keyup</code>:</p> + +<pre class="brush: js">document.addEventListener("mousemove", mouseMoveHandler, false);</pre> + +<h2 id="Asociar_el_movimiento_de_la_pala_con_el_movimiento_del_ratón">Asociar el movimiento de la pala con el movimiento del ratón</h2> + +<p>Podemos cambiar la posición de la pala basándonos en las coordenadas del puntero del ratón. Eso es lo que hace la función siguiente. Añádela detrás de la línea que acabas de añadir:</p> + +<pre class="brush: js">function mouseMoveHandler(e) { + var relativeX = e.clientX - canvas.offsetLeft; + if(relativeX > 0 && relativeX < canvas.width) { + paddleX = relativeX - paddleWidth/2; + } +}</pre> + +<p>En esta función calculamos un valor <code style="font-style: normal; font-weight: normal;">relativeX</code>, que es la posición horizontal del ratón en el "viewport" (<code style="font-style: normal; font-weight: normal;">e.clientX</code>), menos la distancia entre el borde izquierdo del terreno de juego y el borde izquierdo del "viewport" (<code style="font-style: normal; font-weight: normal;">canvas.offsetLeft</code>).</p> + +<p>Si el valor resultante es mayor que cero y menor que el ancho del terreno de juego, es que el ratón está dentro de los límites, y calculamos la posición de la paleta poniéndole el valor <code style="font-style: normal; font-weight: normal;">relativeX</code> menos la mitad del ancho de la paleta, para que el movimiento sea de verdad relativo a la mitad de la paleta.</p> + +<p>Ahora, la paleta seguirá la posición del cursor del ratón pero, como restringimos el movimiento al <canvas>, no desaparecerá completamente por los lados.</p> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Aquí tienes el código para comparar:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/L3gngab5/","","320")}}</p> + +<div class="summary"> +<p>Ejercicio: ajusta los límites del movimiento de la pala para que siempre se vea la pala completa (ahora sólo se ve media en los laterales).</p> +</div> + +<h2 id="Pasos_siguientes">Pasos siguientes</h2> + +<p>Ya tenemos el juego terminado, pero aún lo podemos mejorar con algunos trucos <a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Terminando">Finalizando</a>.</p> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Track_the_score_and_win", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Terminando")}}</p> diff --git a/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/create_the_canvas_and_draw_on_it/index.html b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/create_the_canvas_and_draw_on_it/index.html new file mode 100644 index 0000000000..59703d3bc7 --- /dev/null +++ b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/create_the_canvas_and_draw_on_it/index.html @@ -0,0 +1,108 @@ +--- +title: Crea el lienzo (canvas) y dibuja en él +slug: >- + Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Create_the_Canvas_and_draw_on_it +translation_of: >- + Games/Tutorials/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Mueve_la_bola")}}</p> + +<div class="summary"> +<p>Este es el primero de los 10 pasos del <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Tutorial del Lienzo (Canvas) para desarrollar juegos (Gamedev Canvas Tutorial)</a>. Puedes encontrar el código fuente como debería quedar tras completar esta lección en <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson01.html">Gamedev-Canvas-workshop/lesson1.html</a>.</p> +</div> + +<p><span class="seoSummary">Antes de que podamos programar la parte funcional del juego, necesitamos crear la estructura básica de la página que lo va a contener. Podemos hacerlo utilizando HTML y el elemento {{htmlelement("canvas")}} .</span></p> + +<h2 id="El_HTML_del_juego">El HTML del juego</h2> + +<p>La estructura del documento HTML es muy simple, porque todo el juego se visualizará dentro del elemento {{htmlelement("canvas")}}. Con tu editor de textos favorito, prepara un documento en blanco, guárdalo como <code>index.html</code> en un lugar adecuado, y escribe el siguiente código:</p> + +<pre class="brush: html"><!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <title>Gamedev Canvas Workshop</title> + <style> + * { padding: 0; margin: 0; } + canvas { background: #eee; display: block; margin: 0 auto; } + </style> +</head> +<body> + +<canvas id="myCanvas" width="480" height="320"></canvas> + +<script> + // JavaScript code goes here +</script> + +</body> +</html> +</pre> + +<p>En la cabecera (head) tenemos un <code>charset</code>, el título de la página {{htmlelement("title")}} y un poco de CSS básico. El {{htmlelement("body")}} contiene los elementos{{htmlelement("canvas")}} y {{htmlelement("script")}}. Representaremos el juego en el primero y escribiremos el código JavaScript que lo controla en el segundo. El elemento {{htmlelement("canvas")}} tiene el <code>id</code> <code>myCanvas</code> para que podamos hacer referencia a él con facilidad, y mide 480 píxeles de ancho por 320 de alto. Todo el código JavaScript que vamos a escribir en este tutorial lo pondremos entre las etiquetas <code><script><font face="Thread-00002020-Id-00000048"> y</font></code> <code></script></code>.</p> + +<h2 id="El_lienzo_(canvas)">El lienzo (canvas)</h2> + +<p>Para que podamos visualizar los gráficos en el elemento {{htmlelement("canvas")}}, primero tenemos que preparar una referencia a él en JavaScript. Añade lo siguiente después de la etiqueta <code><script>:</code></p> + +<pre class="brush: js">var canvas = document.getElementById("myCanvas"); +var ctx = canvas.getContext("2d");</pre> + +<p>Aquí estamos guardando una referencia al elemento {{htmlelement("canvas")}} en la variable <code>canvas</code>. Después estamos creando la variable <code>ctx</code> para guardar el contexto de gráficos 2D, que es la herramienta que realmente utilizaremos para dibujar.</p> + +<p>Veamos un fragmento de código de ejemplo que dibuja un cuadrado rojo en el canvas. Añade el código a continuación y abre el archivo <code>index.html</code> con un navegador para comprobar que funciona:</p> + +<pre class="brush: js">ctx.beginPath(); +ctx.rect(20, 40, 50, 50); +ctx.fillStyle = "#FF0000"; +ctx.fill(); +ctx.closePath();</pre> + +<p>Todas las instrucciones están entre los métodos {{domxref("CanvasRenderingContext2D.beginPath()","beginPath()")}} y {{domxref("CanvasRenderingContext2D.closePath()","closePath()")}}. Estamos definiendo un rectángulo utilizando {{domxref("CanvasRenderingContext2D.rect()","rect()")}}: los dos primeros valores especifican las coordenadas de la esquina superior izquierda del rectángulo en el canvas, y los otros dos sirven para indicar el ancho y el alto. En nuestro caso, el rectángulo se dibuja a 20 píxeles desde la izquierda de la pantalla y 40 píxeles desde la parte de arriba, y tiene 50 píxeles de ancho y 50 de alto, con lo que obtenemos un cuadrado perfecto. La propiedad {{domxref("CanvasRenderingContext2D.fillStyle","fillStyle")}} guarda un color que utilizará el método {{domxref("CanvasRenderingContext2D.fill()","fill()")}} para pintar el cuadrado que, en nuestro caso, será rojo.</p> + +<p>Podemos dibujar otras cosas aparte de rectángulos. Aquí hay un fragmento de código que dibuja un círculo verde. Prueba a añadir esto al final de tu código JavaScript, guárdalo y recarga la página en el navegador:</p> + +<pre class="brush: js">ctx.beginPath(); +ctx.arc(240, 160, 20, 0, Math.PI*2, false); +ctx.fillStyle = "green"; +ctx.fill(); +ctx.closePath();</pre> + +<p>Como puedes ver, estamos utilizando otra vez los métodos {{domxref("CanvasRenderingContext2D.beginPath()","beginPath()")}} y {{domxref("CanvasRenderingContext2D.closePath()","closePath()")}}. De lo que hay en medio, la parte más importante del código anterior es el método {{domxref("CanvasRenderingContext2D.arc()","arc()")}}. Tiene seis parámetros:</p> + +<ul> + <li>las coordenadas x e y del centro del arco</li> + <li>el radio del arco</li> + <li>los ángulos inicial y final (en qué ángulo empezar y terminar de dibujar el círculo, en radianes)</li> + <li>la dirección hacia la que se dibujará (<code>false</code> para seguir el sentido de las agujas del reloj, que es el valor por defecto, o <code>true</code> para el sentido contrario). Este parámetro es opcional.</li> +</ul> + +<p>La propiedad {{domxref("CanvasRenderingContext2D.fillStyle","fillStyle")}} tiene un valor distinto al que habíamos puesto antes. Esto se debe a que, como ocurre en CSS, el color se puede especificar como un valor hexadecimal, como un nombre de color en inglés, la función <code>rgba()</code>, o cualquiera de los otros métodos de descripción de color que existen.</p> + +<p>En lugar de utilizar {{domxref("CanvasRenderingContext2D.fill()","fill()")}} y rellenar las formas con colores, podemos utilizar {{domxref("CanvasRenderingContext2D.stroke()","stroke()")}} para colorear únicamente el trazo exterior. Prueba a añadir también esto a tu código JavaScript:</p> + +<pre class="brush: js">ctx.beginPath(); +ctx.rect(160, 10, 100, 40); +ctx.strokeStyle = "rgba(0, 0, 255, 0.5)"; +ctx.stroke(); +ctx.closePath();</pre> + +<p>El código anterior dibuja un rectángulo vacío con el perímetro azul. Gracias al canal alfa de la función <code>rgba()</code>, que es el cuarto valor (Red, Green, Blue, Alpha), el color azul será medio transparente.</p> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Aquí está el código fuente completo de la primera lección, ejecutándose en un JSFiddle:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/x62h15e2/","","370")}}</p> + +<div class="note"> +<p><strong>Ejercicio</strong>: cambia el tamaño y el color de las figuras.</p> +</div> + +<h2 id="Pasos_siguientes">Pasos siguientes</h2> + +<p>Hemos preparado la estructura HTML básica y hemos aprendido un poquito a manejar el canvas. Para continuar, en el segundo capítulo averiguaremos cómo mover la bola en nuestro juego (<a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Mueve_la_bola">Mueve la bola</a>).</p> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Mueve_la_bola")}}</p> diff --git a/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/deteccion_colisiones/index.html b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/deteccion_colisiones/index.html new file mode 100644 index 0000000000..e6d950b834 --- /dev/null +++ b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/deteccion_colisiones/index.html @@ -0,0 +1,128 @@ +--- +title: Detección de colisiones +slug: Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Deteccion_colisiones +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Collision_detection +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Construye_grupo_bloques", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Track_the_score_and_win")}}</p> + +<div class="summary"> +<p>Este es el séptimo paso de los 10 del juego "<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>". Puedes encontrar el código como deberá quedar después de completar la leción en <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson07.html">Gamedev-Canvas-workshop/lesson7.html</a>.</p> +</div> + +<p><span class="seoSummary">Ya tenemos los ladrillos en la pantalla pero el juego todavía no es muy interesante, porque la bola los atraviesa. Tenemos que pensar una manera de detectar colisiones para que la bola pueda rebotar en los ladrillos y romperlos.</span></p> + +<p><span class="seoSummary">Nosotros decidimos cómo implementar esto, por supuesto, pero puede ser complicado calcular si la bola está tocando el rectángulo o no, porque no hay funciones del <canvas> que sirvan para saberlo. En este tutorial vamos a hacerlo de la manera más fácil que existe: comprobaremos si el centro de la bola está tocando (colisionando) con cualquiera de los ladrillos. No siempre funcionará a la perfección y hay formas de detectar colisiones más sofisticadas que funcionan mejor, pero no nos interesa verlas porque estamos aprendiendo y tenemos que hacer las cosas fáciles</span>.</p> + +<h2 id="Una_función_para_detectar_colisiones">Una función para detectar colisiones</h2> + +<p>Para lograr nuestro objetivo vamos a definir una función que, con un bucle, recorrerá todos los ladrillos y comparará la posición de cada uno con la posición de la bola, cada vez que se dibuje un fotograma. Para que el código sea más legible definiremos la variable "b" que almacenará el objeto ladrillo en cada vuelta de bucle:</p> + +<pre class="brush: js">function collisionDetection() { + for(c=0; c<brickColumnCount; c++) { + for(r=0; r<brickRowCount; r++) { + var b = bricks[c][r]; + // calculations + } + } +}</pre> + +<p>Si el centro de la bola está dentro de las coordenadas de uno de nuestros ladrillos, cambiaremos la dirección de la bola. Se cumplirá que el centro de la bola está dentro de ladrillo si se cumplen al mismo tiempo estas cuatro condiciones:</p> + +<ul> + <li>La posición "x" de la bola es mayor que la posición "x" del ladrillo</li> + <li>La posición "x" de la bola es menor que la posición del ladrillo más el ancho del ladrillo</li> + <li>La posición "y" de la bola es mayor que la posición "y" del ladrillo.</li> + <li>La posición "y" de la bola es menor que la posición del ladrillo más su altura.</li> +</ul> + +<p>Traducimos esto a JavaScript:</p> + +<pre class="brush: js">function collisionDetection() { + for(c=0; c<brickColumnCount; c++) { + for(r=0; r<brickRowCount; r++) { + var b = bricks[c][r]; + if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) { + dy = -dy; + } + } + } +}</pre> + +<p>Añade lo anterior a tu código, debajo de la función <code>keyUpHandler()</code>.</p> + +<h2 id="Hacer_que_los_ladrillos_desaparezcan_cuando_reciben_un_golpe">Hacer que los ladrillos desaparezcan cuando reciben un golpe</h2> + +<p>El código anterior funcionará correctamente y la bola cambiará de dirección. El problema es que los ladrillos siguen donde están. Tenemos que imaginar una forma de ocuparnos de los que ya hemos golpeado con la bola. Podemos hacerlo añadiendo un parámetro extra para indicar si queremos pintar cada ladrillo en la pantalla o no. En la parte del código donde inicializamos los ladrillos, añadiremos una propiedad <code>status</code> a cada ladrillo. Cambia tu código fijándote en la línea que está resaltada:</p> + +<pre class="brush: js; highlight:[5]">var bricks = []; +for(c=0; c<brickColumnCount; c++) { + bricks[c] = []; + for(r=0; r<brickRowCount; r++) { + bricks[c][r] = { x: 0, y: 0, status: 1 }; + } +}</pre> + +<p>A continuación consultaremos el "status" de cada ladrillo para saber si lo tenemos que dibujar o no. Si "status" vale 1, lo dibujaremos. Si vale 0, no lo dibujaremos porque habrá sido golpeado por la bola. Actualiza tu función <code>drawBricks()</code> para que quede así:</p> + +<pre class="brush: js; highlight:[4,5,6,7,8,9,10,11,12,13,14]">function drawBricks() { + for(c=0; c<brickColumnCount; c++) { + for(r=0; r<brickRowCount; r++) { + if(bricks[c][r].status == 1) { + var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft; + var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop; + bricks[c][r].x = brickX; + bricks[c][r].y = brickY; + ctx.beginPath(); + ctx.rect(brickX, brickY, brickWidth, brickHeight); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + } + } + } +}</pre> + +<h2 id="Actualizar_el_status_en_la_función_de_detección_de_colisiones">Actualizar el "status" en la función de detección de colisiones</h2> + +<p>Ahora tenemos que ocuparnos del valor de "status" en la función <code>collisionDetection()</code>: si el ladrillo está activo (status 1) comprobaremos si hay colisión. Si hay colisión, pondremos el "status" de ese ladrillo a 0 para no volver a pintarlo. Actualiza <code>collisionDetection()</code> así:</p> + +<pre class="brush: js; highlight:[5,6,7,8,9,10]">function collisionDetection() { + for(c=0; c<brickColumnCount; c++) { + for(r=0; r<brickRowCount; r++) { + var b = bricks[c][r]; + if(b.status == 1) { + if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) { + dy = -dy; + b.status = 0; + } + } + } + } +}</pre> + +<h2 id="Activar_la_función_de_detección_de_colisiones">Activar la función de detección de colisiones</h2> + +<p>Ya sólo falta llamar a la función <code>collisionDetection()</code> desde la función <code>draw()</code>. Añade la línea siguiente dentro de <code>draw()</code> function, justo después de la llamada a <code>drawPaddle()</code>:</p> + +<pre class="brush: js">collisionDetection(); +</pre> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Ahora se comprueban las colisiones cada vez que se dibuja un fotograma. Concretamente, miramos si la bola colisiona con cada ladrillo. ¡Ahora ya podemos romper ladrillos! :-</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/kundan333/myd4vbwg/5/","","320")}}</p> + +<div class="note"> +<p><strong>Ejercicio</strong>: cambia el color de la bola cada vez que choque con un ladrillo.</p> +</div> + +<h2 id="Pasos_siguientes">Pasos siguientes</h2> + +<p>Definitivamente, lo estamos consiguiendo. ¡Adelanteeee! En el capítulo octavo nos ocuparemos de la <a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Track_the_score_and_win">Puntuación y fin del juego ganando</a>.</p> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Construye_grupo_bloques", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Track_the_score_and_win")}}</p> diff --git a/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/fin_del_juego/index.html b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/fin_del_juego/index.html new file mode 100644 index 0000000000..d57ccef444 --- /dev/null +++ b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/fin_del_juego/index.html @@ -0,0 +1,75 @@ +--- +title: Fin del juego +slug: Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Fin_del_juego +tags: + - Canvas + - Fin del juego + - JavaScript + - Tutorial + - graficos +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Game_over +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/es-ES/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Control_pala_y_teclado", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Construye_grupo_bloques")}}</p> + +<div class="summary"> +<p>Este es el quinto paso de 10 del <a href="/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Puedes ver como debería quedar el código fuente después de completar esta lección en <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson05.html">Gamedev-Canvas-workshop/lesson5.html</a>.</p> +</div> + +<p><span id="result_box" lang="es"><span>Es divertido ver la bola rebotando en las paredes y ser capaz de mover la pala pero, aparte de eso, el juego no hace nada y no tiene ningún progreso ni un objetivo final.</span> <span>Sería bueno desde el punto de vista del juego poder perder.</span> <span>La lógica asociada a perder en este juego es fácil de entender: si se te escapa la bola y alcanza el borde inferior de la pantalla, pierdes y se acabó el juego</span></span><span lang="es"><span>.</span></span></p> + +<h2 id="Implementar_el_final_del_juego">Implementar el final del juego</h2> + +<p><span id="result_box" lang="es"><span>Intentemos implementar el final del juego en nuestro juego.</span> <span>Aquí está el trozo de código de la tercera lección en donde hicimos que la pelota rebotara en las paredes:</span></span></p> + +<pre class="brush: js">if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) { + dx = -dx; +} + +if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) { + dy = -dy; +}</pre> + +<p><span id="result_box" lang="es"><span>En lugar de dejar que la pelota rebote en las cuatro paredes, vamos a permitir que lo haga sólo en tres: izquierda, arriba y derecha.</span> Alcanzar <span>la pared inferior supondrá el fin del juego.</span> <span>Editaremos el segundo bloque if y lo convertiremos en un "if else" que activará el estado de "final de juego" cuando la pelota colisione con el borde inferior del terreno de juego.</span> <span>Por ahora nos conformaremos con mostrar un mensaje con la función alert() y con reiniciar el juego volviendo a cargar la página. Modifica el segundo if para que quede así</span><span>:</span></span></p> + +<pre class="brush: js">if(y + dy < ballRadius) { + dy = -dy; +} else if(y + dy > canvas.height-ballRadius) { + alert("GAME OVER"); + document.location.reload(); +}</pre> + +<h2 id="Hacer_que_la_pala_golpee_la_bola">Hacer que la pala golpee la bola</h2> + +<p>Para terminar esta lección sólo nos falta detectar la colisión de la bola y la paleta para que pueda rebotar, volviendo hacia la zona de juego. La manera más sencilla de hacerlo es comprobar si el centro de la bola está entre los límites izquierdo y derecho de la paleta. Actualiza el último <span id="result_box" lang="es"><span>fragmento del código, el "if else" de antes, para que te quede así:</span></span></p> + +<pre class="brush: js">if(y + dy < ballRadius) { + dy = -dy; +} else if(y + dy > canvas.height-ballRadius) { + if(x > paddleX && x < paddleX + paddleWidth) { + dy = -dy; + } + else { + alert("GAME OVER"); + document.location.reload(); + } +}</pre> + +<p>Si la bola toca el <span id="result_box" lang="es"><span>borde inferior del lienzo (Canvas) debemos comprobar si golpea la pala.</span> <span>Si es así, entonces rebota como el jugador se imagina que va a ocurrir;</span> si no,<span> el juego ha terminado.</span></span></p> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Aquí tienes el código que funciona para que lo compares con el tuyo:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/z4zy79fo/","","320")}}</p> + +<div class="note"> +<p><strong>Ejercicio</strong>: haz que la bola se mueva más rápida cuando golpea la pala.</p> +</div> + +<h2 id="Siguientes_pasos">Siguientes pasos</h2> + +<p><span id="result_box" lang="es"><span>Lo estamos haciendo bastante bien hasta ahora y nuestro juego está empezando a despertar interés ahora que se puede perder. </span><span>Pero todavía falta algo.</span> <span>Vamos a pasar al sexto capítulo,</span></span> <a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Construye_grupo_bloques">Construir el muro de ladrillos</a>, <span lang="es"><span>y crear algunos ladrillos para que la bola los destruya.</span></span></p> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Control_pala_y_teclado", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Construye_grupo_bloques")}}</p> diff --git a/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/index.html b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/index.html new file mode 100644 index 0000000000..10ea794d5f --- /dev/null +++ b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/index.html @@ -0,0 +1,52 @@ +--- +title: Famoso juego 2D usando JavaScript puro +slug: Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro +tags: + - 2D Canvas JavaScript Tutorial + - Principiante Juegos +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/es-ES/docs/Games")}}</div> + +<p>{{Next("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Create_the_Canvas_and_draw_on_it")}}</p> + +<p class="summary">En este tutorial paso a paso creamos un juego de la MDN, sencillo y muy famoso, escrito íntegramente en JavaScript puro. Todos los elementos gráficos aparecerán dentro de la etiqueta {{htmlelement("canvas")}} de HTML5.</p> + +<p>Cada paso tiene ejemplos editables y listos para ejecutar, para que puedas ver qué aspecto debería tener el ejercicio en cada momento. Apenderás a utilizar el elemento {{htmlelement("canvas")}} para implementar mecánicas de juego fundamentales como la representación de imágenes, el movimiento, la detección de colisiones, los mecanismos de control y el final del juego ganando o perdiendo.</p> + +<p>Para aprovechar al máximo esta serie de artículos necesitas tener ya un conocimiento básico o intermedio de <a href="/en-US/Learn/Getting_started_with_the_web/JavaScript_basics">JavaScript</a>. Cuando termines este tutorial serás capaz de construir tus propios juegos Web.</p> + +<p><img alt="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." src="https://mdn.mozillademos.org/files/10383/mdn-breakout-gameplay.png" style="display: block; height: 320px; margin: 0px auto; width: 480px;"></p> + +<h2 id="Detalle_de_las_lecciones">Detalle de las lecciones</h2> + +<p>Todas las lecciones y las diferentes versiones del <a href="http://breakout.enclavegames.com/lesson10.html">famoso juego MDN</a> que estamos construyendo juntos están <a href="https://github.com/end3r/Canvas-gamedev-workshop">disponibles en GitHub</a>:</p> + +<ol> + <li><a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Create_the_Canvas_and_draw_on_it">Crea el lienzo (canvas) y dibuja en él</a></li> + <li><a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Mueve_la_bola">Mueve la bola</a></li> + <li><a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Bounce_off_the_walls">Rebota en las paredes</a></li> + <li><a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Control_pala_y_teclado">Control de la pala y el teclado</a></li> + <li><a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Fin_del_juego">Fin del juego</a></li> + <li><a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Construye_grupo_bloques">Construye el muro de ladrillos</a></li> + <li><a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Deteccion_colisiones">Detección de colisiones</a></li> + <li><a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Track_the_score_and_win">Cuenta los puntos y gana</a></li> + <li><a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Controles_raton">Controles del ratón</a></li> + <li><a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Terminando">Finalizando</a></li> +</ol> + +<p>Empezar con JavaScript puro es la mejor forma de adquirir un conocimiento sólido sobre desarrollo de juegos. Después, puedes escoger cualquier entorno de desarrollo (framework) que te guste y usarlo para tus proyectos. Los frameworks son simplemente herramientas construidas con el lenguaje JavaScript; por tanto aunque planees trabajar con ellas, es bueno aprender primero sobre el mismo lenguaje para saber exactamente qué es lo que hay por debajo. Los frameworks aceleran el tiempo de desarrollo y ayudan a tener en cuenta las partes aburridas del juego, pero si algo no funciona como esperas, siempre puedes intentar depurarlo o simplemente escribir tu solución en JavaScript puro.</p> + +<div class="note"> +<p><strong>Nota</strong>: Si estás interesado en aprender sobre el desarrollo de juegos en 2D usando una entorno de desarrollo, consulta esta serie homóloga, <a href="/en-US/docs/Games/Workflows/2D_breakout_game_Phaser">famoso juego 2D usando Phaser</a>.</p> +</div> + +<div class="note"> +<p><strong>Nota</strong>: Esta serie de artículos puede usarse como material para talleres prácticos de desarrollo de juegos. También puedes hacer uso del <a href="/en-US/docs/">kit de contenido canvas Gamedev</a> basado en este tutorial si quieres dar una charla sobre desarrollo de juegos en general.</p> +</div> + +<h2 id="Siguientes_pasos">Siguientes pasos</h2> + +<p>Vale, ¡vamos a empezar! Dirígete hacia el primer tema — <a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Create_the_Canvas_and_draw_on_it">Crea el lienzo (canvas) y dibuja en él</a>.</p> + +<p>{{Next("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Create_the_Canvas_and_draw_on_it")}} </p> diff --git a/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/mueve_la_bola/index.html b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/mueve_la_bola/index.html new file mode 100644 index 0000000000..60a5df8c5a --- /dev/null +++ b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/mueve_la_bola/index.html @@ -0,0 +1,154 @@ +--- +title: Mueve la bola +slug: Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Mueve_la_bola +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/es-ES/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Create_the_Canvas_and_draw_on_it", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Bounce_off_the_walls")}}</p> + +<div class="summary"> +<p>Este es el segundo paso de los 10 del <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">tutorial de Canvas para el desarrollo de juegos</a>. Puedes encontrar el código fuente como debería quedar después de completar la lección en <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson02.html">Gamedev-Canvas-workshop/lesson2.html</a>.</p> +</div> + +<p><span id="result_box" lang="es"><span>Ya sabes cómo dibujar una pelota, lo has aprendido en el artículo anterior. Ahora vamos a hacer que se mueva.</span> <span>Técnicamente, estaremos pintando la pelota en la pantalla, borrándola y luego pintándola de nuevo en una posición ligeramente diferente cada fotograma para dar la impresión de movimiento, igual que se hace en las películas.</span></span></p> + +<p> </p> + +<h2 id="Definir_un_bucle_de_dibujo">Definir un bucle de dibujo</h2> + +<p> </p> + +<p><span id="result_box" lang="es"><span>Para actualizar el dibujo del lienzo en cada fotograma, necesitamos definir una función de dibujo que se ejecutará una y otra vez, cambiando una serie de variables para modificar la posición de cada personaje (sprite). Para que una misma función se ejecute una y otra vez puedes utilizar una función </span><span>de sincronización de JavaScript, como</span></span> {{domxref("WindowTimers.setInterval()", "setInterval()")}} or {{domxref("window.requestAnimationFrame()", "requestAnimationFrame()")}}.</p> + +<p><span id="result_box" lang="es"><span>Elimina todo el código JavaScript que tienes ahora mismo en de tu archivo HTML, excepto las dos primeras líneas, y añade lo siguiente debajo de ellas.</span> <span>La función draw() se ejecutará dentro de setInterval cada 10 milisegundos:</span></span></p> + +<pre class="brush: js">function draw() { + // código para dibujar +} +setInterval(draw, 10);</pre> + +<p><span id="result_box" lang="es"><span>Gracias a la naturaleza infinita de setInterval, la función draw () se llamará cada 10 milisegundos por siempre, o hasta que lo detengamos.</span> <span>Ahora, vamos a dibujar la bola. A</span></span><span lang="es"><span>grega lo siguiente dentro de tu función draw ():</span></span></p> + +<pre class="brush: js">ctx.beginPath(); +ctx.arc(50, 50, 10, 0, Math.PI*2); +ctx.fillStyle = "#0095DD"; +ctx.fill(); +ctx.closePath(); +</pre> + +<p>Prueba tu código actualizado ahora — la bola debería repintarse en cada fotograma (frame).</p> + +<h2 id="Hacer_que_se_mueva">Hacer que se mueva</h2> + +<div id="gt-res-content"> +<div class="trans-verified-button-small" dir="ltr">Aunque la bola se está dibujando cada 10 milisegundos no se nota porque no hay movimiento, se dibuja una y otra vez en el mismo sitio.<span id="result_box" lang="es"><span>Vamos a cambiar eso.</span> <span>En primer lugar, en lugar de dibujar siempre en la posición (50, 50) definiremos un punto de inicio en la parte central inferior del lienzo en las variables llamadas x e y, a continuación, las utilizaremos para definir la posición en la que se dibuja el círculo.</span><br> +<br> +<span>Primero, agrega las dos líneas siguientes a la función draw (), para definir x e y:</span></span></div> +</div> + +<p> </p> + +<pre class="brush: js">var x = canvas.width/2; +var y = canvas.height-30; +</pre> + +<p> </p> + +<p>A continuación actualiza la función <code>draw()</code> para usar las variables x e y en el método {{domxref("CanvasRenderingContext2D.arc()","arc()")}}, como se muestra en la siguiente línea resaltada:</p> + +<pre class="brush: js; highlight:[3]">function draw() { + ctx.beginPath(); + ctx.arc(x, y, 10, 0, Math.PI*2); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); +} +</pre> + +<p><span id="result_box" lang="es"><span>Ahora viene la parte importante: queremos añadir un valor pequeño a x e y después de que cada fotograma se haya dibujado para que parezca que la pelota se está moviendo.</span> <span>Definamos estos valores pequeños como dx y dy, y establezcamos sus valores en 2 y -2 respectivamente.</span> <span>Agrega lo siguiente debajo de sus definiciones de variables x e y:</span></span></p> + +<pre class="brush: js">var dx = 2; +var dy = -2; +</pre> + +<p><span id="result_box" lang="es"><span>Lo último que hay que hacer es actualizar x e y con nuestras variables dx y dy en cada fotograma, de modo que la bola será pintada en la nueva posición en cada actualización.</span> <span>Agrega las dos nuevas líneas</span></span><span lang="es"><span> siguientes indicadas a continuación a la función draw ():</span></span></p> + +<pre class="brush: js; highlight:[7,8]">function draw() { + ctx.beginPath(); + ctx.arc(x, y, 10, 0, Math.PI*2); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + x += dx; + y += dy; +}</pre> + +<p><span id="result_box" lang="es"><span>Guarda el código de nuevo y pruébalo en tu navegador.</span> <span>Esto funciona bien, aunque parece que la bola está dejando un rastro detrás de ella:</span></span></p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10430/ball-trail.png" style="display: block; height: 320px; margin: 0px auto; width: 480px;"></p> + +<h2 id="Borrar_el_lienzo_antes_de_cada_fotograma">Borrar el lienzo antes de cada fotograma</h2> + +<div id="gt-res-content"> +<div class="trans-verified-button-small" dir="ltr" id="gt-res-dir-ctr"><span id="result_box" lang="es"><span>La bola está dejando un rastro porque estamos pintando un nuevo círculo en cada fotograma sin borrar el anterior.</span> <span>No te preocupes, porque hay un método para borrar todo el contenido de lienzo: {{domxref ("CanvasRenderingContext2D.clearRect ()", "clearRect ()")}}.</span> <span>Este método tiene cuatro parámetros: las coordenadas x e y de la esquina superior izquierda de un rectángulo y las coordenadas x e y de la esquina inferior derecha de un rectángulo.</span> En todo el área definida por ese rectángulo se borrará cualquier cosa que se haya pintado antes<span>.</span></span></div> +</div> + +<div id="gt-res-tools"> +<div id="gt-res-tools-l"> +<div id="gt-pb-star"> </div> +</div> +</div> + +<p>Añade la siguiente nueva línea resaltada a la función draw():</p> + +<pre class="brush: js; highlight:[2]">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; +} +</pre> + +<p><span id="result_box" lang="es"><span>Guarda tu código y vuelve a probarlo. Esta vez verás el movimiento de la bola sin dejar rastro.</span> <span>Cada 10 milisegundos se borra todo el lienzo, se dibuja el círculo azul (nuestra pelota) en una posición determinada y los valores x e y se actualizan para el siguiente fotograma.</span></span></p> + +<h2 id="Limpiar_el_código">Limpiar el código</h2> + +<p><span id="result_box" lang="es"><span>Vamos a añadir más y más comandos a la función draw () en los próximos artículos, por lo que es bueno mantenerlo lo más simple y limpio posible.</span> <span>Comencemos moviendo el código de dibujo de la bola a una función separada.</span><br> + <br> + <span>Reemplaza la función draw() con las dos funciones siguientes:</span></span></p> + +<pre class="brush: 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; +}</pre> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p><span id="result_box" lang="es"><span>Puedes comprobar el código terminado de este artículo en la demostración en vivo a continuación, y jugar con ella para entender mejor cómo funciona:</span></span></p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/3x5foxb1/","","415")}}</p> + +<div class="summary"> +<p>Ejercicio: intenta cambiar la velocidad de la bola en movimiento o la dirección hacia la que se mueve.</p> +</div> + +<h2 id="Siguientes_pasos">Siguientes pasos</h2> + +<p>Hemos dibujado nuestra bola y hemos hecho que se mueva, pero cuando supera el borde del canvas, desaparece. En el tercer capítulo exploraremos como hacer que <a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Bounce_off_the_walls">rebote en las paredes</a>.</p> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Create_the_Canvas_and_draw_on_it", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Bounce_off_the_walls")}}</p> diff --git a/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/terminando/index.html b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/terminando/index.html new file mode 100644 index 0000000000..a3bd5e2c2e --- /dev/null +++ b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/terminando/index.html @@ -0,0 +1,95 @@ +--- +title: Terminando +slug: Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Terminando +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Finishing_up +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{Previous("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Controles_raton")}}</p> + +<div class="summary"> +<p>Este es el último de los 10 pasos del <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Puedes encontrar el código fuente tal y como quedará al terminar esta lección en <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson10.html">Gamedev-Canvas-workshop/lesson10.html</a>.</p> +</div> + +<p>Siempre es posible mejorar cualquier juego que hagamos. Por ejemplo, podemos dar vidas al jugador. Así, aunque pierda la bola una o dos veces, todavía puede intentar derribar todo el muro. También podemos mejorar los aspectos gráficos.</p> + +<h2 id="Dar_vidas_al_jugador">Dar vidas al jugador</h2> + +<p>Dar vidas es bastante sencillo. Primero, añade una variable para guardar el número de vidas que tiene en cada momento. Ponla después de las que ya tienes:</p> + +<pre class="brush: js">var lives = 3;</pre> + +<p>Mostrar por pantalla el número de vidas es prácticamente lo mismo que mostrar el contador de puntos. Añade la función siguiente detrás de la función <code>drawScore()</code>:</p> + +<pre class="brush: js">function drawLives() { + ctx.font = "16px Arial"; + ctx.fillStyle = "#0095DD"; + ctx.fillText("Lives: "+lives, canvas.width-65, 20); +}</pre> + +<p>En lugar de terminar el juego inmediatamente, restaremos una vida hasta que ya no quede ninguna. También podemos colocar la bola y la paleta en la posición inicial cuando el jugador empiece con la vida siguiente. En la función <code style="font-style: normal; font-weight: normal;">draw()</code> cambia las dos líneas siguientes...</p> + +<pre class="brush: js">alert("GAME OVER"); +document.location.reload();</pre> + +<p>... por estas otras:</p> + +<pre class="brush: js">lives--; +if(!lives) { + alert("GAME OVER"); + document.location.reload(); +} +else { + x = canvas.width/2; + y = canvas.height-30; + dx = 2; + dy = -2; + paddleX = (canvas.width-paddleWidth)/2; +}</pre> + +<p>Ahora, cuando la bola toca el fondo, restamos una vida. Si no queda ninguna, el jugador pierde y termina la partida. Si queda alguna, entonces colocamos la bola y la paleta en el centro, y hacemos que la bola vaya en la nueva dirección correcta y a la velocidad inicial.</p> + +<h3 id="Sacar_por_pantalla_el_contador_de_vidas">Sacar por pantalla el contador de vidas</h3> + +<p>Tienes que añadir una llamada a <code>drawLives()</code> dentro de <code>draw()</code> debajo de la llamada a <code>drawScore():</code></p> + +<pre class="brush: js">drawLives(); +</pre> + +<h2 id="Mejorar_el_refresco_con_requestAnimationFrame()">Mejorar el refresco con requestAnimationFrame()</h2> + +<p>Ahora vamos a ocuparnos de algo que no es particular de este juego, sino de la forma en la que se muestran las imágenes en pantalla.</p> + +<p>{{domxref("window.requestAnimationFrame", "requestAnimationFrame")}} ayuda al navegador a refrescar la imagen mejor que con el método {{domxref("windowTimers.setInterval()", "setInterval()")}} que estamos utilizando. Cambia la línea siguiente...</p> + +<pre class="brush: js">setInterval(draw, 10);</pre> + +<p>...por esta otra:</p> + +<pre class="brush: js">draw();</pre> + +<p>Y, ahora, al final de la función draw(), justo antes de la llave que la cierra, añade la línea siguiente, que hará que la función <code>draw()</code> se llame a sí misma una y otra vez:</p> + +<pre class="brush: js">requestAnimationFrame(draw);</pre> + +<p>Ahora draw() se ejecuta una y otra vez con un bucle <code>requestAnimationFrame()</code> pero, en lugar de hacerlo cada 10 milisegundos, dejamos que sea el navegadro quien decida cada cuánto tiempo. El navegador sincronizará el refresco, es decir, el número de fotogramas por segundo, a lo que sea capaz la máquina que está ejecutando el juego. De este modo la animación será más eficiente y más suave que el viejo método <code>setInterval()</code>.</p> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Ya hemos terminado. ¡La versión final del juego está lista para publicar!</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/9temh0ta/","","320")}}</p> + +<div class="note"> +<p><strong>Ejercicio</strong>: cambia el número de vidas y el ángulo de la trayectoria de la bola cuando golpea la paleta.</p> +</div> + +<h2 id="Game_over_-_de_momento!">Game over - de momento!</h2> + +<p>Enhorabuena, has terminado todas las lecciones. Ya has aprendido las técnicas básicas de manipulación del <canvas> y la lógica que hay detrás de los juegos 2D sencillos.</p> + +<p>Ahora sería un buen momento para aprender a utilizar entornos de desarrollo (frameworks) y de continuar con el desarrollo de juegos. Puedes echar un vistazo a estas otra forma de realizar el mismo juego que has visto en <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_breakout_game_Phaser">2D breakout game using Phaser</a>, o de echar un vistazo al tutorial <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/HTML5_Gamedev_Phaser_Device_Orientation">Cyber Orb built in Phaser</a>. También puedes leer el contenido de <a href="https://developer.mozilla.org/en/docs/Games">Games section on MDN</a> para inspirarte y seguir aprendiendo.</p> + +<p>También puedes volve al <a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro">índice de este tutorial</a>. ¡Diviértete programando!</p> + +<p>{{Previous("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Controles_raton")}}</p> diff --git a/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/track_the_score_and_win/index.html b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/track_the_score_and_win/index.html new file mode 100644 index 0000000000..b67a730e94 --- /dev/null +++ b/files/es/games/workflows/famoso_juego_2d_usando_javascript_puro/track_the_score_and_win/index.html @@ -0,0 +1,92 @@ +--- +title: Poner un contador y terminar ganando +slug: Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Track_the_score_and_win +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win +--- +<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Deteccion_colisiones", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Controles_raton")}}</p> + +<div class="summary"> +<p>Este es el octavo capítulo de 10, del <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Puedes encontrar el código fuente como debería quedar tras este capítulo en <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson08.html">Gamedev-Canvas-workshop/lesson8.html</a>.</p> +</div> + +<p><span class="seoSummary">Destruir los ladrillos mola, pero para que el juego sea aún mejor, podría dar puntos cada vez que el jugador rompe un ladrillo, y mostrar un contador.</span></p> + +<h2 id="El_contador">El contador</h2> + +<p>Si puedes ver el contador mientras juegas, puede que consigas impresionar a tus amigos. Necesitas una variable para guardar el contador. Añade esto a tu JavaScript, después de las otras definiciones de variables:</p> + +<pre class="brush: js">var score = 0;</pre> + +<p>También necesitas una función <code>drawScore()</code> para enseñar el contador por pantalla. Añade esto después de la función <code>collisionDetection()</code>:</p> + +<pre class="brush: js">function drawScore() { + ctx.font = "16px Arial"; + ctx.fillStyle = "#0095DD"; + ctx.fillText("Score: "+score, 8, 20); +}</pre> + +<p>Dibujar texto en el <canvas> es similar a dibujar un círculo o cualquier otra figura. La definición del tipo de letra (fuente) se hace igual que en CSS, puedes fijar el tamaño y fuente con el método {{domxref("CanvasRenderingContext2D.font","font()")}} method. Despúes utilizas {{domxref("CanvasRenderingContext2D.fillStyle()","fillStyle()")}} para fijar el color y {{domxref("CanvasRenderingContext2D.fillText","fillText()")}} para escribir el texto y el lugar en el que se va a dibujar. El primer parámetro es el texto en si y los otros dos son las coordenadas.</p> + +<p>Para sumar un punto cada vez que se rompe un ladrillo, añade la línea que está marcada aquí debajo:</p> + +<pre class="brush: js; highlight:[9]">function collisionDetection() { + for(c=0; c<brickColumnCount; c++) { + for(r=0; r<brickRowCount; r++) { + var b = bricks[c][r]; + if(b.status == 1) { + if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) { + dy = -dy; + b.status = 0; + score++; + } + } + } + } +}</pre> + +<p>Llamando a <code>drawScore()</code> (dibujar contador) desde la función <code>draw()</code> hace que se muestre el contador actualizado en la pantalla. Añade la línea siguiente en <code>draw()</code>, justo debajo de la llamada a <code>drawPaddle()</code>:</p> + +<pre class="brush: js">drawScore();</pre> + +<h2 id="Mostrar_un_mensaje_de_victoria_cuando_se_hayan_destruido_todos_los_ladrillos">Mostrar un mensaje de victoria cuando se hayan destruido todos los ladrillos</h2> + +<p>Lo de sumar puntos funciona, pero tiene un final. ¿Qué ocurrirá cuando no queden ladrillos? Precisamente ese es el principal objetivo del juego, tendrás que dibujar un mensaje de victoria. Añade las líneas marcadas a tu función <code>collisionDetection()</code>:</p> + +<pre class="brush: js; highlight:[10,11,12,13]">function collisionDetection() { + for(c=0; c<brickColumnCount; c++) { + for(r=0; r<brickRowCount; r++) { + var b = bricks[c][r]; + if(b.status == 1) { + if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) { + dy = -dy; + b.status = 0; + score++; + if(score == brickRowCount*brickColumnCount) { + alert("YOU WIN, CONGRATULATIONS!"); + document.location.reload(); + } + } + } + } + } +}</pre> + +<p>Gracias a esto, los jugadores pueden ganar cuando rompen todos los ladrillos, que es muy importante. La función <code>document.location.reload()</code> vuelve a cargar la página y el juego empieza de nuevo, una vez se hace clic sobre el botón del alert().</p> + +<h2 id="Compara_tu_código">Compara tu código</h2> + +<p>Puedes comparar tu código con este:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/mvfkcydz/","","320")}}</p> + +<div class="note"> +<p><strong>Ejercicio</strong>: añade más puntos por ladrillo y muestra el contador cuando salga el alert() del final del juego con victoria.</p> +</div> + +<h2 id="Pasos_siguientes">Pasos siguientes</h2> + +<p>El juego, ahora mismo, ya tiene buena pinta. En la siguiente lección conseguirás que sea más atractivo porque añadirás el <a href="https://developer.mozilla.org/es/docs/Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Controles_raton">Control del ratón</a>.</p> + +<p>{{PreviousNext("Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Deteccion_colisiones", "Games/Workflows/Famoso_juego_2D_usando_JavaScript_puro/Controles_raton")}}</p> diff --git a/files/es/games/workflows/html5_gamedev_phaser_device_orientation/index.html b/files/es/games/workflows/html5_gamedev_phaser_device_orientation/index.html new file mode 100644 index 0000000000..135193ec50 --- /dev/null +++ b/files/es/games/workflows/html5_gamedev_phaser_device_orientation/index.html @@ -0,0 +1,437 @@ +--- +title: >- + Introducción al Desarrollo de Juegos en HTML5 con Phaser y la API de + Orientación a Dispositivos +slug: Games/Workflows/HTML5_Gamedev_Phaser_Device_Orientation +tags: + - API Vibración + - API orientacion de dispositivos + - Canvas + - Desarrollo de videojuegos + - HTML5 + - Phaser +translation_of: Games/Tutorials/HTML5_Gamedev_Phaser_Device_Orientation +--- +<div>{{GamesSidebar}}</div><p>{{ draft() }}</p> + +<h2 id="Introducción">Introducción</h2> + +<p><span style="line-height: 1.5;">En este tutorial iremos a través del proceso de construcción de un juego en HTML5 para móviles que utilizará las <em>APIs</em> de <a href="https://developer.mozilla.org/en-US/Apps/Build/gather_and_modify_data/responding_to_device_orientation_changes">Orientación para Dispositivos</a> y <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/API/Vibration">Vibración</a> para mejorar la jugabilidad y estará construido utilizando el <em>framework</em> <a href="http://phaser.io/">Phaser</a>. Se recomienda tener conocimientos básicos de JavaScript para sacar mayor provecho a este tutorial.</span></p> + +<h2 id="Ejemplo"><span style="line-height: 1.5;">Ejemplo</span></h2> + +<p><span style="line-height: 1.5;">Al finalizar este tutorial tendrás un juego <em>demo</em> completamente funcional: <a href="http://orb.enclavegames.com/">Cyber Orb</a>. Se verá más o menos así:</span></p> + +<p><span style="line-height: 1.5;"><img alt="" src="https://mdn.mozillademos.org/files/10297/cyber-orb.png" style="display: block; height: 450px; margin: 0px auto; width: 300px;"></span></p> + +<h2 id="Phaser_framework">Phaser framework</h2> + +<p><a href="http://phaser.io/">Phaser</a> es un <em>framework</em> para construir juegos, de móvil o escritorio, en HTML5 . Es nuevo pero está creciendo velozmente gracias a la apasionada comunidad involucrada en el proceso de desarrollo. Puedes chequearlo <a href="https://github.com/photonstorm/phaser">en GitHub</a> donde se encuentra como <em>open source. </em>Lee <a href="http://docs.phaser.io/">la documentación</a> en línea y recorre su gran colección de <a href="http://examples.phaser.io/">ejemplos</a>. El <em>framework</em> Phaser provee una serie de herramientas que acelerarán el desarrollo y te ayudaran a manejar las tareas genéricas necesarias para completar tu juego, para que así puedas concentrarte en la idea del juego en sí.</p> + +<h2 id="Empezando_con_el_proyecto">Empezando con el proyecto</h2> + +<p>Puedes ver <a href="https://github.com/EnclaveGames/Cyber-Orb">el código fuente de Cyber Orb</a> en GitHub. <span style="line-height: 1.5;">La estructura de carpetas no es nada complicada: </span><span style="line-height: 1.5;">el punto de partida es el archivo </span><code>index.html</code><span style="line-height: 1.5;"> donde inicializaremos el <em>framework</em> y </span><span style="line-height: 1.5;">configuraremos el canvas donde correrá el juego.</span></p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10357/cyber-orb-github.png" style="display: block; height: 423px; width: 620px;"></p> + +<p><span style="line-height: 1.5;">Puedes hacer clic en el archivo index desde tu navegador favorito para iniciar el juego y probarlo. </span><span style="line-height: 1.5;">También hay tres carpetas en el directorio: </span></p> + +<ul> + <li><span style="line-height: 1.5;"><code>img</code></span>: Todas las imágenes que usaremos en el juego.</li> + <li><span style="line-height: 1.5;"><code>src</code></span>: Los archivos JavaScript que contienen todo el código fuente del juego definido dentro.</li> + <li><span style="line-height: 1.5;"><code>audio</code>:</span> Los archivos de sonido usados en el juego.</li> +</ul> + +<h2 id="Configurando_el_canvas">Configurando el canvas</h2> + +<p>Vamos a renderizar nuestro juego sobre el elemento <code><canvas></code>, pero no lo haremos manualmente — de esto se ocupará el <em>framework. </em> Vamos a configurarlo: nuestro punto de partida es el archivo <code>index.html</code> con el siguiente contenido. Puedes crearlo tú mismo si quieres hacer un seguimiento más detallado:</p> + +<pre class="brush: html"><!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <title>Cyber Orb</title> + <style> body { margin: 0; background: #333; } </style> + <script src="src/phaser.min.js"></script> + <script src="src/Boot.js"></script> + <script src="src/Preloader.js"></script> + <script src="src/MainMenu.js"></script> + <script src="src/Game.js"></script> +</head> +<body> +<script> +(function() { + var game = new Phaser.Game(320, 480, Phaser.CANVAS, 'game'); + game.state.add('Boot', Ball.Boot); + game.state.add('Preloader', Ball.Preloader); + game.state.add('MainMenu', Ball.MainMenu); + game.state.add('Game', Ball.Game); + game.state.start('Boot'); +})(); +</script> +</body> +</html></pre> + +<p><span style="line-height: 1.5;">Hasta ahora tenemos una simple página web </span><code>HTML</code><span style="line-height: 1.5;"> con el contenido básico en la sección </span><code><head></code><span style="line-height: 1.5;">: configuración de caracteres, título, estilo y las inclusión de los archivos JavaScripts. El </span><code><body></code><span style="line-height: 1.5;"> contiene la inicialización del framework Phaser y las definiciones del estado del juego.</span></p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">var</span> game <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Phaser<span class="punctuation token">.</span>Game</span><span class="punctuation token">(</span><span class="number token">320</span><span class="punctuation token">,</span> <span class="number token">480</span><span class="punctuation token">,</span> Phaser<span class="punctuation token">.</span>CANVAS<span class="punctuation token">,</span> <span class="string token">'game'</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>La linea de arriba inicializará la intancia de Phaser — los argumentos son el ancho del <code><canvas></code>, su altura, el método de renderizado (estamos utilizando <code>CANVAS</code> pero también existen disponibles las opciones <code>WEBGL</code> y <code>AUTO</code>) y el ID opcional del contenedor DOM en el que queremos poner el <code><canvas></code>. Si no hay nada especificado en el último argumento o el elemento no es encontrado, el <code><canvas></code> será añadido a la etiqueta <code><body></code>. Sin el <em>framework </em>para añadir el elemento canvas hubieses tenido que escribir algo como esto dentro de la etiqueta <code><body></code>:</p> + +<pre class="brush: html line-numbers language-html"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">'</span>game<span class="punctuation token">'</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">'</span>320<span class="punctuation token">'</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">'</span>480<span class="punctuation token">'</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<p>Es importante recordar que el <em>framework</em> está montando métodos útiles para acelerar un montón de cosas como la manipulación de imagenes o la administración de elementos, que serían más difíciles si tuvieramos que hacerlo manualmente.</p> + +<div class="note"> +<p><strong>Nota</strong>: Puedes leer este artículo: "<a href="http://gamedevelopment.tutsplus.com/tutorials/getting-started-with-phaser-building-monster-wants-candy--cms-21723">Building Monster Wants Candy</a>" para una introducción en profundidad a las funciones y métodos específicos de Phaser.</p> +</div> + +<p>Volviendo a los estados del juego: La linea de abajo añade un nuevo estado al juego llamado <code>Boot</code>:</p> + +<pre class="brush: js"><code class="language-html">game.state.add('Boot', Ball.Boot);</code></pre> + +<p>El primer valor es el nombre del estado, el segundo es el objeto al que queremos asignárselo. El metodo <code>start</code> está iniciando el estado dado y haciendolo activo. Veamos qué es lo que son los estados realmente.</p> + +<pre class="brush: html"> </pre> + +<h2 id="Gestionando_los_estados_de_juego">Gestionando los estados de juego</h2> + +<p>Los estados en Phaser son partes separadas de la lógica del juego, en nuestro caso los estamos cargando de archivos JavaScript independientes para un mejor mantenimiento. En este juego tenemos estados básicos: <code>Boot</code>, <code>Preloader</code>, <code>MainMenu</code>, <code>Howto</code> y <code>Game</code>. <code>Boot</code> se hará cargo de la inicialización de algunas opciones de configuración, <code>Preloader</code> cargará todos los elementos utilizados como los gráficos y el audio, <code>MainMenu</code> es el menu con el botón de inicio, <code>Howto</code> muestra las intrucciones de cómo jugar y el estado <code>Game</code> es el que finalmente te permite jugar el juego. Veamos rapidamente el contenido de esos estados.</p> + +<h3 id="Boot.js">Boot.js</h3> + +<p>El estado <code>Boot</code> es el primero en el juego.</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">var</span> Ball <span class="operator token">=</span> <span class="punctuation token">{</span> + _WIDTH<span class="punctuation token">:</span> <span class="number token">320</span><span class="punctuation token">,</span> + _HEIGHT<span class="punctuation token">:</span> <span class="number token">480</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span> +Ball<span class="punctuation token">.</span>Boot <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>game<span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">;</span> +Ball<span class="punctuation token">.</span>Boot<span class="punctuation token">.</span>prototype <span class="operator token">=</span> <span class="punctuation token">{</span> + preload<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>load<span class="punctuation token">.</span><span class="function token">image</span><span class="punctuation token">(</span><span class="string token">'preloaderBg'</span><span class="punctuation token">,</span> <span class="string token">'img/loading-bg.png'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>load<span class="punctuation token">.</span><span class="function token">image</span><span class="punctuation token">(</span><span class="string token">'preloaderBar'</span><span class="punctuation token">,</span> <span class="string token">'img/loading-bar.png'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">,</span> + create<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>game<span class="punctuation token">.</span>scale<span class="punctuation token">.</span>scaleMode <span class="operator token">=</span> Phaser<span class="punctuation token">.</span>ScaleManager<span class="punctuation token">.</span>SHOW_ALL<span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>game<span class="punctuation token">.</span>scale<span class="punctuation token">.</span>pageAlignHorizontally <span class="operator token">=</span> <span class="keyword token">true</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>game<span class="punctuation token">.</span>scale<span class="punctuation token">.</span>pageAlignVertically <span class="operator token">=</span> <span class="keyword token">true</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>game<span class="punctuation token">.</span>state<span class="punctuation token">.</span><span class="function token">start</span><span class="punctuation token">(</span><span class="string token">'Preloader'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p>El objeto principal <code>Ball</code> es definido y estamos añadiendo dos variables llamadas <code>_WIDTH</code> y <code>_HEIGHT</code> esos seran el ancho y la altura del canvas de nuestro juego, respectivamente — nos ayudarán a posicionar los elementos en la pantalla. Estamos cargando dos imagenes primero que serán usadas después en el estado <code>Preload</code> para mostrar el progreso de la carga de los demás elementos. La función <code>create</code> contiene algunas de las configuraciones básicas: estamos configurando la escala y la alineación del canvas, y avanzando al estado <code>Preload</code> cuando todo este listo.</p> + +<h3 id="Preloader.js">Preloader.js</h3> + +<p>El estado <code>Preloader</code> se ocupa de cargar todos los elementos:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js">Ball<span class="punctuation token">.</span>Preloader <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>game<span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">;</span> +Ball<span class="punctuation token">.</span>Preloader<span class="punctuation token">.</span>prototype <span class="operator token">=</span> <span class="punctuation token">{</span> + preload<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>preloadBg <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>add<span class="punctuation token">.</span><span class="function token">sprite</span><span class="punctuation token">(</span><span class="punctuation token">(</span>Ball<span class="punctuation token">.</span>_WIDTH<span class="number token">-297</span><span class="punctuation token">)</span><span class="operator token">*</span><span class="number token">0.5</span><span class="punctuation token">,</span> <span class="punctuation token">(</span>Ball<span class="punctuation token">.</span>_HEIGHT<span class="number token">-145</span><span class="punctuation token">)</span><span class="operator token">*</span><span class="number token">0.5</span><span class="punctuation token">,</span> <span class="string token">'preloaderBg'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>preloadBar <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>add<span class="punctuation token">.</span><span class="function token">sprite</span><span class="punctuation token">(</span><span class="punctuation token">(</span>Ball<span class="punctuation token">.</span>_WIDTH<span class="number token">-158</span><span class="punctuation token">)</span><span class="operator token">*</span><span class="number token">0.5</span><span class="punctuation token">,</span> <span class="punctuation token">(</span>Ball<span class="punctuation token">.</span>_HEIGHT<span class="number token">-50</span><span class="punctuation token">)</span><span class="operator token">*</span><span class="number token">0.5</span><span class="punctuation token">,</span> <span class="string token">'preloaderBar'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>load<span class="punctuation token">.</span><span class="function token">setPreloadSprite</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>preloadBar<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">this</span><span class="punctuation token">.</span>load<span class="punctuation token">.</span><span class="function token">image</span><span class="punctuation token">(</span><span class="string token">'ball'</span><span class="punctuation token">,</span> <span class="string token">'img/ball.png'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="comment token">// ...</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>load<span class="punctuation token">.</span><span class="function token">spritesheet</span><span class="punctuation token">(</span><span class="string token">'button-start'</span><span class="punctuation token">,</span> <span class="string token">'img/button-start.png'</span><span class="punctuation token">,</span> <span class="number token">146</span><span class="punctuation token">,</span> <span class="number token">51</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="comment token">// ...</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>load<span class="punctuation token">.</span><span class="function token">audio</span><span class="punctuation token">(</span><span class="string token">'audio-bounce'</span><span class="punctuation token">,</span> <span class="punctuation token">[</span><span class="string token">'audio/bounce.ogg'</span><span class="punctuation token">,</span> <span class="string token">'audio/bounce.mp3'</span><span class="punctuation token">,</span> <span class="string token">'audio/bounce.m4a'</span><span class="punctuation token">]</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">,</span> + create<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>game<span class="punctuation token">.</span>state<span class="punctuation token">.</span><span class="function token">start</span><span class="punctuation token">(</span><span class="string token">'MainMenu'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p>Para crear un nuevo botón tenemos el método <code>add.button</code> con la siguiente lista de argumentos opcionales:</p> + +<ul> + <li>Posición absoluta superior del canvas, en pixeles.</li> + <li>Posición absoluta izquierda del canvas, en pixeles.</li> + <li>Nombre del elemento imagen utilizado por el botón.</li> + <li>Función que será ejecutada cuando alguien haga click sobre el botón.</li> + <li>El contexto de la ejecución.</li> + <li>Cuadro (<em>frame) </em>del elemento imagen utilizado para el estado 'hover' del botón (cuando el mouse se encuentra sobre él).</li> + <li>Cuadro (<em>frame)</em> del elemento imagen utilizado para el estado 'normal' o 'out' del botón.</li> + <li>Cuadro (<em>frame) </em>del elemento imagen utilizado para el 'click' o 'down' del botón.</li> +</ul> + +<p>El <code>anchor.set</code> colocará el punto de ancla en el botón con el cual se realizarán y aplicarán todos los cálculos de posición para el botón. En nuestro caso, está anclado a la mitad del borde izquierdo y al comienzo del borde superior, para así centrarlo de manera horizontal facilmente, sin necesidad de saber su ancho.</p> + +<p>Cuando el boton de inicio es presionado, en lugar de saltar directamente a la acción, el juego mostrará la pantalla con las intrucciones para jugar.</p> + +<h3 id="Howto.js">Howto.js</h3> + +<pre class="brush: js line-numbers language-js"><code class="language-js">Ball<span class="punctuation token">.</span>Howto <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>game<span class="punctuation token">)</span> <span class="punctuation token">{</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span> +Ball<span class="punctuation token">.</span>Howto<span class="punctuation token">.</span>prototype <span class="operator token">=</span> <span class="punctuation token">{</span> + create<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>buttonContinue <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>add<span class="punctuation token">.</span><span class="function token">button</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="string token">'screen-howtoplay'</span><span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>startGame<span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">,</span> + startGame<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>game<span class="punctuation token">.</span>state<span class="punctuation token">.</span><span class="function token">start</span><span class="punctuation token">(</span><span class="string token">'Game'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p>El estado <code>Howto</code> muesta las intrucciones de juego en la pantalla antes de comenzar el juego. Luego de clickear la pantalla el juego es lanzado.</p> + +<h3 id="Game.js">Game.js</h3> + +<p>El estado <code>Game</code> del archivo <code>Game.js</code> es donde ocurre toda la magia. Todas las inicializaciones estan en la función <code>create()</code> (que se lanza una vez al comienzo del juego). Luego de eso, algunas funcionalidades requeriran más código para controlar — escribiremos nuestras propias funciones para manejar tareas más complicadas. En particular, toma nota de la función <code>update()</code> que es ejecutada en cada <em>frame </em>y actualiza cosas como la posición de la pelota.</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js">Ball<span class="punctuation token">.</span>Game <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>game<span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">;</span> +Ball<span class="punctuation token">.</span>Game<span class="punctuation token">.</span>prototype <span class="operator token">=</span> <span class="punctuation token">{</span> + create<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">,</span> + initLevels<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">,</span> + showLevel<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span>level<span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">,</span> + updateCounter<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">,</span> + managePause<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">,</span> + manageAudio<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">,</span> + update<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">,</span> + wallCollision<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">,</span> + handleOrientation<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span>e<span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">,</span> + finishLevel<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span><span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p>Las funciones <code>create</code> y <code>update</code> son específicas del <em>framework</em>, mientras que otras seran nuestras propias creaciones:</p> + +<ul> + <li><code>initLevels</code> inicializa los datos del nivel.</li> + <li><code>showLevel</code> imprime los datos del nivel en la pantalla.</li> + <li><code>updateCounter</code> actualiza el tiempo dedicado a jugar cada nivel y registra el tiempo total dedicado al juego.</li> + <li><code>managePause</code> pausa y reanuda el juego.</li> + <li><code>manageAudio</code> enciende y apaga el audio.</li> + <li><code>wallCollision</code> es ejecutado cuando la pelota golpea las paredes u otros objetos.</li> + <li><code>handleOrientation</code> es la función ligada al evento responsable por la API de orientación de dispositivo, proporciona los controles de movimiento cuando el juego es ejecutado en un dispositivo móvil con el hardware apropiado.</li> + <li><code>finishLevel</code> carga un nuevo nivel cuando se completa el nivel actual, o termina el juego si se completa el nivel final.</li> +</ul> + +<h4 id="Agregando_la_pelota_y_sus_mecanismos_de_movimiento">Agregando la pelota y sus mecanismos de movimiento</h4> + +<p>Primero vamos a ir a la función <code>create()</code>, inicializamos el objeto <code>ball</code> y le asignamos unas cuantas propiedades:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">this</span><span class="punctuation token">.</span>ball <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>add<span class="punctuation token">.</span><span class="function token">sprite</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>ballStartPos<span class="punctuation token">.</span>x<span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>ballStartPos<span class="punctuation token">.</span>y<span class="punctuation token">,</span> <span class="string token">'ball'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">.</span>anchor<span class="punctuation token">.</span><span class="keyword token">set</span><span class="punctuation token">(</span><span class="number token">0.5</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">this</span><span class="punctuation token">.</span>physics<span class="punctuation token">.</span><span class="function token">enable</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">,</span> Phaser<span class="punctuation token">.</span>Physics<span class="punctuation token">.</span>ARCADE<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">.</span>body<span class="punctuation token">.</span><span class="function token">setSize</span><span class="punctuation token">(</span><span class="number token">18</span><span class="punctuation token">,</span> <span class="number token">18</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">.</span>body<span class="punctuation token">.</span>bounce<span class="punctuation token">.</span><span class="keyword token">set</span><span class="punctuation token">(</span><span class="number token">0.3</span><span class="punctuation token">,</span> <span class="number token">0.3</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>Aqui estamos agregando un sprite en un lugar de la pantalla y utilizando la imagen de la pelota de los elementos gráficos ya cargados. También estamos configurando el <code>anchor</code> (ancla) que realizará los cálculos de física para el centro de la pelota, habilitando el motor de físicas Arcade (que manejara todas las físicas para el movimiento de la pelota), y estableciendo el tamaño del cuerpo para la detección de colisiones. La propiedad <code>bounce</code> es utilizada para configurar el 'rebote' de la pelota cuando golpea los obstaculos.</p> + +<h4 id="Controlando_la_pelota">Controlando la pelota</h4> + +<p>Es genial tener lista la pelota para poder lanzarla en la zona del juego, pero también es importante poder realmente moverla! Ahora vamos a añadir la capacidad de controlar con el teclado la pelota en los dispositivos de escritorio, y luego pasaremos a la implementación de la API de Orientación de Dispositivo. Vamos a enfocarnos en el teclado primero añadiendo lo siguiente a la función <code>create()</code>:</p> + +<pre class="brush: js">this.keys = this.game.input.keyboard.createCursorKeys();</pre> + +<p>Como puedes ver, hay una función especial de Phaser llamada <code>createCursorKeys()</code> que nos dará un objeto con controladores de evento para las cuatro teclas de flecha, que nos permitira jugar con: arriba, abajo, izquierda y derecha.</p> + +<p>A continuación añadiremos el siguiente código a la función <code>update()</code>, para que sea ejecutado en cada <em>frame</em>. El objeto <code>this.keys</code> será chequeado con el input del jugador (las teclas que presione por ejemplo) así la pelota podrá reaccionar acorde, con una fuerza predefinida:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">if</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>keys<span class="punctuation token">.</span>left<span class="punctuation token">.</span>isDown<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">.</span>body<span class="punctuation token">.</span>velocity<span class="punctuation token">.</span>x <span class="operator token">-</span><span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>movementForce<span class="punctuation token">;</span> +<span class="punctuation token">}</span> +<span class="keyword token">else</span> <span class="keyword token">if</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>keys<span class="punctuation token">.</span>right<span class="punctuation token">.</span>isDown<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">.</span>body<span class="punctuation token">.</span>velocity<span class="punctuation token">.</span>x <span class="operator token">+</span><span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>movementForce<span class="punctuation token">;</span> +<span class="punctuation token">}</span> +<span class="keyword token">if</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>keys<span class="punctuation token">.</span>up<span class="punctuation token">.</span>isDown<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">.</span>body<span class="punctuation token">.</span>velocity<span class="punctuation token">.</span>y <span class="operator token">-</span><span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>movementForce<span class="punctuation token">;</span> +<span class="punctuation token">}</span> +<span class="keyword token">else</span> <span class="keyword token">if</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>keys<span class="punctuation token">.</span>down<span class="punctuation token">.</span>isDown<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">.</span>body<span class="punctuation token">.</span>velocity<span class="punctuation token">.</span>y <span class="operator token">+</span><span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>movementForce<span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p>De esa manera podemos verificar qué tecla es presionada en determinado <em>frame</em> y aplicar la fuerza definida a la pelota, así aumentar la velocidad en la dirección correcta.</p> + +<h4 id="Implementando_la_API_de_Orientación_del_Dispositivo">Implementando la API de Orientación del Dispositivo</h4> + +<p>Probablemente la parte más interesante del juego es que utiliza la API de Orientación para Dispositivos móviles. Gracias a esto puedes jugar el juego inclinando el dispositivo en la dirección que quieres que la pelota ruede. Aquí está el código de la función <code>create()</code><em> </em>responsable por esto:</p> + +<pre class="brush: js">window.addEventListener("deviceorientation", this.handleOrientation, true);</pre> + +<p>Vamos a añadir un detector de eventos al evento "<code>deviceorientation</code>" y vincularlo a la función <code>handleOrientation</code>, se ve como esto:</p> + +<pre class="brush: js">handleOrientation: function(e) { + var x = e.gamma; + var y = e.beta; +<code class="language-js"> Ball<span class="punctuation token">.</span>_player<span class="punctuation token">.</span>body<span class="punctuation token">.</span>velocity<span class="punctuation token">.</span>x <span class="operator token">+</span><span class="operator token">=</span> x<span class="punctuation token">;</span> + Ball<span class="punctuation token">.</span>_player<span class="punctuation token">.</span>body<span class="punctuation token">.</span>velocity<span class="punctuation token">.</span>y <span class="operator token">+</span><span class="operator token">=</span> y<span class="punctuation token">;</span></code> +}</pre> + +<p><span style="line-height: 1.5;">Mientras más inclines el dispositivo, más fuerza se aplica a la pelota y la velocidad en la que se mueve es mayor.</span></p> + +<p><span style="line-height: 1.5;"><img alt="" src="https://mdn.mozillademos.org/files/10369/cyber-orb-flame-orientation.png"></span></p> + +<div class="note"> +<p><span style="line-height: 1.5;"><strong>Nota</strong>: Para encontrar más sobre implementar la orientación de los dispositivos y cómo se vé en código crudo, lee </span> <a href="https://developer.mozilla.org/en-US/Apps/Build/gather_and_modify_data/responding_to_device_orientation_changes">Keep it level: responding to device orientation changes</a>.</p> +</div> + +<h4 id="Añadiendo_el_agujero">Añadiendo el agujero</h4> + +<p>El principal objetivo del juego es mover la pelota desde la posición inicial a la posición final: un agujero en el suelo. Esta implementación es muy similar a la parte anterior en donde creamos la pelota, y también es añadida en la función <code>create()</code> de nuestro estado <code>Game</code>:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">this</span><span class="punctuation token">.</span>hole <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>add<span class="punctuation token">.</span><span class="function token">sprite</span><span class="punctuation token">(</span>Ball<span class="punctuation token">.</span>_WIDTH<span class="operator token">*</span><span class="number token">0.5</span><span class="punctuation token">,</span> <span class="number token">90</span><span class="punctuation token">,</span> <span class="string token">'hole'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">this</span><span class="punctuation token">.</span>physics<span class="punctuation token">.</span><span class="function token">enable</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>hole<span class="punctuation token">,</span> Phaser<span class="punctuation token">.</span>Physics<span class="punctuation token">.</span>ARCADE<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">this</span><span class="punctuation token">.</span>hole<span class="punctuation token">.</span>anchor<span class="punctuation token">.</span><span class="keyword token">set</span><span class="punctuation token">(</span><span class="number token">0.5</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">this</span><span class="punctuation token">.</span>hole<span class="punctuation token">.</span>body<span class="punctuation token">.</span><span class="function token">setSize</span><span class="punctuation token">(</span><span class="number token">2</span><span class="punctuation token">,</span> <span class="number token">2</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>La diferencia está en que el cuerpo del agujero se configura como inamovible por lo que no se moverá cuando acertamos con la pelota y tendrá calculada la detección de colisión (esto se tratará más adelante en este artículo).</p> + +<h4 id="Construyendo_el_laberinto_de_bloques"><strong>Construyendo el laberinto de bloques</strong></h4> + +<p>Para hacer más difícil el juego, y más interesante, añadiremos algunos obstaculos entre la pelota y la sálida. Podríamos usar un editor de niveles pero por motivo de este tutorial, vamos a crear algo nosotros mismos.</p> + +<p>Para contener el bloque de información usaremos un <em>array</em> con los datos de nivel: para cada bloque almacenaremos las posiciones abolutas izquierda y superior en pixeles (<strong>x </strong>e <strong>y</strong>) y el tipo de bloque: horizontal o vertical (<code>t</code> con el valor <code>'w'</code> para el ancho, y <code>'h'</code> para la altura). Luego, para cargar el nivel analizaremos los datos y mostraremos los bloques especificos para ese nivel. En la función <code>initLevels</code> tenemos:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">this</span><span class="punctuation token">.</span>levelData <span class="operator token">=</span> <span class="punctuation token">[</span> + <span class="punctuation token">[</span> + <span class="punctuation token">{</span> x<span class="punctuation token">:</span> <span class="number token">96</span><span class="punctuation token">,</span> y<span class="punctuation token">:</span> <span class="number token">224</span><span class="punctuation token">,</span> t<span class="punctuation token">:</span> <span class="string token">'w'</span> <span class="punctuation token">}</span> + <span class="punctuation token">]</span><span class="punctuation token">,</span> + <span class="punctuation token">[</span> + <span class="punctuation token">{</span> x<span class="punctuation token">:</span> <span class="number token">72</span><span class="punctuation token">,</span> y<span class="punctuation token">:</span> <span class="number token">320</span><span class="punctuation token">,</span> t<span class="punctuation token">:</span> <span class="string token">'w'</span> <span class="punctuation token">}</span><span class="punctuation token">,</span> + <span class="punctuation token">{</span> x<span class="punctuation token">:</span> <span class="number token">200</span><span class="punctuation token">,</span> y<span class="punctuation token">:</span> <span class="number token">320</span><span class="punctuation token">,</span> t<span class="punctuation token">:</span> <span class="string token">'h'</span> <span class="punctuation token">}</span><span class="punctuation token">,</span> + <span class="punctuation token">{</span> x<span class="punctuation token">:</span> <span class="number token">72</span><span class="punctuation token">,</span> y<span class="punctuation token">:</span> <span class="number token">150</span><span class="punctuation token">,</span> t<span class="punctuation token">:</span> <span class="string token">'w'</span> <span class="punctuation token">}</span> + <span class="punctuation token">]</span><span class="punctuation token">,</span> + <span class="comment token">// ...</span> +<span class="punctuation token">]</span><span class="punctuation token">;</span></code></pre> + +<p>Todos los elementos del <em>array</em> contienen una colección de bloques con una posición <code>x</code> e <code>y</code> y un valor <code>t</code> para cada uno. Luego de <code>levelData</code> pero dentro de la función <code>initLevels</code>, añadiremos los bloques dentro de un <em>array</em> en el loop <code>for</code> usando algunos de los métodos específicos del <em>framework</em>:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">for</span><span class="punctuation token">(</span><span class="keyword token">var</span> i<span class="operator token">=</span><span class="number token">0</span><span class="punctuation token">;</span> i<span class="operator token"><</span><span class="keyword token">this</span><span class="punctuation token">.</span>maxLevels<span class="punctuation token">;</span> i<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> newLevel <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>add<span class="punctuation token">.</span><span class="function token">group</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + newLevel<span class="punctuation token">.</span>enableBody <span class="operator token">=</span> <span class="keyword token">true</span><span class="punctuation token">;</span> + newLevel<span class="punctuation token">.</span>physicsBodyType <span class="operator token">=</span> Phaser<span class="punctuation token">.</span>Physics<span class="punctuation token">.</span>ARCADE<span class="punctuation token">;</span> + <span class="keyword token">for</span><span class="punctuation token">(</span><span class="keyword token">var</span> e<span class="operator token">=</span><span class="number token">0</span><span class="punctuation token">;</span> e<span class="operator token"><</span><span class="keyword token">this</span><span class="punctuation token">.</span>levelData<span class="punctuation token">[</span>i<span class="punctuation token">]</span><span class="punctuation token">.</span>length<span class="punctuation token">;</span> e<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> item <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>levelData<span class="punctuation token">[</span>i<span class="punctuation token">]</span><span class="punctuation token">[</span>e<span class="punctuation token">]</span><span class="punctuation token">;</span> + newLevel<span class="punctuation token">.</span><span class="function token">create</span><span class="punctuation token">(</span>item<span class="punctuation token">.</span>x<span class="punctuation token">,</span> item<span class="punctuation token">.</span>y<span class="punctuation token">,</span> <span class="string token">'element-'</span><span class="operator token">+</span>item<span class="punctuation token">.</span>t<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + newLevel<span class="punctuation token">.</span><span class="function token">setAll</span><span class="punctuation token">(</span><span class="string token">'body.immovable'</span><span class="punctuation token">,</span> <span class="keyword token">true</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + newLevel<span class="punctuation token">.</span>visible <span class="operator token">=</span> <span class="keyword token">false</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>levels<span class="punctuation token">.</span><span class="function token">push</span><span class="punctuation token">(</span>newLevel<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p>Primero, <code>add.group()</code> es usado para crear un nuevo grupo de items. Luego, el <em>body tipe</em> <code>ARCADE</code> se configura para permitir los cálculos de física. El método <code>newLevel.create</code> crea nuevos items en el grupo con posiciones superior e izquierda iniciales y su propia imagen. Si no quieres recorrer nuevamente la lista de elementos para agregar una propiedad a cada uno explicitamente, puedes usar <code>setAll</code> en un grupo para aplicarlo a todos los items en ese grupo.</p> + +<p>Los objetos son almacenados en el <em>array</em> <code>this.levels</code>, el cual es por defecto invisible. Para cargar niveles específicos, nos aseguramos de que los niveles previos esten escondidos, y mostramos el nivel actual:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js">showLevel<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span>level<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> lvl <span class="operator token">=</span> level <span class="operator token">|</span> <span class="keyword token">this</span><span class="punctuation token">.</span>level<span class="punctuation token">;</span> + <span class="keyword token">if</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>levels<span class="punctuation token">[</span>lvl<span class="number token">-2</span><span class="punctuation token">]</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>levels<span class="punctuation token">[</span>lvl<span class="number token">-2</span><span class="punctuation token">]</span><span class="punctuation token">.</span>visible <span class="operator token">=</span> <span class="keyword token">false</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>levels<span class="punctuation token">[</span>lvl<span class="number token">-1</span><span class="punctuation token">]</span><span class="punctuation token">.</span>visible <span class="operator token">=</span> <span class="keyword token">true</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p>Gracias a eso el juego da al jugador un reto: ahora tiene que rodar la pelota a través del área de juego y guiarla por el laberinto construido por bloques. Es solo un ejemplo de cargar los niveles, y solo hay 5 puramente para mostrar la idea, pero podés trabajar en expandirlo por tu cuenta.</p> + +<h4 id="Detección_de_colisión"><strong>Detección de colisión</strong></h4> + +<p>Hasta este punto tenemos la pelota, que puede ser controlada por el jugador, el agujero que se tiene que alcanzar y los obstáculos que bloquean el camino. <span style="line-height: 1.5;">Sin embargo, hay un problema: nuestro juego todavía no tiene ninguna detección de colisiones, así que no sucede nada cuando la pelota golpea los bloques, sólo los atraviesa. Vamos a arreglarlo! La buena noticia es que el <em>framework</em> se ocupará de calcular la detección de colisones, nosotros sólo debemos especificar los objetos con los que colisionará en la función <code>update()</code>:</span></p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">this</span><span class="punctuation token">.</span>physics<span class="punctuation token">.</span>arcade<span class="punctuation token">.</span><span class="function token">collide</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>borderGroup<span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>wallCollision<span class="punctuation token">,</span> <span class="keyword token">null</span><span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">this</span><span class="punctuation token">.</span>physics<span class="punctuation token">.</span>arcade<span class="punctuation token">.</span><span class="function token">collide</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>levels<span class="punctuation token">[</span><span class="keyword token">this</span><span class="punctuation token">.</span>level<span class="number token">-1</span><span class="punctuation token">]</span><span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>wallCollision<span class="punctuation token">,</span> <span class="keyword token">null</span><span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>Esto le dirá al <em>framework</em> que ejecute la función <code>wallCollision</code> cuando la pelota golpee cualquiera de las paredes. Podemos usar la función <code>wallCollision</code> para añadir cualquier funcionalidad que querramos, como por ejemplo agregar el sonido de rebote e implementar la <strong>API de Vibración</strong>.</p> + +<p><span style="line-height: 1.5;">También debemos volver al objeto pelota y limitarlo a moverse sólo en la zona visible, para que no salga de la pantalla. Hay una función muy útil en Phaser que se llama </span><code style="font-style: normal; line-height: 1.5;">collideWorldBounds</code><span style="line-height: 1.5;">:</span></p> + +<pre class="brush: js">ball.body.collideWorldBounds = true;</pre> + +<p>Hace exactamente lo que necesitamos: ahora la pelota rebotará en los bordes de la pantalla como de las paredes.</p> + +<h4 id="Añadiendo_el_sonido">Añadiendo el sonido</h4> + +<p>Entre los elementos precargados hay una pista de audio (en varios formatos para asegurar la compatibilidad con el navegador), que podremos usar ahora. Debe primero ser definida en la función <code>create()</code>:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">this</span><span class="punctuation token">.</span>bounceSound <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>game<span class="punctuation token">.</span>add<span class="punctuation token">.</span><span class="function token">audio</span><span class="punctuation token">(</span><span class="string token">'audio-bounce'</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p><span class="punctuation token">Si el estado del audio es <code>true</code> (es decir que el sonido del juego está activado)</span> podremos reproducirlo en la función <code>wallCollision</code>:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">if</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>audioStatus<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>bounceSound<span class="punctuation token">.</span><span class="function token">play</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p>Eso es todo: cargar y reproducir sonidos es sencillo con Phaser.</p> + +<h4 id="Implementando_la_API_de_Vibración">Implementando la API de Vibración</h4> + +<p>Cuando la detección de colisión funcione como es esperado, añadamos algunos efectos especiales con la ayuda de la API de Vibración.<img alt="" src="https://mdn.mozillademos.org/files/10371/cyber-orb-flame-vibration.png"></p> + +<p>La mejor forma de usarla en nuestro caso es haciendo que el teléfono vibre cada vez que la pelota golpee las paredes: dentro de la función <code>wallCollision</code>:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">if</span><span class="punctuation token">(</span><span class="string token">"vibrate"</span> <span class="keyword token">in</span> window<span class="punctuation token">.</span>navigator<span class="punctuation token">)</span> <span class="punctuation token">{</span> + window<span class="punctuation token">.</span>navigator<span class="punctuation token">.</span><span class="function token">vibrate</span><span class="punctuation token">(</span><span class="number token">100</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p><span class="punctuation token">Si el método <code>vibrate</code> es soportado por el navegador y está disponible en el objeto <code>window.navigator</code>, hará vibrar al telefono por 100 milisegundos. Eso es todo!</span></p> + +<h4 id="Añadiendo_el_tiempo_transcurrido">Añadiendo el tiempo transcurrido</h4> + +<p>Para mejorar la re-jugabilidad y dar a los jugadores la opción de competir entre ellos, almacenaremos el tiempo transcurrido: los jugadores entonces intentaran mejorar su tiempo de finalizacion. Para implementar esto en el juego tenemos que crear una variable para almacenar el número actual de segundos transcurrido desde el inicio del juego y mostrarselo al jugador durante el juego. Definamos primero las variables en la función <code>create</code>:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">this</span><span class="punctuation token">.</span>timer <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> <span class="comment token">// time elapsed in the current level</span> +<span class="keyword token">this</span><span class="punctuation token">.</span>totalTimer <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> <span class="comment token">// time elapsed in the whole game</span></code></pre> + +<p>Luego, podemos inicializar los objetos de texto necesarios para mostrar la información al usuario:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">this</span><span class="punctuation token">.</span>timerText <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>game<span class="punctuation token">.</span>add<span class="punctuation token">.</span><span class="function token">text</span><span class="punctuation token">(</span><span class="number token">15</span><span class="punctuation token">,</span> <span class="number token">15</span><span class="punctuation token">,</span> <span class="string token">"Time: "</span><span class="operator token">+</span><span class="keyword token">this</span><span class="punctuation token">.</span>timer<span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>fontBig<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">this</span><span class="punctuation token">.</span>totalTimeText <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>game<span class="punctuation token">.</span>add<span class="punctuation token">.</span><span class="function token">text</span><span class="punctuation token">(</span><span class="number token">120</span><span class="punctuation token">,</span> <span class="number token">30</span><span class="punctuation token">,</span> <span class="string token">"Total time: "</span><span class="operator token">+</span><span class="keyword token">this</span><span class="punctuation token">.</span>totalTimer<span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>fontSmall<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>Estamos definiendo la posición superior e izquierda del texto, el contenido que se muestra y el estilo aplicado al texto. Lo hemos impreso en pantalla, pero sería bueno actualizar los valores cada segundo:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">this</span><span class="punctuation token">.</span>time<span class="punctuation token">.</span>events<span class="punctuation token">.</span><span class="function token">loop</span><span class="punctuation token">(</span>Phaser<span class="punctuation token">.</span>Timer<span class="punctuation token">.</span>SECOND<span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>updateCounter<span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>Este bucle, también en la función <code>create</code>, ejecutará la función <code>updateCounter</code> cada segundo desde el comienzo del juego, así podemos aplicar los cambios acordes. Así es como se ve la función <code>updateCounter</code> completa:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js">updateCounter<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>timer<span class="operator token">++</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>timerText<span class="punctuation token">.</span><span class="function token">setText</span><span class="punctuation token">(</span><span class="string token">"Time: "</span><span class="operator token">+</span><span class="keyword token">this</span><span class="punctuation token">.</span>timer<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>totalTimeText<span class="punctuation token">.</span><span class="function token">setText</span><span class="punctuation token">(</span><span class="string token">"Total time: "</span><span class="operator token">+</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>totalTimer<span class="operator token">+</span><span class="keyword token">this</span><span class="punctuation token">.</span>timer<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">,</span></code></pre> + +<p>Como puedes ver estamos incrementando la variable <code>this.timer</code> y actualizando el contenido del objeto de texto con el valor actual en cada iteración, por lo que el jugador verá el tiempo transcurrido.</p> + +<h4 id="Terminando_el_nivel_y_el_juego">Terminando el nivel y el juego</h4> + +<p>La pelota está rodando en la pantalla, el temporizador funciona y tenemos el agujero al que tenemos que llegar. Vamos a configurar la posibilidad de finalizar el juego! La siguiente linea en la funcion <code>update()</code> añade un detector que se activa cuando la pelota llega al agujero.</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">this</span><span class="punctuation token">.</span>physics<span class="punctuation token">.</span>arcade<span class="punctuation token">.</span><span class="function token">overlap</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>hole<span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>finishLevel<span class="punctuation token">,</span> <span class="keyword token">null</span><span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>Esto funciona de manera similar al método <code>colide</code> explicado anteriormente. Cuando la pelota se superpone con el agujero (en lugar de colisionar), la función <code>finishLevel</code> es ejecutada:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js">finishLevel<span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">if</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>level <span class="operator token">>=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>maxLevels<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>totalTimer <span class="operator token">+</span><span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>timer<span class="punctuation token">;</span> + <span class="function token">alert</span><span class="punctuation token">(</span><span class="string token">'Congratulations, game completed!\nTotal time of play: '</span><span class="operator token">+</span><span class="keyword token">this</span><span class="punctuation token">.</span>totalTimer<span class="operator token">+</span><span class="string token">' seconds!'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>game<span class="punctuation token">.</span>state<span class="punctuation token">.</span><span class="function token">start</span><span class="punctuation token">(</span><span class="string token">'MainMenu'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="keyword token">else</span> <span class="punctuation token">{</span> + <span class="function token">alert</span><span class="punctuation token">(</span><span class="string token">'Congratulations, level '</span><span class="operator token">+</span><span class="keyword token">this</span><span class="punctuation token">.</span>level<span class="operator token">+</span><span class="string token">' completed!'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>totalTimer <span class="operator token">+</span><span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>timer<span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>timer <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>level<span class="operator token">++</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>timerText<span class="punctuation token">.</span><span class="function token">setText</span><span class="punctuation token">(</span><span class="string token">"Time: "</span><span class="operator token">+</span><span class="keyword token">this</span><span class="punctuation token">.</span>timer<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>totalTimeText<span class="punctuation token">.</span><span class="function token">setText</span><span class="punctuation token">(</span><span class="string token">"Total time: "</span><span class="operator token">+</span><span class="keyword token">this</span><span class="punctuation token">.</span>totalTimer<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>levelText<span class="punctuation token">.</span><span class="function token">setText</span><span class="punctuation token">(</span><span class="string token">"Level: "</span><span class="operator token">+</span><span class="keyword token">this</span><span class="punctuation token">.</span>level<span class="operator token">+</span><span class="string token">" / "</span><span class="operator token">+</span><span class="keyword token">this</span><span class="punctuation token">.</span>maxLevels<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">.</span>body<span class="punctuation token">.</span>x <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>ballStartPos<span class="punctuation token">.</span>x<span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">.</span>body<span class="punctuation token">.</span>y <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>ballStartPos<span class="punctuation token">.</span>y<span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">.</span>body<span class="punctuation token">.</span>velocity<span class="punctuation token">.</span>x <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>ball<span class="punctuation token">.</span>body<span class="punctuation token">.</span>velocity<span class="punctuation token">.</span>y <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> + <span class="keyword token">this</span><span class="punctuation token">.</span><span class="function token">showLevel</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">,</span></code></pre> + +<p>Si el nivel actual es igual al maximo número de niveles (5, en este caso), entonces el juego termina: recibiras un mensaje de felicitación junto con el numero de segundas transcurridos durante todo el juego, y un botoón para presionar que te llevará al menú principal.</p> + +<p>Si el nivel actual es menor que 5, todas las variables necesarias se reinician y el siguiente nivel es cargado.</p> + +<h2 id="Ideas_para_nuevas_características">Ideas para nuevas características</h2> + +<p><span style="line-height: 1.5;">Esto no es más que una demostración funcional de un juego que podría tener un montón de características adicionales. Por ejemplo podemos añadir poderes para recoger en el camino que harán que nuestra pelota ruede más rápido, otro podría detener el temporizador durante unos segundos o dar la pelota poderes especiales para atravesar obstáculos. También hay espacio para los obstáculos y trampas que harán más lenta la pelota, acelerar el tiempo o trampas de la propia pelota. Puedes crear más niveles con dificultades diferentes para cada uno. Incluso puedes obtener logros, tablas de clasificación y medallas para diferentes acciones en el juego. Hay un sinfín de posibilidades: sólo dependen de tu imaginación.</span></p> + +<h2 id="Resumen">Resumen</h2> + +<p>Espero que este tutorial te ayude a introducirte dentro del desarrollo de los juegos 2D y te inspire a crear asombrosos juegos por tu cuenta. Puedes jugar el demo de Cyber Orb y chequear su código fuente en GitHub.</p> + +<p>HTML5 nos da herramientas en bruto, los <em>frameworks</em> construidos sobre estas se están volviendo más rápidos y mejores, por lo que ahora es un gran momento para meterse en el desarrollo de juegos web. En este tutorial usamos Phaser, pero hay un gran número de otros <em>frameworks</em> que vale la pena considerar también, como ImpactJS, Construct 2 o PlayCanvas — depende de tus preferencias, habilidades de programación (o la falta de estas), el tamaño de tu proyecto, los requerimientos y otros aspectos. Deberías chequearlos todos y decidir cual es el que mejor se ajusta a tus necesidades.</p> diff --git a/files/es/games/workflows/index.html b/files/es/games/workflows/index.html new file mode 100644 index 0000000000..3a0807cc77 --- /dev/null +++ b/files/es/games/workflows/index.html @@ -0,0 +1,10 @@ +--- +title: Workflows for different game types +slug: Games/Workflows +tags: + - NeedsTranslation + - TopicStub +translation_of: Games/Tutorials +--- +<div>{{GamesSidebar}}</div><p>This page will contain links to different article series covering different workflows for effectively creating different types of web games, whether you want to create a 2D or 3D game from scratch, or port a C++ or Flash game over to open web technologies.</p> +<p>For example, a <a href="/en-US/docs/Games/Workflows/HTML5_Gamedev_Phaser_Device_Orientation">2D maze game with Phaser and the Device Orientation API</a>.</p> |