dijous, 19 de desembre de 2013

M'estrene en la programació de videojocs ;)

Tinc un greu problema que ja he descrit en uns altres posts. M'agrada provar una tecnologia i quan ja faig algo, perd l'interés en mi. Ara intentaré què no ho faça. Em vaig proposar a mi mateixa programar videojocs. És una de les meues assignatures pendents. Després de pegar-me algunes òsties que altres, especialment, per què pensava que la part principal era la del programador, però ja he vist i comprés que no, he trobat la tecnologia adequada. Farà uns 16 anys ho vaig intentar en ASM (i no ho vaig aconseguir). Després en Pascal, C... fa poc menys d'un any ho vaig intentar amb  MonoGame. També em vaig cansar. Finalment he aconseguit dur un xicotet projecte a terme amb Unity. La primera ventaja que té, és que pots comprar (alguns són debades) assets (gràfics, so, scripts...), cosa que et permet, si eres un patan amb els programes de disseny gràfic com jo, obtindre algua imatge per als jocs. La segona és que té una versió gratuïta (amb certs límits). Total, que després de un parell de setmanes, seguir diversos tutorials i pegar-me unes quantes cabotades contra la paret, he aconseguit fer un clon del Simon (seguir la seqüència). De moment, he fet un cutre (recordeu que no sé dibuixar ni en paper ni per ordinador) joc, però qui sap... Podeu observar una demo en  http://drpep.vicentfernandez.cat. Prompte estarà disponible per Android i possiblement per altres plataformes, ja què unity et permet fer-ho de manera més o menys senzilla i gratuïta:



dimecres, 20 de novembre de 2013

Rotllo personal ;)

Després de pegar-li voltes ja he trobat què m'agrada fer. Sempre he pecat de no agradar-me els projectes grans i llargs (sobretot açò). Em canse de seguida de fer el mateix. No valdria per a estar en una línia de muntatge  ni per a professions no repetitives (o potser sí, mai se sap que et vindrà en aquesta vida). Sempre m'ha agradat fer un projecte curt, una "proveta" per provar tal o qual cosa i ja està. Ja duc temps programat aplicacions per a mòbil (mini aplicacions). Però trobe que estic a gust. Es poden fer de més complicades, però. Però també simples. Una funcionalitat i avant. Això et permet fer una aplicació en dos-tres setmanes (de moment açò és el meu hobby, possiblement en dos-tres dies podria fer alguna de les aplicacions que ja tinc publicades, inclús alguna en menys). El cas és què, de moment, mentres dure sóc feliç i prompte (espere) em clavaré al món dels jocs. Veure'm com queda la cosa... ;)

dijous, 14 de novembre de 2013

Clean Code... WTF? És realment viable?

Després d'haver llegit un bon grapat (realment no tants però així quede d'entés ;)) de llibres sobre fer codi clar, bona programació... no sé com dir-ho, en anglés Clean Code, he trobat a l'anar a modificar (adaptar) programes d'altres (programari lliure) que no hi havia per on agarrar-ho. Vaig a posar un cas (no, no vaig a refactoritzar-lo ni vaig a menyspreuar-lo) en el que volia "treballar" actualment. Volia fer una modificació del fòrum Simple Machines Forum (el fòrum és una passada, va molt bé i inclou de serie una versió per a mòbil que ve molt bé). El resultat és què  la funció (on supose) que volia fer la modificació, té un tamany de més de 600 línies!!! Recordem que uns dels principis (segons l'Uncle Bob) és què les funcions han de fer una i només una cosa, i han de ser curtes. El que caldria supose què és refacoritzar-lo, però a veure qui és el guapo que es posa ara a fer-ho  (hi ha molt de codi al fòrum). He de dir també que el codi està fet en php, i no aprofita classes. No he gastat molt PHP, especialment en projectes grans, però he llegit que no es gasta en cap projecte seriòs i mitjanament gran per què és un dolor de cap bestial. I això fa que un bon disseny siga realment complicat. Dubte què hagen fet TDDs, programació àgil...
També cal tindre en compte què moltes vegades s'ha de posar codi de presentació i codi de lògica junt (si no gastes un framework tipus smarty).
El que volia dir, és que la programació bonica i bona (hehehehe) és molt bonica (encara que em repetisca) però, és viable? Encara no he participat en un projecte gran per averiguar-ho. Hi ha qui diu que sí i m'asegura que ho ha fet així (Jaume Cardona si em lliges digues hola ;)) i en altres projectes (especialment en les consultores) diuen què és inviable. El que si què és cert, que amb un gran equip de xicotets contribuidors com pot tindre este paquet de fòrum pot ser  (i dic pot ser) que valga més l'espart que l'escurada. Espere continuar dedicant-me a la programació molt de temps (continuant o no amb la docència) i aniré averiguant-ho.

diumenge, 3 de novembre de 2013

S'acaba la introducció a la programació

Com ja vaig avisar, estic fet un curs de programació obert al públic ;):
http://moodle.plataformesdigitals.cat/course/view.php?id=8
Hem acabat el curs d'introducció, que serà el següent?
Possiblement orientació a objectes, però... ;)

dijous, 31 d’octubre de 2013

Secret Santa

Per fi, i fruit de la necessitat he creat una nova "aplicació". Realment és una web per a mòbil, però que es pot visitar com aplicació des de qualsevol mòbil (bo, de moment només windows phone i android). Es tracta d'una aplicació per a fer els sortejos d'amic invisible. Cada usuari tindra un altre usuari com a resultat.
També es pot veure via web a :
http://secretsanta.vicentfernandez.cat

Podeu veure unes captures de pantalla:




diumenge, 13 d’octubre de 2013

Comence un curs de programació

He començat un curs de programació (realment seran una série de cursos), obert a tot el públic clar (es pot entrar com a visitant),

http://moodle.plataformesdigitals.cat/course/view.php?id=8

La idea és anar fent un curs o cursos de totes les fases de programació:


  • Programació bàsica (Introducció a la programació) 
  • Entorns de programació
  • Programació Orientada a Objectes
  • Programació de jocs
  • Programació RAD
  • Programació Mòbil
  • Programació servidor
  • TDDs
  • Gestió de projectes (gestió de codi, personal..)
  • ...

dilluns, 7 d’octubre de 2013

Quan dos "gurús" recomanen el contrari



Ja m'ha passat alguna vegada i fa poc estava comentant-ho amb un col·lega (Hola Master Jail /Juan Ramon ;)). Després de llegir-me el llibre Clean Code de Robert C. Martin, vaig començar a llegir-me el llibre Test-Driven Development by Example de Kent Beck. El llibre me l'havia recomanat molta gent, des de Juan Ramon fins al mateix autor de Clean Code al seu llibre. La meua sorpresa ha sigut al inspeccionar les recomanacions d'eliminació de duplicitat al fer els tests, al final el codi del test queda així:

public void testMultiplication() {
   Dollar five= new Dollar(5);
   assertEquals(new Dollar(10), five.times(2));
   assertEquals(new Dollar(15), five.times(3));
}


o encara pitjor:
public void testEquality() {
     assertTrue(new Dollar(5).equals(new Dollar(5)));
     assertFalse(new Dollar(5).equals(new Dollar(6)));    
     assertTrue(new Franc(5).equals(new Franc(5)));
     assertFalse(new Franc(5).equals(new Franc(6)));
}

