hugoruscitti/pilas

View on GitHub
data/manual/fisica/index.html

Summary

Maintainability
Test Coverage
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  
  
  <title>Fisica - pilas-engine</title>
  

  <link rel="shortcut icon" href="../img/favicon.ico">

  
  <link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>

  <link rel="stylesheet" href="../css/theme.css" type="text/css" />
  <link rel="stylesheet" href="../css/theme_extra.css" type="text/css" />
  <link rel="stylesheet" href="../css/highlight.css">

  
  <script>
    // Current page data
    var mkdocs_page_name = "Fisica";
    var mkdocs_page_input_path = "fisica.md";
    var mkdocs_page_url = "/fisica/";
  </script>
  
  <script src="../js/jquery-2.1.1.min.js"></script>
  <script src="../js/modernizr-2.8.3.min.js"></script>
  <script type="text/javascript" src="../js/highlight.pack.js"></script>
  <script src="../js/theme.js"></script> 

  
</head>

<body class="wy-body-for-nav" role="document">

  <div class="wy-grid-for-nav">

    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
      <div class="wy-side-nav-search">
        <a href=".." class="icon icon-home"> pilas-engine</a>
        <div role="search">
  <form id ="rtd-search-form" class="wy-form" action="../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" />
  </form>
</div>
      </div>

      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
        <ul class="current">
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="..">Principal</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../que_juegos/">Tipos de juegos</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../instalacion/">Instalación</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../about/">Acerca de ...</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../empezando/">Empezando y los primeros pasos con pilas</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../actores/">Actores</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../actores_personalizados/">Actores personalizados</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../grupos/">Grupos</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../colisiones/">Colisiones</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../etiquetas/">Etiquetas</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 current">
        <a class="current" href="./">Fisica</a>
        
            <ul>
            
                <li class="toctree-l3"><a href="#fisica">Física</a></li>
                
                    <li><a class="toctree-l4" href="#el-motor-box2d">El motor: Box2D</a></li>
                
                    <li><a class="toctree-l4" href="#unos-ejemplos">Unos ejemplos</a></li>
                
                    <li><a class="toctree-l4" href="#modo-depuracion-de-fisica">Modo depuración de física</a></li>
                
                    <li><a class="toctree-l4" href="#fisica-personalizada">Física personalizada</a></li>
                
                    <li><a class="toctree-l4" href="#escala-real-y-tamano-de-figuras">Escala real y tamaño de figuras</a></li>
                
                    <li><a class="toctree-l4" href="#cambiando-la-gravedad-interactivamente">Cambiando la gravedad interactivamente</a></li>
                
            
            </ul>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../controles/">Controles</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../joystick/">Joystick</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../imagen/">Imagen</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../sonidos/">Audio: Sonidos y Música</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../dibujado_simple_en_pantalla/">Dibujado simple en pantalla</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../dibujado_avanzado_con_superficies/">Dibujado avanzado con Superficies</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../tareas/">Manejo de tiempo con tareas</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../interpolacion/">Interpolaciones</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../controlando_la_pantalla/">Controlando la pantalla</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../comportamientos/">Comportamientos</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../escenas/">Escenas</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../interfaz/">Interfaz de usuario</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../menu/">Cómo crear menúes para tu juegos</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../mapas_y_plataformas/">Mapas y plataformas</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../dialogos/">Diálogos</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../camara/">Manejo de Cámara</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../eventos/">Eventos</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../texto/">Textos</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../habilidades/">Habilidades</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../depurando/">Depurando</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../como_funciona_pilas_por_dentro/">¿Cómo funciona pilas por dentro?</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../complementos/">Complementos</a>
        
    </li>
<li>
          
            <li>
    <li class="toctree-l1 ">
        <a class="" href="../desarrolladores/">Guía para desarrolladores</a>
        
    </li>
<li>
          
        </ul>
      </div>
      &nbsp;
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
        <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
        <a href="..">pilas-engine</a>
      </nav>

      
      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="breadcrumbs navigation">
  <ul class="wy-breadcrumbs">
    <li><a href="..">Docs</a> &raquo;</li>
    
      
    
    <li>Fisica</li>
    <li class="wy-breadcrumbs-aside">
      
    </li>
  </ul>
  <hr/>
</div>
          <div role="main">
            <div class="section">
              
                <h1 id="fisica">Física</h1>
<p>Pilas incluye integración con un sistema de física
para realizar simulaciones y dotar a tus juegos
de mas realismo y diversión.</p>
<h2 id="el-motor-box2d">El motor: Box2D</h2>
<p>El motor de física seleccionado para pilas se llama Box2D, el mismo
motor de física utilizado en el juego Angry Birds.</p>
<p>Así, Box2D y PyBox2D son las bibliotecas protagonistas
de casi toda la funcionalidad que vas a ver en este módulo.</p>
<p>El módulo <code>pilas.fisica</code> es solamente un facilitador para utilizar Box2D, y
que puedas comenzar a jugar con físicas rápidamente.</p>
<p>Así que aprovecho este espacio para dar las gracias a <strong>Erin Catto</strong>, y
su grupo de desarrollo por haber creado <strong>Box2D</strong>.</p>
<h2 id="unos-ejemplos">Unos ejemplos</h2>
<p>El motor de física se puede mostrar en funcionamiento
usando un ejemplo, escribe el siguiente código:</p>
<pre><code>pelotas = pilas.actores.Pelota() * 10
</code></pre>

<p>esto creará un grupo de circunferencias que rebotarán
hasta la parte inferior de la pantalla.</p>
<p>De manera similar puedes crear un montón de cajas y
hacerlas rebotar:</p>
<pre><code>cajas = pilas.actores.Caja() * 10
</code></pre>

<p>Como puedes ver, el resultado es un grupo caótico
de actores chocando entre sí. Mas adelante veremos
como personalizar y "controlar" un poco el escenario.</p>
<p><img alt="" src="../imagenes/fisica/fisica.jpg" /></p>
<p>Los actores que tienen física son un poco particulares, pero
aún así se los puede tratar como a otros actores. Por
ejemplo, si quieres poder arrastrar y soltar figuras con
el mouse, puedes enseñarles una habilidad:</p>
<pre><code>pelotas.aprender(&quot;arrastrable&quot;)
cajas.aprender(&quot;arrastrable&quot;)
</code></pre>

<h2 id="modo-depuracion-de-fisica">Modo depuración de física</h2>
<p>Cuando haces juegos con física o movimientos realistas es
muy importante tener en cuenta un concepto importate:</p>
<p>Si bien uno observa pelotas y cajas, en realidad, internamente
son solo cuadrados y circunferencias.</p>
<p>Lo que ocurre en pantalla son dos cosas, por una lado vemos imágenes
con aspecto de caja o pelota, y por el otro se nos oculta una
simulación entre polígonos mucho mas primitiva y simple.</p>
<p>Observa esta escena:</p>
<p><img alt="" src="../imagenes/fisica/fisica_1.jpg" /></p>
<p>Cada uno de esos actores está asociado a una figura
geométrica, la física en realidad se da en un nivel muy
primitivo de figuras. El aspecto de las cosas es
solo eso, un aspecto. Lo que "manda" en el comportamiento
físico son las figuras geométricas (cuerpos).</p>
<p>Intenta lo siguiente, pulsa la tecla <strong>F11</strong> o pulsá el
botón "mostrar figuras físicas" que aparece abajo a la
derecha:</p>
<p><img alt="" src="../imagenes/fisica/fisica_2.jpg" /></p>
<p>Las lineas blancas indican polígonos que el
motor de física puede controlar, las cajas tienen forma
rectangular, los actores Pelota tienen figuras circulares, y
el suelo y las paredes también están en el sistema de física.</p>
<p>Si por algún motivo quieres que los objetos no estén contenidos
en la pantalla, y sean un poco mas libres, podrías eliminar
las paredes:</p>
<pre><code>pilas.fisica.eliminar_paredes()
</code></pre>

<p>o incluso podrías eliminar el suelo:</p>
<pre><code>pilas.fisica.eliminar_suelo()
</code></pre>

<p>Pero recuerda que los objetos que no se ven en la pantalla
de todas maneras estarán ahí. Una buena idea es eliminarlos
ni bien los dejas de usar.</p>
<h2 id="fisica-personalizada">Física personalizada</h2>
<p>Los actores <code>Pelota</code> y <code>Caja</code> están bien para simulaciones
simples y generales. Pero, ¿cómo podemos dotar a nuestros
propios actores de ese comportamiento?.</p>
<p>Los objetos o figuras físicas viven dentro del módulo de física
y son invisibles (al principio), pero luego se pueden vincular
a cualquier actor con facilidad.</p>
<p>Intenta lo siguiente, ingresa en el modo interactivo de pilas
y pulsa la tecla <strong>F11</strong> o pulsá el botón "mostrar figuras físicas" que
aparece abajo a la derecha:</p>
<p><img alt="" src="../imagenes/fisica/fisica_personalizada_1.jpg" /></p>
<p>Ahora creá dos figuras físicas, una circunferencia estática
y otra dinámica:</p>
<pre><code>circulo = pilas.fisica.Circulo(0, 0, 50, dinamica=False)
circulo_dinamico = pilas.fisica.Circulo(10, 200, 50)
</code></pre>

