Aug 05 2010

Grafitti Analysis : WIP

J’espère que vous connaissez déjà graffiti Analysis (un super projet d’Evan Roth) qui tente de mémoriser et d’archiver des données de “tag”. La base de données est ouverte et on peut donc charger les tags au format “GML” (graffiti mark up language). Je vais essayer de terminer une appli de lecture de tags et écriture de tag. J’ai déjà réussi à lire de tags, la j’en crée. Il ne me reste plus qu’a tout mettre ensemble pour faire une appli finie. Je balancerai bien sûr toutes les sources.


Jul 21 2010

Turboconnard AGD : Exemple 2 Connard jump

Tag: android,Eclipse,Jeux indépendants,jeux vidéoTurbo Connard @ 14:16

Je continue peinard les tests du framework. Hier j’ai essayé de faire “Connard Jump”. Un peu plus de 100 lignes de code pour un gameplay bien connu des détenteurs de webphones (comme ils disent) :

J’ai ajouté un schtroumpfeur de textures qui charge tout les ressources de R.drawable en texture opengl. Du coup on a plus à se soucier de charger les textures on peut directement faire :

Bitmap b = new Bitmap(R.drawable.machin);
 stage.addChild(b);

Voila donc la source de Connard Jump :

 

 

package com.hello;

import java.util.Vector;

import com.turboconnard.core.Agd;
import com.turboconnard.display.Bitmap;
import com.turboconnard.display.Sprite;
import com.turboconnard.events.AccelerometerEvent;
import com.turboconnard.events.Event;
import com.turboconnard.geom.Point3D;
import com.turboconnard.hardware.Accelerometer;

public class HelloWorld2D extends Agd {
        private static final float MINISPACE = 40;
        private static final double SPACE = 50;
        private Bitmap hero;
        private float vitY;
        private float vitX = 0;
        private float cibleX = 0;
        private Sprite decors;
        private Vector<Sprite> pfCheck;
        private float _y;
        private float _lastY;

        public HelloWorld2D() {
                super();
                Bitmap b = new Bitmap(R.drawable.background);
                b.x = stage.width / 2;
                b.y = stage.height / 2;
                vitY = -10;
               
                hero = new Bitmap(R.drawable.test);
                hero.x = stage.width / 2;
                hero.y = stage.height5;
                decors = new Sprite();
                decors.z = 0;//1;

                hero.z =  0;//-1;
                stage.addChild(b);
                stage.addChild(decors);
                stage.addChild(hero);
               
                Accelerometer.getInstance().addEventListener(AccelerometerEvent.ON_CHANGE, this);
                generateLevel();
        }
        /**
         * create FirstPlatforms
         */

        private void generateLevel() {
                _y = stage.height;
                while (_y > 0) {
                        _y = _y – (float) (Math.random() * SPACE) – MINISPACE;
                        addPlateform(_y);
                }
        }

        private void addPlateform(float pY) {
                _lastY = pY;
                Bitmap pf = new Bitmap(R.drawable.plate);
                pf.y = pY;
                pf.x = (float) Math.random() * stage.width;
                decors.addChild(pf);
        }

        public void update() {
                //gravity
                vitY += 0.3;
                //acceleration x
                cibleX += (vitX – cibleX) / 5;
                //if we go up
                if (vitY < 0) {
                        checkAddPF();          
                } else {
                        //if we go down
                        checkPF();
                        testColision();
                }
                //move x
                hero.x += cibleX;
                //bounce against walls
                if (hero.x > stage.width) {
                        hero.x = stage.width;
                        cibleX *= -1;
                }else if (hero.x < 0) {
                        hero.x = 0;
                        cibleX *= -1;
                }
                //loose !
                if (hero.y > stage.height) {
                        vitY *= -0.5;
                        /*
                        hero.y = stage.height;
                        */

                }
        }
       
        private void checkAddPF() {
                //if hero.y <250 move level
                if (hero.y < 250){
                        _y += vitY;
                        //addPlateform if offset is > MINISPACE
                        if( (_lastY – _y )> MINISPACE ) addPlateform(_y –  (float) (Math.random() * SPACE) );
                        decors.y -= vitY;              
                }else{
                        //if hero.y >250 move hero
                        hero.y += vitY;
                }
        }

        private void checkPF() {
                pfCheck = new Vector<Sprite>();
                for (Sprite b : decors.getDisplayList()) {
                        if ((b.y + decors.y) > hero.y)
                                pfCheck.add(b);
                        if (b.y + decors.y > stage.height)
                                decors.removeChild(b);
                }
                hero.y += vitY;
        }

        private void testColision() {
                for (Sprite b : pfCheck) {
                        if ((b.x50) < hero.x && (b.x + 50) > hero.x && (hero.y+hero.height/2) > (b.y + decors.y) ) {
                                hero.y = (b.y + decors.y -hero.height/2);
                                vitY = -10;
                                return;                        
                        }
                }
        }
        public void event(Event e) {
                if (e.name == AccelerometerEvent.ON_CHANGE) {
                        Point3D p = (Point3D) e.param;
                        vitX = p.x;
                }
        }
}
 

hop la :


Jul 15 2010

Turboconnard AGD : Exemple

Tag: android,jeux vidéo,openglTurbo Connard @ 19:11

Youpi, ça commence à ressembler à quelque chose.
Quand on touche l’écran un cube est placé dans l’espace à des positions aléatoires, le téléphone vibre quand vous le touchez (hmmm, hot, sex…).
Pencher le téléphone influe sur la rotation des cubes. Faut que je sorte les textures (actuellement en dur dans le Cube) et je file le sources.

Exemple de code simple :

package com.helloworldagd;

import android.view.MotionEvent;

import com.turboconnard.core.Agd;
import com.turboconnard.display.Cube;
import com.turboconnard.display.Sprite;
import com.turboconnard.events.AccelerometerEvent;
import com.turboconnard.events.Event;
import com.turboconnard.geom.Point3D;
import com.turboconnard.hardware.Accelerometer;
import com.turboconnard.hardware.Vibrato;

public class HelloWorldAGD extends Agd {

        private Sprite s;
        private float tx;
        private float ty;
        public HelloWorldAGD(){
                super();
                Accelerometer.getInstance().addEventListener(AccelerometerEvent.ON_CHANGE, this);
                tx = ty = 0;
                s = new Sprite();
                s.x = stage.width / 2;
                s.y = stage.height / 2;
                stage.addChild(s);

        }
        public void addCube(){
                Cube c = new Cube((float) (Math.random()*80 + 20));
                c.x = (float) Math.random()*stage.width(stage.width/2);
                c.y = (float) Math.random()*stage.height-(stage.height/2);
                c.z = (float) Math.random()*stage.height-(stage.height/2);
                s.addChild(c);         

                Vibrato.getInstance().vibrate(30);
        }
        public boolean onTouchEvent(MotionEvent e){
                if(e.getAction() == MotionEvent.ACTION_DOWN){
                        addCube();
                }
                return true;
        }
        public void update(){

        }
        public void event(Event e){
                if(e.name == AccelerometerEvent.ON_CHANGE){
                        Point3D p = (Point3D) e.param;
                        tx += (p.x – tx)/5;
                        ty += (p.y – ty)/5;

                        s.rotationX += tx;
                        s.rotationY += ty;
                }
        }
}
 

 

Et voilà ça fait ça :


Jul 09 2010

AGD – En avant pour opengl

Tag: android,Jeux indépendants,jeux vidéo,openglTurbo Connard @ 19:31

Après avoir fait mumuse  avec mon framework turboconnard agd, j’ai quand même remarqué que ça ramait… le développement “Canvas mode” pour le jeu c’est vraiment trop lent.

Je suis donc passé en mode opengl pour dessiner mes jolis sprites. Le problème avec opengl c’est que c’est hyper complexe. Il faut environ douze jours pour comprendre comment tracer un triangle puis deux fois plus de temps pour y appliquer une texture. Je cherche à faire des choses simple… mais c’est déjà l’enfer pour trouver un tutoriel sur “comment appliquer une texture sur un carré” alors lorsqu’il s’agit de trouver “comment faire apparaitre une texture à 100% dans un univers en 3D” c’est la mort…

Le but recherché :

Dessiner des trucs en deux dimensions dans un univers en trois dimensions. Typiquement, ça permet de développer peinard en 2D sans se prendre la tête et de temps en temps claquer un effet 3D pour le “Wow effect”.

Une solution :

En opengl il y a un “mode” qui permet d’aplatir toutes les perspectives et d’ainsi travailler en deux dimensions (glOrthof pour android) et c’est pratique. Seulement si vous voulez une couche de 3D en plus ben vous êtes niqué.

On utilise alors le mode glFrustumf! (à tes souhaits)

glFrustumf c’est la méthode qui permet de définir la perspective de votre scène 3D. Bien comprendre cette méthode vous facilitera la vie pour vous représenter les éléments en 3D calqués sur votre écran 2d.

Cette méthode attend six paramètres : left, right,  bottom,top, near, far. Les quatre premiers définissent le rapport de la fenêtre de vue de la scène. Cette fonction permet de définir le fenêtre de projection de l’univers 3D sur votre écran.

explications :

votre écran à un rapport largeur / hauteur (16/9, 4/3 etc…)  avec un glFrustumf(-1,1,-1,1,near,far); vous aurez une projection de ce type :

Il faut donc “calculer” une projection correcte de type :  glFrustumf(-(width/height),(width/height),-1,1,near,far);
Pour une unité de hauteur il ya (width/height) de largeur :  Pour un 16/9 ça fait bien, 1 de hauteur pour 1.7778 de largeur.

Ok pour le rapport, fastoche. Après ça, ce que je voulais c’était d’avoir une texture à 100% lorsqu’elle est en z = 0.
Il faut d’abord comprendre que par défaut le “point de vue” de la scène est en 0,0,0 dans le repère. Si vous arrivez à afficher un quelconque objet, pour le voir vous devez soit reculer la “caméra”, soit éloigner l’objet. Mais de combien dois-je reculer la caméra pour que mon objet occupe bien sa “taille réelle” ?

La précédente fenêtre qu’on a déterminée se positionne  en fait au paramètre “near” sur l’axe z :

exemple ici : glFrustumf(-(width/height),(width/height),-1,1,7,20);

Tout objet en dehors de la zone “couleur jambon” sur l’axe Z n’apparaitra pas. Maintenant, il faut réussir à placer l’objet bleu à la bonne position sur l’axe Z pour qu’il s’imprime à 100% sur l’écran. Un peu de trigonométrie suffit :

L’objet est un plan d’une unité (1×1), une texture de 64×64 est mappée dessus.

mon écran fait “height” en hauteur pour “1″ unité (rappelez vous le glFrustumf à 1 pour la hauteur).
le rapport de la texture est (64 / height ) pour une unité.

On calcule l’angle de l’origine vers l’objet  :
ang = Math.atan2( ( 64 / height)) , near);
puis avec l’angle on calcul le z.

z =  1/Math.tan(ang);

Du coup si on recule la camera de -z, la texture fera pile poil 64×64 sur votre écran.


Jul 04 2010

Flying Saucer Android release

Tag: android,Eclipse,Jeux indépendants,jeux vidéoTurbo Connard @ 19:39

Je viens de poster dans les downloads de agd une première version de “flying saucer” : le super mini jeu qui se termine en 20 secondes.

J’ai développé ce prototype pour être confronté à de vrais problèmes lors de sa réalisation et ça a porté ces fruits, j’ai dû ajouter plein de trucs relous. Je pense que ce jeu en restera la. Certes, douze ennemis à tuer c’est pas forcément le jeu le plus fun de la terre mais il permet d’appréhender des logiques simple de développement. C’est pourquoi bien sûr, je fournis les sources.

Voilà vous pouvez essayer de compiler ce jeu et de vous amuser pendant au moins une minute !

 

 

 

 


Jun 27 2010

Turboconnard Android Game Developpement

Tag: android,Eclipse,Jeux indépendantsTurbo Connard @ 16:52

Bon, c’est un peu pompeux comme nom mais c’est la seule chose qui me soit venue…

J’ai donc commencé un petit framework pour développer des jeux sur android. Flash ressemble énormément au java dans sa syntaxe mais les logiques de développement sont un peu différentes. J’avoue avoir des automatismes de flasheurs et n’arrive pas trop à concevoir des applications différemment qu’en pensant “Flash”. Le concept d’imbrication de clips, sprites est quand même pas mal. J’ai donc recréé ce système d’imbrication pour ne pas m’emmerder à recalculer à chaque fois les translations et rotations de canvas avant les “draw”. J’ai aussi complètement pompé le système événementiel qui me plait bien… Bref, pour l’instant ça me convient pas mal et je vais surement ajouter des choses à ce framework au fur et à mesure de mes avancées dans le monde magique d’android.

C’est par ici : http://code.google.com/p/turboconnard-agd/

mini proto :