En canvi, Bob Martin sempre ens recomana guardar els objectes en una variable (anomenar-los si no em falla la memòria). La primera línia de l'últim test deuria d'haver-se escrit així:

   dollarfive = new Dollar(5);
   anotherdollarfive = new Dollar(5);
   assertTrue(dorlarfive.equals(anotherdollarfive));

És a dir, exactament remomanacions contràries. A mi, personalment m'agrada no tindre mètodes/objectes anònims i guardar-los en variables (com ho fa Bob Martin). La majoria de programadors de node.js fan el contrari... per a gustos colors. I a vosaltres, que vos agrada més?

dilluns, 9 de setembre de 2013

TDD estan molt bé però...

Doncs com ja heu vist (si és que algú segueix el meu bloc, clar ;)) que estic intentant aprendre a programar decentment. I intente, per això, gastar TDDs. Però de vegades em planteja més problemes propis del sistema de test, que si no els gastara.
L'exemple que m'ha fet "pedre" unes quantes hores, és amb el nunit de Visual Studio, fent un test d'una classe em C# de Windows Phone Class Library (target 7.1 SDK, no sé si això és rellevant però pense que no). En resum, el test seria algo així:

   [TestMethod]
        public void testAutenticadorLogin()
        {
            Autenticador au = new Autenticador("http://localhost", 800, "test", "test");
            au.login();
        }

Què simplement intenta autenticar mitjançant un webservice instal·lat en localhost, l'usuari test i la contrassenya test.

Doncs sempre que intentava llançar el test em traia una excepció d'arxiu no trobat. Després de diverses proves, inclús funcionant en l'aplicació de mostra però no en el test, descubrisc què el problema està en al fer el login (au.login), per tal d'obrir una url remota (l'accés al webservice) gastem el el component WebClient:

 System.Net.WebClient wc = new System.Net.WebClient();

Si comentava eixa línia el programa no fallava al runtime (òbviament no feia l'esperat). Pareix ser què al ser una dependència (System.Net) no la pot trobar el sistema de test (nunit). L'única solució que he trobat després de fer un poc de googling ha segut anar a C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0 (la carpeta on està instal·lat el framwork utilitzat) i copiar tant el .xml com el dll corresponent a System.net a la carpeta debug del projecte de test:

  1. Anar a la carpeta on està el framework, en el meu cas C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0
  2. copiar els arxius .dll i .xml que creen la dependència, en el meu cas System.Net.dll i System.Net.xml, a la carpeta debug
  3. creuar els dits i que funcione ;)
El cas és que ara no llença l'excepció, però he de continuar mirant que passa per què ara a l'intentar descarregar la url (en el callback) dona este missatge:
[net_webclient]\r\nArgumentos: \r\nLas cadenas de recursos de depuración no están disponibles. La clave y los argumentos suelen proporcionar suficiente información para diagnosticar el problema. Vea http://go.microsoft.com/fwlink/?linkid=106663&Version=4.0.60310.0&File=System.Net.dll&Key=net_webclient

Ja que, entre altres coses eixa url no existeix ja ;)
I recorde, el problema només està en el framework de test, l'aplicació mòbil funciona "funciona" perfectament.

dijous, 5 de setembre de 2013

Múltiples plataformes amb Visual Studio II ( i Estrenant GitHub )

Ja fa temp que volia fer alguna cosa semblant. Ja fa temps vaig crear un parser C# per a feeds atom que val tant per Android, com per a WP ( i deuria de valer per a IOS també). Molt modest però valia per a fer aplicacions que llegiren de blogs personals. El parser formarà part de d'una col·lecció que aniré afegint anomenada (molt originalment) util, que es pot trobar en https://github.com/fercavi/util.

La classe anomenada cAtom (notació hongaresa, la vaig fer abans de llegir Clean Code ;)), només té una operació, Run() ;) (realment 2, ara ho explique).  Quan acabe el Run tindrà dos llistes, una de títols (getTitle) i una de notícies (getValue).
Els passos seran els següents:
1. Inicialitzar-la en el constructor, diguent-li la url que volem llegir i, opcionalment, el nombre d'elements que volem extraure (per defecte 10).
2. Afegir-li un callback, en els mòbils la majoria d'events són asíncrons, per tant necessitarem una funció de callback que serà la que carregue la informació gràfica d'interfície  una vegada estiga carregada la informació del feed Atom.
3. Executar Run() que serà el procés que faça la feina i quan acabe execute la funció callback del pas 2.


Anem a veure l'exemple d'ús per a Android i per a WP. Tenim el projecte WPCore  (WP Class Library) què tindrà el namespace util, ara només la classe cAtom. (ho he havut de fer així per com funciona Xamarin). I creem un projecte testWP (Windows Phone App) que tindrà la interfície gràfica i demés coses específiques de WP. A la interfície WP afegim un botó i un navegador web, per a visualitzar les dades baixades. El codi seria:

private void Button_Click_1(object sender, RoutedEventArgs e)
        {

            carregador = new util.cAtom("http://www.vicentfernandez.cat/feeds/posts/default", 10);
            carregador.CarregarDades += callBackCarregador;
            carregador.Run();
        }

Vegem que hem afegit un callback que serà qui òmpliga les dades:

private void callBackCarregador()
        {
            string html = "<html><body>";
            foreach (var titol in carregador.getTitle())
            {
                html += "<h2>" + titol + "</h2>";
            }
            html += "</body></html>";
            visualitzador.NavigateToString(html);
        }

I ara vegem el resultat:



Ara anem a fer la mateixa aplicació en android. Creem una Android Class Library (anomenada AndroidCore) buida i afegirem un element existent (cAtom.css) de l'anterior projecte. Però hem de tindre en compte que haurem de posar afegir com a link enlloc de copiar, per tal que les modificacions en un projecte afecten a l'altre.
Després crearem un altre projecte Android (anomenat testAndroid), però esta vegada aplicació, i afegirem una referència a l'anterior projecte. Afegim un WebView a l'aplicació i posem el codi per a què quan s'aprete el botó es visualitze:

 button.Click += delegate
            {
                carregador = new util.cAtom("http://www.vicentfernandez.cat/feeds/posts/default", 10);
                carregador.CarregarDades += CallbackCarregarDades;
                carregador.Run();
            };

Vegem que (òbviament) també té un callback:
private void CallbackCarregarDades()
        {
             Android.Webkit.WebView wc = FindViewById<Android.Webkit.WebView>(Resource.Id.webView1);
             string html = "<html><body>";
             foreach (var titol in carregador.getTitle())
             {
                 html += "<h2>" + titol + "</h2>";
             }
             html += "</body></html>";
             wc.LoadData(html, "text/html; charset=UTF-8", "ISO-8859-1");
       }

I ara vegem el resultat:

dissabte, 31 d’agost de 2013

Múltiples plataformes amb Visual Studio

Si recordem estàvem creant un dau fa uns quants posts (m'ha pillat vacances, i les vacances, vacances són ;)). Ara anem a aprofitar el projecte que teníem  que simplement era test i la classe dau, i anem a afegir un nou projecte, per exemple Windows phone: (Botó dret sobre la solució i afegir nou projecte) seleccionem Windows phone:

Afegim un botó que quan fem click cree un dau, i mostre el número. Haurem de referenciar els projectes Project->Add Reference, seleccionar projecte i posem el projecte dau per a poder crear el dau, a banda de es recomanable que tot tinga el mateix namespace, si no haurem d'anar afegint usings.
Es possible que si actualitzeu els namespaces vos done problemes. Haureu també de canviar-ho als arxius .xaml:x:Class="RollDice.App ...

on RollDice és el nom del namespace. Afegim un botó, i un event capturador de l'event:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
            Dau d = new Dau(10);
            int res = d.Tirada();
            MessageBox.Show(res.ToString());
}
I veiem el resultat:
 
Ara anem a fer el mateix amb Android, crearem un projecte Android:



El que anem a fer és substituir el codi de la funció delegada per capturar l'event que hi ha, per un codi similar al que tenien en la funció anterior. Però abans cal enllaçar la classe dau. En principi i en teoria a l'haver fet una biblioteca de classes podriem fer-ho directament afegint al projecte d'Android una referència al projecte Dau, però com hi ha un problema de moment (en teoria estan a punt d'arreglar-ho), anem a fer una xapusa i anem a enllaçar l'arxiu (afegir arxiu existent) de la classe dau.cs i així ho tindrem arreglat.  Una vegada ho tenim, canviem el codi de l'event Click per:
button.Click += delegate {
RollDice.Dau d = new RollDice.Dau(10);
int res = d.Tirada();
button = FindViewById<Button>(Resource.Id.MyButton);
button.Text = res.ToString();
};
 




Arranquem, ens dirà que seleccionem la imatge de l'emulador i tal, i després d'un ratet (la primera vegada ha d'instal·lar tot el framework .net a l'emulador):

 
I ja hem vist com gastar el mateix codi per a Android i per a Windows Phone ;)

Xamarin Studio

Hem va quedar pendent, fa dos posts, explicar com fer una solución en VS multiplataforma. Per a explicar-ho el primer que necessite és un framework multiplataforma. He elegit Xamarin, podía haver elegit qualsevol altre, però este em permet escriure en C# tot el codi, davall el paraigüa de Mono. Si només vols fer programes sense reutilitzar cap component extern ni res, la versió és gratuïta. Si per exemple vols fer jocs i utilitzar Monogame (port de XNA per a moltes plataformes) ahí has d'adquirir alguna versió de pago. També pot ser que vullgues utilitzar VS per a fer programes en Android amb C#....  Doncs hauràs de pagar mínim 300$ per desenvolupador per plataforma mínim. Pot parèixer un poc car, però si vas a dedicar-te professionalment a desenvolupar aplicacions per a móbil no tens més remei (d'este o d'altre similar). M'explique, imaginem que vas a fer un programa per a mòbils i vols fer-ho per a les plataformes més gastades (Windows phone, Iphone i Android). Tens dos opcions o escriure TOT el programa en C#, Objective C i Java (respectivament), i adaptar-te a les particularitats de cada plataforma o escriure tota la lògica en C# (en este exemple) i adaptar la part gràfica (interfície) a cada plataforma.
Aprofitant que sóc professor (;), ho vaig haver de demostrar) he adquirit la versió educacional per 100$ cada plataforma. La instal·lació és molt senzilla, anem a WWW.xamarin.com i baixem l'instal·lador. Segons el compte que tingam (si hem pagat o no) ens instal·larà unes coses o unes altres, però l'avantatja que instal·la tots els requisits. Si teniu  una connexió de risa com jo (3 MB )  estarà un ratet baixant coses (algunes hores) i s'instal·larà els pluggins per al VS (si el teniu instal·lat i si teniu una versió que no siga la express, ja que no permet instal·lar plugin) .
I amb això ja estaríem llestos per al següent post ;)

Val a dir que la comunitat de Xamarin és una comunitat prou activa. Et permet comprar components, té un fòrum de suport, organitzen webminaris (seminaris online)... A mi m'ha agradat l'experiència.

divendres, 30 d’agost de 2013

Presumint d'ordinador

Mira que m'agrada presumir de ben poques coses. De fet em considere (i em solen considerar) una persona ben modesta. Però ara no me n'he pogut estar... Vaig a presumir d'ordinador:


Vaig a sustituir el meu ordinador de sobretaula (amb le stres pantalles) per este bitxet. No està mal, eh?
Especificacions:

  • i7 3610QM
  • 8GB de RAM (ampliables a 32)
  • 128 GB SSD (si no teniu disc SSD vos ho recomane abans de canviar de PC)
  • 500 GB de disc mecànic
  • ATI 7970M  2GB (casinà ;))
Això si ho he fet de segona mà, i el problema és que ara no puc fer-li ni una extensió de garantia ni assegurar-lo (no trobe en cap lloc que ho vullguen fer).
Però és una filigrana... estic escrivint este post des d'una màquina virtual, sense apenes drivers i MacOS va com el llamp. (No, no m'estic passant a MacOS, però per a fer aplicacions per a iphone/ipad/macos no tens un altre remei).

Em queda fer algun test en algun joc, de moment, el heaven engine trau uns 40-50fps, mentres que la torre vella, apenes passava de 15 (en la versió actual, clar). Tots els emuladors de mòbil van a la perfecció... no sé què més puc demar  (a banda de tindre temps per a disfrutar-lo)

diumenge, 11 d’agost de 2013

TDDs + reutilització d'objectes en Visual Studio 2012

Doncs això, mai m'he mostrat partidari de cap metodologia de programació, ni tan sols de la programació orientada a objectes... però deu ser que em faig major ;) Anem a matar en un post dos pardals d'un tir. Anem a gastar una de les bases de les metodologies àgils (en realitat no té per què, es pot emprar en qualsevol metodologia) i anem a començar a veure com fer codi "multiplataforma".
Anem a gastar Visual Studio 2012. Creem una solució de Portable Class Library (en C#):
Creem una nova classe, Dau:
namespace RollDice
{
    public class Dau
    {

    }
Sense cap mètode. Per què sense cap mètode? Ahí està la gràcia dels TDD (Test Driven Development, Desenvolupament Orientat a Test). Anirem omplint la classe segons fallen els tests.
Ara anem a afegir una nova solució, què serà de test c#:
Ens crearà una classe de test buida, li canviarem el namespace per a que siga el mateix que la classe dau:
[TestClass]
    public class testDau
    {

         [TestMethod]
         public void TestMethod1(){
        }
    }

De moment només ens interessa saber que el mètode que hi haja darrere de cada [TesMethod] Serà un test, ens eixirà a la finestra de tests (després veurem).
Què és el primer que hem de comprovar? Que li fa falta a un dau? El nombre de cares, no? Si no heu jugat a rol, possiblement no ho entendreu ;)
canviem el nom al test, per a que siga més encertat, creem un dau amb 4 cares i comprovem que realment les tinga quan es crea, per a això ens caldrà afegir una variable privada dau:
 private Dau dau;
 [TestMethod]
        public void TestCares()
        {
            dau = new Dau(4);
            Assert.AreEqual(4, dau.getCares);           
        }

Anem a pams, el primer que passa és què això no compila, la classe Dau està buida i no té cap mètode, fem que compile, afegim a la classe dau el constructor i la propietat cares:
 public Dau(int cares)
        {
            getCares = cares;
        }       
        public int getCares {  get; private set; }

 Ara que compila anem a veure que fa el test. Crea un dau de 4 cares, i el test passarà (les condicions de passar el test es fan amb les instruccions Assert) si efectivament el test és de 4 cares.  Seleccionem el menu Test->Run All Test

Si el test passa veurem un check verd, si no passa, veureu una aspa roja,comproveu-ho posant:
  Assert.AreEqual(5, dau.getCares);

Una vegada ja tenim comprovat que el constructor funciona, anem a acabar el dau. Què li falta? Tirar, l'opció de tirar. Abans de programar el codi, recordeu, hem de fer el test; afegim a la classe de test:
 [TestMethod]
        public void TestTirades()
        {
                dau = new Dau(10);
                 int tirada = dau.Tirada();
                Assert.IsTrue(tirada <= 10);
                Assert.IsTrue(tirada >= 1);
          }

      
en este exemple, creem un dau de 10 cares, el llancem, i comprovem que la tirada estiga entre 1 i el nombre de cares. Com no compilarà, creem el mètode a la classe dau:
  public int Tirada()
        {
            Random random = new Random();
            return random.Next(1, getCares);
        }

Vejam que el test passa. Òbviament este test, només serà vàlid per a 10 cares, res ens impedix fer este test:

 [TestMethod]
        public void TestTirades()
        {
          
            for (int i = 1; i <= 20; i++)
            {
                dau = new Dau(i);
                int tirada = dau.Tirada();
                Assert.IsTrue(tirada <= i);
                Assert.IsTrue(tirada >= 1);
            }
        }

 I així hauriem comprovat que els daus, almenys fins a 20 cares, funcionen ;). Doncs això és el TDD, primer realitzar quins tests ha de passar (incloent limits de vectors, entrades extranyes, si llança excepcions...)
A propers posts continuarem el projecte afegint múltiples configuracions per al projecte

dijous, 25 de juliol de 2013

Lectures per a l'estiu

Tinc un poc abandonat el blog, per què no he tingut massa temp, estic fent proves i llegint llibres. D'això va este post, de llibres. Lectures recomanades per a ser un bon programador (multiplataforma), especialment dedicat per a jocs. Comencem amb llenguatges de programació, C#, The C# Player's Guide, de TB Whiteker, he arribat a ell mitjançant els seus tutorials:


No es pot trobar per kindle, però en Amazon està per 20€. C# trobe que és el llenguatge del futur (més que java), òbviament em puc enganyar (de fet, segur que m'enganye tenint en compte la meua sort en les apostes). I gràcies a la tasca dels xics de Mono, es pot programar per a quasi qualsevol plataforma. De vegades cal una altra biblitoeca (Xamarin, tinc un post pendent sobre eixe tema). Cal recordar que el creador de C# és el mateix què el de delphi, per algo serà...

Una vegada tenim clar com es programa en C#, necessitarem que ens diguen com programar per mantindre bé el codi.Al principi pareix una pèrdua de temps, però a mig-llarg termini t'estalvia temps si vas a programar algo més complicat que el joc d'endevina el número ;), el llibre és ben conegut entre programadors veterans, i escrit per un dels impulsors de les metodologies àgils:
Hi ha ara en aquestos moments una pack dels dos llibres (Clean Code i The Clean Coder) de Robert C. Martin (també conegut com Uncle Bob) per 16€ en versió Kindle. Este llibre no pot faltar a la teua biblioteca.

I per últim (encara no me l'he llegit però si comprat), podem trobar com programar per a windows 8 i windows phone 8 mitjançant Monogame (port a XNA), és a dir que val per a qualsevol plataforma. En estos moments el podem trobar per 20€ en versió Kindle, Windows 8 and Windows Phone 8 Game Development, per Adam Dawes, un membre de la comunitat de MonoGame:

No vos deixeu enganyar, encara que parle de windows 8, és perfectament vàlid per a Linux, ios, mac, Android...

dijous, 27 de juny de 2013

Invertir incrementa la productivitat?

De vegades, pareix que invertir és cremar diners, sobretot si observem a l'empresariat "patri". Ja duc diversos dies fent proves, cavil·legant, investigant... En el tema de fer desenvolupaments multiplataforma. La idea més fàcil, baixar-se el sdk de cada plataforma (sol ser gratuït) i ala, a la marxeta. Parlant de mòvils: BB, WP, IOS, Android sense comptar versions. Damunt cada versió té el seu llenguatge de programació (C++,C#-VB,Objective C, Java), encara què són prou pareguts. És a dir que estariem parlant de 4 entorns en 4 (o més) llenguatges de programació. Crec que unificar un programa amb eixos criteris podria ser un esforç massa gran, inclús per als que no ens dediquem professionalment a açò (almenys no de moment). Mirant alternatives, he trobat diverses, sobretot amb diferents preus:

Phonegap

 http://phonegap.com/
Gratuït, però només treballa amb interfícies

Xamarin

http://xamarin.com
pots fer aplicacions simples gratis amb C#, per a IOS i Android. Hi ha versions més completes per 300$ cada plataforma.

Unity

http://unity3d.com/
Exclusivament per a jocs, 1500$ per plataforma, pràcticament per a qualsevol plataforma. Si volem escriptori, android, ios serien 4500$. Suposant BB i WP que estan en fase beta, serien 7500$. Seria una inversió molt important per a un programador freelance.

XNA

http://www.monogame.net/
http://msdn.microsoft.com/en-us/centrum-xna.aspx

Actualment mort, creat per microsoft.Principalment per a jocs. Incialment creat per a plataformes.NET ara continuat mitjançant MonoGame per a quasi totes les plataformes (juntament amb Xamarin per a ios i android). Pots acabar fent aplicaicons per a pràcticament totes les platafomes.

Marmalade

http://www.madewithmarmalade.com/
La versió per a totes les plataformes són 1500$ a l'any. És de les poques què inclou BB.


De moment vaig a provart la versión XNA+Monogame+Xamarin gratuïta, si em convenç adquiriré llicència, que no tinc res en contra de pagar per serveis que són útils. Anem a fer càlculs, què és al que anava al principi de l'article, imaginem què vull fer un joc per a les 4 plataformes d'abans. Imaginem que costa, aproximadametn 2 mesos de fer en cada plataforma. Això faria un total de 8 mesos. En canvi fer l'aplicació per un framework que et fa la feina, serien 2-3 mesos. Caldira veure si la diferència de mesos (en sou) equival al que pagues de llicència pels programes. Per exemple, el cas de Xamarin em 300$ per plataforma, cap programador cobraria 300$ per un treball de 2 mesos. A més, la llicència ja la tindries per als propers desenvolupaments, així que només en un projecte ja estaria més que amortitzada.
Els empressaris són reacis a fer este tipus d'inversions, però crec que he demostrat, més que de sobra, que incrementaria, i en molt, els beneficis.







dimarts, 18 de juny de 2013

Nova aplicació: Club Taekwondo La Safor

A la espera de que em deixen drets per a públicar dades i  utilitzar logos del Club de Taekwondo al que pertany,
Simplement és un lector de Atom, que he enllaçat al blog del club (http://taekwondolasafor.blogspot.com.es). Bàsicament he realitzat una xorrada de classe lectora, que explicaré en un post posterior, i he posat un component webbrowser que llig del que li passa la classe lectora de Atom, Canviant-li els logos, el  fons, i un línia de codi (la url del blog), es podria fer per a qualsevol Atom.

dijous, 13 de juny de 2013

Passant POST i GET paràmetres en windows phone

Un dels problemes principals quan accedim a urls és passar paràmetres amb GET i POST. No és molt complicat, però pots tirar-te uns quants dies buscant informació si tens la mala sort que tinc jo ;).
Primer ja hem treballat amb GET, és la forma "normal" amb que hem treballat en anteriors posts, simplement amb un webclient i  esperar l'arxiu de manera asíncrona, per a passar par1, par2... per get els afegirem a la url que obrim:


            WebClient wc = new WebClient();
            wc.DownloadStringCompleted += HttpCompleted; //funció que es cridarà quan es connecte l'event
            wc.DownloadStringAsync(new Uri("http://url?par1=valor1&par2=valor2"));



 private void HttpCompleted(object sender, DownloadStringCompletedEventArgs e)
        {

            if (e.Error == null)
            {
                  //en e.Result tindrem l'arxiu com a cadena de text
             }
       }



El problema és que si volem fer-ho per POST o si volem afegir cookies ho haurem de fer d'una altra manera, ho haurem de fer amb webrequest, i necessitarem capturar dos "events", l'inici de la descàrrega i inici de l'stream de dades dades POST, i veurem un allDone que del que parlarem després: 

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sTuentiURLLogin);
            request.ContentType = "application/x-www-form-urlencoded";
            request.Method = "POST";
            request.BeginGetRequestStream(new AsyncCallback(BGRS), request);


 private static void BGRS(IAsyncResult asynchronousResult)
         {
             HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

            //Final de l'stream de dades post:
             Stream postStream = request.EndGetRequestStream(asynchronousResult); 

            //que volem enviar:
             string postData = "par1=valor1&par2=valor2";
             byte[] byteArray = Encoding.UTF8.GetBytes(postData);
             postStream.Write(byteArray, 0, postData.Length);
             postStream.Close();

            //esperem la resposta asíncronament:
             request.BeginGetResponse(new AsyncCallback(BGR), request);
             allDone.WaitOne();

         }

 private static void BGR(IAsyncResult asynchronousResult)
        {
             HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
             HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
             Stream streamResponse = response.GetResponseStream();
             StreamReader streamRead = new StreamReader(streamResponse);           

              //en responseeString tindrem el Resultat final
              string responseString = streamRead.ReadToEnd();
      }


