hugoruscitti/pilas

View on GitHub
data/manual/actores_personalizados/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>Actores personalizados - 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 = "Actores personalizados";
    var mkdocs_page_input_path = "actores_personalizados.md";
    var mkdocs_page_url = "/actores_personalizados/";
  </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 current">
        <a class="current" href="./">Actores personalizados</a>
        
            <ul>
            
                <li class="toctree-l3"><a href="#actores-personalizados">Actores personalizados</a></li>
                
                    <li><a class="toctree-l4" href="#creando-una-clase">Creando una clase</a></li>
                
                    <li><a class="toctree-l4" href="#mostrando-el-actor-en-la-pantalla">Mostrando el actor en la pantalla</a></li>
                
                    <li><a class="toctree-l4" href="#comportamiento-heredado">Comportamiento heredado</a></li>
                
                    <li><a class="toctree-l4" href="#creando-metodos-nuevos">Creando métodos nuevos</a></li>
                
                    <li><a class="toctree-l4" href="#el-metodo-especial-actualizar">El método especial "actualizar"</a></li>
                
                    <li><a class="toctree-l4" href="#leyendo-el-codigo-de-otros-actores">Leyendo el código de otros actores</a></li>
                
                    <li><a class="toctree-l4" href="#parametros-iniciales-para-los-actores">Parametros iniciales para los actores</a></li>
                
                    <li><a class="toctree-l4" href="#detectando-errores-y-problemas-al-inicializar">Detectando errores y problemas al inicializar</a></li>
                
            
            </ul>
        
    </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 ">
        <a class="" href="../fisica/">Fisica</a>
        
    </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>Actores personalizados</li>
    <li class="wy-breadcrumbs-aside">
      
    </li>
  </ul>
  <hr/>
</div>
          <div role="main">
            <div class="section">
              
                <h1 id="actores-personalizados">Actores personalizados</h1>
<p>Cuando tu juego crece, comienza la necesidad de crear
tus propios actores, darles personalidad y lograr
funcionalidad personalizada.</p>
<p>Esta página describe como crear tus propios actores
usando imágenes y algunos comportamientos propios.</p>
<h2 id="creando-una-clase">Creando una clase</h2>
<p>El primer paso para crear un actor personalizado
es construir una clase para agrupar toda la funcionalidad
esperada.</p>
<p>Comencemos con una imagen sencilla para el
actor, este archivo se llama <code>alien.png</code> y está
en el directorio de nuestro código:</p>
<p><img alt="imagen alien.png" src="../imagenes/actores_personalizados/alien.png" /></p>
<p>Luego, es momento de crear el código de la clase para
agrupar todo lo relacionado a este nuevo actor. Por
ejemplo con un código así:</p>
<pre><code>import pilasengine

class Alien(pilasengine.actores.Actor):

    def iniciar(self):
        self.imagen = &quot;alien.png&quot;
</code></pre>

<h2 id="mostrando-el-actor-en-la-pantalla">Mostrando el actor en la pantalla</h2>
<p>Meditante la clase solamente hemos creado la "definición"
del actor, pero no lo hemos incorporado en el juego
aún.</p>
<p>El siguiente paso es incorporarlo al juego usando
la sentencia:</p>
<pre><code>alien = Alien(pilas)
</code></pre>

<p>Ahora con el código completo, tendrías que ver al personaje
en el centro de la pantalla:</p>
<p><img alt="imagen alien.png" src="../imagenes/actores_personalizados/completo.png" /></p>
<h2 id="comportamiento-heredado">Comportamiento heredado</h2>
<p>Algo interesante de los nuevos actores es que incorporan
por herencia lo que saben hacer casi todos los actores
de <code>pilas</code>, ya que le hemos indicado que heredará
de clase actor con la linea <code>class Alien(pilasengine.actores.Actor):</code>.</p>
<p>Por ejemplo, podrías escribir algo como:</p>
<pre><code>alien.decir(u"¡oh, no, humanos!")
</code></pre>
<p><img alt="" src="../imagenes/actores_personalizados/decir.png" /></p>
<h2 id="creando-metodos-nuevos">Creando métodos nuevos</h2>
<p>Ten en cuenta que ahora con nuestra nueva
clase podemos crear funcionalidad nueva y específica
para este actor alien.</p>
<p>Solo tenemos que tener precaución de dirigirnos al
actor como <code>self</code> dentro de los métodos. Por ejemplo,
si quiero crear un método para saludar puedo escribir:</p>
<pre><code>import pilasengine

