[Code Snippet] Collision cercle contre cercle

Syltech Message lu Posté le 15 Jan 2009 à 23:15 Bulle
Avatar de Syltech
Membre Confirmé

Messages : 282
GCPoints : 71266
Bon cette fois, je présente un code permettant des collisions cercle contre cercle.
Le but de mon exemple est de simulé des collisions avec les arbres d'une foret.
Le clic gauche permet d'ajouter des arbres à la position du curseur de la souris.

Exemple d'utilisation sur une map 3D : http://syltech.ifrance.com/Collision.wm

Code :
set display mode desktop width(),desktop height(),32,1
sync on

Type Tcercle
x as float
y as float
t as float
EndType

Global nx as float
Global ny as float

arbre_max as integer : arbre_max=99
dim arbre(arbre_max) as Tcercle

joueur as Tcercle
joueur.x = screen width()/2
joueur.y = screen height()/2
joueur.t = 20

do
   cls

   old_msc=msc
   msc=mouseclick()
   msx=mousex()
   msy=mousey()

   rem déplacement du joueur
   if rightkey()=1 : angle=angle+2 : endif
   if leftkey()=1 : angle=angle-2 : endif
   if upkey()=1
   joueur.x=joueur.x+cos(angle)*2
   joueur.y=joueur.y+sin(angle)*2
   endif

   rem le clic gauche de la souris permet de rajouter des arbres
   if msc=1 && old_msc=0
      arbre(nArbre).x=msx
      arbre(nArbre).y=msy
      arbre(nArbre).t=30+rnd(20)
      inc nArbre
      if nArbre=arbre_max+1 : nArbre=0 : endif
   endif

   ink rgb(168,230,29),0

   rem on vérifie la distance entre le joueur et les arbres de la scène
   rem si le joueur est en collision avec un arbre, on ajuste la position du joueur
   for i=0 to arbre_max

      if distance(joueur.x,joueur.y,arbre(i).x,arbre(i).y)-joueur.t-arbre(i).t<0

         CoeficientDirecteurInv(joueur.x,joueur.y,arbre(i).x,arbre(i).y,joueur.t+arbre(i).t)
         joueur.x=arbre(i).x+nx : joueur.y=arbre(i).y+ny

      endif

      circle arbre(i).x,arbre(i).y,arbre(i).t

   next a

   ink rgb(255,255,255),0
   circle joueur.x,joueur.y,joueur.t
   line joueur.x,joueur.y,joueur.x+cos(angle)*joueur.t,joueur.y+sin(angle)*joueur.t
   text 0,0,str$(screen fps())
   text 0,14,str$(nArbre)

   Sync
Loop

function CoeficientDirecteurInv(x1 as float, y1 as float, x2 as float, y2 as float, Taille as float)
   Normalex as float : Normaley as float : MagnitudeInv as float
   Normalex=x1-x2
   Normaley=y1-y2
   MagnitudeInv = Taille / Sqrt(Normalex^2+Normaley^2)
   nx=Normalex * MagnitudeInv : ny=Normaley * MagnitudeInv
endfunction

function distance(x1 as float, y1 as float, x2 as float, y2 as float)
   result as float : result = sqrt((x2-x1)^2+(y2-y1)^2)
endfunction result


En espérant que ça soit utile à quelqu'un :)

Syltech
Dernière édition le 31 Jan 2009 à 22:51
Image
Darktib Message lu Posté le 17 Jan 2009 à 13:32 Bulle
Avatar de Darktib
Membre Ultime

Messages : 4017
GCPoints : 347288
Excellent !

Je vais essayer d'ajouter ca a la librairie de collisions que j'ai faite sur ton code. En tout cas l'exemple que tu donne(une foret) est exactement le cas qui pourrait me servir :wink:
Apparement les perfs sont tres bonnes, et j'ai bien aimé la réaction du joueur qu'on on fait un arbre pile dessus.
Mod Message lu Posté le 18 Jan 2009 à 10:17 Bulle
Avatar de Mod
Webmaster

Messages : 4954
GCPoints : 2100823
Il y a juste deux petites erreurs, avec le second paramètre de la commande "ink" qui n'est pas présent. Rapide à corriger.

Toujours aussi pratique, sinon :).
Syltech Message lu Posté le 18 Jan 2009 à 20:48 Bulle
Avatar de Syltech
Membre Confirmé

Messages : 282
GCPoints : 71266
Enfaite la commande "ink" n'a pas obligatoirement de 2eme paramètre avec la version 7 de Dark Basic, c'est pour ça ^^

Content que ça plaise en tout cas :)

Je posterais surement d'autres codes du genre, des codes simples et utiles.

Syltech :)
Image
bebou007 Message lu Posté le 18 Jan 2009 à 23:26 Bulle
Avatar de bebou007
Explorateur

Messages : 238
GCPoints : 43228
c'est quand même bizar v 1.071 et il me fait l'erreur du ink obliger de metre un 2 eme

Syltech Message lu Posté le 18 Jan 2009 à 23:32 Bulle
Avatar de Syltech
Membre Confirmé

Messages : 282
GCPoints : 71266
hum... C'est surement une version bêta de la 7.0 que j'ai alors, je sais plus si je l'ai mise a jour... lol
Je met à jour Dark Basic et je modifie mon post pour rajouter un deuxième paramètre.

Syltech

Edit: Bon, bha résultat je n'ai pas besoin non plus du deuxième paramètre avec la version 7.1, et au passage j'ai mis à jour mon premier post.
Dernière édition le 20 Jan 2009 à 05:06
Image
Syltech Message lu Posté le 28 Jan 2009 à 10:24 Bulle
Avatar de Syltech
Membre Confirmé

Messages : 282
GCPoints : 71266
Bon je fais un double post pour ceux qui qui n'oserez pas utiliser ce snippet, le flemme de testé ou je ne sais quoi...

http://syltech.ifrance.com/Collision.wm

Regardez cette petite vidéo, le personnage a des collisions avec la hauteur de terrain et les arbres, c'est vraiment tout simple à programmer...

N'hésitez pas à utiliser ce snippet!
Vous pouvez en faire ce que vous voulez! :wink:

Syltech
Image
Tersaken Message lu Posté le 28 Jan 2009 à 13:11 Bulle
Avatar de Tersaken
Membre Confirmé

Messages : 302
GCPoints : 23103
J'ai perdu mon cd de db pro, impossible d'y installer les mises à jour.
Mais dès que je remet la main dessus, je testerai tout ça.
J'ai pu cependant regarder la vidéo, et effectivement, ton systeme à l'air efficace :wink:
Syltech Message lu Posté le 28 Jan 2009 à 13:43 Bulle
Avatar de Syltech
Membre Confirmé

Messages : 282
GCPoints : 71266
Ah! Tersaken! :grin:

Pour DBPro, j'ai moi aussi perdu mon CD, presque aussitôt après l'avoir acheter d'ailleurs(ça fait quelques années)... Bref, à partir du moment que tu as ta clé d'enregistrement, et ton e-mail, il y a toujours moyen de l'activé et de le mettre à jour!

Voici ma méthode:
J'installe la version trial 6.2, je renomme le dossier d'installation en supprimant le mot "Trial", j'installe par dessus la mise à jour 6.8, je l'active et c'est bon il reste plus qu'a mettre les autres mises à jour!
Je n'ai pas essayé de mettre directement la version 7.0 sur la version trial, peut être que ça marche!

Syltech

Dernière édition le 28 Jan 2009 à 13:45
Image
Darktib Message lu Posté le 28 Jan 2009 à 14:00 Bulle
Avatar de Darktib
Membre Ultime

Messages : 4017
GCPoints : 347288
Wow la faille ^^

Pas mal comme info en tout cas.

Sinon je pense qu'il y a moyen d'optimiser en de testant que les 3 cercles les plus proches par exemple
Syltech Message lu Posté le 28 Jan 2009 à 14:09 Bulle
Avatar de Syltech
Membre Confirmé

Messages : 282
GCPoints : 71266
Oui, il y a moyen d'optimiser de cette façon, mais à mon avis, il y a plus efficace.
Il suffit de délimité une map d'arbres en plusieurs bloc, et on calcul la collisions seulement avec les arbres qui sont dans le même bloc que le joueur.
Ça limite considérablement le nombre d'arbres testés dans la boucle For.

Pour la technique que j'utilise pour l'installation de DarkBasic, c'est pas plus mal que ça fonctionne comme ça, les CD n'ont pas une durée de vie éternel, et je pense que la clé et quand même la plus importante...

Je pensais que tout le monde connaissais ça lol


Syltech

Edit : Enfaite, pour l'optimisation la première chose que l'on calcul est la distance entre le joueur et l'arbre dans la boucle For.
Le calcul de collision seulement pour les 3 arbres les plus proches ne changerait pas grand chose, ça ferait 3 calculs de collision en plus du test de distance avec tous les arbres.
Tandis que si l'on fait ça par blocs, on devrait utiliser une boucle For pour déterminer dans quel bloc on se trouve et une autre boucle For pour un test de collision avec le nombre d'arbres dans le bloc.
Bref, je pense qu'avec cette technique on passe moins de temps dans les boucles For.
Dernière édition le 28 Jan 2009 à 14:36
Image
Syltech Message lu Posté le 11 Fév 2009 à 20:08 Bulle
Avatar de Syltech
Membre Confirmé

Messages : 282
GCPoints : 71266
Hum, je viens de remarqué que les formules du genre "(x2-x1)^2+(y2-y1)^2+(z2-z1)^2" étaient très gourmande niveau Fps à cause du "^2".
J'ai remarqué ça après avoir fait quelques optimisations sur mon moteur de collision 3D.
Avec les "^2" de mes fonctions de calculs de distance, j'étais à 200 Fps, et après avoir changer mes formules par "(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1)", je me suis retrouvé à... 400 Fps !

Donc si vous utilisez mon snippet, je vous conseille fortement de changer ma fonction "distance" par :

Code :
function distance(x1 as float, y1 as float, x2 as float, y2 as float)
   result as float : result = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
endfunction result


voilou!

Syltech
Dernière édition le 11 Fév 2009 à 20:09
Image
Répondre
GameCorp - Site d'apprentissage et d'entraide à la création de jeux vidéo.
XHTML Valid 1.1 - Page générée en 0.0457 secondes