Sí voleu saber com funciona internament, simplement llegiu un poc els comentaris que he posat, tampoc té molta dificutat, el mètode BGRS, envia el POST asíncronament, i l'arreplega asíncronament el mètode BGR. Per últim ens faltaria afeir un:

 Private static ManualResetEvent allDone = new ManualResetEvent(false);

per a fer el allDone.WaitOne(), el que fa el mètode és esperar (bloquejar-se) fins que aplega un senyal (descàrrega).

Si vulguerem enviar cookies, seria molt senzill amb un element:

   static private CookieContainer CC = new CookieContainer(); 

en la primera petició, afegirem el codi:

request.CookieContainer = CC;

I així podrem arreplegar les cookies de tornada, si el que vulguerem és enviarla:
Cookie cook = new Cookie("email", "fercavi666@gmail.com", "/", ".gmail.com");
CC.Add(new Uri("http://www.google.com"),cook);

siguent: email la "clau", "fercavi666@gmail.com", el valor, "/" la ruta i ".gmail.com" el domini.

dimecres, 12 de juny de 2013

XNA: el perquè de tot plegat

Parafrassejant el títol del mestre Monzó, duc uns dies pegant-li voltes a una cosa, la idea de fer un joc. No tinc massa temps, i estic fent massa coses a l'hora, però m'apasiona la idea d'un joc multiplataforma. Mai de la vida havia programat videojocs, la veritat, mai m'havia agradat. Però ara em pica el cuquet. Però bé com a introducció personal ja n'hi ha prou. He estat mirant, i vaig a provar amb XNA. El què més m'ha agradat és que el mateix codi (repetisc, el mateix codi), val per fer fer programes(jocs) en:
-Windows phone
-Windows
-XBOX

Anem a fer una demostració (basada en les tutorials de RB Whitaker):


Instal·lem el VS2010 (podem fer-ho amb la versió express, gratuita), i després del SP1, ens baixem i instal·lem el XNA. Una vegada instal·lat podrem elegir quin tipus de projecte volem:


Com no tenim (jo almenys) una XBOX, ens haurem de conformar amb un Microsoft Game ;)

Veurem que tenim una classe Game1, dins d'un namespace windowsGame2 (que deuriem de canviar en desenvolupaments seriosos). Anem a posar un fons de pantalla, afegim com a variable de classe:
private Texture2D background;
Ara afegirem al projecte, l'arxiu a carregarm el meu cas, el mural que va pintar la meua princesa, Content->Botó dret->Afegir element existent
Tornem al codi,  i busquem l'event LoadContent. En este event és on s'ha de fer la càrrega de les textures de tot el joc. Ahí afegirem la línia
  background = Content.Load<Texture2D>("mural");
és a dir que la variable background, carregarà una textura2d, bassant-se en el objecte mural de la secció Content (contingut). Si ens fixem, davant hi ha una línia que diu
spriteBatch = new SpriteBatch(GraphicsDevice);
la vairaible spriteBatch farà de finestra on dibuixarem tot.
Per últim ens quedarà dibuixar-ho. En l'event Draw, afegim el següent codi:

            spriteBatch.Begin();//comença a dibuixar
            spriteBatch.Draw(background, new Rectangle(0, 0, 800, 480), Color.White);
            spriteBatch.End(); //acaba

la línia central, és la interessant, dibuixa la textura background (l'hem carregada en l'event Load), com a posició inicial el centre de la pantalla, posem blanc, per què algun color s'havia de posar ;), executem i:






 Ara anem a provar si amb el mateix codi podem fer-ho per a windows phone, no vaig a explicar els motius però el XNA actualment només el tinc configurat en el VS 2012, per a la versió 8 de windows phone. En canvi el XNA per a ordinador, el tinc per a la versió VS 2010.
Ara afegirem la textura mural igual que hem fet abans:
i ara copiem i peguem el codi anterior, arranquem, esperem que arranque l'emulador, i veurem com carrega la imatge

dijous, 30 de maig de 2013

MyQuery per a Windows Phone

L'aplicació ja està en marxa!!!!
Treballant en un projecte nou, desenvolupament oficial per a terminals amb windows phone.  En projecte MyQuery: poder executar consultes SQL a qualsevol servidor MySQL, sent necessaris(alguns són obvis) els següents paràmetres:
  • Servidor de base de dades
  • usuari
  • password
  • Consulta SQL
  • base de dades
Pròximament i possible:
  • Xifrat
  • Altres servidors que no siguen MySQL

L'aplicació consistirà posar els paràmetres de connexió, introduïr la consulta (bé siga select, insert, alter..) i es mostrarà el resultat de forma tabular.












Òbviamnet no hi ha drivers de mySQL per a windows phone, ni trobe què per a cap dispositiu mòvil, per tant he havut d'utilitzar un servidor intermediari que farà les connexions i l'aplicació rebrà el resultat. L'aplicació es gratuïta i a veure si es pot traure algo (si pagara el servidor ja em pegaria amb un canto en les dents) mitjançant adds. Estic platejant-me una aplicació que costé (pocs) diners MyQuery+ amb els següents afegits:
  • Sense publicitat
  •  Xifrat
  • el límit de la consulta a 2000 caràcters, ara està en 1024
  • Connexió a altres servidors SQL
  • Algun trigger que t'avise quan es cumplisquen certes condicions (cert camp aplegue a un valor determinat)
  • ...

dilluns, 13 de maig de 2013

Per fi!, tema dominat: mysql asincron en node.js

Escoltant marea (no té res a veure, però així indique preferències musicals ;)), he trobat la solució al problema dels posts anteriors. Resulta que la funció query del paquet és asíncrona, és a dir que no se pot saber quan s'executarà, però serà quan s'acabe la funció que la crida. Aleshores el que hem de fer és no retornar la resposta fins que no s'execute el callback. I així ens evitem el problema, si has estat seguint el post entendràs la consulta i tot:


function fservidor(request, response){
var resXML="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><resposta>";
function frequeston(){
  // El codi 200 vol dir què la petició ha segut correcta, i enviem la resposta en text pla.
   response.writeHead(200, {
         'Content-Type': 'text/plain'
      }); //end writehead
 }//end frequeston

request.on("end", frequeston);
 var client = mysql.createConnection('mysql://'+user + ':'+pass+'@'+server+'/'+database);
 client.query("select * from personatges",function (err,result){
   resXML+="<personatges><personatge><id>" + result[0].id + "</id></personatge></personatges>";
   resXML+="</resposta>";
 response.end(resXML);
  }//callback query
 );//query


}

var servidor = http.createServer(fservidor);
servidor.listen(10000);



Si ens fixem la línia en roig, (la resposta), està fins el callback, per tant ens assegurem que no es retornarà la resposta al client fins que no s'execute el callback. Això és així per què el servidor node.js té un únic fil, (al contrari, com per exemple php, que cada petició és un nou fil), i per cada petició s'execute una vegada fservidor() fins que acaba. Si mysql fora síncrona, i fora una consulta llarga (per exemple), el servidor quedaria colapsat fins que la petició a la base de dades es realitzara i no estaria realitzant cap procés. Així, retorna el control i pot atendre les següent peticions. Recordem node.js és un servidor orientat a events.
La resposta en l'exemple, òbviament no té molt de sentit lògic però si ilustratiu:

<?xml version="1.0" encoding="ISO-8859-1"?>
<resposta><personatges><personatge><id>1</id></personatge>
</personatges></resposta>



dilluns, 6 de maig de 2013

L'estotèric abast de les variables en node.js

Com ja comentava en l'anterior post, ja duc un temps barallant-me amb handlers i demés malea del node.js. Crec que he descobert un altre problema de node.js. L'abast de les variables. Si jo definisc una variable en una funció, les modificacions fetes en la variable en les funcions definides dins no quedaran guardades. Trobe què és molt més fàcil veure-ho amb un exemple, si jo tinc el següent codi paregut als exemples anteriors (recordem la taula de personatges del joc de rol simple):

var resXML="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><resposta>";
   var i=0;
   client.query(action, function getSQL(err,result,fields){
     //console.log(fields);
     if (err){
       console.log("Error: " + err);
     }//if
     resXML = resXML + "<" + fields[0].table + ">";
     for(i=0;i<result.length;i++){
             resXML = resXML+"<"+fields[i].name+">" + i + "<" + fields[i].name + "/>";
     }//for
     resXML = resXML+"<" + fields[0].table + "/>";
     console.log(resXML);
   } //end getSQL
   );//client.query
   resXML =resXML+"</resposta>";
  console.log(resXML);


independentment del significat del codi (estava fent proves, per tant no en té molt), vegem dos línies de console.log, una en roig i l'altra en blau. La principal diferència és què una està dins de la funció que manipula el resultat i l'altra fora. El resultat aparent deuria de ser què, llevat de l'afegit  "</resposta>" de l'última línia, deuria de ser igual. Doncs no, el resultat és este:
Fora:<?xml version="1.0" encoding="ISO-8859-1"?><resposta></resposta>
Dins:<?xml version="1.0" encoding="ISO-8859-1"?><resposta></resposta><personatges><id>0<id/><nom>1<nom/><classe>2<classe/><personatges/>

És a dir, primer acaba la funció i després realitza el "callback", si analitzem el fora/dins. Això és "lògic", tal i com he comentat este matí en l'anterior post. El problema "greu", és que la variable resXML no ha estat modificada, o almenys no quan acaba eixa funció, cosa que fa que el valor de la variable resXML no valga per a res. Aleshores, en la pràctica, les variables de fora, no es poden modificar dins, i el que veuen és una còpia de "només lectura", tipus els paràmetres dels llenguatges de programació tradicional.
Val a dir que no he investigat tant per saber com és la teoria, ja què és possible que en la teoria diga que si que són modificables, però en la pràctica, almenys en funcions asíncrones, no ho són; ja què, quan puga ser actualitzat el seu valor realment, siga massa tard.

Tot això em fa pensar que he estat perdent el temps (bo, allò que el saber no ocupa lloc, però molt de temps), i podria passar-me  a programar servidors en qualsevol altre llenguatge... per molt que el meu vell amic Jaume Cardona n'estiga d'enamorat, del node.js. Amb PHP possiblement hauria acabat totes les proves ja.

Handlers d'errors en node.js quina bogeria ;)

Després de dos dies tornat-me varilla amb els handlers d'error en node.js, al final, quasi de casualitat he descobert que passa. Imaginem que vull connectar a una base de dades:

function doLogin(){
  var client = mysql.createConnection('mysql://'+user + ':'+pass+'@'+server+'/'+database);
  client.connect();
 }//function doLogin


La funció connect pot fallar en cas que els paràmetres siguen incorrectes, no hi haja connexió... si eixe error no és capturat, tanca el programa (tancant el servidor). Primer proví amb try catch, herència d'altres llenguatges no tant moderns ;) i no, no vaig aconseguir capturar l'error. Per tant vaig llegir que la millor cosa que podia fer en javascript (node.js) era afegir  una funció callback (que s'executa en cas d'error, i passada com a paràmetre). La funció ha de ser algo així:

 function errResult(err,result){
  if (err != null) {
         berror = true;
   }
  else{
       berror = false;
  }
 }//function errResult


on en err estarà el missatge d'error i berror serà una variable d'error que podrem examinar si hi ha havut error o no al login. canviarem el codi de doLogin per:

client.connect(errResult);

i tindrem el codi següent per a veure si s'ha produït el login correctament:

doLogin()
if (!berror) {//login OK
    res= "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><resposta>OK</resposta>";
  }
  else{//error login
    res = cadena_error_login_ini + error_missatge +cadena_error_login_fi;
  }

