Dans tous les
jeux "Professionnels" qui utilisent des Sprites
il existe un moteur (programme spécialement conçu
pour réaliser des déplacements d'images
en tenant compte de l'image de fond, de la vitesse de
déplacement , des collisions, des animations...
et de bien d'autres effets). Nous n'allons pas prendre
en compte tous ses paramètres et nous concentrer
sur les Collisions. (pour
le Déplacement voir le tutoriel32...
)
|
. |
Essai 1: Détection de
collisions entre 2 images (l'image1 rentre
en collision avec l'image2)
|
.Le cas le plus simple consiste
à détecter une collision entre 2 images.
Il suffit de verifier à partir des 4 points qui
sont aux 4 coins de l'image: |
if (image2.left<= image1.left<=image2.left+image2.width) |
or (image2.right<= image1.right<=image2.right+image2.width)
then |
if (mage2.top<= image1.top<=image2.top+image2.height) |
(or image2.bottom<= image1.bottom<=image2.bottom+image2.height)
then collision |
. |
Essai 2: Détection de
2 images aux contours irréguliers.
|
.Il est rare que l'image qui bouge
ressemble à un carré...l'image est certe
mémorisée dans un Tbitmap ou Tpicture carré,
mais le motif qui est à l'interieur est souvant
loin d'avoir la même forme !!! |
La première méthode
n'est donc pas appropriée car si elle détecte
bien le chevauchement des 2 images cela ne veux pas dire
que les motifs qui sont dessus se sont touchés...c'est
le cas dans certains jeux, rappelez vous combien vous
avez ralé de perdre alors que vous n'avez pas été
touché... |
La premiére idée
qui vient à l'esprit est de gérer une image
comme un négatif de photo...enfin moi c'est la
première que j'ai eu... pas vous ?? en d'autre
terme avoir une couleur de fond facilement repérable.
Prendre une couleur peu utilisé (éviter
le noir qui sert souvant à entourer les sprites
pour les faire ressortir) et dessiner tous ses dessins
sur un fond, par exemple rouge (attention si votre dessin
utilise le même rouge que celui du fond ces parties
seront considérer comme le fond et n'entrainerons
pas de collision !). Cela ne veux pas dire qu'on ne peut
plus utiliser le rouge pour dessiner, le rouge pur =rgb(255,0,0),
il est possible d'utiliser toutes les autres nuances rgb(254,0,0),rgb(253,0,0)
etc... |
Il faut maintenant determiner
le morceau d'image qui contient l'image1 et l'image2,
inutile de verifier tout l'écran. En limitant la
zone du test de collision on accélère la
vitesse de traitement.... Grâce aux coordonnées
de nos 2 images (right,left,top,bottom) cela reste facile
à réaliser, même si il faut y laisser
quelques neurones pour y arriver .... On détermine
alors une zone mémoire de la taille du rectangle
englobant nos 2 images. Reste maintenant à verifier
le chevauchement des dessins sur les 2 images. |
- copier l'image 1 sur la zone
mémoire |
- copier point par point l'image
2 sur la zone mémoire, si (image2.canvas.pixel[x,y]<>rouge)
and (zone_memoire.canvas.pixel[x,y]<>rouge)
alors il y a collision |
Ca commence à être
bien...mais il y a mieux !!! |
. |
Essai 3 : Enfin nous y voilà...
le InterSectRect
|
.En un mot la commande :InterSectRect
va nous simplifier grandement la tache. Cette commande
va nous retourner UNIQUEMENT le rectangle correspondant
à l'intersection des 2 images. Super Cool ça...
non :)) |
Il faudra ensuite tester dans
ce rectangle si les morceaux de l'image1 et de l'image2
se chevauchent sur une partie dessinée... bref,
un exemple et souvant plus clair ! |
var ax, ay : integer;
OK : boolean;
collisionR : Trect;
c1, c2 : tcolor;
begin
ok := true
If not intersectrect(Collisionr, bounds(x1,y1,bitmap1.width,bitmap1.height),
bounds(x2,y2, bitmap2.width, bitmap2.height))then
|
// maintenant que tu as le rectangle intersection il faut affiner pour savoir si les
// lignes ou courbes non rouges se touchent.
// On est donc obligé de tester les pixels individuellement dans chaque zone des
// bitmaps correspondant au rectangle collision
// si les 2 pixels ne sont pas à rouge, il y a collision et on arrête
|
begin
for ay := collisionR.top to collisionR.bottom do
for ax := collisionR.left to collisionR.right do
begin
c1 := bitmap1.canvas.pixels[ax - x1, ay - y1];
c2 := bitmap2.canvas.pixels[ax - x2, ay - y2];
if (c1 <> clred) and (c2 <> clred) then
begin
ok := false;
break;
end;
end;
end;
|
. |
Améliorations possibles
:
|
Ecrire cette procédure
en assembleur ... si tu l'as fait, envoie la moi...ici |