class Alien(pilasengine.actores.Actor):

    def iniciar(self):
        self.imagen = &quot;alien.png&quot;

    def saludar(self):
        self.decir(&quot;Hola mundo!!!, soy el nuevo actor alien&quot;)

    def dar_vuelta(self):
        self.rotacion = [360]
</code></pre>

<p>Y ahora tenemos dos métodos nuevos para invocar:</p>
<pre><code>alien.saludar()
</code></pre>
<p><img alt="" src="../imagenes/actores_personalizados/saludar.png" /></p>
<p>y otro un poquito mas complejo:</p>
<pre><code>alien.dar_vuelta()
</code></pre>
<p><img alt="" src="../imagenes/actores_personalizados/dar_vuelta.gif" /></p>
<h2 id="el-metodo-especial-actualizar">El método especial "actualizar"</h2>
<p>Una de las cosas mas importantes de la clase actor
es que incorpora un método especial llamado <code>actualizar</code>. Este método se llamará automáticamente
60 veces por segundo.</p>
<p>Por ejemplo, imagina que buscamos hacer que el
actor se mueva para los costados usando las flechas
del teclado, podemos usar esté método, simplemente
así:</p>
<pre><code>class Alien(pilasengine.actores.Actor):

    def iniciar(self):
        self.imagen = &quot;alien.png&quot;

    def saludar(self):
        self.decir(&quot;Hola mundo!!!, soy el nuevo actor alien&quot;)

    def dar_vuelta(self):
        self.rotacion = [360]

    def actualizar(self):
        if self.pilas.control.izquierda:
            self.x -= 5
            self.espejado = True
        if self.pilas.control.derecha:
            self.x += 5
            self.espejado = False
</code></pre>

<p>Es decir, como el método actualizar se llama casi
todo el tiempo, podemos usarlo para consultar
el estado del teclado y hacer algo.</p>
<p>En este caso, si se pulsa hacia la izquierda movemos
el actor un poquito a la izquierda (con <code>self.x -= 5</code>)
y además invertimos el gráfico del actor para que mire a la
izquierda (con <code>self.espejado = True</code>). Y claro, hacemos lo
opuesto para el lado
derecho.</p>
<p>Así se ve mientras voy pulsando las teclas <code>izquierda</code>
y <code>derecha</code>:</p>
<p><img alt="" src="../imagenes/actores_personalizados/caminando.gif" /></p>
<p>También existe otro método llamado <code>luego_de_actualizar</code>, que se llamará
justo después de aplicarle física al actor. A grandes rasgos es muy similar
al método <code>actualizar</code>, ya que se llamará 60 veces por segundo y recibe los
mismos argumentos.</p>
<h2 id="leyendo-el-codigo-de-otros-actores">Leyendo el código de otros actores</h2>
<p>Pilas viene con una función especial llamada
<code>pilas.ver</code>, que te permite ver el código de
cualquier objeto y conocer su funcionamiento.</p>
<p>Esta función es super útil para conocer el código
de otras clases actor, e incluso aprender algunas
ideas interesantes.</p>
<p>Estos son algunos ejemplos de invocación, cada
una de estas sentencias te mostrará el código
de la clase completa:</p>
<pre><code class="python">pilas.ver(pilasengine.actores.Mono)
pilas.ver(pilasengine.actores.Aceituna)
pilas.ver(pilasengine.actores.Pacman)
pilas.ver(mono)
</code></pre>