<p>El primer círculo aparecerá en el centro de la ventana, y el
segundo comenzará en la posición <code>(10, 200)</code>, es decir,
en la parte superior de la ventana y luego caerá
rebotando. Algo así:</p>
<p><img alt="" src="../imagenes/fisica/fisica_personalizada_2.jpg" /></p>
<p>Ahora bien, habrás notado que estas dos circunferencias las
podemos ver porque está habilitado el módulo de depuración (que
activamos con <strong>F11</strong>), pero esto no lo va a ver alguien que juegue
a nuestro juego. El modo depuración es solo para desarrolladores.</p>
<p>Lo que nos falta hacer, es darles apariencia a esas figuras. Algo
así como una piel..</p>
<p>Para esto podemos usar actores. La dinámica es así, tenemos que
crear dos actores, y luego decirle a estos actores que se comporten
cómo figuras geométricas.</p>
<p>Agreguemos a nuestro programa estas 4 lineas de código, queremos
que el primer circulo (el del centro) sea un mono, y el otro
círculo que sea una bomba:</p>
<pre><code>mono = pilas.actores.Mono()
mono.aprender(pilas.habilidades.Imitar, circulo)

bomba = pilas.actores.Bomba()
bomba.aprender(pilas.habilidades.Imitar, circulo_dinamico)
</code></pre>

<p>Esto es diferente a lo anterior, los objetos físicos ahora
tienen apariencia:</p>
<p><img alt="" src="../imagenes/fisica/fisica_personalizada_3.jpg" /></p>
<p>Ahora podríamos desactivar el modo depuración física (pulsando
nuevamente <strong>F11</strong>) y jugar un poco impulsando la bomba de un
lado a otro:</p>
<pre><code>circulo_dinamico.y = 200
</code></pre>

<p>Ten en cuenta que ahora la figura del motor físico es la
que determina el movimiento y la rotación, así que ya no
funcionará escribir algo cómo <code>bomba.y = 200</code>, ahora tienes
que escribir <code>circulo_dinamico.y = 200</code> para mover al actor...</p>
<p>Otra cosa a considerar, es que en nuestro ejemplo no ajustamos
muy bien el tamaño del <code>circulo_dinamico</code> con el de la
bomba. Esto es un detalle poco relevante aquí, porque solo
quiero explicar cómo se usa el motor, pero cuando hagas tus
juegos, recuerda usar el modo depuración de física para detectar
estos detalles y corregirlos, son muy importantes para que
tus usuarios disfruten del juego. Recuerda que ellos no
verán los círculos rojos... solo verán la apariencia
de los actores.</p>
<h2 id="escala-real-y-tamano-de-figuras">Escala real y tamaño de figuras</h2>
<p>Pilas utiliza una pantalla que se puede medir en pixels, de hecho, todas
las imágenes tienen un tamaño en pixels predefinido.</p>
<p>Pero dentro del mundo físico de box2d, las figuras no tienen tamaño en pixels
sino en metros.</p>
<p>¿Cual es la relación?, pilas convierte pixels a metros para mantener al mundo
de box2D en coherencia con lo que estamos viendo en pantalla.</p>
<p>30 pixels son equivalentes a 1 metro:</p>
<p><img alt="" src="../imagenes/fisica/escalas.png" /></p>
<h2 id="cambiando-la-gravedad-interactivamente">Cambiando la gravedad interactivamente</h2>
<p>Por defecto, la gravedad del escenario es de (0, -9), esto
significa que los objetos se dirigen hacia abajo, y lo hacen con
una aceleración de 90 mts/s^2 (metros sobre segundos cuadrados).</p>
<p>Pero no estás obligado a que esto sea siempre así, de hecho
si quieres hacer un juego que transcurra en el espacio seguramente
vas a querer eliminar por completo la gravedad del escenario
para que los objetos puedan "flotar", ¿no?.</p>
<p>Entonces, Podrías cambiar la gravedad en cualquier momento cambiando
los atributos <code>gravedad_x</code> o <code>gravedad_y</code> del objeto
<code>fisica</code> así:</p>
<pre><code>pilas.fisica.gravedad_x = 20
pilas.fisica.gravedad_y = 0
</code></pre>

<p>El atributo <code>gravedad_x</code> representará la aceleración horizontal, donde los
valores positivos acelerán los objetos hacia la derecha, y los valores
negativos a la izquierda.</p>
<p>De forma similar funciona el atributo <code>gravedad_y</code>, los valores positivos
aceleran los objetos hacia arriba y los valores negativos hacia abajo.</p>
              
            </div>
          </div>
          <footer>

  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="../controles/" class="btn btn-neutral float-right" title="Controles"/>Siguiente <span class="icon icon-circle-arrow-right"></span></a>
      
      
        <a href="../etiquetas/" class="btn btn-neutral" title="Etiquetas"><span class="icon icon-circle-arrow-left"></span> Anterior</a>
      
    </div>
  

  <hr/>

  <div role="contentinfo">
    <p>
    <!-- Copyright etc -->
    </p>
  </div>

  Creado con <em>MkDocs</em>.


  <script>
  $(document).ready(function() {
     $('img').each(function(elemento) {
        if (this.src.indexOf('github.io') > 0) {
          this.src = this.src.replace('github.io/imagenes', 'github.io/pilas-manual/imagenes');
        }
     });
  });
  </script>

  <script>
  $(document).ready(function() {
    String.prototype.endsWith = function(suffix){
      return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };

    $('a').each(function(){
      var x=this.href;

      if (!this.href.endsWith('html') && this.href.indexOf('#') < 0 && this.href.indexOf('http://') === -1 && this.href.indexOf('https://') === -1) {
        if (this.href.endsWith('/')) {
          this.href = this.href + "index.html";
        } else {
          this.href = this.href + "/index.html";
        }
      }
    });
  });
  </script>


  <script>
    function alternar_menu() {
      var sidebar = document.querySelectorAll(".wy-nav-side")[0];
      var left = sidebar.style.left;

      if (left === "-300px") {
        sidebar.style.left = "0px";
      } else {
        if (left === "0px") {
          sidebar.style.left = "-300px";
        } else {
          sidebar.style.left = "0px";
        }
      }

    }

    $(document).ready(function() {

      document.querySelector('ul.wy-breadcrumbs>li>a').onclick = function() {
        var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);

        if (w < 768) {
          alternar_menu();
          return false;
        } else {
          return true;
        }

      }
    });
  </script>

  <style>
    .rst-versions {
      border: 0 !important;
    }
    .wy-nav-side {
      padding-bottom: 50px;
    }
    .wy-nav-content-wrap {
      background-color: white !important;
    }

    .wy-nav-content {
      background-color: white !important;
    }

    .star {
        display: inline-block !important;
        width: 14px !important;
        height: 14px !important;
        background-image: url('/imagenes/star.png');
        margin-bottom: -2px;
        margin-left: 4px;
    }
  </style>


</footer>


<script type="text/javascript">
  var dentro_de_pilas_engine = (document.location.href.indexOf('file://') === 0);

  // Ocultando la barra de búsqueda
  if (dentro_de_pilas_engine) {
    var b = document.getElementsByName('q');
    b[0].style.display = "none"
  }
</script>


<style media="screen">
  code {
    font-size: 15px !important;
  }
</style>

<style>

img {
  width: auto !important;
}

pre {
  padding: 0px !important;
}

.hljs {
  font-size: 15px;
}

td {
  padding: 15px;
  text-align: center;
}

.wy-menu-vertical li.current {
  background: #0B0B0B;
}

.wy-menu-vertical li.on a, .wy-menu-vertical li.current>a {
  color: #FFFFFF;
  padding: 0.4045em 1.618em;
  font-weight: bold;
  position: relative;
  background: #6C6C6C;
  border: none;
  border-bottom: none;
  border-top: none;
  padding-left: 1.618em -4px;
}

.wy-menu-vertical li.current a {
  color: rgb(186, 186, 186);
}

.wy-menu-vertical li.current a:hover {
  background: #444444;
}
</pre>
      
        </div>
      </div>

    </section>

  </div>

<div class="rst-versions" role="note" style="cursor: pointer">
    <span class="rst-current-version" data-toggle="rst-current-version">
      
      
        <span><a href="../etiquetas/" style="color: #fcfcfc;">&laquo; Previous</a></span>
      
      
        <span style="margin-left: 15px"><a href="../controles/" style="color: #fcfcfc">Next &raquo;</a></span>
      
    </span>
</div>

</body>
</html>