• Create Account

### #ActualLennyLen

Posted 28 February 2013 - 08:21 AM

Let's take a look at the loop you have so far:



while (!key[KEY_ESC]) {
blit(my_pic, screen, 0,0,106,48,404,404);
show_mouse(my_pic);
int i, t;
for (i = 0; i <= 640; i++)
for(t = 0; t <= 480; t++)
//stuck on this area, don't know where to go from here
blit(my_pic, buffer, 0, 0, i, t, SCREEN_W, SCREEN_H);
}


This code is going to keep running continually, so ask yourself "do I want to keep drawing my original image to the buffer over and over again, and why?"  I don't think you do.

Then you have two for loops that cause your image to be redrawn 307200 times, at various positions, a great many of which are outside of the buffer you're drawing them to. Again, this is not something you want to be doing.

So what do you want to be doing?  Well, you want to divide one image into 16 blocks and you've already created a struct to put them in, so lets start by creating an array of these structs with 16 members:



Block blocks[16];


The easiest way to get the 16 pieces is to do two loops to divide the image by four along the width and height. We can then create sub-bitmaps of the original image like so:



int x, y, n = 0, block_w = my_pic->w / 4, block_h = my_pic->h / 4;

for (y = 0; y < 4; y++) {

for (x = 0; x < 4; x++) {

blocks[n].piece = create_sub_bitmap(my_pic, x * block_w, y * block_h, block_w, block_h);
blocks[n].position = n;
n++;
}
}


For now, I've left the position numbers sequential. You can randomize them yourself later to mix up the pieces.

Whenever you want to draw your pieces in the positions they're in you can do this (this example draws them to the top-left corner of the buffer):



for (y = 0; y < 4; y++) {

for (x = 0; x < 4; x++)
blit(blocks[y * 4 + x].piece, buffer, 0, 0, x * block_w, y * block_h, block_w, block_h);

}


I would have two buffers myself, one for the whole screen, and one for the play area. I would then blit all the pieces to the play area, from the top left, then I would blit this to your screen buffer. This way if you want to change where the play area is on your screen at a later point, there will be less code to change.

The following code puts all this together and allows to load your image, divide it into the 16 parts and then draw the 16 pieces. I'll let you take it form here to decide what to do next. If you need help after giving it a go yourself, feel free to ask.



#include <allegro.h>

void init();
void deinit();

typedef struct{
BITMAP *piece;  //this would be a piece of the picture (1 of the 16 squares)
int position;
}Block;

int main() {
init();

BITMAP *buffer, *play_buffer, *my_pic;
PALETTE palette;
clear_to_color(screen, makecol(255, 255, 255));

buffer = create_bitmap(SCREEN_W, SCREEN_H);
play_buffer = create_bitmap(my_pic->w, my_pic->h);

if(my_pic==NULL)
{
set_gfx_mode(GFX_TEXT, 0,0,0,0);
return 1;
}

Block blocks[16];

int x, y, n = 0, block_w = my_pic->w / 4, block_h = my_pic->h / 4;

for (y = 0; y < 4; y++) {

for (x = 0; x < 4; x++) {

blocks[n].piece = create_sub_bitmap(my_pic, x * block_w, y * block_h, block_w, block_h);
blocks[n].position = n;
n++;
}
}

for (y = 0; y < 4; y++) {

for (x = 0; x < 4; x++)
blit(blocks[y * 4 + x].piece, play_buffer, 0, 0, x * block_w, y * block_h, block_w, block_h);

}

// blit the play area bufer to the middle of the screen buffer
blit(play_buffer, buffer, 0, 0, (buffer->w - play_buffer->w) / 2, (buffer->h - play_buffer->h) / 2, play_buffer->w, play_buffer->h);
// then blit the screen buffer to the actual screen
blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);

for (n = 0; n <16; n++)
destroy_bitmap(blocks[n].piece);
destroy_bitmap(my_pic);
deinit();
return 0;
}
END_OF_MAIN()

void init() {
int depth, res;
allegro_init();
depth = desktop_color_depth();
if (depth == 0) depth = 32;
set_color_depth(depth);
res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
if (res != 0) {
allegro_message(allegro_error);
exit(-1);
}

install_timer();
install_keyboard();
install_mouse();
}

void deinit() {
clear_keybuf();
}

### #1LennyLen

Posted 28 February 2013 - 08:20 AM

Let's take a look at the loop you have so far:

while (!key[KEY_ESC]) {
blit(my_pic, screen, 0,0,106,48,404,404);
show_mouse(my_pic);
int i, t;
for (i = 0; i <= 640; i++)
for(t = 0; t <= 480; t++)
//stuck on this area, don't know where to go from here
blit(my_pic, buffer, 0, 0, i, t, SCREEN_W, SCREEN_H);
}


This code is going to keep running continually, so ask yourself do I want to keep drawing my original image to the buffer over and over again, and why?  I don't think you do.

Then you have two for loops that cause your image to be redrawn 307200 times, at various positions, a great many of which are outside of the buffer you're drawing them to. Again, this is not something you want to be doing.

So what do you want to be doing?  Well, you want to divide one image into 16 blocks and you've already created a struct to put them in, so lets start by creating an array of these structs with 16 members:

Block blocks[16];


The easiest way to get the 16 pieces is to do two loops to divide the image by four along the width and height. We can then create sub-bitmaps of the original image like so:

	int x, y, n = 0, block_w = my_pic->w / 4, block_h = my_pic->h / 4;

for (y = 0; y < 4; y++) {

for (x = 0; x < 4; x++) {

blocks[n].piece = create_sub_bitmap(my_pic, x * block_w, y * block_h, block_w, block_h);
blocks[n].position = n;
n++;
}
}


For now, I've left the position numbers sequential. You can randomize them yourself later to mix up the pieces.

Whenever you want to draw your pieces in the positions they're in you can do this (this example draws them to the top-left corner of the buffer):

for (y = 0; y < 4; y++) {

for (x = 0; x < 4; x++)
blit(blocks[y * 4 + x].piece, buffer, 0, 0, x * block_w, y * block_h, block_w, block_h);

}


I would have two buffers myself, one for the whole screen, and one for the play area. I would then blit all the pieces to the play area, from the top left, then I would blit this to your screen buffer. This way if you want to change where the play area is on your screen at a later point, there will be less code to change.

The following code puts all this together and allows to load your image, divide it into the 16 parts and then draw the 16 pieces. I'll let you take it form here to decide what to do next. If you need help after giving it a go yourself, feel free to ask.

#include <allegro.h>

void init();
void deinit();

typedef struct{
BITMAP *piece;  //this would be a piece of the picture (1 of the 16 squares)
int position;
}Block;

int main() {
init();

BITMAP *buffer, *play_buffer, *my_pic;
PALETTE palette;
clear_to_color(screen, makecol(255, 255, 255));

buffer = create_bitmap(SCREEN_W, SCREEN_H);
play_buffer = create_bitmap(my_pic->w, my_pic->h);

if(my_pic==NULL)
{
set_gfx_mode(GFX_TEXT, 0,0,0,0);
return 1;
}

Block blocks[16];

int x, y, n = 0, block_w = my_pic->w / 4, block_h = my_pic->h / 4;

for (y = 0; y < 4; y++) {

for (x = 0; x < 4; x++) {

blocks[n].piece = create_sub_bitmap(my_pic, x * block_w, y * block_h, block_w, block_h);
blocks[n].position = n;
n++;
}
}

for (y = 0; y < 4; y++) {

for (x = 0; x < 4; x++)
blit(blocks[y * 4 + x].piece, play_buffer, 0, 0, x * block_w, y * block_h, block_w, block_h);

}

// blit the play area bufer to the middle of the screen buffer
blit(play_buffer, buffer, 0, 0, (buffer->w - play_buffer->w) / 2, (buffer->h - play_buffer->h) / 2, play_buffer->w, play_buffer->h);
// then blit the screen buffer to the actual screen
blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);

for (n = 0; n <16; n++)
destroy_bitmap(blocks[n].piece);
destroy_bitmap(my_pic);
deinit();
return 0;
}
END_OF_MAIN()

void init() {
int depth, res;
allegro_init();
depth = desktop_color_depth();
if (depth == 0) depth = 32;
set_color_depth(depth);
res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
if (res != 0) {
allegro_message(allegro_error);
exit(-1);
}

install_timer();
install_keyboard();
install_mouse();
}

void deinit() {
clear_keybuf();
}

PARTNERS