La lògica ens dius que quan cridem a doLogin, esta cridarà a errResult i actualitzarà la variable berror en el cas pertinent. Això pensava jo i res més lluny de la realitat. La cosa és que posara les dades que posara sempre em donava OK. Com ja he dit duc un cap de setmana fent proves i no hi ha habut manera. Al final he decidit fer un log de totes les accions a veure que passava:

 function doLogin(){
  var client = mysql.createConnection('mysql://'+user + ':'+pass+'@'+server+'/'+database);
  console.log("Abans de connect");
  client.connect(errResult);
  console.log("Després de connect");
 }//function doLogin


function errResult(err,result){
  if (err != null) {
     error_missatge=err;
     berror = true;
     console.log("Ha havut un error però s\'haurà capturat?");
   }
  else{
    error_missatge = "";
    berror = false;
  }
  console.log(berror);
 }//function errResult


I en la funció del servidor (hi ha més coses però les estic omitint per no fer més llarg el copy & paste):

doLogin();
  console.log("doLogin");
  if (!berror) {//login OK
    res= "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><resposta>OK</resposta>";
  }
  else{//error login
    res = cadena_error_login_ini + error_missatge +cadena_error_login_fi;
  }

 response.end(res);
console.log("final servidor");





L'eixida de consola deuria de ser:
Abans de connect
Ha havut un error però s'haurà capturat?
 Després de connect
doLogin
final servidor





Però no, resulta ser:

Abans de connect
Després de connect
doLogin
final servidor
Ha havut un error però s'haurà capturat?

Cosa que ens indica que la funció callback de maneig d'error s'execute una vegada ha acabat la funció principal del servidor. Per tant este model no ens val per capturar l'error. Caldrà canviar el model, pròximament posaré la solució al problema ;)

dilluns, 22 d’abril de 2013

Accedit a un webservice des de windows phone

Bé, per fi les meues obligacions m'han deixat un ratet per fer el que volia fer fa molt de temps, una aplicació de windows phone que accedira al webservice qeu vam crear en node.js farà mig any. No vaig a entrar en com s'instal·la el sdk per què és abaixar un downloader  de la web de microsoft i ja està. A més, el sdk és gratuït, et baixa la versió de Visual Studio 2010 Express (gratuïta) i tot.
La idea era, quan s'aprete un botó, connectar-se a un webservice, que ens retornarà un xml, processar-lo i mostrar-lo en un grid ;) Ha segut ben farragós, per què programar per a dispositius mòbils no és com programar en escriptori, però ha estat divertit... ;) Anem per feina. Primer de tot l'aspecte visual, afegirem un botó i un grid:

Ara anem a programar que farà el botó, ja què obtindre un xml remot, no és difícil, però tampoc és tant fàcil com pareix, ja què windows phone no permet les connexions sincrones, i per tant hem de posar un handler per a quan es complete la descàrrega:

 private void button1_Click(object sender, RoutedEventArgs e)
        {
            WebClient wc = new WebClient();
            wc.DownloadStringCompleted += HttpCompleted; //funció que es cridarà quan es connecte l'event
            wc.DownloadStringAsync(new Uri("http://192.168.2.120:1000/"));
        }


 Ara, si no hi ha error, en la funció HttpCompleted realitzarem les accions pertinents. Com necessitarem suport XML, haurem d'afegir al projecte les referencies System.XML.Linq manualment (Project->Add Reference, marquem System.XML.Linq) i així podrem posar using System.XML.Linq al projecte:

 private void HttpCompleted(object sender, DownloadStringCompletedEventArgs e)
        {

            if (e.Error == null)
            {
                  ...
             }
       }

Ara anem a completar el handler amb el procés de l'xml i del grid, que també ha tingut tela... Si no recordeu l'estructura de l'xml, vos recomane visitar els articles anterior, per exemple este fet en delphi:

                int nrows,i = 0;//variables auxiliars
                int ncols = 4; //id,nom,classe, nivell
               
                XDocument xdoc = XDocument.Parse(e.Result, LoadOptions.None);
                XElement xele = xdoc.Elements("xml").First();
                xele = xele.Elements("resposta").First();
              
                xele = xele.Elements("personatges").First();//naveguem per l'xml
                nrows = xele.Elements("personatge").Count(); //obtenim les files



I ara afegirem les columnes, millor dit les definicions de les columnes, per a cada columna haurem d'afegir una definició manualment i per a les files, el mateix. Es pot fer en temps d'edició, però se suposa que no sabem ni quantes files ni quantes columnes (bé, en este cas, si que sabem el nombre de columnes) pot tindre la resposta.
               for (i = 0; i < ncols; i++)
                {
                    ColumnDefinition col = new ColumnDefinition();
                    grid1.ColumnDefinitions.Add(col);
                }


I ara, recorreguem tots els personatges de la resposta  amb un foreach i creem una fila, la fila serà un conjunt de components TextBlock, que caldrà afegir-los al grid, i després posar-li fila i columna amb el mètode estàtic (de classe) SetColumn i setRow:
                i = 0; //comptador de files
                foreach (XElement ele in xele.Elements("personatge")){ //naveguem pels personatges
                    TextBlock id = new TextBlock();
                    TextBlock nom = new TextBlock();
                    TextBlock nivell = new TextBlock();
                    TextBlock classe = new TextBlock();
                    RowDefinition rowDef1 = new RowDefinition();
                  
                    id.Text = ele.Elements("id").First().Value; //obtenim els valors del node actual
                    nom.Text = ele.Elements("nom").First().Value;
                    classe.Text = ele.Elements("classe").First().Value;
                    nivell.Text = ele.Elements("nivell").First().Value;
                    grid1.RowDefinitions.Add(rowDef1); //afegim fila
                    grid1.Children.Add(id); //afegim els TextBlock creats al grid
                    grid1.Children.Add(nom);
                    grid1.Children.Add(nivell);
                    grid1.Children.Add(classe);
                    Grid.SetColumn(id, 0); //Posem Columna
                    Grid.SetColumn(nom, 1);
                    Grid.SetColumn(classe, 2);
                    Grid.SetColumn(nivell, 3);
                    Grid.SetRow(id, i); //posem Fila
                    Grid.SetRow(nom, i);
                    Grid.SetRow(classe, i);
                    Grid.SetRow(nivell, i);
                    i++; //incrementem el comptador de Files

                }


I obtindrem el següent resultat:



