IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants graphiques Android Discussion :

Création d'une carte à base de tuiles


Sujet :

Composants graphiques Android

  1. #1
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut Création d'une carte à base de tuiles
    Bonjour à tous et à toutes(il y en a peu, mais ça existe )

    Je suis me suis mis récemment au Java et à Android (j'étais sur C# avant), et j'ai pour but de réussir à coder proprement une application affichant une carte (perso) faite de tuiles(256x256).
    En C# je faisais ça avec un Panel et des PictureBox (je sais, c'est pas bien), mais cette fois ci j'aimerai bien directement dessiner dans un Canva... (et si j'y arrive, je transpose le tout su la version C#, ça lui fera du bien)

    J'ai stocké les tuiles dans le dossier drawable, et leur nom est de la forme suivante :
    • x0y0z0, x0z1y0, ..., xNyNzU

    N est un multiple de 256 (0 = 0, 1 = 256, ..., N = N*256) et U est le niveau de zoom (0, 1, etc...)
    Pour ce qui est de la l'algo, j'imagine qui faudrait créer une collection de Bitmap, initialiser la capacité de la collection avec le nombre maximum de tuiles qui peut être affiché à l'écran :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int nbTuilesX = (int)Math.floor((double)largeurEcran / 256) + 2;
    int nbTuilesY = (int)Math.floor((double)hauteurEcran / 256) + 2;
    int nbTuilesTotal = nbTuilesX * nbTuilesY ;
    Cette collection serait une sorte de SparseArray avec deux clés (abscisse, ordonnée) et pourrait à la volée ajouter et enlever des éléments...
    Lors du déplacement de la carte, il faudrait vérifier que la collection contienne les tuiles appropriées et soit les afficher, soit les charger :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    // On prend les coordonnées des coins haut-gauche et bas-droite de l'écran par rapport à l'origine de la carte
    int coinHautGaucheX = origineEcranX;
    int coinHautGaucheY = origineEcranY;
    int coinBasDroiteX = origineEcranX + largeurEcran;
    int coinBasDroiteY = origineEcranY + hauteurEcran;
     
    /* On calcul les origines(en multiples de 256) de la tuile la plus en haut à gauche
    et la tuile la plus en bas à droite qui doivent être affichées */
    int originePremiereTuileX = (int)Math.floor((double)coinHautGaucheX / 256);
    int originePremiereTuileY = (int)Math.floor((double)coinHautGaucheY / 256);	
    int origineDerniereTuileX = (int)Math.floor((double)coinBasDroiteX / 256);
    int origineDerniereTuileY = (int)Math.floor((double)coinBasDroiteY / 256);
     
    // On trouve les origines de toutes les tuiles à afficher(en multiples de 256)
    for(int x = originePremiereTuileX; x <= origineDerniereTuileX; x++) {
    	for(int y = originePremiereTuileY; y <= origineDerniereTuileY; y++) {
    		// Actions sur la tuile(x,y) dont la position est (x*256, y*256)
    		if(/* Test si la tuile(x,y) existe dans la collection */
    			// Afficher la tuile(x,y)
    		else
    			// Charger nouvelle tuile(x,y)
    	}	
    }
    A partir d'ici je suis un peu perdu...
    Si vous avez la moindre idée ou le moindre conseil, je suis preneur

    J'aimerai vraiment aboutir à un code optimiser pour que la "glisse" soit la plus confortable possible(plus de fps et moins de ms quoi...) ^^

    Des idées ?

  2. #2
    Rédacteur
    Avatar de Viish
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2009
    Messages
    427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 427
    Par défaut
    J'ai regardé vite fait ton code et tes explications et voici ce que je te propose (si j'ai bien compris) :

    Tu crées une HashTable qui contiendra tes tuiles, indexées par leur nom en xNyNzU. Comme ça tu te facilites la condition de ton if et tu te facilites sa récupération.
    Ensuite pour la charger, ben tu crées ton nouveau Bitmap a partir de ton drawable et tu l'insères dans la HashTable.

    En espérant que ça t'aide.

  3. #3
    Rédacteur
    Avatar de Viish
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2009
    Messages
    427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 427
    Par défaut
    Oh je viens de me rendre compte, j'ai oublié de te dire que tu devrais mettre tes images dans le dossiers Assets plutôt que Drawable, ça te permettra de les loader plus facilement (et surtout à partir du nom du fichier).

  4. #4
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut Arf...
    Je m'étais basé sur l'article suivant :Astuces #5 : Stop aux HashMaps! (très bon blog sur Android en passant). Mais bon, String étant un objet...

    En tout cas, merci pour l'info, je vais retourner à mes tests

    Ps : Merci pour l'astuce des Assets (je vais faire mes petites recherches là dessus aussi)

  5. #5
    Rédacteur
    Avatar de Viish
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2009
    Messages
    427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 427
    Par défaut
    Ou alors tu peux essayer de développer 2 fonctions, une permettant d'associer a une de tes tuiles xNyNzU un unique entier pour utiliser ensuite un SparseArray, et l'autre pour faire le chemin inverse (si tu en as besoin).

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 67
    Par défaut
    Bonjour DamiB,

    Bien que peu en mesure de t'aider, ton sujet m'intéresse ...

    Pourquoi des tuiles ?
    N'est-il pas possible d'avoir une image bitmap qui déborde (largement voire très largement) de l'écran et de n'afficher que la partie centrée sur une position qui nous intéresse ?
    Il faut régler bien sûr le pb de la calibration ....

  7. #7
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Pour avoir un affichage plus fluide, il est bon d'anticiper le chargement des tuiles en faisant en sorte qu'il y ait autour de l'affichage une marge de tuiles non visibles et lorsque tu te décentres suffisament tu charges les tuiles du pourtour pour régénérer la marge.

  8. #8
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut Merci + Question
    Bonjour macRiaz ^^

    Ta solution est envisageable pour mes deux premiers niveaux de zoom qui ont des résolutions de 768x512 et 1536x1024 mais j'arrive vite à des résolutions importantes (24576x16384) ce qui aboutirait à un OutOfMemoryException sur Android...

    Donc autant utiliser (et charger en mémoire) des petits bouts de carte, juste ce qu'il faut pour afficher une partie de cette dernière à l'écran.

    C'est la même astuce qu'ils utilisent dans Google Map et Google Earth

    Bonjour Graffito ^^²

    J'y ai pensé, mais je vais devoir faire des tests, pour trouver le juste milieu vu que plus de Bitmap en mémoire = moins de mémoire pour le reste des fonctionnalités...

    Mes petits tests se poursuivent, ça charge bien, et affiche bien les Bitmaps (qui sont restés dans drawable pour le moment, je vais les mettre dans assets un peu plus tard je pense)
    Maintenant se pose la question de savoir comment faire pour -lors du MotionEvent.ACTION_MOVE- pour enlever les tuiles hors du champ et d'insérer les tuiles qui viennent de rentrer dans le champs...
    Pour l'instant avec le code ci-dessous, on ne parcourt que les tuiles à afficher :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // On trouve les origines de toutes les tuiles à afficher(en multiples de 256)
    for(int x = originePremiereTuileX; x <= origineDerniereTuileX; x++) {
    	for(int y = originePremiereTuileY; y <= origineDerniereTuileY; y++) {
    		// Actions sur la tuile(x,y) dont la position est (x*256, y*256)
    		if(/* Test si la tuile(x,y) existe dans la collection */
    			// Afficher la tuile(x,y)
    		else
    			// Charger nouvelle tuile(x,y)
    	}	
    }
    Hors, il faut aussi enlever les tuiles qui ne doivent plus être afficher du HashMap, avec un code qui devrait ressembler à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if((Tuile.X < originePremiereTuileX && Tuile.X > origineDerniereTuileX) &&
    (Tuile.Y < originePremiereTuileY && Tuile.Y > origineDerniereTuileY)) {
    	// la tuile est hors champs : on enlève 
    }
    else { /* La tuile est toujours dans le champs : on la garde */ }
    // Il y a aussi le niveau de zoom à prendre en compte, mais il suffi de vider complètement le HashMap lors d'un changement de zoom
    Le problème dans tout ça c'est que les données d'abscisse et d'ordonnée sont stockées dans un String donc impossible de faire une recherche individuelle sur les X ou les Y...

    Me revoilà perdu encore une fois

    Ps : Des idées ?

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 67
    Par défaut
    Bonjour DamiB,

    Je ne suis pas encore sur ce sujet, mais je pense que je vais me laisser tenter et je suis tes progrès du coin de l'oeil !
    Les cartes que je veux utiliser sont des cartes aéronautique. Par exemple, la France IGN 1/500.000 fait 5200x5200 px et près de 15 Mo .... J'aurais plein de questions sur les dalles, mais ce n'est pas l'endroit ...

    Revenons à Android, pourquoi ne pas stoker les dalles dans des champs BLOB d'une base SQLITE qui, une fois qu'on a compris l'essentiel fait très bon ménage avec ANDROID. L'intérêt, si cela est possible, est que la sélection des dalles devient un jeu d'enfant ...

  10. #10
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut
    Coucou macRiaz

    C'est vrai, que stocker les tuiles dans sqLite pourrait être sympa, mais ça ferait un nombre impressionnant d'enregistrements, mais je pense que c'est possible vu que j'arrive à en faire tenir quelques milliers la base de données sqlce de Windows Ce (si Windows y arrive, Android devrait pas s'en tirer si mal je pense)

    Mais pour l'instant, mon but c'est de réussir à faire un "tile engine" optimisé... (pour ensuite porter la logique sur WinCe en passant)

    Pour le moment, je suis un peu bloqué sur l'application de la logique (vu que je suis tout nouveau sur Android et Java). J'ai un mal fou à bien concevoir certaines des étapes :
    • Détection du nombre de tuiles max qui peuvent être affichées (ça c'est bon)
    • Initialisation d'une collection de tuile avec le nombre de tuiles max en capacité (là, j'ai du mal à savoir comment faire)
    • Détection des tuiles à afficher (ça aussi c'est bon, je trouve les coordonnées de la première et de la dernière et je fait deux foucles "for" pour trouver l'ensemble)
    • Détection des tuiles dans la collection à supprimer ou à conserver (je vois à peu près comment faire, mais pas vraiment où le placer)
    • Création des nouvelles tuiles dans la collection
    • Afficher les tuiles (enfin :°)


    Je suis un peu perdu dans l'ordre à suivre, et je suis sur qu'on peut faire plusieurs de ces opérations en même temps.

    Pour l'instant j'essaye de faire tout ça avec une classe Tile (Bitmap Image, int X, int Y) et un ArrayList<Tile>... mais je suis un peu perdu avec la classe Iterator...


    Mais je garde espoir ^^

  11. #11
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    MacRiaz : Les cartes que je veux utiliser sont des cartes aéronautique.
    A ma connaissance, pratiquement toutes les cartes aéronautiques étant des scan, on est obligé de les refaire pour avoir du vectorisé. Par exemple les routes, les waypoints et les navaids peuvent être récupérés dans les AIP.
    Ps: Si tu ouvres une discussion sur ce sujet, envoie-moi un message pour indiquer le forum.

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 67
    Par défaut
    Oui Graffito ...

    Mais j'utilise un excellent logiciel qui tourne sous W CE (NAVI) et qui utilise ces cartes bitmap. Avoir à l'écran la même carte que celle qu'on a sur les genoux est extrêmement confortable. J'utilise l'IGN 1/500000 (ainsi que la CARTABOSSY) et j'ai récupéré d'excellentes cartes VFR italiennes (en PDF) sur le site du SIA italien.

    Ca marche très bien, mais je ne connais pas la logique interne du programme ...

  13. #13
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Apparament, NAVI est un fond carte bitmap IGN + info aéro vectorisées et CARTABOSSY est un modèle de terrain numérisé + info aéro vectorisées.

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 67
    Par défaut
    Oui Graffito, c'est bien cela ...

    La contrainte (qui n'en n'est pas une pour moi) est que l'orientation de la carte est toujours Nord vers le haut.

    Le top, c'est que les informations numériques calculées qui viennent au dessus du bitmap (aérodromes, points de report, zones, etc) peut ne pas être visibles, car se superposant au fond de carte ils alourdissent le visuel, mais elles restent actives. Si on clique sur une zone ou un terrain, les infos afférentes sont présentées.

    Le fond de carte est l'IGN ou n'importe quelle autre que l'utilisateur sait élaborer et calibrer (j'ai cité le cas des cartes italiennes).

    NAVI est une très belle application, très fonctionnelle.

  15. #15
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut Orientation + Détection du touché
    Pour ce qui est de l'orientation, il me semble que pour faire tourner la carte il faut utiliser des matrices de transformation ([ame="http://en.wikipedia.org/wiki/Transformation_matrix"]matrices de transformation[/ame]) (il me semble que c'est bien gérer par DirectX et OpenGL) mais ayant déjà du mal avec un affichage normal, je ne compte pas m'y pencher d'ici un certain temps ^^

    En passant, voici un petit bout de code pour la détection du touché :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Display ecran = getWindowManager().getDefaultDisplay();
    int largeurEcran = ecran.getWidth();
    int hauteurEcran = ecran.getHeight();
    // Origine de l'écran par rapport à l'origine de la carte
    float origineEcranX = 0;
    float origineEcranY = 0;
    // Vecteur qui sauvegarde la position de la "touche" de l'écran
    float vecteurPositionToucheX = 0;
    float vecteurPositionToucheY = 0;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public boolean onTouchEvent(MotionEvent event) {
    	float positionToucheX = event.getX(); // Rien de bien compliqué ^^
    	float positionToucheY = event.getY();
     
    	switch(event.getAction()) {
    		case MotionEvent.ACTION_DOWN: // Initialisation du vecteur
    			vecteurPositionToucheX = origineEcranX + positionToucheX;
    			vecteurPositionToucheY = origineEcranY + positionToucheY;
    			break;
    		case MotionEvent.ACTION_MOVE: // Modifications de l'origine de la carte en fonction du vecteur et de la position de la "touche"
    			float nouvelleOrigineEcranX = vecteurPositionToucheX - positionToucheX;
    			float nouvelleOrigineEcranY = vecteurPositionToucheY - positionToucheY;
    			if(nouvelleOrigineEcranX > 0 && (nouvelleOrigineEcranX + largeurEcran) < tailleCarteX) // Permet de ne pas scroller en dehors de la carte
    				origineEcranX = nouvelleOrigineEcranX;
    			if(nouvelleOrigineEcranY > 0 && (nouvelleOrigineEcranY + hauteurEcran) < tailleCarteY)
    				origineEcranY = nouvelleOrigineEcranY;
    			break;
    	}
    }

  16. #16
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut Ca fonctionne, mais ça lag un peu... quand même...
    Rebonjour à tous,

    je viens de terminer un premier jet pour la carte, ça fonctionne, mais ça lag un peu (certainement due au trois boucles imbriquées). J'aimerais votre avis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    	float positionEcranX  = event.getX();
    	float positionEcranY = event.getY();
     
    	switch(event.getAction()) {
    		case MotionEvent.ACTION_DOWN:
    			vecteurPositionEcranX = origineEcranX + positionEcranX;
    			vecteurPositionEcranY = origineEcranY + positionEcranY;
    			break;
    		case MotionEvent.ACTION_MOVE:
    			float nouvelleOrigineEcranX = vecteurPositionEcranX - positionEcranX;
    			float nouvelleOrigineEcranY = vecteurPositionEcranY - positionEcranY;
     
    			if(nouvelleOrigineEcranX > 0 && (nouvelleOrigineEcranX + largeurEcran) < 1536) // Largeur de la carte zoom n°1
    				origineEcranX = nouvelleOrigineEcranX;
    			if(nouvelleOrigineEcranY > 0 && (nouvelleOrigineEcranY + hauteurEcran) < 1024) // Hauteur de la carte zoom 1
    				origineEcranY = nouvelleOrigineEcranY;
     
    			initialisationTuiles();
    			break;
        }
    	return true;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    public void initialisationTuiles() {
    	int coinHautGaucheX = (int)origineEcranX;
    	int coinHautGaucheY = (int)origineEcranY;
    	int coinBasDroiteX = (int)origineEcranX + largeurEcran;
    	int coinBasDroiteY = (int)origineEcranY + hauteurEcran;
     
    	int originePremiereTuileX = (int)Math.floor((double)coinHautGaucheX / 256);
    	int originePremiereTuileY = (int)Math.floor((double)coinHautGaucheY / 256);	
    	int origineDerniereTuileX = (int)Math.floor((double)coinBasDroiteX / 256);
    	int origineDerniereTuileY = (int)Math.floor((double)coinBasDroiteY / 256);
     
    	Iterator<Tile> TuilesIter;			
    	for(int x = originePremiereTuileX; x <= origineDerniereTuileX; x++) { // Première boucle pour les X
    		for(int y = originePremiereTuileY; y <= origineDerniereTuileY; y++) { // Deuxième boucle pour les Y
    			boolean tuileExtiste = false;
    			if(!Tuiles.isEmpty()) {
    				TuilesIter = Tuiles.iterator();
    				while (TuilesIter.hasNext()){ // Troisième boucle pour les Tuiles T_T
    					Tile Tuile = TuilesIter.next();
    					int X = Tuile.X();
    					int Y = Tuile.Y();
    					if((X < originePremiereTuileX || X > origineDerniereTuileX) || (Y < originePremiereTuileY || Y > origineDerniereTuileY)) { // Hors champ : on vire
    						TuilesIter.remove();
    					}
    					else if (X == x && Y == y) { // Dans le champ : on affiche
    						Bitmap Image = Tuile.Image();
    						surface.drawBitmap(Image, (float)(X*256) - origineEcranX, (float)(Y*256) - origineEcranY, null);
    						tuileExtiste = true; // Puis on dit qu'elle existe pour pas recréer la même tuile plus bas...
    					}
    				}
    			}
    			if (!tuileExtiste) { // Si finalement la tuile n'existe pas, on la créer et affiche
    				String Nom = "x" + x + "y" + y + "z" + niveauZoom;
    				int Id = trouverDrawableId(Nom);
    				Bitmap Image = ((BitmapDrawable)Main.this.getResources().getDrawable(Id)).getBitmap();
    				Tile Tuile = new Tile(Image, x, y);						
    				Tuiles.add(Tuile);
    				surface.drawBitmap(Image, (float)(x*256) - origineEcranX, (float)(y*256) - origineEcranY, null);
    			}
    		}
    	}
    	view.invalidate(); // Puis on actualise...
    }
    Ca fait beaucoup de boucles imbriquées quand même... vous avez des idées ? peut être faire une partie des calculs dans un autre Thread...

  17. #17
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Bonjour,

    Tu pourrais séparer les traitement InitialisationTuiles du ActionMove en empilant les coordonnées les ActionMove et en les dépilant dans un timer.

    L'astuce est que tu traites seulement le dernier élément de la pile et que tu ignores les autres. Ainsi, tu "sautes" des actionmove très rapprochés.

    Dans l'idéal, le réglage de l'intervalle du timer doit être correspondre à peu prés au temps d'affichage.

    PS : Comme on peut compliquer un peu pour fluidifier le mouvement de carte, j'ai gardé la notion de pile, bien que dans le traitement proposé un seul élément suffise.

  18. #18
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut ou face :°)
    Je n'ai jamais utilisé de pile avant, c'est peu être un bon moyen de m'initier aux piles... remarques, c'est cumulable avec l'exportation des calculs sur un autre thread (ça pourrait augmenter la réactivité..)

    Ps : viens de modifier un peu le code, pour remplacer les coordonnées récupérées dans onTouchEvent par des int au lieu des float, j'ai remarqué une amélioration de la réactivité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    int origineEcranX = 0;
    int origineEcranY = 0;
    int vecteurPositionEcranX = 0;
    int vecteurPositionEcranY = 0;
     
    /*[...]*/
     
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    	int positionEcranX  = (int)event.getX();
    	int positionEcranY = (int)event.getY();
     
    	/*[...]*/
     
        	case MotionEvent.ACTION_MOVE:
        		int nouvelleOrigineEcranX = vecteurPositionEcranX - positionEcranX;
        		int nouvelleOrigineEcranY = vecteurPositionEcranY - positionEcranY;
     
    	/*[...]*/
     
    }

  19. #19
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut petite question toute bête...
    C'était juste pour savoir si vous avez des idées sur comment afficher des boutons sur la Carte, j'entends par bouton une image cliquable style un bouton plus et un bouton moins sur les coins bas-gauche et bas-droite
    J'ai réussi à ajouter des éléments au dessus de la Carte (MySurface) en utilisant la méthode addContentView qui ajoute une vue au FrameLayout parent de l'activité, voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    public class Main extends Activity {
     
    	MySurface view;
    	TextView  textview;
    	Button    button;
    	/*[...]*/
     
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState); 
     
            view = new MySurface(this); // Initialisation de la Carte
     
    		// Initialisation du TextView + quelques paramètres
            textview = new TextView(this);
            textview.setText(R.string.app_name);
            textview.setPadding(10, 10, 10, 10);
            textview.setTextColor(Color.WHITE);
            textview.setBackgroundColor(Color.argb(99, 00, 00, 00));
     
    		// Initialisation du Button + listener pour zoomer
            button = new Button(this);
            button.setText("+");
            button.setOnClickListener(new OnClickListener() {			
    			@Override
    			public void onClick(View v) {
    				view.niveauZoom++;
    				view.initialiserDimensionsCarte(); // Initialise deux int avec les dimensions de la carte suivant niveauZoom
    				/* Ajouter quelques méthodes dans la classe de la Carte :
    				- conserver la position sur la Carte en zoomant
    				- etc...(pour faire plus Class quoi :°)*/
    				view.Tuiles.clear();
    				view.initialisationTuiles();
    			}
    		});
     
            FrameLayout.LayoutParams params; // Création des paramètres pour addContentView
     
    		// Instenciation : width, height
            params = new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
            addContentView(view, params); // On ajoute au FrameLayout qui contient l'activité (du moins il me semble que c'est ça)
     
    		// Instenciation : width, height, gravity
            params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
            params.setMargins(0, 0, 0, 10); // Une petite marge en bas
            addContentView(textview, params);
     
            params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM);
            addContentView(button, params);
        }
     
    	/*[...]*/
    }
    Voire aussi des "boutons" sur la Carte style points gps cliquables pour lancer d'autres activités...
    Pour les boutons sur la carte par contre, je cherche encore... des idées ?

    Ps : j'ai cherché pour les Assets (et j'ai trouvé :°), voici le petit bout de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    AssetManager Asset;
     
    /*[...]*/
     
    if (!tuileExtiste) {
    	Bitmap Image;
    	Asset = getAssets();
    	InputStream inputStream = null;
    	try {
    		inputStream = Asset.open("zooms/zoom" + niveauZoom + "/" + x+ "." + y + ".jpg");
    		Image = BitmapFactory.decodeStream(inputStream);
    	} catch (IOException e) {
    		Image = ((BitmapDrawable)Main.this.getResources().getDrawable(R.drawable.tuilevide)).getBitmap();
    	}
    	Tile Tuile = new Tile(Image, x, y);
    	Tuiles.add(Tuile);
    	surface.drawBitmap(Image, (float)(x*256) - origineEcranX, (float)(y*256) - origineEcranY, null);
    }
    Pour ce qui est de la réactivité, sur l'émulateur, il semble que ce soit un poil (mais un tout petit poil) plus rapide. Malheureusement ma machine Android frezze lors du boot donc j'ai pas pu tester ça en live (en passant : c'est bizarre car le pilote ADB se lance bien, et la machine est bien reconnue par Eclipse...)

  20. #20
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut Problème Assets : INSTALL_FAILED_INSUFFICIENT_STORAGE
    Bonjour à tous, me revoici avec un problème de taille ^^

    Apparemment, je stocke trop d'images dans le dossier assets... voici la hiérarchie du dossier :

    • assets
      • zooms
        • zoom0
          • 6 images (117Ko)
        • zoom1
          • 24 images (367Ko)
        • zoom2
          • 44 images (903Ko)
        • zoom3
          • 136 images (2.01Mo)
        • zoom4
          • 520 images (6.78Mo)
        • zoom5
          • 1621 images (16.2Mo)


    Soit 26.38Mo de tuiles au total

    Mais au moment de lancer l'application sur l'émulateur (1.5), je me retrouves avec ça dans la Console :

    Installation error: INSTALL_FAILED_INSUFFICIENT_STORAGE

    et ça dans le LogCat :

    ERROR/PackageManager(563): Couldn't copy package file to temp file.

    Le pire étant que je prévoyais de mettre des logos et des icones dans le dossier assets (qui devait être téléchargés depuis le web et stockés pour être précis...)

    Ps : Je suis ouvert à toute critique et/ou suggestion ^^

Discussions similaires

  1. Réponses: 15
    Dernier message: 28/05/2012, 21h11
  2. Réponses: 3
    Dernier message: 22/05/2007, 12h05
  3. création d'une carte au format jpg
    Par TocTocKiéLà? dans le forum C++
    Réponses: 2
    Dernier message: 13/02/2007, 18h28
  4. [SQL] Création d'une nouvelle base
    Par balabonov dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 27/09/2006, 16h14
  5. création d'une carte avec navigation du type mappy
    Par BernardT dans le forum Interfaces Graphiques en Java
    Réponses: 3
    Dernier message: 30/10/2005, 02h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo