Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [A5] al_get_pixel

This thread is locked; no one can reply to it. rss feed Print
[A5] al_get_pixel
Ninjarobot
Member #12,640
March 2011

Does al_get_pixel return the pixel's colour in "ffffff" format?
If so how can I compare the colour this function returns with another hex colour?
I've tried:

#SelectExpand
1if( (al_get_pixel(canvas,SCREEN_W/2,SCREEN_H/2) ) =="ffcc66")

and it gives me :"error: no match for 'operator==' in 'al_get_pixel(canvas, 320, 240) == "ffcc66"

I am trying to compare the colour of a target pixel and if it's X to paint red but if it's anything else to paint a sand-ish colour. Another question I have is if it's possible to use al_get_pixel on my canvas without making ALLEGRO_BITMAP canvas a global. I tried to use a reference but made it worse.

Thanks in advance.

#SelectExpand
1#include <stdio.h> 2#include <allegro5/allegro.h> 3#include <allegro5/allegro_primitives.h> 4#include <allegro5/allegro_color.h> 5 6 7 8/* constants and definitions */ 9 10const int SCREEN_W = 640; 11const int SCREEN_H = 480; 12const float FPS = 60; 13const int paddle_height = 96; 14const int paddle_width = 16; 15const int bouncer_size = 16; 16const int cursor_size=18; 17ALLEGRO_BITMAP *canvas= NULL; 18 19enum MYKEYS { 20 KEY_UP, KEY_DOWN, KEY_W, KEY_S,KEY_A,KEY_D,KEY_SPACE,KEY_P 21}; 22 23/* functions */ 24 25void draw_cursor(float x,float y) 26{ 27 al_draw_circle(x , y, cursor_size, al_color_html("ff0000"), 2.0); 28} 29 30void drop_sand(float x,float y) 31{ if((al_get_pixel(canvas,SCREEN_W/2,SCREEN_H/2))=="ffcc66") 32 { 33 al_draw_filled_circle( x, y, cursor_size-3, al_color_html("ffff66")); 34 } 35 36 else 37 al_draw_filled_circle( x, y, cursor_size-3, al_color_html("ffcc66")); 38 39 40 41} 42 43 44 45void draw_ball(float x, float y) 46{ 47 // fill 48 al_draw_filled_circle(x, y, bouncer_size, al_color_html("6be97d")); 49 // shadow 50 al_draw_filled_circle(x+bouncer_size/4, y+bouncer_size/4, bouncer_size/3*2, al_color_html("59ce76")); 51 // shine 52 al_draw_filled_circle(x-bouncer_size/3, y-bouncer_size/3, bouncer_size/4, al_color_html("9bffaa")); 53} 54 55 56 57 58int main(int argc, char **argv) 59{ 60 ALLEGRO_DISPLAY *display = NULL; 61 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 62 ALLEGRO_TIMER *timer = NULL; 63 ALLEGRO_BITMAP *sand = NULL; 64 ALLEGRO_BITMAP *bouncer = NULL; 65 ALLEGRO_BITMAP *cursor= NULL; 66 67 68 69 float bouncer_x = SCREEN_W / 2.0 - bouncer_size / 2.0; 70 float bouncer_y = SCREEN_H / 2.0 - bouncer_size / 2.0; 71 float bouncer_dx = 4.0, bouncer_dy = -4.0; 72 73 float cursor_x=(SCREEN_W / 2.0); 74 float cursor_y=(SCREEN_H / 2.0); 75 76 bool key[8] = {false, false, false, false, false, false, false, false}; 77 bool redraw = true; 78 bool doexit = false; 79 80 if(!al_init()) { 81 fprintf(stderr, "failed to initialized allegro\n"); 82 return -1; 83 } 84 85 if(!al_install_keyboard()) { 86 fprintf(stderr, "failed to install keyboard\n"); 87 return -1; 88 } 89 90 91 al_init_primitives_addon(); 92 93 al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); 94 al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); 95 96 97 //initialize display (w, h) 98 display = al_create_display(SCREEN_W, SCREEN_H); 99 if(!display) { 100 fprintf(stderr, "failed to create display\n"); 101 return -1; 102 } 103 104 timer = al_create_timer(1.0/FPS); 105 if(!timer) { 106 fprintf(stderr, "failed to create timer\n"); 107 return -1; 108 } 109 110 draw_cursor(300,200); 111 112 113 114 cursor = al_create_bitmap(cursor_size,cursor_size); 115 sand = al_create_bitmap(cursor_size-3,cursor_size-3); 116 bouncer = al_create_bitmap(bouncer_size, bouncer_size); 117 canvas = al_create_bitmap(SCREEN_W, SCREEN_H); 118 119 120 if(!bouncer) { 121 fprintf(stderr, "failed to create bouncer bitmap\n"); 122 return -1; 123 } 124 125 126 127 al_set_target_bitmap(bouncer); 128 al_clear_to_color(al_map_rgb (0,0,0)); 129 al_set_target_bitmap(cursor); 130 al_clear_to_color(al_map_rgb (0,0,0)); 131 al_set_target_bitmap(canvas); 132 al_clear_to_color(al_map_rgb(0,0,0)); 133 134 135 al_set_target_bitmap(al_get_backbuffer(display)); 136 137 event_queue = al_create_event_queue(); 138 if(!event_queue) { 139 fprintf(stderr, "failed to create event queue\n"); 140 return -1; 141 } 142 143 al_register_event_source(event_queue, al_get_display_event_source(display)); 144 145 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 146 147 al_register_event_source(event_queue, al_get_keyboard_event_source()); 148 149 al_clear_to_color(al_map_rgb(0, 0, 0)); 150 151 al_flip_display(); 152 153 al_start_timer(timer); 154 155 while(!doexit) 156 { 157 ALLEGRO_EVENT ev; 158 159 al_wait_for_event(event_queue, &ev); 160 161 if(ev.type == ALLEGRO_EVENT_TIMER) { 162 163 //DROP SAND 164 if (key[KEY_SPACE]==true) 165 { 166 al_set_target_bitmap(canvas); 167 drop_sand(cursor_x, cursor_y); 168 al_set_target_bitmap(al_get_backbuffer(display)); 169 redraw = true; 170 171 } 172 173 //CURSOR 174 if (key[KEY_W] && cursor_y >= 22.0) 175 { 176 cursor_y -= 4.0; 177 } 178 if(key[KEY_S] && cursor_y <= SCREEN_H - cursor_size - 4.0) 179 { 180 cursor_y += 4.0; 181 } 182 if(key[KEY_A] && cursor_x >= 22.0) 183 { 184 cursor_x -= 4.0; 185 } 186 if(key[KEY_D] && cursor_x <= SCREEN_W - cursor_size - 4.0) 187 { 188 cursor_x += 4.0; 189 } 190 //CURSOR 191 192 //logic for the bouncer 193 if(bouncer_x < 0 || bouncer_x > SCREEN_W - bouncer_size) { 194 bouncer_dx = -bouncer_dx; 195 } 196 197 if(bouncer_y < 0 || bouncer_y > SCREEN_H - bouncer_size) { 198 bouncer_dy = -bouncer_dy; 199 } 200 201 202 203 bouncer_x += bouncer_dx; 204 bouncer_y += bouncer_dy; 205 206 redraw = true; 207 } 208 209 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 210 break; 211 } 212 213 else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) { 214 switch(ev.keyboard.keycode) { 215 case ALLEGRO_KEY_UP: 216 key[KEY_UP] = true; 217 break; 218 219 case ALLEGRO_KEY_DOWN: 220 key[KEY_DOWN] = true; 221 break; 222 223 case ALLEGRO_KEY_W: 224 key[KEY_W] = true; 225 break; 226 227 case ALLEGRO_KEY_S: 228 key[KEY_S] = true; 229 break; 230 231 case ALLEGRO_KEY_A: 232 key[KEY_A] = true; 233 break; 234 235 case ALLEGRO_KEY_D: 236 key[KEY_D] = true; 237 break; 238 239 case ALLEGRO_KEY_SPACE: 240 key[KEY_SPACE] = true; 241 break; 242 } 243 } 244 245 else if(ev.type == ALLEGRO_EVENT_KEY_UP) { 246 switch(ev.keyboard.keycode) { 247 case ALLEGRO_KEY_UP: 248 key[KEY_UP] = false; 249 break; 250 251 case ALLEGRO_KEY_DOWN: 252 key[KEY_DOWN] = false; 253 break; 254 255 case ALLEGRO_KEY_W: 256 key[KEY_W] = false; 257 break; 258 259 case ALLEGRO_KEY_S: 260 key[KEY_S] = false; 261 break; 262 263 case ALLEGRO_KEY_A: 264 key[KEY_A] = false; 265 break; 266 267 case ALLEGRO_KEY_D: 268 key[KEY_D] = false; 269 break; 270 271 case ALLEGRO_KEY_SPACE: 272 key[KEY_SPACE] = false; 273 break; 274 275 case ALLEGRO_KEY_ESCAPE: 276 doexit = true; 277 break; 278 } 279 } 280 281 if(redraw && al_is_event_queue_empty(event_queue)) { 282 redraw = false; 283 al_set_target_bitmap(cursor); 284 al_clear_to_color(al_map_rgb(0,0,0)); 285 286 al_set_target_bitmap(bouncer); 287 al_clear_to_color(al_map_rgb(0,0,0)); 288 289 290 291 292 al_set_target_bitmap(al_get_backbuffer(display)); 293 al_draw_bitmap(canvas, 0, 0, 0); 294 draw_cursor(cursor_x, cursor_y); 295 draw_ball(bouncer_x, bouncer_y); 296 297 298 299 al_rest(0.02); 300 301 al_flip_display(); 302 } 303 } 304 al_destroy_bitmap(cursor); 305 al_destroy_bitmap(bouncer); 306 al_destroy_bitmap(sand); 307 al_destroy_timer(timer); 308 al_destroy_display(display); 309 al_destroy_event_queue(event_queue); 310 311 return 0; 312}

