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

2D Java Discussion :

[LibGdx] [isometric map Tmx] collision avec des tuiles


Sujet :

2D Java

  1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur Informatique et Réseaux
    Inscrit en
    Avril 2011
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Informatique et Réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 232
    Points : 182
    Points
    182
    Par défaut [LibGdx] [isometric map Tmx] collision avec des tuiles
    Bonjour,
    depuis un petit moement maintenant je suis coincé avec la détection de collision avec des Tuiles.
    J'uitlise donc un IsometricTiledMapRenderer.

    Pour la detection des tuiles j'utilise la projection de la caméra pour déduire les coordonnées du point:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    private static Vector2 toIsometricGridPoint(float x, float y) {
    		Vector2 point = new Vector2(x, y);
    		point.rotate(45);
    	    return point;
    	}
    Pour déplacer mon personnage, j'utilise:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public static Vector2 screenToMap(Vector2 initialPosition) {
    		Vector3 v3 = GameScreen.getCamera().unproject(new Vector3(initialPosition, 0));
    		return new Vector2(v3.x, v3.y);
    	}
    Et les coordonnées transmises sont bonnes.

    J'ai essayer d'utiliser un camera.project() mais ça ne fonctionne pas.

    En allant un peu plus loin pour la collision avec une tuile qui a la propriété "blocked", il semble que l'angle de rotation n'est pas de 45°.
    Un image en dira plus:
    http://www.developpez.net/forums/att...&thumb=1&stc=1

    la flèche en blanc indique le mouvement de mon personnage.
    Les tuiles encadrées en rouge contiennent la propriété "blocked".
    Le trait bleu est la collision que je détecte.

    Cette collision semble bien être avec un angle de 45° mais ma map semble être avec un angle de 26 degrés. Bizarre tout ça. Je dois louper quelque chose.
    Est-ce un problème avec la création de ma carte?

    Voici le code de la création de la carte dans la méthode show de ma classe GameScreen qui implémente l'interface Screen:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    TmxMapLoader loader = new TmxMapLoader();
    		map = loader.load("maps/test.tmx");
    		renderer = new IsometricTiledMapRenderer(map);
     
    		camera = new OrthographicCamera();
     
    		TiledMapTileLayer collisionLayer = (TiledMapTileLayer) map.getLayers().get("foreground");
    		EntityManager.createPlayer(1 * collisionLayer.getTileWidth()/2, 1 * collisionLayer.getTileHeight()/2, collisionLayer);
    Merci pour votre aide.
    Images attachées Images attachées  

  2. #2
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Lot (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2012
    Messages : 31
    Points : 19
    Points
    19
    Par défaut
    Salut,

    Le problème quand on utilise des librairies c'est qu'on ne pige rien du tout à l’isométrique et sont fonctionnement (dans la théorie comme dans la pratique), alors qu'en plus il n'y à rien de plus facile à faire qu'un moteur isométrique...

    Déjà vire moi ces librairies qui ne servent à rien.

    Allez, je te donne le code, ça seras plus simple.

    côté map tu génère ta grille en fonction d'une taille prédéfinie. Tu peux aussi faire une grille infiniment grande avec un peut plus de réflexion

    for(int height = 0; height < WIDTH; height++)
    for(int width = 0; width < HEIGHT; width++)
    new Cell(width, height);



    Dans le constructeur de ta case (Cell) tu crée un Polygon, qui vas te servir pour l'affichage et le listener.

    int width = LARGEUR DE LA CASE;
    int height = SA HAUTEUR;

    //les deux lignes qui viennent sont extraite d'un de mes codes, les valeurs sont la pour définir la marge je crois... C'est vieux.
    int i1 = (x * width + height * (y % 2)) + height + 11;
    int i2 = y * (height / 2) + 4;

    int pointX[] = new int[4];
    int pointY[] = new int[4];

    pointX[0] = i1;
    pointY[0] = i2;

    pointX[1] = i1 + height;
    pointY[1] = i2 + (height / 2);

    pointX[2] = i1;
    pointY[2] = i2 + height;

    pointX[3] = i1 - height;
    pointY[3] = i2 + (height / 2);

    this.x = i1;
    this.y = i2;

    this.polygon = new Polygon(pointX, pointY, 4);


    Voilà, maintenant tu ajoute chaque case dans un tableau.

    Dans ton graphique tu parcours le tableau de la même façon que tu crée ta grille :

    for(int height = 0; height < WIDTH; height++)
    for(int width = 0; width < HEIGHT; width++)
    cells.get(width, height).paint(Graphics)



    après tu fais ta fonction main, pour dessiner la grille il suffit de faire graphics2D.drawPolygon(this.polygon). Pour dessiner les tiles tu as la position x, y. Pour le reste avec l'ordre des calques je ne t'aiderais pas car il faut réfléchir un minimum pour faire un jeu vidéo.

    après tu te mets un listeners de souris.

    Point point = pointer retourné par le listener;

    for(Cell cell : cells.values)
    if(cell.getPolygon().contains(point) {
    contients le point.
    }


    c'est tout simple ! Tu as tout.

  3. #3
    Membre habitué
    Homme Profil pro
    Ingénieur Informatique et Réseaux
    Inscrit en
    Avril 2011
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Informatique et Réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 232
    Points : 182
    Points
    182
    Par défaut
    Salut à toi et un grand merci.
    Il est vrai que je ne me suis jamais lancé dans le coding d'un moteur isométrique mais en fin de compte c'est assez simple.

    Voici ce que le rendu me donne:
    Nom : IsometricMap.png
Affichages : 857
Taille : 11,8 Ko

    Petite précision par rapport à ton code du constructeur de la classe Cell:
    tu ne fais pas apparaître la différence entre width le nombre de pixel et donc la position des points et width le numéro de la cellule.
    C'est peut-être voulu mais pour d'autres développeurs je la redonne (par contre moi je pars du centre de la cellule pour calculer les points du polygone) :
    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
     
    public class Cell {
    	public static final int WIDTH = 64;
    	public static final int HEIGHT = 32;
     
    	public Polygon polygon;
     
    	public int x;
    	public int y;
    	public int centerX;
    	public int centerY;
     
    	public Cell(int nbCellWidth, int nbCellHeight) {
    //		int centerX = (x * WIDTH + HEIGHT * (y % 2)) + HEIGHT + 11;
    //		int centerY = y * (HEIGHT / 2) + 4;
     
    		x = nbCellWidth;
    		y = nbCellHeight;
     
    		centerX = nbCellWidth * WIDTH + WIDTH / 2 - (nbCellHeight % 2) * WIDTH / 2;
    		centerY = nbCellHeight * HEIGHT / 2 + HEIGHT / 2;
     
    		float[] point = new float[8];
     
    		point[0] = centerX;
    		point[1] = centerY - HEIGHT / 2;
     
    		point[2] = centerX + WIDTH / 2;
    		point[3] = centerY;
     
    		point[4] = centerX;
    		point[5] = centerY + HEIGHT / 2;
     
    		point[6] = centerX - WIDTH / 2;
    		point[7] = centerY;
     
    		this.polygon = new Polygon(point);
    	}
    }
    Je vais approfondir dans cette voie et encore merci cette grande aide.

  4. #4
    Membre habitué
    Homme Profil pro
    Ingénieur Informatique et Réseaux
    Inscrit en
    Avril 2011
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Informatique et Réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 232
    Points : 182
    Points
    182
    Par défaut
    Bonsoir à tous,
    J'ai pu un peu avancer sur le moteur isométrique mais là je bloque car je n'arrive pas comprendre le principe des calques et de la hauteur des tuiles.
    Bien sûr il y a aussi l'ordre du rendu à gérer où j'ai aussi du mal.

    Voici là ou j'en suis:
    j'ai une liste de cellule et chaque cellule à 4 sprites (1 par calque)
    Une cellule a une hauteur que j'ajoute au centerY.
    Elle a aussi une méthode draw(int layer) pour dessiner la texture du layer

    Dans la méthode draw de mon écran je dessine calque par calque. J'ai intercalé mon personnage entre 2 calques:
    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
     
    		for (int nbTileHeight = Map.NB_TILE_AXE_Y - 1; nbTileHeight >= 0; nbTileHeight--) {
    			for (int nbTileWidth = Map.NB_TILE_AXE_X - 1; nbTileWidth >= 0; nbTileWidth--) {
    				Tile tile = Map.getTile(nbTileWidth, nbTileHeight);
    				tile.draw(spriteBatch, 0);
    			}
    		}
     
    		EntityManager.act(delta);
    		EntityManager.draw(spriteBatch);
     
    		for (int nbTileHeight = Map.NB_TILE_AXE_Y - 1; nbTileHeight >= 0; nbTileHeight--) {
    			for (int nbTileWidth = Map.NB_TILE_AXE_X - 1; nbTileWidth >= 0; nbTileWidth--) {
    				Tile tile = Map.getTile(nbTileWidth, nbTileHeight);
    				tile.draw(spriteBatch, 1);
    			}
    		}
     
    		for (int nbTileHeight = Map.NB_TILE_AXE_Y - 1; nbTileHeight >= 0; nbTileHeight--) {
    			for (int nbTileWidth = Map.NB_TILE_AXE_X - 1; nbTileWidth >= 0; nbTileWidth--) {
    				Tile tile = Map.getTile(nbTileWidth, nbTileHeight);
    				tile.draw(spriteBatch, 2);
    			}
    		}
     
    		for (int nbTileHeight = Map.NB_TILE_AXE_Y - 1; nbTileHeight >= 0; nbTileHeight--) {
    			for (int nbTileWidth = Map.NB_TILE_AXE_X - 1; nbTileWidth >= 0; nbTileWidth--) {
    				Tile tile = Map.getTile(nbTileWidth, nbTileHeight);
    				tile.draw(spriteBatch, 3);
    			}
    		}
    Ce qui me donne avec des arbres dans le 2ème calque:
    Nom : GameTrees.png
Affichages : 831
Taille : 12,3 Ko

    Bien sur c'est assez rudimentaire et sans intelligence (pas de gestion d'ordre dynamique pour l'affichage) car j'essaye de comprendre les principes de base.

    Je n'arrive pas à comprendre comment gérer la hauteur d'une cellule et le calque:
    Quel est la différence?
    Faut-il gérer les 2?
    Comment afficher des textures qui dépassent la largeur et la hauteur de ma cellule?
    Comment faire des "marches" avec ces 2 critères pour que personnage les "montent" sans y avoir de trou dessous:
    Nom : GameSteps.png
Affichages : 912
Taille : 13,5 Ko

    Il y a quelques trucs qui m'échappent dans les principes isométriques que j'arrive pas à trouver sur les innombrables sites qui en parlent ou dans les codes sources de différents jeux.
    Est-ce que tu pourrais me donner un petit coup de pouce stp?

    Merci

  5. #5
    Membre habitué
    Homme Profil pro
    Ingénieur Informatique et Réseaux
    Inscrit en
    Avril 2011
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Informatique et Réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 232
    Points : 182
    Points
    182
    Par défaut
    Bonjour,
    J'ai réussi à comprendre comment afficher mes éléments afin qu'ils se positionnent comme il faut (devant ou derrière):
    Pour chaque tuile que je dessine, je dessine à la suite les 4 calques puis le ou les entités (joueurs, ennemis, objet, ...) qui sont dessus.

    Par contre je n'arrive toujours pas à comprendre le fonctionnement avec des tuiles de différentes hauteurs.

    Merci.

Discussions similaires

  1. [XNA] Problème de collision avec des tiles
    Par Ryokath dans le forum C#
    Réponses: 0
    Dernier message: 10/03/2014, 14h21
  2. Collision avec des droites
    Par Pantoled dans le forum ActionScript 1 & ActionScript 2
    Réponses: 0
    Dernier message: 02/03/2009, 19h43
  3. [Newton] Probleme de collision avec la map
    Par drcd dans le forum Newton
    Réponses: 3
    Dernier message: 09/04/2008, 22h39
  4. Réponses: 2
    Dernier message: 02/02/2008, 19h04
  5. gestion des collisions avec sdl
    Par kirtap1969 dans le forum SDL
    Réponses: 3
    Dernier message: 18/10/2007, 21h16

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