<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results for 'app:weblogs' matching tags 'ASP.NET MVC', 'Desarrollo de Software', and 'Azure'</title><link>http://msmvps.com/search/SearchResults.aspx?q=app:weblogs&amp;tag=ASP.NET+MVC,Desarrollo+de+Software,Azure&amp;orTags=0&amp;o=DateDescending</link><description>Search results for 'app:weblogs' matching tags 'ASP.NET MVC', 'Desarrollo de Software', and 'Azure'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Programando Juegos Sociales en L&amp;#237;nea (Parte 2) Tankster y Windows Azure Toolkit For Social Games</title><link>http://msmvps.com/blogs/lopez/archive/2011/07/22/social_2D00_online_2D00_games_2D00_programming_2D00_part_2D00_2_2D00_tankster_2D00_and_2D00_windows_2D00_azure_2D00_toolkit_2D00_for_2D00_social_2D00_games.aspx</link><pubDate>Fri, 22 Jul 2011 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1796584</guid><dc:creator>lopez</dc:creator><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/07/20/social_2D00_online_2D00_games_2D00_programming_2D00_part_2D00_1_2D00_introduction.aspx"&gt;Anterior Post&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/08/03/social_2D00_online_2D00_games_2D00_programming_2D00_part_2D00_3_2D00_tankster_2D00_blob_2D00_storage_2D00_and_2D00_jsonp.aspx"&gt;Siguiente Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El mi&amp;eacute;rcoles pasado, 20 de Julio, Microsoft liber&amp;oacute; una versi&amp;oacute;n &amp;ldquo;preview&amp;rdquo; del Windows Azure Toolkit for Social Games, y public&amp;oacute; una versi&amp;oacute;n beta (con c&amp;oacute;digo) de un primer juego de demostraci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Pueden bajar el c&amp;oacute;digo desde Codeplex: &lt;a href="http://watgames.codeplex.com/" title="http://watgames.codeplex.com/"&gt;http://watgames.codeplex.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pueden jugar el juego en l&amp;iacute;nea en: &lt;a href="http://www.tankster.net/" title="http://www.tankster.net/"&gt;http://www.tankster.net/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tankster01.jpg" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;La soluci&amp;oacute;n actual tiene estos proyectos:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tankster03.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Tankster.GamePlay es un Web Role. Hay un &amp;uacute;nico WorkerRole. Tankster.Core es una librer&amp;iacute;a de clases. Hay c&amp;oacute;digo interesante en Tankster.Common: utilitarios Azure para acceder a repositorios, un &amp;ldquo;job engine&amp;rdquo;, y m&amp;aacute;s; todo ese c&amp;oacute;digo es independiente del juego, podr&amp;iacute;a usarse en cualquier proyecto Azure.&lt;/p&gt;
&lt;p&gt;Estos son mis primeros cortos comentarios sobre el c&amp;oacute;digo y la implementaci&amp;oacute;n de las &amp;ldquo;features&amp;rdquo; de este juego (recuerden, es un beta! Algunas de estas implementaciones podr&amp;iacute;an cambiar en el pr&amp;oacute;ximo &amp;ldquo;release&amp;rdquo;):&lt;/p&gt;
&lt;p&gt;- Tecnolog&amp;iacute;a cliente: HTML5, Javascript, &lt;a href="http://easeljs.com/"&gt;EaselJs&lt;/a&gt; (para programaci&amp;oacute;n del canvas, que permite implementar la parte gr&amp;aacute;fica). &lt;br /&gt;- Tecnolog&amp;iacute;a servidor: ASP.NET MVC 3, algunas vistas Razor para pruebas (tema interesante: &amp;iquest;C&amp;oacute;mo probar el juego cuando sin usar el juego REAL), WCF Web API (otro tema interesante: ver tecnolog&amp;iacute;as alternativas para manejar la actividad del juego. Es importante: un tema a cuidar en este tipo de aplicaciones es c&amp;oacute;mo responder a una gran carga desde el cliente) &lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tankster04.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;- Hay un modelo en el cliente y entidades en Javascript. Vean See src/model, src/game.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tankster05.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;br /&gt;- Hay un modelo del juego There is a server game model (see Tankster.Core class library project)&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tankster06.png" alt="" /&gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&lt;br /&gt;- Pueden jugar en modo &amp;ldquo;single player&amp;rdquo; o pueden elegir &amp;ldquo;multi-player online&amp;rdquo;. En este caso, el juego usa el ACS Portal para permitir la autenticaci&amp;oacute;n usando Federated Authentication:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tankster02.jpg" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;- El c&amp;oacute;digo cliente reside en una sola p&amp;aacute;gina: index.html (con montones de archivos javascript referenciados desde ah&amp;iacute;) &lt;br /&gt;- El c&amp;oacute;digo cliente env&amp;iacute;a JSON (comandos) a los WCF Web API endpoints, usando Ajax/JQuery. Hay varios servicios publicados, exponiendo una interfaz tipo REST&lt;/p&gt;
&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;routes.MapServiceRoute&amp;lt;GameService&amp;gt;(&amp;quot;&lt;span style="color:#8b0000;"&gt;game&lt;/span&gt;&amp;quot;);
routes.MapServiceRoute&amp;lt;AuthService&amp;gt;(&amp;quot;&lt;span style="color:#8b0000;"&gt;auth&lt;/span&gt;&amp;quot;);
routes.MapServiceRoute&amp;lt;UserService&amp;gt;(&amp;quot;&lt;span style="color:#8b0000;"&gt;user&lt;/span&gt;&amp;quot;);
routes.MapServiceRoute&amp;lt;TestService&amp;gt;(&amp;quot;&lt;span style="color:#8b0000;"&gt;test&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;- Mucha de la actividad del juego es enviado al servicio game/command. El servicio (en el web role) actualiza el estado del juego guard&amp;aacute;ndolo en un blob en el Azure Storage. Fragmento de c&amp;oacute;digo:&lt;/p&gt;
&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#008000;"&gt;// Add gameAction&lt;/span&gt;
var gameAction = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; GameAction
{
    Id = Guid.NewGuid(),
    Type = commandType,
    CommandData = commandData,
    UserId = &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.CurrentUserId,
    Timestamp = DateTime.UtcNow
};
&lt;span style="color:#008000;"&gt;// Cleanup game actions lists&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; game.GameActions.Count(); i++)
{
    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (game.GameActions[i].Timestamp &amp;lt; DateTime.UtcNow.AddSeconds(-10))
    {
        game.GameActions.RemoveAt(i);
        i--;
    }
}
game.GameActions.Add(gameAction);
&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.gameRepository.AddOrUpdateGame(game);&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;- El estado del juego es &amp;ldquo;poleado&amp;rdquo; por los clientes javascript consultando directamente el blob storage. De esta forma, el Web Role ASP.NET MVC tiene menos carga. &lt;br /&gt;- El blob reside en el mismo dominio, as&amp;iacute; que no son necesarias llamadas Ajax cross-domain. Pero el juego est&amp;aacute; preparado para ese tipo de llamadas, reemplezando el objeto XmlHttpRequest por un componente Flash. &lt;br /&gt;- El modo de juego Skirmish (cinco jugadores en una batalla) est&amp;aacute; hecho encolando los jugadores hasta llegar a cinco. Ese trabajo lo hace el Worker Role. Va publicando el estado en un blob que es &amp;ldquo;poleado&amp;rdquo; por los clientes. &lt;br /&gt;- Las estad&amp;iacute;sticas son procesadas en el worker role: los clientes javascrip env&amp;iacute;an comando al Web Role, &amp;eacute;ste selecciona algunos para estad&amp;iacute;sticas y los env&amp;iacute;a a una cola Azure. No se ocupa de las estad&amp;iacute;sticas en el momento, para no afectar al cliente. Finalmente, esos datos para estad&amp;iacute;sticas se manejan en el Worker Role. &lt;br /&gt;- User status, Game status, Skirmish Game Queue status son blobs. &lt;br /&gt;- Las estad&amp;iacute;sticas se guardan en SQL Azure. &lt;br /&gt;- El &amp;uacute;nico worker role tiene un Job Engine (motor de trabajos) para procesar varias tareas, ejemplo &amp;ldquo;fluent&amp;rdquo;:&lt;/p&gt;
&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#008000;"&gt;// Game Queue for Skirmish game&lt;/span&gt;
Task.TriggeredBy(Message.OfType&amp;lt;SkirmishGameQueueMessage&amp;gt;())
    .SetupContext((message, context) =&amp;gt;
    {
         context.Add(&amp;quot;&lt;span style="color:#8b0000;"&gt;userId&lt;/span&gt;&amp;quot;, message.UserId);
    })
    .Do(
        &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SkirmishGameQueueCommand(userRepository, 
            gameRepository, workerContext))
    .OnError(logException)
    .Start();
&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Hay varios puntos para comentar y discutir, alimento para futuros posts. Seguramente la soluci&amp;oacute;n actual evolucionar&amp;aacute; y nuevas versiones ser&amp;aacute;n publicadas (&amp;iquest;esta semana? &amp;iquest;la pr&amp;oacute;xima?). Pero es interesante ver publicado un juego en l&amp;iacute;nea y su c&amp;oacute;digo disponible para analizarlo.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>