A banda de la utilitat que pot tindre per realitzar aplicacions que funcionen en tots els  mòvils (no sempre és viable fer versió web i que esta s'acoble a tots els terminals), també és l'única manera que he trobat de poder accedir a servidors de bases de dades des de dispositius mòbils, ja que, habitualment els sdk no disposen de drivers per connectar directament. Per tant, la única solució (que se m'ha ocorregut, poden haver més), és posar un servidor entre mig que puga accedir-hi. De fet, és l'aplicació que he pensat d'accés a mysql,  a veure si em dona i adquirisc llicència de programador per distribuïr aplicacions ;)

dijous, 11 d’abril de 2013

Kodu game Lab

Aprofitant que com a professor tinc accés a algunes eines de microsoft, m'he trobat aquesta eina. Consisteix en un game maker, extremadament fàcil d'utilitzar. De fet està pensat per a docents que no són programadors/informàtics. Un mes després d'haver fet els tutorials he pogut fer aquest exemple en 10 minuts.  Bàsicament consisteix en posar objectes predefinits (pomes, arbres...) i actors (el bo, el dolent...). Els actors poden realitzar accions bé sobre els objectes o bé sobre els altres actors, les accions seran definides mitjançant els programes, d'una manera molt senzilla com veurem més avant, però en resum seran sempre una serie de condicions (WHEN) i accions a realitzar quan es cumplisquen les condicions (DO).
La idea de l'exemple a construir era la següent: Un món buid, on hi ha l'actor bo i l'actor roïn.  Si l'actor roïn ens pilla perdem el joc, però si no ens pilla abans d'agafar 5 pomes, guanyem. Molt simple i pas a pas, comencem en un món buit, i amb l'eina pinzell de terreny, posem un terreny, si no estariem al buit ;):


Ara afeim amb l'eina actors 3 tipus d'objectes, el protagonista (Kodu, per defecte), les pomes a menjar i una espècie d'ou fregit, que serà l'enemic:


Sense deseleccionar l'eina d'actors, "escriurem" el programa dels actors, amb el botó dret sobre cada actor, i seleccionant l'opcio Program. Les pomes òbviament no tenen comportament ;) Kodu detectarà les polsacions del teclat i actuarà en conseqüència. Si tropessa amb una poma, se la menjarà i pujarà un punt al marcador, si arribem a 5 guanyem:














Ara escriurem sobre l'enemic, en quan veja a Kodu, anirà a acaçar-lo, si l'agarra, es perdem ;):













És realment senzill fer tota classe d'exercicis amb esta eina. Per exemple, seleccionar el resultat d'una operació, l'ordre correcte de les frasses... I amb un parell de vesprades fent els tutorials que et proveïxen, tens formació per fet coses simples

dimecres, 13 de març de 2013

Windows 8 en tres monitors

Aprofitant que l'institut té el pack dreamspark premium ;) puc, com a professor fer un ús educatiu de pràcticament tots els seus recursos. Això em va animar a provar el windows 8 i la interfície metro. Ho havia provat al mòvil (sóc fan de Nokia, i no tenia opció) i m'havia agradat. Tot i que alguns amics se'n fan creus per què sempre he tingut fama de Linuxer ;). Jo ja fa anys que no li faig "ascos" a res, sempre que em permeta fer el que jo vullc (i no siga ilegal ;)). El cas és que la interfície metro en un monitor i per a pantalles tàctils no està mal, però... amb més monitors, els tiles poden quedar partits i fa un efecte horrorós:















Podem observar que els tiles són molt grans, això és per què escala a la resolució de pantalla, i clar 3 1920x3 és una amplària molt gran ;)
Les aplicacions en l'interfície metro també s'obrin a pantalla completa, també es fan molt grans, excessivament gran:




Per sort podem elegir, almenys de moment l'interfície "normal", veurem que ens espera en les properes versions. Metro, està destinat per a usuaris nous (igual els té una interfície que una altra) i per a dispositius tàctils. Pensant-ho bé, per a un que començá, igual és més fàcil... serà questió de provar ;)

divendres, 1 de febrer de 2013

Primer programa en asm

No vaig a escriure un tutorial en asm, ja que trobe que no val la pena... ;) Però anem a veure el primer programa "Hola món" típic als tutorials de programació.
Tal i com contava en un post anterior, anem a gastar Visual Asm (easy code). Seleccionem crear i li diguem crear un nou projecte, com aplicació de consola:

I ara anem a veure com escrivim en pantalla, la forma més fàcil  que he trobat és trovar l'identificador de l'arxiu pantalla (handle), i escriure uns caràcters en eixa pantalla. Per obtindre l'identificador gastarem la funció del sistema GetStdHandle, i per escriure en eixe identificador, WriteFile. Ho escrivim amb els paràmetres corresponents en la secció main, pareguda a la funció main de C:

Main:
 Push - 11D               ;STD_OUTPUT_HANDLE estàndard output, pel dispositiu què preguntem
CALL GetStdHandle       ;en EAX tindrem el handle
Push 0, Addr buff      ; variable on guardem coses, no val per a res en este cas
Push 9, 'Hola món!'    ;9 tamany de la cadena 'hola món!', en caràcters
PUSH EAX                ;el guardem
CALL WriteFile         ;escrivem en la pantalla
Xor Eax, Eax             ;EAX=0 acabem sense error
Ret


la secció data al principi haurà de contindre la nova varible creada:
.Data

hInst    DD        NULL
buff    DD      0

Executem i tenim el resultat:

vegem que el caracter "extrany" ó apareix incorrectament codificada, d'això parlarem en una altra ocasió. No ha segut tant difícil, eh?

Edite

Si estiguerem en C, el codi hauria segut una cosa sembant a:

 int main(){
    int hd;
    char cadena[]='Hola món';
    int buff=0;
    hd=GetStdHandle(11);
   WriteFile(hd,cadena,strlen(cadena),buff);
   return 0;
}

Programació en assemblador

Com em torna a picar el cuquet de programar en assemblador (asm a partir d'ara), i sempre la gent em preguta per què? quina utilitat té... doncs bé, la justificació teòrica (dels llibres) què donen, és què tens un major control de la màquina, pots optimitzar codi... Fent una analogia mecànica, sempre comparen un canvi de marxes manual (asm) i  un automàtic (C++),  no vull ni pensar que seria el VB.NET actual... potser conduir amb la ment.
Anem a posar un exemple, si tinguem este programa en C:


#include <stdio.h>
void main(){
     int i;
     int vector[10];
     for(i=0;i<=9;i++) vector[i]=0;
}

fem una compilació per veure que s'executa realment (gcc -S) i obtenim el següent codi en asm:
        .file   "prova.c"
        .text
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $48, %esp
        movl    $0, -4(%ebp)
        jmp     .L2
.L3:
        movl    -4(%ebp), %eax
        movl    $0, -44(%ebp,%eax,4)
        addl    $1, -4(%ebp)
.L2:
        cmpl    $9, -4(%ebp)
        jle     .L3
        leave
        ret


Si observerm, el codi de la copia del vector (inicialitzar a 0),  es fa entre .L3, i  .L2. Realment podriem fer-ho amb menys instruccions, per exemple:
   lea edi, vector
   mov ecx,9
   xor eax,eax
   repsz stosd


Possiblement no siga un bon exemple per què simplement ens estalviariem una instrucció o dos ;), però per a certes coses, no és "recomanat", si no imprescindible, sobretot la interacció amb els hardware. Realment es fa farragosa amb llenguatges com C, quan és molt senzilla en asm. Encara que la millor cosa és juntar-les les dos. Fer parts no crítiques en llenguatges d'alt nivell, i parts crítiques (que necessiten optimització, d'accés al hardware...) en asm. I després mesclar-ho tot.

Un ús curiós és el shellcode, que s'usa en programes maliciosos, per executar instruccions que no deurien de ser executades.  Es passa el shellcode com a paràmetre i es fa que "d'alguna manera" salte l'execució del programa del fil normal fins al paràmetre. Eixe codi pot obrir un shell, o qualsevol altra cosa que "considerem convenient". Llàstima que vaig pedre el meu PFC, sóc un desastre, però tractava sobre el tema, a veure si em torne a reenganxar ;).