<h2 id="parametros-iniciales-para-los-actores">Parametros iniciales para los actores</h2>
<p>Existen varios casos en donde queremos crear actores
pero especificando algunos parametros iniciales, como
la posición, energia o cualquier otro valor
externo a la clase.</p>
<p>Para estos parámetros podemos crear argumentos personalizados
en la clase nueva, por ejemplo, si quieres crear al actor
<code>Alien</code> (que tomamos de ejemplo aquí) pero quieres especificarle
energia, podrías escribir:</p>
<pre><code>alien = Alien(pilas, energia=100, nombre=&quot;pepe alien&quot;, con_sombra=True)
</code></pre>

<p>Y atender esos argumentos desde el método iniciar:</p>
<pre><code class="python">class Alien(pilasengine.actores.Actor):

    def iniciar(self, energia, nombre, con_sombra):
        self.imagen = &quot;alien.png&quot;

        self.nombre = nombre
        self.energia = energia

        if con_sombra:
            self.sombra = pilas.actores.Sombra()
            self.sombra.escala = 0.6
            self.sombra.y = -45
        else:
            self.sombra = None

        self.decir(&quot;Hola, me llamo &quot; + nombre)

    def actualizar(self):
        # Si el actor tiene sombra, hacemos que siga al
        # actor.
        if self.sombra:
            self.sombra.x = self.x
            self.sombra.y = self.y -45
</code></pre>

<p>Y el resultado debería quedarte así:</p>
<p><img alt="" src="../imagenes/actores_personalizados/personalizado.png" /></p>
<h2 id="detectando-errores-y-problemas-al-inicializar">Detectando errores y problemas al inicializar</h2>
<p>Es muy importante que al momento de crear actores a partir
de clases especifiques los argumentos a utilizar. Hemos incluído
algo de código especial en <strong>pilas</strong> para detectar errores comunes, como
argumentos faltantes o incorrectos.</p>
<p>Pero aún así, ten en cuenta que todo argumento que le envíes
a un actor al crearlo tiene que estar declarado como argumento
en el método <code>iniciar</code>.</p>
<p>Por ejemplo, un mensaje de error habitual que mostrará pilas si olvidamos
el nombre de los argumentos podría ser:</p>
<pre><code>× TypeError: No se puede llamar al metodo 'iniciar' de la clase 'Alien'.
×    Faltan 3 argumentos: energia, nombre, con_sombra.
×    El método 'iniciar' espera estos 3 argumentos: ['energia', 'nombre', 'con_sombra']
</code></pre>

<p>Esto significa que hemos querido crear un actor a partir de una clase
que espera 3 argumentos, pero solo hemos llamado incorrectamente.</p>
<p>Regresando a nuestro ejemplo anterior, esto produciría un error:</p>
<pre><code>alien = Alien(pilas)
</code></pre>

<p>mientras que este otro ejemplo sí funcionará, porque el método
<code>iniciar</code> de la clase <code>Alien</code> espera los argumentos <code>energia</code>, <code>nombre</code> y
<code>con_sombra</code>:</p>
<pre><code class="python">alien = Alien(pilas, energia=100, nombre=&quot;pepe alien&quot;, con_sombra=True))
</code></pre>
              
            </div>
          </div>
          <footer>

  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="../grupos/" class="btn btn-neutral float-right" title="Grupos"/>Siguiente <span class="icon icon-circle-arrow-right"></span></a>
      
      
        <a href="../actores/" class="btn btn-neutral" title="Actores"><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="../actores/" style="color: #fcfcfc;">&laquo; Previous</a></span>
      
      
        <span style="margin-left: 15px"><a href="../grupos/" style="color: #fcfcfc">Next &raquo;</a></span>
      
    </span>
</div>

</body>
</html>