Jump to content

  • Log In with Google      Sign In   
  • Create Account

Allegro problems with tiles


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 PlayswithSquirrels   Members   -  Reputation: 102

Like
0Likes
Like

Posted 27 February 2013 - 09:03 PM

I'm relatively new at programming and am I'm making a 16-puzzle on allegro, and got a little stuck as to the tiles. I got as far as creating the structure, but as for the fitting the matrix in the loop I'm stumped. My goal is to break the image into 16 separate squares, with 1bit of distance between each, so I can see each of them defined. This is what I have so far.

#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;
	BITMAP *my_pic;
	PALETTE palette;
	clear_to_color(screen, makecol(255, 255, 255));

	buffer = create_bitmap(404,404);
	my_pic = load_bitmap("chihuahua2.bmp", palette);
		
	
	if(my_pic==NULL)
	{
		set_gfx_mode(GFX_TEXT, 0,0,0,0);
		allegro_message("Can't load chihuahua.bmp");
		return 1;
	}

	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);
	}
	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();
}

Any and all feedback is welcome.


Edited by PlayswithSquirrels, 27 February 2013 - 09:05 PM.


Sponsor:

#2 LennyLen   Crossbones+   -  Reputation: 4023

Like
1Likes
Like

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));

	my_pic = load_bitmap("chihuahua2.bmp", palette);
	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);
		allegro_message("Can't load chihuahua.bmp");
		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);
        readkey();

        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();
}

Edited by LennyLen, 28 February 2013 - 08:21 AM.


#3 PlayswithSquirrels   Members   -  Reputation: 102

Like
0Likes
Like

Posted 28 February 2013 - 06:00 PM

Thanks!!! You were a big help! smile.png






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS