data/manual/habilidades/index.html
<!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>Habilidades - 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 = "Habilidades";
var mkdocs_page_input_path = "habilidades.md";
var mkdocs_page_url = "/habilidades/";
</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 ">
<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 current">
<a class="current" href="./">Habilidades</a>
<ul>
<li class="toctree-l3"><a href="#habilidades">Habilidades</a></li>
<li><a class="toctree-l4" href="#un-ejemplo">Un ejemplo</a></li>
<li><a class="toctree-l4" href="#un-ejemplo-mas-hacer-que-un-actor-se-pueda-mover-con-el-mouse">Un ejemplo más: hacer que un actor se pueda mover con el mouse</a></li>
<li><a class="toctree-l4" href="#una-habilidad-mas-compleja-disparar">Una habilidad más compleja: Disparar</a></li>
<li><a class="toctree-l4" href="#listado-de-habilidades-existentes">Listado de habilidades existentes</a></li>
<li><a class="toctree-l4" href="#crear-habilidades-personalizadas">Crear habilidades personalizadas</a></li>
</ul>
</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>
</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> »</li>
<li>Habilidades</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main">
<div class="section">
<h1 id="habilidades">Habilidades</h1>
<p>Pilas permite añadir funcionalidad a tus objetos
de manera sencilla, dado que usamos el concepto
de habilidades, un enfoque similar a la
programación orientada a <a href="http://es.wikipedia.org/wiki/Programación_orientada_a_componentes">componentes</a>
y <a href="http://es.wikipedia.org/wiki/Mixin">mixins</a>.</p>
<h2 id="un-ejemplo">Un ejemplo</h2>
<p>Una habilidad es una funcionalidad que está implementada
en alguna clase, y que si quieres la puedes vincular
a un actor cualquiera.</p>
<p>Veamos un ejemplo, imagina que tienes un actor en
tu escena y quieres que la rueda del mouse te permita
cambiarle el tamaño.</p>
<p>Puedes usar la habilidad <code>AumentarConRueda</code> y vincularla
al actor fácilmente.</p>
<p>El siguiente código hace eso:</p>
<pre><code class="python">import pilasengine
pilas = pilasengine.iniciar()
mono = pilas.actores.Mono()
mono.aprender(pilas.habilidades.AumentarConRueda)
</code></pre>
<p>o bien:</p>
<pre><code>mono.aprender('AumentarConRueda')
</code></pre>
<p>así, cuando uses la rueda del mouse el tamaño del personaje aumentará
o disminuirá.</p>
<p>Nota que aquí usamos la metáfora de "aprender habilidades", porque
las habilidades son algo que duran para toda la vida
del actor.</p>
<h2 id="un-ejemplo-mas-hacer-que-un-actor-se-pueda-mover-con-el-mouse">Un ejemplo más: hacer que un actor se pueda mover con el mouse</h2>
<p>Algo muy común en los juegos es que puedas
tomar piezas con el mouse y moverlas por la pantalla.</p>
<p>Esta habilidad llamada <code>Arrastrable</code> representa eso, puedes vincularlo
a cualquier actor y simplemente funciona:</p>
<pre><code class="python">import pilasengine
pilas = pilasengine.iniciar()
mono = pilas.actores.Mono()
mono.aprender("arrastrable")
</code></pre>
<h2 id="una-habilidad-mas-compleja-disparar">Una habilidad más compleja: Disparar</h2>
<p>Una habilidad que tiene más complejidad que las anteriores
es disparar, una habilidad que te permite hacer que un
personaje pueda crear "disparos" sean de la clase que sea.</p>
<p>Por ejemplo, lo mas sencillo es indicarle a un actor
que puede disparar, usando una munición por omisión:</p>
<pre><code class="python">import pilasengine
pilas = pilasengine.iniciar()
mono = pilas.actores.Mono()
mono.aprender("moverseComoCoche")
mono.aprender("disparar")
</code></pre>
<p>Y como resultado vamos a conseguir que nuestro
actor se pueda mover con el teclado y disparar con la tecla
espacio.</p>
<p>Y si queremos cambiar la munición de la habilidad
disparar, podemos especificarlo con el parámetro <code>municion</code>:</p>
<pre><code class="python">mono.aprender("disparar", municion="aceituna")
</code></pre>
<p>Esta habilidad también es útil para hacer un enemigo que dispare
automáticamente cada determinado tiempo, por ejemplo 1 segundo:</p>
<pre><code class="python">mono = pilas.actores.Mono()
mono.aprender("Disparar", control=None)
def dispara():
mono.disparar()
return True
pilas.tareas.agregar(1, dispara)
</code></pre>
<h2 id="listado-de-habilidades-existentes">Listado de habilidades existentes</h2>
<table>
<thead>
<tr>
<th><strong>Habilidad</strong></th>
<th><strong>Parámetros</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>Arrastrable</td>
<td></td>
</tr>
<tr>
<td>AumentarConRueda</td>
<td></td>
</tr>
<tr>
<td>Disparar</td>
<td>municion, grupo_enemigos, cuando_elimina_enemigo, frecuencia_de_disparo, angulo_salida_disparo ...</td>
</tr>
<tr>
<td>EliminarseSiSaleDePantalla</td>
<td></td>
</tr>
<tr>
<td>Imitar</td>
<td>objeto_a_imitar, con_escala, con_rotacion</td>
</tr>
<tr>
<td>LimitadoABordesDePantalla</td>
<td></td>
</tr>
<tr>
<td>MirarAlActor</td>
<td>actor_a_seguir, lado_seguimiento="ARRIBA"</td>
</tr>
<tr>
<td>MoverseComoCoche</td>
<td>control, velocidad_maxima, aceleracion, deceleracion, rozamiento, velocidad_rotacion</td>
</tr>
<tr>
<td>MoverseConElTeclado</td>
<td>control, direcciones, velocidad_maxima, aceleracion, con_rotacion, velocidad_rotacion, marcha_atras</td>
</tr>
<tr>
<td>PuedeExplotar</td>
<td></td>
</tr>
<tr>
<td>PuedeExplotarConHumo</td>
<td></td>
</tr>
<tr>
<td>RebotarComoCaja</td>
<td></td>
</tr>
<tr>
<td>RebotarComoPelota</td>
<td></td>
</tr>
<tr>
<td>RotarConMouse</td>
<td></td>
</tr>
<tr>
<td>SeMantieneEnPantalla</td>
<td>permitir_salida</td>
</tr>
<tr>
<td>SeguirAlMouse</td>
<td></td>
</tr>
<tr>
<td>SeguirClicks</td>
<td></td>
</tr>
<tr>
<td>SiempreEnElCentro</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="crear-habilidades-personalizadas">Crear habilidades personalizadas</h2>
<p>Para crear una habilidad nueva, tienes que crear una clase
y vincularla al módulo de habilidades.</p>
<p>La clase tiene que heredar de <code>pilasengine.habilidades.Habilidad</code> y
puede tener un método <code>actualizar</code>, en donde generalmente se
coloca la acción a realizar:</p>
<pre><code class="python">class GirarPorSiempre(pilasengine.habilidades.Habilidad):
def actualizar(self):
self.receptor.rotacion += 1
pilas.habilidades.vincular(GirarPorSiempre)
actor = pilas.actores.Actor()
actor.aprender('GirarPorSiempre')
</code></pre>
<p>El método <code>actualizar</code> de la habilidad se ejecutará 60 veces por segundo, y
en este caso harán que cualquier actor que aprenda la habilidad <code>GirarPorSiempre</code>
de vueltas constantemente.</p>
<p>Notá que dentro de los métodos de la habilidad, la variable <code>self.receptor</code> apunta
al actor que conoce a esa habilidad.</p>
<p>Por último, en este ejemplo, vinculamos la nueva habilidad al módulo de
habilidades usando el método <code>pilas.habilidades.vincular</code>.</p>
<h3 id="argumentos-iniciales-para-las-habilidades">Argumentos iniciales para las habilidades</h3>
<p>Hay casos en donde queremos que las habilidades pueda recibir argumentos
iniciales, para esos casos necesitamos crear el método <code>iniciar</code> y configurarlo
correctamente.</p>
<p>Siguiendo con nuestro ejemplo, imaginá que ahora queremos que esta habilidad
nos permita hacer girar a los actores pero a diferentes velocidades: en algunos
casos queremos enseñar a una actor a girar rápido y a otro mas lento. ¿Cómo
sería en pilas?.</p>
<p>Lo primero es crear la clase, muy parecida a la anterior, solamente que
ahora creamos el método iniciar con dos argumentos, el primer es <code>receptor</code>, que
es obligatorio y el segundo es nuestro argumento de velocidad:</p>
<pre><code class="python">class GirarPorSiemprePersonalizado(pilasengine.habilidades.Habilidad):
def iniciar(self, receptor, velocidad):
self.receptor = receptor
self.velocidad = velocidad
def actualizar(self):
self.receptor.rotacion += self.velocidad
pilas.habilidades.vincular(GirarPorSiemprePersonalizado)
</code></pre>
<p>Ahora, la nueva habilidad necesita que le especifiquemos la velocidad
al iniciar, así que tenemos que usar algo así:</p>
<pre><code class="python">actor_lento = pilas.actores.Actor()
actor_lento.aprender('GirarPorSiemprePersonalizado', 1)
actor_rapido = pilas.actores.Actor(y=100)
actor_rapido.aprender('GirarPorSiemprePersonalizado', 5)
</code></pre>
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="../depurando/" class="btn btn-neutral float-right" title="Depurando"/>Siguiente <span class="icon icon-circle-arrow-right"></span></a>
<a href="../texto/" class="btn btn-neutral" title="Textos"><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="../texto/" style="color: #fcfcfc;">« Previous</a></span>
<span style="margin-left: 15px"><a href="../depurando/" style="color: #fcfcfc">Next »</a></span>
</span>
</div>
</body>
</html>