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.
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.