Arthur Kalliokoski
Second in Command
February 2005
avatar

A C compiler wants the '0x' prefix to denote a hexadecimal representation. And binary integers are just bits, the 0xFFFF whatever, vs 45093 is just a convenience for the human reader.

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

Matthew Leverton
Supreme Loser
January 1999
avatar

Does al_get_pixel return the pixel's colour in "ffffff" format?

I don't know... let's check the documentation. That seems like a reasonable place for the answer to be.

Quote:

ALLEGRO_COLOR al_get_pixel(ALLEGRO_BITMAP *bitmap, int x, int y)

Looks like it returns a structure. Let's see what it looks like.

Quote:

An ALLEGRO_COLOR structure describes a color in a device independant way. Use al_map_rgb et al. and al_unmap_rgb et al. to translate from and to various color representations.

There's the answer.

kenmasters1976
Member #8,794
July 2007

al_get_pixel() returns an ALLEGRO_COLOR. You can use al_unmap_rgb() and then compare the individual color components.

Ninjarobot
Member #12,640
March 2011

I did read that part in the manual but I noticed al_unmap_rgb(and the spin-offs) is void which confuses me on how I am supposed to retrieve the colour let alone compare it. Sorry if I am missing something here.

Matthew Leverton
Supreme Loser
January 1999
avatar

Note that you can click on any of the related discussions in the online manual to see how a function is used with some context.

unsigned char r, g, b;
al_unmap_rgb(col, &r, &g, &b);

if (r == 0xff && g == 0x00 && b == 0x00)
{
}

You could create a function:

bool cmp_color(ALLEGRO_COLOR col, unsigned int h)
{
  unsigned char r, g, b;
  al_unmap_rgb(col, &r, &g, &b);

  return r == ((h >> 16) & 0xff) && 
         g == ((h >> 8) & 0xff) && 
         b == h & 0xff;
}

if (cmp_color(c, 0xff0000))
{
}

Neil Roy
Member #2,229
April 2002
avatar

I used this to check for any colour other than black (all zeros which is transparent in my game). I'm looking for anything other than zero to show a collision (two coloured pixels occupying the same location on overlapping sprites). I chose memcmp(). This won't work in all circumstances, but it worked well here. ALLEGRO_COLOR simply holds RGBA values.

         // sample a pixel from each object
         pixel[0] = al_get_pixel(object1->img, (over_left-object1->x)+cx, (over_top-object1->y)+cy);
         pixel[1] = al_get_pixel(object2->img, (over_left-object2->x)+cx, (over_top-object2->y)+cy);


         // We'll compare the memory of our pixels to our transparent structure and see if we have a
         // collision.  If both memcmp() is true (non-zero) than we have a collision.
         if(memcmp(&pixel[0], &trans, sizeof(trans)) && memcmp(&pixel[1], &trans, sizeof(trans)))
         {
            collision=true;
            goto EXIT;
         }

Go to: