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

Développement 2D, 3D et Jeux Discussion :

Comment savoir si le personnage est sur un bloc ou non?


Sujet :

Développement 2D, 3D et Jeux

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 11
    Points : 7
    Points
    7
    Par défaut Comment savoir si le personnage est sur un bloc ou non?
    Bonjour tout le monde,
    Malgré des recherches, je n'arrive pas à comprendre ceci, par exemple dans un mario en 2D, comment savoir si l'utilisateur a sauté sur un bloc, et surtout lui dire qu'il reste dessus.
    Je pensais faire un fichier xml contenant l'emplacement de tous les blocs composant le niveaux mais même avec cette solution j'ai du mal à comprendre comment faire .
    Donc je viens demander votre aide s'il vous plait .
    Je code en c++, et java.
    J'ai déjà fait un petit jeu en 2d mais on ne pouvait pas sauté, je n'avais donc pas ce problème.

    Merci par avance de vos réponses, bonne soirée.

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Bonjour,


    En théorie, votre monde est divisé en bloc de taille régulière (disons des blocs de 16 pixels sur 16).
    Si vous avez un bloc (coin supérieur gauche) qui est à la position 32x96 bah, vous savez que si Mario est au dessus (soit mario.pos.x + mario.width > 32) et alors Mario ne peut pas tomber en dessous de 96.

    Habituellement on a une structure Rectangle, avec dedans une fonction pour savoir si deux rectangle se touche.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    Salut oui il faut utiliser une structure de type rectangle comme le dit Littlewhite.
    Tous les blocs matérialisés par des structures de type rectangle il faut les mettre dans une liste par exemple std::list ou std::vector ( en Java cela existe aussi)
    Le gros problème si tu fais un Mario c'est pas seulement les collisions qui sont difficiles à gérer c'est aussi les animations lorsque Mario saute

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 11
    Points : 7
    Points
    7
    Par défaut
    Merci de vos réponses rapide!
    Je vois un peu mieux comment faire maintenant, je vais déjà m’entraîner sur un petit exemple.

    Pour les animations, j'avais déjà fait un jeu avec Qt pour un projet de programmation, et avec l'utilisation d'un QTimer, on avait réussi à faire les animations pour le déplacement. Je pense que c'est assez proche pour le saut.

    Bonne journée.

  5. #5
    Inactif  

    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    166
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 166
    Points : 332
    Points
    332
    Par défaut
    salut,

    les jeux genre mario ça fonctionnait avec des objets convertis en tableau de tuiles.

    si tu veux pas t'embêter à faire ça dans un éditeur de maps, tu peux coder à la main les objets qui composent ta map dans un fichier xml, ensuite ton programme les convertit en grille de tuiles au chargement (les premiers épisodes de mario faisaient comme ça car y'avait pas la place pour stocker des tilemap dans les cartouches)

    ensuite on calcule les collisions entre les personnages et le tableau de tuiles. pour bien séparer les données graphiques des données sur la rigidité, tu peux faire un tableau de booléens à part qui encode uniquement la rigidité.

    y'a plein de techniques différentes, la plus complète c'est de tester le volume qui englobe le mouvement du rectangle ( soit un hexagone ) dans la grille, avec un ordering des cases le long du vecteur déplacement, et puis de faire un test "collision box" sur les cellules

    en voilà une plus simple qui est suffisante pour un jeu de plateforme: tu décomposes le mouvement et les collisions sur X et Y.
    d'abord tu déplaces le rectangle sur X, tu parcours toutes les cellules traversées par le segment du rectangle qui est du côté du sens du mouvement, et si une de ces cellules est solide alors on rabat le rectangle contre le bord de la cellule (et il faut calculer ça avec des integer sinon ça foire)
    ensuite rebelote sur Y

    une fois que t'arrives à déplacer un genre d'objet volant contre ta grille, tu rajoutes un effet de gravité et un saut


    voilà... donc c'est un boulot assez long et chiant à faire... y'a une source de mario en java ici: http://www.mojang.com/notch/mario/release.zip
    pour voir à quoi ressemble un projet amateur qui a réussi: http://www.advsys.net/ken/build.htm

  6. #6
    Inactif  

    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    166
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 166
    Points : 332
    Points
    332
    Par défaut
    j'ai isolé le bout de code avec les collisions mario / grille:
    enfin je crois

    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
    54
    55
    56
    57
    58
    59
            if (ya > 0)
            {
                if (isBlocking(x + xa - width, y + ya, xa, 0)) collide = true;
                else if (isBlocking(x + xa + width, y + ya, xa, 0)) collide = true;
                else if (isBlocking(x + xa - width, y + ya + 1, xa, ya)) collide = true;
                else if (isBlocking(x + xa + width, y + ya + 1, xa, ya)) collide = true;
            }
            if (ya < 0)
            {
                if (isBlocking(x + xa, y + ya - height, xa, ya)) collide = true;
                else if (collide || isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
                else if (collide || isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
            }
            if (xa > 0)
            {
                sliding = true;
                if (isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
                else sliding = false;
                if (isBlocking(x + xa + width, y + ya - height / 2, xa, ya)) collide = true;
                else sliding = false;
                if (isBlocking(x + xa + width, y + ya, xa, ya)) collide = true;
                else sliding = false;
            }
            if (xa < 0)
            {
                sliding = true;
                if (isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
                else sliding = false;
                if (isBlocking(x + xa - width, y + ya - height / 2, xa, ya)) collide = true;
                else sliding = false;
                if (isBlocking(x + xa - width, y + ya, xa, ya)) collide = true;
                else sliding = false;
            }
     
            if (collide)
            {
                if (xa < 0)
                {
                    x = (int) ((x - width) / 16) * 16 + width;
                    this.xa = 0;
                }
                if (xa > 0)
                {
                    x = (int) ((x + width) / 16 + 1) * 16 - width - 1;
                    this.xa = 0;
                }
                if (ya < 0)
                {
                    y = (int) ((y - height) / 16) * 16 + height;
                    jumpTime = 0;
                    this.ya = 0;
                }
                if (ya > 0)
                {
                    y = (int) ((y - 1) / 16 + 1) * 16 - 1;
                    onGround = true;
                }
                return false;
            }

    j'ai pas tout compris... y'a moyen de coder ça plus simplement

    j'avais fait ça en javascript, je ferai ptêt un portage en c si je me sens le courage, vla la version javascript déjà:

    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
    	// move and collide against the grid
     
    			var col:int , row:int;			
    			player.x += dx;  // move and collide on x			
    			if ( dx < 0 ) { // left seg
    				col = player.left / 16 ;
    				for ( row = player.top / 16 ; row < player.bottom / 16 ; row++ ) {
    					if ( grid[ col + row * 16 ] ) player.x = (col+1) * 16;
    				}
    			} else if ( dx > 0 ) { // right seg
    				col = player.right / 16 ;
    				for ( row = player.top / 16 ; row < player.bottom / 16 ; row++ ) {
    					if ( grid[ col + row * 16 ] ) player.x = col * 16 - player.width;
    				}
    			}			
    			player.y += dy;  // move and collide on y
    			if ( dy < 0 ) { // top seg
    				row = player.top / 16 ;
    				for ( col = player.left / 16 ; col < player.right / 16 ; col++ ) {
    					if ( grid[ col + row * 16 ] ) player.y = (row+1) * 16;
    				}
    			} else if ( dy > 0 ) { // bottom seg
    				row = player.bottom / 16 ;
    				for ( col = player.left / 16 ; col < player.right / 16 ; col++ ) {
    					if ( grid[ col + row * 16 ] ) player.y = row * 16 - player.height;
    				}
    			}
    pour faire ça mieux faut remplacer *16 et /16 par <<4 et >>4 , là j'avais codé le truc de façon à ce que ça soit lisible pour les débutants
    pour voir à quoi ressemble un projet amateur qui a réussi: http://www.advsys.net/ken/build.htm

Discussions similaires

  1. comment savoir si le téléphone est sur le reseau
    Par QAYS dans le forum Windows Mobile
    Réponses: 0
    Dernier message: 10/09/2013, 12h18
  2. Réponses: 5
    Dernier message: 01/04/2008, 08h33
  3. Comment savoir si un activeX est installé sur le client?
    Par r0d dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 10/12/2007, 09h37
  4. Réponses: 9
    Dernier message: 14/09/2006, 17h04
  5. Comment savoir si la souris est sur un TChart ?
    Par marsupilami34 dans le forum Composants VCL
    Réponses: 1
    Dernier message: 30/09/2005, 23h16

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