<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2038738643649632209</id><updated>2012-01-27T22:01:25.111+01:00</updated><category term='Haskell'/><category term='ActionScript 3'/><category term='Juego Pong - Guía ActionScript 3'/><category term='XML'/><category term='Flash'/><category term='programación'/><category term='JavaScript'/><category term='Android'/><category term='Trucos'/><category term='Nivel bajo'/><category term='Winamp'/><title type='text'>MI</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>25</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-1261889058095154932</id><published>2010-11-20T21:17:00.002+01:00</published><updated>2010-11-20T21:20:36.449+01:00</updated><title type='text'>Me mudo</title><content type='html'>Llevaba tiempo queriendo abandonar blogger y mudarme a una opción más versátil. La solución ha sido Wordpress combinado con un nuevo dominio: &lt;a href="http://www.metafisicainformatica.com"&gt;www.metafisicainformatica.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;He mudado allí todo el contenido de este blog, y puesto que ahora todo es más sencillo de organizar y la potencia ofrecida será mayor, intentaré publicar semanalmente.&lt;br /&gt;&lt;br /&gt;Gracias a blogger por los servicios prestados. A partir de ahora nos leemos &lt;a href="http://www.metafisicainformatica.com/"&gt;aquí&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-1261889058095154932?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/1261889058095154932/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2010/11/me-mudo.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/1261889058095154932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/1261889058095154932'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2010/11/me-mudo.html' title='Me mudo'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-2270364272947303150</id><published>2010-04-21T14:32:00.003+02:00</published><updated>2010-04-21T14:42:16.343+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android y El Androide Libre</title><content type='html'>Llevo tiempo cacharreando con Android, el SO para móviles de Google. Y este verano tengo pensado meterme de lleno con ello y, por supuesto, traer aquí un&lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html"&gt; tutorial al estilo del que creé sobre ActionScript 3.0&lt;/a&gt;, pero que verse sobre un juego desarrollado en Android, aunque aún no tengo decidido el tipo (un &lt;span style="font-weight: bold;"&gt;Pong&lt;/span&gt; seguro que no).&lt;br /&gt;&lt;br /&gt;Mientras llega el verano y el bendito tiempo libre, aprovecho huecos para ir investigando cosas sobre Android, y una de las mayores fuentes de información sobre ello en español es &lt;a href="http://www.elandroidelibre.com"&gt;El Androide Libre - &lt;strong&gt;http://www.elandroidelibre.com&lt;/strong&gt;&lt;/a&gt;, que además ha organizado un concurso en el que, para participar, hay que escribir un post mencionándolos.&lt;br /&gt;&lt;br /&gt;Pues eso.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-2270364272947303150?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/2270364272947303150/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2010/04/android-y-el-androide-libre.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/2270364272947303150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/2270364272947303150'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2010/04/android-y-el-androide-libre.html' title='Android y El Androide Libre'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-836888047414596134</id><published>2009-11-21T13:35:00.004+01:00</published><updated>2009-11-25T09:44:10.998+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>HTC Sync no sincroniza con HTC con Android</title><content type='html'>&lt;p&gt;Uno de los problemas comunes que suelen surgir cuándo se instala el HTC Sync desde un dispotivio HTC es que &lt;strong&gt;no es posible encontrar el driver necesario para la sincronización&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Este problema deriva de la configuración en español de Windows, ya que el driver es buscado en la carpeta &lt;strong&gt;C:\Programfiles\HTC\HTC Driver\Driver Files\XP_x86&lt;/strong&gt;, cuándo, en verdad y debido al idioma, está en &lt;strong&gt;C:\Archivos de programa\HTC\HTC Driver\Driver Files\XP_x86&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;La solución es bien sencilla:&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Click derecho sobre &lt;strong&gt;Mi PC&lt;/strong&gt; -&gt; &lt;strong&gt;Administrar&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Pulsamos en &lt;strong&gt;Administrador de dispositivos&lt;/strong&gt; y buscamos &lt;strong&gt;ABD&lt;/strong&gt;, que es el dispositivo que falla.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Click derecho sobre él, e instalar controlador.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Elegís buscar el controlador manualmente, y seleccionáis la carpeta en la que se encuentra: &lt;strong&gt;C:\Archivos de programa\HTC\HTC Driver\Driver Files\XP_x86&lt;/strong&gt;  &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Pulsáis finalizar, y todo debería funcionar perfectamente&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-836888047414596134?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/836888047414596134/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/11/htc-sync-no-sincroniza-con-htc-con.html#comment-form' title='9 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/836888047414596134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/836888047414596134'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/11/htc-sync-no-sincroniza-con-htc-con.html' title='HTC Sync no sincroniza con HTC con Android'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-5013041092451669279</id><published>2009-10-07T13:23:00.004+02:00</published><updated>2009-10-07T13:32:56.121+02:00</updated><title type='text'>La ciencia en España no necesita tijeras</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lVd850Hzqko/Ssx3Q0WSukI/AAAAAAAAAT8/d_EYrFMUFmQ/s1600-h/3973473121_e76fde787c_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 400px;" src="http://4.bp.blogspot.com/_lVd850Hzqko/Ssx3Q0WSukI/AAAAAAAAAT8/d_EYrFMUFmQ/s400/3973473121_e76fde787c_o.jpg" alt="" id="BLOGGER_PHOTO_ID_5389813984869399106" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family:arial;"&gt;Me uno, (aquí y en &lt;a href="http://metafisicadecostumbres.blogspot.com/"&gt;Metafísica de Costumbres&lt;/a&gt;) hoy miércoles, 7 de octubre, a la iniciativa de &lt;a href="http://aldea-irreductible.blogspot.com/2009/10/la-ciencia-en-espana-no-necesita.html"&gt;La Aldea Irreductible&lt;/a&gt; ante la intención de este Nuestro Gobierno &lt;a href="http://www.elpais.com/articulo/sociedad/ciencia/victima/presupuesto/elpepusoc/20091004elpepisoc_3/Tes"&gt;de reducir en un 15% los fondos para investigación&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Es decir, frenar un poquito más el avance en materia científica en este país. No sé cuál es el plan (ni si existe), no ya a corto, sino a largo plazo, para que España salga de este agujero, pero recortar en investigación y desarrollo (en conocimiento, al fin y al cabo) no parece el mejor camino.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-5013041092451669279?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/5013041092451669279/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/10/la-ciencia-en-espana-no-necesita.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/5013041092451669279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/5013041092451669279'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/10/la-ciencia-en-espana-no-necesita.html' title='La ciencia en España no necesita tijeras'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lVd850Hzqko/Ssx3Q0WSukI/AAAAAAAAAT8/d_EYrFMUFmQ/s72-c/3973473121_e76fde787c_o.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-1865037323789936813</id><published>2009-09-20T17:09:00.004+02:00</published><updated>2009-09-20T17:33:13.446+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>Conclusión y archivos fuente Pong 1.1</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;La idea es que esta guía no acabe aquí, pero obligaciones de diferente índole me impiden dedicarle más tiempo, al menos de momento. De todos modos, si has logrado llegar hasta quí paso a paso, habrás aprendido lo suficiente como para seguir explorando Flash, ActionScript 3 y todas sus posibilidades.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Aquí están &lt;a href="http://www.mediafire.com/download.php?n5oz1meegag"&gt;los archivos fuente del Pong 1.1&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Cualquier comentario, error o sugerencia será bien recibido. &lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/09/un-campo-de-futbol.html"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-1865037323789936813?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/1865037323789936813/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/09/conclusion-y-archivos-fuente-pong-11.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/1865037323789936813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/1865037323789936813'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/09/conclusion-y-archivos-fuente-pong-11.html' title='Conclusión y archivos fuente Pong 1.1'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-773648738258537682</id><published>2009-09-20T16:48:00.003+02:00</published><updated>2009-09-20T17:13:25.191+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>Un campo de fútbol</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para concluir con este capítulo, vamos a crear un escenario algo más elaborado: un campo de fútbol.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;La clase CampoFutbol&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Dentro de la carpeta &lt;strong&gt;escenario&lt;/strong&gt; vamos a crear una nueva clase que llamaremos &lt;strong&gt;CampoFutbol&lt;/strong&gt; cuyo código será:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package mi.pong.escenario &lt;br /&gt;{&lt;br /&gt; import com.senocular.utils.KeyObject;&lt;br /&gt; import flash.display.GradientType;&lt;br /&gt; import flash.display.Sprite;&lt;br /&gt; import flash.display.Stage;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public class CampoFutbol extends Escenario&lt;br /&gt; {&lt;br /&gt;  private var verdeG1_1:uint = 0x01B101;&lt;br /&gt;  private var verdeG1_2:uint = 0x02D202; &lt;br /&gt;  private var verdeG2_1:uint = 0x25FC25;&lt;br /&gt;  private var verdeG2_2:uint = 0x00FB00;&lt;br /&gt;  &lt;br /&gt;  public function CampoFutbol(stage:Stage, keyObject:KeyObject) &lt;br /&gt;  {&lt;br /&gt;   super(stage, keyObject);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public override function creaEscenario()&lt;br /&gt;  {&lt;br /&gt;   var nZonas:uint = 8;&lt;br /&gt;   var anchoZona:Number = stageRef.stageWidth / nZonas;&lt;br /&gt;   &lt;br /&gt;   for (var i:uint = 0; i &lt; nZonas; i++) {&lt;br /&gt;    var zona:Sprite = creaZona(i, anchoZona);&lt;br /&gt;    zona.y = 0;&lt;br /&gt;    zona.x = (stageRef.stageWidth / nZonas) * i;&lt;br /&gt;    addChild(zona);&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   dibujaLineas();&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  private function creaZona(i:uint, anchoZona:Number):Sprite &lt;br /&gt;  {&lt;br /&gt;   var zona:Sprite  = new Sprite();&lt;br /&gt;   if ( i % 2 != 0)&lt;br /&gt;    zona.graphics.beginGradientFill(GradientType.LINEAR, [verdeG1_1, verdeG1_2], [1, 1], [0, 255]);&lt;br /&gt;   else&lt;br /&gt;    zona.graphics.beginGradientFill(GradientType.LINEAR, [verdeG2_1, verdeG2_2], [1, 1], [0, 255]);&lt;br /&gt;    &lt;br /&gt;   zona.graphics.drawRect(0, 0, stageRef.stageWidth / 8, stageRef.stageHeight);&lt;br /&gt;   zona.graphics.endFill();&lt;br /&gt;   return zona;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  private function dibujaLineas():void &lt;br /&gt;  {&lt;br /&gt;   var margen:Number = 15;&lt;br /&gt;   var anchoLinea:Number = 5;&lt;br /&gt;   var linea:Sprite = new Sprite();&lt;br /&gt;   linea.graphics.beginFill(0xFFFFFF);&lt;br /&gt;   // Línea del centro&lt;br /&gt;   linea.graphics.drawRect(stageRef.stageWidth / 2 - anchoLinea / 2, margen, anchoLinea, stageRef.stageHeight - 2 * margen);&lt;br /&gt;   // Líneas de fondo&lt;br /&gt;    // Izquierda&lt;br /&gt;   linea.graphics.drawRect(margen, margen, anchoLinea, stageRef.stageHeight - 2 * margen);&lt;br /&gt;    // Derecha&lt;br /&gt;   linea.graphics.drawRect(stageRef.stageWidth - margen - anchoLinea, margen, anchoLinea, stageRef.stageHeight - 2 * margen);&lt;br /&gt;   // Líneas de banda&lt;br /&gt;    // Superior&lt;br /&gt;   linea.graphics.drawRect(margen, margen - anchoLinea, stageRef.stageWidth - margen * 2, anchoLinea);&lt;br /&gt;    // Inferior&lt;br /&gt;   linea.graphics.drawRect(margen, stageRef.stageHeight - margen, stageRef.stageWidth - margen * 2, anchoLinea);&lt;br /&gt;   linea.graphics.endFill();&lt;br /&gt;   addChild(linea);&lt;br /&gt;   &lt;br /&gt;   // Círculo central&lt;br /&gt;   var centro:Sprite = new Sprite();&lt;br /&gt;   var radioCentro:Number = stageRef.stageHeight / 3;&lt;br /&gt;   centro.graphics.beginFill(0xFFFFFF);&lt;br /&gt;   centro.graphics.drawEllipse(stageRef.stageWidth / 2 - radioCentro / 2, stageRef.stageHeight / 2 - radioCentro / 2, radioCentro, radioCentro);&lt;br /&gt;   centro.graphics.drawEllipse(stageRef.stageWidth / 2 - radioCentro / 2 + anchoLinea, stageRef.stageHeight / 2 - radioCentro / 2 + anchoLinea, radioCentro - anchoLinea*2, radioCentro - anchoLinea*2);&lt;br /&gt;   centro.graphics.endFill();&lt;br /&gt;   addChild(centro);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Dos cosas importantes en este código:&lt;/p&gt;&lt;br /&gt;&lt;p&gt; - La clase &lt;strong&gt;CampoFutbol&lt;/strong&gt; es heredera de la clase &lt;strong&gt;Escenario&lt;/strong&gt;, con lo cual, hereda todas sus funciones. Sin embargo, nosotros queremos redefinir una de las funciones: &lt;em&gt;creaEscenario&lt;/em&gt;, porque queremos que la creación de este escenario sea distinta a la del padre. Para realizar este cometido utilizamos la palabra clave &lt;strong&gt;override&lt;/strong&gt;, que "sobreescribe" al método del padre. Es decir, será este método el que se utiliza y no el heredado.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- Todas las funciones utilizadas en el atributo &lt;em&gt;graphics&lt;/em&gt; corresponden a métodos de dibujado que proporciona Flash. Podéis encontrar más información &lt;a href="http://help.adobe.com/es_ES/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7dd9.html"&gt;aquí&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ahora, para verlo en acción, ve a la clase Main y cambia la clase al escenario:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;var escenario:Escenario = new CampoFutbol(stage, key);&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Puedes encontrar los archivos de este proyecto terminado en el siguiente capítulo.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/09/anadiendo-los-marcadores.html"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/09/conclusion-y-archivos-fuente-pong-11.html"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-773648738258537682?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/773648738258537682/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/09/un-campo-de-futbol.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/773648738258537682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/773648738258537682'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/09/un-campo-de-futbol.html' title='Un campo de fútbol'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-7152920384100029907</id><published>2009-09-03T18:12:00.002+02:00</published><updated>2009-09-20T17:06:35.146+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>Añadiendo los Marcadores</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Nuestro marcador Flash&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Para la creación de nuestro marcador, vamos a utilizar únicamente un &lt;strong&gt;texto dinámico&lt;/strong&gt; de Flash, que variará según varíe el número de goles de cada jugador.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Así que, creamos un nuevo símbolo en Flash: menú &lt;strong&gt;Insertar -&gt; Nuevo símbolo...&lt;/strong&gt; De nombre &lt;strong&gt;Marcador&lt;/strong&gt; y de tipo &lt;strong&gt;Clip de película&lt;/strong&gt;. De momento, como aún no la hemos creado, no asociamos el símbolo con ninguna clase ActionScript.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ahora, escogemos la &lt;strong&gt;Herramienta de Texto (T)&lt;/strong&gt;, clickamos en el centro de nuestro símbolo recién creado y escribimos un 0.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En la ventana propiedades, hemos de asegurarnos de que es un &lt;strong&gt;Texto dinámico&lt;/strong&gt; (lo cual nos permitirá variarlo mientras se esté ejecutando Flash. Como nombre de instancia (que nos servirá para acceder al texto desde código ActionScript) escribimos &lt;strong&gt;puntuacion_text&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Puedes escoger el formato que quieras para el texto. Yo he elegido como &lt;strong&gt;Familia&lt;/strong&gt;: &lt;em&gt;Tahoma&lt;/em&gt;; &lt;strong&gt;Estilo&lt;/strong&gt;: &lt;em&gt;Regular&lt;/em&gt;; &lt;strong&gt;Tamaño&lt;/strong&gt;: &lt;em&gt;30.0 pt&lt;/em&gt; y &lt;strong&gt;Color&lt;/strong&gt;: &lt;em&gt;Blanco&lt;/em&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Y ya tenemos nuestro marcador.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Código del marcador&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;En FlashDevelop, creamos una clase llamada &lt;strong&gt;Marcador&lt;/strong&gt; dentro de la carpeta &lt;strong&gt;objeto&lt;/strong&gt;, pero fuera de &lt;strong&gt;colisionable&lt;/strong&gt; y &lt;strong&gt;colsionador&lt;/strong&gt;. El código ActionScript para &lt;strong&gt;Marcador&lt;/strong&gt; será el siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package mi.pong.objeto&lt;br /&gt;{&lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; import flash.display.Stage;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public class Marcador extends MovieClip&lt;br /&gt; {&lt;br /&gt;  protected var id:uint; // Identificador para el marcador, normalmente el número de jugador&lt;br /&gt;  protected var puntuacion:int = 0;&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * Constructor del Marcador.&lt;br /&gt;   * @param stage Stage de referencia.&lt;br /&gt;   * @param id_jugador Jugador al que representa.&lt;br /&gt;   */&lt;br /&gt;  public function Marcador(stage:Stage, id_jugador:uint) &lt;br /&gt;  {&lt;br /&gt;   id = id_jugador;&lt;br /&gt;   iniciaPosicion(stage);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * Establece una nueva puntuación en el marcador.&lt;br /&gt;   * @param nueva_puntuacion Nueva puntuación.&lt;br /&gt;   */&lt;br /&gt;  public function setPuntuacion(nueva_puntuacion:int)&lt;br /&gt;  {&lt;br /&gt;   puntuacion = nueva_puntuacion;&lt;br /&gt;   puntuacion_text.text = puntuacion.toString();&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * Suma la puntuación a la ya acumulada.&lt;br /&gt;   * @param acum_puntuacion Puntuación a sumar.&lt;br /&gt;   */&lt;br /&gt;  public function sumaPuntuacion(acum_puntuacion:int)&lt;br /&gt;  {&lt;br /&gt;   puntuacion += acum_puntuacion;&lt;br /&gt;   puntuacion_text.text = puntuacion.toString();&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * Inicia la posición del marcador, en relación a un Stage de&lt;br /&gt;   * referencia.&lt;br /&gt;   * @param stage Stage de referencia.&lt;br /&gt;   */&lt;br /&gt;  public function iniciaPosicion(stage:Stage)&lt;br /&gt;  {&lt;br /&gt;   puntuacion_text.text = puntuacion.toString();&lt;br /&gt;   var separacion:uint = 15;&lt;br /&gt;   x = (stage.stageWidth / 2) + ((this.width + separacion) * id) - (this.width + separacion) / 2;&lt;br /&gt;   y = width / 2 + separacion;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- Para cambiar el texto del marcador que hemos creado en Flash, utilizamos &lt;strong&gt;puntuacion_text.text&lt;/strong&gt;. Recuerda que puntuacion_text es el nombre que dimos a la instancia de texto dinámico en el marcador.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Añadiendo los marcadores al escenario&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Lo primero, en la clase &lt;strong&gt;Escenario&lt;/strong&gt; creamos un &lt;strong&gt;Vector&lt;/strong&gt; que albergue los maracadores:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;protected var marcadores:Vector.&amp;lt;Marcador&amp;gt;;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Y modificamos el constructor:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function Escenario(stage:Stage, keyObject:KeyObject) &lt;br /&gt;  {&lt;br /&gt;   stageRef = stage;&lt;br /&gt;   key = keyObject;&lt;br /&gt;   colisionables = new Vector.&amp;lt;IColisionable&amp;gt;;&lt;br /&gt;   colisionadores = new Vector.&amp;lt;IColisionador&amp;gt;;&lt;br /&gt;   marcadores = new Vector.&amp;lt;Marcador&amp;gt;;&lt;br /&gt;   creaPongs(2);&lt;br /&gt;   creaMarcadores(2);&lt;br /&gt;   creaEscenario();&lt;br /&gt;   creaBolas(1);&lt;br /&gt;   addEventListener(Event.ENTER_FRAME, bucle, false, 0, true);&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;dónde, aparte de crear el &lt;strong&gt;Vector&lt;/strong&gt; de marcadores, además llamamos a la nueva función &lt;em&gt;creaMarcadores&lt;/em&gt; cuya definición es la siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  /**&lt;br /&gt;   * Añade un número de marcadores al escenario.&lt;br /&gt;   * @param num_marc Número de marcadores.&lt;br /&gt;   */&lt;br /&gt;  public function creaMarcadores(num_marc:uint)&lt;br /&gt;  {&lt;br /&gt;   for (var i:uint = 0; i &lt; num_marc; i++)&lt;br /&gt;   {&lt;br /&gt;    var marcador:Marcador = new Marcador(stageRef, i);&lt;br /&gt;    stageRef.addChild(marcador);&lt;br /&gt;    marcadores.push(marcador);&lt;br /&gt;   }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Y ahora, ¿recuerdas que en GolEvent teníamos un atributo &lt;em&gt;lado&lt;/em&gt; que indicaba dónde se produjo el gol? Pues ha llegado el momento de utilizarlo. Podemos borrar el contenido de la función &lt;em&gt;golAnotado&lt;/em&gt; en &lt;strong&gt;Escenario&lt;/strong&gt; y cambiarlo por este otro:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  /**&lt;br /&gt;   * Tratamiento tras que se produza un evento.&lt;br /&gt;   * @param e El evento producido.&lt;br /&gt;   */&lt;br /&gt;  public function golAnotado(e:GolEvent)&lt;br /&gt;  {&lt;br /&gt;   marcadores[e.lado].sumaPuntuacion(1);&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt; - &lt;strong&gt;marcadores[e.lado]&lt;/strong&gt;: Tenemos dos marcadores dentro del &lt;strong&gt;Vector&lt;/strong&gt;. Uno en la posición "0" y otro en la posición "1". ¿Cómo decidimos dónde sumar puntuación? Con el atributo antes mencionado. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Y ya tenemos los marcadores funcionando.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/08/produciendo-y-detectando-los-goles.html"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/09/un-campo-de-futbol.html"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-7152920384100029907?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/7152920384100029907/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/09/anadiendo-los-marcadores.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/7152920384100029907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/7152920384100029907'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/09/anadiendo-los-marcadores.html' title='Añadiendo los Marcadores'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-2947074174089739913</id><published>2009-08-26T20:46:00.007+02:00</published><updated>2009-09-03T18:14:29.201+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>Produciendo y detectando los goles</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;¡Gol!&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Si nuestro propósito es crear un marcador que contabilice el número de goles anotado por cada jugador, lo primero que necesitamos es ser capaces de detectar los &lt;strong&gt;goles.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para detectar los goles vamos a utilizar &lt;strong&gt;Eventos.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Qué es un evento?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;En Programación Orientada a Objetos, un &lt;strong&gt;evento&lt;/strong&gt; es un &lt;strong&gt;suceso que ocurre en un determinado momento y que podemos detectar&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Simple, ¿no? Se produce un gol &lt;strong&gt;=&amp;gt;&lt;/strong&gt; Lo detecto &lt;strong&gt;=&amp;gt;&lt;/strong&gt; Lo reflejo en el marcador.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Definición de GolEvent&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Lo primero que debemos hacer es definir el Evento. El Evento, como cualquier otro concepto u objeto en POO, es una clase. Pero, para especificar que es un evento, ésta debe heredar de la clase de ActionScript &lt;strong&gt;&lt;a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/events/Event.html"&gt;Event&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para mantener el pulcro orden que hemos intentado llevar hasta ahora, vamos a crear una nueva subcarpeta en&lt;strong&gt; pong &lt;/strong&gt;llamada &lt;strong&gt;evento&lt;/strong&gt;, y en ella vamos a crear la clase &lt;strong&gt;GolEvent&lt;/strong&gt;. Pero antes, un pequeño concepto para entender el código de GolEvent:&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Qué es un atributo estático (static) o de clase?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;Es un atributo global compartido por todas las instancias (objetos) de una clase. Su definición es la siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;visibilidad &lt;em&gt;static&lt;/em&gt; atributo_de_clase:Tipo = valor;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Es decir, con static especificamos que se trata de un atributo de clase. ¿Y para qué sirve esto? Pongamos un ejemplo.&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;public class MiClase&lt;br /&gt;{&lt;br /&gt; public static var numero:Number = 0;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Ahora, sólo con importar la clase &lt;strong&gt;MiClase&lt;/strong&gt; tendríamos acceso a "MiClase.numero" sin necesidad de crear ningún objeto de esta clase. Por ejemplo, el código:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;trace(MiClase.numero);&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;tendría como salida:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;0&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Hay algunos detalles más detrás de los miembros &lt;strong&gt;static&lt;/strong&gt; (cómo que las funciones también pueden serlo), pero de momento esto nos sirve para continuar.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ahora sí, la definición de &lt;strong&gt;GolEvent&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package mi.pong.evento&lt;br /&gt;{&lt;br /&gt; import flash.events.Event;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public class GolEvent extends Event&lt;br /&gt; {&lt;br /&gt;  public static const GOL_EVENT:String = "GolEvent";&lt;br /&gt;  public static const IZQUIERDA:uint = 0;&lt;br /&gt;  public static const DERECHA:uint = 1;&lt;br /&gt;  &lt;br /&gt;  public var lado:uint;&lt;br /&gt;  &lt;br /&gt;  public function GolEvent(lado_gol:uint) &lt;br /&gt;  {&lt;br /&gt;   super(GOL_EVENT);&lt;br /&gt;   lado = lado_gol;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;-&lt;strong&gt; GOL_EVENT:String: &lt;/strong&gt;Este es el &amp;quot;nombre del evento&amp;quot;. La clase Event &amp;quot;nos obliga&amp;quot; a definir un string identificativo para los eventos. Este string se envía al constructor padre a través de &lt;strong&gt;super(GOL_EVENT); &lt;/strong&gt;Posteriormente, este string nos servirá para detectar el evento. El modificador &lt;strong&gt;const &lt;/strong&gt;(en contraste con &lt;strong&gt;var&lt;/strong&gt;) especifica que el valor de este atributo &lt;strong&gt;no puede ser cambiado&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;IZQUIERDA, DERECHA: &lt;/strong&gt;Estas dos constantes nos servirán para determinar en cuál de los dos lados se produjo el gol, para poder sumarlo al marcador correspondiente.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;lado: &lt;/strong&gt;Esta atributo contendrá el lado en el que se produjo el gol (&lt;strong&gt;IZQUIERDA &lt;/strong&gt;o &lt;strong&gt;DERECHA&lt;/strong&gt;).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- En el constructor, lo primero que hacemos es llamar al constructor padre (el de la clase Event) con en el nombre del evento. Esto debemos hacerlo obligatoriamente siempre. Lo hacemos con la palabra especial &lt;strong&gt;super&lt;/strong&gt;, que explicaré a continuación. Después asignamos al atributo &lt;strong&gt;lado &lt;/strong&gt;el lado desde el que se produjo el gol, que viene dado en forma de parámetro en el constructor.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- Notad que, por convenio, las &lt;strong&gt;constantes van escritas con mayúsculas.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Para qué sirve la palabra clave &amp;quot;super&amp;quot;?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;La palabra &lt;strong&gt;super&lt;/strong&gt; nos da acceso desde una clase hija a los miembros de su clase padre. Es decir, si yo tengo una clase &lt;strong&gt;&amp;quot;Transporte&amp;quot; &lt;/strong&gt;con una función &lt;strong&gt;&amp;quot;viajar&amp;quot;&lt;/strong&gt; y quiero acceder a ella desde su clase hija &lt;strong&gt;&amp;quot;Avión&amp;quot;&lt;/strong&gt; puedo hacerlo con &lt;em&gt;super.viajar().&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En verdad, &lt;strong&gt;super&lt;/strong&gt; no se utiliza con este fin, puesto que se puede acceder a viajar (y a cualquier otro miembro de &lt;strong&gt;Transporte&lt;/strong&gt;) sin necesidad de especificarlo.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;El único caso de uso real es en el del constructor. Aunque no se especifique textualmente, internamente, todos los constructores de clases heredades definen como primera instrucción &lt;strong&gt;super()&lt;/strong&gt;, que llama al constructor de la clase padre. Cuándo lo definimos explícitamente, como en el caso de &lt;strong&gt;GolEvent&lt;/strong&gt; es porque necesitamos especificar parámetros para el constructor de la clase padre.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;¿Quién produce el GolEvent?&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;El siguiente paso es &lt;strong&gt;producir el evento&lt;/strong&gt; para posteriormente detectarlo.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Aunque se podría hacer de diferentes maneras, de todos los elementos que de momento tenemos en nuestro juego, el que más sentido tiene que produzca los eventos de Gol es la &lt;strong&gt;Bola.&lt;/strong&gt; Al fin y al cabo, es la que mejor sabe cuándo ha llegado a los confines del escenario.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Añadimos el código necesario en la función &lt;em&gt;loop &lt;/em&gt;de Bola, en dónde ya detectamos cuándo llega a los límites del campo:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function loop(e:Event)&lt;br /&gt;  { &lt;br /&gt;   x += vx;&lt;br /&gt;   y += vy;&lt;br /&gt;   &lt;br /&gt;   if (y &lt; 0)&lt;br /&gt;   {&lt;br /&gt;    y = 0;&lt;br /&gt;    vy = -vy;&lt;br /&gt;   }&lt;br /&gt;   else if (y &gt; stageRef.stageHeight)&lt;br /&gt;   {&lt;br /&gt;    y = stageRef.stageHeight;&lt;br /&gt;    vy = -vy;&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   if (x &lt; 0)&lt;br /&gt;   {&lt;br /&gt;    iniciaPosicion();&lt;br /&gt;    dispatchEvent(new GolEvent(GolEvent.DERECHA));&lt;br /&gt;    vx = 5;&lt;br /&gt;    vy = 0;&lt;br /&gt;   }&lt;br /&gt;   else if (x &gt; stageRef.stageWidth)&lt;br /&gt;   {&lt;br /&gt;    iniciaPosicion();&lt;br /&gt;    dispatchEvent(new GolEvent(GolEvent.IZQUIERDA));&lt;br /&gt;    vx = -5;&lt;br /&gt;    vy = 0;&lt;br /&gt;   }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;dispatchEvent(new GolEvent(GolEvent.DERECHA)): &lt;/strong&gt;esta función (heredada de &lt;strong&gt;MovieClip&lt;/strong&gt;) permite a la bola lanzar un evento que alguien puede escuchar. Básicamente esto se traduce en: &amp;quot;Oye, mira, soy la bola. Que ha habido gol por la derecha.&amp;quot; Por la izquierda es análogo.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;La clave ahora está en detectar ese evento y procesarlo.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;¿Quién detecta el GolEvent?&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Cómo la idea era y es que el &lt;strong&gt;Escenario&lt;/strong&gt; se encargue de la mayor lógica del juego posible, será él quién detecte el evento. La manera de detectar los eventos es algo que ya hemos hecho en varias ocasiones, con la función &lt;em&gt;addEventListener(...)&lt;/em&gt;. Vamos a realizar una modificación en la función &lt;em&gt;creaBolas &lt;/em&gt;del &lt;strong&gt;Escenario&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function creaBolas(num_bolas:uint)&lt;br /&gt;  {&lt;br /&gt;   for (var i:uint = 0; i &lt; num_bolas; i++)&lt;br /&gt;   {&lt;br /&gt;    var bola:Bola = new Bola(stageRef);&lt;br /&gt;    bola.addEventListener(GolEvent.GOL_EVENT, golAnotado, false, 0, true);&lt;br /&gt;    stageRef.addChild(bola);&lt;br /&gt;    colisionadores.push(bola);&lt;br /&gt;   }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;bola.addEventListener(GolEvent.GOL_EVENT, golAnotado, ...)&lt;/strong&gt;: Añadimos un eventListener ("oyente de eventos") a la bola, que queda a la expectativa de que ésta haga un &lt;em&gt;dispatchEvent(...)&lt;/em&gt; que contenga un &lt;strong&gt;GolEvent&lt;/strong&gt; para ejecutar la función &lt;em&gt;golAnotado&lt;/em&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Cobra aquí importancia el atributo estático &lt;em&gt;GOL_EVENT&lt;/em&gt;, y cómo lo especificamos en la clase padre &lt;strong&gt;Event&lt;/strong&gt; (a través de &lt;em&gt;super(GOL_EVENT)&lt;/em&gt;), convirtiéndolo así en el &amp;quot;nombre del evento&amp;quot;. Ahora en &lt;em&gt;addEventListener&lt;/em&gt; indicamos que el evento que nos interesa detectar es el que lleva ese nombre.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ahora sólo nos queda definir la función &lt;em&gt;golAnotado&lt;/em&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function golAnotado(e:GolEvent)&lt;br /&gt;  {&lt;br /&gt;   trace("¡Gol!");&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;golAnotado(e:GolEvent): &lt;/strong&gt;Al utilizarla en &lt;em&gt;addEvenlistener&lt;/em&gt;, la función &lt;em&gt;golAnotado&lt;/em&gt; recibe como parámetro un evento (en este caso, de tipo GolEvent).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;De momento, esto nos sirve para comprobar si todo el flujo de eventos funciona. En el siguiente capítulo crearemos los marcadores.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/08/bug-i-la-bola-loca.html"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/09/anadiendo-los-marcadores.html"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-2947074174089739913?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/2947074174089739913/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/08/produciendo-y-detectando-los-goles.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/2947074174089739913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/2947074174089739913'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/08/produciendo-y-detectando-los-goles.html' title='Produciendo y detectando los goles'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-1589818617697161078</id><published>2009-08-17T20:45:00.001+02:00</published><updated>2009-08-26T20:47:56.905+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>Bug (I): La Bola loca</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;div class="bug"&gt;Bug (I): La bola loca&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Los errores imprevistos (o &lt;strong&gt;bugs&lt;/strong&gt;) son algo bastante común en la programación, y que suelen aparecer en la ejecución continuada de nuestros programas. Por mucho que se planee una implementación de código, siempre acaba apareciendo una situación inesperada que rompe nuestro preciado código. No pasa nada. Si aparece un &lt;strong&gt;bug &lt;/strong&gt;se soluciona, y a otra cosa.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En este caso, nosotros encontramos un error&lt;strong&gt; si intentamos golpear la pelota con la partes puntiagudas (los extremos) del pong&lt;/strong&gt;. No siempre sucede, pero la mayoría de las veces la bola empieza a rebotar dentro del pong. Queda atrapada.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En código, el problema viene dado porque la bola rebota continuadas veces en poco tiempo, cambiando su dirección de izquierda a derecha (y viceversa) una y otra vez sin llegar a salir del área de colisión del pong.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;La solución que propongo es añadir un &lt;strong&gt;Timer&lt;/strong&gt; a la bola. Un reloj que, tras la colisión, espere un tiempo para volver a comprobar si hay colisiones, y así dar tiempo a la bola para abandonar la zona de colisiones del pong.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En código, añadimos estos atributos a la clase &lt;strong&gt;Bola&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  // Para evitar múltiples colisiones&lt;br /&gt;  private var colisionado:Boolean = false;&lt;br /&gt;  private var timer:Timer = new Timer(100);&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Añadimos la inicialización del timer al constructor:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function Bola(stage:Stage) &lt;br /&gt;  {&lt;br /&gt;   stageRef = stage;&lt;br /&gt;   addEventListener(Event.ENTER_FRAME, loop, false, 0, true);&lt;br /&gt;   iniciaPosicion();&lt;br /&gt;   timer.addEventListener(TimerEvent.TIMER, colisionTime, false, 0, true);&lt;br /&gt;   timer.stop();&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Lo que decimos con este código, es que cada vez que se cumpla el tiempo especificado en el constructor del &lt;strong&gt;Timer&lt;/strong&gt; se ejecute la función &lt;em&gt;colisionTime&lt;/em&gt;. Además, lo detenemos con &lt;em&gt;timer.stop()&lt;/em&gt;, porque de momento no queremos que corra. El código de &lt;em&gt;colisionTime&lt;/em&gt; es el siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function colisionTime(e:TimerEvent)&lt;br /&gt;  {&lt;br /&gt;   timer.stop();&lt;br /&gt;   colisionado = false;&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Es decir, pasado el tiempo, indicamos que la bola "ha dejado de colisionar". Pero nos falta, entonces, ver cuándo &lt;em&gt;colisionado&lt;/em&gt; cambia a true. Este cambio sucede en la función &lt;em&gt;colisiona&lt;/em&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function colisiona(objeto:IColisionable):void&lt;br /&gt;  {&lt;br /&gt;   if (!colisionado)&lt;br /&gt;    {&lt;br /&gt;     var vel_x:Number = Math.abs(vx);&lt;br /&gt;     if (vel_x &lt; max_velocidad)&lt;br /&gt;     {&lt;br /&gt;      vel_x += acc;&lt;br /&gt;     }&lt;br /&gt;      &lt;br /&gt;     if (vx &gt; 0)&lt;br /&gt;     {&lt;br /&gt;      vx = -vel_x;&lt;br /&gt;     }&lt;br /&gt;     else&lt;br /&gt;     {&lt;br /&gt;      vx = vel_x;&lt;br /&gt;     }&lt;br /&gt;     vy = ((y - objeto.getY()) / objeto.getHeight() * 2) * vel_x;&lt;br /&gt;     &lt;br /&gt;     colisionado = true;&lt;br /&gt;     timer.start();&lt;br /&gt;    }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Si no acaba de colisionar, dejamos que se produzcan las modificaciones propias de la colisión. Después ponemos &lt;em&gt;colisionado&lt;/em&gt; a "true" e iniciamos el reloj, que, pasado el periodo marcado, volverá a dejar la bola activa para colisiones. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sin embargo, si la bola acabara de colisionar, la función no se ejecutaría.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Si soy sincero, la solución que he encontrado no me acaba de convencer. Funciona, sí, pero quizá algo así debería tener una solución más sencilla. Si alguien tiene una solución mejor, que no dude en proponerla en los comentarios.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/08/el-codigo-del-escenario.html"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/08/produciendo-y-detectando-los-goles.html"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-1589818617697161078?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/1589818617697161078/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/08/bug-i-la-bola-loca.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/1589818617697161078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/1589818617697161078'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/08/bug-i-la-bola-loca.html' title='Bug (I): La Bola loca'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-2392100981652365335</id><published>2009-08-13T11:59:00.004+02:00</published><updated>2009-08-26T20:23:06.633+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>El código del Escenario</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;La nueva clase Main&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Como dijimos anteriormente, la clase &lt;strong&gt;Escenario&lt;/strong&gt; será la encargada de controlar la lógica del juego. La clase &lt;strong&gt;Main&lt;/strong&gt; ahora únicamente se encargará de crear el &lt;strong&gt;control de teclado&lt;/strong&gt;, el &lt;strong&gt;Escenario&lt;/strong&gt; y de añadirlo a Flash. La clase &lt;strong&gt;Main&lt;/strong&gt; presupone (y presupone bien) que la clase Escenario se encargará de todo. Así pues, esta es nuestra nueva clase &lt;strong&gt;Main&lt;/strong&gt;, que no tiene mayor misterio:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package&lt;br /&gt;{&lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; import mi.pong.escenario.Escenario;&lt;br /&gt; import com.senocular.utils.KeyObject;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public class Main extends MovieClip&lt;br /&gt; {&lt;br /&gt;  private var key:KeyObject;&lt;br /&gt;  &lt;br /&gt;  public function Main() &lt;br /&gt;  {&lt;br /&gt;   key = new KeyObject(stage);&lt;br /&gt;   var escenario:Escenario = new Escenario(stage, key);&lt;br /&gt;   stage.addChildAt(escenario, 0);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;h6&gt;El código del Escenario&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Para empezar, necesitamos añadir nuevos atributos en la clase &lt;strong&gt;Escenario&lt;/strong&gt; para soportar la nueva lógica:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  // Objetos estáticos sobre los que se puede colisionar, incluidos los pongs&lt;br /&gt;  protected var colisionables:Vector.&amp;lt;IColisionable&amp;gt;;&lt;br /&gt;  &lt;br /&gt;  // Objetos móviles que pueden colisionar con objetos estáticos o con otros&lt;br /&gt;  // objetos móviles&lt;br /&gt;  protected var colisionadores:Vector.&amp;lt;IColisionador&amp;gt;;&lt;br /&gt;  &lt;br /&gt;  // Variables generales&lt;br /&gt;  protected var key:KeyObject;&lt;br /&gt;  protected var stageRef:Stage;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Y modificar el constructor del escenario: &lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-size:x-small"&gt;(Por comodidad, no añado los &lt;em&gt;imports&lt;/em&gt; del código, pero recuerda que todas las clases que utilices deben estar importadas, si no, el código no compilará)&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function Escenario(stage:Stage, keyObject:KeyObject) &lt;br /&gt;  {&lt;br /&gt;   stageRef = stage;&lt;br /&gt;   key = keyObject;&lt;br /&gt;   colisionables = new Vector.&amp;lt;IColisionable&amp;gt;;&lt;br /&gt;   colisionadores = new Vector.&amp;lt;IColisionador&amp;gt;;&lt;br /&gt;   creaPongs(2);&lt;br /&gt;   creaEscenario();&lt;br /&gt;   creaBolas(1);&lt;br /&gt;   addEventListener(Event.ENTER_FRAME, bucle, false, 0, true);&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Vemos que en el constructor recibimos el &lt;strong&gt;stage&lt;/strong&gt; y el control de teclado &lt;strong&gt;keyObject&lt;/strong&gt;, que asignamos a sus atributos correspondientes. Igualmente, creamos las listas de &lt;strong&gt;colisionables&lt;/strong&gt; y &lt;strong&gt;colisionadores&lt;/strong&gt; y después vienen una serie de funciones (aún no definidas) en las que &lt;strong&gt;inicializamos&lt;/strong&gt; todo el escenario: &lt;strong&gt;creaPongs, creaEscenario, creaBola&lt;/strong&gt;.&lt;/p&gt; &lt;br /&gt;&lt;p&gt;Finalmente, añadimos al escenario un EventListener que al inicio de cada FRAME ejecutará la función &lt;strong&gt;bucle&lt;/strong&gt; (también sin definir). Esta función será &lt;strong&gt;el bucle del juego&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Puede parecer que estamos haciendo muchas cosas y todas ellas muy complejas, pero no es así. Repasemos: queremos transferir la lógica del &lt;strong&gt;Main&lt;/strong&gt; al &lt;strong&gt;Escenario&lt;/strong&gt; para lograr un mayor &lt;strong&gt;encapsulamiento&lt;/strong&gt;. Así que hemos añadido los atributos necesarios para esta tarea al &lt;strong&gt;Escenario&lt;/strong&gt; y los hemos inicializado. Hemos creado, también, los pongs, hemos dibujado el escenario y creado una bola (aunque aún no hayamos visto el código concreto de nada de esto). Y además, iniciado el &lt;strong&gt;bucle del juego&lt;/strong&gt;, que se encarga de toda la lógica.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Veamos ahora el código concreto de cuada una de estas funciones no definidas:&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;creaPongs&lt;/h5&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  /**&lt;br /&gt;   * Añade un número de pongs al escenario.&lt;br /&gt;   * @param num_pongs Número de pongs a crear.&lt;br /&gt;   */&lt;br /&gt;  public function creaPongs(num_pongs:uint)&lt;br /&gt;  {&lt;br /&gt;   for (var i:uint = 0; i &lt; num_pongs; i++)&lt;br /&gt;   {&lt;br /&gt;    var miPong:Pong = new Pong(stageRef, i, key);&lt;br /&gt;    stageRef.addChild(miPong);&lt;br /&gt;    colisionables.push(miPong);&lt;br /&gt;   }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Un bucle en el que creamos un pong por vuelta. Y además, lo añadimos al escenario y a &lt;strong&gt;la lista de colisionables&lt;/strong&gt;. Clave este último detalle.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;El código entre en /** ... */ es &lt;strong&gt;documentación del código&lt;/strong&gt;. En &lt;em&gt;@param&lt;/em&gt; estamos especificando que la función recibe como parámetro "num_pongs". Existen herramientas que pueden traducirnos toda esta información en una web, al estilo de la &lt;a href="http://help.adobe.com/es_ES/AS3LCR/Flash_10.0/index.html"&gt;documentación de ActionScript 3&lt;/a&gt;. Pero este es un tema que, de momento, no se va a cubrir en esta guía.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;creaBolas&lt;/h5&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  /**&lt;br /&gt;   * Añade un número de bolas al escenario.&lt;br /&gt;   * @param num_bolas Número de bolas a crear.&lt;br /&gt;   */&lt;br /&gt;  public function creaBolas(num_bolas:uint)&lt;br /&gt;  {&lt;br /&gt;   for (var i:uint = 0; i &lt; num_bolas; i++)&lt;br /&gt;   {&lt;br /&gt;    var bola:Bola = new Bola(stageRef);&lt;br /&gt;    stageRef.addChild(bola);&lt;br /&gt;    colisionadores.push(bola);&lt;br /&gt;   }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Análogo (para variar) a la creación de pongs. La única diferencia, que la bola, como corresponde, se añade a la lista de colisionadores.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;creaEscenario&lt;/h5&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  /**&lt;br /&gt;   * Crea el escenario. Un cuadrado verde que ocupa todo el stage.&lt;br /&gt;   */&lt;br /&gt;       public function creaEscenario()&lt;br /&gt;  {&lt;br /&gt;   graphics.beginFill(0x66FF99);&lt;br /&gt;    graphics.drawRect(0, 0, stageRef.stageWidth, stageRef.stageHeight);&lt;br /&gt;   graphics.endFill();&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;La apariencia del &lt;strong&gt;Escenario&lt;/strong&gt; por defecto es sencilla: un cuadrado verde que ocupa todo la pantalla Flash.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En esta función, hacemos uso de las funciones que ofrece ActionScript 3 para &lt;strong&gt;dibujar directamente sobre la pantalla Flash&lt;/strong&gt;. Aunque parece complejo, en verdad es bastante sencillo. El único &lt;em&gt;pero&lt;/em&gt; es que hay que seguir una metodología bastante marcada para que todo funcione correctamente. Algunas claves (que ampliaremos en los siguientes capítulos):&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;1)&lt;/strong&gt; Las funciones de dibujo se invocan siempre desde el atributo &lt;strong&gt;graphics&lt;/strong&gt; (cuya clase es &lt;strong&gt;Graphics&lt;/strong&gt;) que contiene la clase &lt;strong&gt;Sprite&lt;/strong&gt; y sus herederas. &lt;strong&gt;MovieClip&lt;/strong&gt; entre ellas.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;2)&lt;/strong&gt; &lt;strong&gt;beginFill(color)&lt;/strong&gt;: indicamos que vamos a comenzar a dibujar formas del color que especificamos en el parámetro &lt;em&gt;color&lt;/em&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;3)&lt;/strong&gt; &lt;strong&gt;drawRect(x, y, width, height)&lt;/strong&gt;: Dibujamos un rectángulo que parte en el punto &lt;em&gt;x&lt;/em&gt; e &lt;em&gt;y&lt;/em&gt; cuyo ancho mide &lt;em&gt;width&lt;/em&gt; y cuyo alto mide &lt;em&gt;height&lt;/em&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;4)&lt;/strong&gt; &lt;strong&gt;endFill()&lt;/strong&gt;: indicamos que hemos terminado de dibujar.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Importante&lt;/strong&gt;: Todas las instrucciones de dibujado de formas &lt;strong&gt;deben estar obligatoriamente entre beginFill y endFill&lt;/strong&gt;, si no, obtendremos resultados inesperados (A aquéllos que hayan trabajado con OpenGL esto les sonará).&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;bucle&lt;/h5&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  /**&lt;br /&gt;   * Bucle principal del escenario.&lt;br /&gt;   * @param e Evento que produjo el disparo de la función.&lt;br /&gt;   */&lt;br /&gt;  private function bucle(e:Event)&lt;br /&gt;  {&lt;br /&gt;   for (var i = 0; i &lt; colisionadores.length; i++)&lt;br /&gt;   {&lt;br /&gt;    for (var j = 0; j &lt; colisionables.length; j++)&lt;br /&gt;    {&lt;br /&gt;     if (colisionadores[i].getHitBox().hitTestObject(colisionables[j].getHitBox()))&lt;br /&gt;     {&lt;br /&gt;      colisionadores[i].colisiona(colisionables[j]);&lt;br /&gt;      colisionables[j].recibeColision(colisionadores[i]);&lt;br /&gt;     }&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Tenemos dos bucles anidados, en los que estamos recorriendo la lista de &lt;strong&gt;colisionadores&lt;/strong&gt; y comprobando con cada uno de los objetos de la lista &lt;strong&gt;colisionables&lt;/strong&gt; si se produjo alguna colisión. Si así fuere, llamaríamos a las funciones correspondientes: &lt;strong&gt;colisionadores[i].colisionaba(colisionable[j]) &lt;/strong&gt; y &lt;strong&gt;colisionables[j].recibeColision(colisionadores[i]).&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En verdad, como de momento sólo tenemos bolas y pongs, esto se podría traducir por &lt;strong&gt;bola.colisiona(pong) &lt;/strong&gt;y &lt;strong&gt;pong.recibeColision(bola).&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;La bola que colisiona...&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Pues ya estamos preparados para implementar la funcion &lt;strong&gt;&lt;em&gt;colisiona&lt;/em&gt;&lt;/strong&gt; en la clase &lt;strong&gt;Bola&lt;/strong&gt; que dejamos vacía en el capítulo anterior. Pero antes, vamos a a modificar un par de casas en la clase &lt;strong&gt;Bola:&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;1)&lt;/strong&gt; En los atributos. Esto son todos los atributos que tiene, por el momento, &lt;strong&gt;Bola&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  private var vx:Number = 5;&lt;br /&gt;  private var vy:Number = 0;&lt;br /&gt;  private var max_velocidad:Number = 15;&lt;br /&gt;  private var acc:Number = 0.25;&lt;br /&gt;  &lt;br /&gt;  private var stageRef:Stage;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Como se puede ver, aparece &lt;em&gt;acc&lt;/em&gt;, que es la aceleración de la bola, que sumaremos cada vez que colisione. Y desaparece el atributo &lt;em&gt;colisionadores&lt;/em&gt;, ya que es ahora el escenario quien se encarga de las colisiones de la bola. No olvides eliminar también el bucle en el que se testean las colisiones en la función &lt;em&gt;loop&lt;/em&gt;. En consecuencia, éste es el nuevo constructor de &lt;strong&gt;Bola&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function Bola(stage:Stage) &lt;br /&gt;  {&lt;br /&gt;   stageRef = stage;&lt;br /&gt;   addEventListener(Event.ENTER_FRAME, loop, false, 0, true);&lt;br /&gt;   iniciaPosicion();&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Ahora sí, el código de &lt;strong&gt;colisiona&lt;/strong&gt;. Recuerda que esta función se ejecutará siempre que la bola colisione:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;public function colisiona(objeto:IColisionable):void&lt;br /&gt;  {&lt;br /&gt;   var vel_x:Number = Math.abs(vx);&lt;br /&gt;   if (vel_x &lt; max_velocidad)&lt;br /&gt;   {&lt;br /&gt;    vel_x += acc;&lt;br /&gt;   }&lt;br /&gt;   if (vx &gt; 0)&lt;br /&gt;   {&lt;br /&gt;    vx = -vel_x;&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;    vx = vel_x;&lt;br /&gt;   }&lt;br /&gt;   vy = ((y - objeto.getY()) / objeto.getHeight() * 2) * vel_x;&lt;br /&gt;    &lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;En esencia, estamos cambiando la dirección de la bola y aumentando su aceleración. Siempre que su velocidad no supere la máxima permitida.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Un detalle importante, es que no podemos poner &lt;strong&gt;max_velocidad&lt;/strong&gt; el valor que deseemos. Si la ponemos demasiado alta, la bola &lt;em&gt;atravesará&lt;/em&gt; al pong. En el futuro intentaremos solucionar este problema.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/08/la-bola-y-el-pong-como-icolisionador-e.html"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/08/bug-i-la-bola-loca.html"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-2392100981652365335?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/2392100981652365335/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/08/el-codigo-del-escenario.html#comment-form' title='6 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/2392100981652365335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/2392100981652365335'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/08/el-codigo-del-escenario.html' title='El código del Escenario'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-2734116346719373607</id><published>2009-08-07T12:36:00.006+02:00</published><updated>2009-08-15T13:44:57.165+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>La Bola y el Pong como IColisionador e IColisionable</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Un pequeño problema...&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Antes de nada vamos a realizar algo de trabajo sucio y molesto. En nuestro afán de mantener nuestro código ordenado, no serán pocas las veces que tengamos que reescribir y cambiar cosas que ya teníamos, como es el caso que se nos presenta a continuación. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Queremos una organización como la de la imagen. Así que vamos a crear las carpetas que nos falten y mover los .as que tenemos a su lugar correspondiente. Además, en las carpetas &lt;strong&gt;colisionable&lt;/strong&gt; y &lt;strong&gt;colisionador&lt;/strong&gt; vamos a &lt;strong&gt;clickar con el boton derecho&lt;/strong&gt;,&lt;strong&gt; Add... &lt;/strong&gt;y en esta ocasión, como lo que queremos son dos nuevas interfaces&lt;strong&gt; -&amp;gt; New Interface... &lt;/strong&gt;Lo  haremos por dos veces, con los nombres &lt;strong&gt;IColisionador &lt;/strong&gt;e &lt;strong&gt;IColisionable&lt;/strong&gt; en sus respectivas carpetas.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://lh4.ggpht.com/_lVd850Hzqko/SnrH8KGREAI/AAAAAAAAASY/gSVkqrqH1RM/organizacion.jpg"/&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Y, aunque no lo pareciese, con este simple movimiento nos hemos cargado varias cosas que antes funcionaban. Abre ahora &lt;strong&gt;Bola.as&lt;/strong&gt; y la clase &lt;strong&gt;Pong.as&lt;/strong&gt; y verás dos mensajes advirtiéndote  que el nombre de paquete no concucerda con la ruta de carpetas. Y no sólo eso, también en el fichero Flash, si  nos vamos a las propiedades del Clip de Película &lt;strong&gt;Bola&lt;/strong&gt; o de &lt;strong&gt;Pong &lt;/strong&gt;de la bibloteca, si en el apartado &lt;strong&gt;Clase&lt;/strong&gt; clickamos en el tic que valida la clase, también obtendremos un error. ¿Qué ha pasado? Pues que hemos movido los archivos de carpeta, y ahora Flash nos lo encuentra.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;La solución es sencilla: en &amp;quot;Pong.as&amp;quot; cambiamos la actual cabecera del paquete por esto: &lt;strong&gt;package mi.pong.objeto.colisionable&lt;/strong&gt; (la nueva ruta de carpetas en la que se encuentra Pong) y en las propiedades del símbolo Flash cambiamos la clase por su nueva localización &lt;strong&gt;mi.pong.objeto.colisionable.Pong&lt;/strong&gt;. Repetimos proceso (sólo que cambiando &amp;quot;colisionable&amp;quot; por &amp;quot;colisionador&amp;quot;) con la clase &lt;strong&gt;Bola&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En el futuro tendremos cuidado para evitar estas pérdidas de tiempo.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;IColisionable e IColisionador&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Definimos en sendos archivos las interfaces &lt;strong&gt;IColisionable&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package mi.pong.objeto.colisionable &lt;br /&gt;{&lt;br /&gt; import flash.display.DisplayObject;&lt;br /&gt; import mi.pong.objeto.colisionador.IColisionador;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public interface IColisionable &lt;br /&gt; {&lt;br /&gt;  function getHitBox():DisplayObject;&lt;br /&gt;  function recibeColision(objeto:IColisionador):void;&lt;br /&gt;  function getY():Number;&lt;br /&gt;  function getHeight():Number;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;p&gt; e &lt;strong&gt;IColisionador&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package mi.pong.objeto.colisionador &lt;br /&gt;{&lt;br /&gt; import flash.display.DisplayObject;&lt;br /&gt; import mi.pong.objeto.colisionable.IColisionable;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public interface IColisionador &lt;br /&gt; {&lt;br /&gt;  function getHitBox():DisplayObject;&lt;br /&gt;  function colisiona(objeto:IColisionable):void;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Vamos por partes:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;function getHitBox():DisplayObject;&lt;/strong&gt; Esta función, definida en ambas interfaces, será la que  proporciene el área de colisión de cada objeto. El rectángulo transparente al que llamamos "hitBox" y que añadimos en los símbolos Bola y Pong de nuestro Flash en capítulos anteriores. El objeto que se devuelve es de tipo &lt;strong&gt;DisplayObject&lt;/strong&gt;, que es una clase antecesora (el padre del padre del padre...) de &lt;strong&gt;MovieClip&lt;/strong&gt;. ¿Por qué &lt;strong&gt;DisplayObject&lt;/strong&gt; y no &lt;strong&gt;MovieClip&lt;/strong&gt;? Por generalidad. &lt;strong&gt;DisplayObject&lt;/strong&gt; representa cualquier objeto que pueda representarse en el canvas de Flash. &lt;strong&gt;MovieClip &lt;/strong&gt;representa un único tipo de objetos que pueden representarse por pantalla.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;function recibeColision( objeto:IColisionador ) &lt;/strong&gt; y &lt;strong&gt;function colisiona( objeto:IColisionable ) &lt;/strong&gt;: es la función que se ejecutará cuándo el objeto reciba la colisión / colisione. Además, le pasaremos como parámetro aquello contra lo que colisionó.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;function getY():Number; function getHeight():Number;&lt;/strong&gt; Sólo las hemos puesto (de momento) en &lt;strong&gt;IColisionable&lt;/strong&gt;. Como sus nombres indican, nos devuelven la posición en el eje &amp;quot;y&amp;quot; y la altura del pong. Las necesitaremos para calcular la trayectoria de la bola.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Muy bien, tenemos nuestras dos interfaces. ¿Y? ¿Qué tienen que ver con Bola y Pong? Bueno, de momento nada. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Antes de continuar, recordemos que la idea era que el &lt;strong&gt;Escenario &lt;/strong&gt;tratara los objetos que contuviere de &lt;strong&gt;manera genérica, &lt;/strong&gt;sin preocuparse de si eran bolas, pongs, ítems... Sólo necesitaba saber si eran &lt;strong&gt;IColisionable&lt;/strong&gt; o &lt;strong&gt;IColisionador&lt;/strong&gt;. Pues el siguiente paso es convertir las clases que tenemos de momento (Bola y Pong) en ICoisionable o IColisonador. Y eso lo conseguimos &lt;strong&gt;implementando las respectivas interfaces.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Bola como IColsionador&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;La bola es un colisionador. Para decírselo a ActionScript 3, debemos especificarlo en &lt;strong&gt;Bola.as&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En la zona de importación, importamos la interfaz deseada. En verdad, no es realmente necesaria esta importación, porque, al encontrarse en la misma carpeta, &lt;strong&gt;Bola&lt;/strong&gt; &amp;quot;ve&amp;quot; a &lt;strong&gt;IColisionador&lt;/strong&gt;. La que sí es necesaria es &lt;strong&gt;IColisionable&lt;/strong&gt;, debido a &lt;strong&gt;colisiona(objeto:IColisionable)&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;import mi.pong.objeto.colisionador.IColisionador;&lt;br /&gt;import mi.pong.objeto.colisionable.IColisionable;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Ahora, en la definición de clase, especificamos que &lt;strong&gt;Bola&lt;/strong&gt; implementa &lt;strong&gt;IColisionable&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;public class Bola extends MovieClip implements IColisionador &lt;br /&gt;{&lt;br /&gt;   ...&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Y por último, implementamos los métodos de la interfaz en la clase Bola. &lt;strong&gt;Hay que implementarlos todos, si no obtendríamos un error.&lt;/strong&gt; Añadimos las definiciones al final de la clase:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  // Implementación de la interfaz IColisionable&lt;br /&gt;  public function getHitBox():DisplayObject&lt;br /&gt;  {&lt;br /&gt;   return hitBox;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public function colisiona(objeto:IColisionable):void&lt;br /&gt;  {&lt;br /&gt;&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- En &lt;strong&gt;getHitBox()&lt;/strong&gt;  devolvemos &lt;strong&gt;hitBox&lt;/strong&gt; que es el área de colisión definida en forma de rectángulo en Flash. Vamos, que estamos devolviendo la cajita transparente que tiene la Bola. La necesitaremos para calcular colisiones.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- De momento, dejamos sin definir &lt;strong&gt;colsiona(objeto:IColisionable)&lt;/strong&gt;. Lo haremos cuándo tengamos establecido el flujo de control del escenario.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Pong como IColisionable&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Los pasos a seguir en este caso son análogos a los seguidos con &lt;strong&gt;Bola&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;&lt;br /&gt;import mi.pong.objeto.colisionador.IColisionador;&lt;br /&gt;import mi.pong.objeto.colisionable.IColisionable;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;public class Pong extends MovieClip implements IColisionable&lt;br /&gt; {&lt;br /&gt;    ...&lt;/pre&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  // Interfaz IColisionable&lt;br /&gt;  public function getHitBox():DisplayObject &lt;br /&gt;  {&lt;br /&gt;   return hitBox;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public function recibeColision(objeto:IColisionador):void&lt;br /&gt;  {&lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public function getY():Number&lt;br /&gt;  {&lt;br /&gt;   return y;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public function getHeight():Number&lt;br /&gt;  {&lt;br /&gt;   return height;&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- En &lt;strong&gt;getHitBox()&lt;/strong&gt; devolvemos igualmente &lt;strong&gt;hitBox&lt;/strong&gt; y en &lt;strong&gt;getY()&lt;/strong&gt; y &lt;strong&gt;getHeight()&lt;/strong&gt; la posición &amp;quot;y&amp;quot; y la altura del objeto respectivamente.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para cerrar el ciclo y e intentar aclarar un poco las ideas respecto a las interfaces, vayámonos a la clase Escenario, y añadamos el siguiente código:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package mi.pong.escenario &lt;br /&gt;{&lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; import mi.pong.objeto.colisionable.IColisionable;&lt;br /&gt; import mi.pong.objeto.colisionador.IColisionador;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public class Escenario extends MovieClip&lt;br /&gt; {&lt;br /&gt;  // Objetos estáticos sobre los que se puede colisionar, incluidos los pongs&lt;br /&gt;  protected var colisionables:Vector.&amp;lt;IColisionable&amp;gt;;&lt;br /&gt;  &lt;br /&gt;  // Objetos móviles que pueden colisionar con objetos estáticos o con otros&lt;br /&gt;  // objetos móviles&lt;br /&gt;  protected var colisionadores:Vector.&amp;lt;IColisionador&amp;gt;;&lt;br /&gt;        &lt;br /&gt;       public function Escenario()&lt;br /&gt;       {&lt;br /&gt;&lt;br /&gt;       }&lt;br /&gt;     }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Lo más importante es &lt;strong&gt;protected var colisionables:Vector.&amp;lt;IColisionable&amp;gt;&lt;/strong&gt; y &lt;strong&gt;protected var colisionadores:Vector.&amp;lt;IColisionador&amp;gt;&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- Primero, y volviendo a la POO, &lt;strong&gt;protected&lt;/strong&gt; indica que el atributo es &lt;strong&gt;solamente visible por las clases herederas y por la propia clase.&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- Y segundo, aquí vemos por fin el uso de las interfaces. Especificamos dos listas (&lt;strong&gt;Vector&lt;/strong&gt;), una que contiene objetos de tipo &lt;strong&gt;IColisionable &lt;/strong&gt; y la otra de tipo &lt;strong&gt;IColisionador. &lt;/strong&gt;Y el escenario no sabe si son bolas, pongs, ítems... Sólo sabe que unas colisionan y otras son colisionables. Y las trata a todas por igual.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Un último detalle, para que Flash reconozca la clase &lt;strong&gt;Vector&lt;/strong&gt;, debéis comprobar dos cosas:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;1) &lt;/strong&gt;En &lt;strong&gt;FlashDevelop, &lt;/strong&gt;en &lt;strong&gt;Project -&amp;gt; Properties -&amp;gt; Output -&amp;gt; Target &lt;/strong&gt;debe estar seleccionado &lt;strong&gt;Flash Player 10.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;2) &lt;/strong&gt;En &lt;strong&gt;Flash CS4, &lt;/strong&gt;en &lt;strong&gt;Archivo -&amp;gt; Configuración de la Publicación -&amp;gt; &lt;/strong&gt;en la pestaña &lt;strong&gt;Flash -&amp;gt; Reproductor &lt;/strong&gt;y debe poner igualmente &lt;strong&gt;Flash Player 10.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Si utilizas versiones de Flash anteriores y no dispones de la clase &lt;strong&gt;Vector&lt;/strong&gt; puedes utilizar perfectamente en su lugar en la clase &lt;strong&gt;Array&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/07/que-queremos-que-haga-nuestro-escenario.html"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/08/el-codigo-del-escenario.html"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-2734116346719373607?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/2734116346719373607/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/08/la-bola-y-el-pong-como-icolisionador-e.html#comment-form' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/2734116346719373607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/2734116346719373607'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/08/la-bola-y-el-pong-como-icolisionador-e.html' title='La Bola y el Pong como IColisionador e IColisionable'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_lVd850Hzqko/SnrH8KGREAI/AAAAAAAAASY/gSVkqrqH1RM/s72-c/organizacion.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-9185006167176468366</id><published>2009-07-29T21:09:00.005+02:00</published><updated>2009-08-07T12:39:52.646+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>¿Qué queremos que haga nuestro Escenario?</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;. &lt;/p&gt;&lt;br /&gt;&lt;p style="font-size:x-small;"&gt;Y sí, lamentablemente y por falta de tiempo, tuve que prescindir de las imágenes para las cabeceras de cada capítulo.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Definición del  Escenario&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;En previsión de lo que va a ser un aumento exponencial de las clases de nuestro juego, deberíamos comenzar a organizarlas de manera estructurada para que nuestro proyecto Flash no se acabe convirtiendo en una amalgama de código intratable.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Todo lo relacionado con los escenarios parece tener la suficiente importancia como para poder considerarlo como un bloque separado de Pong y Bola. Así, en nuestro proyecto de FlashDevelop, dentro de la carpeta "pong", vamos a añadir una subcarpeta (&lt;strong&gt;un nuevo paquete&lt;/strong&gt;) a la que llamaremos &amp;quot;&lt;strong&gt;escenario&lt;/strong&gt;&amp;quot;. Y dentro de esta carpeta, creamos nuestra clase &lt;strong&gt;Escenario.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Antes de escribir código, vamos a pensar que representa esta clase Escenario y qué queremos hacer con ella. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ya nombramos &lt;strong&gt;el encapsulamiento &lt;/strong&gt;de la Programación Orientada a Objetos. Pero vamos a definirlo bien para que no nos perdamos.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Qué es el encapsulamiento?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;En POO, es el proceso por el que ocultamos la implementación interna de una clase (o concepto) y sólo podemos acceder y modificar su estado por métodos definidos por la propia clase. Es decir, sabemos como interactuar con él y lo que podemos esperar que haga, pero no sabemos &amp;quot;cómo funciona por dentro&amp;quot;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Lo que queremos es &lt;strong&gt;encapsular el Escenario&lt;/strong&gt; (bueno, el Escenario y muchas cosas más...) y que sea él quién se encargue de colocar los pongs, de controlar las colisiones y los marcadores y de otras muchas cosas que ya veremos. Y queremos que lo haga bien. Y queremos que desde cualquier otro sitio (la clase Main, por ahora), cuándo un objeto de la clase Escenario sea creado todo funcione correctamente. &lt;strong&gt;Creamos el Escenario y nos olvidamos.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Bien, pues pensemos qué tareas tendrá asignada nuestra maravillosa clase Escenario:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- Creación y colocación de los &lt;strong&gt;pongs, bolas y otros objetos&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- Control de &lt;strong&gt;colisiones&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- Control de &lt;strong&gt;puntuación&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Bueno, esto de momento.&lt;/p&gt;&lt;br /&gt;&lt;h6 style="font-size:small"&gt;Control de colisiones: Colisionadores y colisionables&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Hasta ahora, el control de colisiones había sido muy sencillo. Le decíamos a la &lt;strong&gt;bola&lt;/strong&gt; con que cosas podía colisionar y ella se encargaba de ver si chocaba o no. Esta información se le transmitíamos a la &lt;strong&gt;bola&lt;/strong&gt; en su creación. Pero hacerlo así tiene una consecuencia:&lt;strong&gt; el número de objetos con los que la bola podía colsionar no puede aumentar ni disminuir. &lt;/strong&gt;Y, aunque de momento esto no sucede, sucederá. Y en previsión de ello, en nuestro escenario vamos a definir dos tipos de objetos:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;Colisionadores&lt;/strong&gt;: aquellos objetos que pueden lanzarse a la búsqueda del choque de otros objetos. Ej: la bola, misiles lanzados desde los pongs, etc.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;Colisionables: &lt;/strong&gt;objetos que esperan ser embestidos por los objetos colisionadores. Ej: los pongs, los ítems que aparezcan en el escenario, etc.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Y ahora llega el gran problema: &lt;strong&gt;¿cómo le decimos a ActionScript 3 que un pong es un colisionable y una bola un colisionador? &lt;/strong&gt;Una solución factible podría ser definir dos clases: &lt;strong&gt;Colisionadores&lt;/strong&gt; y &lt;strong&gt;Colisionables&lt;/strong&gt;, y que cada una de las clases necesarias heredase de su respectiva clase padre. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Lamentablemente, esta solución no es viable debido a que &lt;strong&gt;ActionScript 3 no soporta la herencia múltiple&lt;/strong&gt; (heredar de varias clases simultáneamente) como por ejemplo C++. Sin embargo existe una solución parecida, que nos servirá perfectamente para la realización de nuestro propósito: &lt;strong&gt;las interfaces.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Qué es una interfaz?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;Simplificando mucho, una interfaz es un conjunto de métodos sin cuerpo (sin definición). Se dice que una clase &lt;strong&gt;implementa una interfaz&lt;/strong&gt; cuándo define todas sus funciones.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para concretizar un poco más, utilicemos un ejemplo. Por ejemplo, supongamos que tenemos una interfaz&lt;strong&gt; Volador&lt;/strong&gt;. Y esta interfaz define los siguientes métodos: despegar, volar y aterrizar.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Y ahora tenemos dos clases: &lt;strong&gt;Pájaro &lt;/strong&gt;y &lt;strong&gt;Avión. &lt;/strong&gt;Nuestro propósito es crear una clase &lt;strong&gt;Cielo &lt;/strong&gt;que contenga todo tipo de objetos voladores, pero a la clase &lt;strong&gt;Cielo &lt;/strong&gt;no le interesa saber si esos objetos son pájaros o aviones. Sólo que son voladores. Y quiere tratarlos a todos de la misma manera. Por ello tendrá un conjunto de objetos que implementan la interfaz &lt;strong&gt;Volador.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Así, &lt;strong&gt;Pájaro&lt;/strong&gt; tendrá sus propios métodos y atributos: comer, limpiarse, y además &lt;strong&gt;implementará &lt;/strong&gt;la interfaz &lt;strong&gt;Volador&lt;/strong&gt;, definiendo despegar, volar y aterrizar. Lo mismo sucederá con &lt;strong&gt;Avión&lt;/strong&gt;, que tendrá sus métodos y atributos propios, pero que también definirá despegar, volar y aterrizar.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Y es importante destacar que la &lt;strong&gt;implmentación de despegar&lt;/strong&gt; &lt;strong&gt;en&lt;/strong&gt; &lt;strong&gt;Pájaro es distinta que la de&lt;/strong&gt; &lt;strong&gt;Avión. &lt;/strong&gt;Un pájaro despega de manera distinta a cómo lo hace un avión. Sí. Pero los dos pueden &lt;strong&gt;despegar&lt;/strong&gt;, porque los dos son &lt;strong&gt;voladores. &lt;/strong&gt;En este punto es dónde radica la potencia de las interfaces.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;Definición de interfaces en ActionScript 3&lt;/h5&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;public interface INombre&lt;br /&gt;{&lt;br /&gt; function metodo1([parámetros1]):tipo_devol1;&lt;br /&gt; function metdoo2([parámetros2]):tipo_devol2;&lt;br /&gt;   ...&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Las interfaces no admiten atributos. Por una convención no escrita (o quizá sí) todas los nombres de nuestras interfaces comenzarán con "I", por aquello de &lt;strong&gt;I&lt;/strong&gt;nterfaz.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Pasemos, por fin, a escribir el código para nuestro escenario y vemos mejor, también, todo esto de las interfaces.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/07/fase-ii-objetivos.html"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/08/la-bola-y-el-pong-como-icolisionador-e.html"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-9185006167176468366?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/9185006167176468366/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/que-queremos-que-haga-nuestro-escenario.html#comment-form' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/9185006167176468366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/9185006167176468366'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/que-queremos-que-haga-nuestro-escenario.html' title='¿Qué queremos que haga nuestro Escenario?'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-8091089014955465948</id><published>2009-07-24T15:34:00.008+02:00</published><updated>2009-08-17T11:57:59.186+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>FASE II: Objetivos</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://lh4.ggpht.com/_lVd850Hzqko/SmmR2-KXzaI/AAAAAAAAAPE/SU25bL3IB24/FASE%20II%20objetivos.jpg" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h5&gt;Resultado al finalizar la Fase II&lt;/h5&gt;&lt;object width='650' height='450'&gt;&lt;embed src='http://img18.imageshack.us/img18/6131/pong11.swf' width='650' height='450'&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;h5&gt;Objetivos&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;- Creación de un &lt;strong&gt;escenario de fondo&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- Introducción de &lt;strong&gt;marcadores de puntuación&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;Arreglar algunos bugs&lt;/strong&gt;.&lt;br /&gt;&lt;p&gt;Para realizar estos cambios vamos a introducir un poco (pero muy poco) de Ingeniería del Software, estructurando el código de nuestro juego de manera que en el futuro nos resulte lo más sencillo posible introducir cambios.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En la Programación Orientada a Objetos son comunes los &lt;strong&gt;diagramas UML&lt;/strong&gt;. Esquemas gráficos en los que podemos entender de un vistazo como está estrucutrada nuestra aplicación. El diagrama UML (simplificado) que define los objetivos que nos hemos marcado en esta fase es:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://lh6.ggpht.com/_lVd850Hzqko/SmmR2rGStSI/AAAAAAAAAPA/MJirTcf2SJg/UMLpong1.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;No vamos a hacer un estudio en profundidad en UML, pero sí a definir las bases.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;Las clases se definen dentro de cajas.&lt;/strong&gt; Así, en el diagrama aparecen las clases que ya teníamos en el pasado (Main, Pong, Bola) y algunas nuevas (Escenario, CampoFutbol, Marcador).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;Las agregaciones se definen con un diamente conectado a las componentes de la agregación. &lt;/strong&gt;En Escenario, por ejemplo, tenemos un diamente al que se conectan Marcador, Pong y Bola. Esto significa que, entre otras cosas, el Escenario se compondrá de marcadores, pongs y bolas (sin especificar el número).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;Las generalizaciones (o herencia) se define con una flecha que va desde la clase más concreta a la clase más general. &lt;/strong&gt;En esencia, CampoFutbol es una clase hija de Escenario. Hereda todas sus características y además añadirá otras propias de un campo de fútbol.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Echando un vistazo al diagrama UML podemos sacar en claro que ahora será la clase Escenario la que se encargue de interactuar con bolas, pongs y marcadores, y la clase Main, simplmente, se encargará de crear un Escenario, sin preocuparse de cómo funciona por dentro. Está separación (&lt;strong&gt;o encapsulación&lt;/strong&gt;) nos será muy útil, por ejemplo, a la hora de meter un menú o una pantalla de inicio en nuestro juego. Bastará con que la clase Main llame al Menú, y el Menú al Escenario.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;CampoFutbol &lt;/strong&gt;será uno de los primeros escenarios que creemos para nuestro Pong.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/07/fase-i-conclusion.html"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/07/que-queremos-que-haga-nuestro-escenario.html"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-8091089014955465948?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/8091089014955465948/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/fase-ii-objetivos.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/8091089014955465948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/8091089014955465948'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/fase-ii-objetivos.html' title='FASE II: Objetivos'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_lVd850Hzqko/SmmR2-KXzaI/AAAAAAAAAPE/SU25bL3IB24/s72-c/FASE%20II%20objetivos.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-3442142779865416039</id><published>2009-07-21T11:31:00.004+02:00</published><updated>2009-07-21T11:54:36.692+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='programación'/><title type='text'>Integrar JavaScript y XML: un ejemplo sencillo, pero potente</title><content type='html'>&lt;p&gt;Vamos a mostrar, a través de un ejemplo, la sencilla manera en la que podemos integrar JavaScript y XML.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Supongamos que queremos incluir en nuestra web un apartado que contenga una lista de hipervínculos (o links). El problema es que esta lista va a variar continuamente y no queremos andar modificando el HTML cada vez.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;La solución&lt;/strong&gt; consiste en tener la lista de hipervínculos en un archivo XML externo y cargar la lista dinámicamente ayudados de JavaScript y su parser XML.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Nuestro archivo XML tiene el siguiente formato:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;&amp;lt;?xml version="1.0" encoding="iso-8859-1"?&amp;gt;&lt;br /&gt;&amp;lt;lista&amp;gt;&lt;br /&gt; &amp;lt;link&amp;gt;&lt;br /&gt;  &amp;lt;titulo&amp;gt;Google&amp;lt;/titulo&amp;gt;&lt;br /&gt;  &amp;lt;href&amp;gt;http://www.google.es&amp;lt;/href&amp;gt;&lt;br /&gt; &amp;lt;/link&amp;gt;&lt;br /&gt; &amp;lt;link&amp;gt;&lt;br /&gt;  &amp;lt;titulo&amp;gt;Metafísica de Costumbres&amp;lt;/titulo&amp;gt;&lt;br /&gt;  &amp;lt;href&amp;gt;http://metafisicadecostumbres.blogspot.com&amp;lt;/href&amp;gt;&lt;br /&gt; &amp;lt;/link&amp;gt;&lt;br /&gt; &amp;lt;link&amp;gt;&lt;br /&gt;  &amp;lt;titulo&amp;gt;Metafísica Informática&amp;lt;/titulo&amp;gt;&lt;br /&gt;  &amp;lt;href&amp;gt;http://metafisicainformatica.blogspot.com&amp;lt;/href&amp;gt;&lt;br /&gt; &amp;lt;/link&amp;gt;&lt;br /&gt;&amp;lt;/lista&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Un detalle importante es la cabecera XML. &lt;strong&gt;Necesitamos especificar encoding="iso-8859-1" para evitar problemas con las tildes y las ñ&lt;/strong&gt;. De no hacerlo, nos aparecerían símbolos raros en lugar de ñ y vocales acentuadas.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;El código JavaScript que necesitamos para resolver nuestro problema es el siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;div id="links"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;// En la variable div_links obtenemos el contenedor div con el id 'links'&lt;br /&gt;var div_links = document.getElementById('links');&lt;br /&gt;&lt;br /&gt;var xmlDoc = cargarXMLDoc('links.xml');&lt;br /&gt;if (xmlDoc != null)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; // Obtenemos la lista de links&lt;br /&gt; var links_tag = xmlDoc.getElementsByTagName("lista")[0].getElementsByTagName("link");&lt;br /&gt;&lt;br /&gt; for (var i = 0; i &amp;lt; links_tag.length; i++)&lt;br /&gt; {&lt;br /&gt;  // Obtenemos el título del link&lt;br /&gt;  var titulo = links_tag[i].getElementsByTagName("titulo")[0].childNodes[0].nodeValue;&lt;br /&gt;&lt;br /&gt;  // Obtenemos el hipervínculo del link&lt;br /&gt;  var href = links_tag[i].getElementsByTagName("href")[0].childNodes[0].nodeValue;&lt;br /&gt;&lt;br /&gt;  // Modificamos el contenido html del contenedor div&lt;br /&gt;  div_links.innerHTML += "&amp;lt;p&amp;gt;&amp;lt;a href=" + href + "&amp;gt;" + titulo + "&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;";&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function cargarXMLDoc(archivoXML) &lt;br /&gt;{&lt;br /&gt; var xmlDoc;&lt;br /&gt;&lt;br /&gt; if (window.XMLHttpRequest)&lt;br /&gt;   {&lt;br /&gt;    xmlDoc = new window.XMLHttpRequest();&lt;br /&gt;    xmlDoc.open("GET", archivoXML, false);&lt;br /&gt;    xmlDoc.send("");&lt;br /&gt;    return xmlDoc.responseXML;&lt;br /&gt;   }&lt;br /&gt; // para IE 5 y IE 6&lt;br /&gt; else if (ActiveXObject("Microsoft.XMLDOM"))&lt;br /&gt;   {&lt;br /&gt;    xmlDoc = new ActiveXObject("Microsoft.XMLDOM");&lt;br /&gt;    xmlDoc.async = false;&lt;br /&gt;    xmlDoc.load(archivoXML);&lt;br /&gt;    return xmlDoc;&lt;br /&gt;   }&lt;br /&gt; alert("Error cargando el documento.");&lt;br /&gt; return null;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Puedes encontrar información detallada sobre el parser XML (en inglés) &lt;a href="http://www.w3schools.com/XML/xml_parser.asp"&gt;aquí&lt;/a&gt;.&lt;/p&gt;&lt;/br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-3442142779865416039?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/3442142779865416039/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/integrar-javascript-y-xml-un-ejemplo.html#comment-form' title='10 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/3442142779865416039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/3442142779865416039'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/integrar-javascript-y-xml-un-ejemplo.html' title='Integrar JavaScript y XML: un ejemplo sencillo, pero potente'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-3900384838687805967</id><published>2009-07-20T11:43:00.002+02:00</published><updated>2010-11-20T21:44:22.150+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>Fase I: Conclusión</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes/"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Fase I: Conclusión&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Hemos llegado al final de la &lt;strong&gt;Fase I&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Puedes descargar &lt;a href="http://www.mediafire.com/?qmt4zmkafq1"&gt;aquí los archivos fuente del proyecto&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;También me gustaría utilizar este post a modo de feedback, y que en los comentarios dejarais vuestra opinión sobre lo que llevamos de guía. Sugerencias de mejora, si hay cosas poco (o mal) explicadas, fallos, e incluso vuestras propias versiones del juego.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;A partir de aquí, puedes continuar con &lt;a href="http://metafisicainformatica.blogspot.com/2009/07/fase-ii-objetivos.html"&gt;la Fase II de esta guía&lt;/a&gt;, en la que introduciremos una serie de mejoras.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/3-iii-deteccion-de-colisiones/"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/fase-ii-objetivos/"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-3900384838687805967?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/3900384838687805967/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/fase-i-conclusion.html#comment-form' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/3900384838687805967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/3900384838687805967'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/fase-i-conclusion.html' title='Fase I: Conclusión'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-560043953794344120</id><published>2009-07-15T20:26:00.038+02:00</published><updated>2010-11-20T21:32:07.256+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ActionScript 3'/><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><category scheme='http://www.blogger.com/atom/ns#' term='Nivel bajo'/><category scheme='http://www.blogger.com/atom/ns#' term='Flash'/><category scheme='http://www.blogger.com/atom/ns#' term='programación'/><title type='text'>Tutorial ActionScript 3 - Juego Pong - Principiantes</title><content type='html'>&lt;p&gt;&lt;img src="http://lh5.ggpht.com/_lVd850Hzqko/SliR2kO6xfI/AAAAAAAAAMU/rKmWLXNSB8E/ActionScriptTitulo.jpg" alt="ActionScript 3.0 - Guía para principiantes" height="160" width="700" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;Objetivo&lt;/h5&gt;&lt;br /&gt;&lt;p style="font-size: x-small;"&gt;Click en la ventana Flash para jugar. Controles: w, s, flecha arriba, flecha abajo.&lt;/p&gt;&lt;br /&gt;&lt;object height="420" width="620"&gt;&lt;embed src="http://img401.imageshack.us/img401/8894/pong1.swf" wmode="transparent" height="420" width="620"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;!--– google_ad_section_start –--&gt;&lt;br /&gt;&lt;h5&gt;¿De qué va la Guía?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;Bienvenidos al primer curso de esta Metafísica Informática: &lt;strong&gt;ActionScript 3.0 - Guía para principiantes&lt;/strong&gt;. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;ActionScript 3.0&lt;/strong&gt; es un poderosísimo lenguaje de script integrado en Flash y que permite realizar todo tipo de virguerías, desde películas de animación hasta juegos realmente complejos.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Cuál es el objetivo?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;El enfoque de la guía será doble:&lt;/p&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;&lt;strong&gt;Teórico&lt;/strong&gt;: Aprender y entender los pormenores de ActionScript 3.0 y los conceptos básicos (y no tan básicos) de la&lt;strong&gt; Programación Orientadas a Objetos.&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;strong&gt;Práctico:&lt;/strong&gt; Aplicar la teoría en un proyecto práctico: El desarrollo desde cero del clásico juego &lt;strong&gt;Pong&lt;/strong&gt;. Un juego, en esencia, bastante simple (en su desarrollo y juego), pero al que iremos añadiendo difrentes items y funcionalidades para darle mayor gracia.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;!--– google_ad_section_end –--&gt;&lt;br /&gt;&lt;h5&gt;¿Qué necesito saber para seguirla?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;No vendría mal  algo de experiencia con la parte gráfica de Flash: trabajo con capas, formas, colores, dregadados... Aunque si no es el caso, no importa demasiado. Cuándo utilicemos Flash para desarrollar la parte visual de nuestro Pong, se procurará explicar detalladamente todos los pasos.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Respecto a conocimientos de programación, lo básico: Qué es una variable, un bucle, una condición... &lt;/p&gt;&lt;br /&gt;&lt;p&gt;No es necesario ningún conocimiento sobre Programación Orientada a Objetos.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;Últimas indicaciones&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;No necesitas haber trabajado con la versión antigua de ActionScript, &lt;strong&gt;ActionScript 2&lt;/strong&gt;. Aunque comparten puntos comunes, ActionScript 2 y ActionScript 3 son lenguajes que trabajan de manera  distinta.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;La guía se va a realizar sobre &lt;strong&gt;Flash CS4&lt;/strong&gt;, aunque en principio puede seguirse con cualquier otra versión de Flash que admita ActionScript 3.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Algo importante que quiero recalcar es que esta guía está escrita de &lt;strong&gt;aprendiz a aprendiz&lt;/strong&gt;. Mi trabajo con ActionScript 3 y Flash es relativamente reciente, y cualquier comentario o corrección será bien recibido.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;Puedes &lt;a href="http://www.metafisicainformatica.com/2010/11/20/1-i-lo-primero-organizacion/"&gt;comenzar la guía de ActionScript 3&lt;/a&gt;, o echar un vistazo al índice que viene a continuación.&lt;br /&gt;&lt;h5&gt;Índice&lt;/h5&gt;&lt;br /&gt;&lt;div id="fase"&gt;&lt;a name="indice"&gt;FASE I: Pong 1.0&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div id="contenido"&gt;&lt;br /&gt;&lt;ol style="font-weight: bold;"&gt;&lt;br /&gt; &lt;li&gt;Primeros pasos&lt;br /&gt;&lt;ol&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/1-i-lo-primero-organizacion/"&gt;Lo primero, organización&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;Introducción. FlashDevelop: organizando nuestros archivos .as. Jerarquía de carpetas&lt;/div&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/1-ii-la-clase-del-documento/"&gt;La clase del Documento&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;¿Qué es la clase del Documento? Creando la clase del documento. Comentarios en AS3. Conectando nuestro Flash con Main.as.&lt;/div&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;ActionScript y la Programación Orientada a Objetos.&lt;br /&gt;&lt;ol style="list-style-type: upper-roman; font-weight: normal; font-size: small;"&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/2-i-concepto-de-clase-clases-en-actionscript-3/"&gt;Concepto de clase. Clases en ActionScript 3&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;Un mundo lleno de objetos... Concepto de Clase. ¿Qué es un atributo? ¿Qué es un método? ¿Cuál es la diferencia entre Clase y Objeto? Clases en ActionScript 3. Definición de paquetes. Definición de clases. Añadiendo atributos y métodos a nuestra clase Pong. Definición de variables. Visibilidad de atributos y funciones. Definición de atributos. Definición de funciones. El constructor de la clase. Creando un objeto de la clase Pong.&lt;/div&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/2-ii-herencia-en-actionscript-3/"&gt;Herencia en ActionScript 3&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;Diseño gráfico de nuestro pong. Enlazando la clase Pong con su representación gráfica. Añadiendo el pong a la escena. ¿Cuál es la idea básica tras la herencia?&lt;/div&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Finalizando nuestro Pong básico&lt;br /&gt;&lt;ol style="list-style-type: upper-roman; font-weight: normal; font-size: small;"&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/3-i-controlando-el-pong-desde-teclado/"&gt;Controlando el pong desde teclado&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;Colocando los pongs. ¿Cómo accedo a los métodos y atributos de un objeto? Controlando desde el teclado nuestros pongs. ¿Qué es un evento?&lt;/div&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/3-ii-movimiento-avanzado/"&gt;Movimiento avanzado&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;Control de velocidad realista. Acotando los límites del movimiento.&lt;/div&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/3-iii-deteccion-de-colisiones/"&gt;Detección de colisiones&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;La clase Bola. Detección de colisiones. ¿Cómo detecto colisiones en ActionScript?. Toques finales.&lt;/div&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li style="border-top: 1px #999 solid; margin-top: 15px; padding-top: 10px;"&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/fase-i-conclusion/"&gt;Conclusión y archivos fuente Pong 1.0 &lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div id="fase"&gt;FASE II: Pong 1.1 - Pong con escenarios y marcadores&lt;/div&gt;&lt;br /&gt;&lt;div id="contenido"&gt;&lt;br /&gt;&lt;ol style="font-weight: bold;"&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/fase-ii-objetivos/"&gt;Objetivos&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Creando el Escenario&lt;br /&gt;&lt;ol&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/%c2%bfque-queremos-que-haga-nuestro-escenario/"&gt;¿Qué queremos que haga nuestro escenario?&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;Definición del Escenario. ¿Qué es el encapsulamiento? Control de colisiones: Colisionadores y colisionables. ¿Qué es una interfaz? Definición de interfaces en ActionScript 3.&lt;/div&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/la-bola-y-el-pong-como-icolisionador-e-icolisionable/"&gt;La Bola y el Pong como IColisionador e IColisionable&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;Un pequeño problema... IColisionable e IColisionador. Bola como IColisionador. Pong como IColisionable.&lt;/div&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/el-codigo-del-escenario/"&gt;El código del Escenario&lt;/a&gt;&lt;br /&gt;&lt;div id="puntos"&gt;La nueva clase Main. El código del Escenario. &lt;em&gt;creaPongs&lt;/em&gt;, &lt;em&gt;creaBolas&lt;/em&gt;, &lt;em&gt;creaEscenario&lt;/em&gt;, &lt;em&gt;bucle&lt;/em&gt;. La bola que colisiona...&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/bug-i-la-bola-loca/"&gt;Bug (I): La Bola loca&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Añadiendo los marcadores&lt;br /&gt;&lt;ol&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/produciendo-y-detectando-los-goles/"&gt;Produciendo y detectando los goles&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;¡Gol! ¿Qué es un evento? Definición de GolEvent. ¿Qué es un atributo estático (static) o de clase? ¿Para qué sirve la palabra clave "super"? ¿Quién produce el GolEvent? ¿Quién detecta el GolEvent?&lt;/div&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/anadiendo-los-marcadores/"&gt;Añadiendo los marcadores&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;Nuestro marcador Flash. Código del marcador. Añadiendo los marcadores al Escenario&lt;/div&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/un-campo-de-futbol/"&gt;Un campo de fútbol&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;div id="puntos"&gt;La clase CampoFutbol&lt;/div&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li style="border-top: 1px #999 solid; margin-top: 15px; padding-top: 10px;"&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/conclusion-y-archivos-fuente-del-pong-1-1/"&gt;Conclusiones y archivos fuente del Pong 1.1&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-560043953794344120?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/560043953794344120/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html#comment-form' title='18 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/560043953794344120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/560043953794344120'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html' title='Tutorial ActionScript 3 - Juego Pong - Principiantes'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_lVd850Hzqko/SliR2kO6xfI/AAAAAAAAAMU/rKmWLXNSB8E/s72-c/ActionScriptTitulo.jpg' height='72' width='72'/><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-5067979188814480746</id><published>2009-07-15T19:55:00.011+02:00</published><updated>2010-11-20T21:43:08.626+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>3.III. Detección de colisiones</title><content type='html'>&lt;p style="font-size: x-small;"&gt;Esta entrada pertenece a &lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes/"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;img src="http://lh5.ggpht.com/_lVd850Hzqko/Sl385AzXq4I/AAAAAAAAANs/wwQOrC_pKe4/3_3Colisiones.jpg" /&gt;&lt;/p&gt;&lt;p&gt;Resultado al final del capítulo (Click sobre Flash para jugar; Controles: w, s, flecha arriba, flecha abajo):&lt;/p&gt;&lt;object height="400" width="550"&gt;&lt;br /&gt;&lt;embed src="http://img253.imageshack.us/img253/865/pong.swf" height="400" width="550"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;/object&gt;&lt;br /&gt;&lt;h6&gt;La clase Bola&lt;/h6&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Algo fundamental para que nuestro juego tenga algo de sentido es una bola que rebote de pong en pong. Breve recordatorio (y último detallado) de los pasos a seguir a la hora de crear una nueva clase que tenga una representación gráfica:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1) Creación de la clase ActionScript&lt;/strong&gt;: Con nuestro proyecto Pong abierto en&lt;strong&gt; FlashDevelop, click derecho en la carpeta pong -&amp;gt; Add... -&amp;gt; New Class... -&amp;gt; Bola.as&lt;/strong&gt;. Y para empezar, escribimos el siguiente código en el archivo:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class="actionscript"&gt;package mi.pong&lt;br /&gt;{&lt;br /&gt;import flash.display.MovieClip;&lt;br /&gt;import flash.display.Stage;&lt;br /&gt;import flash.events.Event;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* ...&lt;br /&gt;* @author ASL&lt;br /&gt;*/&lt;br /&gt;public class Bola extends MovieClip&lt;br /&gt;{&lt;br /&gt;private var vx:Number = 5;&lt;br /&gt;private var vy:Number = 0;&lt;br /&gt;private var max_velocidad:Number = 2;&lt;br /&gt;&lt;br /&gt;private var stageRef:Stage;&lt;br /&gt;&lt;br /&gt;public function Bola(stage:Stage)&lt;br /&gt;{&lt;br /&gt;stageRef = stage;&lt;br /&gt;&lt;br /&gt;addEventListener(Event.ENTER_FRAME, loop, false, 0, true);&lt;br /&gt;iniciaPosicion();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function iniciaPosicion()&lt;br /&gt;{&lt;br /&gt;x = stageRef.stageWidth / 2;&lt;br /&gt;y = stageRef.stageHeight / 2;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function loop(e:Event)&lt;br /&gt;{&lt;br /&gt;x += vx;&lt;br /&gt;y += vy;&lt;br /&gt;&lt;br /&gt;if (y &amp;lt; 0)&lt;br /&gt;{&lt;br /&gt;y = 0;&lt;br /&gt;vy = -vy;&lt;br /&gt;}&lt;br /&gt;else if (y &amp;gt; stageRef.stageHeight)&lt;br /&gt;{&lt;br /&gt;y = stageRef.stageHeight;&lt;br /&gt;vy = -vy;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (x &amp;lt; 0)&lt;br /&gt;{&lt;br /&gt;iniciaPosicion();&lt;br /&gt;vx = 5;&lt;br /&gt;vy = 0;&lt;br /&gt;}&lt;br /&gt;else if (x &amp;gt; stageRef.stageWidth)&lt;br /&gt;{&lt;br /&gt;iniciaPosicion();&lt;br /&gt;vx = -5;&lt;br /&gt;vy = 0;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Espero que no resulte demasiado extraño al lector el código escrito para la clase Bola. Tiene bastantes puntos comunes con el código de la clase Pong. Al igual que los pongs, la bola también tiene una velocidad, aunque esta vez formada por dos componentes (ya que puede moverse hacia todas partes), la del eje x "&lt;strong&gt;vx&lt;/strong&gt;" y la del eje y "&lt;strong&gt;vy&lt;/strong&gt;". También una velocidad máxima "&lt;strong&gt;max_velocidad&lt;/strong&gt;", que utilizaremos en el futuro para "calibrar" su velocidad.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;El último bloque de la función loop (que es la función que se ejecuta cada vez que comienza un nuevo frame) controla que la bola no salga de los límites del eje x de la película, devolviendo a ésta al centro del campo.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2) Creación del símbolo Flash: &lt;/strong&gt;En la ventana Flash -&amp;gt; Insertar -&amp;gt; Nuevo símbolo... y utilizamos las siguientes opciones:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://lh3.ggpht.com/_lVd850Hzqko/Sl4A8BPYztI/AAAAAAAAANw/jZu1VuYFxLQ/s400/Bolapropiedades.jpg" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;y para el símbolo dibujamos un simple círculo blanco (ya habrá tiempo para mejorar la apariencia de nuestro juego) con las propiedades de la imagen:&lt;/p&gt;&lt;p&gt;&lt;img src="http://lh3.ggpht.com/_lVd850Hzqko/Sl4Be6fdCKI/AAAAAAAAAN0/2UuSBJ8Ixqo/s400/bolasimbolo.jpg" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Para añadir nuestra bola al juego añadimos lo siguiente en la función Main:&lt;/p&gt;&lt;pre class="actionscript"&gt;...&lt;br /&gt;var bola:Bola = new Bola(stage);&lt;br /&gt;addChild(bola);&lt;br /&gt;...&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Empiezo a ir un poco rápido porque entiendo que después de todo el rollo soltado en capítulos anteriores, el lector entiende más o menos todo lo que estamos haciendo. Si queda cualquier duda, siempre puedes preguntarla en los comentarios.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Bien, si ejecutamos nuestro Flash veremos nuestra&lt;strong&gt; bola &lt;/strong&gt;moviéndose de un lado otro sin mucho sentido. Ahora, lo que necesitamos, es que colisione con los pongs.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h6&gt;Detección de colisiones&lt;/h6&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;En el problema de las &lt;strong&gt;colisiones entre objetos&lt;/strong&gt; es uno de los problemas tradicionales en la programación de cualquier tipo de videojuego. Son muchas las maneras en las que puede ser abordado y resuelto, y en esta guía he optado por una en particular, que para este caso y desde mi punto de vista, es la más sencillo y adecuado.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;La técnica consiste en definir un área, dentro del objeto, que sea "capaz de colisionar". Es decir, que aunque gráficamente dos objetos estén superpuestos, sólo se produzca colisión si sus áreas de colisión están superpuestas. &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Las colisiones, de manera gráfica (la zona más oscurá representa la zona de colisión de cada objeto):&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://lh4.ggpht.com/_lVd850Hzqko/Sl4GtvPPVZI/AAAAAAAAAN4/jKyt85ghfBY/limitescolision.jpg" height="278" width="500" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;En la primera, obviamente, no hay colisión. En la segunda, la bola está sobre el gráfico que representa el pong, pero no sobre su zona de colisión. En la última, sendas zonas de colisiones se superponen, produciéndose el choque.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;¿Y cómo vamos a representar esta zona de colisiones? Pues, saliéndonos un poco (muy poco, ¿eh?) de aquello que dijimos de que "todo aquello que pueda hacerse desde ActionScript será hecho desde ActionScript". &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Nuestra zona de colisiones va a ser &lt;strong&gt;un nuevo símbolo&lt;/strong&gt; al que vamos a llamar "&lt;strong&gt;HitBox&lt;/strong&gt;" cuyo único contenido va a ser un cuadrado sin borde y de un color semitransparente. Este símbolo &lt;strong&gt;no va a estar asociado a ninguna clase ActionScript.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://lh4.ggpht.com/_lVd850Hzqko/Sl4JR28GVUI/AAAAAAAAAN8/t_WIqN-nu9g/hitBox.jpg" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Ahora necesitamos definar la zona de colisión en los símbolos para la bola y el pong. &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1) En la &lt;strong&gt;ventana de Biblioteca (Ctrl+L), click derecho en el símbolo Pong -&amp;gt; Edición...&lt;/strong&gt; Crea una nueva capa llamada hitBox y selecciónala. Ahora arrastra desde la biblioteca un símbolo "HitBox" hasta el centro del Pong. &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;2) Con la &lt;strong&gt;herramienta de transformación libre (Q)&lt;/strong&gt; ajustamos el cuadrado a la zona de colisión buscada.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;3) &lt;strong&gt;Nombramos a la instancia del símbolo como "hitBox"&lt;/strong&gt;. Este paso es muy importante, porque será el que nos dé acceso a la zona de colisión desde el código ActionScript.&lt;/p&gt;&lt;p&gt;&lt;img src="http://lh6.ggpht.com/_lVd850Hzqko/Sl4OTKoDSkI/AAAAAAAAAOA/Sbmivu6_9O0/hitBoxprocess.jpg" style="border: 1px solid rgb(0, 0, 0);" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Seguimos el mismo proceso para la bola.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h5&gt;¿Cómo detecto colisiones en ActionScript?&lt;/h5&gt;&lt;pre class="actionscript"&gt;object1.hitTestObject(object2)&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Que devuelve true si los objetos object1 y object2 han colisionado.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Vamos a pensar un poco la lógica que queremos detras de nuestras colisiones: De momento, sólo tenemos un objeto que puede colisionar: &lt;strong&gt;la bola&lt;/strong&gt;, y dos objetos sobre los que colisionar, &lt;strong&gt;los pongs.&lt;/strong&gt; Entonces, sólo necesitamos que la bola sepa sobre que objetos puede colisionar. Esto lo vamos a conseguir pasándole un &lt;strong&gt;Array &lt;/strong&gt;(una "lista") con ambos pongs, en la función Main, por supuesto. Nuestra función tendrá este aspecto:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class="actionscript"&gt;  public function Main()&lt;br /&gt;{&lt;br /&gt;key = new KeyObject(stage);&lt;br /&gt;var colisionadores:Array = new Array();&lt;br /&gt;&lt;br /&gt;var miPong1:Pong = new Pong(stage, 0, key);&lt;br /&gt;addChild(miPong1);&lt;br /&gt;colisionadores.push(miPong1);&lt;br /&gt;       &lt;br /&gt;var miPong2:Pong = new Pong(stage, 1, key);&lt;br /&gt;addChild(miPong2);&lt;br /&gt;colisionadores.push(miPong2);&lt;br /&gt;&lt;br /&gt;var bola:Bola = new Bola(stage, colisionadores);&lt;br /&gt;addChild(bola);&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;- &lt;strong&gt;colisionadores.push(miPong1);&lt;/strong&gt; Con la función push añadimos un elemento al Array.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;En verdad, estamos repitiendo código, y podemos agrupar la creación de pongs en un bucle:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class="actionscript"&gt;  public function Main()&lt;br /&gt;{&lt;br /&gt;key = new KeyObject(stage);&lt;br /&gt;var colisionadores:Array = new Array();&lt;br /&gt;&lt;br /&gt;for (var i:uint; i &amp;lt; 2; i++)&lt;br /&gt;{&lt;br /&gt;var miPong:Pong = new Pong(stage, i, key);&lt;br /&gt;addChild(miPong);&lt;br /&gt;colisionadores.push(miPong);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var bola:Bola = new Bola(stage, colisionadores);&lt;br /&gt;addChild(bola);&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Ahora debemos modificar la clase Bola para que procesa las colisiones. Añadimos un atributo para guardar la lista de colisionadores:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class="actionscript"&gt;private var colisionadores:Array;&lt;br /&gt;...&lt;br /&gt;public function Bola(stage:Stage, lista_colisiones:Array)&lt;br /&gt;{&lt;br /&gt;stageRef = stage;&lt;br /&gt;colisionadores = lista_colisiones;&lt;br /&gt;addEventListener(Event.ENTER_FRAME, loop, false, 0, true);&lt;br /&gt;iniciaPosicion();&lt;br /&gt;}&lt;br /&gt;...&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Y el procesamiento de colisiones en la función loop:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class="actionscript"&gt;public function loop(e:Event)&lt;br /&gt;{&lt;br /&gt;for (var i:uint = 0; i &amp;lt; colisionadores.length; i++)&lt;br /&gt;{&lt;br /&gt;if (hitBox.hitTestObject(colisionadores[i].hitBox))&lt;br /&gt;{&lt;br /&gt; vx = -vx;&lt;br /&gt; vy = ((y - colisionadores[i].y) / colisionadores[i].width*2) * max_velocidad;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;    &lt;br /&gt;        x += vx;&lt;br /&gt;y += vy;&lt;br /&gt;        ...&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Y aquí entra en juego el nombre de instancia "hitBox", que fue cómo nombramos a nuestro cuadradito semitransparente. Nombrando la instancia como hitBox conseguimos tener un nuevo atributo en la clase correspondiente que representa nuestra zona de colisión. Por eso realizamos el test sobre ellas.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;En &lt;strong&gt;hitBox.hitTestObject(colisionadores[i].hitBox)&lt;/strong&gt; ,el primer "hitBox" está haciendo referencia a la zona de colisión de la bola, y el segundo, al del colisionador, en este caso, cualquiera de los pongs.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Si se produce una colisión, cambiamos las componentes de velocidad de la bola.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h6&gt;Toques finales&lt;/h6&gt;&lt;p&gt;Ya podríamos ejecutar nuestro juego pong y sería completamente funcional. Pero vamos a añadir un par de detalles para darle algo de vistosidad:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1) &lt;/strong&gt;Seleccionar un color totalmente transparante (con Alfa a 0%) para el símbolo HitBox y evitar que aparezca en pantalla.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2) &lt;/strong&gt;Elegir un color verde para el fondo de la película (puedes hacerlo desde &lt;strong&gt;Propiedades del Documento).&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3) &lt;/strong&gt;Ajustar la velocidad de la película a 30 FPS (con el documento seleccionado, en la ventana de propiedades, o en la línea de tiempo). Esta velocidad dará una mejor sensación de fluidez.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4) &lt;/strong&gt;Y cómo extra, he añadido en una nueva capa una sombra para el Pong, copiando la forma del pong y desplazándola ligeramente, borrando el contorno y dándole un color grisáceo semitransparente.&lt;/p&gt;&lt;p&gt;Hasta aquí el desarrollo de nuestro &lt;strong&gt;Pong Básico. &lt;/strong&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;En el&lt;a href="http://www.metafisicainformatica.com/2010/11/20/fase-i-conclusion/"&gt; siguiente capítulo encontrarás los archivos fuente del proyecto&lt;/a&gt;.&lt;/p&gt;&lt;table align="center" border="0" width="200"&gt;&lt;br /&gt;&lt;tbody&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;  &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/3-ii-movimiento-avanzado/"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/fase-i-conclusion/"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-5067979188814480746?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/5067979188814480746/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/3iii-deteccion-de-colisiones.html#comment-form' title='8 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/5067979188814480746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/5067979188814480746'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/3iii-deteccion-de-colisiones.html' title='3.III. Detección de colisiones'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_lVd850Hzqko/Sl385AzXq4I/AAAAAAAAANs/wwQOrC_pKe4/s72-c/3_3Colisiones.jpg' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-7675731134152267118</id><published>2009-07-14T20:20:00.002+02:00</published><updated>2010-11-20T21:40:48.766+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>3. II. Movimiento avanzado</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes/"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://lh6.ggpht.com/_lVd850Hzqko/SlzG-L_hjBI/AAAAAAAAANo/3iOI5mM_rLA/3_2MovimientoAvaznado.jpg"/&gt;&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Control de velocidad realista&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Vamos a realizar un control de velocidad basado en términos de &lt;strong&gt;aceleración&lt;/strong&gt;. Es decir, cada vez que pulsemos una tecla, vamos a &lt;strong&gt;propulsar &lt;/strong&gt;nuestro pong, sumándole una aceleración la velocidad que ya tuviere. Además, para que la cosa no se vaya de madre y el pong se vuelva medio loco, vamos a simular fricción con el aire, que frenará nuestro pong. Nuestras variables para el control de velocidad serán:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  // Control de velocidad&lt;br /&gt;  private var vy:Number = 0; // Velocidad actual&lt;br /&gt;  private var acc:Number = 1; // Aceleración&lt;br /&gt;  private var friccion:Number = 0.95; // Fricción con el aire&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Inicializar los atributos en su declaración surge el mismo efecto que si los iniciaramos en el constructor de clase.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para hacer uso de estas nuevos atributos, modificamos la función &lt;strong&gt;mover&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function mover(e:Event)&lt;br /&gt;  {&lt;br /&gt;   if (key.isDown(upKey))&lt;br /&gt;   {&lt;br /&gt;    vy -= acc;&lt;br /&gt;   }&lt;br /&gt;   else if (key.isDown(downKey))&lt;br /&gt;   {&lt;br /&gt;    vy += acc;&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   y += vy;&lt;br /&gt;   vy *= friccion;&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Si probamos la película, veremos que nuestros pongs ahora se desplazan de manera más suave y realista.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Acotando los límites del movimiento&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Aún así, seguimos teniendo un problema importante: Cuándo el pong llega a alguno de los límites de película, desaparece. Podemos controlar esto de manera sencilla, añadiendo el siguiente bloque al final de la función &lt;strong&gt;mover&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;   if (y &lt; 0)&lt;br /&gt;   {&lt;br /&gt;    y = 0;&lt;br /&gt;    vy = -vy;&lt;br /&gt;   }&lt;br /&gt;   else if (y &gt; stageRef.stageHeight)&lt;br /&gt;   {&lt;br /&gt;    y = stageRef.stageHeight;&lt;br /&gt;    vy = -vy;&lt;br /&gt;   }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Con este trozo de código, controlamos que la posición "y" de nuestro pong (su punto central) no salga de los límites de la película (Recuerda que &lt;strong&gt;stageRef&lt;/strong&gt; era una referencia al escenario principal de la película). Si el pong intenta salir de los límites, restablecemos su posición al límite más cercano y revertimos la dirección de su velocidad, consiguiendo un efecto de rebote bastante resultón.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/3-i-controlando-el-pong-desde-teclado/"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/3-iii-deteccion-de-colisiones/"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-7675731134152267118?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/7675731134152267118/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/3-ii-movimiento-avanzado.html#comment-form' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/7675731134152267118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/7675731134152267118'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/3-ii-movimiento-avanzado.html' title='3. II. Movimiento avanzado'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_lVd850Hzqko/SlzG-L_hjBI/AAAAAAAAANo/3iOI5mM_rLA/s72-c/3_2MovimientoAvaznado.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-7580443856421240366</id><published>2009-07-14T19:25:00.009+02:00</published><updated>2010-11-20T21:39:53.945+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>3.I. Controlando el pong desde teclado</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes/"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://lh5.ggpht.com/_lVd850Hzqko/Sln4gP5vV3I/AAAAAAAAANc/9UEF6-OBMZw/3_1MovimientoPong.jpg" alt="Controlando desde el teclado nuestro pong" width="600" height="100" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Dejamos atrás la POO y nos centramos en el desarrollo puro y duro de nuestro juego Flash.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Colocando los pongs&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Para que nuestro juego tenga algo de sentido, necesitamos al menos dos pongs colocados en el campo de juego, uno al lado izquierdo y el oponente en el lado derecho. Para controlar su posición en el escenario vamos a utilizar los atributos &amp;quot;&lt;strong&gt;x&lt;/strong&gt;&amp;quot; e &amp;quot;&lt;strong&gt;y&lt;/strong&gt;&amp;quot; que nuestra clase Pong ha heredado de MovieClip.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Cómo accedo a los métodos y atributos de un objeto?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;Utilizamos el punto &amp;quot;.&amp;quot; para acceder a los miembros de un objeto.&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;&lt;br /&gt;// Acceso a atributos&lt;br /&gt;miObjeto.atributo = valorAtributo;&lt;br /&gt;// Acceso a métodos&lt;br /&gt;miObjeto.cualquierMetodo(parametros);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Para simplificar la colocación de los pongs en el campo de juego, vamos a hacer a nuestra clase Pong "inteligente", añadiéndole un atributo "num_jugador" que contendrá el número jugador. Éste indicará si el jugador debe situarse a la izquierda (jugador 0) o a la derecha (jugador 1). Añadimos a la clase Pong el atributo:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;&lt;br /&gt;...&lt;br /&gt;private var num_jugador:uint;&lt;br /&gt;...&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;uint&lt;/strong&gt; es el tipo de variable que engloba todos los números &gt;= 0.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para el cálculo de las coordenadas que ha de ocupar el pong, necesitamos saber el tamaño del escenario. ¿Quién tiene esta información? La clase Main, por supuesto. La clase Main ha heredado de MovieClip un atributo &amp;quot;&lt;strong&gt;stage&lt;/strong&gt;&amp;quot; de la clase &amp;quot;&lt;strong&gt;Stage&amp;quot; &lt;/strong&gt;que contiene las dimensiones del escenario.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://lh5.ggpht.com/_lVd850Hzqko/SloDPt205wI/AAAAAAAAANk/wDGZ1w1BL8w/s400/stage.jpg" alt="stage" width="400" height="331" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;De hecho, estos valores coincidirán con los valores que especifices en las &lt;strong&gt;Propiedades del Documento &lt;/strong&gt;(&lt;strong&gt;click derecho sobre el fondo  -&amp;gt; Propiedades del Documento...&lt;/strong&gt;)&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://lh3.ggpht.com/_lVd850Hzqko/SloDPkDy_lI/AAAAAAAAANg/y1UThw7NOxk/PropDocumento.jpg" alt="Propiedades del documento" width="614" height="277" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;La ventaja de especificar la colocación de los pongs respecto a las dimensiones del escenario es que, si éstas cambian, todo permanecerá colocado en su sitio. Porque en el futuro será útil, vamos a añadir a la clase Pong un atributo &amp;quot;&lt;strong&gt;stageRef&amp;quot; &lt;/strong&gt;de tipo &amp;quot;&lt;strong&gt;Stage&amp;quot;&lt;/strong&gt; que contendrá los datos del escenario. Recuerda que has de importar Stage para evitar fallos en la compilación (import flash.display.Stage;):&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;&lt;br /&gt;...&lt;br /&gt;private var num_jugador:uint;&lt;br /&gt;private var stageRef:Stage;&lt;br /&gt;...&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Vamos a hacer saber a la clase Pong de su número de jugador y del escenario a través del constructor de la clase, añadiéndole parámetros. Borramos el viejo constructor y añadimos el siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function Pong(stage:Stage, n_jugador:uint) &lt;br /&gt;  {&lt;br /&gt;   this.stageRef = stage;&lt;br /&gt;   this.num_jugador = n_jugador;&lt;br /&gt;   iniciaPosicion();&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;stage:Stage, n_jugador:uint&lt;/strong&gt; son los parámetros del constructor, los cuáles enviaremos cuándo creemos el objeto con &lt;strong&gt;new.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;this: &lt;/strong&gt;Es una referencia al objeto actual. &lt;strong&gt;this&lt;/strong&gt; da acceso a todos los miembros del objeto actual. En este caso, a los atributos stageRef y num_jugador de la clase Pong.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Cómo ves, tras asignar los atributos llamamos a la función &lt;strong&gt;iniciaPosicion()&lt;/strong&gt; que tiene la siguiente especificación:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function iniciaPosicion()&lt;br /&gt;  {&lt;br /&gt;   var proporcion:uint = 20;&lt;br /&gt;   this.y = stageRef.stageHeight / 2;&lt;br /&gt;   if (num_jugador == 0)&lt;br /&gt;   {&lt;br /&gt;    this.x = stageRef.stageWidth / proporcion;&lt;br /&gt;    this.scaleX = -1;&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;    this.x = stageRef.stageWidth - stageRef.stageWidth / proporcion; &lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Hemos utilizado algo de matemática sencilla para colocar los pongs en su lugar correspondiente. Con "&lt;strong&gt;this.scaleX = -1;&lt;/strong&gt;",  obtenemos la imagen espejo de nuestro pong, cosiguiendo así su orientación correcta en la pantalla. (Puedes probar ejecutar el Flash con &amp;quot;this.scaleX = -1&amp;quot; añadido y sin añadir para entender a lo que me refiero.).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;La clase Pong queda tal que así:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package mi.pong &lt;br /&gt;{&lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; import flash.display.Stage;&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt; * ...&lt;br /&gt; * @author ASL&lt;br /&gt; */&lt;br /&gt; &lt;br /&gt; public class Pong extends MovieClip &lt;br /&gt; {&lt;br /&gt;  private var vy:N&lt;br /&gt;  private var num_jugador:uint;&lt;br /&gt;  private var stageRef:Stage;&lt;br /&gt;  &lt;br /&gt;  public function Pong(stage:Stage, n_jugador:uint) {&lt;br /&gt;   this.stageRef = stage;&lt;br /&gt;   this.num_jugador = n_jugador;&lt;br /&gt;   iniciaPosicion();&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public function iniciaPosicion()&lt;br /&gt;  {&lt;br /&gt;   var proporcion:uint = 20;&lt;br /&gt;   this.y = stageRef.stageHeight / 2;&lt;br /&gt;   if (num_jugador == 0)&lt;br /&gt;   {&lt;br /&gt;    this.x = stageRef.stageWidth / proporcion;&lt;br /&gt;    this.scaleX = -1;&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;    this.x = stageRef.stageWidth - stageRef.stageWidth / proporcion; &lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Y ya sólo queda añdir nuestros pongs desde la clase Main:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package&lt;br /&gt;{&lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; import mi.pong.Pong;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public class Main extends MovieClip&lt;br /&gt; {&lt;br /&gt;  &lt;br /&gt;  public function Main() &lt;br /&gt;  {&lt;br /&gt;   var miPong1:Pong = new Pong(stage, 0);&lt;br /&gt;   addChild(miPong1);&lt;br /&gt;   &lt;br /&gt;   var miPong2:Pong = new Pong(stage, 1);&lt;br /&gt;   addChild(miPong2);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Recuerda que &lt;strong&gt;stage&lt;/strong&gt; es un atributo dado por la clase Main (quién lo ha heredado de MovieClip) que representa el escenario del documento. Hubiera surtido el mismo efecto si hubiéramos utilizado "&lt;strong&gt;this.stage&lt;/strong&gt;".&lt;/p&gt;&lt;br /&gt;&lt;h6 style="font-size:medium;"&gt;Controlando desde el teclado nuestros pongs&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Para el control de teclado vamos a utilizar una clase ya creada de un señor que sabe bastante de ActionScript, &lt;a href="http://www.senocular.com" target="_blank"&gt;Senocular&lt;/a&gt;. Puedes descargar la clase &lt;a href="http://www.senocular.com/flash/actionscript.php?file=ActionScript_3.0/com/senocular/utils/KeyObject.as" target="_blank"&gt;aquí&lt;/a&gt;. Deberías crear la jerarquía de carpetas &lt;strong&gt;com -&amp;gt; senocular -&amp;gt; utils&lt;/strong&gt; y ahí crear el archivo KeyObject.as con el contenido del link.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;KeyObject es una clase que nos va a permitir saber si una tecla cualquiera está pulsada en el teclado, y con esta información, mover el pong hacia un lado o hacia otro. Como tenemos un único teclado, sólo necsitamos &lt;strong&gt;un KeyObject para todo el juego, así que lo crearemos en la clase Main&lt;/strong&gt;. Y además, ambos Pong necesitan saber de ése teclado, con lo cual &lt;strong&gt;añadiremos un parámetro más en el constructor de la clase Pong:&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;...&lt;br /&gt;&lt;br /&gt; public class Main extends MovieClip&lt;br /&gt; {&lt;br /&gt;  private var key:KeyObject;&lt;br /&gt;  &lt;br /&gt;  public function Main() &lt;br /&gt;  {&lt;br /&gt;   key = new KeyObject(stage);&lt;br /&gt;   &lt;br /&gt;   var miPong1:Pong = new Pong(stage, 0, key);&lt;br /&gt;   addChild(miPong1);&lt;br /&gt;   &lt;br /&gt;   var miPong2:Pong = new Pong(stage, 1, key);&lt;br /&gt;   addChild(miPong2);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;...&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;key = new KeyObject(stage)&lt;/strong&gt;: El único parámetro que necesita KeyObject es el escenario principal.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ahora hay que adaptar la clase Pong a las nuevas necesidades. Necesitamos un atributo &lt;strong&gt;key &lt;/strong&gt;para guardar la información de teclado que nos pasan desde el constructor, y dos atributos más: &lt;strong&gt;upKey&lt;/strong&gt; y &lt;strong&gt;downKey&lt;/strong&gt; que especificarán las teclas concretas que mueven nuestro pong.&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;...&lt;br /&gt;  //Control de teclado&lt;br /&gt;  private var key:KeyObject;&lt;br /&gt;  private var upKey:uint;&lt;br /&gt;  private var downKey:uint;&lt;br /&gt;...&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Y necesitamos la inicialización de todas estas variables:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt; ...&lt;br /&gt;  public function Pong(stage:Stage, n_jugador:uint, key:KeyObject) &lt;br /&gt;  {&lt;br /&gt;   this.stageRef = stage;&lt;br /&gt;   this.num_jugador = n_jugador;&lt;br /&gt;   this.key = key;&lt;br /&gt;   &lt;br /&gt;   iniciaPosicion();&lt;br /&gt;   iniciaTeclado();&lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt; ...&lt;/pre&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;&lt;br /&gt;  private function iniciaTeclado()&lt;br /&gt;  {&lt;br /&gt;   if (num_jugador == 1)&lt;br /&gt;   {&lt;br /&gt;    upKey = Keyboard.UP;&lt;br /&gt;    downKey = Keyboard.DOWN;&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;    upKey = 87; // W&lt;br /&gt;    downKey = 83; // S&lt;br /&gt;   }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- Observa que declaramos iniciaTeclado() como &lt;strong&gt;private&lt;/strong&gt; porque no queremos que nadie pueda acceder a ella desde fuera de la clase.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;upKey = Keyboard.UP; downKey = Keyboard.DOWN&lt;/strong&gt;: Para el caso del jugador uno, asignamos a sus teclas las constantes para la tecla UP y DOWN que contiene Keyboard (import flash.ui.Keyboard;)&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- En el caso del &lt;strong&gt;jugador 0 &lt;/strong&gt;asignamos las constantes a mano porque, desgraciadamente y por algún motivo que desconozco, las constantes para las letras del telcado sólo existen en el AIR runtime, que no es nuestro caso. Puedes ver los códigos de teclas &lt;a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/ui/Keyboard.html" target="_blank"&gt;aquí&lt;/a&gt;. Ten cuidado también cuándo previsualices el juego desde Flash, porque estas teclas no te funcionarán. Para que lo hagan, ejecuta el archivo .swf que se crea en el mismo director que tu archivo .fla cada vez que previsualizas la película.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ahora, lo que necesitamos es procesar las pulsaciones de estas teclas. Para ello vamos a utilizar la función &lt;strong&gt;mover&lt;/strong&gt; y el atributo &lt;strong&gt;vy &lt;/strong&gt;que declaramos hace tiempo:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;  public function mover(e:Event)&lt;br /&gt;  {&lt;br /&gt;   if (key.isDown(upKey))&lt;br /&gt;   {&lt;br /&gt;    vy -= 1;&lt;br /&gt;   }&lt;br /&gt;   else if (key.isDown(downKey))&lt;br /&gt;   {&lt;br /&gt;    vy += 1;&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   this.y += vy;&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;mover(e:Event)&lt;/strong&gt;: ahora explicaremos porque la función mover necesita este parámetro &amp;quot;e&amp;quot;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;key.isDown(una_tecla)&lt;/strong&gt;: esta función nos devuelve un booleano indicando si una_tecla está pulsada o no.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;this.y += vy&lt;/strong&gt; : añadimos a la posición "y" del pong la velocidad, que ha sido modificada con las pulsaciones de teclado.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Todo está ya conectado, pero nos falta un último detalle: &lt;strong&gt;¿cuándo se ejecuta la función mover?&lt;/strong&gt; Para resolver este problema, añadimos la siguiente instrucción al constructor de la clase Pong:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;...&lt;br /&gt;addEventListener(Event.ENTER_FRAME, mover, false, 0, true);&lt;br /&gt;...&lt;/pre&gt;&lt;br /&gt;&lt;p&gt; - &lt;strong&gt;addEventListener (Event.ENTER_FRAME, mover, false, 0, true) &lt;/strong&gt;: Con esta función le estamos diciendo a la clase Pong que cada vez que se produzca el evento "Event.ENTER_FRAME", ejecute la función "mover". El resto de parámetros de momento no tienen relevancia.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Qué es un evento?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;En ActionScript, un evento es &lt;strong&gt;algo que sucede y que podemos detectar, para realizar las acciones oportunas&lt;/strong&gt;. Los eventos pueden ser de múltiples tipos: &lt;strong&gt;eventos de teclado&lt;/strong&gt; (se pulsó una tecla), &lt;strong&gt;eventos de ratón&lt;/strong&gt; (se pulsó el botón derecho), &lt;strong&gt;eventos de película&lt;/strong&gt; (se entró en un nuevo frame), etc.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En este caso, nos interesa que cada vez que nuestra película Flash entre en un nuevo Frame (fotograma) se actualicen las posiciones del pong. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;La función&lt;strong&gt; mover(e:Event) &lt;/strong&gt;necesita el parámetro &amp;quot;e&amp;quot; de tipo Event porque será ahí dónde se guarda el evento que se produjo. Sin este parámetro, no lograremos compilar.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Después de tanto trasiego, la clase Pong queda así:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package mi.pong &lt;br /&gt;{&lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; import flash.display.Stage;&lt;br /&gt; import com.senocular.utils.KeyObject;&lt;br /&gt; import flash.ui.Keyboard;&lt;br /&gt; import flash.events.Event;&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt; * ...&lt;br /&gt; * @author ASL&lt;br /&gt; */&lt;br /&gt; &lt;br /&gt; public class Pong extends MovieClip &lt;br /&gt; {&lt;br /&gt;  private var vy:Number;&lt;br /&gt;  &lt;br /&gt;  private var num_jugador:uint;&lt;br /&gt;  private var stageRef:Stage;&lt;br /&gt;  &lt;br /&gt;  //Control de teclado&lt;br /&gt;  private var key:KeyObject;&lt;br /&gt;  private var upKey:uint;&lt;br /&gt;  private var downKey:uint;&lt;br /&gt;  &lt;br /&gt;  public function Pong(stage:Stage, n_jugador:uint, key:KeyObject) &lt;br /&gt;  {&lt;br /&gt;   this.stageRef = stage;&lt;br /&gt;   this.num_jugador = n_jugador;&lt;br /&gt;   this.key = key;&lt;br /&gt;   &lt;br /&gt;   iniciaPosicion();&lt;br /&gt;   iniciaTeclado();&lt;br /&gt;   &lt;br /&gt;   &lt;br /&gt;   addEventListener(Event.ENTER_FRAME, mover, false, 0, true);&lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public function iniciaPosicion():void&lt;br /&gt;  {&lt;br /&gt;   var proporcion:uint = 20;&lt;br /&gt;   this.y = stageRef.stageHeight / 2;&lt;br /&gt;   if (num_jugador == 0)&lt;br /&gt;   {&lt;br /&gt;    this.x = stageRef.stageWidth / proporcion;&lt;br /&gt;    this.scaleX = -1;&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;    this.x = stageRef.stageWidth - stageRef.stageWidth / proporcion; &lt;br /&gt;   &lt;br /&gt;   vy = 0;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  private function iniciaTeclado():void&lt;br /&gt;  {&lt;br /&gt;   if (num_jugador == 1)&lt;br /&gt;   {&lt;br /&gt;    upKey = Keyboard.UP;&lt;br /&gt;    downKey = Keyboard.DOWN;&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;    upKey = 87; // W&lt;br /&gt;    downKey = 83; // S&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public function mover(e:Event)&lt;br /&gt;  {&lt;br /&gt;   if (key.isDown(upKey))&lt;br /&gt;   {&lt;br /&gt;    vy -= 1;&lt;br /&gt;   }&lt;br /&gt;   else if (key.isDown(downKey))&lt;br /&gt;   {&lt;br /&gt;    vy += 1;&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   this.y += vy;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;¡Los pongs ya están en movimiento! Aunque necesitamos un movimiento más fluido que el conseguido hasta ahora para que la jugabilidad sea satisfactoria. Tema que abordamos en el siguiente capítulo.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/2-ii-herencia-en-actionscript-3/"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/3-ii-movimiento-avanzado/"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-7580443856421240366?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/7580443856421240366/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/3i-controlando-el-pong-desde-teclado.html#comment-form' title='6 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/7580443856421240366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/7580443856421240366'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/3i-controlando-el-pong-desde-teclado.html' title='3.I. Controlando el pong desde teclado'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_lVd850Hzqko/Sln4gP5vV3I/AAAAAAAAANc/9UEF6-OBMZw/s72-c/3_1MovimientoPong.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-8133971319621227111</id><published>2009-07-04T21:41:00.008+02:00</published><updated>2010-11-20T21:38:29.119+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>2.II. Herencia en ActionScript 3</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes/"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://img139.imageshack.us/img139/8158/22herencia.jpg" alt="Herencia en ActionScript 3" width="600" height="100" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Diseño gráfico de nuestro pong&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Antes de explicar el concepto de &lt;strong&gt;herencia&lt;/strong&gt;, vamos a colocar, por fin, nuestro pong en la ventana Flash. Lo primero que necesitamos es una representación gráfica para él. Con la ventana Flash activa: menú &lt;strong&gt;Insertar&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Nuevo símbolo... &lt;/strong&gt;En el diálogo que nos aparece, elegimos como nombre para el símbolo &lt;strong&gt;Pong. &lt;/strong&gt;Y en el tipo, &lt;strong&gt;Clip de película.&lt;/strong&gt; Puedes elegir el diseño que quieras. Aquí, el que he seguido yo:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://img16.imageshack.us/img16/5923/crearpong.jpg" alt="Creando nuestro pong" width="450" height="200" border="1" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;1)&lt;/strong&gt; Dibujamos un rectángulo con la &lt;strong&gt;Herramienta Rectángulo (R)&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;2) &lt;/strong&gt;Con la herramienta de &lt;strong&gt;Tansformación Libre (Q), &lt;/strong&gt;con Ctrl+Shitf pulsados, clickamos sobre la esquina inferior derecha del rectángulo y arrastramos hacia arriba, hasta conseguir la forma adecuada.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;3)&lt;/strong&gt; Con todo lo que acabamos de dibujar seleccionado, en la ventana &lt;strong&gt;Color (Shift + F9)&lt;/strong&gt; uilizamos los siguientes valores:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://img30.imageshack.us/img30/3702/colorpong.jpg" alt="Color para el Pong" width="229" height="312" align="middle" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Un último detalle importante que has de tener en cuenta, es que el gráfico &lt;strong&gt;ha de estar lo más centrado posible&lt;/strong&gt; en el clip de película. Si te fijas, una pequeña cruz es la que marca este centro. Si tu pong no estuviera centrado, trasládalo de modo que su centro (que se marca cuándo tienes seleccionada la &lt;strong&gt;Heramienta de Transformación Libre (Q)), &lt;/strong&gt;quede alineado con el del clip.&lt;/p&gt;&lt;br /&gt;&lt;h6 style="font-size:small"&gt;Enlazando la clase Pong con su representación gráfica&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Nuestro objetivo es que la clase Pong que tenemos definida en el archivo &lt;strong&gt;Pong.as&lt;/strong&gt; esté asociada a la representación gráfica que le hemos creado. Para ello debemos seguir dos pasos:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;1)&lt;/strong&gt; Especificar, en ActionScript, que la clase Pong tiene una representación gráfica en forma de clip de película (&lt;strong&gt;MovieClip)&lt;/strong&gt;. Y hacemos esto mediante la &lt;strong&gt;herencia &lt;/strong&gt;de MovieClip en la clase Pong.&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package mi.pong &lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public class Pong extends MovieClip &lt;br /&gt; {&lt;br /&gt;  private var vy:int;&lt;br /&gt;  &lt;br /&gt;  public function Pong() &lt;br /&gt;  {&lt;br /&gt;   trace("¡Objeto de la clase Pong creado!");&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public function mover():void&lt;br /&gt;  {&lt;br /&gt;   // Vacío. Aún no sabemos cómo vamos a mover nuestro Pong&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;public class Pong extends MovieClip: &lt;/strong&gt;Aquí estamos especificando que la clase Pong &lt;strong&gt;hereda &lt;/strong&gt;de la clase &lt;strong&gt;MovieClip&lt;/strong&gt; de Flash. Es decir, que Pong, además de tener sus atributos y sus métodos propios, además también &lt;strong&gt;hereda &lt;/strong&gt;todas las características MovieClip, entre ellos, la representación gráfica. &lt;strong&gt;MovieClip &lt;/strong&gt;es la clase que Flash utiliza para las representaciones gráficas con línea temporla.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;2) &lt;/strong&gt;Indicar que el símbolo Pong que hemos creado en Flash está relacionado con la clase Pong del archivo Pong.as. Para ello, en la ventana&lt;strong&gt; Biblioteca, click derecho sobre el símbolo Pong&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Propiedades&lt;/strong&gt;, y en caso de no estar extendido, pulsamos &lt;strong&gt;Avanzado.&lt;/strong&gt; Ahí, selecionamos &lt;strong&gt;Exportar para ActionScript&lt;/strong&gt;. En clase, la clase con la que queremos vincular el símbolo (y su ubicación en su respectivo paquete) &amp;quot;&lt;strong&gt;mi.pong.Pong&amp;quot;&lt;/strong&gt;, y en clase base, si no estuviera ya, &amp;quot;&lt;strong&gt;flash.display.MovieClip&amp;quot;.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Tras estos dos pasos, cada vez que creemos un objeto de la clase Pong, este objeto tendrá asociado el símbolo Pong que creamos al inicio del capítulo.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Añadiendo el pong a la escena&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Ahora cobra sentido aquel &amp;quot;extends MovieClip&amp;quot; que añadimos a la clase Main. El documento Flash es, en esencia, un clip de película, un &lt;strong&gt;MovieClip.&lt;/strong&gt;Y, al igual que con el Pong, a este MovieClip podemos asociarle una clase ActionScript, en este caso, Main.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Por ser Main la clase que representa al MovieClip principal de nuestro archivo Flash, es él quién controla todo lo que sucede en la parte gráfica de la aplicación. Por eso debe ser en él en el que añadamos nuestro pong.&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package&lt;br /&gt;{&lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; import mi.pong.Pong;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public class Main extends MovieClip&lt;br /&gt; {&lt;br /&gt;  &lt;br /&gt;  public function Main() &lt;br /&gt;  {&lt;br /&gt;   var miPong:Pong = new Pong();&lt;br /&gt;   addChild(miPong);&lt;br /&gt;   miPong.x = stage.stageWidth / 2;&lt;br /&gt;   miPong.y = stage.stageHeight / 2;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;-&lt;strong&gt; addChild(miPong): &lt;/strong&gt;añadimos a nuestra película miPong.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;miPong.x = stage.stageWidth / 2: &lt;/strong&gt;&amp;quot;x&amp;quot; es un atributo heredado desde MovieClip. Indica la posición, en el eje de las x, del objeto dentro de la película. &lt;strong&gt;stage.stageWidth&lt;/strong&gt; indica el ancho de la película. Lo dividimos entre 2 para centrar. Análogo para &lt;strong&gt;miPong.y&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Si ahora pruebas la película, verás a nuestro Pong, en el centro.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Cuál es la idea básica tras la herencia?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;La herencia nos permite crear clases generales de las que poder heredar en clases más concretas. Por ejemplo, podríamos tener una clase padre &lt;strong&gt;Transporte&lt;/strong&gt;, con atributos generales como &amp;quot;velocidad&amp;quot; o &amp;quot;precio&amp;quot; y unas clases heredades, más concretas, como &lt;strong&gt;Avión, Tren, Automóvil&lt;/strong&gt;... &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para especificar que una clase hereda de otra utilizamos la palabra clave &lt;strong&gt;extends:&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;&lt;br /&gt;public class miClase extends ClasePadre&lt;br /&gt;{&lt;br /&gt; // Definición de clase&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;En capítulos posteriores revisaremos esta definición y todas sus aplicaciones. De momento, nos vale con saber que para poder asociar clases ActionScript con símbolos Flash necesitamos que éstas hereden de &lt;strong&gt;MovieClip&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/2-i-concepto-de-clase-clases-en-actionscript-3/"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/3-i-controlando-el-pong-desde-teclado/"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-8133971319621227111?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/8133971319621227111/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/esta-entrada-pertenece-actionscript-3.html#comment-form' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/8133971319621227111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/8133971319621227111'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/07/esta-entrada-pertenece-actionscript-3.html' title='2.II. Herencia en ActionScript 3'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-1319170572544499949</id><published>2009-06-30T20:15:00.010+02:00</published><updated>2010-11-20T21:36:56.414+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>2.I. Concepto de Clase. Clases en ActionScript 3</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes/"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://img14.imageshack.us/img14/8939/21laclase.jpg" alt="Concepto de clase. Clases en ActionScript 3" height="100" width="600" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Un mundo lleno de objetos...&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Si conoces los conceptos de programación de objetos, puedes saltarte estos puntos hasta llegar a la última parte del capítulo.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Son muchos y variados los tipos de programación que existen actualmente. Programación estrucuturada, orientada a objetos, lógica, funcional... Cada una con sus pros y sus contras y un sistema propio de funcionaminento.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;El &lt;strong&gt;principio básico de la Programación Orientada a Objetos&lt;/strong&gt; es que todo aquello que necesitamos para representar nuestros programas&lt;strong&gt; son objetos&lt;/strong&gt;. Y si lo piensas, razón no le falta. En nuestro &lt;strong&gt;Pong&lt;/strong&gt; vamos a necesitar diferentes objetos para jugar: una &lt;strong&gt;bola&lt;/strong&gt;, los &lt;strong&gt;Pong&lt;/strong&gt; contra las que va a rebotar la bola, unos &lt;strong&gt;marcadores&lt;/strong&gt; para llevar la puntuación... Todos ellos objetos. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;(&lt;strong&gt;Anotación informática carente de interés&lt;/strong&gt;: Bueno, siendo estrictos, no todo en la &lt;strong&gt;POO&lt;/strong&gt; son objetos estrictamente... Debate intenso a la vez que inútil que mantienen defensores de la &lt;strong&gt;programación funcional pura&lt;/strong&gt; frente a los que defienden la &lt;strong&gt;orientación a objetos&lt;/strong&gt;...)&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Es obvio que &lt;strong&gt;no todos los objetos son iguales&lt;/strong&gt;. Un jarrón no es lo mismo que una pelota, pero un jarrón verde tampoco &lt;em&gt;es exactamente igual&lt;/em&gt; a un jarrón rojo. Aquí es dónde interviene, por fin, el &lt;strong&gt;concepto de clase&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Concepto de Clase&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Vamos a pasar un poco rápido sobre la teoría, porque cuándo realicemos el ejemplo en ActionScript se verá mucho más claro.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En POO, una clase es un &lt;strong&gt;tipo de objeto&lt;/strong&gt;. Todas las pelotas del mundo pertenecen a la clase &lt;em&gt;pelota&lt;/em&gt;, y todos los jarrones del mundo a la clase &lt;em&gt;jarrón&lt;/em&gt;. Además, cada tipo de objeto tiene unas acciones asociadas (métodos) y unas características propias (atributos).&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Qué es un atributo?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;Un &lt;strong&gt;atributo es una característica del tipo de objeto. &lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En el caso del jarrón, posibles atributos serían: color (así podemos distinguar el jarrón rojo del verde), volumen, contenido...&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Y en el caso de la pelota: tamaño, velocidad, dirección...&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Qué es un método?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;Un &lt;strong&gt;método es una acción que el tipo de objeto puede realizar&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para el jarrón, posibles métodos serían: rellenar, romper...&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para la pelota: golpear, parar, pinchar...&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Cuál es la diferencia entre Clase y Objeto?&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;Una &lt;strong&gt;objeto es una instanciación de una clase&lt;/strong&gt;. En cristiano, cuándo Dios creó el mundo, lo primero que se hizo fue un molde con forma humana. Ese molde era la &lt;strong&gt;clase&lt;/strong&gt;. La clase &lt;em&gt;humano. &lt;/em&gt;Y cuándo creó a Adán utilizando ese molde, creó un &lt;strong&gt;objeto&lt;/strong&gt; de la clase &lt;em&gt;humano.&lt;/em&gt; Adán es el objeto&lt;strong&gt;, &lt;/strong&gt; &lt;em&gt;humano&lt;/em&gt; la clase&lt;strong&gt;.&lt;/strong&gt; Adán lo concreto, &lt;em&gt;humano&lt;/em&gt; lo abstracto.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Clases en ActionScript 3&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Vamos a crear nuestra primera (segunda, si contamos el Main.as) clase en ActionScript. Y para empezar, vamos a pensar en uno de los tipos de objeto que vamos a necesitar para nuestro Pong: efectivamente, &lt;strong&gt;un Pong&lt;/strong&gt;. La barrita-mini-pared que subirá y bájara evitando que la pelota sobrepase los límites de nuestro campo.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Con el proyecto Pong abierto en FlashDevelop, vamos a crear unas carpetas para organizar nuestro trabajo mejor: &lt;strong&gt;click derecho sobre la raíz del proyecto Pong (AS3) -&amp;gt; Add -&amp;gt; New Folder...&lt;/strong&gt; y lo llamos &lt;strong&gt;"mi"&lt;/strong&gt;, y sobre esta nueva carpeta, misma operación y añadimos una subcarpeta llamada "&lt;strong&gt;pong&lt;/strong&gt;". Y sobre esta carpeta, misma operación, pero en vez de New Folder seleccionamos &lt;strong&gt;New Class&lt;/strong&gt; y la llamamos &lt;strong&gt;Pong.as&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Por convención, los nombres de las clases se escriben con mayúsculas, mientras que los de las carpetas (paquetes) con minúscula. Ahora ya es un buen momento para explicar el código que aparece.&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package mi.pong&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* ...&lt;br /&gt;* @author ASL&lt;br /&gt;*/&lt;br /&gt;public class Pong&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;public function Pong()&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;package mi.pong&lt;/strong&gt;: Es el paquete (jerarquía de carpetas) en el que se encuentra la clase alojada (el archivo .as). Es decir, dentro de la carpeta "mi", en la carpeta "pong". Es importante que el package esté bien especificado para evitar problemas en la compilación.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;public class Pong: &lt;/strong&gt;Definición de la clase Pong.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;public function Pong(): &lt;/strong&gt;Constructor de la clase Pong.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ya han aparecido bastantes cosas nuevas, así que sinteticemos:&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;Definición de paquetes&lt;/h5&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package carpeta_raiz.subcarpeta1.subcarpeta2.(...)&lt;br /&gt;{&lt;br /&gt;// Definición de clases del paquete&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;h5&gt;Definición de clases&lt;/h5&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;public class MiClase&lt;br /&gt;{&lt;br /&gt;// Lista de atributos&lt;br /&gt;&lt;br /&gt;public function MiClase()&lt;br /&gt;  {&lt;br /&gt;   // Definición del constructor&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // Lista de métodos&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;¿Y el &lt;em&gt;public&lt;/em&gt; qué significa? De momento quédate con la idea de que todo aquello que sea public puede ser referenciado por otros archivos .as.&lt;/p&gt;&lt;br /&gt;&lt;h6 style="font-size: small;"&gt;Añadiendo atributos y métodos a nuestra clase Pong&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Sin más, añadamos caracterísiticas a nuestra &lt;strong&gt;clase Pong&lt;/strong&gt; para convertirla en una clase útil. ¿Qué atributos y métodos podemos añadir a nuestro pong?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;Velocidad&lt;/strong&gt;: atributo para predecir su localización. Además, el pong sólo se mueve verticalmente, así que sólo necesitaremos saber la velocidad en el eje de la y.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;-&lt;strong&gt;Mover&lt;/strong&gt;: método para poder desplazar el Pong por la pantalla.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;Definición de variables&lt;/h5&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;var nombre_variable:tipo_variable [= valor_inicial];&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Los &lt;strong&gt;atributos&lt;/strong&gt; son variables que tienen una &lt;strong&gt;visbilidad&lt;/strong&gt; especificada y que se declaran en el cuerpo de la clase, fuera de todo tipo de función.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;Visibilidad de atributos y funciones&lt;/h5&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Los tres tipos de visibilidad para atributos y funciones son:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;public:&lt;/strong&gt; Cualquier clase externa puede acceder a ellos.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;private: &lt;/strong&gt;Sólo clases internas pueden acceder a ella.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;protected: &lt;/strong&gt;Sólo clases hijas pueden acceder a ellas. Las clases hijas se explicarán más adelante.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;Definición de atributos&lt;/h5&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;visibilidad var nombre_atributo:tipo_atributo [= valor_inicial];&lt;/pre&gt;&lt;br /&gt;&lt;h5&gt;Definición de funciones&lt;/h5&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;visibilidad function nombre_atributo([parámteros...]):tipo_devolución&lt;br /&gt;{&lt;br /&gt;// Cuerpo de la función&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;h5&gt;El constructor de la clase&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;Consideramos el &lt;strong&gt;constructor&lt;/strong&gt; de clase a aquella función que tiene el mismo nombre que la clase. Cuándo creemos un objeto, el constructor de clase será la primera función en ejecutarse.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Pues ahora que sabemos todo esto, vamos a añadir a nuestra clase Pong el atributo &lt;strong&gt;velocidad &lt;/strong&gt;y el método &lt;strong&gt;mover.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package mi.pong&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* ...&lt;br /&gt;* @author ASL&lt;br /&gt;*/&lt;br /&gt;public class Pong&lt;br /&gt;{&lt;br /&gt;private var vy:Number;&lt;br /&gt;&lt;br /&gt;public function Pong()&lt;br /&gt;{&lt;br /&gt; trace("¡Objeto de la clase Pong creado!");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function mover():void&lt;br /&gt;{&lt;br /&gt; // Vacío. Aún no sabemos cómo vamos a mover nuestro Pong&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;private var vy:int&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;: Especifica que el atributo "vy" es del tipo entero (un número redondo negativo o positivo) y además privado. Sólo puede ser visto dentro de la clase Pong.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;public function mover():void : &lt;/strong&gt;Una función pública llamada mover; &lt;strong&gt;void&lt;/strong&gt; es un tipo especial, que indica que la función no devuelve nada.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Creando un objeto de la clase Pong&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Cómo habrás notado, hemos añadido un &lt;em&gt;trace("¡Objeto de la clase pong creado!")&lt;/em&gt;; en el constructor de clase. Este mensaje nos servirá para constatar (a falta aún de una representación gráfica para el pong) que el objeto ha sido creado.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Abrimos Main.as y modificamos el código que teníamos por lo siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package&lt;br /&gt;{&lt;br /&gt;import flash.display.MovieClip;&lt;br /&gt;import mi.pong.Pong;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* ...&lt;br /&gt;* @author ASL&lt;br /&gt;*/&lt;br /&gt;public class Main extends MovieClip&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;public function Main()&lt;br /&gt;{&lt;br /&gt; var miPong:Pong = new Pong();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;import mi.pong.Pong: &lt;/strong&gt;Si queremos crear un objeto de tipo de Pong, lo primero que hemos de hacer es importar la clase, especificando delante del nombre el paquete en el que está. Si no la importáramos, obtendríamos un error.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- &lt;strong&gt;var miPong:Pong = new Pong()&lt;/strong&gt;: &lt;em&gt;new&lt;/em&gt; seguido de un constructor nos devuelve un objeto de la clase especificada. Ese objeto se almacena en la variable miPong, que ha sido especificado del tipo Pong. Observa que esto es una variable dentro la función, no un atributo de la clase, y que por eso no se especifica ninguna visibilidad.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ctrl+Enter para probar la película, F2 para ver la salida y ahí estará la prueba viviente de que creamos nuestro objeto de la clase Pong. Algo soso, sí. En el siguiente capítulo mostaremos nuestro pong dentro de la ventana Flash.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/1-ii-la-clase-del-documento/"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/2-ii-herencia-en-actionscript-3/"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-1319170572544499949?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/1319170572544499949/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principantes-2.html#comment-form' title='10 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/1319170572544499949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/1319170572544499949'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principantes-2.html' title='2.I. Concepto de Clase. Clases en ActionScript 3'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-9146614897658757597</id><published>2009-06-29T20:47:00.008+02:00</published><updated>2010-11-20T21:34:52.339+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>1.II.La clase del Documento</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes/"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://img83.imageshack.us/img83/2517/12clasedocumento.jpg" alt="La clase del Documento" width="600" height="100" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;¿Qué es la clase del Documento?&lt;/h5&gt;&lt;p&gt;Una política que vamos a seguir durante toda esta guía será que siempre que podamos controlar cualquier funcionalidad u objeto desde ActionScript (aunque pudiera realizarse desde Flash de manera más sencilla) lo &lt;strong&gt;controlaremos con ActionScript&lt;/strong&gt;. En algunas ocasiones quizá pueda resultar rebuscado, pero veremos que, a la larga, será mucho más beneficioso.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Y para empezar a aplicar esta política vamos a crear &lt;strong&gt;la clase del Documento&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Resultará contradictorio para el lector novel, pero &amp;quot;la clase del Documento&amp;quot; en verdad &lt;strong&gt;tiene poco que ver con el concepto de clase de la Programación Orientada a Objetos, &lt;/strong&gt;que explicaremos más adelante.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para simplificar (y porque de momento no necesitas saberlo) vamos a considerar a la clase del Documento como &lt;strong&gt;el archivo ActionScript en el que inicilizaremos todas los componentes&lt;/strong&gt; &lt;strong&gt;de nuestro juego&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Creando la clase del documento&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Como hemos dicho, la clase del documento es un archivo de ActionScript, así que eso es lo que necesitamos.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Con el &lt;a href="http://metafisicainformatica.blogspot.com/2009/06/introduccion-una-de-las-cosas-mas.html"&gt;proyecto Pong que creamos en FlashDevelop&lt;/a&gt; abierto, &lt;strong&gt;click derecho en la raíz del proyecto, Pong (AS3) -&amp;gt; Add... -&amp;gt; New Class&lt;/strong&gt;. Llamaremos a la clase &lt;strong&gt;Main.as&lt;/strong&gt;. Aceptamos ¡y ya tenemos nuestra clase Main! Sin saber ActionScript ni nada... El código que obtenemos es el siguiente:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package &lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public class Main &lt;br /&gt; {&lt;br /&gt;  &lt;br /&gt;  public function Main() &lt;br /&gt;  {&lt;br /&gt;   // Aquí, el código de inicialización&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;En &lt;strong&gt;@author&lt;/strong&gt; aparecerá el nombre que especificaste al instalar FlashDevelop. El "&lt;strong&gt;// Aquí, el código de inicialización&lt;/strong&gt;" es un comentario.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;Comentarios&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;Los comentarios son texto que no se tendrán en cuenta a la hora de ejecutar nuestra aplicación. Sirven para explicar código y hacer anotaciones. En ActionScript (y en Java, y en C, y en C++, y en otros lenguajes...) se pueden realizar comentarios de dos maneras:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;a)&lt;/strong&gt; Comentarios en &lt;strong&gt;única línea&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;// Comentario en una línea&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;b)&lt;/strong&gt; Comentarios en &lt;strong&gt;varias líneas&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;/* Comentario en&lt;br /&gt;varias líneas */&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Va a ser mucha la sintaxis (&amp;quot;cómo se escriben las cosas&amp;quot;) que va a aparecer, y puede que al cabo del tiempo hayas olvidado la mitad. Cuándo aprendo un lenguaje nuevo, suelo  ir anotando en una lista, en papel, toda la sintaxis que voy aprendiendo, para que luego sea más rápido consultar cualquier duda. Te recomiendo que lo hagas, porque también te será útil cuándo, después de un tiempo sin utilizar un lenguaje, quieras volver a retomarlo.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Bien, &lt;strong&gt;volviendo a&lt;/strong&gt; &lt;strong&gt;nuestra clase Main&lt;/strong&gt;: De momento no nos interesa saber todos los pormenores de su sintaxis, sólo que  &lt;strong&gt;function Main&lt;/strong&gt; es una función (una serie de órdenes que se ejecutarán al iniciar nuestro Flash) y que únicamente hay que sustituir &amp;quot;// Aquí, el código de inicialización&amp;quot; por el código ActionScript que queramos que se ejecute.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para empezar, vamos borrar el comentario y lo vamos a sustituir por:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;trace("Pong");&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;trace&lt;/strong&gt; es una función que recibe una variable y la imprime por la consola Flash. En este caso, le enviamos un &lt;strong&gt;String&lt;/strong&gt; (una serie de caracteres entrecomillados). Puede ser muy útil a la hora de &lt;strong&gt;depurar&lt;/strong&gt; nuestro código (ver dónde y por qué está fallando).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Apuntamos &lt;strong&gt;trace&lt;/strong&gt; en nuestra lista de funciones importantes, y guardamos Main.as.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Otro detalle importante es añadir &amp;quot;&lt;strong&gt;import flash.display.MovieClip;&lt;/strong&gt;&amp;quot; y &amp;quot;&lt;strong&gt;extends MovieClip&lt;/strong&gt;&amp;quot; al código como sigue:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package&lt;br /&gt;{&lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public class Main extends MovieClip&lt;br /&gt; {&lt;br /&gt;  &lt;br /&gt;  public function Main() &lt;br /&gt;  {&lt;br /&gt;   trace("Pong");&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;De momento, siguen si preocuparnos el por qué de esto. Ya hablaremos de ello más adelante.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Conectando nuestro Flash con Main.as&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Ahora, ¿qué tenemos? Un archivo &lt;strong&gt;Main.as&lt;/strong&gt; y un archivo &lt;strong&gt;pong.fla&lt;/strong&gt;, que sí, están en la misma carpeta, pero que no guardan ninguna otra relación. ¿Cómo le decimos a pong.fla que Main.as es la clase de su documento? &lt;/p&gt;&lt;br /&gt;&lt;p&gt;En Flash, clickamos en el documento (el rectangulito blanco, el lienzo) y nos aparecerán sus propiedades en la ventana &lt;strong&gt;Propiedades&lt;/strong&gt; (haz click en el menú &lt;strong&gt;Ventana -&amp;gt; Propiedades&lt;/strong&gt; o pulsa &lt;strong&gt;Ctrl+F3&lt;/strong&gt; si no la encuentras). Y en el apartado &lt;strong&gt;Publicar&lt;/strong&gt;, en el campo &lt;strong&gt;Clase&lt;/strong&gt; escribimos &lt;strong&gt;Main, &lt;/strong&gt;el nombre de nuestra clase para el documento&lt;strong&gt;.&lt;/strong&gt; Así haremos referencia al archivo Main.as.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://img524.imageshack.us/img524/1374/12prop.png" width="284" height="350" align="center" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Y ahora previsualizamos la película (&lt;strong&gt;menú Control -&amp;gt; Probar película&lt;/strong&gt; o &lt;strong&gt;Ctrl+Enter&lt;/strong&gt;). ¿Ya la has probado? ¿No hay nada? Pulsa &lt;strong&gt;F2&lt;/strong&gt; para ver la consola de salida de Flash. ¡Sí, pone &lt;strong&gt;Pong&lt;/strong&gt;! La función &lt;strong&gt;trace&lt;/strong&gt; lo puso ahí. Vale, venga, no es  gran cosa. Pero hay que tener paciencia. Ya &lt;strong&gt;hemos logrado conectar Main.as con pong.fla&lt;/strong&gt;, paso clave para continuar con el desarrollo de nuestro juego.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para no dejar con mal sabor de boca al lector al final de este capítulo, y para comprobar que realmente podemos manejar  Flash a nuestro antojo desde ActionScript, y no sólo la consola de salida, vamos a cambiar nuestra clase Main por el siguiente código:&lt;/p&gt;&lt;br /&gt;&lt;pre class="actionscript"&gt;package&lt;br /&gt;{&lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ...&lt;br /&gt;  * @author ASL&lt;br /&gt;  */&lt;br /&gt; public class Main extends MovieClip&lt;br /&gt; {&lt;br /&gt;  &lt;br /&gt;  public function Main() &lt;br /&gt;  {&lt;br /&gt;   graphics.beginFill(0x000000);&lt;br /&gt;   graphics.drawRect(stage.stageWidth / 2, stage.stageHeight / 2, 50, 50);&lt;br /&gt;   graphics.endFill();&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Probamos la película y... ahí está: &lt;strong&gt;un cuadrado negro en el centro&lt;/strong&gt;. Menos es nada.&lt;/p&gt;&lt;br /&gt;&lt;table width="200" border="0" align="center"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/1-i-lo-primero-organizacion/"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes.html#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/2-i-concepto-de-clase-clases-en-actionscript-3/"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-9146614897658757597?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/9146614897658757597/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes_29.html#comment-form' title='7 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/9146614897658757597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/9146614897658757597'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/06/actionscript-3-guia-para-principiantes_29.html' title='1.II.La clase del Documento'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-7618352597703039513</id><published>2009-06-28T18:17:00.018+02:00</published><updated>2010-11-20T21:34:00.550+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Juego Pong - Guía ActionScript 3'/><title type='text'>1.I. Lo primero, organización</title><content type='html'>&lt;p style="font-size:x-small;"&gt;Esta entrada pertenece a &lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes/"&gt;ActionScript 3 - Guía para Principiantes&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;img src="http://img134.imageshack.us/img134/6031/11organizacion.jpg" alt="Lo primero, organización" width="600" height="160" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h6&gt;Introducción&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Una de las cosas más importantes para el desarrollo de cualquier proyecto software (y  para cualquier proyecto en general) es una buena organización. A organizar se aprende con experiencia, tras escarmentar después de cientos de horas de mala programación que, a la hora de hacer algún cambio en nuestro código para añadir &lt;strong&gt;una nueva funcionalidad,&lt;/strong&gt; derivaron en otros tantos cientos de horas de reorganización y reescritura.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;La organización es práctica y está llena de beneficios pero, sinceramente, al principio es un coñazo. Normalmente, uno lo que quiere es tirar líneas de código de manera salvaje para ver resultados lo antes posible. Para proyectos pequeños puede ser una vía satisfactoria (de hecho se hace ahí fuera en aplicaciones por las que luego cobran un pastón), pero si aspiramos a que nuestro proyecto sea de verdad una &lt;strong&gt;obra de ingeniería&lt;/strong&gt;, una buena organización es clave para no perdernos entre la multitud de archivos y código que vamos a crear.&lt;/p&gt;&lt;br /&gt;&lt;h6 style="font-size:small;"&gt;FlashDevelop: organizando nuestros archivos .as&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Aunque Flash CS4 nos permite trabajar con los archivos de ActionScript, para el desarrollo de nuestro código &lt;strong&gt;vamos a trabajar con una aplicación externa: &lt;a href="http://www.flashdevelop.org/community/viewforum.php?f=11"&gt;FlashDevelop&lt;/a&gt;,&lt;/strong&gt; un entorno de programación gratuito que no sólo nos va a ayudar a mantener nuestros archivos de ActionScript organizados, sino que además nos echará una mano con atajos de código y otras herramientas automáticas de las que el editor de Flash CS4 carece.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Una vez instalado FlashDevelop, empezamos, ahora sí, con nuestro proyecto.&lt;/p&gt;&lt;br /&gt;&lt;h6&gt;Jerarquía de carpetas&lt;/h6&gt;&lt;br /&gt;&lt;p&gt;Creamos una carpeta llamada "&lt;strong&gt;Pong&lt;/strong&gt;" y dentro de ésta, una subcarpeta llamada "&lt;strong&gt;src&lt;/strong&gt;".&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Lo siguiente es crear el eje central de nuestro proyecto: &lt;strong&gt;el archivo Flash&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Abrimos &lt;strong&gt;Adobe Flash&lt;/strong&gt;, y &lt;strong&gt;creamos un nuevo Archivo de Flash (AS 3.0)&lt;/strong&gt; y lo guardamos en la subcarpeta &lt;strong&gt;"src"&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ahora es el momento de &lt;strong&gt;ejecutar FlashDevelop&lt;/strong&gt;. Creamos un nuevo proyecto para nuestro Pong: Menú&lt;strong&gt; Project -&amp;gt; New project&lt;/strong&gt;... y seleccionamos &lt;strong&gt;Flash IDE Project&lt;/strong&gt;. Abajo, en &lt;strong&gt;Name&lt;/strong&gt; escribimos "&lt;strong&gt;Pong&lt;/strong&gt;" y en &lt;strong&gt;Location&lt;/strong&gt; seleccionamos la &lt;strong&gt;carpeta "src"&lt;/strong&gt; dentro de Pong que creamos anteriormente.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;En síntesis, nuestra situación actual es la siguiente:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Por un lado tenemos &lt;strong&gt;Adobe Flash&lt;/strong&gt;, con nuestro "pong.fla" abierto. En él realizaremos toda &lt;strong&gt;la parte gráfica&lt;/strong&gt; de nuestro juego.&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Y por otro, &lt;strong&gt;FlashDevelop&lt;/strong&gt;, con el proyecto "Pong" en el que desarrollaremos todo el &lt;strong&gt;código ActionScript&lt;/strong&gt;.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;table align="center" border="0" width="200" style="margin-top:0px;"&gt;&lt;br /&gt; &lt;tbody&gt;&lt;tr&gt;&lt;br /&gt;   &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes"&gt;Anterior&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;   &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/tutorial-actionscript-3-juego-pong-principiantes#indice"&gt;Índice&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;   &lt;td&gt;&lt;a href="http://www.metafisicainformatica.com/2010/11/20/1-ii-la-clase-del-documento/"&gt;Siguiente&lt;/a&gt;&lt;/td&gt;&lt;br /&gt; &lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-7618352597703039513?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/7618352597703039513/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/06/introduccion-una-de-las-cosas-mas.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/7618352597703039513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/7618352597703039513'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/06/introduccion-una-de-las-cosas-mas.html' title='1.I. Lo primero, organización'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-995842118936238198</id><published>2009-01-02T15:16:00.024+01:00</published><updated>2009-01-27T20:32:01.892+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='programación'/><title type='text'>Números aleatorios (Random) en Haskell</title><content type='html'>Conseguir un puto &lt;b&gt;número aleatorio en Haskell&lt;/b&gt; no es nada trivial. He estado buscando algunas soluciones, y al final he sacado el siguiente código, que no sé sí será el más correcto, pero funciona:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;miRandom =&lt;br /&gt;    do&lt;br /&gt;       newStdGen&lt;br /&gt;       g&lt;-getStdGen&lt;br /&gt;              let             &lt;br /&gt;                  a = 0::Int            &lt;br /&gt;                  b = 20::Int            &lt;br /&gt;                  x = randomR (a, b) g         &lt;br /&gt;       print x&lt;/pre&gt;&lt;br /&gt;Que imprime por pantalla:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(17,1295529924 1123184626)&lt;br /&gt;:: IO ()&lt;/pre&gt;&lt;br /&gt;La función &lt;b&gt;miRandom&lt;/b&gt; imprime por pantalla la representación de la variable &lt;i&gt;x&lt;/i&gt; que es del tipo &lt;b&gt;(Int, StdGen)&lt;/b&gt;. Vamos, el 17 es el número aleatorio entre 0 y 20, que son las variables &lt;i&gt;a&lt;/i&gt; y &lt;i&gt;b&lt;/i&gt;, y los otros dos números largos y extraños que forman el segundo campo de la tupla son un nuevo &lt;b&gt;StdGen&lt;/b&gt;, que explicaremos después.&lt;br /&gt;&lt;dl&gt;&lt;dt&gt;StdGen&lt;/dt&gt;&lt;dd&gt;Tipo de dato que representa un generador de números aleatorios. Necesario para todas las funciones encargadas de la generación del número.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;getStdGen&lt;/dt&gt;&lt;dd&gt;Función que devuelve el generador de números aleatorios por defecto.&lt;br /&gt;&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;newStdGen:&lt;/dt&gt;&lt;dd&gt;Función que "actualiza" el generador de números aleatorios por defecto.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;randomR&lt;/dt&gt;&lt;dd&gt;&lt;i&gt;::(Random a, RandomGen b) =&gt; (a,a) -&gt; b -&gt; (a,b)&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Recibe una tupla con los límites entre los que queremos sacar el elemento aleatorio y, como segundo un generador de números aleatorios, siempre del tipo &lt;b&gt;StdGen&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;En realidad, por defecto, pueden sacarse elementos aleatorios de los siguientes tipos de datos: &lt;b&gt;Bool, Int, Integer, Char, Float, Double&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Importante: clases genéricas (como Num) &lt;b&gt;NO&lt;/b&gt; funcionarán en esta función.&lt;/dd&gt;&lt;br /&gt;&lt;/dl&gt;Todo eso está muy bien, sí, pero hay un problema, y es que si ahora creamos esta función:&lt;br /&gt;&lt;pre&gt;miRandom2 =&lt;br /&gt;    do &lt;br /&gt;      newStdGen&lt;br /&gt;      g&lt;-getStdGen&lt;br /&gt;      let &lt;br /&gt;         a = 0::Int&lt;br /&gt;         b = 20::Int&lt;br /&gt;         x = randomR (a, b) g&lt;br /&gt;         y = randomR (a, b) g&lt;br /&gt;      print x&lt;br /&gt;      print y&lt;/pre&gt;&lt;br /&gt;y la ejecutamos, obtenemos esto:&lt;br /&gt;&lt;pre&gt;(12,1295689980 1326707213)&lt;br /&gt;(12,1295689980 1326707213)&lt;br /&gt; :: IO ()&lt;/pre&gt;&lt;br /&gt;Es decir, el número aleatorio generado (el 12) es el mismo para ambas variables. ¿Casualidad? Podría ser. Pero si ejecutamos la función infinitas veces esas infinitas veces y las siguientes, los números aleatorios generados por &lt;b&gt;randomR&lt;/b&gt; serán siempre los mismos para x e y. ¿Por qué? Porque el generador de números aleatorios siempre es el mismo, &lt;i&gt;g&lt;/i&gt; y a partir de él siempre se generan los mismos números.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solución:&lt;/b&gt; ¿Recuerdas que &lt;b&gt;randomR&lt;/b&gt; devuelve una tupla en la que el primer miembro es el elemento aleatorio y el segundo dos números grandes y extraños? Pues ese segundo miembro es un nuevo elemento de tipo &lt;b&gt;StdGen&lt;/b&gt;, distinto al original recibido por la función, y que utilizaremos para encontrar el siguiente número aleatorio. Entonces:&lt;br /&gt;&lt;pre&gt;miRandom3 =&lt;br /&gt;  do &lt;br /&gt;     newStdGen&lt;br /&gt;     g&lt;-getStdGen&lt;br /&gt;     let &lt;br /&gt;        a = 0::Int&lt;br /&gt;        b = 20::Int&lt;br /&gt;        x = randomR (a, b) g&lt;br /&gt;        y = randomR (a, b) (snd x)&lt;br /&gt;     print x&lt;br /&gt;     print y&lt;/pre&gt;&lt;br /&gt;Que tiene como salida:&lt;br /&gt;&lt;pre&gt;(14,1994861249 30671636)&lt;br /&gt;(16,413980776 402357293)&lt;br /&gt; :: IO ()&lt;/pre&gt;&lt;br /&gt;Para terminar, recalcar que el uso de &lt;b&gt;newStdGen&lt;/b&gt; es necesario para actualizar el generador de números aleatorios por defecto. &lt;br /&gt;&lt;br /&gt;Si no lo hiciéramos, en cada una de las ejecuciones de &lt;b&gt;miRandom3&lt;/b&gt; los números aleatorios serían los mismos. Es decir, si en la primera ejecución &lt;b&gt;fst x&lt;/b&gt; fuera 13 y &lt;b&gt;fst y&lt;/b&gt; fuera 15, en las sucesivas ejecuciones de &lt;b&gt;miRandom3&lt;/b&gt;, &lt;b&gt;fst x&lt;/b&gt; y &lt;b&gt;fst y&lt;/b&gt; continuarían valiendo 13 y 15, porque ambas generaciones, al no haber sido invocada &lt;b&gt;newStdGen&lt;/b&gt;, partirían del mismo &lt;b&gt;StdGen&lt;/b&gt; por defecto.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-995842118936238198?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/995842118936238198/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/01/numero-aleatorio-random-en-haskell.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/995842118936238198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/995842118936238198'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2009/01/numero-aleatorio-random-en-haskell.html' title='Números aleatorios (Random) en Haskell'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2038738643649632209.post-2914628720363528766</id><published>2008-12-30T19:44:00.003+01:00</published><updated>2009-01-27T20:38:20.363+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trucos'/><category scheme='http://www.blogger.com/atom/ns#' term='Winamp'/><title type='text'>Minimizar Winamp a System Tray</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lVd850Hzqko/SVpuWJdqLrI/AAAAAAAAALM/2Q9a-_5xioU/s1600-h/logo_winamp.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: left; cursor: pointer; width: 94px; height: 94px;" src="http://3.bp.blogspot.com/_lVd850Hzqko/SVpuWJdqLrI/AAAAAAAAALM/2Q9a-_5xioU/s400/logo_winamp.jpg" alt="Winamp" id="BLOGGER_PHOTO_ID_5285658439449194162" border="0" /&gt;&lt;/a&gt;Dios, parecerá una gilipollez, pero hasta ayer, a la hora de trabajar en Windows con muchas ventanas abiertas mientras escuchaba música, el reproductor, &lt;b&gt;Winamp&lt;/b&gt; en este caso, siempre estaba en medio dando por culo cuándo pulsaba Alt+TAB para cambiar de ventanita y siempre lo acababa escogiendo por error.&lt;br /&gt;&lt;br /&gt;Solución: minimizarlo al System Tray o systray, que es la minibarra en la que suelen estar la hora, el antivirus... para que deje de molestar.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lVd850Hzqko/SVpwifswK-I/AAAAAAAAALU/ttXJ3yTgm-w/s1600-h/winamp1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 156px; height: 30px;" src="http://2.bp.blogspot.com/_lVd850Hzqko/SVpwifswK-I/AAAAAAAAALU/ttXJ3yTgm-w/s400/winamp1.jpg" alt="" id="BLOGGER_PHOTO_ID_5285660850599767010" border="0" /&gt;&lt;/a&gt;&lt;blockquote&gt;Tan fácil como ir al menú  &lt;b&gt;Options &gt; Preferences&lt;/b&gt;(Opciones &gt; Preferencias) y en el apartado &lt;b&gt;General Preferences&lt;/b&gt;, se selecciona System Tray en Show Winamp in:&lt;/blockquote&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lVd850Hzqko/SVp0M22VLFI/AAAAAAAAALc/jBMyEJupbAs/s1600-h/winamp2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 311px;" src="http://1.bp.blogspot.com/_lVd850Hzqko/SVp0M22VLFI/AAAAAAAAALc/jBMyEJupbAs/s400/winamp2.png" alt="" id="BLOGGER_PHOTO_ID_5285664876903345234" border="0" /&gt;&lt;/a&gt;O sea, "Muestra Winamp en: ... System Tray". De cajón. No pasa nada. Yo también lo busqué en Google en vez de mirar en las opciones.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2038738643649632209-2914628720363528766?l=metafisicainformatica.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://metafisicainformatica.blogspot.com/feeds/2914628720363528766/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://metafisicainformatica.blogspot.com/2008/12/minimizar-winamp-system-tray.html#comment-form' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/2914628720363528766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2038738643649632209/posts/default/2914628720363528766'/><link rel='alternate' type='text/html' href='http://metafisicainformatica.blogspot.com/2008/12/minimizar-winamp-system-tray.html' title='Minimizar Winamp a System Tray'/><author><name>Ángel Serrano</name><uri>http://www.blogger.com/profile/17464325135504566301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_lVd850Hzqko/SvhaQiaoC8I/AAAAAAAAAVY/qm5CB3z0BpQ/S220/caricatura.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lVd850Hzqko/SVpuWJdqLrI/AAAAAAAAALM/2Q9a-_5xioU/s72-c/logo_winamp.jpg' height='72' width='72'/><thr:total>3</thr:total></entry></feed>
