PDA

Voir la version complète : [PSP][Tutorial] Jour 10 : Collisions entre un sprite et une map


pjeff
24/01/2008, 18h26
Jour 10 Les collisions entre 1 sprite et une map
par PJEFF



Bonjour. Bienvenue dans la suite des tutoriels consacrés au développement sur PSP.

Pour des raisons évidentes j’ai repris les tutoriels déjà existants pour les adapter à ce qui suivra.
Je ne vais commenter que le code ajouté, pour le reste référez-vous aux anciens tutoriels.



Une Précision : c'est un cours basique j'entends par là que ça ne peut pas correspondre à tous les types de jeux et qu'il est possible de l'écrire de plusieurs façons différentes, il y a des choses à revoir ou à adapter selon la situation ou le jeu concerné.
exemple : pour un RPG prendre en considération qu'il ne faut pas tester entièrement le joueur mais qu'une partie et la partie inférieure du personnage ....


1) Déclaration Générale

Je pense qu'il n'y a pas besoin de commentaire...

............
//Déclaration des maps utilisées
OSL_MAP *Map01, *Map_collision;
OSL_IMAGE *Joueur ; //Déclaration du joueur

#define TILE_NOSOLID 0 //déclaration pour les non solide
#define TILE_SOLID 1 //déclaration pour les impassables
..........



dans le main

..........
Joueur= oslLoadImageFile("player.png", OSL_IN_RAM, OSL_PF_5551);
//place Le joueur vers le centre de l'écran et dans sa position de départ
Joueur->x = 240;
Joueur->y = 130;
...........




2) Déclaration des maps utilisées


Ici on utilise 2 maps une pour la carte visible et une pour les collisions
Je ne vais pas expliquer le détail car ça a déjà été fait sur un autre tuto.


/*
====================
Gestion_Map()

Initialisation des maps
====================
*/

void Gestion_Map()
{

//configuration de la map
Map01= oslCreateMap(
Map01_tileset, //Tileset
(void *)sprite_map, //Map
16,16, //Taille des tiles
30,17, //Taille de la Map
OSL_MF_U16); //Format de la Map

//configuration de la map
Map_collision= oslCreateMap(
collision_tileset, //Tileset
(void *)collisions_map, //Map
16,16, //Taille des tiles
30,17, //Taille de la Map
OSL_MF_U16); //Format de la Map

}





3) Déclaration de la fonction pour les Collisions pour la Map


Dans un premier temps on fait une fonction qui nous retourne la case (ou sprite) sur laquelle le joueur est placé



/*
====================
GetTile

Retourne le sprite sur lequel le player est positionné
====================
*/

short GetTile(OSL_MAP *m,int col, int row) //information relative a la map on regarde sur les coordonnées x et y sur quel tile on est
{
u16 *map = (u16*)m->map;
return map[row*m->mapSizeX + col]; //on retourne le numéro de la map
}



fonction de la gestion des collisions en elle même, retourne 1 si collision
Test de collision pour la partie Demander suivant la touche appuyer haut, bas, gauche, droit.
concrètement on prend les coordonnées sur lesquelles on se place X , Y et on les divise par la taille de chaque tile et on a la position x et y de la tile sur laquelle on est positionné.

ensuite on regarde le numéro de celle ci pour vérifier si elle et passable ou non

le +2 ou -2 écrit un peut partout se sont des valeur pour ne pas être bloqué quand il y a une collision autrement on ne pourrait se déplacer dans les autres sens.
Bien faire attention on fait le test des collisions, si il n'y en a pas on refait le test avec des coordonnées légèrement différentes car on est peut être partiellement sur un autre tile.
exemple:

http://pjeffadsl.free.fr/docs2/output/tut1_screen1.png
comme on le vois on est en décalage, on est entre 2 sprites


/*
====================
oslCollisionMap

Gestion des collisions avec les map et les perso pour le RPG
====================
*/

int oslCollisionMap(OSL_MAP *m,OSL_IMAGE *Collision,int haut,int bas, int gauche, int droit)
{
int tile;


//Test de collision pour la partie Demander suivant la touche appuyer haut, bas, gauche, droit.

if (haut)
{
tile = GetTile(m,((m->scrollX + Collision->x +Collision->stretchX ))/ m->tileX, (m->scrollY + Collision->y - 2)/ m->tileY);
if (!tile)
{
tile = GetTile(m,((m->scrollX + Collision->x))/ m->tileX, (m->scrollY + Collision->y - 2)/ m->tileY); //essaye avec la moitié du personnage pour que la tête passe quoi qu'il arrive
}
}

if (bas)
{
tile = GetTile(m,((m->scrollX + Collision->x +Collision->stretchX ))/ m->tileX, (m->scrollY + Collision->y + Collision->stretchY + 2)/ m->tileY);
if (!tile)
{
tile = GetTile(m,((m->scrollX + Collision->x))/ m->tileX, (m->scrollY + Collision->y + Collision->stretchY + 2)/ m->tileY);
}
}
if (gauche)
{
tile = GetTile(m,((m->scrollX + Collision->x - 2))/ m->tileX, (m->scrollY + Collision->y + Collision->stretchY)/ m->tileY);
if (!tile)
{
tile = GetTile(m,((m->scrollX + Collision->x - 2))/ m->tileX, (m->scrollY + Collision->y)/ m->tileY);
}
}

if (droit)
{
tile = GetTile(m,((m->scrollX + Collision->x +Collision->stretchX + 2))/ m->tileX, (m->scrollY + Collision->y + Collision->stretchY)/ m->tileY);
if (!tile)
{
tile = GetTile(m,((m->scrollX + Collision->x +Collision->stretchX + 2))/ m->tileX, (m->scrollY + Collision->y)/ m->tileY);
}
}

// c'est ici que on décide si oui ou non on passe.
switch(tile)
{
case TILE_NOSOLID:
// pas de collision sur le sprite retourne donc 0
return 0;
break;
case TILE_SOLID:
// impassable retourne simplement 1 car impassable
return 1;
break;

//On peut rajouter autant de cases que besoin selon ce que l'on recherche.
}


return 0;
}






4)Utilisation des collisions


Rappeler vous le jour 9 des tutoriels c'est le même principe, on teste lors de l'appui sur chaque touche si oui ou non il y a une collision.
si pas de collision on avance.


/*
====================
Touches

Gestion des touches pour le jeux :)
====================
*/
void Touches()
{
//Lit les touches
oslReadKeys();

if (osl_keys->held.down)
{
// ICI on test une collision avec la map Map_collision et le joueur
if (!oslCollisionMap(Map_collision,Joueur,0,1,0,0))
{

//ok on bouge
Joueur->y += 2;
}

}

if (osl_keys->held.up)
{
if (!oslCollisionMap(Map_collision,Joueur,1,0,0,0))
{
Joueur->y -= 2;
}

}

if (osl_keys->held.left)
{
if (!oslCollisionMap(Map_collision,Joueur,0,0,1,0))
{
Joueur->x -= 2;
}

}

if (osl_keys->held.right)
{
if (!oslCollisionMap(Map_collision,Joueur,0,0,0,1))
{
Joueur->x += 2;
}
}

}





5) Ne pas oublier d'afficher la map

là on n'affiche que la map du sol et pas celle des collisions

dans le main

//Affiche la map concernée, mais n'affiche pas la map des collision
oslDrawMapSimple(Map01);




6) voila le beau résultat


!!!!!!!!!!!!!ATTENTION !!!!!!!!!!!!!!!!!!
La carte utilisée ne nécessite pas de scroll , si vous devez utiliser un scroll ne pas oublier de l'appliquer sur la map des collisions également !!!! autrement les collision seront faussées et déplacées .



http://pjeffadsl.free.fr/docs2/output/tut2_screen3.png


Telechargement
Tutorial2collmap.rar (http://pjeffadsl.free.fr/docs2/output/Tutorial2collmap.rar)


Je ne sais pas si j'ai etait suffisament clair dabs ce tutorial si besoin je rajouterais des precisions
Merci de corriger les fautes et de supprimer ce message une fois effectuer, encore merci a vous.

Riolehh
24/01/2008, 18h49
Très belle initiative ;)

Edit : aïe les vilaines fautes :S

Dr.Vince
24/01/2008, 20h07
Je ne vais pas expliquer le détail car ça a déjà été fait sur un autre tuto.


hum..... de quel tuto parles-tu ???

ça m'intéresse car je cherche à faire des maps de collisions à partir de map de niveau avec gbagraphics

pjeff
24/01/2008, 20h27
hum..... de quel tuto parles-tu ???

ça m'intéresse car je cherche à faire des maps de collisions à partir de map de niveau avec gbagraphics


l'essentiel et marquer ici :
http://www.playeradvance.org/forum/showthread.php?t=4085

Petit rappel au cas ou pour faire une map Collision il faut le faire de la meme facon que une map classique mais avec des sprites de collisions.

J'ai mit a jour le Fichier source de ce tutorial pour inclure les sources pour GBAGRAPHICS avec les collisions et la map du jeux.
tu ouvres le fichier avec gbagraphic et regarde ce qui ce passe tu verra il y a rien de compliquer

fiorello
11/03/2008, 20h43
I will be very, very grateful if someone could translate it to english ^^

And if someone can help me, coz' im not movoing the char in my game but scrolling the map(like in normal rpg)