<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>gergonzalez &#187; Casos de Estudio</title>
	<atom:link href="http://www.gergonzalez.com/category/casos-de-estudio/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gergonzalez.com</link>
	<description>descubiendo la magia del iPhone SDK</description>
	<lastBuildDate>Tue, 24 Nov 2009 17:29:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Nuestro primer videojuego para iPhone &#8211; III</title>
		<link>http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-iii/</link>
		<comments>http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-iii/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 17:29:23 +0000</pubDate>
		<dc:creator>gergonzalez</dc:creator>
				<category><![CDATA[Casos de Estudio]]></category>
		<category><![CDATA[Iphone]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[videojuegos]]></category>

		<guid isPermaLink="false">http://www.gergonzalez.com/?p=369</guid>
		<description><![CDATA[Llevamos ya dos posts y todavía no hemos conseguido que nuestro videojuego sea medianamente jugable. Hoy nos proponemos acabar con esa situación mediante la implementación de la detección de colisiones y la inteligencia artificial de nuestro oponente.


Detección de colisiones
Llamamos detección de colisiones a la lógica que nos permite detectar cuando dos o más sprites, en [...]]]></description>
			<content:encoded><![CDATA[<p>Llevamos ya dos posts y todavía no hemos conseguido que nuestro videojuego sea medianamente jugable. Hoy nos proponemos acabar con esa situación mediante la implementación de la detección de colisiones y la inteligencia artificial de nuestro oponente.</p>
<p><a href="http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-iii"><img alt="" src="http://farm3.static.flickr.com/2746/4131323382_95bd737713_o.jpg" class="alignnone" width="618" height="250" /></a></p>
<p><span id="more-369"></span></p>
<h4>Detección de colisiones</h4>
<p>Llamamos detección de colisiones a la lógica que nos permite detectar cuando dos o más sprites, en nuestro caso vistas, chocan entre ellos y en función a esas colisiones actuar en consecuencia.</p>
<p>Para nuestro juego tendremos que detectar cuando la pelota choca con cualquiera de las paletas o en los límites de pantalla, y en cuyo caso producir un cambio en su velocidad con el fin de que se cumpla la<strong> tercera Ley de Newton</strong> o de acción y reacción. No profundizaremos más en el tema, se deja a gusto del lector hacer el juego un poco más divertido con cambios en relación al punto de impacto de la pelota con la raqueta.</p>
<p>Pues vamos a ello, primeramente tendremos que volver a modificar nuestra cabecera <strong>iPingPongViewController.h</strong> declarando nuevas variables instanciadas y un método:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;UIKit/UIKit.h&gt;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> iPingPongViewController <span style="color: #002200;">:</span> UIViewController <span style="color: #002200;">&#123;</span>
&nbsp;
	UIView <span style="color: #002200;">*</span>player1;
	UIView <span style="color: #002200;">*</span>player2;
&nbsp;
	UIView <span style="color: #002200;">*</span>ball;
&nbsp;
	UILabel <span style="color: #002200;">*</span>player1Score;
	UILabel <span style="color: #002200;">*</span>player2Score;
&nbsp;
	UILabel <span style="color: #002200;">*</span>startLabel;
&nbsp;
	CGPoint ballVelocity;
&nbsp;
	<span style="color: #a61390;">BOOL</span> gameRunning;
&nbsp;
	NSInteger player1ScoreValue;<span style="color: #11740a; font-style: italic;">//New</span>
	NSInteger player2ScoreValue;<span style="color: #11740a; font-style: italic;">//New</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIView <span style="color: #002200;">*</span>ball;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIView <span style="color: #002200;">*</span>player1;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIView <span style="color: #002200;">*</span>player2;
&nbsp;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UILabel <span style="color: #002200;">*</span>player1Score;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UILabel <span style="color: #002200;">*</span>player2Score;
&nbsp;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UILabel <span style="color: #002200;">*</span>startLabel;
&nbsp;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic<span style="color: #002200;">&#41;</span> CGPoint ballVelocity;
&nbsp;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic<span style="color: #002200;">&#41;</span> NSInteger player1ScoreValue;<span style="color: #11740a; font-style: italic;">//New</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic<span style="color: #002200;">&#41;</span> NSInteger player2ScoreValue;<span style="color: #11740a; font-style: italic;">//New</span>
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>playAgain<span style="color: #002200;">:</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span> newGame;<span style="color: #11740a; font-style: italic;">//New</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>No creo que nadie a estas alturas albergue dudas ante el código anterior, simplemente declaramos dos variables instanciadas de tipo NSInteger que almacenarán el tanteo que luego será mostrado por las etiquetas player1Score. Además nos hemos declarado un método que usaremos para controlar quien es el jugador ganador.</p>
<p>Sin más dilación, abrimos <strong>iPingPongViewController.m</strong> e introducimos:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kBallSpeedX 3</span>
<span style="color: #6e371a;">#define kBallSpeedY 2</span>
&nbsp;
<span style="color: #6e371a;">#define kFPS 0.01</span>
<span style="color: #11740a; font-style: italic;">//New</span>
<span style="color: #6e371a;">#define kScoreToWin 5</span>
&nbsp;
<span style="color: #6e371a;">#import &quot;iPingPongViewController.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> iPingPongViewController
&nbsp;
<span style="color: #a61390;">@synthesize</span> ball, player1, player2, player1Score, player2Score; 
<span style="color: #a61390;">@synthesize</span> startLabel, ballVelocity;
<span style="color: #a61390;">@synthesize</span> player1ScoreValue, player2ScoreValue;<span style="color: #11740a; font-style: italic;">//New</span>
&nbsp;
...
&nbsp;
	<span style="color: #002200;">&#91;</span><span style="color: #400080;">NSTimer</span> scheduledTimerWithTimeInterval<span style="color: #002200;">:</span>kFPS target<span style="color: #002200;">:</span>self 
                      selector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>gameLoop<span style="color: #002200;">&#41;</span> userInfo<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span> repeats<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>gameLoop<span style="color: #002200;">&#123;</span>
&nbsp;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>gameRunning<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
		ball.center <span style="color: #002200;">=</span> 
CGPointMake<span style="color: #002200;">&#40;</span>ball.center.x <span style="color: #002200;">+</span> ballVelocity.x, ball.center.y <span style="color: #002200;">+</span> ballVelocity.y<span style="color: #002200;">&#41;</span>;
&nbsp;
		<span style="color: #11740a; font-style: italic;">//Collision Detection</span>
		<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>ball.center.x&gt;self.view.bounds.size.width || ball.center.x &lt; <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#123;</span>
&nbsp;
			ballVelocity.x <span style="color: #002200;">=</span> <span style="color: #002200;">-</span>ballVelocity.x;	
		<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>ball.center.y&gt;self.view.bounds.size.height || ball.center.y &lt; <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#123;</span>
&nbsp;
			ballVelocity.y <span style="color: #002200;">=</span> <span style="color: #002200;">-</span>ballVelocity.y;
		<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>CGRectIntersectsRect <span style="color: #002200;">&#40;</span>ball.frame, player1.frame<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#123;</span>
			<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>ball.center.y &lt; player1.center.y<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#123;</span>
				ballVelocity.y <span style="color: #002200;">=</span> <span style="color: #002200;">-</span>ballVelocity.y<span style="color: #002200;">-</span><span style="color: #2400d9;">0.1</span>;
			<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>CGRectIntersectsRect <span style="color: #002200;">&#40;</span>ball.frame, player2.frame<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#123;</span>
			<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>ball.center.y &lt; player2.center.y<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#123;</span>
				ballVelocity.y <span style="color: #002200;">=</span> <span style="color: #002200;">-</span>ballVelocity.y<span style="color: #002200;">+</span><span style="color: #2400d9;">0.1</span>;
			<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #002200;">&#125;</span>	
&nbsp;
		<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>ball.center.y &lt;<span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
			player1ScoreValue<span style="color: #002200;">++</span>;
			ballVelocity <span style="color: #002200;">=</span> CGPointMake<span style="color: #002200;">&#40;</span>kBallSpeedX, kBallSpeedY<span style="color: #002200;">&#41;</span>;
			<span style="color: #002200;">&#91;</span>self playAgain<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>player1ScoreValue &gt;<span style="color: #002200;">=</span> kScoreToWin<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>ball.center.y &gt; self.view.bounds.size.height<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
			player2ScoreValue<span style="color: #002200;">++</span>;
			ballVelocity <span style="color: #002200;">=</span> CGPointMake<span style="color: #002200;">&#40;</span>kBallSpeedX, kBallSpeedY<span style="color: #002200;">&#41;</span>;
			<span style="color: #002200;">&#91;</span>self playAgain<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>player2ScoreValue &gt;<span style="color: #002200;">=</span> kScoreToWin<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
&nbsp;
			<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>startLabel.hidden<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
				startLabel.hidden <span style="color: #002200;">=</span> <span style="color: #a61390;">NO</span>;
			<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>playAgain<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span> newGame <span style="color: #002200;">&#123;</span>
	gameRunning <span style="color: #002200;">=</span> <span style="color: #a61390;">NO</span>;
	ball.center <span style="color: #002200;">=</span> self.view.center;
	<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>newGame<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
		<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>player2ScoreValue &gt; player1ScoreValue<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
			startLabel.text <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;PLAYER 2 WINS!&quot;</span>;
		<span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
			startLabel.text <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;PLAYER 1 WINS!&quot;</span>;
		<span style="color: #002200;">&#125;</span>
&nbsp;
		player2ScoreValue <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
		player1ScoreValue <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
	<span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
		startLabel.text <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;TAP TO START GAME&quot;</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
	player1Score.text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%d&quot;</span>,player1ScoreValue<span style="color: #002200;">&#93;</span>;
	player2Score.text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%d&quot;</span>,player2ScoreValue<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
...</pre></td></tr></table></div>

<p>Al igual que en posts anteriores hacemos uso de constantes, en este caso para representar el número de puntos necesarios para ganar. Ya en nuestro método <strong>gameloop</strong> vemos como para la implementación de la detección de colisiones simplemente utilizamos cláusulas condicionales if para testear si la pelota se encuentra o tocando los bordes de la pantalla en cuyo caso cambia su velocidad con respecto al eje x, o interseccionando con la paleta, modificando entonces su velocidad en el eje y, y añadiéndole un factor para que la velocidad vaya aumentando en función a los golpes devueltos. Para evitar el molesto efecto que se produce a veces de que la pelota queda atrapada en nuestra paleta hemos introducido un if más que chequea esta problemática.</p>
<p>Lo siguiente que hacemos es comprobar cuando la pelota toca los bordes inferior y superior de nuestra pantalla y que suponen que un jugador ha logrado un punto, por lo tanto se aumenta la variable habilitada para tal fin y se llama al método que acabamos de declarar <strong>playAgain</strong>, el cual comprueba si hemos alcanzado el número de puntos necesarios para ganar, mostrando el mensaje correspondiente. También desde este método se actualizan las etiquetas que utilizamos como marcador.</p>
<p>Si simulamos ahora veremos como la pelota ya no desaparece de nuestra pantalla, ya que al llegar a una pared esta choca y cambia su dirección manteniéndose en la pantalla, lo mismo ocurre al colisionar con cualquiera de las dos paletas. Nuestro problema reside ahora en que nuestro oponente nos observa impertérrito y no hace ni ademán de devolvernos la pelota&#8230;</p>
<h4>IA</h4>
<p>Una vez implementada la detección de colisiones tenemos que hacer que la vista player2 interactúe con nosotros y nos intente devolver la pelota o lo que es lo mismo, asignarle una ia. Debido al carácter de nuestro caso de estudio, no vamos a profundizar en complejos sistemas para simular inteligencias artificiales, algo completamente fuera del alcance de este caso de estudio.</p>
<p>Por lo tanto vamos a crear una sencilla ia, para ello nuestro competidor empezará su movimiento en el momento en que la pelota sobrepase la red, y su movimiento consistirá en que a partir de este momento seguirá la dirección de la pelota, una constante que llamaremos kPlayer2Speed será el que controlará la velocidad de nuestro competidor y determinará el nivel de dificultad de este.</p>
<p>Pues vamos a ello, esta vez no necesitamos reescribir nuestro header, por eso en <strong>iPingPongViewController.m</strong> declararemos la constante antes nombrada y la lógica de comportamiento de nuestro oponente:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kBallSpeedX 3</span>
<span style="color: #6e371a;">#define kBallSpeedY 2</span>
&nbsp;
<span style="color: #6e371a;">#define kFPS 0.01</span>
<span style="color: #6e371a;">#define kScoreToWin 5</span>
<span style="color: #11740a; font-style: italic;">//New</span>
<span style="color: #6e371a;">#define kPlayer2Speed 3</span>
&nbsp;
...
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>gameLoop<span style="color: #002200;">&#123;</span>
&nbsp;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>gameRunning<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>	
...		
               <span style="color: #11740a; font-style: italic;">//AI</span>
		<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>ball.center.y &lt;<span style="color: #002200;">=</span> self.view.center.y<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
			<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>ball.center.x &lt; player2.center.x<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
				player2.center <span style="color: #002200;">=</span> 
        CGPointMake<span style="color: #002200;">&#40;</span>player2.center.x <span style="color: #002200;">-</span> kPlayer2Speed, player2.center.y<span style="color: #002200;">&#41;</span>;
			<span style="color: #002200;">&#125;</span>
&nbsp;
			<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>ball.center.x &gt; player2.center.x<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
				player2.center <span style="color: #002200;">=</span> 
         CGPointMake<span style="color: #002200;">&#40;</span>player2.center.x <span style="color: #002200;">+</span> kPlayer2Speed, player2.center.y<span style="color: #002200;">&#41;</span>;
			<span style="color: #002200;">&#125;</span>
		<span style="color: #002200;">&#125;</span>
&nbsp;
...</pre></td></tr></table></div>

<p>Como vemos nuestra lógica consiste en lo anteriormente explicado, comprobamos que la pelota sobrepasa la red y entonces nuestra vista player2 cambiará sus coordenadas con respecto a x en la misma dirección en la que se mueve la pelota con una velocidad determinada por la constante kPlayer2Speed. Tan simple como eso.</p>
<p>Pues ya está, ahora ya podemos simular y ver nuestro juego en acción, muy limitado y poco trabajado, pero ahora es cosa de cada uno mejorarlo a partir de las premisas dadas. Buena Suerte. En próximos post ya terminaremos este caso de estudio, mediante la introducción de un menú y sonidos. Saludos.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-iii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nuestro primer videojuego para iPhone &#8211; II</title>
		<link>http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-ii/</link>
		<comments>http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-ii/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 12:16:07 +0000</pubDate>
		<dc:creator>gergonzalez</dc:creator>
				<category><![CDATA[Casos de Estudio]]></category>
		<category><![CDATA[Iphone]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[videojuegos]]></category>

		<guid isPermaLink="false">http://www.gergonzalez.com/?p=349</guid>
		<description><![CDATA[Ya estamos de vuelta con nuestro caso de estudio sobre la creación de un videojuego, después de implementar la interfaz gráfica en el post anterior, hoy vamos a ver como darle un poco de vida mediante la implementación del Game Loop y de la interacción con el usuario.


Game Loop
El Game Loop, o bucle de juego [...]]]></description>
			<content:encoded><![CDATA[<p>Ya estamos de vuelta con nuestro caso de estudio sobre la creación de un videojuego, después de implementar la interfaz gráfica en el post anterior, hoy vamos a ver como darle un poco de vida mediante la implementación del Game Loop y de la interacción con el usuario.</p>
<p><a href="http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-ii/"><img alt="" src="http://farm3.static.flickr.com/2712/4127150103_b984414d43_o.jpg" class="alignnone" width="618" height="250" /></a></p>
<p><span id="more-349"></span></p>
<h4>Game Loop</h4>
<p>El Game Loop, o bucle de juego (¡qué difícil es adaptar términos al castellano!), es una de las partes más importantes de un videojuego, se podría decir que es el corazón de nuestro juego, siendo cada iteración del bucle como un latido, y al igual que a nosotros nos es imposible vivir sin un corazón, a un videojuego le sería imposible existir sin su Game Loop.</p>
<p>Hay infinidad de técnicas para implementar el Game Loop, queda en manos del programador y de las características de la plataforma en la que se trabaja la elección de este. Para este ejemplo no hemos entrado a analizar el grado de optimización de los recursos de nuestro iPhone, simplemente nos hemos limitado a que fuera sencillo y funcional.</p>
<p>Bueno, pues vamos a ir completando nuestro código anterior con el fin de implementar nuestro Game Loop, para ello en el header de nuestra clase <strong>iPingPongViewController.h</strong> declararemos una nueva variable instanciada que llamaremos <strong>ballVelocity</strong>, la cual no es más que una estructura del tipo CGPoint que contendrá un par de coordenadas que usaremos para definir la velocidad de nuestra pelota durante la ejecución, y también una variable del tipo BOOL y una etiqueta que usaremos para evitar que el juego empiece a ejecutarse nada más cargarse:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;UIKit/UIKit.h&gt;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> iPingPongViewController <span style="color: #002200;">:</span> UIViewController <span style="color: #002200;">&#123;</span>
&nbsp;
	UIView <span style="color: #002200;">*</span>player1;
	UIView <span style="color: #002200;">*</span>player2;
	UIView <span style="color: #002200;">*</span>ball;
&nbsp;
	UILabel <span style="color: #002200;">*</span>player1Score;
	UILabel <span style="color: #002200;">*</span>player2Score;
        UILabel <span style="color: #002200;">*</span>startLabel;<span style="color: #11740a; font-style: italic;">//New	</span>
&nbsp;
	CGPoint ballVelocity;<span style="color: #11740a; font-style: italic;">//New</span>
&nbsp;
	<span style="color: #a61390;">BOOL</span> gameRunning;<span style="color: #11740a; font-style: italic;">//New</span>
&nbsp;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIView <span style="color: #002200;">*</span>ball;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIView <span style="color: #002200;">*</span>player1;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIView <span style="color: #002200;">*</span>player2;
&nbsp;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UILabel <span style="color: #002200;">*</span>player1Score;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UILabel <span style="color: #002200;">*</span>player2Score;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UILabel <span style="color: #002200;">*</span>startLabel;<span style="color: #11740a; font-style: italic;">//New</span>
&nbsp;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic<span style="color: #002200;">&#41;</span> CGPoint ballVelocity;<span style="color: #11740a; font-style: italic;">//New</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>El siguiente paso consistirá en abrir <strong>iPingPongViewController.m</strong> y, al igual que para implementar nuestra interfaz, sobrecargaremos el método <strong>loadView</strong> para inicializar nuestras nuevas variables y crearemos una instancia de <strong>NSTimer</strong> que llamará a nuestro evento <strong>gameLoop</strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">//New</span>
<span style="color: #6e371a;">#define kBallSpeedX 3</span>
<span style="color: #6e371a;">#define kBallSpeedY 2</span>
&nbsp;
<span style="color: #6e371a;">#define kFPS 0.01</span>
&nbsp;
<span style="color: #6e371a;">#import &quot;iPingPongViewController.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> iPingPongViewController
&nbsp;
<span style="color: #a61390;">@synthesize</span> ball, player1, player2, player1Score, player2Score;
<span style="color: #a61390;">@synthesize</span> startLabel, ballVelocity;<span style="color: #11740a; font-style: italic;">//New</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Implement loadView to create a view hierarchy programmatically,</span>
<span style="color: #11740a; font-style: italic;">// without using a nib.</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>loadView <span style="color: #002200;">&#123;</span>
&nbsp;
	<span style="color: #11740a; font-style: italic;">//Create the main view and assign a black color to background</span>
	CGRect backgroundFrame <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIScreen mainScreen<span style="color: #002200;">&#93;</span> applicationFrame<span style="color: #002200;">&#93;</span>;
        ...	
&nbsp;
	<span style="color: #11740a; font-style: italic;">//New</span>
	<span style="color: #11740a; font-style: italic;">//Tap to Start Label</span>
	startLabel <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UILabel alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>
                             CGRectMake<span style="color: #002200;">&#40;</span>self.view.center.x<span style="color: #002200;">-</span><span style="color: #2400d9;">50</span>, <span style="color: #2400d9;">200</span>, <span style="color: #2400d9;">100</span>, <span style="color: #2400d9;">15</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
	startLabel.font <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIFont fontWithName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Helvetica&quot;</span> size<span style="color: #002200;">:</span><span style="color: #2400d9;">12</span><span style="color: #002200;">&#93;</span>;
	startLabel.text <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;TAP TO START GAME&quot;</span>;
	startLabel.textColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor whiteColor<span style="color: #002200;">&#93;</span>;
	startLabel.backgroundColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor blackColor<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self.view addSubview<span style="color: #002200;">:</span>startLabel<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">//Game start Paused</span>
	gameRunning <span style="color: #002200;">=</span> <span style="color: #a61390;">NO</span>;
&nbsp;
	ballVelocity <span style="color: #002200;">=</span> CGPointMake<span style="color: #002200;">&#40;</span>kBallSpeedX, kBallSpeedY<span style="color: #002200;">&#41;</span>;
&nbsp;
	<span style="color: #002200;">&#91;</span><span style="color: #400080;">NSTimer</span> scheduledTimerWithTimeInterval<span style="color: #002200;">:</span>kFPS target<span style="color: #002200;">:</span>self 
selector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>gameLoop<span style="color: #002200;">&#41;</span> userInfo<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span> repeats<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>gameLoop<span style="color: #002200;">&#123;</span>
&nbsp;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>gameRunning<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
	ball.center <span style="color: #002200;">=</span> 
CGPointMake<span style="color: #002200;">&#40;</span>ball.center.x <span style="color: #002200;">+</span> ballVelocity.x, ball.center.y <span style="color: #002200;">+</span> ballVelocity.y<span style="color: #002200;">&#41;</span>;
&nbsp;
	<span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
&nbsp;
		<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>startLabel.hidden<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
			startLabel.hidden <span style="color: #002200;">=</span> <span style="color: #a61390;">NO</span>;
		<span style="color: #002200;">&#125;</span>			
         <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
...
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>dealloc <span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>player1 release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>player2 release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>ball release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>player1Score release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>player2Score release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>startLabel release<span style="color: #002200;">&#93;</span>;<span style="color: #11740a; font-style: italic;">//New</span>
        <span style="color: #002200;">&#91;</span>super dealloc<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>En el código superior vemos como primeramente nos hemos definido una serie de constantes que representan la velocidad de la pelota y la cantidad de frames por segundo (FPS), o lo que es lo mismo, el tiempo en milisegundos que nuestro timer tardará en llamar al Game Loop. Ya en <strong>loadView</strong> hemos inicializado la nueva etiqueta, el estado del juego, la velocidad de la pelota y, como hemos dicho antes, hemos creado una instancia de NSTimer que ejecutará nuestro Game Loop cada x tiempo en función a la constante kFPS que hayamos elegido.</p>
<p>Después hemos creado un nuevo método llamado <strong>gameLoop</strong> en el cual, por ahora, simplemente comprobamos el estado del juego mediante gameRunning y en caso de ser positivo cambiamos la posición de la variable ball sumándole la velocidad de la pelota en la coodenada correspondiente, de esta manera implementamos el movimiento de la pelota en función del tiempo.</p>
<p>Si simulamos no pasa nada, veremos nuestra interfaz anterior más una etiqueta que nos incita a tocar la pantalla, pero al hacerlo no ocurre nada, vamos a solucionarlo.</p>
<h4>Control</h4>
<p>Una de principales características del dispositivo iPhone es la carencia de un teclado físico, esta carencia es suplida por una interfaz táctil que nos permite registrar cada uno de los toques que se producen en la pantalla del terminal. Con estas características decidimos que la mejor manera de implementar nuestra interacción con el usuario es mediante el movimiento de nuestra paleta a la par que nuestro dedo, sin perder su posición con respecto al eje y, pero sí en x.</p>
<p>Entonces, para implementar un control como el descrito, abrimos de nuevo <strong>iPingPongViewController.m</strong> y copiamos en el lugar correspondiente los siguientes métodos:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;">...
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>didReceiveMemoryWarning <span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Releases the view if it doesn't have a superview.</span>
    <span style="color: #002200;">&#91;</span>super didReceiveMemoryWarning<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">//New</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>touchesBegan<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSSet</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>touches withEvent<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIEvent <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>event <span style="color: #002200;">&#123;</span>
&nbsp;
	<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>gameRunning<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
		startLabel.hidden <span style="color: #002200;">=</span> <span style="color: #a61390;">YES</span>;
		gameRunning <span style="color: #002200;">=</span> <span style="color: #a61390;">YES</span>;
	<span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>gameRunning<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>self touchesMoved<span style="color: #002200;">:</span>touches withEvent<span style="color: #002200;">:</span>event<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>	
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>touchesMoved<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSSet</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>touches withEvent<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIEvent <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>event<span style="color: #002200;">&#123;</span>
&nbsp;
	UITouch <span style="color: #002200;">*</span>touch <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>event allTouches<span style="color: #002200;">&#93;</span> anyObject<span style="color: #002200;">&#93;</span>;
	CGPoint location <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>touch locationInView<span style="color: #002200;">:</span>self.view<span style="color: #002200;">&#93;</span>;
	player1.center <span style="color: #002200;">=</span> CGPointMake<span style="color: #002200;">&#40;</span>location.x, player1.center.y<span style="color: #002200;">&#41;</span>;;
&nbsp;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>dealloc <span style="color: #002200;">&#123;</span>
...</pre></td></tr></table></div>

<p>Como se observa, hemos sobrecargado touchesBegan para hacer que el juego empiece cuando se pulse por primera vez la pantalla, para ello simplemente testeamos el estado del juego y en caso de estar pausado lo ponemos en estado de ejecución y ocultamos la etiqueta <strong>startLabel</strong>. </p>
<p>En lo que se refiere al control del juego propiamente dicho, hemos decidido hacerlo lo más sencillo posible, simplemente con la sobrecarga de <strong>touchesMoved</strong> asignamos a la vista <strong>player1</strong> las coordenadas en x que obtenemos del toque del dedo en la vista principal, manteniendo constante la coordenada con respecto a y.</p>
<p>En esta ocasión, al simular, veremos como nuestra pelota se mueve hasta desaparecer de pantalla, es normal, no hay límites que produzcan un cambio en su dirección y velocidad. Lo que si observaremos es como si movemos el dedo por la pantalla nuestra raqueta se mueve por el eje x al igual que nuestro dedo.</p>
<p>Pues por hoy ya es suficiente, más adelante implementaremos la detección de colisiones y una sencilla inteligencia artificial para nuestro oponente.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nuestro primer videojuego para iPhone &#8211; I</title>
		<link>http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-i/</link>
		<comments>http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-i/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 09:44:17 +0000</pubDate>
		<dc:creator>gergonzalez</dc:creator>
				<category><![CDATA[Casos de Estudio]]></category>
		<category><![CDATA[Iphone]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[videojuegos]]></category>

		<guid isPermaLink="false">http://www.gergonzalez.com/?p=315</guid>
		<description><![CDATA[Nuevo diseño y nuevo enfoque más orientado al mundo de los videojuegos, por ello, durante este post y sucesivos nos dedicaremos a programar cierto clásico imperecedero que emulaba el tenis de mesa.


El juego original
Creado en 1972 por Atari, pong es uno de los primeros videojuegos de la historia y como tal forma parte de nuestro [...]]]></description>
			<content:encoded><![CDATA[<p>Nuevo diseño y nuevo enfoque más orientado al mundo de los videojuegos, por ello, durante este post y sucesivos nos dedicaremos a programar cierto clásico imperecedero que emulaba el tenis de mesa.<br />
<a href="http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-i/"><img alt="" src="http://farm3.static.flickr.com/2747/4118782737_b88354e83e_o.jpg" class="alignnone" width="618" height="250" /></a><br />
<span id="more-315"></span></p>
<h4>El juego original</h4>
<p>Creado en 1972 por Atari, pong es uno de los primeros videojuegos de la historia y como tal forma parte de nuestro legado y recuerdo. Considerado un videojuego perteneciente al género deportivo, pong simulaba, con mucha imaginación eso sí, el tenis de mesa o ping-pong. </p>
<p>La mecánica de juego era realmente sencilla, un jugador controlaba una pala, normalmente la de la parte izquierda, mientras que la otra era controlada por la máquina o por otro jugador. El objetivo consistía en que uno de los jugadores consiguiera más puntos que el oponente, obteniendo esos puntos cuando el jugador adversario fallaba al devolver la pelota.</p>
<p><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/LPkUvfL8T1I&#038;hl=es_ES&#038;fs=1&#038;iv_load_policy=3&#038;rel=0&#038;color1=0x006699&#038;color2=0x54abd6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/LPkUvfL8T1I&#038;hl=es_ES&#038;fs=1&#038;iv_load_policy=3&#038;rel=0&#038;color1=0x006699&#038;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>
<h4>Empezando</h4>
<p>Para empezar lo primero que debemos hacer es ejecutar <strong>Xcode</strong> y crear un nuevo proyecto, <strong>File &gt; New Project</strong> o <strong>⌘⇧N</strong>, elegimos el template <strong>View-Based Application</strong>, pulsamos <strong>choose&#8230;</strong> le ponemos de nombre <strong>iPingPong</strong> y aceptamos.</p>
<h4>Interfaz gráfica</h4>
<p>Nuestra intención es lograr la interfaz original que se muestra en la imagen inferior. Para ello debemos identificar que variables instanciadas vamos a declarar en nuestra clase <strong>iPingPongViewController</strong>, a simple vista observamos tres vistas para las palas <strong>(player1, player2)</strong> y la pelota <strong>(ball)</strong>, y dos etiquetas para el marcador <strong>(player1Score, player2Score)</strong>, para la red no es necesario declarar ninguna variable, ya que es un mero elemento decorativo y no cambiará su valor durante la ejecución de nuestro juego.</p>
<p style="text-align:center;"><img src="http://www.gergonzalez.com/wp-content/uploads/2009/11/iPingPong.jpg" alt="iPingPong" title="iPingPong" width="323" height="600" class="aligncenter size-full wp-image-331" style="border:none;"/></p>
<p>Una vez claras las variables, abrimos <strong>iPingPongViewController.h</strong> e introducimos el siguiente código para declararlas:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;UIKit/UIKit.h&gt;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> iPingPongViewController <span style="color: #002200;">:</span> UIViewController <span style="color: #002200;">&#123;</span>
&nbsp;
	UIView <span style="color: #002200;">*</span>player1;
	UIView <span style="color: #002200;">*</span>player2;	
	UIView <span style="color: #002200;">*</span>ball;
&nbsp;
	UILabel <span style="color: #002200;">*</span>player1Score;
	UILabel <span style="color: #002200;">*</span>player2Score;	
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIView <span style="color: #002200;">*</span>ball;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIView <span style="color: #002200;">*</span>player1;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIView <span style="color: #002200;">*</span>player2;
&nbsp;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UILabel <span style="color: #002200;">*</span>player1Score;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UILabel <span style="color: #002200;">*</span>player2Score;
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>Antes de seguir ocultaremos el status bar que nos hace perder 20px de superficie de juego, abrimos <strong>iPingPong-info.plist</strong>, añadimos &#8220;<strong>status bar is initially hidden&#8221;</strong> y activamos el checkbutton.</p>
<p><img src="http://www.gergonzalez.com/wp-content/uploads/2009/11/statusbar1.jpg" alt="statusbar" title="statusbar" width="618" height="355" class="aligncenter size-full wp-image-335" /></p>
<p>Lo siguiente será inicializar nuestras variables instanciadas haciendo uso del método loadView() con los valores necesarios para obtener nuestro interfaz, para ello vamos a <strong>iPingPongViewController.m</strong> y copiamos:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;iPingPongViewController.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> iPingPongViewController
&nbsp;
<span style="color: #a61390;">@synthesize</span> ball, player1, player2, player1Score, player2Score;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Implement loadView to create a view hierarchy programmatically,</span>
<span style="color: #11740a; font-style: italic;">// without using a nib.</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>loadView <span style="color: #002200;">&#123;</span>
&nbsp;
	<span style="color: #11740a; font-style: italic;">//Create the main view and assign a black color to background</span>
	CGRect backgroundFrame <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIScreen mainScreen<span style="color: #002200;">&#93;</span> applicationFrame<span style="color: #002200;">&#93;</span>;
	UIView <span style="color: #002200;">*</span>view <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIView alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>backgroundFrame<span style="color: #002200;">&#93;</span>;
	view.backgroundColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor blackColor<span style="color: #002200;">&#93;</span>;
	self.view <span style="color: #002200;">=</span> view;
	<span style="color: #002200;">&#91;</span>view release<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">//Create the net</span>
	<span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> i<span style="color: #002200;">=</span><span style="color: #2400d9;">0</span>; i&lt;<span style="color: #2400d9;">20</span>; i<span style="color: #002200;">++</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
		UIView <span style="color: #002200;">*</span>net <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIView alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>
                           CGRectMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">16</span><span style="color: #002200;">*</span>i, self.view.center.y<span style="color: #002200;">-</span><span style="color: #2400d9;">2</span>, <span style="color: #2400d9;">8</span>, <span style="color: #2400d9;">4</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
		net.backgroundColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor lightGrayColor<span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#91;</span>self.view addSubview<span style="color: #002200;">:</span>net<span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#91;</span>net release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
	<span style="color: #11740a; font-style: italic;">//Create the Score</span>
	player1Score <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UILabel alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>
			         CGRectMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">10</span>, <span style="color: #2400d9;">190</span>, <span style="color: #2400d9;">30</span>, <span style="color: #2400d9;">30</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
	player1Score.font <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIFont fontWithName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Helvetica&quot;</span> size<span style="color: #002200;">:</span><span style="color: #2400d9;">30</span><span style="color: #002200;">&#93;</span>;
	player1Score.text <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;0&quot;</span>;
	player1Score.textColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor whiteColor<span style="color: #002200;">&#93;</span>;
	player1Score.backgroundColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor blackColor<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self.view addSubview<span style="color: #002200;">:</span>player1Score<span style="color: #002200;">&#93;</span>;
&nbsp;
	player2Score <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UILabel alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>
				 CGRectMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">10</span>, <span style="color: #2400d9;">260</span>, <span style="color: #2400d9;">30</span>, <span style="color: #2400d9;">30</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
	player2Score.font <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIFont fontWithName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Helvetica&quot;</span> size<span style="color: #002200;">:</span><span style="color: #2400d9;">30</span><span style="color: #002200;">&#93;</span>;
	player2Score.text <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;0&quot;</span>;
	player2Score.textColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor whiteColor<span style="color: #002200;">&#93;</span>;
	player2Score.backgroundColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor blackColor<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self.view addSubview<span style="color: #002200;">:</span>player2Score<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">//Create our elements</span>
	player1 <span style="color: #002200;">=</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIView alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>
			  CGRectMake<span style="color: #002200;">&#40;</span>self.view.center.x<span style="color: #002200;">-</span><span style="color: #2400d9;">25</span>, <span style="color: #2400d9;">420</span>, <span style="color: #2400d9;">50</span>, <span style="color: #2400d9;">10</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
	player1.backgroundColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor whiteColor<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self.view addSubview<span style="color: #002200;">:</span>player1<span style="color: #002200;">&#93;</span>;
&nbsp;
	player2 <span style="color: #002200;">=</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIView alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>
			  CGRectMake<span style="color: #002200;">&#40;</span>self.view.center.x<span style="color: #002200;">-</span><span style="color: #2400d9;">25</span>, <span style="color: #2400d9;">50</span>, <span style="color: #2400d9;">50</span>, <span style="color: #2400d9;">10</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
	player2.backgroundColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor whiteColor<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self.view addSubview<span style="color: #002200;">:</span>player2<span style="color: #002200;">&#93;</span>;
&nbsp;
	ball <span style="color: #002200;">=</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIView alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>
		   CGRectMake<span style="color: #002200;">&#40;</span>self.view.center.x<span style="color: #002200;">-</span><span style="color: #2400d9;">4</span>, self.view.center.y<span style="color: #002200;">-</span><span style="color: #2400d9;">4</span>, <span style="color: #2400d9;">8</span>, <span style="color: #2400d9;">8</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
	ball.backgroundColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor whiteColor<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self.view addSubview<span style="color: #002200;">:</span>ball<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>didReceiveMemoryWarning <span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Releases the view if it doesn't have a superview.</span>
    <span style="color: #002200;">&#91;</span>super didReceiveMemoryWarning<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>dealloc <span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>player1 release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>player2 release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>ball release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>player1Score release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>player2Score release<span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#91;</span>super dealloc<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>En el código podemos observar como todas las vistas se inicializan con un color, tamaño y coordenadas y se asignan a la vista principal. Igual ocurre con las etiquetas, pero asignándoles un tamaño y tipo de letra. Para la red utilizamos un bucle for para instanciar las UIViews (vistas) que la formarán. Y ya para acabar, no debemos olvidar el uso del método <strong>dealloc()</strong> para limpiar los recursos alojados.</p>
<p>Ahora sólo nos queda <strong>simular</strong> para poder disfrutar de nuestra interfaz gráfica. </p>
<p>Y esto es todo, ya en sucesivos posts se le otorgará interactividad y movimiento. Si encontráis algún error o tenéis alguna duda o pregunta no dudéis en comentar.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gergonzalez.com/casos-de-estudio/nuestro-primer-videojuego-para-iphone-i/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
