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

Lazarus Pascal Discussion :

Collision d'objets dans un jeu


Sujet :

Lazarus Pascal

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 3
    Par défaut Collision d'objets dans un jeu
    Bonsoir à tous,

    Je réalise un jeu ressemblant à "angry birds" sur Lazarus. J'ai actuellement réalisé tout le code permettant le mouvement du projectile et je m'attaque maintenant au code permettant la collisions des blocs cibles (avec le projectile et entre eux).

    J'ai pour l'instant réalisé un ensemble de fonctions et procédures permettant la détection de la collision. Cela compile mais Lazarus me dit que j'ai une exception de classe...

    J'ai une classe mère abstraite définie comme suit :
    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
    CMObject = class
     
         // The position of the moving object
         fposition:Cvector;
          fspeedy, fspeedx:real;
         // The size of the window in which it moves
         fwinw,fwinh:real;
     
         // angle
         fangle:real;
     
         procedure drawYourself(canv:TCanvas); virtual; abstract;
         function absolutetolocal(V:Cvector):Cvector;
         function localtoabsolute(V:Cvector):Cvector;
         procedure collision(mobjects:tstringlist);
         function collidewithblock(other:Cmobject):Cvector;virtual;abstract;
         function collisionprecheck(other:Cmobject):Cvector;virtual;abstract;
         procedure move(); virtual; abstract;
         procedure drawDebug(canv:TCanvas); virtual; abstract;
    end;
    Une classe Cvector :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Cvector= class
      fx:real;
      fy:real;
     
    constructor create (ax,ay:real);
    end;
    Et une classe Cblock (définissant les blocs cibles) :
    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
    Cblock = Class (CMobject)
           fL:real;
           fimage : TBitmap;
           fshape:array [1..4] of Cvector;
     
    constructor create (aao : TstringList; awinw,awinh,aangle, ax,ay, aL, aspeedx,aspeedy:real; aimgfname:string);
    procedure drawyourself(canv:Tcanvas); override ;
    procedure move(); override;
    function collidewithblock(other:Cmobject):Cvector;override;
    function collisionprecheck(other:Cmobject):Cvector;override;
    function getside(V:Cvector):integer; //return the side of the block where the collision occurs
      //procedure setspeed(vx,vy);
      //function getrelativespeed
      //procedure collisionspeedxy();//modifies linear speed of incoming block in the absolute frame
      //procedure collisionspeedtheta();//modifies rotation speed of the current block in the absolute frame
    end;
    Voilà le constructeur de la classe Cblock :
    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
    constructor Cblock.create(aao:TStringList; awinw,awinh, aangle,ax,ay,aL,aspeedx,aspeedy:real; aimgfname:string);
    Var V1,V2,V3,V4:Cvector;
     
    begin
        // The window width and height
         fwinw := awinw;
         fwinh := awinh;
     
         // Position of the blocks
         fposition:=Cvector.create(ax,ay);
     
         fangle:=aangle;
         //size of the block
     
         fL:= aL;
     
          // initial speed
     
          fspeedx:=aspeedx;
          fspeedy:=aspeedy;
     
         //image
     
       fimage:=Tbitmap.create;
       fimage.LoadFromFile(aimgfname);
     
       V1:=Cvector.create(-aL/2,-aL/2);
       V2:=Cvector.create(aL/2,-aL/2);
       V3:=Cvector.create(aL/2,aL/2);
       V4:=Cvector.create(-aL/2,aL/2);
     
       fshape[1]:=localtoabsolute(V1);
       fshape[2]:=localtoabsolute(V2);
       fshape[3]:=localtoabsolute(V3);
       fshape[4]:=localtoabsolute(V4);
     
    end;
    J'ai deux fonctions permettant de passer du repère local du bloc au repère absolu et inversement :
    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
    function Cmobject.absolutetolocal(V:Cvector):Cvector;
    var ax,ay:real;
    begin
    ax:=(V.fx-fposition.fx)*cos(fangle)-(V.fy-fposition.fy)*sin(fangle);
    ay:=(V.fx-fposition.fx)*sin(fangle)+(V.fy-fposition.fy)*cos(fangle);
    absolutetolocal:=Cvector.create(ax,ay);
    end;
     
    function Cmobject.localtoabsolute(V:Cvector):Cvector;
    var
    ax,ay:real;
    begin
    ax:=V.fx*cos(fangle)+V.fy*sin(fangle)+fposition.fx;
    ay:=V.fy*cos(fangle)-V.fx*sin(fangle)+fposition.fy;
    localtoabsolute:=Cvector.create(ax,ay);
    end;
    Voilà les fonctions de collision :
    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
    60
    61
    62
    63
    64
    function Cblock.getside(V:Cvector):integer;
    var x,y,x1,x2,x3,x4,y1,y2,y3,y4:real;
        side:integer;
    begin
    x:=absolutetolocal(V).fx; //coordinates of v in the absolute frame
    y:=absolutetolocal(V).fy;
    x1:=absolutetolocal(fshape[1]).fx;
    y1:=absolutetolocal(fshape[1]).fy;
    x2:=absolutetolocal(fshape[2]).fx;
    y2:=absolutetolocal(fshape[2]).fy;
    x3:=absolutetolocal(fshape[3]).fx;
    y3:=absolutetolocal(fshape[3]).fy;
    x4:=absolutetolocal(fshape[4]).fx;
    y4:=absolutetolocal(fshape[4]).fy;
     
    if y>=0  //cadran x, y positifs
    then
        if  x>=0
        then
            if abs(x3-x)<=abs(y3-y)
            then
                side:=3
            else
                side:=4
        else               //cadran x negatif, y positif
            if  abs(x4-x)<=abs(y4-y)
            then
                side:=1
            else
                side:=4
    else   //y<0
        if x>=0  // cadran x positif, y negatif
        then
            if abs(x2-x)<=abs(y2-y)
            then
                side:=3
            else
                side:=2
        else             // cadran x, y negatifs
            if abs((x1-x))<=abs(y1-y)
            then
                side:=1
            else
                side:=2
    ;
    getside:=side;
    end;
     
    function Cblock.collisionprecheck(other:Cmobject):Cvector;
    begin
    other.collidewithblock(self);
    end;
     
    function Cblock.collidewithblock(other:Cmobject ):Cvector;//attention repère locaux!! //rectifier avec un centrage sur le point d'inertie !
    var i:integer;
    begin
    for i:=1 to 4 do
    if      (self.absolutetolocal((other as Cblock).fshape[i]).fy>=-(self.fL)/2) and ( self.absolutetolocal((other as Cblock).fshape[i]).fx>=-(self.fl)/2)
        and (self.absolutetolocal((other as Cblock).fshape[i]).fy<=self.fL/2) and (self.absolutetolocal((other as Cblock).fshape[i]).fx<=self.fL/2)
    then
            collidewithblock:=(other as Cblock).fshape[i]
    else
            collidewithblock:=nil;
    end;
    J'ai aussi des fonctions de collision entre le projectile et les blocs (Cprojectile étant la classe du projectile qui ressemble grandement à la classe Cblock) :
    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
    function Cprojectile.collidewithblock(other:Cmobject):Cvector; //attention repères locaux!!
    begin
    if (other.absolutetolocal(self.fposition).fx)>=-(((other as Cblock).fL)/2)
       then
       if(other.absolutetolocal(self.fposition).fy)>=-(((other as Cblock).fL)/2)
           then
           if (other.absolutetolocal(self.fposition).fx)<=(((other as Cblock).fL)/2)
              then
              if(other.absolutetolocal(self.fposition).fy)<=(((other as Cblock).fL)/2)
              then
              collidewithblock:=self.fposition
              else
              collidewithblock:=nil
           else
           collidewithblock:=nil
       else
       collidewithblock:=nil
    else
    collidewithblock:=nil
    end;
     
    function Cprojectile.collisionprecheck(other:Cmobject):Cvector;
    begin
    self.collidewithblock(other);
    end;
    Enfin j'ai la procédure suivante :
    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
    procedure Cmobject.collision(mobjects:tstringlist);
    var i,j:integer;
    begin
     
    for j:=0 to mobjects.count do
    if self <> mobjects.objects[j]
    then
    begin
    if
    (self.collisionprecheck(mobjects.objects[j] as Cmobject)<>nil )
    then
    self.fspeedx:=0;
    self.fspeedy:=0;
    end;
     
    end;
    Pour finir j'ai cette ligne dans l'unité principale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (mobjects.objects[i] as CMObject).collision(mobjects);
    Je sais que c'est assez moche mais si vous pouviez m'aider, je vous en serais très reconnaissant. Je suis vraiment bloqué...

    Dernière chose. Ne serait-il pas plus facile pour moi de réaliser les blocs avec 4 lignes plutôt qu'avec des images? Je souhaite effectivement faire tourner les blocs sur eux-même après la collision pour plus de réalité...

    Bonne soirée

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    trop de code à lire pour comprendre ce qu'il se passe

    mais tu peux être intéressé par le portable sous Delphi de box2D
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

Discussions similaires

  1. [XCode] Augmenter vitesse objet dans un jeu
    Par mr.foxvolt dans le forum Objective-C
    Réponses: 2
    Dernier message: 30/04/2014, 22h27
  2. Réponses: 2
    Dernier message: 02/10/2012, 12h39
  3. objets à utiliser dans un jeu réseau
    Par slouma_b_h dans le forum Réseau et multijoueurs
    Réponses: 13
    Dernier message: 03/10/2009, 18h57
  4. Collision dans un jeu de voiture
    Par japle dans le forum Physique
    Réponses: 5
    Dernier message: 21/07/2006, 14h33
  5. [arbre] Sauvegarder un objet dans un fichier
    Par Guigui_ dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2003, 00h55

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