tag:blogger.com,1999:blog-3739731231981932592024-03-14T07:49:22.630+01:00DroideandoAngelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.comBlogger17125tag:blogger.com,1999:blog-373973123198193259.post-46095732436711786842011-06-12T13:28:00.000+02:002011-06-12T13:28:32.007+02:00Como compilar tu propio andengine.jar<h2>Consiguiendo los fuentes</h2><br />
<p>Primero necesitamos los fuentes de <a target="_new" href="http://www.andengine.org/">andengine</a>. Usaremos un <a target="_new" href="http://mercurial.selenic.com/downloads/">Cliente de Mercurial</a>.<br />
</p><br />
<p>En mi caso (debian) "apt-get install mercurial", en ubuntu deberia funcionar también. Si estás usando windows, de los clientes de arriba usa el que más te guste, pero no los he probado y ahí no te puedo ayudar. Creamos un directorio en nuestro pc, y vamos con un terminal a ese directorio.<br />
</p><br />
<div class="bash">hg clone https://andengine.googlecode.com/hg/ andengine</div><br />
<p>Nos tiene que dar una salida como ésta:<br />
requesting all changes<br />
adding changesets<br />
adding manifests<br />
adding file changes<br />
added 818 changesets with 3243 changes to 703 files (+4 heads)<br />
updating to branch default<br />
410 files updated, 0 files merged, 0 files removed, 0 files unresolved<br />
</p><br />
<p>Enhorabuena, nuestro primer paso para tener nuestro propio andengine.jar esta completo.</p><br />
<h2>Importando los fuentes al android</h2><br />
<p>En Eclipse, vamos a File -> Import </p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-N_bx_yourzs/TfQYXfDHELI/AAAAAAAABMI/Ppz3IfQ-DkI/s1600/101.png" /></div><br />
<p>Seleccionamos "Existing Projects into Workspace" y le damos a Siguiente. Ahora en "Select root directory" vamos al directorio que creamos anteriormente para bajar los fuentes de andengine. En mi caso, esto pinta como ésto:</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-UrjY_vRapnA/TfQZeeU_gRI/AAAAAAAABMQ/RhFLc1gqVms/s1600/102.png" /></div><br />
<p>Si has seguido los pasos bien, en Projects debes ver AndEngine chequeado. Dale a Finish.<br />
</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-M3T21GaZU2Y/TfQb12mAE2I/AAAAAAAABMY/V_5-97doQWw/s1600/103.png" /></div><br />
<p>Ahora tenemos el proyecto metido en eclipse, pero tiene algún error.<br />
</p><br />
<h2>Arreglando los errores</h2><br />
<p>Una vez importado el proyecto en Eclipse, necesitamos crear un directorio "res", hacemos click derecho en el raiz del proyecto AndEngine, y le damos a New -> Folder.<br />
</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://4.bp.blogspot.com/-Uwo2Y07uFKM/TfQcKU_AbsI/AAAAAAAABMg/VmhYVIc3omQ/s1600/104.png" /></div><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-mLtSXiIMD5g/TfQcxr3R9BI/AAAAAAAABMw/_0eykog8jPs/s1600/105.png" /></div><br />
<p>Una vez creados el directorio res, ya no ha errores en el proyecto.</p><br />
<h2>Creando el archivo .jar</h2><br />
<p>Botón derecho en el raiz del proyecto AndEngine y seleccionamos export. <br />
</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://1.bp.blogspot.com/-dJf5IZyk8E8/TfQcncB1FmI/AAAAAAAABMo/1WkenEMi6og/s1600/106.png" /></div><br />
<p>Ahora seleccionamos Java -> Jar y hacemos click en Siguiente.<br />
</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-veuLH_d16RY/TfQdLkbWWsI/AAAAAAAABM4/Jju78S9QBU0/s1600/107.png" /></div><br />
<p>En la siguiente pantalla necesitamos hacer algo <b>importante</b>, necesitamos quitar del andengine.jar lo que no necesitamos. En la parte de la derecha, deschequear TODO lo de andengine, porque no es necesario. También he quitado la carpeta donde hay imagenes y uml...<br />
Ahora le damos una salida al archivo jar y hacemos click en finish.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-lW7Bf6lvcm0/TfQd2O8nnOI/AAAAAAAABNA/62YlNXaTyR4/s1600/108.png" /></div><br />
<p>Espero que os haya servido de ayuda. Un saludo.</p>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com6tag:blogger.com,1999:blog-373973123198193259.post-18199259338784499282011-04-08T15:55:00.000+02:002011-04-08T15:55:06.905+02:00Estado actual del proyecto<p>Perdon por la calidad del video. Espero en los proximos dias subir a subversion el codigo del proyecto y hacer unos 3 articulo para llegar de lo que tenemos ahora a lo que se ve en el video. Usando Box2d para las físicas. Espero que os guste.</p><br />
<center><br />
<iframe title="YouTube video player" width="480" height="390" src="http://www.youtube.com/embed/u1_5bKirrD0" frameborder="0" allowfullscreen></iframe><br />
</center>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com3tag:blogger.com,1999:blog-373973123198193259.post-44019615617553132252011-03-26T18:33:00.000+01:002011-03-26T18:33:50.809+01:00Introducción a AndEngine (Parte V)<h2>Anteriormente en Droideando</h2><br />
<ul><li><a href="http://droideando.blogspot.com/2011/03/introduccion-andengine-parte-i.html">Introducción a AndEngine (Parte I)</a></li>
<li><a href="http://droideando.blogspot.com/2011/03/introduccion-andengine-parte-ii.html">Introducción a AndEngine (Parte II)</a></li>
<li><a href="http://droideando.blogspot.com/2011/03/introduccion-andengine-parte-iii.html">Introducción a AndEngine (Parte III)</a></li>
<li><a href="http://droideando.blogspot.com/2011/03/introduccion-andengine-parte-iv.html">Introducción a AndEngine (Parte IV)</a></li>
</ul><br />
<h2>Objetivos de hoy</h2><ul><li>Terminar el CatapultDetector para hacerlo funcionar bien</li>
<li>Hacer que el jugador reaccione al Detector</li>
</ul></p><br />
<h2>Con el Detector</h2><br />
<p>Ya tengo terminado el detector, pongo aqui el código completo y luego vamos a verlo por partes</p><br />
<div class="java"><div class="head">CatapultDetector.java</div><ol><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">com.pruebas.andengine</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.TouchEvent</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.BaseDetector</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">android.view.MotionEvent</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">class</span> CatapultDetector <span class="kw1">extends</span> BaseDetector <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">float</span> ANGLE_CONSTANT <span class="sy0">=</span> <span class="nu0">90</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">float</span> DEFAULT_MAX_DISTANCE <span class="sy0">=</span> <span class="nu0">80</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Fields</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// Listener for the Detector</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">final</span> ICatapultDetectorListener mCatapultDetectorListener<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw4">float</span> mMaxDistance<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// First Touch</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mFirstX<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mFirstY<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constructors</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> CatapultDetector<span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> ICatapultDetectorListener pCatapultDetectorListener<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span><span class="br0">(</span>DEFAULT_MAX_DISTANCE, pCatapultDetectorListener<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> CatapultDetector<span class="br0">(</span><span class="kw1">final</span> <span class="kw4">float</span> pMaxDistance,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> ICatapultDetectorListener pCatapultDetectorListener<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">setMaxDistance</span><span class="br0">(</span>pMaxDistance<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetectorListener</span> <span class="sy0">=</span> pCatapultDetectorListener<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods for/from SuperClass/Interfaces</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> <span class="kw4">boolean</span> onManagedTouchEvent<span class="br0">(</span>TouchEvent pSceneTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> touchX <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">getX</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> touchY <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">getY</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">int</span> action <span class="sy0">=</span> pSceneTouchEvent.<span class="me1">getAction</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">switch</span> <span class="br0">(</span>action<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">case</span> MotionEvent.<span class="me1">ACTION_DOWN</span><span class="sy0">:</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mFirstX</span> <span class="sy0">=</span> touchX<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mFirstY</span> <span class="sy0">=</span> touchY<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">case</span> MotionEvent.<span class="me1">ACTION_MOVE</span><span class="sy0">:</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">case</span> MotionEvent.<span class="me1">ACTION_UP</span><span class="sy0">:</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// case MotionEvent.ACTION_CANCEL:</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> distanceX <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">abs</span><span class="br0">(</span>touchX <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstX</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> <span class="kw4">float</span> distanceY <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">abs</span><span class="br0">(</span>touchY <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstY</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> distance <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">min</span><span class="br0">(</span><span class="br0">(</span><span class="kw4">float</span><span class="br0">)</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">hypot</span><span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span> distanceX, <span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span> distanceY<span class="br0">)</span>, mMaxDistance<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">double</span> angleX <span class="sy0">=</span> touchX <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstX</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">double</span> angleY <span class="sy0">=</span> touchY <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstY</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> <span class="kw4">float</span> angle <span class="sy0">=</span> <span class="br0">(</span><span class="kw4">float</span><span class="br0">)</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">toDegrees</span><span class="br0">(</span><a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">atan2</span><span class="br0">(</span>angleY,</pre></li><li class="li1"><pre class="de1">angleX<span class="br0">)</span><span class="br0">)</span></pre></li><li class="li1"><pre class="de1"><span class="sy0">+</span> ANGLE_CONSTANT<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">if</span> <span class="br0">(</span>action <span class="sy0">==</span> MotionEvent.<span class="me1">ACTION_MOVE</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetectorListener</span>.<span class="me1">onCharge</span><span class="br0">(</span><span class="kw1">this</span>, pSceneTouchEvent,</pre></li><li class="li2"><pre class="de2">distance, angle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetectorListener</span>.<span class="me1">onShoot</span><span class="br0">(</span><span class="kw1">this</span>, pSceneTouchEvent,</pre></li><li class="li1"><pre class="de1">distance, angle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">default</span><span class="sy0">:</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Getter & Setter</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> <span class="kw4">void</span> setMaxDistance<span class="br0">(</span><span class="kw4">float</span> mMaxDistance<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mMaxDistance</span> <span class="sy0">=</span> mMaxDistance<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">float</span> getMaxDistance<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">return</span> mMaxDistance<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> <span class="kw4">float</span> getX<span class="br0">(</span><span class="kw1">final</span> TouchEvent pTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> pTouchEvent.<span class="me1">getX</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> <span class="kw4">float</span> getY<span class="br0">(</span><span class="kw1">final</span> TouchEvent pTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> pTouchEvent.<span class="me1">getY</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Inner and Anonymous Classes</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">static</span> <span class="kw1">interface</span> ICatapultDetectorListener <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Methods</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onCharge<span class="br0">(</span><span class="kw1">final</span> CatapultDetector pCatapultDetector,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TouchEvent pTouchEvent, <span class="kw1">final</span> <span class="kw4">float</span> pDistance,</pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> <span class="kw4">float</span> pAngle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onShoot<span class="br0">(</span><span class="kw1">final</span> CatapultDetector pCatapultDetector,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TouchEvent pTouchEvent, <span class="kw1">final</span> <span class="kw4">float</span> pDistance,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> pAngle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li></ol><div class="foot">Parsed in 0.130 seconds at 31.87 KB/s, using GeSHi 1.0.8.10</div></div><br />
<br />
<p>Vamos primero a profundizar un poco en el Listener que es lo primero que hay que hacer bajo mi punto de vista</p><br />
<div class="java"><div class="head">Listener de la clase CatapultDetector</div><ol><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">static</span> <span class="kw1">interface</span> ICatapultDetectorListener <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> <span class="kw4">void</span> onCharge<span class="br0">(</span><span class="kw1">final</span> CatapultDetector pCatapultDetector,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TouchEvent pTouchEvent, <span class="kw1">final</span> <span class="kw4">float</span> pDistance,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> pAngle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onShoot<span class="br0">(</span><span class="kw1">final</span> CatapultDetector pCatapultDetector,</pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> TouchEvent pTouchEvent, <span class="kw1">final</span> <span class="kw4">float</span> pDistance,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> pAngle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.091 seconds at 7.05 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Este Listener tiene que responder a dos eventos, cuando estamos cargando y cuando soltamos para realizar el disparo. Para el primero usamos un método onCharge(), que le pasa los siguientes parámetros:<br />
<ul><li><b>pCatapultDetector:</b> El propio detector.</li>
<li><b>pTouchEvent:</b> El evento en pantalla que ha desencadenado la acción.</li>
<li><b>pDistance:</b> la distancia desde el punto incial de pulsación hasta el punto actual.</li>
<li><b>pAngle:</b> En ángulo formado desde el primer punto de pulsación al actual. Este parámetro se puede aplicar a un sprite y girará correctamente .</li>
</ul>Los parámetros del el onShoot() son los mismos, solo que el evento implica disparo. Veamos ahora las variables del Detector.<br />
</p><br />
<div class="java"><div class="head">Variables de la clase CatapultDetector</div><ol><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">float</span> ANGLE_CONSTANT <span class="sy0">=</span> <span class="nu0">90</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">float</span> DEFAULT_MAX_DISTANCE <span class="sy0">=</span> <span class="nu0">80</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Fields</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">// Listener for the Detector</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">final</span> ICatapultDetectorListener mCatapultDetectorListener<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mMaxDistance<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// First Touch</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw4">float</span> mFirstX<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mFirstY<span class="sy0">;</span></pre></li></ol><div class="foot">Parsed in 0.086 seconds at 6.68 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Tenemos primero las constantes<br />
<ul><li><b>ANGLE_CONSTANT:</b> En las pruebas que realicé con el Detector, tenia que sumarle 90 al ángulo que calculaba para que el sprite rotara en la dirección que yo necesitaba.</li>
<li><b>DEFAULT_MAX_DISTANCE:</b> Distancia máxima de carga por defecto, si no se le indica ninguna, la velocidad máxima de carga son 80 pixeles. Esto quiere decir que si alejo el dedo mas de 80 píxeles del punto inicial de toque, no carga a 81 ni a 90, el máximo es 80. Recordad que siempre son 80 pixeles relativos a la resolución deseada de trabajar, Si luego ejecutamos el programa en un terminal con una resolución mayor, AndEngine controlará ésto .</li>
</ul></p><br />
<p>Un repaso a las variables<br />
<ul><li><b>mCatapultDetectorListener:</b> Es un ICatapultDetectorListener que hemos visto antes. Es obligado para un Detector tener un Listener que "escuche" los eventos que este Detector dispara. Se le indica en el constructor de la clase.</li>
<li><b>mMaxDistance:</b> Variable donde guardamos la máxima distancia actual para este detector.</li>
<li><b>mFirstX,mFirstY:</b> Aqui guardamos la posición de la primera pulsación para calcular la distancia el ángulo.</li>
</ul></p><br />
<p>Veamos los dos constructures de la clase</p><br />
<div class="java"><div class="head">Constructores de la clase CatapultDetector</div><ol><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constructors</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> CatapultDetector<span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> ICatapultDetectorListener pCatapultDetectorListener<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span><span class="br0">(</span>DEFAULT_MAX_DISTANCE, pCatapultDetectorListener<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> CatapultDetector<span class="br0">(</span><span class="kw1">final</span> <span class="kw4">float</span> pMaxDistance,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> ICatapultDetectorListener pCatapultDetectorListener<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">setMaxDistance</span><span class="br0">(</span>pMaxDistance<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetectorListener</span> <span class="sy0">=</span> pCatapultDetectorListener<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li></ol><div class="foot">Parsed in 0.086 seconds at 5.98 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Tenemos dos constructores. Al primero se le manda solamente el ICatapultDetectorListener que va a escuchar, con este constructor se usa la máxima distancia por defecto. Éste llama al segundo con el parámetro de maxima distancia con la constante antes vista. El segundo es el más completo, que aparte del listener recibe la máxima distancia de carga.</p><br />
<p>La miga del Detector está en el método onManagedTouchEvent(). Recibe como parámetro únicamente el TouchEvent. Vamos por partes.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> touchX <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">getX</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> touchY <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">getY</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">int</span> action <span class="sy0">=</span> pSceneTouchEvent.<span class="me1">getAction</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li></ol><div class="foot">Parsed in 0.081 seconds at 1.88 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Aqui usamos variables finales para guardar datos que vamos a usar despues. En la primera línea guardamos la posición X pulsada, en la segunda guardamos la posición Y y en la tercera guardamos la acción realizada, en este caso vamos a controlar los siguientes:<br />
<ul><li><b>ACTION_DOWN :</b> Cuando se pulsa la pantalla.</li>
<li><b>ACTION_MOVE :</b> Cuando ya tenemos la pantalla pulsada y lo que hacemos es mover el dedo por la pantalla.</li>
<li><b>ACTION_UP :</b> Acción de levantar el dedo.</li>
</ul></p><br />
<p>Cuando el evento es ACTION_DOWN, lo único que hacemos es guardar los puntos donde hemos pulsado para posteriormente calcular ángulos y distancia.</p><br />
<p>Para el ACTION_MOVE y ACTION_UP tenemos un mismo código que controla los dos.</p><br />
<div class="java"><div class="head">ACTION_MOVE y ACTION_UP</div><ol><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> distanceX <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">abs</span><span class="br0">(</span>touchX <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstX</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> distanceY <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">abs</span><span class="br0">(</span>touchY <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstY</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> distance <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">min</span><span class="br0">(</span><span class="br0">(</span><span class="kw4">float</span><span class="br0">)</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">hypot</span><span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span> distanceX, <span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span> distanceY<span class="br0">)</span>, mMaxDistance<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> <span class="kw4">double</span> angleX <span class="sy0">=</span> touchX <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstX</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">double</span> angleY <span class="sy0">=</span> touchY <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstY</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> angle <span class="sy0">=</span> <span class="br0">(</span><span class="kw4">float</span><span class="br0">)</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">toDegrees</span><span class="br0">(</span><a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">atan2</span><span class="br0">(</span>angleY,</pre></li><li class="li1"><pre class="de1">angleX<span class="br0">)</span><span class="br0">)</span></pre></li><li class="li1"><pre class="de1"><span class="sy0">+</span> ANGLE_CONSTANT<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">if</span> <span class="br0">(</span>action <span class="sy0">==</span> MotionEvent.<span class="me1">ACTION_MOVE</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetectorListener</span>.<span class="me1">onCharge</span><span class="br0">(</span><span class="kw1">this</span>, pSceneTouchEvent,</pre></li><li class="li1"><pre class="de1">distance, angle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetectorListener</span>.<span class="me1">onShoot</span><span class="br0">(</span><span class="kw1">this</span>, pSceneTouchEvent,</pre></li><li class="li2"><pre class="de2">distance, angle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li></ol><div class="foot">Parsed in 0.078 seconds at 8.91 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Primera y segunda linea, cogemos el número de píxeles de distancia desde el primero toque hasta el actual. En la tercera línea calculamos con la función hypot de Math la distancia real entre los dos puntos de toque, el inicial y el actual. En esa tercera línea realmente cogemos el mínimo de la distancia Real y la variable mMaxDistance, con lo cual si la distancia es mayor que la máxima nos devuelve nMaxDistance. Ya tenemos calculada la distancia, vamos a por el ángulo.</p><br />
<p>La mejor manera que encontré de hallar el ángulo entre los dos puntos es la de las siguientes lineas. hasta que guardamos en la variable angle el valor del ángulo. </p><br />
<p>Luego si la acción es ACTION_MOVE lanzamos un onCharge() y si es un ACTION_UP lanzamos un onShoot().</p><br />
<p>Con esto terminamos por completo el Detector, habrá maneras más bonitas y eficientes de hacerlo, pero a mi con esta me vale por ahora. Si alguien ve mejoras/correcciones sobre el Detector le mandaré unas cañas virtuales.</p><br />
<h2>Repaso a la clase Player</h2><br />
<p>Primero si miramos el sprite que hemos creado del jugador, realmente lo hemos guardado en un objeto AnimatedSprite, para poder hacer la animación del balanceo de cuando se suelta el jugador o cuando la pelota lo golpee.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://4.bp.blogspot.com/-gpN3lmNwc8Y/TY4gJV7ygdI/AAAAAAAABKU/je41Exfauqk/s1600/ui_player.png" /></div><br />
<p>Tenemos aqui los diferentes frames de la animación. Vamos al tajo. Definimos una constante para definir el frame máximo para la carga, los dos últimos son para hacer el movimiento de rebote cuando se suelta.<p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> PLAYER_CHARGE_ANIMATIONS <span class="sy0">=</span> <span class="nu0">5</span><span class="sy0">;</span></pre></li></ol><div class="foot">Parsed in 0.073 seconds at 737 B/s, using GeSHi 1.0.8.10</div></div><br />
<p>Ahora añadimos un procedimiento a la clase</p><br />
<div class="java"><div class="head">Añadir este procedimiento a la clase Player</div><ol><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> setCharge<span class="br0">(</span><span class="kw1">final</span> <span class="kw4">float</span> angle, <span class="kw1">final</span> <span class="kw4">float</span> distance<span class="br0">)</span></pre></li><li class="li1"><pre class="de1"><span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">int</span> step <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">round</span><span class="br0">(</span>distance <span class="sy0">*</span> PLAYER_CHARGE_ANIMATIONS <span class="sy0">/</span> Main.<span class="me1">MAX_CHARGE_DISTANCE</span><span class="br0">)</span><span class="sy0">;</span> </pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">stopAnimation</span><span class="br0">(</span>step<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">setRotation</span><span class="br0">(</span>angle<span class="br0">)</span><span class="sy0">;</span> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.067 seconds at 3.32 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>En la primera linea sacamos por una regla de 3 el paso correspondiente a la distancia que nos ha enviado el Detector. Aqui usamos una constante Main.MAX_CHARGE_DISTANCE que definiremos después. Una vez tenemos el sprite que vamos a pintar, usamos el método stopAnimation de SpriteAnimation para parar la animación en ese frame y luego lo rotamos en el ángulo que toca.</p><br />
<p>Vamos ahora al <b>Main.java</b> y metemos esa constante. A mi se me quedan así.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> CAMERA_WIDTH <span class="sy0">=</span> <span class="nu0">480</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> CAMERA_HEIGHT <span class="sy0">=</span> <span class="nu0">320</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">float</span> MAX_CHARGE_DISTANCE <span class="sy0">=</span> <span class="nu0">80</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Astring+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">String</span></a> TAG <span class="sy0">=</span> <span class="st0">"AndEngineTest"</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li></ol><div class="foot">Parsed in 0.069 seconds at 4.94 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Ahora en el onLoadScene() tocamos donde se crea el CatapultDetector y le pasamos esta constante.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span> <span class="sy0">=</span> <span class="kw1">new</span> SurfaceScrollDetector<span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span>.<span class="me1">setEnabled</span><span class="br0">(</span><span class="kw2">false</span><span class="br0">)</span><span class="sy0">;</span> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetector</span> <span class="sy0">=</span> <span class="kw1">new</span> CatapultDetector<span class="br0">(</span>MAX_CHARGE_DISTANCE,<span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mCatapultDetector</span>.<span class="me1">setEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li></ol><div class="foot">Parsed in 0.089 seconds at 2.46 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Y cambiamos el método onCharge()</p><br />
<div class="java"><ol><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onCharge<span class="br0">(</span>CatapultDetector pCatapultDetector,</pre></li><li class="li1"><pre class="de1">TouchEvent pTouchEvent, <span class="kw4">float</span> pDistance, <span class="kw4">float</span> pAngle<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mActivePlayer</span>.<span class="me1">setCharge</span><span class="br0">(</span>pAngle,pDistance<span class="br0">)</span><span class="sy0">;</span> </pre></li><li class="li2"><pre class="de2"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.076 seconds at 2.42 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Donde le pasamos al jugador la carga. Con esto ya funciona perfectamente el movimiento. En mi caso esto funciona bien. Si teneis algún problema con esta parte del tutorial decidmelo y aclaro ese punto. Por hoy está bien, en el siguiente voy a intentar hacer las animaciones de soltar al jugador, y poner un HUD para el marcador.</p>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com6tag:blogger.com,1999:blog-373973123198193259.post-15911014926498666952011-03-25T17:14:00.000+01:002011-03-25T17:14:21.235+01:00Introducción a AndEngine (Parte IV)<h2>Anteriormente en Droideando</h2><br />
<ul><li><a href="http://droideando.blogspot.com/2011/03/introduccion-andengine-parte-i.html">Introducción a AndEngine (Parte I)</a></li>
<li><a href="http://droideando.blogspot.com/2011/03/introduccion-andengine-parte-ii.html">Introducción a AndEngine (Parte II)</a></li>
<li><a href="http://droideando.blogspot.com/2011/03/introduccion-andengine-parte-iii.html">Introducción a AndEngine (Parte III)</a></li>
</ul><br />
<h2>Objetivos de hoy</h2><ul><li>Crear el sprite del jugador</li>
<li>Crear un Detector de AndEngine para el efecto de catapulta en el jugador</li>
</ul></p><br />
<br />
<h2>Creamos el jugador</h2><br />
<p>Para crear el jugador he decidido usar un AnimatedSprite, pero como seguro que le tengo que meter alguna cosa, heredo la clase y la uso.</p><br />
<p>Para crear la clase, vamos a la carpeta de nuestros fuentes en Eclipse. File New -> Class y le ponemos Name Player y SuperClass AnimatedSprite. Le añadimos un TAG para el debug y por ahora listo.Se nos queda algo así.<p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">com.pruebas.andengine</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.sprite.AnimatedSprite</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.HoldDetector</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.HoldDetector.IHoldDetectorListener</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.region.TiledTextureRegion</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">android.util.Log</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> <span class="kw1">class</span> Player <span class="kw1">extends</span> AnimatedSprite <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Astring+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">String</span></a> TAG <span class="sy0">=</span> <span class="st0">"Player"</span><span class="sy0">;</span> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> Player<span class="br0">(</span><span class="kw4">float</span> pX, <span class="kw4">float</span> pY, TiledTextureRegion pTiledTextureRegion<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">super</span><span class="br0">(</span>pX, pY, pTiledTextureRegion<span class="br0">)</span><span class="sy0">;</span> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li></ol><div class="foot">Parsed in 0.077 seconds at 7.25 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Ahora volvemos al Main.java y añadimos una variable para guardar el jugador activo y cambamos la variable mFaceTextureRegion por mBallTextureRegion para que el nombre coincida con lo que lleva dentro, y le cambiamos también el tipo a TiledTextureRegion. Se queda así.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Fields</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> ZoomCamera mCamera<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> Texture mTexture<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> TiledTextureRegion mBallTextureRegion<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> TiledTextureRegion mPlayerTextureRegion<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> SurfaceScrollDetector mScrollDetector<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> TMXTiledMap mTMXTiledMap<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> Player mActivePlayer<span class="sy0">;</span></pre></li></ol><div class="foot">Parsed in 0.106 seconds at 3.86 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Aqui pongo el sprite del jugador para que lo bajeis a vuestro proyecto, en la carpeta assets/gfx como de costumbre</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-SLfKJU3H3I8/TYyjXa0r_4I/AAAAAAAABJ4/MKsX1xD9FEU/s1600/ui_player.png" /></div><br />
<p>Pongo también el sprite de la pelota (provisional, necesito un balón de verdad para echarle fotos), al mismo sitio assets/gfx.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-ehSy0NklOKM/TYymU4udGJI/AAAAAAAABKA/dn94ihFTb34/s1600/ui_ball.png" /></div><br />
<p>Ahora vamos a cambiar la carga de texturas para cargar estas dos nuevas textuas. La carga de texturas se hace en el objeto mTexture. El objeto mTexture debe ser por exigencias de AndEngine tanto en altura como longitud potencias de 2 en píxeles. Para las texturas que tenemos ahora mismo, lo mínimo sin despercidicar ni un pixel en memoria es 256X256 píxeles. La textura en memoria se quedaría algo como ésto:</p><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/--OHO1VUn6KU/TYyozzPheSI/AAAAAAAABKI/qEuPZ85evTU/s1600/paso1.png" /></div><br />
<p>Ahora vamos a cambiar en onLoadResources para cargar todo esto que hemos metido nuevo. Primero el tamaño de la textura pasa a ser 256X256 para poder albergar las texturas que hemos metido nuevas. A la hora de crear la textura de la pelota, usamos la funcion createTiledFromAsset(), que usa los siguientes parámetros:<br />
<ul><li><b>this.mTexture:</b> El primero parámetro es el objeto textura donde lo vamos a guardar. En el objeto mTexture de la clase.</li>
<li><b>this:</b> La clase actual. Pocos comentarios al respecto.</li>
<li><b>"gfx/ui_ball.png":</b> La ruta a la imagen.</li>
<li><b>0,0:</b> los dos siguientes parámetros es donde vamos a colocar éste objeto dentro de mTexture, en este caso vamos a colocar la pelota en la parte de la izquierda y el jugador en la derecha, o sea, para la pelota le ponemos 0,0 y para el jugador 128,0.</li>
<li><b>2,4:</b> Número de Filas y Columnas, en el caso tanto de la pelota como del jugador son 2,4.</li>
</ul>Se queda una cosa así:<br />
</p><br />
<div class="java"><ol><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onLoadResources<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mTexture</span> <span class="sy0">=</span> <span class="kw1">new</span> Texture<span class="br0">(</span><span class="nu0">256</span>, <span class="nu0">256</span>,</pre></li><li class="li1"><pre class="de1">TextureOptions.<span class="me1">BILINEAR_PREMULTIPLYALPHA</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mBallTextureRegion</span> <span class="sy0">=</span> TextureRegionFactory.<span class="me1">createTiledFromAsset</span><span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mTexture</span>, <span class="kw1">this</span>, <span class="st0">"gfx/ui_ball.png"</span>, <span class="nu0">0</span>, <span class="nu0">0</span>, <span class="nu0">2</span>, <span class="nu0">4</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mPlayerTextureRegion</span> <span class="sy0">=</span> TextureRegionFactory.<span class="me1">createTiledFromAsset</span><span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mTexture</span>, <span class="kw1">this</span>, <span class="st0">"gfx/ui_player.png"</span>, <span class="nu0">128</span>, <span class="nu0">0</span>, <span class="nu0">2</span>, <span class="nu0">4</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mEngine</span>.<span class="me1">getTextureManager</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">loadTexture</span><span class="br0">(</span><span class="kw1">this</span>.<span class="me1">mTexture</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.074 seconds at 6.24 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Ahora vamos a tocar el método onLoadScene(). Primero eliminamos el código que creaba la bola y desactivamos el Detector de Scroll. El final del procedimiento se me queda así.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1">scene.<span class="me1">setOnAreaTouchTraversalFrontToBack</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span> <span class="sy0">=</span> <span class="kw1">new</span> SurfaceScrollDetector<span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span>.<span class="me1">setEnabled</span><span class="br0">(</span><span class="kw2">false</span><span class="br0">)</span><span class="sy0">;</span> <span class="co1">//Hemos puesto esto a false</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="coMULTI">/*</span></pre></li><li class="li1"><pre class="de1"><span class="coMULTI"> final int centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;</span></pre></li><li class="li1"><pre class="de1"><span class="coMULTI"> final int centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion</span></pre></li><li class="li1"><pre class="de1"><span class="coMULTI"> .getHeight()) / 2;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="coMULTI"> final Sprite ball = new Sprite(centerX, centerY,</span></pre></li><li class="li1"><pre class="de1"><span class="coMULTI"> this.mFaceTextureRegion);</span></pre></li><li class="li1"><pre class="de1"><span class="coMULTI"> scene.getLastChild().attachChild(ball);</span></pre></li><li class="li1"><pre class="de1"><span class="coMULTI"> */</span></pre></li><li class="li2"><pre class="de2">scene.<span class="me1">setOnSceneTouchListener</span><span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">scene.<span class="me1">setTouchAreaBindingEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> scene<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.077 seconds at 7.57 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Ahora metemos el jugador en pantalla y ya podemos probar como se ve y eso. Para ello creamos un método createPlayer().</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw4">void</span> createPlayer<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> Scene scene <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">mEngine</span>.<span class="me1">getScene</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> Player sprite <span class="sy0">=</span> <span class="kw1">new</span> Player<span class="br0">(</span><span class="nu0">200</span>, <span class="nu0">100</span>, <span class="kw1">this</span>.<span class="me1">mPlayerTextureRegion</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// scene.registerTouchArea(sprite);</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1">scene.<span class="me1">getLastChild</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">attachChild</span><span class="br0">(</span>sprite<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mActivePlayer</span> <span class="sy0">=</span> sprite<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.069 seconds at 5.99 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Aqui lo que hacemos es para probar ponemos un jugador en la posicion 200,100. Ahora llamamos a este método desde onLoadComplete().</p><br />
<div class="java"><ol><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onLoadComplete<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">// scene.set </span></pre></li><li class="li1"><pre class="de1">createPlayer<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.072 seconds at 1.08 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>En este punto ya podemos ejecutar el programa para ver como va la cosa. Se ve el cesped y el jugador, pero no responde al Scroll porque lo hemos desactivado. Por ahora todo va bien. Vamos a crear el Detector.</p><br />
<h2>Creando un Detector</h2><br />
<p>Mirando un poco los fuentes del ScrollDetector, que funciona de fábula y siendo el juego tipo catapultas bastante popular, porqué no hacer un Detector de catapultas?? Manos a la obra.</p><br />
<p>Creamos una nueva clase en nuestro proyecto. Nombre: CatapultDetector y SuperClass BaseDetector (org.anddev.andengine.input.touch.detector.BaseDetector)</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">com.pruebas.andengine</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.TouchEvent</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.BaseDetector</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">class</span> CatapultDetector <span class="kw1">extends</span> BaseDetector <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> <span class="kw4">boolean</span> onManagedTouchEvent<span class="br0">(</span>TouchEvent pSceneTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// TODO Auto-generated method stub</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li></ol><div class="foot">Parsed in 0.091 seconds at 3.82 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Un detector es un objeto para usarlo como hicimos con el ScrollDetector en el anterior tutorial. Necesitamos una interface listener. Vamos a ello.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">static</span> <span class="kw1">interface</span> ICatapultDetectorListener <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> <span class="kw4">void</span> onCharge<span class="br0">(</span><span class="kw1">final</span> CatapultDetector pCatapultDetector,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TouchEvent pTouchEvent, <span class="kw1">final</span> <span class="kw4">float</span> pDistance,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> pAngle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onShoot<span class="br0">(</span><span class="kw1">final</span> CatapultDetector pCatapultDetector,</pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> TouchEvent pTouchEvent, <span class="kw1">final</span> <span class="kw4">float</span> pDistance,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> pAngle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li></ol><div class="foot">Parsed in 0.102 seconds at 6.30 KB/s, using GeSHi 1.0.8.10</div></div><br />
<br />
<p>Este es un listener básico para probar el funcionamiento. Al objeto que esté escuchando le pasamos un ángulo y una distancia. Esta clase la definimos dentro de la CatapultDetector al final como en los demás Detectors que he visto en los fuentes de AndEngine.</p><br />
<p>Vamos a meterle algunas variables al Detector que algunas las vamos a usar ya mismo y otras las usaremos después. No preocuparse por los warnings, ya nos encargaremos de eso más tarde</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">float</span> TRIGGER_SCROLL_MINIMUM_DISTANCE_DEFAULT <span class="sy0">=</span> <span class="nu0">10</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">float</span> ANGLE_CONSTANT <span class="sy0">=</span> <span class="nu0">10</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> DEFAULT_STEPS <span class="sy0">=</span> <span class="nu0">6</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> DEFAULT_MAX_DISTANCE <span class="sy0">=</span> <span class="nu0">100</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Fields</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">//Minimum distance to execute </span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mTriggerScrollMinimumDistance<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">//Listener for the Detector</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">final</span> ICatapultDetectorListener mCatapultDetectorListener<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">boolean</span> mTriggered<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">//First Touch</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mFirstX<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mFirstY<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">//Last Touch</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw4">float</span> mLastX<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mLastY<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">int</span> mSteps<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mMaxDistance<span class="sy0">;</span></pre></li></ol><div class="foot">Parsed in 0.088 seconds at 10.05 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Creamos unos métodos que usaremos después y los Getter y Setter para mTriggerScrollMinimumDistance.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Getter & Setter</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> <span class="kw4">void</span> setTriggerScrollMinimumDistance<span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw4">float</span> mTriggerScrollMinimumDistance<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mTriggerScrollMinimumDistance</span> <span class="sy0">=</span> mTriggerScrollMinimumDistance<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> <span class="kw4">float</span> getTriggerScrollMinimumDistance<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> mTriggerScrollMinimumDistance<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Methods</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> <span class="kw4">float</span> getX<span class="br0">(</span><span class="kw1">final</span> TouchEvent pTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> pTouchEvent.<span class="me1">getX</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> <span class="kw4">float</span> getY<span class="br0">(</span><span class="kw1">final</span> TouchEvent pTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> pTouchEvent.<span class="me1">getY</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.098 seconds at 7.41 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Tocamos un poco los constructores de la clase</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constructors</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> CatapultDetector<span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> ICatapultDetectorListener pCatapultDetectorListener<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span><span class="br0">(</span>TRIGGER_SCROLL_MINIMUM_DISTANCE_DEFAULT, pCatapultDetectorListener<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> CatapultDetector<span class="br0">(</span><span class="kw1">final</span> <span class="kw4">float</span> pTriggerScrollMinimumDistance,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> ICatapultDetectorListener pCatapultDetectorListener<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">setTriggerScrollMinimumDistance</span><span class="br0">(</span>pTriggerScrollMinimumDistance<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetectorListener</span> <span class="sy0">=</span> pCatapultDetectorListener<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.077 seconds at 7.53 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Y ahora tocamos el método donde se va a llevar todo a cabo, para nuestra primera prueba nos vale algo sencillo como ésto</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods for/from SuperClass/Interfaces</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> <span class="kw4">boolean</span> onManagedTouchEvent<span class="br0">(</span>TouchEvent pSceneTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> touchX <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">getX</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> touchY <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">getY</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">switch</span> <span class="br0">(</span>pSceneTouchEvent.<span class="me1">getAction</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">case</span> MotionEvent.<span class="me1">ACTION_DOWN</span><span class="sy0">:</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mFirstX</span> <span class="sy0">=</span> touchX<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mFirstY</span> <span class="sy0">=</span> touchY<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mLastX</span> <span class="sy0">=</span> touchX<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mLastY</span> <span class="sy0">=</span> touchY<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mTriggered</span> <span class="sy0">=</span> <span class="kw2">false</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">case</span> MotionEvent.<span class="me1">ACTION_MOVE</span><span class="sy0">:</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">case</span> MotionEvent.<span class="me1">ACTION_UP</span><span class="sy0">:</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">case</span> MotionEvent.<span class="me1">ACTION_CANCEL</span><span class="sy0">:</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> distanceX <span class="sy0">=</span> touchX <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mLastX</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> distanceY <span class="sy0">=</span> touchY <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mLastY</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">if</span> <span class="br0">(</span>pSceneTouchEvent.<span class="me1">getAction</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">==</span> MotionEvent.<span class="me1">ACTION_MOVE</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> triggerScrollMinimumDistance <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">mTriggerScrollMinimumDistance</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">if</span> <span class="br0">(</span><span class="kw1">this</span>.<span class="me1">mTriggered</span></pre></li><li class="li1"><pre class="de1"><span class="sy0">||</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">abs</span><span class="br0">(</span>distanceX<span class="br0">)</span> <span class="sy0">></span> triggerScrollMinimumDistance</pre></li><li class="li1"><pre class="de1"><span class="sy0">||</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">abs</span><span class="br0">(</span>distanceY<span class="br0">)</span> <span class="sy0">></span> triggerScrollMinimumDistance<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> distance <span class="sy0">=</span> <span class="br0">(</span><span class="kw4">float</span><span class="br0">)</span><a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">hypot</span><span class="br0">(</span><span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span>distanceX,<span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span>distanceY<span class="br0">)</span><span class="sy0">;</span> </pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">double</span> angleX <span class="sy0">=</span> touchX <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstX</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> <span class="kw4">double</span> angleY <span class="sy0">=</span> touchY <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstY</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> angle <span class="sy0">=</span> <span class="br0">(</span><span class="kw4">float</span><span class="br0">)</span><a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">toDegrees</span><span class="br0">(</span><a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">atan2</span><span class="br0">(</span>angleY, angleX<span class="br0">)</span><span class="br0">)</span><span class="sy0">+</span>ANGLE_CONSTANT<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetectorListener</span>.<span class="me1">onCharge</span><span class="br0">(</span><span class="kw1">this</span>, pSceneTouchEvent, distance, angle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mLastX</span> <span class="sy0">=</span> touchX<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mLastY</span> <span class="sy0">=</span> touchY<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mTriggered</span> <span class="sy0">=</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">else</span></pre></li><li class="li1"><pre class="de1"><span class="br0">{</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">default</span><span class="sy0">:</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li></ol><div class="foot">Parsed in 0.097 seconds at 16.70 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Ya entraré mas a detalle en otro artículo de como funciona el Detector, pero mirando los fuentes puedes hacerte una idea bastante clara. Con esto ya tenemos el Detector en el punto para probarlo. Volvamos al Main.java. Creamos una variable privada para albergar el detector.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Fields</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> ZoomCamera mCamera<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> Texture mTexture<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> TiledTextureRegion mBallTextureRegion<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> TiledTextureRegion mPlayerTextureRegion<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> SurfaceScrollDetector mScrollDetector<span class="sy0">;</span> </pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> TMXTiledMap mTMXTiledMap<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> Player mActivePlayer<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> CatapultDetector mCatapultDetector<span class="sy0">;</span> <span class="co1">//Nueva variable Creada</span></pre></li></ol><div class="foot">Parsed in 0.078 seconds at 6.09 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Ahora necesitamos le decimos a nuestra Clase Main, que implemente la interface ICatapultDetectorListener.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">class</span> Main <span class="kw1">extends</span> BaseGameActivity <span class="kw1">implements</span> IScrollDetectorListener,</pre></li><li class="li1"><pre class="de1">IOnSceneTouchListener, ICatapultDetectorListener</pre></li></ol><div class="foot">Parsed in 0.082 seconds at 1.54 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Ahora implementamos los métodos de ICatapultDetectorListener.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onCharge<span class="br0">(</span>CatapultDetector pCatapultDetector,</pre></li><li class="li1"><pre class="de1">TouchEvent pTouchEvent, <span class="kw4">float</span> pDistance, <span class="kw4">float</span> pAngle<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1">Log.<span class="me1">d</span><span class="br0">(</span>TAG, <span class="st0">"Cargando... {Distancia:"</span> <span class="sy0">+</span> pDistance <span class="sy0">+</span> <span class="st0">", angulo: "</span></pre></li><li class="li2"><pre class="de2"><span class="sy0">+</span> pAngle <span class="sy0">+</span> <span class="st0">"}"</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mActivePlayer</span>.<span class="me1">setRotation</span><span class="br0">(</span>pAngle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onShoot<span class="br0">(</span>CatapultDetector pCatapultDetector,</pre></li><li class="li1"><pre class="de1">TouchEvent pTouchEvent, <span class="kw4">float</span> pDistance, <span class="kw4">float</span> pAngle<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1">Log.<span class="me1">d</span><span class="br0">(</span>TAG, <span class="st0">"Disparo... {Distancia:"</span> <span class="sy0">+</span> pDistance <span class="sy0">+</span> <span class="st0">", angulo: "</span> <span class="sy0">+</span> pAngle</pre></li><li class="li1"><pre class="de1"><span class="sy0">+</span> <span class="st0">"}"</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.084 seconds at 5.75 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>En el método onCharge() rotamos el jugador el ángulo que correspode, en el onShoot() un debug solamente, aunque realmente en el estado del detector no se va a disparar este evento aún. Lo siguiente es crear en el onLoadScene() el Scroll y asignarlo.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span> <span class="sy0">=</span> <span class="kw1">new</span> SurfaceScrollDetector<span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span>.<span class="me1">setEnabled</span><span class="br0">(</span><span class="kw2">false</span><span class="br0">)</span><span class="sy0">;</span> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">//Creamos el detector de catapulta</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mCatapultDetector</span> <span class="sy0">=</span> <span class="kw1">new</span> CatapultDetector<span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetector</span>.<span class="me1">setEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li></ol><div class="foot">Parsed in 0.093 seconds at 2.55 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Y en el onSceneTouchEvent le pasamos el evento al CatapultDetector.</p><br />
<br />
<div class="java"><ol><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">boolean</span> onSceneTouchEvent<span class="br0">(</span>Scene pScene, TouchEvent pSceneTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">if</span> <span class="br0">(</span><span class="kw1">this</span>.<span class="me1">mActivePlayer</span> <span class="sy0">!=</span> <span class="kw2">null</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetector</span>.<span class="me1">onTouchEvent</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.079 seconds at 2.59 KB/s, using GeSHi 1.0.8.10</div></div><br />
<br />
<p>Ya tenemos el proyecto en otro momento para poder ejecutar y ver que está pasando por debajo de todo ésto. F11 y arranca splash... aparece el campo con el jugador, hacemos click en cualquier sitio, y al mover el dedo por la pantalla vemos como el jugador gira, aunque no lo hace en el ángulo correcto, pero es un principio. Ahora mismo mis archivos están asi:</p><br />
<br />
<div class="java"><div class="head">Main.java</div><ol><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">com.pruebas.andengine</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.Engine</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.camera.ZoomCamera</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.options.EngineOptions</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXProperties</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXTile</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXTileProperty</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.ITMXTilePropertiesListener</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.scene.Scene</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.sprite.AnimatedSprite</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.sprite.Sprite</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.util.FPSLogger</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.TouchEvent</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.ScrollDetector</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.SurfaceScrollDetector</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.ScrollDetector.IScrollDetectorListener</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.Texture</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.TextureOptions</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.region.TextureRegion</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.region.TextureRegionFactory</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.region.TiledTextureRegion</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.ui.activity.BaseGameActivity</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.util.Debug</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">android.util.Log</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">com.pruebas.andengine.CatapultDetector.ICatapultDetectorListener</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">class</span> Main <span class="kw1">extends</span> BaseGameActivity <span class="kw1">implements</span> IScrollDetectorListener,</pre></li><li class="li1"><pre class="de1">IOnSceneTouchListener, ICatapultDetectorListener <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> CAMERA_WIDTH <span class="sy0">=</span> <span class="nu0">480</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> CAMERA_HEIGHT <span class="sy0">=</span> <span class="nu0">320</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Astring+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">String</span></a> TAG <span class="sy0">=</span> <span class="st0">"AndEngineTest"</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Fields</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> ZoomCamera mCamera<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> Texture mTexture<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> TiledTextureRegion mBallTextureRegion<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> TiledTextureRegion mPlayerTextureRegion<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> SurfaceScrollDetector mScrollDetector<span class="sy0">;</span> </pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> TMXTiledMap mTMXTiledMap<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> Player mActivePlayer<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> CatapultDetector mCatapultDetector<span class="sy0">;</span> <span class="co1">//Nueva variable Creada</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constructors</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Getter & Setter</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods for/from SuperClass/Interfaces</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onLoadComplete<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> </pre></li><li class="li1"><pre class="de1">createPlayer<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> Engine onLoadEngine<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span> <span class="sy0">=</span> <span class="kw1">new</span> ZoomCamera<span class="br0">(</span><span class="nu0">0</span>, <span class="nu0">0</span>, CAMERA_WIDTH, CAMERA_HEIGHT<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> <span class="kw4">int</span> alturaTotal <span class="sy0">=</span> CAMERA_HEIGHT <span class="sy0">*</span> <span class="nu0">3</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span>.<span class="me1">setBounds</span><span class="br0">(</span><span class="nu0">0</span>, CAMERA_WIDTH, <span class="nu0">0</span>, alturaTotal<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span>.<span class="me1">setBoundsEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw1">new</span> Engine<span class="br0">(</span><span class="kw1">new</span> EngineOptions<span class="br0">(</span><span class="kw2">true</span>, ScreenOrientation.<span class="me1">LANDSCAPE</span>,</pre></li><li class="li1"><pre class="de1"><span class="kw1">new</span> RatioResolutionPolicy<span class="br0">(</span>CAMERA_WIDTH, CAMERA_HEIGHT<span class="br0">)</span>,</pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mCamera</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onLoadResources<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mTexture</span> <span class="sy0">=</span> <span class="kw1">new</span> Texture<span class="br0">(</span><span class="nu0">256</span>, <span class="nu0">256</span>,</pre></li><li class="li1"><pre class="de1">TextureOptions.<span class="me1">BILINEAR_PREMULTIPLYALPHA</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mBallTextureRegion</span> <span class="sy0">=</span> TextureRegionFactory.<span class="me1">createTiledFromAsset</span><span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mTexture</span>, <span class="kw1">this</span>, <span class="st0">"gfx/ui_ball.png"</span>, <span class="nu0">0</span>, <span class="nu0">0</span>, <span class="nu0">2</span>, <span class="nu0">4</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mPlayerTextureRegion</span> <span class="sy0">=</span> TextureRegionFactory.<span class="me1">createTiledFromAsset</span><span class="br0">(</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mTexture</span>, <span class="kw1">this</span>, <span class="st0">"gfx/ui_player.png"</span>, <span class="nu0">128</span>, <span class="nu0">0</span>, <span class="nu0">2</span>, <span class="nu0">4</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mEngine</span>.<span class="me1">getTextureManager</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">loadTexture</span><span class="br0">(</span><span class="kw1">this</span>.<span class="me1">mTexture</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> Scene onLoadScene<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mEngine</span>.<span class="me1">registerUpdateHandler</span><span class="br0">(</span><span class="kw1">new</span> FPSLogger<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> Scene scene <span class="sy0">=</span> <span class="kw1">new</span> Scene<span class="br0">(</span><span class="nu0">1</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">try</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXLoader tmxLoader <span class="sy0">=</span> <span class="kw1">new</span> TMXLoader<span class="br0">(</span><span class="kw1">this</span>, <span class="kw1">this</span>.<span class="me1">mEngine</span></pre></li><li class="li1"><pre class="de1">.<span class="me1">getTextureManager</span><span class="br0">(</span><span class="br0">)</span>, <span class="co1">// TextureOptions.BILINEAR_PREMULTIPLYALPHA,</span></pre></li><li class="li2"><pre class="de2">TextureOptions.<span class="me1">NEAREST</span>, <span class="kw1">new</span> ITMXTilePropertiesListener<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onTMXTileWithPropertiesCreated<span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXTiledMap pTMXTiledMap,</pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> TMXLayer pTMXLayer,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXTile pTMXTile,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXProperties<span class="sy0"><</span>TMXTileProperty<span class="sy0">></span> pTMXTileProperties<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mTMXTiledMap</span> <span class="sy0">=</span> tmxLoader.<span class="me1">loadFromAsset</span><span class="br0">(</span><span class="kw1">this</span>, <span class="st0">"tmx/field.tmx"</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span> <span class="kw1">catch</span> <span class="br0">(</span><span class="kw1">final</span> TMXLoadException tmxle<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1">Debug.<span class="me1">e</span><span class="br0">(</span>tmxle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXLayer tmxLayer <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">mTMXTiledMap</span>.<span class="me1">getTMXLayers</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">get</span><span class="br0">(</span><span class="nu0">0</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">scene.<span class="me1">getFirstChild</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">attachChild</span><span class="br0">(</span>tmxLayer<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2">scene.<span class="me1">setOnAreaTouchTraversalFrontToBack</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span> <span class="sy0">=</span> <span class="kw1">new</span> SurfaceScrollDetector<span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span>.<span class="me1">setEnabled</span><span class="br0">(</span><span class="kw2">false</span><span class="br0">)</span><span class="sy0">;</span> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mCatapultDetector</span> <span class="sy0">=</span> <span class="kw1">new</span> CatapultDetector<span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetector</span>.<span class="me1">setEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">scene.<span class="me1">setOnSceneTouchListener</span><span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">scene.<span class="me1">setTouchAreaBindingEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> scene<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onCharge<span class="br0">(</span>CatapultDetector pCatapultDetector,</pre></li><li class="li1"><pre class="de1">TouchEvent pTouchEvent, <span class="kw4">float</span> pDistance, <span class="kw4">float</span> pAngle<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1">Log.<span class="me1">d</span><span class="br0">(</span>TAG, <span class="st0">"Cargando... {Distancia:"</span> <span class="sy0">+</span> pDistance <span class="sy0">+</span> <span class="st0">", angulo: "</span></pre></li><li class="li1"><pre class="de1"><span class="sy0">+</span> pAngle <span class="sy0">+</span> <span class="st0">"}"</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mActivePlayer</span>.<span class="me1">setRotation</span><span class="br0">(</span>pAngle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> <span class="kw4">void</span> onShoot<span class="br0">(</span>CatapultDetector pCatapultDetector,</pre></li><li class="li1"><pre class="de1">TouchEvent pTouchEvent, <span class="kw4">float</span> pDistance, <span class="kw4">float</span> pAngle<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1">Log.<span class="me1">d</span><span class="br0">(</span>TAG, <span class="st0">"Disparo... {Distancia:"</span> <span class="sy0">+</span> pDistance <span class="sy0">+</span> <span class="st0">", angulo: "</span> <span class="sy0">+</span> pAngle</pre></li><li class="li1"><pre class="de1"><span class="sy0">+</span> <span class="st0">"}"</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span> </pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onScroll<span class="br0">(</span>ScrollDetector pScollDetector, TouchEvent pTouchEvent,</pre></li><li class="li1"><pre class="de1"><span class="kw4">float</span> pDistanceX, <span class="kw4">float</span> pDistanceY<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mCamera</span>.<span class="me1">offsetCenter</span><span class="br0">(</span><span class="sy0">-</span>pDistanceX, <span class="sy0">-</span>pDistanceY<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">boolean</span> onSceneTouchEvent<span class="br0">(</span>Scene pScene, TouchEvent pSceneTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">if</span> <span class="br0">(</span><span class="kw1">this</span>.<span class="me1">mActivePlayer</span> <span class="sy0">!=</span> <span class="kw2">null</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetector</span>.<span class="me1">onTouchEvent</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw4">void</span> createPlayer<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> Scene scene <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">mEngine</span>.<span class="me1">getScene</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> Player sprite <span class="sy0">=</span> <span class="kw1">new</span> Player<span class="br0">(</span><span class="nu0">200</span>, <span class="nu0">100</span>, <span class="kw1">this</span>.<span class="me1">mPlayerTextureRegion</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">scene.<span class="me1">getLastChild</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">attachChild</span><span class="br0">(</span>sprite<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mActivePlayer</span> <span class="sy0">=</span> sprite<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Inner and Anonymous Classes</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li></ol><div class="foot">Parsed in 0.129 seconds at 53.47 KB/s, using GeSHi 1.0.8.10</div></div><br />
<br />
<div class="java"><div class="head">CatapultDetector.java</div><ol><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">com.pruebas.andengine</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.TouchEvent</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.BaseDetector</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">android.view.MotionEvent</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">class</span> CatapultDetector <span class="kw1">extends</span> BaseDetector <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">float</span> TRIGGER_SCROLL_MINIMUM_DISTANCE_DEFAULT <span class="sy0">=</span> <span class="nu0">10</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">float</span> ANGLE_CONSTANT <span class="sy0">=</span> <span class="nu0">10</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> DEFAULT_STEPS <span class="sy0">=</span> <span class="nu0">6</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw4">float</span> DEFAULT_MAX_DISTANCE <span class="sy0">=</span> <span class="nu0">100</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Fields</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">//Minimum distance to execute </span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mTriggerScrollMinimumDistance<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">//Listener for the Detector</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">final</span> ICatapultDetectorListener mCatapultDetectorListener<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">boolean</span> mTriggered<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">//First Touch</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mFirstX<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw4">float</span> mFirstY<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">//Last Touch</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mLastX<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mLastY<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">int</span> mSteps<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw4">float</span> mMaxDistance<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Constructors</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> CatapultDetector<span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> ICatapultDetectorListener pCatapultDetectorListener<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span><span class="br0">(</span>TRIGGER_SCROLL_MINIMUM_DISTANCE_DEFAULT, pCatapultDetectorListener<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> CatapultDetector<span class="br0">(</span><span class="kw1">final</span> <span class="kw4">float</span> pTriggerScrollMinimumDistance,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> ICatapultDetectorListener pCatapultDetectorListener<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">setTriggerScrollMinimumDistance</span><span class="br0">(</span>pTriggerScrollMinimumDistance<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetectorListener</span> <span class="sy0">=</span> pCatapultDetectorListener<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods for/from SuperClass/Interfaces</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// =========================================================== </span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> <span class="kw4">boolean</span> onManagedTouchEvent<span class="br0">(</span>TouchEvent pSceneTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> touchX <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">getX</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> touchY <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">getY</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">switch</span> <span class="br0">(</span>pSceneTouchEvent.<span class="me1">getAction</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">case</span> MotionEvent.<span class="me1">ACTION_DOWN</span><span class="sy0">:</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mFirstX</span> <span class="sy0">=</span> touchX<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mFirstY</span> <span class="sy0">=</span> touchY<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mLastX</span> <span class="sy0">=</span> touchX<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mLastY</span> <span class="sy0">=</span> touchY<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mTriggered</span> <span class="sy0">=</span> <span class="kw2">false</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">case</span> MotionEvent.<span class="me1">ACTION_MOVE</span><span class="sy0">:</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">case</span> MotionEvent.<span class="me1">ACTION_UP</span><span class="sy0">:</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">case</span> MotionEvent.<span class="me1">ACTION_CANCEL</span><span class="sy0">:</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> distanceX <span class="sy0">=</span> touchX <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mLastX</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> distanceY <span class="sy0">=</span> touchY <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mLastY</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">if</span> <span class="br0">(</span>pSceneTouchEvent.<span class="me1">getAction</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">==</span> MotionEvent.<span class="me1">ACTION_MOVE</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> triggerScrollMinimumDistance <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">mTriggerScrollMinimumDistance</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">if</span> <span class="br0">(</span><span class="kw1">this</span>.<span class="me1">mTriggered</span></pre></li><li class="li1"><pre class="de1"><span class="sy0">||</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">abs</span><span class="br0">(</span>distanceX<span class="br0">)</span> <span class="sy0">></span> triggerScrollMinimumDistance</pre></li><li class="li1"><pre class="de1"><span class="sy0">||</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">abs</span><span class="br0">(</span>distanceY<span class="br0">)</span> <span class="sy0">></span> triggerScrollMinimumDistance<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> distance <span class="sy0">=</span> <span class="br0">(</span><span class="kw4">float</span><span class="br0">)</span><a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">hypot</span><span class="br0">(</span><span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span>distanceX,<span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span>distanceY<span class="br0">)</span><span class="sy0">;</span> </pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">double</span> angleX <span class="sy0">=</span> touchX <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstX</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> <span class="kw4">double</span> angleY <span class="sy0">=</span> touchY <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFirstY</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> angle <span class="sy0">=</span> <span class="br0">(</span><span class="kw4">float</span><span class="br0">)</span><a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">toDegrees</span><span class="br0">(</span><a href="http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Math</span></a>.<span class="me1">atan2</span><span class="br0">(</span>angleY, angleX<span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCatapultDetectorListener</span>.<span class="me1">onCharge</span><span class="br0">(</span><span class="kw1">this</span>, pSceneTouchEvent, distance, angle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mLastX</span> <span class="sy0">=</span> touchX<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mLastY</span> <span class="sy0">=</span> touchY<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mTriggered</span> <span class="sy0">=</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">else</span></pre></li><li class="li1"><pre class="de1"><span class="br0">{</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">default</span><span class="sy0">:</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Getter & Setter</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> setTriggerScrollMinimumDistance<span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw4">float</span> mTriggerScrollMinimumDistance<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mTriggerScrollMinimumDistance</span> <span class="sy0">=</span> mTriggerScrollMinimumDistance<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">float</span> getTriggerScrollMinimumDistance<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> mTriggerScrollMinimumDistance<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> <span class="kw4">float</span> getX<span class="br0">(</span><span class="kw1">final</span> TouchEvent pTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> pTouchEvent.<span class="me1">getX</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">protected</span> <span class="kw4">float</span> getY<span class="br0">(</span><span class="kw1">final</span> TouchEvent pTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> pTouchEvent.<span class="me1">getY</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Inner and Anonymous Classes</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// =========================================================== </span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">static</span> <span class="kw1">interface</span> ICatapultDetectorListener <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Methods</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onCharge<span class="br0">(</span><span class="kw1">final</span> CatapultDetector pCatapultDetector,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TouchEvent pTouchEvent, <span class="kw1">final</span> <span class="kw4">float</span> pDistance,</pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> <span class="kw4">float</span> pAngle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onShoot<span class="br0">(</span><span class="kw1">final</span> CatapultDetector pCatapultDetector,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TouchEvent pTouchEvent, <span class="kw1">final</span> <span class="kw4">float</span> pDistance,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">float</span> pAngle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li></ol><div class="foot">Parsed in 0.126 seconds at 38.60 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Bueno, por hoy está bien, voy a seguir trabajando en el Detector y cuando lo tenga terminado lo pongo en el foro de AndEngine y subo otro artículo siguiendo por la misma línea.</p>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com7tag:blogger.com,1999:blog-373973123198193259.post-56229486713227750332011-03-24T20:07:00.003+01:002011-03-25T12:32:19.686+01:00Introducción a AndEngine (Parte III)<h2>Anteriormente en Droideando</h2><br />
<ul><li><a href="http://droideando.blogspot.com/2011/03/introduccion-andengine-parte-i.html">Introducción a AndEngine (Parte I)</a></li>
<li><a href="http://droideando.blogspot.com/2011/03/introduccion-andengine-parte-ii.html">Introducción a AndEngine (Parte II)</a></li>
</ul><br />
<h2>Objetivo de hoy</h2><br />
<p>Hoy tenemos varios objetivos:<br />
<ul><li>Ponerle una pantalla de splash al juego</li>
<li>Crear el fondo realista de un campo de futbol</li>
</ul></p><br />
<h2>Pantalla de Splash</h2><br />
<p>Todo juego que se precie tiene que empezar con un splash bien bonito. Vamos a ver como podemos hacer ello con AndEngine. Nos ofrece una clase BaseSplashActivity. Nos vamos en "Package Explorer" a src/com.pruebas.andengine y creamos una nueva clase.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://1.bp.blogspot.com/-4R9isXAB24c/TYuE2qz1XQI/AAAAAAAABJI/xelbXU5nI4A/s1600/paso1.png" /></div><br />
<p>Le ponemos en Name SplashExample, y vamos a SuperClass y le damos a buscar la clase BaseSplashActivity y aceptamos.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://1.bp.blogspot.com/-Ajizm-ORG6o/TYuFNbo-xTI/AAAAAAAABJQ/hm-4hiEEsag/s1600/paso2.png" /></div><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-F2fSDSLQfpM/TYuFQr32UKI/AAAAAAAABJY/FzUstyiFf4A/s1600/paso3.png" /></div><br />
<p>Nos genera una clase como esta.<b>OJO:</b> el método getFollowUpActivity por un error del formateador que uso para ésto muestra como comentarios html, ni caso... dejadlo como os lo genera Eclipse. </p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">com.pruebas.andengine</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.source.ITextureSource</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.ui.activity.BaseSplashActivity</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">android.app.Activity</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">class</span> SplashExample <span class="kw1">extends</span> BaseSplashActivity <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="co1">//Ojo, porque esto no se ve bien aqui, dejadlo como Eclipse lo genera</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> Class<span class="sy0"><?</span> <span class="kw1">extends</span> Activity<span class="sy0">></span> getFollowUpActivity<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// TODO Auto-generated method stub</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">return</span> <span class="kw2">null</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> ScreenOrientation getScreenOrientation<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// TODO Auto-generated method stub</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">null</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li2"><pre class="de2"><span class="kw1">protected</span> <span class="kw4">float</span> getSplashDuration<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// TODO Auto-generated method stub</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="nu0">0</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> ITextureSource onGetSplashTextureSource<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// TODO Auto-generated method stub</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">null</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.074 seconds at 11.94 KB/s, using GeSHi 1.0.8.10</div></div><
<p><br />
Ahora vamos a tocar algunas de los métodos de la clase para que muestre el splash que queremos. Si no tienes ninguna imagen de splash que quieras usar, puedes bajarte la que pongo a continuación. <b>OJO</b>: Recuerda guardarla como assets/gfx/splash.png</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-akHDhTx6nP4/TYuHQGlwoWI/AAAAAAAABJg/SrBaw6DVHiU/s1600/splash.png" /></div><br />
<br />
<p>Ahora tocamos la clase para que muestre el splash desde la imagen. primero definimos unas constantes </p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> SPLASH_DURATION <span class="sy0">=</span> <span class="nu0">3</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">float</span> SPLASH_SCALE_FROM <span class="sy0">=</span> 1f<span class="sy0">;</span></pre></li></ol><div class="foot">Parsed in 0.074 seconds at 3.24 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>SPLASH_DURATION define el numero de segundos del splash, 3 está bien. La segunda constante es el origen desde el que se escala... por ejemplo, si pones 0.5f el splash aparecerá pequeñito y llegará a ocupar toda la pantalla.</p><p>En el primer procedimiento getFollowUpActivity(), lo que debemos devolver es la Actividad que se va a ejecutar después del splash. En este caso Main.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> Class<span class="sy0"><?</span> <span class="kw1">extends</span> Activity<span class="sy0">></span> getFollowUpActivity<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> Main.<span class="kw1">class</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.080 seconds at 1.19 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>En el segundo método getScreenOrientation(), debemos devolver la orientación de la pantalla, en este caso es apaisada.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">protected</span> ScreenOrientation getScreenOrientation<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> ScreenOrientation.<span class="me1">LANDSCAPE</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.082 seconds at 1.15 KB/s, using GeSHi 1.0.8.10</div></div><p>Tercer método getSplashDuration(), devolvemos la constante</p><br />
<div class="java"><ol><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">protected</span> <span class="kw4">float</span> getSplashDuration<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> SPLASH_DURATION<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.077 seconds at 1.01 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Y por último onGetSplashTextureSource(), que devolvemos la textura que hemos guardado antes en el disco...</p><br />
<br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">protected</span> ITextureSource onGetSplashTextureSource<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw1">new</span> AssetTextureSource<span class="br0">(</span><span class="kw1">this</span>, <span class="st0">"gfx/splash.png"</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li></ol><div class="foot">Parsed in 0.076 seconds at 1.51 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Ahora implementamos un nuevo método por si queremos hacer el zoom y jugar con él.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">protected</span> <span class="kw4">float</span> getSplashScaleFrom<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> SPLASH_SCALE_FROM<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li></ol><div class="foot">Parsed in 0.077 seconds at 1.06 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Bien, ya tenemos la clase del Splash, ahora hay que meterla en el AndroidManifest.xml y poerla por defecto. Para ello nos vamos a editar el AndroidManifest.xml como texto y añadimos la actividad y la ponemos para que se ejecute al empezar el programa.</p><br />
<div class="xml"><ol><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"><activity</span> <span class="re0">android:name</span>=<span class="st0">"SplashExample"</span></span></pre></li><li class="li1"><pre class="de1"><span class="sc3"> <span class="re0">android:label</span>=<span class="st0">"@string/app_name"</span><span class="re2">></span></span></pre></li><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"><intent-filter<span class="re2">></span></span></span></pre></li><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"><action</span> <span class="re0">android:name</span>=<span class="st0">"android.intent.action.MAIN"</span> <span class="re2">/></span></span></pre></li><li class="li2"><pre class="de2"><span class="sc3"><span class="re1"><category</span> <span class="re0">android:name</span>=<span class="st0">"android.intent.category.LAUNCHER"</span> <span class="re2">/></span></span></pre></li><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"></intent-filter<span class="re2">></span></span></span></pre></li><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"></activity<span class="re2">></span></span></span></pre></li></ol><div class="foot">Parsed in 0.004 seconds at 87.19 KB/s, using GeSHi 1.0.8.10</div></div><br />
<br />
<p>Y eliminamos de la actividad Main los intent-filter para que la única que se ejecute al comenzar el juego sea la del splash. Le damos F11 para correr el proyecto y podmeos ver la pantalla de splash funcionando correctamente.</p><br />
<h2>Creando el fondo del juego</h2><br />
<p>Para crear el fondo del juego hay varias opciones. Primero probé con un RepeatingSpriteBackground, pero no se movía con el scroll de la pantalla, fuera. Mirando por los fuentes de AndEngine he visto una cosa llamada TMXLoader que carga un nivel de un xml y te pone todo en su sitio... me llamó la atención y manos a la obra</p><br />
<p>Afortunadamente tiene un editor de niveles gratuito y open source para todas las pataformas. Lo primero era crear el sprite con el fondo de cesped. Aqui lo teneis. Como siempre va a assets/gfx.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-iPc23JGBoPw/TYuMQZOcUwI/AAAAAAAABJo/_L4KNbDnlOA/s1600/background_tile.png" /></div><br />
<p>El sistema para crear niveles se basa en pngs que estén divididos como un tablero de ajedrez, para mi caso necesitaba las cuatro esquinas, arriba, abajo, izquierda, derecha y centro, 9 sprites.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://4.bp.blogspot.com/-8fYskoXu52k/TYuNux_PAII/AAAAAAAABJw/4TTaqwTIBOk/s1600/background_tile.png" /></div><br />
<p>Pongo el png con los bordes dibujados aqui para que entendais más o menos como lo he estructurado. 9 celdas de 120x120. Ahora me he bajado el editor de mapas. En Debian ha sido muy facil, un buen "sudo apt-get install tiled" y todo solucionado. En debian u otros linux la instalación será similar usando tu gestor de paquetes favorito. En windows puedes ir a <a href="http://www.mapeditor.org/" target="_blank">su web</a> y bajarlo. <b>OJO:</b> Al instalarlo comprobar en Editar->Preferencias donde pone "Almacenar la capa de patrones como" poned Base64 (con compresion gzip), si no AndEngine da errores y no carga el archivo tmx.</p><br />
<p>Tras un rato de diversión obtengo el archivo .tmx que es el mapa con una estructura xml. Ahora vamos a añadirlo al proyecto. Creamos una carpeta nueva en assets que se llame tmx para meter aqui nuestros mapas, y creamos un archivo llamado field.tmx. El mio tiene una pinta así.<br />
</p><div class="xml"><ol><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"><map</span> <span class="re0">version</span>=<span class="st0">"1.0"</span> <span class="re0">orientation</span>=<span class="st0">"orthogonal"</span> <span class="re0">width</span>=<span class="st0">"4"</span> <span class="re0">height</span>=<span class="st0">"8"</span> <span class="re0">tilewidth</span>=<span class="st0">"120"</span> <span class="re0">tileheight</span>=<span class="st0">"120"</span><span class="re2">></span></span></pre></li><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"><tileset</span> <span class="re0">firstgid</span>=<span class="st0">"1"</span> <span class="re0">name</span>=<span class="st0">"background"</span> <span class="re0">tilewidth</span>=<span class="st0">"120"</span> <span class="re0">tileheight</span>=<span class="st0">"120"</span><span class="re2">></span></span></pre></li><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"><image</span> <span class="re0">source</span>=<span class="st0">"gfx/background_tile.png"</span><span class="re2">/></span></span></pre></li><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"></tileset<span class="re2">></span></span></span></pre></li><li class="li2"><pre class="de2"><span class="sc3"><span class="re1"><layer</span> <span class="re0">name</span>=<span class="st0">"Capa de Patrones 1"</span> <span class="re0">width</span>=<span class="st0">"4"</span> <span class="re0">height</span>=<span class="st0">"8"</span><span class="re2">></span></span></pre></li><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"><data</span> <span class="re0">encoding</span>=<span class="st0">"base64"</span> <span class="re0">compression</span>=<span class="st0">"gzip"</span><span class="re2">></span></span></pre></li><li class="li1"><pre class="de1">H4sIAAAAAAAAA2NlYGBghGI2IGYBYk4oZqYBnx2ImaCYA4gB8HAreoAAAAA=</pre></li><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"></data<span class="re2">></span></span></span></pre></li><li class="li1"><pre class="de1"><span class="sc3"><span class="re1"></layer<span class="re2">></span></span></span></pre></li><li class="li2"><pre class="de2"><span class="sc3"><span class="re1"></map<span class="re2">></span></span></span></pre></li></ol><div class="foot">Parsed in 0.006 seconds at 69.25 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Atentos al image-source, apunta a gfx/background_tile.png, si editais el mapa desde tiled luego igual teneis que tocar a donde apuntan las imagenes.</p><p>Antes de empezar a meter código, yo tengo el Main.java así:</p><div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">com.pruebas.andengine</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.Engine</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.camera.ZoomCamera</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.options.EngineOptions</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.scene.Scene</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.scene.background.ColorBackground</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.sprite.Sprite</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.util.FPSLogger</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.TouchEvent</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.ScrollDetector</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.SurfaceScrollDetector</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.ScrollDetector.IScrollDetectorListener</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.Texture</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.TextureOptions</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.region.TextureRegion</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.region.TextureRegionFactory</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.ui.activity.BaseGameActivity</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">android.util.Log</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> <span class="kw1">class</span> Main <span class="kw1">extends</span> BaseGameActivity <span class="kw1">implements</span> IScrollDetectorListener,</pre></li><li class="li1"><pre class="de1">IOnSceneTouchListener <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constants</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> CAMERA_WIDTH <span class="sy0">=</span> <span class="nu0">480</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> CAMERA_HEIGHT <span class="sy0">=</span> <span class="nu0">320</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Astring+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">String</span></a> TAG <span class="sy0">=</span> <span class="st0">"AndEngineTest"</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Fields</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> ZoomCamera mCamera<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> Texture mTexture<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> TextureRegion mFaceTextureRegion<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> SurfaceScrollDetector mScrollDetector<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Constructors</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Getter & Setter</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods for/from SuperClass/Interfaces</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onLoadComplete<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// TODO Auto-generated method stub</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> Engine onLoadEngine<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span> <span class="sy0">=</span> <span class="kw1">new</span> ZoomCamera<span class="br0">(</span><span class="nu0">0</span>, <span class="nu0">0</span>, CAMERA_WIDTH, CAMERA_HEIGHT<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> <span class="kw4">int</span> alturaTotal <span class="sy0">=</span> CAMERA_HEIGHT <span class="sy0">*</span> <span class="nu0">3</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span>.<span class="me1">setBounds</span><span class="br0">(</span><span class="nu0">0</span>, CAMERA_WIDTH, <span class="nu0">0</span>, alturaTotal<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span>.<span class="me1">setBoundsEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw1">new</span> Engine<span class="br0">(</span><span class="kw1">new</span> EngineOptions<span class="br0">(</span><span class="kw2">true</span>, ScreenOrientation.<span class="me1">LANDSCAPE</span>,</pre></li><li class="li1"><pre class="de1"><span class="kw1">new</span> RatioResolutionPolicy<span class="br0">(</span>CAMERA_WIDTH, CAMERA_HEIGHT<span class="br0">)</span>,</pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mCamera</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onLoadResources<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mTexture</span> <span class="sy0">=</span> <span class="kw1">new</span> Texture<span class="br0">(</span><span class="nu0">64</span>, <span class="nu0">64</span>,</pre></li><li class="li1"><pre class="de1">TextureOptions.<span class="me1">BILINEAR_PREMULTIPLYALPHA</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mFaceTextureRegion</span> <span class="sy0">=</span> TextureRegionFactory.<span class="me1">createFromAsset</span><span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mTexture</span>, <span class="kw1">this</span>, <span class="st0">"gfx/ui_ball_1.png"</span>, <span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mEngine</span>.<span class="me1">getTextureManager</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">loadTexture</span><span class="br0">(</span><span class="kw1">this</span>.<span class="me1">mTexture</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> Scene onLoadScene<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mEngine</span>.<span class="me1">registerUpdateHandler</span><span class="br0">(</span><span class="kw1">new</span> FPSLogger<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> Scene scene <span class="sy0">=</span> <span class="kw1">new</span> Scene<span class="br0">(</span><span class="nu0">1</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">scene.<span class="me1">setBackground</span><span class="br0">(</span><span class="kw1">new</span> ColorBackground<span class="br0">(</span><span class="nu0">0</span>, <span class="nu0">0</span>, 0.8784f<span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2">scene.<span class="me1">setOnAreaTouchTraversalFrontToBack</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span> <span class="sy0">=</span> <span class="kw1">new</span> SurfaceScrollDetector<span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span>.<span class="me1">setEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> <span class="kw4">int</span> centerX <span class="sy0">=</span> <span class="br0">(</span>CAMERA_WIDTH <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFaceTextureRegion</span>.<span class="me1">getWidth</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="sy0">/</span> <span class="nu0">2</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">int</span> centerY <span class="sy0">=</span> <span class="br0">(</span>CAMERA_HEIGHT <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFaceTextureRegion</span></pre></li><li class="li1"><pre class="de1">.<span class="me1">getHeight</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="sy0">/</span> <span class="nu0">2</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> Sprite ball <span class="sy0">=</span> <span class="kw1">new</span> Sprite<span class="br0">(</span>centerX, centerY,</pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mFaceTextureRegion</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">scene.<span class="me1">getLastChild</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">attachChild</span><span class="br0">(</span>ball<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">scene.<span class="me1">setOnSceneTouchListener</span><span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">scene.<span class="me1">setTouchAreaBindingEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> scene<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> <span class="kw4">void</span> onScroll<span class="br0">(</span>ScrollDetector pScollDetector, TouchEvent pTouchEvent,</pre></li><li class="li1"><pre class="de1"><span class="kw4">float</span> pDistanceX, <span class="kw4">float</span> pDistanceY<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span>.<span class="me1">offsetCenter</span><span class="br0">(</span><span class="sy0">-</span>pDistanceX, <span class="sy0">-</span>pDistanceY<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">boolean</span> onSceneTouchEvent<span class="br0">(</span>Scene pScene, TouchEvent pSceneTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span>.<span class="me1">onTouchEvent</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Inner and Anonymous Classes</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li></ol><div class="foot">Parsed in 0.106 seconds at 43.53 KB/s, using GeSHi 1.0.8.10</div></div><p>Vamos a crear una variable para el TMXTiledMap.</p><pre class="brush: java">private TMXTiledMap mTMXTiledMap;
</pre><p>En el procedimiento onLoadScene() cuando ponemos el color de fondo con el comando<p><pre class="brush: java">scene.setBackground(new ColorBackground(0, 0, 0.8784f));
</pre><p>Cambiamos ese código por éste otro</p><div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXLoader tmxLoader <span class="sy0">=</span> <span class="kw1">new</span> TMXLoader<span class="br0">(</span><span class="kw1">this</span>, <span class="kw1">this</span>.<span class="me1">mEngine</span></pre></li><li class="li1"><pre class="de1">.<span class="me1">getTextureManager</span><span class="br0">(</span><span class="br0">)</span>,</pre></li><li class="li1"><pre class="de1">TextureOptions.<span class="me1">BILINEAR_PREMULTIPLYALPHA</span>,</pre></li><li class="li1"><pre class="de1"><span class="kw1">new</span> ITMXTilePropertiesListener<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onTMXTileWithPropertiesCreated<span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXTiledMap pTMXTiledMap,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXLayer pTMXLayer,</pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> TMXTile pTMXTile,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXProperties<span class="sy0"><</span>tmxtileproperty<span class="sy0">></span> pTMXTileProperties<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mTMXTiledMap</span> <span class="sy0">=</span> tmxLoader.<span class="me1">loadFromAsset</span><span class="br0">(</span><span class="kw1">this</span>, <span class="st0">"tmx/field.tmx"</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span> <span class="kw1">catch</span> <span class="br0">(</span><span class="kw1">final</span> TMXLoadException tmxle<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1">Debug.<span class="me1">e</span><span class="br0">(</span>tmxle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> TMXLayer tmxLayer <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">mTMXTiledMap</span>.<span class="me1">getTMXLayers</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">get</span><span class="br0">(</span><span class="nu0">0</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">scene.<span class="me1">getFirstChild</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">attachChild</span><span class="br0">(</span>tmxLayer<span class="br0">)</span><span class="sy0">;</span></pre></li></ol><div class="foot">Parsed in 0.078 seconds at 9.36 KB/s, using GeSHi 1.0.8.10</div></div><p>Con esto ya podemos darle a F11 y ver como queda la cosa... bien, no??. Bueno tiene un pequeño problema, por lo menos en el terminal que yo estoy probando, cuando hago scroll me salen unas lineas negras en la junta de las texturas. Investigando un poco por los foros de AndEngine veo la manera de solucionarlo. Vamos a la parte donde creamos la textura de fondo... y cambiamos TextureOptions.BILINEAR_PREMULTIPLYALPHA por TextureOptions.NEAREST. Luego vamos a la parte donde creamos la cámara en onLoadEngine() y ponemos esto para la creación de la cámara para que ajuste a enteros la posición de la cámara y se vea ese feo efecto en la teléfono.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span> <span class="sy0">=</span> <span class="kw1">new</span> ZoomCamera<span class="br0">(</span><span class="nu0">0</span>, <span class="nu0">0</span>, CAMERA_WIDTH, CAMERA_HEIGHT<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onApplyMatrix<span class="br0">(</span>GL10 pGL<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2">GLHelper.<span class="me1">setProjectionIdentityMatrix</span><span class="br0">(</span>pGL<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">GLU.<span class="me1">gluOrtho2D</span><span class="br0">(</span>pGL, <span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="kw1">this</span>.<span class="me1">getMinX</span><span class="br0">(</span><span class="br0">)</span>, <span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="kw1">this</span>.<span class="me1">getMaxX</span><span class="br0">(</span><span class="br0">)</span>,</pre></li><li class="li1"><pre class="de1"><span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="kw1">this</span>.<span class="me1">getMaxY</span><span class="br0">(</span><span class="br0">)</span>, <span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="kw1">this</span>.<span class="me1">getMinY</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"><span class="br0">}</span><span class="sy0">;</span></pre></li></ol><div class="foot">Parsed in 0.091 seconds at 3.29 KB/s, using GeSHi 1.0.8.10</div></div><p>Ale, asunto solucinoado, ya tenemos esto funcionando correctamente. Así se me queda el Main.java.</p><br />
<div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">com.pruebas.andengine</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.Engine</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.camera.ZoomCamera</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.options.EngineOptions</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXProperties</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXTile</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXTileProperty</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.ITMXTilePropertiesListener</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.scene.Scene</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.sprite.Sprite</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.entity.util.FPSLogger</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.TouchEvent</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.ScrollDetector</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.SurfaceScrollDetector</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.input.touch.detector.ScrollDetector.IScrollDetectorListener</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.Texture</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.TextureOptions</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.region.TextureRegion</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.opengl.texture.region.TextureRegionFactory</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.ui.activity.BaseGameActivity</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.anddev.andengine.util.Debug</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">class</span> Main <span class="kw1">extends</span> BaseGameActivity <span class="kw1">implements</span> IScrollDetectorListener,</pre></li><li class="li1"><pre class="de1">IOnSceneTouchListener <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constants</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> CAMERA_WIDTH <span class="sy0">=</span> <span class="nu0">480</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">static</span> <span class="kw1">final</span> <span class="kw4">int</span> CAMERA_HEIGHT <span class="sy0">=</span> <span class="nu0">320</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <a href="http://www.google.com/search?hl=en&q=allinurl%3Astring+java.sun.com&btnI=I%27m%20Feeling%20Lucky"><span class="kw3">String</span></a> TAG <span class="sy0">=</span> <span class="st0">"AndEngineTest"</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Fields</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">private</span> ZoomCamera mCamera<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> Texture mTexture<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> TextureRegion mFaceTextureRegion<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> SurfaceScrollDetector mScrollDetector<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">private</span> TMXTiledMap mTMXTiledMap<span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Constructors</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Getter & Setter</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// Methods for/from SuperClass/Interfaces</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onLoadComplete<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li2"><pre class="de2"><span class="co1">// TODO Auto-generated method stub</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> Engine onLoadEngine<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span> <span class="sy0">=</span> <span class="kw1">new</span> ZoomCamera<span class="br0">(</span><span class="nu0">0</span>, <span class="nu0">0</span>, CAMERA_WIDTH, CAMERA_HEIGHT<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">int</span> alturaTotal <span class="sy0">=</span> CAMERA_HEIGHT <span class="sy0">*</span> <span class="nu0">3</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span>.<span class="me1">setBounds</span><span class="br0">(</span><span class="nu0">0</span>, CAMERA_WIDTH, <span class="nu0">0</span>, alturaTotal<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span>.<span class="me1">setBoundsEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">return</span> <span class="kw1">new</span> Engine<span class="br0">(</span><span class="kw1">new</span> EngineOptions<span class="br0">(</span><span class="kw2">true</span>, ScreenOrientation.<span class="me1">LANDSCAPE</span>,</pre></li><li class="li1"><pre class="de1"><span class="kw1">new</span> RatioResolutionPolicy<span class="br0">(</span>CAMERA_WIDTH, CAMERA_HEIGHT<span class="br0">)</span>,</pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onLoadResources<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mTexture</span> <span class="sy0">=</span> <span class="kw1">new</span> Texture<span class="br0">(</span><span class="nu0">64</span>, <span class="nu0">64</span>,</pre></li><li class="li1"><pre class="de1">TextureOptions.<span class="me1">BILINEAR_PREMULTIPLYALPHA</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mFaceTextureRegion</span> <span class="sy0">=</span> TextureRegionFactory.<span class="me1">createFromAsset</span><span class="br0">(</span></pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mTexture</span>, <span class="kw1">this</span>, <span class="st0">"gfx/ui_ball_1.png"</span>, <span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mEngine</span>.<span class="me1">getTextureManager</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">loadTexture</span><span class="br0">(</span><span class="kw1">this</span>.<span class="me1">mTexture</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> Scene onLoadScene<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mEngine</span>.<span class="me1">registerUpdateHandler</span><span class="br0">(</span><span class="kw1">new</span> FPSLogger<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> Scene scene <span class="sy0">=</span> <span class="kw1">new</span> Scene<span class="br0">(</span><span class="nu0">1</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">try</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXLoader tmxLoader <span class="sy0">=</span> <span class="kw1">new</span> TMXLoader<span class="br0">(</span><span class="kw1">this</span>, <span class="kw1">this</span>.<span class="me1">mEngine</span></pre></li><li class="li1"><pre class="de1">.<span class="me1">getTextureManager</span><span class="br0">(</span><span class="br0">)</span>, <span class="co1">// TextureOptions.BILINEAR_PREMULTIPLYALPHA,</span></pre></li><li class="li2"><pre class="de2">TextureOptions.<span class="me1">NEAREST</span>, <span class="kw1">new</span> ITMXTilePropertiesListener<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">void</span> onTMXTileWithPropertiesCreated<span class="br0">(</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXTiledMap pTMXTiledMap,</pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> TMXLayer pTMXLayer,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXTile pTMXTile,</pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXProperties<span class="sy0"><</span>tmxtileproperty<span class="sy0">></span> pTMXTileProperties<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mTMXTiledMap</span> <span class="sy0">=</span> tmxLoader.<span class="me1">loadFromAsset</span><span class="br0">(</span><span class="kw1">this</span>, <span class="st0">"tmx/field.tmx"</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span> <span class="kw1">catch</span> <span class="br0">(</span><span class="kw1">final</span> TMXLoadException tmxle<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1">Debug.<span class="me1">e</span><span class="br0">(</span>tmxle<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> TMXLayer tmxLayer <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">mTMXTiledMap</span>.<span class="me1">getTMXLayers</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">get</span><span class="br0">(</span><span class="nu0">0</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">scene.<span class="me1">getFirstChild</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">attachChild</span><span class="br0">(</span>tmxLayer<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2">scene.<span class="me1">setOnAreaTouchTraversalFrontToBack</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span> <span class="sy0">=</span> <span class="kw1">new</span> SurfaceScrollDetector<span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span>.<span class="me1">setEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="kw1">final</span> <span class="kw4">int</span> centerX <span class="sy0">=</span> <span class="br0">(</span>CAMERA_WIDTH <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFaceTextureRegion</span>.<span class="me1">getWidth</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="sy0">/</span> <span class="nu0">2</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> <span class="kw4">int</span> centerY <span class="sy0">=</span> <span class="br0">(</span>CAMERA_HEIGHT <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">mFaceTextureRegion</span></pre></li><li class="li1"><pre class="de1">.<span class="me1">getHeight</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="sy0">/</span> <span class="nu0">2</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">final</span> Sprite ball <span class="sy0">=</span> <span class="kw1">new</span> Sprite<span class="br0">(</span>centerX, centerY,</pre></li><li class="li2"><pre class="de2"><span class="kw1">this</span>.<span class="me1">mFaceTextureRegion</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">scene.<span class="me1">getLastChild</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">attachChild</span><span class="br0">(</span>ball<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">scene.<span class="me1">setOnSceneTouchListener</span><span class="br0">(</span><span class="kw1">this</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">scene.<span class="me1">setTouchAreaBindingEnabled</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> scene<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li1"><pre class="de1">@Override</pre></li><li class="li2"><pre class="de2"><span class="kw1">public</span> <span class="kw4">void</span> onScroll<span class="br0">(</span>ScrollDetector pScollDetector, TouchEvent pTouchEvent,</pre></li><li class="li1"><pre class="de1"><span class="kw4">float</span> pDistanceX, <span class="kw4">float</span> pDistanceY<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mCamera</span>.<span class="me1">offsetCenter</span><span class="br0">(</span><span class="sy0">-</span>pDistanceX, <span class="sy0">-</span>pDistanceY<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2">@Override</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">boolean</span> onSceneTouchEvent<span class="br0">(</span>Scene pScene, TouchEvent pSceneTouchEvent<span class="br0">)</span> <span class="br0">{</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">this</span>.<span class="me1">mScrollDetector</span>.<span class="me1">onTouchEvent</span><span class="br0">(</span>pSceneTouchEvent<span class="br0">)</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li2"><pre class="de2"> </pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Methods</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"> </pre></li><li class="li2"><pre class="de2"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// Inner and Anonymous Classes</span></pre></li><li class="li1"><pre class="de1"><span class="co1">// ===========================================================</span></pre></li><li class="li1"><pre class="de1"><span class="br0">}</span></pre></li><li class="li1"><pre class="de1"> </pre></li></ol><div class="foot">Parsed in 0.120 seconds at 48.29 KB/s, using GeSHi 1.0.8.10</div></div><br />
<p>Bueno, por hoy está bien. Para el siguiente capítulo vamos a Implementar nuestro propio Detector, como el IScrollDetector pero para juegos estilo catapulta. Ya lo tengo hecho, pero una cosa es hacerlo y otra ponerlo aquí y explicarlo. Mañana más.</p>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com35tag:blogger.com,1999:blog-373973123198193259.post-86971575663139631812011-03-21T20:19:00.013+01:002011-03-23T00:41:19.578+01:00Introducción a AndEngine (Parte II)<h2>Anteriormente en Droideando</h2><br />
<ul><li><a href="http://droideando.blogspot.com/2011/03/introduccion-andengine-parte-i.html">Introducción a AndEngine (Parte I)</a></li>
</ul><br />
<h2>Creando nuestro primer objeto</h2><br />
<p>Antes de crear nuestro objeto, vamos a tocar un poco el AndroidManifest.xml para añadirle permiso a la aplicación para que bloquee la suspensión del teléfono, bastante útil para un juego. Editamos el archivo y después de la linea donde pone <pre class="brush: xml"><uses-sdk android:minSdkVersion="4" /></pre>ponemos <pre class="brush: xml"><uses-permission android:name="android.permission.WAKE_LOCK"/></pre>.</p><br />
<p>Vamos a crear nuestro primer objeto en pantalla, para usar imágenes en AndEngine no se usa el típico R de android. Creamos una carpeta, en assets llamada gfx.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://4.bp.blogspot.com/-PAmBggJeZ1M/TYeNb--HxdI/AAAAAAAABHE/WZ6-sHmG8AY/s1600/paso1.jpg" /></div><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-zIP_6Z3EG0Q/TYeNfd-Xc-I/AAAAAAAABHM/VYiUIijoVXQ/s1600/paso2.jpg" /></div><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-QXRvfOra_VU/TYeNiLv1NQI/AAAAAAAABHU/_Mms7cdFjxE/s1600/paso3.jpg" /></div><br />
<p>Ahora descarga esta imagen a tu disco duro y ponla en la carpeta assets/gfx de tu proyecto, Puedes guardarla directamente ahí o arrastrarla desde tu carpeta de descargas a la carpeta gfx de eclipse. <strike>Si vas a usar una imagen diferente tienes que tener en cuenta que tanto la anchura de la imagen como la altura en píxeles deben ser potencias de 2</strike>.</p><p>Edito: No es necesario que las imágenes estén en un tamaño que sea potenica de 2. Lo que se necesita que sea una potencia de 2 es el objeto mTexture. Acabo de enterarme como va ésto, el siguiente artículo ya sé de que va a ir..</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-QkUJFcFUsUI/TYeN9JzU75I/AAAAAAAABHc/vv98IJH3wuc/s1600/ui_ball_1.png" /></div><br />
<p>Lo siguiente es tocar nuestro proyecto en eclipse para que se muestre esa imagen. En la parte donde definimos la cámara añadimos 2 variables nuevas.</p><br />
<pre class="brush: java">// ===========================================================
// Fields
// ===========================================================
private ZoomCamera mCamera;
private Texture mTexture;
private TextureRegion mFaceTextureRegion;
</pre><br />
<p>En el método onLoadResources() tenemos que cargar la imagen a memoria.</p><br />
<pre class="brush: java">@Override
public void onLoadResources() {
this.mTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mFaceTextureRegion = TextureRegionFactory.createFromAsset(this.mTexture, this, "gfx/ui_ball_1.png", 0, 0);
this.mEngine.getTextureManager().loadTexture(this.mTexture);
}
</pre><br />
<p>Y finalmente en el método onLoadScene() ponemos el código necesario para mostrar la imagen centrada en la pantalla.</p><br />
<pre class="brush: java">@Override
public Scene onLoadScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene(1);
scene.setBackground(new ColorBackground(0, 0, 0.8784f));
final int centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
final int centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;
/* Dibujamos la bola en el centro de la pantalla. */
final Sprite ball = new Sprite(centerX, centerY, this.mFaceTextureRegion);
scene.getLastChild().attachChild(ball);
return scene;
}
</pre><br />
<p>Ahora si ejecutamos nuestro programa en pantalla sale lo que nosotros esperábamos.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-IouGZDVUxss/TYeQofRUUmI/AAAAAAAABHk/wqGYOGJhSM8/s1600/device_1.png" /></div><br />
<p>Hasta ahora todo correcto. Ahora vamos a controlar el movimiento de la cámara con toques de dedo.</p><br />
<br />
<h2>Controlando el Scroll</h2><br />
<p>Para que funcione el movimiento de la cámara debemos hacer que nuestra clase Main implemente dos clases.</p><br />
<ul><li><b>IScrollDetectorListener: </b> Esta clase es una clase que nos brinda AndEngine para controlar scroll, la implementamos en la clase e implementamos el método al que nos obliga.</p><li><b>IOnSceneTouchListener: </b> Esta clase nos da la posibilidad de controlar la pantalla táctil.</p></ul><p>La clase se nos queda así:</p><pre class="brush: java">public class Main extends BaseGameActivity implements IScrollDetectorListener, IOnSceneTouchListener
</pre><p>Implementamos los métodos necesarios</p><pre class="brush: java">@Override
public void onScroll(ScrollDetector pScollDetector, TouchEvent pTouchEvent,
float pDistanceX, float pDistanceY) {
}
@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
return true;
}
</pre><p>Ahora vamos a poner algo dentro de esos métodos, en onScroll ponemos solamente un mensaje de log, para verlo luego en el debug.</p><pre class="brush: java">@Override
public void onScroll(ScrollDetector pScollDetector, TouchEvent pTouchEvent,
float pDistanceX, float pDistanceY) {
Log.d(TAG, "Scroll {x:"+pDistanceX+", y: "+pDistanceY+"}");
}
</pre><p>En el TouchEvent pasamos el evento directamente al ScrollDetector.</p><pre class="brush: java"> @Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
this.mScrollDetector.onTouchEvent(pSceneTouchEvent);
return true;
}
</pre><p>Tenemos que tocar un poco también el método onLoadScene() para que el engine escuche los enventos de la pantalla táctil:</p><pre class="brush: java">@Override
public Scene onLoadScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene(1);
scene.setBackground(new ColorBackground(0, 0, 0.8784f));
scene.setOnAreaTouchTraversalFrontToBack();
this.mScrollDetector = new SurfaceScrollDetector(this);
this.mScrollDetector.setEnabled(true);
final int centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
final int centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;
/* Dibujamos la bola en el centro de la pantalla. */
final Sprite ball = new Sprite(centerX, centerY, this.mFaceTextureRegion);
scene.getLastChild().attachChild(ball);
scene.setOnSceneTouchListener(this);
scene.setTouchAreaBindingEnabled(true);
return scene;
}
</pre><p>Y añadimos a la clase el ScrollDetector. Con lo cual los Fields se quedan asi</p><pre class="brush: java">// ===========================================================
// Fields
// ===========================================================
private ZoomCamera mCamera;
private Texture mTexture;
private TextureRegion mFaceTextureRegion;
private SurfaceScrollDetector mScrollDetector;
</pre><p>Vamos un momento a la vista debug y definimos dos vistas para poder filtrar la información de Logcat y entender un poco lo que está pasando. Creamos dos Filtros, uno para "AndEngineTest" y otro para "AndEngine".</p><div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://1.bp.blogspot.com/-F0d8mTvlwLs/TYeXyQFO3VI/AAAAAAAABHs/RpG8jMv5gqY/s1600/paso4.jpg" /></div><div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://4.bp.blogspot.com/--CaQrQ99zGI/TYec-9X7deI/AAAAAAAABIc/vrJu2vvgMfc/s1600/paso5.jpg" /></div><div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://1.bp.blogspot.com/-etz3FF7qhXc/TYeX9ciCYaI/AAAAAAAABH8/XQBXTI1TIk8/s1600/paso6.jpg" /></div><div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://4.bp.blogspot.com/-C7WLu176VLg/TYeYB6UTSMI/AAAAAAAABIE/_msPO2a4i4Q/s1600/paso7.jpg" /></div><p>Ahora ya tenemos el entorno preparado para ver un poco de información de lo que pasa por debajo con lo que hemos escrito. Debugeamos el proyecto (F11), pasamos a la vista debug y pinchamos con el dedo en la pantalla y lo movemos hacia arriba y hacia abajo. Ésto es lo que vemos en la pantalla de debug...</p><p>Ahora mismo tenemos los fuentes del Main.java así:</p><pre class="brush: java">package com.pruebas.andengine;
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.ZoomCamera;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.input.touch.detector.ScrollDetector;
import org.anddev.andengine.input.touch.detector.SurfaceScrollDetector;
import org.anddev.andengine.input.touch.detector.ScrollDetector.IScrollDetectorListener;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import android.util.Log;
public class Main extends BaseGameActivity implements IScrollDetectorListener,
IOnSceneTouchListener {
// ===========================================================
// Constants
// ===========================================================
static final int CAMERA_WIDTH = 480;
static final int CAMERA_HEIGHT = 320;
private static final String TAG = "AndEngineTest";
// ===========================================================
// Fields
// ===========================================================
private ZoomCamera mCamera;
private Texture mTexture;
private TextureRegion mFaceTextureRegion;
private SurfaceScrollDetector mScrollDetector;
// ===========================================================
// Constructors
// ===========================================================
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void onLoadComplete() {
// TODO Auto-generated method stub
}
@Override
public Engine onLoadEngine() {
this.mCamera = new ZoomCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
this.mCamera));
}
@Override
public void onLoadResources() {
this.mTexture = new Texture(64, 64,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mFaceTextureRegion = TextureRegionFactory.createFromAsset(
this.mTexture, this, "gfx/ui_ball_1.png", 0, 0);
this.mEngine.getTextureManager().loadTexture(this.mTexture);
}
@Override
public Scene onLoadScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene(1);
scene.setBackground(new ColorBackground(0, 0, 0.8784f));
scene.setOnAreaTouchTraversalFrontToBack();
this.mScrollDetector = new SurfaceScrollDetector(this);
this.mScrollDetector.setEnabled(true);
final int centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
final int centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion
.getHeight()) / 2;
/* Dibujamos la bola en el centro de la pantalla. */
final Sprite ball = new Sprite(centerX, centerY,
this.mFaceTextureRegion);
scene.getLastChild().attachChild(ball);
scene.setOnSceneTouchListener(this);
scene.setTouchAreaBindingEnabled(true);
return scene;
}
@Override
public void onScroll(ScrollDetector pScollDetector, TouchEvent pTouchEvent,
float pDistanceX, float pDistanceY) {
Log.d(TAG, "Scroll {x:" + pDistanceX + ", y: " + pDistanceY + "}");
}
@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
this.mScrollDetector.onTouchEvent(pSceneTouchEvent);
return true;
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
</pre><div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-PK8HOkPqkRg/TYea1Tw_mBI/AAAAAAAABIM/8x3-vMNYfus/s1600/debug1.jpg" /></div><div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-WUaCQSX7XpA/TYea5VgbyrI/AAAAAAAABIU/8NiXk19CdvE/s1600/debug2.jpg" /></div><p>En la pestaña "AndEngine" vemos mensajes del AndEngine, inicialización y muestra cada cierto tiempo los FPS (escenas dibujadas por segundo). En la pestaña "AndEngineTest" vemos lo que hemos colocado en el método onScroll().</p><p>En mi caso he movido el dedo primero arriba y luego hacia abajo verticalmente, y me muestra mensajes que lo corroboran, primero mensajes de scroll con pocas variaciones en el eje X y variaciones positivas en el eje Y, y luego cambiando a variaciones negativas en el eje Y.</p><p>Ya estamos detectando el movimiento del dedo sobre la pantalla y AndEngine nos brinda clases para hacernos más sencillo todo ésto. Ahora vamos a ver como podemos mover la cámara según el scroll, y como definimos los límites.</p><h2>Controlando la cámara</h2><p>Ahora ponemos el siguiente código en nuestro método onScroll()</p><pre class="brush: java">@Override
public void onScroll(ScrollDetector pScollDetector, TouchEvent pTouchEvent,
float pDistanceX, float pDistanceY) {
this.mCamera.offsetCenter(-pDistanceX, -pDistanceY);
}
</pre><p>Ejecutamos y podemos mover la cámara con el dedo, y se mueve fluidamente, pero no tiene límites, se va hasta donde quiera, y lo que me interesa en este caso es que la pantalla tenga unas dimensones determinadas. Para ello tocamos un poco el método onLoadEngine() y solucionado.</p><pre class="brush: java">@Override
public Engine onLoadEngine() {
this.mCamera = new ZoomCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
final int alturaTotal = CAMERA_HEIGHT*3;
this.mCamera.setBounds(0, CAMERA_WIDTH, 0, alturaTotal);
this.mCamera.setBoundsEnabled(true);
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
this.mCamera));
}
</pre><p>Bueno, pues con ésto terminamos la segunda parte la introducción a AndEngine. En la próxima lección intentaré poner un fondo de cesped en con una textura, pintar los jugadores desde un xml y cierta interacción de los jugadores.</p><p>Otras partes del tutorial:</p><ul><li><a href="http://droideando.blogspot.com/2011/03/introduccion-andengine-parte-i.html">Introducción a AndEngine (Parte I)</a></li>
</ul>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com28tag:blogger.com,1999:blog-373973123198193259.post-77962214658144123972011-03-21T18:15:00.000+01:002011-03-21T18:15:12.103+01:00Introducción a AndEngine (Parte I)<h2>Qué es AndEngine</h2><p><a href="http://www.andengine.org/" target="_blank">AndEngine</a> es un Engine 2d usando Opengl para juegos para la plataforma Android.</p><p>En AndEngine se usa una terminología propia, explico aquí los conceptos más básicos</p><ul><li><b>BaseGameActivity:</b> El BaseGameActivity es la raiz del juego, que contiene el motor y crea la vista donde se va a dibujar todo. Hay siempre exactamente un solo Engine por cada BaseGameActivity.</li>
<li><b>Engine:</b> El Engine es el motor interno del juego, se encarga de ir dibujando en pantalla y actualizando objetos en la escena, que contiene todo el contenido que tu juego lleva. Normalmente hay una escena por por Engine, a menos que vayas a usar un SplitScreenEngines.</li>
<li><b>IResolutionPolicy:</b> Una implementacion de IResolutionPolicy interface es parte del EngineOptions. Te hace abstraerte de la resolución del terminal, tú trabajas para una resolución y el AndEngine se encarga del resto.</li>
<li><b>Camera:</b> Un objeto Camera define el rectangulo visible actualmente de la escena actual, no tiene porqué ser la escena completa. Normalmente hay una cámara por escena. Hay subclases específicas que permiten hacer zoom y mover la cámara suavemente.</li>
<li><b>Scene:</b> La clase Scene es el contenedor para todos los objetos que se van a dibujar en la escena. Una escena puede tener Layers, que son capas para ordenar objetos. Hay subclases de la Scene como CameraScene/HUD/MenuScene que tienen comportamientos específicos.</li>
<li><b>Entity:</b> Una entidad es un objeto que puede ser dibujado, como Imagenes, rectángulos, Texto, Líneas. Una entidad tiene posición/rotación/zoom/color... </li>
<li><b>Texture:</b> Una textura es una imagen que se guarda en memoria. En Android, las imágenes deben ser una potencia de 2.</li>
<li><b>ITextureSource:</b> Una implementacion de ITextureSource-interface se encarga de cargar una imagen en una posición en la textura.</li>
<li><b>TextureRegion:</b> Una TextureRegion define un rectangulo en una imagen. Las TextureRegion se usan por Sprites para usar una imagen grande en la que guardamos muchas imagenes pequeñicas.</li>
<li><b>PhysicsConnector:</b> Motor de físicas integrado en el Engine</li>
</ul><br />
<h2>Obteniendo AndEngine</h2><br />
<p>Para obtener andEngine, puedes bajar los fuentes de <a href="http://www.andengine.org/" target="_blank">su página</a> y también puedes bajar un <a href="http://sora101.net/andengine/andengine.jar" target="_blank">jar preparadito</a>, que es lo que yo he usado para esta introducción.</p><br />
<p>Primero bajamos <a href="http://sora101.net/andengine/andengine.jar" target="_blank">este archivo</a> y lo guardamos en el equipo.</p><br />
<h2>Creación del proyecto en Eclipse</h2><br />
<p>Comenzamos como siempre File -> New Project.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://4.bp.blogspot.com/-dSXEON619mk/TYd0FEGqAmI/AAAAAAAABF0/hkZUuaXQNT8/s1600/paso1.jpg" /></div><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://4.bp.blogspot.com/-RSarW103xR8/TYd0TR9tFnI/AAAAAAAABF8/Us8Xy6Sbf08/s1600/paso2.jpg" /></div><br />
<p>Siguiente y Finish. Ahora creamos una carpeta lib en la raiz del proyecto</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://4.bp.blogspot.com/-I501P-Ps7rc/TYd2Mbot0GI/AAAAAAAABGE/nXLR4H3yF7k/s1600/paso3.jpg" /></div><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-b2Vy2UQqS60/TYd2nfdciqI/AAAAAAAABGM/xxudNkLxk7U/s1600/paso4.jpg" /></div><br />
<p>Ahora arrastramos el <a href="http://sora101.net/andengine/andengine.jar" target="_blank">archivo descargado</a> a la carpeta lib de eclipse. Se queda algo así.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-ia07rTXV6Rs/TYd3lDcQp0I/AAAAAAAABGU/UAMOKsazASU/s1600/paso5.jpg" /></div><br />
<p>Ahora botón derecho en el archivo andengine.jar y le damos a Build Path -> Add to Build Path.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-1JBRA6YM1yw/TYd5b2gNm9I/AAAAAAAABGc/Em5FjooVPSU/s1600/paso6.jpg" /></div><br />
<p>Ahora vamos al archivo Main.java y cambiamos Activity por BaseGameActivity. Eliminamos el constructor, organizamos los imports, implementamos los métodos de BaseGameActivity y nos queda algo como esto.</p><br />
<pre class="brush: java">package com.pruebas.andengine;
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import android.os.Bundle;
public class Main extends BaseGameActivity {
@Override
public void onLoadComplete() {
// TODO Auto-generated method stub
}
@Override
public Engine onLoadEngine() {
// TODO Auto-generated method stub
return null;
}
@Override
public void onLoadResources() {
// TODO Auto-generated method stub
}
@Override
public Scene onLoadScene() {
// TODO Auto-generated method stub
return null;
}
}
</pre><br />
<p>Ahora cambiamos un poco la estructura del archivo para que se vea todo un poco más claro</p><br />
<pre class="brush: java">package com.pruebas.andengine;
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.ui.activity.BaseGameActivity;
public class Main extends BaseGameActivity {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
// ===========================================================
// Constructors
// ===========================================================
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void onLoadComplete() {
// TODO Auto-generated method stub
}
@Override
public Engine onLoadEngine() {
// TODO Auto-generated method stub
return null;
}
@Override
public void onLoadResources() {
// TODO Auto-generated method stub
}
@Override
public Scene onLoadScene() {
// TODO Auto-generated method stub
return null;
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
</pre><br />
<h2>Empezando</h2><br />
<p>Ahora vamos a crear una cámara necesaria para el funcionamiento del juego. Creamos variables para definir sobre que resolucion vamos a trabajar y una variable para el TAG que vamos a usar para los mensajes de Log</p><br />
<pre class="brush: java"> // ===========================================================
// Constants
// ===========================================================
static final int CAMERA_WIDTH = 480;
static final int CAMERA_HEIGHT = 320;
private static final String TAG = "AndEngineTest";
// ===========================================================
// Fields
// ===========================================================
private ZoomCamera mCamera;
</pre><br />
<p>Ahora implementamos el procedimiento onLoadEngine()</p><br />
<pre class="brush: java"> @Override
public Engine onLoadEngine() {
this.mCamera = new ZoomCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
}
</pre><br />
<p>Así definimos la cámara, esencial para poder ver algo. Ahora implementamos el procedimiento onLoadScene() y le ponemos un color de fondo.</p><br />
<br />
<pre class="brush: java"> @Override
public Scene onLoadScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene(1);
scene.setBackground(new ColorBackground(0, 0, 0.8784f));
return scene;
}
</pre><br />
<p>Después de organizar los imports y dejarlo todo bonico nos queda así:</p><br />
<pre class="brush: java">package com.pruebas.andengine;
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.ZoomCamera;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.ui.activity.BaseGameActivity;
public class Main extends BaseGameActivity {
// ===========================================================
// Constants
// ===========================================================
static final int CAMERA_WIDTH = 480;
static final int CAMERA_HEIGHT = 320;
private static final String TAG = "AndEngineTest";
// ===========================================================
// Fields
// ===========================================================
private ZoomCamera mCamera;
// ===========================================================
// Constructors
// ===========================================================
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void onLoadComplete() {
// TODO Auto-generated method stub
}
@Override
public Engine onLoadEngine() {
this.mCamera = new ZoomCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
}
@Override
public void onLoadResources() {
// TODO Auto-generated method stub
}
@Override
public Scene onLoadScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene(1);
scene.setBackground(new ColorBackground(0, 0, 0.8784f));
return scene;
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
</pre><br />
<br />
<br />
<p>Ahora vamos a arrancar la aplicación para ver un color de fondo. Vamos a run Configurations</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-EZrqmwb-QZM/TYeF6PtEMFI/AAAAAAAABGk/qQTR-ybsFT8/s1600/paso7.jpg" /></div><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://1.bp.blogspot.com/-F0OF8-OKSCk/TYeGYMIb0aI/AAAAAAAABGs/YKk8gszAo8g/s1600/paso8.jpg" /></div><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-3pugzUnFjHw/TYeGhmQjcLI/AAAAAAAABG0/pBtPn1loYUY/s1600/paso9.jpg" /></div><br />
<p>Apply -> Run y ya podemos ver en nuestro terminal nuestro primer programa con AndEngine.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-Pogradpf_Z0/TYeHiMnFj5I/AAAAAAAABG8/WMuJyqUIcKg/s1600/device.png" /></div><br />
<p>Con esto termina la primera parte del tutorial, en la segunda entrega el objetivo es pintar objetos en pantalla, definir una escena mayor que lo que se puede ver en pantalla y moverse por la pantalla con TouchEvents</p>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com33tag:blogger.com,1999:blog-373973123198193259.post-4675957033114017192011-02-24T20:09:00.002+01:002011-02-25T15:07:18.274+01:00Ciclo de vida de una aplicación Android<h2>¿Porqué es importante esto?</h2><p>El ciclo de vida de una aplicación en Android es manejada por el sistema operativo, basándose en las necesidades del usuario, los recursos disponibles, etc. Si tenemos una aplicación que está consumiendo muchos recursos y arrancamos otra nueva aplicación, el sistema operativo probablemente le diga a la aplicación que se queda en segundo plano que libere todo lo que pueda, y si es necesario la cerrará.En Android los recursos son normalmente muy limitados y por eso el sistema operativo tiene más control sobre las aplicaciones que en programas de escritorio.</p><p>En la mayoria de los casos, <b>cada aplicacion Android corre en su propio proceso de Linux</b>. Este proceso es creado para la aplicación cuando la arrancamos y seguirá corriendo hasta que no sea necesario y el sistema reclame recursos para otras aplicaciones y se los dé a éstas.<br />
</p><h2>Tipos de procesos</h2><p>Para decidir que proceso debe ser liquidado, Android ordena los procesos por importancia:<br />
<ol><li><b>Foregound Process.</b> Es la aplicación que contiene la actividad que ahora mismo se está mostrando en pantalla (Se ha llamado al método onResume()). Habrá muy pocos procesos Foreground corriendo a la vez en el sistema y estos procesos sólamente se liquidarán si la memoria es tan baja que ni matando al resto de procesos tenemos los recursos necesarios.</li>
<li><b>Visible process.</b> Es el que contiene una actividad que es visible, pero no en primera fila (se ha llamando al metodo onPause()). Por ejempo, estoy leyendo un email, y hago click en un enlace http y abre el navegador y me lleva a esa web. En ese momento el navegador sería <b>Foregound Process</b> y el cliente de mail sería un <b>Visible process</b>. Estos procesos son considerados importantes por el sistema operativo y normalmente no se cierran.</li>
<li><b>Service process.</b> Es un servicio como los de cualquier unix. Estos procesos hacen cosas en segundo plano que normalmente son importantes, el sistema nunca va a liquidar un servicio a menos que sea necesario para mantener vivos todos los Visible y Foreground.</li>
<li><b>Background process.</b> Es un proceso que contiene una actividad que actualmente no es visible por el usuario, estos procesos no tienen demasiada importancia, puede ser un programa que arranqué hace tiempo y no lo he vuelto a usar, pasa a estar en background. Por eso es importante que cuando nuestra aplicación pase a Background, liberar en la medida de lo posible todos los recursos que podamos.</li>
<li><b>Empty process.</b> Es un proceso que no alberga nada ya, lo usa Android como cahe para cuando se crea un proceso nuevo.</li>
</ol></p><br />
<br />
<h2>Al Turrón</h2><br />
<p>Android puede en cualquier momento pausar, parar, destruir nuestra aplicación según las necesidades del momento y nosotros debemos controlar todos estos eventos para hacer una aplicación robusta.<br />
<ul><li><b>onCreate()</b> Llamado cuando la actividad es llamada por primera vez. Es donde debes crear la inicialización normal de la aplicación, crear vistas, hacer los bind de los datos, etc. Este método te da acceso al estado de la aplicación cuando se cerró. Después de esta llamada siempre se llama al onStart().<br />
</li>
<li><b>onRestart()</b> Llamada cuando tu actividad ha sido parada, antes de volver a ser empezada. Siempre viene despues un onStart().<br />
</li>
<b>onStart()</b> Llamada cuando la actividad esta siendo visible por el usuario. Después de ésta, se puede ir al onResume() si la actividad va a ser visible o se puede ir al onStop() si se esconde. </li>
<li><b>onResume()</b> Llamada cuando la actividad va a empezar a interactuar con el usuario, en este punto es el último punto antes de que el usuario ya vea la actividad y pueda empezar a interactuar con ella. Siempre despues de un onResume() viene un onPause().<br />
</li>
<li><b>onPause()</b> LLamada cuando el sistema va a empezar una nueva actividad. Ésta necesita parar animaciones, y parar todo lo que esté haciendo. Hay que intentar que esta llamada dure poco tiempo, porque hasta que no se ejecute este método no arranca la siguiente actividad. Después de esta llamada puede venir un onResume() si la actividad vuelve a primer plano o un onStop() si se hace invisible para el usuario.<br />
</li>
<li><b>onStop()</b> Llamada cuando la actividad ya no es visible al usuario, porque otra actividad ha pasado a primer plano. Desde Aqui se puede ir al onRestart() si vuelve a primer plano o al onDestroy() si se destruye del todo.<br />
</li>
<li><b>onDestroy()</b> Esta es la llamada final a la actividad, después de ésta, es totalmente destruida.<br />
</li>
</ul></p><p>Un gráfico cortesía de google explicando el proceso gráficamente<br />
</p><div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-r47WtxEaNHA/TWassofX3II/AAAAAAAABEw/p_i25PEi4pQ/s1600/activity_lifecycle.png" /></div>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com6tag:blogger.com,1999:blog-373973123198193259.post-84771270268301120212011-02-24T19:15:00.000+01:002011-02-24T19:15:32.352+01:00Punto de entrada de un proyecto android<h2>¿Por donde empiezo?</h2><br />
<p>Un punto importante para entender el programa es por conocer dónde comienza la ejecución del programa. En un programa java normal buscarías el método Main. ¿Donde está el método Main en Android?</p><br />
<p>Si miramos el fichero AndroidManifest.xml ahí tenemos la información que estamos buscando. El fichero en cuestión tiene una pinta así:</p><br />
<pre class="brush: xml"><application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="Principal"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</pre><br />
<p>Para Android, el punto de entrada de la aplicación se define en el archivo xml, vemos que tenemos una Activity llamada ".principal", vemos que la Activity define un intent-filter para la acción <i>android.intent.action.MAIN</i> y para la categoría <i>android.intent.category.LAUNCHER</i>. Cuando Android arranca una aplicación, mira en su AndroidManifest.xml y arranca la actividad o actividades que tengan MAIN como accion y LAUNCHER como categoría.<br/>En este caso, por el name="Principal" se busca la clase Principal y se lanza.<br />
</p>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com1tag:blogger.com,1999:blog-373973123198193259.post-32342730650088306532011-02-24T18:22:00.001+01:002011-02-24T18:35:44.468+01:00Tutorial del primer proyecto en android.<p>Vamos a crear una serie de tutoriales en los que cubriremos la estructura esencial de una aplicación en Android. En el primer tutorial vamos a ver como crear una aplicación desde cero, el típico "Hola mundo", pero con un poquito de funcionalidad.<br />
</p><br />
<h2>Conceptos esenciales</h2><br />
<p>Hay varios conceptos esenciales que por lo menos te deben sonar para entender un poco de lo que pasa aqui:<br />
<ul><li><b>View :</b> Las Views (vistas) son elementos de la interfaz que se usan para construir la interfaz de usuario, por ejemplo: botones, imagenes, un label... Si estás familiarizado con views de J2EE y Swing sabrás lo que son las vistas en Android</li>
<li><b>Activity :</b> Una activity normalmente es una pantalla de tu programa, por ejemplo, creamos una aplicación con una pantalla de splash, una pantalla principal, pues serían dos "Activitys", una para la pantalla de splash y otra para la principal. Normalmente contienen una o mas Vistas, pero también puede haber que no contengan nada visual, como por ejemplo los servicios.</li>
<li><b>Intent :</b> Éste es un concepto que me costó bastante entender y que volveremos en un tutorial específico sobre el tema. Un "Intent" es la intención de hacer algo: mandar un sms, comenzar una Activity, Mostrar los Contactos, Mostrar una web... Ésto se entiende mejor sobre el terreno. Cuando creas una "intent" en tu programa, no siempre es el mismo programa el que las ejecuta, a veces es el sistema el que las invoca según ciertos eventos.</li>
<li><b>Content Provider :</b> Es la forma que tiene Android de compartir datos entre aplicaciones, puedes definir datos públicos para otras aplicaciones y obtener datos de otras aplicaciones del sistema (por ejemplo: lista de contactos)</li>
<li><b>Services :</b> Son servicios a la antigua usanza. Son procesos que corren en segundo plano y pueden estar corriendo un largo periodo de tiempo. Hay dos tipos de servicios: locales y remotos. Los servicios locales son componentes que solo son accesibles desde la misma aplicación. Los servicios remotos pueden ser accedidos por otras aplicaciones del terminal.</li>
<li><b>AndroidManifest.xml :</b> Es el archivo de configuración de la aplicación, si vienes de J2EE es algo parecido al web.xml. Guarda el nombre de tu aplicación, los servicios que tiene, las actividades que tiene, mucha información en este archivo...</li>
<li><b>Android Virtual Devices :</b> No todo el mundo tiene un teléfono con Android y los AVD son máquinas emuladas con el SDK de Android que te permiten probar en diferentes versiones de Android el programa que estás haciendo.</li>
</ul><br />
</p><br />
<h2>Creación del proyecto</h2><br />
<p>Primero arrancamos Eclipse y le damos a File -> New Android Project</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://2.bp.blogspot.com/-7P8k1WyEvAI/TWaGlGDdFoI/AAAAAAAABEI/QI8bGpfPFNo/s1600/paso1.png" /></div><br />
<p>En este paso tenemos que poner las siguientes cosas en Eclipse<br />
<ul><li><b>Project Name :</b> Un nombre para el proyecto en Eclipse. "HolaMundo" por ejemplo</li>
<li><b>Build Target :</b> La versión de android que vas a usar como base, en este caso, Android 1.6</li>
<li><b>Application Name :</b> Nombre de la aplicación que se verá en nuestro teléfono.</li>
<li><b>Package Name :</b> En este caso: com.pruebas.holaMundo</li>
<li><b>Create Activity :</b> Esto te crea una activity y la pone como actividad principal del programa, o sea, que la arranca al iniciar el programa. En este caso a la activity le hemos puesto el nombre de "Principal".</li>
<li><b>Min SDK Version :</b> Versión mínima del SDK necesaria para correr el programa. Hemos dicho que Android 1.6, que es el 4.</li>
</ul><br />
Le damos a <b>Finish</b> y tenemos ya el proyecto creado en Eclipse.<br />
</p><br />
<br />
<h2>¿Qué es todo esto?</h2><br />
<p>Eclipse nos crea una estructura de directorios como la siguiente</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://4.bp.blogspot.com/-OdGQBo_XFoc/TWaIlANL-OI/AAAAAAAABEQ/Cw8HlOz92S8/s1600/paso2.png" /></div><br />
<br />
<p>Vamos a repasar los directorios importantes para lo que vamos a ver hoy<br />
<br />
<ul><li><b>src :</b> Aqui es donde van los fuentes de nuestro programa</li>
<li><b>gen :</b> Archivos generados automáticamente. No tocar.</li>
<li><b>res :</b> Carpeta donde se guardan los "resources" del programa. Los resources pueden ser imágenes, layouts (pantallas), archivos binarios... todo lo que no sean fuentes.</li>
<li><b>AndroidManifest.xml :</b> Es un archivo de configuración del programa, ahora veremos que se puede poner en él.</li>
</ul></p><br />
<p><br />
<h2>Al turrón</h2><br />
<p>Vamos a ver qué código ha generado Eclipse para nosotros.</p><br />
<pre class="brush: java">package com.pruebas.holamundo;
import android.app.Activity;
import android.os.Bundle;
public class Principal extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
</pre><br />
<br />
<p>Ha creado una clase "Principal" que extiende la clase Activity. En el onCreate de la clase llama al onCreate de la clase Activity y luego <i>setContentView(R.layout.main);</i>, Esto hace que se muestre de la carpeta res/layout/main.xml como pantalla.<br />
<br />
Veamos qué hay en res/layout/main.xml...<br />
</p><br />
<pre class="brush: xml"><?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<textview
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
</pre><br />
<p>Vamos a hacerlo funcionar. Le damos en el menu a Run -> Run configurations.</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-w-Acb4RqBuM/TWaRjW4xu-I/AAAAAAAABEY/o4MVAm6Cg6c/s1600/paso3.png" /></div><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-yVjGCUWqgwI/TWaSCDKyS7I/AAAAAAAABEg/XXlPSwWy87s/s1600/paso4.png" /></div><br />
<p>En project, le damos a Browse y seleccionamos nuestro proyecto de Eclipse: "holaMundo". Aplicamos y listo.<br />
Ahora le damos a Run->Run y en nuestro teléfono o emulador deberíamos ver ésto</p><br />
<div class="separator" style="clear: both; text-align: center;"><img src="http://3.bp.blogspot.com/-8XgDaoQezmg/TWaS9gAYuBI/AAAAAAAABEo/10yaSgIQnWM/s1600/paso5.png" /></div><br />
Enhorabuena, ya tienes una aplicación den Android.<br />
<br />
En el siguiente capítulo: veremos con un poco de detalle las carpetas y archivos del proyecto.Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com2tag:blogger.com,1999:blog-373973123198193259.post-2167091901523636852011-02-05T16:33:00.000+01:002011-02-05T16:33:19.706+01:00Como asociar tipos de archivos a programas externos en eclipse<p>Tengo un tipo de archivos que es un .bin que quiero abrirlos con <a href="http://live.gnome.org/Ghex">ghex</a>. Para ello en eclipse hay que hacer lo siguiente.</p><br />
<p>Vamos al menú a Window -> Preferences<br />
<br />
<div class="separator"><img border="0"src="http://1.bp.blogspot.com/_4X_Stgfmito/TU1sZ8HiBmI/AAAAAAAABDQ/X6NHUL7gMfc/s1600/Pantallazo-1.png" /><br />
</div></p><br />
<p>Vamos al General -> File associations<br />
<br />
<div class="separator"><img border="0" src="http://1.bp.blogspot.com/_4X_Stgfmito/TU1szEYZRhI/AAAAAAAABDY/13lJORI36fo/s1600/Pantallazo-2.png" /><br />
</div></p><br />
<p>Ahora en la parte de arriba, en File Types: Le damos Add y ponemos por ejemplo en mi caso "*.bin". Ahora teniendo seleccionado arriba el nuevo filtro (*.bin) damos abajo a "Add...", seleccionamos -> external programs -> browse y buscamos el ejecutable que queremos que se haga cargo de ese tipo de archivos. Por ejemplo y en este caso "/usr/bin/ghex2".<br />
</p><br />
<p>Ahora ya cada vez que le dais a ese tipo de archivos en eclipse, usa el programa seleccionado para abrirlo... Bueno, que os aproveche.<br />
</p>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com0tag:blogger.com,1999:blog-373973123198193259.post-39802072971555966932011-02-04T15:11:00.001+01:002011-02-05T16:09:44.270+01:00Como añadir a subversion los archivos que he creado nuevos?<p>Bueno, pues he encontrado la manera, que elegante... <a target="_blank" href="http://porras.lacoctelera.net/post/2007/06/25/anadir-subversion-todos-archivos-anadidos-previamente">enlace</a></p><br />
<pre class="brush: shell">svn st | grep ^\? | cut -d ' ' -f 7 | xargs svn add
</pre>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com0tag:blogger.com,1999:blog-373973123198193259.post-74180477638060985592011-02-04T12:15:00.002+01:002011-02-04T12:15:39.685+01:00Depurar proyectos en Android (Source not found)<p>Sacado de <a href="http://android.opensourceror.org/2010/01/18/android-source/">aqui</a> y de diversas fuentes que voy poniendo enlaces conforme vayan saliendo. Yo no he inventado ésto, ni lo he descubierto, solo os lo pongo aquí para que no perdais el tiempo como lo he tenido que perder yo. <br />
</p><br />
<p>Si hay alguna parte que os parece que hay algún agujero en la explicación, os atrancais en algun punto o no os funciona, decidmelo en los comentarios e intentaré solucionarlo en la medida de mis posibilidades. Estaré atento a los comentarios, lo prometo ;)<br />
</p><br />
<p>Llego a un punto del proyecto en el que necesitaba debuggear ciertos errores, me salía un mensaje en el eclipse que decía <b>Source Not Found</b>, me costó algo de tiempo solucionar ésto. Si os ha servido de ayuda, por favor, linkadme, poned un comentario, o enviadme cheques a mi casa.<br />
</p><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://4.bp.blogspot.com/_4X_Stgfmito/TUrt9QYWFJI/AAAAAAAABCQ/bWCYq7Q5BfY/s1600/eclipse1.jpg" /></div><br />
<p>El mismo problema aparece cuando estás debuggeando. Hay que conseguir los fuentes de android para colocarlos en la carpeta donde tengas instalado el sdk de android. Como siempre hay varias maneras de conseguir ésto. Una sencilla y otra un poco más complicada.</p><br />
<h2>La manera sencilla: aprovecharse del trabajo de otros</h2><br />
<p>La manera sencilla es descargar directamente los fuentes preparados que un <a href="http://android.opensourceror.org/2010/01/18/android-source/">amable caballero</a> nos ha preparado para que los usemos (nos 22MB cada uno). Aquí os dejo los enlaces:<br />
<ul><li><a href="http://www.mediafire.com/file/mywjymazt3m/sources-1.5-cupcake.zip">Cupcake (1.5)</a></li>
<li><a href="http://www.mediafire.com/file/r0uzq1f0e0m/sources-1.6-donut.zip">Donut (1.6)</a></li>
<li><a href="http://www.mediafire.com/file/mninnmzznxc/sources-2.1-eclair.zip">Eclair (2.1)</a></li>
</ul></p><br />
<br />
<br />
<h2>La manera de los valientes: prepararse su propio zip</h2><br />
<p>Comencemos el camino de los valientes. Necesitamos varias cosicas:<br />
<ul><li>Python 2.4 lo más normal es que lo tengas instalado, si no es así lo puedes obtener de su <a href="http://www.python.org">página oficial</a>.</li>
<li>JDK 6. Si no tienes éste, apaga y vámonos.</li>
<li>Git 1.5.4 or más moderno. Puedes encontrarlo en <a href="http://git.or.cz/">http://git.or.cz/</a> o en tu gestor de paquetes (sudo apt-get install git-core).</li>
</ul></p><br />
<p>Ahora hay que instalar <b>Repo</b>. Repo es una herramienta que hace más facil todo el proceso de bajar los fuentes de android. Para más información acerca de Repo visiten la exquisita <a href="http://source.android.com/source/git-repo.html">documentación</a> de google acerca del tema.<br />
<ol><li>Creamos un directorio en nuestra carpeta personal y lo incluimos en el path:<br />
<pre class="brush: shell">mkdir ~/bin
PATH=~/bin:$PATH
</pre></li>
<li>Descargamos el comando repo y nos aseguramos que está como ejecutable<br />
<pre class="brush: shell">curl http://android.git.kernel.org/repo > ~/bin/repo
chmod a+x ~/bin/repo
</pre></li>
</ol></p><br />
<p>Una vez tengamos todos los requisitos creamos una carpeta para meter todos los fuentes de android.</p><br />
<pre class="brush: shell">cd
mkdir android-src
cd android-src
</pre><br />
<p>Ahora llamamos al repo que hemos bajado para inicializar el repositorio<br />
<ul><li>CupCake (Android 1.5)</li>
<li>Donut (Android 1.6)</li>
<li>EClair (Android 2.0)</li>
<li>Froyo (Android 2.2)</li>
<li>Gingerbread (Android 2.3)</li>
</ul><pre class="brush: shell">repo init -u git://android.git.kernel.org/platform/manifest.git -b donut
</pre><br />
<br />
<br />
Debe dar una salida como lo siguiente:<br />
<br />
<pre class="brush: shell">Getting repo ...
from git://android.git.kernel.org/platform/manifest.git
remote: Counting objects: 659, done.
remote: Compressing objects: 1remote: 00% (285/285), done.
remote: Total 659 (delta 256), reused 617 (delta 237)
Receiving objects: 100% (659/659), 180.40 KiB | 100 KiB/s, done.
Resolving deltas: 100% (256/256), done.
From git://android.git.kernel.org/platform/manifest
* [new branch] android-1.5 -> origin/android-1.5
* [new branch] android-1.5r2 -> origin/android-1.5r2
* [new branch] android-1.5r3 -> origin/android-1.5r3
* [new branch] android-1.5r4 -> origin/android-1.5r4
.......................
* [new tag] android-sdk-tools_r7 -> android-sdk-tools_r7
From git://android.git.kernel.org/platform/manifest
* [new tag] android-1.0 -> android-1.0
Your Name [angel]:
</pre><br />
Nos pide el nombre amablemente, se lo damos. Nos pide una dirección de correo electrónico, yo se la dí, los conspiranoicos que pongan lo que quieran. Cuando terminemos tiene que salir una cosa como ésta.<br />
<br />
<pre class="brush: shell">repo initialized in /home/angel/android-src
</pre><br />
</p><br />
<p>Ya tenemos incializado el repositorio, ahora le damos a bajar los fuentes con el comando<br />
<br />
<pre class="brush: shell">repo sync
</pre><br />
Se pone a bajar una gran cantidad de archivos, unos 4 gigas me bajó a mi.<br />
<br />
<pre class="brush: shell">Initializing project platform/bionic ...
remote: Counting objects: 7582, done.
remote: Compressing objects: 100% (2710/2710), done.
remote: Total 7582 (delta 5191), reused 7124 (delta 4805)
Receiving objects: 100% (7582/7582), 2.62 MiB | 176 KiB/s, done.
Resolving deltas: 100% (5191/5191), done.
From git://android.git.kernel.org/platform/bionic
* [new branch] cdma-import -> korg/cdma-import
* [new branch] cupcake -> korg/cupcake
* [new branch] cupcake-release -> korg/cupcake-release
........................
* [new tag] android-sdk-tools_r7 -> android-sdk-tools_r7
Checking out files: 100% (7697/7697), done.ut files: 4% (331/7697)
Checking out files: 100% (5528/5528), done.
Checking out files: 100% (453/453), done.g out files: 5% (27/453)
Checking out files: 100% (3804/3804), done.out files: 3% (116/3804)
Checking out files: 100% (4187/4187), done.out files: 25% (1061/4187)
Checking out files: 100% (403/403), done.g out files: 21% (85/403)
Checking out files: 100% (641/641), done.g out files: 23% (148/641)
Checking out files: 100% (601/601), done.g out files: 3% (23/601)
Checking out files: 100% (7313/7313), done.out files: 18% (1332/7313)
Checking out files: 100% (6591/6591), done.out files: 0% (62/6591)
Checking out files: 100% (350/350), done.ng out files: 48% (169/350)
Checking out files: 100% (282/282), done.ng out files: 10% (31/282)
Checking out files: 100% (1670/1670), done. out files: 0% (8/1670)
Checking out files: 100% (11/11), done.king out files: 45% (5/11)
Syncing work tree: 100% (141/141), done.
</pre><br />
Y así termina el proceso y terminamos con un directorio lleno de cosicas como éste.<br />
</p><br />
<div class="separator"><img border="0" src="http://1.bp.blogspot.com/_4X_Stgfmito/TUvdRUfSOxI/AAAAAAAABDI/ZP9u8IN9N9U/s1600/sube.png" /></div><br />
<br />
<p>Ahora hay que preparar los bonitos zips. <a href="http://blog.michael-forster.de/2008/12/view-android-source-code-in-eclipse.html">Un caballero</a> nos propone hacerlo con un script de python. <a href="http://stuffthathappens.com/blog/2008/11/01/browsing-android-source-in-eclipse/">Otro caballero</a> explica como hacerlo a mano. Me cuadra la primera forma.<br />
</p><br />
<p>Creamos un archivo en la carpeta sources llamado prepara.py, lo editamos y pegamos ésto:<br />
<pre class="brush: python">from __future__ import with_statement # for Python < 2.6
import os
import re
import zipfile
# open a zip file
DST_FILE = 'sources.zip'
if os.path.exists(DST_FILE):
print DST_FILE, "already exists"
exit(1)
zip = zipfile.ZipFile(DST_FILE, 'w', zipfile.ZIP_DEFLATED)
# some files are duplicated, copy them only once
written = {}
# iterate over all Java files
for dir, subdirs, files in os.walk('.'):
for file in files:
if file.endswith('.java'):
# search package name
path = os.path.join(dir, file)
with open(path) as f:
for line in f:
match = re.match(r'\s*package\s+([a-zA-Z0-9\._]+);', line)
if match:
# copy source into the zip file using the package as path
zippath = match.group(1).replace('.', '/') + '/' + file
if zippath not in written:
written[zippath] = 1
zip.write(path, zippath)
break;
zip.close()
</pre>
Ahora nos vamos a la carpeta y ejecutamos:
<pre class="brush: shell">python prepara.py
</pre></p><h2>Ya tenemos los fuentes, ahora que?</h2><p>Una vez tenemos los fuentes, creamos un directorio llamado sources dentro de la carpeta donde esta el android.jar que estamos usando, en mi caso es la carpeta android-sdk-linux_86/platforms/android-4/sources y la carpeta tiene que tener una pinta como ésta:</p><div class="separator"><img border="0" src="http://1.bp.blogspot.com/_4X_Stgfmito/TUsARPnP7NI/AAAAAAAABCg/3G39D4f0s7k/s1600/pantalla2.png" /></div><p>Con esto ya tenemos los fuentes de android integrados en eclipse para poder curiosear y mirarle las tripas a este amiguito que nos regala google. Sin embargo para que el debugger encuentre esos fuentes hay que indicárselo</p><p>Hay que cambiar la perspectiva de eclipse a modo debug
<img border="0" src="http://2.bp.blogspot.com/_4X_Stgfmito/TUsDOEnQ3II/AAAAAAAABCo/kjeCiDo5a9o/s1600/paso1.png" />
</p><p>Botón derecho en el proyecto y darle a "Edit Source Lookup"
<img border="0" src="http://2.bp.blogspot.com/_4X_Stgfmito/TUsDimJ6obI/AAAAAAAABCw/Qd0_NJAj1bY/s1600/paso2.png" />
</p><p>Le damos "Add" y luego "File System Directory"
<img border="0" src="http://3.bp.blogspot.com/_4X_Stgfmito/TUsDxWfotTI/AAAAAAAABC4/r-GNsUOpAto/s1600/paso3.png" />
</p><p>Le damos "Browse" y localizamos nuestra carpeta de sources creada, en mi caso:
<img border="0" src="http://3.bp.blogspot.com/_4X_Stgfmito/TUsECpgnziI/AAAAAAAABDA/hrmUMZu6ugs/s1600/paso5.png" />
</p><p>Y Voilá... ya tenemos nuestro debugger funcionando para que sepamos de qué va el error que nos estaba dando el programa</p>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com9tag:blogger.com,1999:blog-373973123198193259.post-45960342788919466412011-01-05T01:39:00.007+01:002011-02-04T02:43:00.939+01:00Mi primera layoutMe encuentro con la tesitura de hacer el layout de la pantalla principal...<br />
<br />
La idea que tengo es un fondo de cesped de campo de futbol, dividido en dos partes verticalmente, en la parte de arriba el logotipo de la pantalla y abajo dos botones para "Nueva Partida" y para "Salir".<br />
<br />
Viendo la excelente documentación de google, la manera mas cómoda de poner el fondo es con <a href="http://developer.android.com/reference/android/widget/FrameLayout.html"><FrameLayout></a>.<br />
<br />
Cuando defines un FrameLayout, el contenido de lo que pongas despues va uno encima de otro, especial para mi fondo de la vista.<br />
<br />
<pre class="brush: xml"><?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<imageview
android:id="@+id/mainMenuBackground"
android:src="@drawable/title_background_p"
android:adjustViewBounds="true"
android:gravity="center_vertical"
android:scaleType="fitXY"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</pre>Viendo más en detalle ésto para comprender como funcionan los FrameLayouts de Android. Las únicas propiedades reseñables son las siguientes:<br />
<pre class="brush: plain">android:layout_width="fill_parent"
android:layout_height="fill_parent"
</pre>Esto quiere decir que el FrameLayout ocupa toda la pantalla.<br />
Dentro de este FrameLayout ponemos la imagen<br />
<pre class="brush: xml">android:src="@drawable/title_background_p"
android:id="@+id/mainMenuBackground"
android:adjustViewBounds="true"
android:gravity="center_vertical"
android:scaleType="fitXY"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
</pre><br />
A continuacion ponemos un LinearLayout hacia abajo, que lo vamos a dividir en dos partes iguales. En la parte de arriba ponemos un logotipo provisional y en la parte de abajo dos botones.<br />
<br />
El layout se queda así.<br />
<br />
<pre class="brush: xml"><?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<imageview
android:id="@+id/mainMenuBackground"
android:src="@drawable/title_background_p"
android:adjustViewBounds="true"
android:gravity="center_vertical"
android:scaleType="fitXY"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<linearlayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" >
<imageview
android:id="@+id/mainMenuTitle"
android:src="@drawable/logo_l"
android:adjustViewBounds="true"
android:gravity="center_vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:scaleType="centerInside"
/>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_weight="1"
>
<Button
android:id="@+id/new_button"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_margin="2dp"
android:gravity="center_vertical"
android:text="@string/new_game_label" />
<Button
android:id="@+id/exit_button"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_margin="2dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:text="@string/exit_label" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</pre>Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com0tag:blogger.com,1999:blog-373973123198193259.post-91463957889613467942011-01-04T17:36:00.001+01:002011-02-04T02:42:33.818+01:00Subida inicial a google code.He hecho una subida inicial a <a href="https://code.google.com/p/ch-soccer/">google code.</a><br />
<br />
Creado el proyecto... configurado subversion para poder trabajar desde cualquiera de los dos equipos que tengo sin tener que estar copiando carpetas, y por supuesto para que curioseeis todo lo que os apetezca.<br />
<br />
Por ahora no tengo nada del juego hecho, una pantalla inicial que me ha servido para jugar con los layouts de android, que acostumbrado a otros métodos de desarrollo me ha parecido un poco marciano, pero bueno, le voy pillando el puntico...<br />
<br />
Ahora mismo la aplicación pinta de ésta manera (conseguido que se vea bien tanto en apaisado como en normal).<br />
<br />
En breve pondré un post sobre los layouts, lo que necesitaba y los diferentes acercamientos que he hecho.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_4X_Stgfmito/TSNMMkCJs8I/AAAAAAAABA0/CdLCzJ3cZOQ/s1600/normal.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://4.bp.blogspot.com/_4X_Stgfmito/TSNMMkCJs8I/AAAAAAAABA0/CdLCzJ3cZOQ/s320/normal.png" width="213" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_4X_Stgfmito/TSNMMq72fkI/AAAAAAAABA4/OiSu1sOtHIw/s1600/apaisado.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="http://1.bp.blogspot.com/_4X_Stgfmito/TSNMMq72fkI/AAAAAAAABA4/OiSu1sOtHIw/s320/apaisado.png" width="320" /></a></div><br />
Bueno, luego más....Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com0tag:blogger.com,1999:blog-373973123198193259.post-1154156359278991582010-12-27T19:32:00.004+01:002011-02-04T02:42:10.072+01:00Instalación del Entorno de DesarrolloBueno, primero decir que trabajo en un Ubuntu 10.10 recien instalado.<br />
<br />
Lo primero que he tenido que hacer es instalar el jre de java. Para ello usando el instalador de paquetes está todo hecho.<br />
<br />
Luego he descargado el SDK de android y lo he ejecutado y actualizado todos los componentes. Sin problemas.<br />
<br />
He instalado Eclipse y el Plugin sin problemas tampoco.<br />
<br />
A la hora de que me reconociera el terminal (Orange Boston), he tenido algun problema porque en Eclipse me salían unos signos de interrogación.<br />
<br />
Investigando he visto que el comando "platform-tools/adb devices" en la carpeta del sdk me dice que no tengo permisos suficientes, buceando un poco he encontrado la solución:<br />
<br />
<br />
Vamos a la consola y ponemos lo siguiente:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" height="226" src="http://3.bp.blogspot.com/_4X_Stgfmito/TRjakMVvTXI/AAAAAAAABAA/d6yV_NY-17Y/s320/Pantallazo.png" width="320" /></div><br />
Antes y despues de enchufar el telefono por el usb al ordenador.... Con lo cual me quedo con el numerito de antes del teléfono y lo uso para escribir el archivo siguiente, que si no lo tienes, lo creas y listo.<br />
<br />
En la carpeta /etc/udev/rules.d el archivo 99-android.rules, le he puesto el siguiente contenido...<br />
<br />
<br />
<pre class="brush">SUBSYSTEM=="usb", ATTR{idVendor}=="0489", MODE="0666"
</pre><br />
Reinicio el pc y todo funcionando perfectamente.<br />
<br />
He estado mirando fuentes de juegos para ir cogiendo ideas y posibles implementaciones y me ha gustado mucho <a href="http://replicaisland.net/">Replica Island</a>, os lo recomiendo encarecidamente, un fuente muy organizado y se ve claramente una estructura pensada para un juego...<br />
<br />
Cualquier duda que tengais con lo que ya he realizado, no dudeis en ponerlo en los comentarios, y os ayudaré en la medida de mis posibilidades.<br />
<br />
Bueno empiezo a escribir codigo, ya iré poniendo por aquí mis aventuras y avances.<br />
<br />
Un saludo.Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com0tag:blogger.com,1999:blog-373973123198193259.post-67859479295088874982010-12-27T18:02:00.000+01:002010-12-27T18:02:03.903+01:00Hola mundoHola mundo!, esto funciona.<br />
<br />
<br />
Bueno, aquí iré informando de mis avances y descubrimientos en el mundillo de la programación para android en linux.<br />
<br />
<br />
Próximamente... la instalación y preparación del entorno de desarrollo.Angelhttp://www.blogger.com/profile/01073241333005135564noreply@blogger.com0