Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Control Collision

This thread is locked; no one can reply to it. rss feed Print
Control Collision
pito2901
Member #16,119
November 2015

Hi !

I'm here because I can't resolve my problem :

I'm releazing a 2D game with Allegro 5 and I'm not able to make collision with my character. Actually, I made a tile map and a table with the tiles number.

My problem is that I can't know the position of my character on the map. So I can't control collision with it.

So if you can give me some answers, it will be great !

Here the zip file.

Thanks.

PS: I'm french and sorry if there are mistakes in my language.

Chris Katko
Member #1,881
January 2002
avatar

You always track your player position.

for example:

float player_x;
float player_y;

bool map[32][32]; //1 indicates solid, 0 is empty
const int TILE_WIDTH = 16;
const int TILE_HEIGHT = TILE_WIDTH;

if(map[player_x / TILE_WIDTH][player_y / HEIGHT) == 1) //convert from position to index in the map by dividing by the tile size
{
//collision has occurred
}

You can use the player_x and player_y to represent the "center" of your character, then draw the character with:

my_draw_function(player_bitmap, player_x / PLAYER_WIDTH, player_y / PLAYER_HEIGHT)

This would center it at your player point. Or for a platformer, you want to center horizontally, but not vertically. You want to be checking your players feet, not his chest. (Whereas the exact center could work for a space ship.) So you'd do:

my_draw_function(player_bitmap, player_x / PLAYER_WIDTH, player_y - PLAYER_HEIGHT).

That is, centered horizontally, but not vertically. And you subtract the height to move the sprite higher on the screen so now the bottom of the graphic (typically his / her feet) will be the contact point.

You can also have more contact points, such as top/bottom/left/right.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

pito2901
Member #16,119
November 2015

Can you translate your answer with my code please ?

Allegro.h

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_color.h> 3#include <allegro5/allegro_image.h> 4#include <allegro5/allegro_primitives.h> 5#include <allegro5/allegro_native_dialog.h> 6 7//Couleurs 8#define GRIS al_map_rgb(178,178,178) 9#define BLEUF al_map_rgb(12,99,238) 10#define BLEUC al_map_rgb(17,193,243) 11#define VERT al_map_rgb(51,205,95) 12#define ORANGE al_map_rgb(255,201,0) 13#define ROUGE al_map_rgb(239,71,58) 14#define VIOLET al_map_rgb(136,106,234) 15#define NOIR al_map_rgb(68,68,68) 16 17#define screenx 400 18#define screeny 400 19 20#define tilex 100 21#define tiley 100 22 23 24/**************************************** 25PERSO 26****************************************/ 27 28struct perso { 29 ALLEGRO_BITMAP *face[3], *gauche[3], *droite[3], *back[3]; 30 int posx, posy; 31 int x = screenx / 2, 32 y = screeny / 2; 33}; 34 35/********************************** 36 MAP 37**********************************/ 38 39struct carte { 40 ALLEGRO_BITMAP *image; 41 int x, y; 42}; 43 44void init_carte(carte *m, int largeur, int hauteur) { 45 m->x = - largeur / 2 + screenx / 2; 46 m->y = - hauteur / 2 + screeny /2; 47} 48 49void affiche_carte(carte *m, perso *p) { 50 al_draw_bitmap(m->image, m->x, m->y, 0); 51 al_draw_bitmap(p->face[1], p->x - 23, p->y - 23, 0); 52} 53 54/* Déplacements */ 55enum KEYS { UP, RIGHT, LEFT, DOWN, F, KEY_MAX }; 56bool key[KEY_MAX] = { false }; 57 58/* Mouvements */ 59void haut(carte *m, perso *p, int compt_back) { 60 m->y = m->y + 5; 61 al_draw_bitmap(m->image, m->x, m->y, 0); 62 63 al_draw_bitmap(p->back[compt_back], p->x - 23, p->y - 23, 0); 64} 65void bas(carte *m, perso *p, int compt_face) { 66 m->y = m->y - 5; 67 al_draw_bitmap(m->image, m->x, m->y, 0); 68 69 al_draw_bitmap(p->face[compt_face], p->x - 23, p->y - 23, 0); 70} 71void gauche(carte *m, perso *p, int compt_gauche) { 72 m->x = m->x + 5; 73 al_draw_bitmap(m->image, m->x, m->y, 0); 74 75 al_draw_bitmap(p->gauche[compt_gauche], p->x - 23, p->y - 23, 0); 76} 77void droite(carte *m, perso *p, int compt_droite) { 78 m->x = m->x - 5; 79 al_draw_bitmap(m->image, m->x, m->y, 0); 80 81 al_draw_bitmap(p->droite[compt_droite], p->x - 23, p->y - 23, 0); 82}

main.cpp

#SelectExpand
1#include <stdio.h> 2#include <stdlib.h> 3#include <allegro.h> 4 5// fonction contrôle d'erreur 6void erreur(const char*txt) 7{ 8 ALLEGRO_DISPLAY*d; 9 d = al_is_system_installed() ? al_get_current_display() : NULL; 10 al_show_native_message_box(d, "ERREUR", txt, NULL, NULL, 0); 11 exit(EXIT_FAILURE); 12} 13/****************************************************************** 14******************************************************************/ 15int main() 16{ 17 // Pointeurs 18 ALLEGRO_DISPLAY *display; // fenêtre 19 ALLEGRO_EVENT_QUEUE *queue; // evenement 20 ALLEGRO_TIMER *timer; // temps 21 22 /**************************************** 23 INITIALISATIONS 24 ****************************************/ 25 if (!al_init()) 26 erreur("Erreur : Allegro"); 27 28 // Création d'une fenêtre 29 display = al_create_display(screenx, screeny); 30 if (!display) 31 erreur("Erreur : Display"); 32 // Propriétés de la fenêtre 33 // Titre 34 al_set_window_title(display, "Premier programme !"); 35 36 // Couleur de fond 37 al_clear_to_color(ROUGE); 38 39 /**************************************** 40 VARIABLES 41 ****************************************/ 42 43 // Map 44 carte map; 45 46 // Perso 47 perso mario; 48 49 bool fin = false, 50 dessin = false; 51 52 // Dessin 53 if (!al_init_primitives_addon()) 54 erreur("Dessin"); 55 56 // Clavier 57 if (!al_install_keyboard()) 58 erreur("Clavier"); 59 60 // Souris 61 if (!al_install_mouse()) 62 erreur("Souris"); 63 64 // Image 65 if (!al_init_image_addon()) 66 erreur("Images"); 67 68 // Face 69 char nom[256]; 70 for (int i = 0; i < 3; i++) { 71 sprintf_s(nom, "./images/perso/face%d.png", i); 72 mario.face[i] = al_load_bitmap(nom); 73 } 74 float compt_face = 0; 75 76 // Gauche 77 for(int i = 0; i < 3; i++) { 78 sprintf_s(nom, "./images/perso/gauche%d.png", i); 79 mario.gauche[i] = al_load_bitmap(nom); 80 } 81 float compt_gauche = 0; 82 83 // Droite 84 for (int i = 0; i < 3; i++) { 85 sprintf_s(nom, "./images/perso/droite%d.png", i); 86 mario.droite[i] = al_load_bitmap(nom); 87 } 88 float compt_droite = 0; 89 90 // Back 91 for (int i = 0; i < 3; i++) { 92 sprintf_s(nom, "./images/perso/back%d.png", i); 93 mario.back[i] = al_load_bitmap(nom); 94 } 95 float compt_back = 0; 96 97 // Map 98 // Collision 99 map.image = al_load_bitmap("./images/map/test.png"); 100 int hauteur = al_get_bitmap_height(map.image); 101 int largeur = al_get_bitmap_width(map.image); 102 init_carte(&map, largeur, hauteur); 103 104 // Carte 105 int carte[5][5] = { 106 { 16,16,16,16,16 }, 107 { 16,1,16,3,16 }, 108 { 16,16,16,16,16 }, 109 { 16,9,16,11,16 }, 110 { 16,16,16,16,16 } 111 }; 112 113 // Temps 114 const int fps = 24; 115 timer = al_create_timer(1.0 / fps); 116 if (!timer) 117 erreur("timer"); 118 119 // Evenements 120 queue = al_create_event_queue(); 121 if (!queue) 122 erreur("queue"); 123 124 al_register_event_source(queue, 125 al_get_display_event_source(display)); 126 al_register_event_source(queue, 127 al_get_keyboard_event_source()); 128 al_register_event_source(queue, 129 al_get_timer_event_source(timer)); 130 131 al_start_timer(timer); 132 133 while (!fin) 134 { 135 // Récupérer un évenement 136 ALLEGRO_EVENT even; 137 al_wait_for_event(queue, &even); 138 139 // [Échap] 140 if (even.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 141 fin = true; 142 143 else if (even.type == ALLEGRO_EVENT_KEY_DOWN) 144 { 145 switch (even.keyboard.keycode) 146 { 147 case ALLEGRO_KEY_UP: 148 key[UP] = true; 149 break; 150 case ALLEGRO_KEY_DOWN: 151 key[DOWN] = true; 152 break; 153 case ALLEGRO_KEY_LEFT: 154 key[LEFT] = true; 155 break; 156 case ALLEGRO_KEY_RIGHT: 157 key[RIGHT] = true; 158 break; 159 160 case ALLEGRO_KEY_ESCAPE: 161 fin = true; 162 break; 163 } 164 } 165 166 else if (even.type == ALLEGRO_EVENT_KEY_UP) 167 { 168 switch (even.keyboard.keycode) 169 { 170 case ALLEGRO_KEY_UP: 171 key[UP] = false; 172 break; 173 case ALLEGRO_KEY_DOWN: 174 key[DOWN] = false; 175 break; 176 case ALLEGRO_KEY_LEFT: 177 key[LEFT] = false; 178 break; 179 case ALLEGRO_KEY_RIGHT: 180 key[RIGHT] = false; 181 break; 182 default: 183 dessin = false; 184 } 185 } 186 187 else if (even.type == ALLEGRO_EVENT_TIMER) 188 { 189 al_clear_to_color(ROUGE); 190 191 affiche_carte(&map, &mario); 192 193 if (key[UP]) 194 { 195 haut(&map, &mario, compt_back); 196 compt_back = compt_back + .5; 197 if (compt_back > 2) 198 compt_back = 0; 199 } 200 else if (key[DOWN]) 201 { 202 bas(&map, &mario, compt_face); 203 compt_face = compt_face + .5; 204 if (compt_face > 2) 205 compt_face = 0; 206 } 207 else if (key[LEFT]) 208 { 209 gauche(&map, &mario, compt_gauche); 210 compt_gauche = compt_gauche + .5; 211 if (compt_gauche > 2) 212 compt_gauche = 0; 213 } 214 else if (key[RIGHT]) 215 { 216 droite(&map, &mario, compt_droite); 217 compt_droite = compt_droite + .5; 218 if (compt_droite > 2) 219 compt_droite = 0; 220 } 221 else 222 { 223 affiche_carte(&map, &mario); 224 } 225 } 226 227 al_flip_display(); 228 229 230 } 231 232 al_destroy_display(display); 233 234 return 0; 235}

Thanks.

Go to: