|
This thread is locked; no one can reply to it. |
1
2
|
Allegro5 Cant get Tilemaps to work. |
Kris Asick
Member #1,424
July 2001
|
_tile_sheet = VZ_LoadBitmap("Textures","vz_tiles_1.png",ALLEGRO_VIDEO_BITMAP|ALLEGRO_MIN_LINEAR|ALLEGRO_MAG_LINEAR|ALLEGRO_NO_PREMULTIPLIED_ALPHA); if (_tile_sheet == NULL) FatalErrorMsg(8,display); for (z = 0; z < VZ_MAX_FRAMES; z++) if ((tile_bmp[z] = al_create_sub_bitmap(_tile_sheet,(z%51)*20+2,(z/51)*20+2,16,16)) == NULL) FatalErrorMsg(9,display); This is my tile loading code. Typically, you want to modulo one coordinate by the number of tiles per col/row, and divide the other. In my case, each column goes up by 1 and each row by 51, so I modulo the X by 51 and divide the Y by 51, then just multiply each by the space between each tile. I also extend my tiles by 2 pixels in both directions since I have to be prepared to scale them. In fact, this a good practice to do with ALL 2D graphics using hardware acceleration that need to be joined together out of pieces, like status bars and whatnot. --- Kris Asick (Gemini) |
Audric
Member #907
January 2001
|
Kris, I see you use things like FatalErrorMsg(8,display); apparently with 8 or 9 to get information about the point where the problem was raised. #define FATAL_ERR Error_handler(__FILE__, __LINE__)
Then you can use the macro any number of time, each occurence will pass a different filename + line number. Edit: GCC additionally provides _func_ which is the function's name. |
Angeljruiz
Member #14,553
September 2012
|
Thats understandable kris :p Thanks for introducing me to a interesting concept tho @Enclave what do you mean? |
Kris Asick
Member #1,424
July 2001
|
Audric said: In case you don't know, compilers provide macros like FILE and LINE that expand into source filename and line number. Didn't know that... but it wouldn't really help me much anyways since I can actually use the MSVC10 debugger with A5 projects and the FatalErrorMsg() routine I developed is intended for end-users to know what went wrong if something does go wrong in the completed product. My only problem at the moment is that the popups produced by the FatalErrorMsg() routine are appearing BEHIND the Allegro window, and when I try to shut the program down with an exit() call it's turning Allegro off before calling my additional uninitialization routines, which crashes the program. Meh, I'll figure out how to make that all work soon enough, it's not a high priority right now. --- Kris Asick (Gemini) |
Raidho36
Member #14,628
October 2012
|
Why don't use allegro native dialogs? They work fine. Unless there's a crash already happened, of course. |
Kris Asick
Member #1,424
July 2001
|
Raidho36 said: Why don't use allegro native dialogs? They work fine. Unless there's a crash already happened, of course. I am. void FatalErrorMsg (int errornum, ALLEGRO_DISPLAY *display) { if (display != NULL) al_show_mouse_cursor(display); al_show_native_message_box(display, "Vectorzone - Fatal Error", _errormsg[errornum], NULL, NULL, ALLEGRO_MESSAGEBOX_ERROR); exit(1); }
--- Kris Asick (Gemini) |
EnClave
Member #14,661
October 2012
|
this is my code to load tiles right now, BlockSize = 64 1
2void LoadMap(const char *filename, std::vector< std::vector <int> > &map)
3{
4 std::ifstream openfile(filename);
5 if(openfile.is_open())
6 {
7 std::string line, value;
8 int space;
9
10 while(!openfile.eof())
11 {
12 std::getline(openfile, line);
13
14 if(line.find("[TileSet]") != std::string::npos)
15 {
16 state = TileSet;
17 continue;
18 }
19 else if (line.find("[Map]") != std::string::npos)
20 {
21 state = Map;
22 continue;
23 }
24
25 switch(state)
26 {
27 case TileSet:
28 if(line.length() > 0)
29 tileSet = al_load_bitmap(line.c_str());
30 break;
31 case Map:
32 std::stringstream str(line);
33 std::vector<int> tempVector;
34
35 while(!str.eof())
36 {
37 std::getline(str, value, ' ');
38 if(value.length() > 0)
39 tempVector.push_back(atoi(value.c_str()));
40 }
41 map.push_back(tempVector);
42 break;
43 }
44 }
45 }
46 else
47 {
48 }
49}
50
51
52
53 //%%%%% RITAR UPP TILES %%%%%//
54
55void DrawMap(std::vector <std::vector <int> > map)
56{
57 for(int i = 0; i < map.size(); i++)
58 {
59 for(int j = 0; j < map[i].size(); j++)
60 {
61al_draw_bitmap_region(tileSet, map[i][j] * BlockSize, 0, BlockSize, 64, j * BlockSize,
62 i * BlockSize, NULL);
63 }
64 }
65}
and I'm kind of loading the pngs from the .txt files, like this: my problem is tho that in my Tilesheet my program can only load tiles horizontal right now my .png file is 1088x64 because it can only load horizontal but now i have runned out of space in the .png file, i want it to be example 1088x128 and the program can load the tiles on the second row aswell. |
Angeljruiz
Member #14,553
September 2012
|
Well in my code i fix that by keeping the x value and increasing it every time it reads a value and once it gets to the maximum tiles per row or whatever i reset it to 0 then increment the y value. Why dont you just do that ? :p |
EnClave
Member #14,661
October 2012
|
The thing was i couldent implement your "Loading maps code" into my own code and i dont want to like straight copy your code because i dont recognize anything there hehe, hmm i really have water above my head right now, this is extremly complicated i might need to change this code, because i followed some guys tutorial but i dont understand it so well, damn, i just want a nice working Mapload function |
Angeljruiz
Member #14,553
September 2012
|
But mine is so much simpler than yours, albeit maybe a little bit more cryptic looking X) int tiles[40][30]; I then open up a file then keep looping until it is the end of the file, keeping track of how many values have been stored, once 40 values (the number of how many tiles per row) has been stored it must mean that its time to increase the y value because all the tiles in that row are filled up. //openfile bla bla bla while (File >> temp) //loops until end { Tiles[x][y] = temp; x++; //next tile in the row if (x == TILES_PER_ROW /*40*/) //all the rows are filled up { x = 0; //reset it y++; //next column } }
Then, as ive already explained, i just make a bitmap out of the tiles then i just draw the bitmap as you would with any other bitmap. |
EnClave
Member #14,661
October 2012
|
Yeah, actully i borrowed your code and implemented in my code, it runs good but now it just creates a bitmap and only using the: BitTile = al_create_bitmap(800, 600); so it doesent matter what i do in my .txt document it takes like the first tile in my png file and just copys it to 800 x 600, here is a screenshot do you know why it does that? |
Angeljruiz
Member #14,553
September 2012
|
Emm im not sure, maybe bad input? I know when you give bad input it just keeps repeating the last good input. Also check the updateBitMap function and make sure its actually drawing the tile that the input corrisponds to. |
EnClave
Member #14,661
October 2012
|
Yeah this is extremly wierd can it have something to do with i changed your [40][30] to [100][100] because i want to make bigger maps? anyway with some touching of the code i end up with this, also there is the png file im using and also the update code, hmm |
Kris Asick
Member #1,424
July 2001
|
One of the ways I debug a problem like this is to actually do all the logic, step by step, in my head, following along in my code. You can either do this in a forwards motion to determine what the result should be, or a backwards motion to determine what you need to start with to get the result you want. However, I just noticed something obvious: You're only going up by increments of 32 when pulling tile references, not 64 like your tile sizes are. I also noticed that tile #0 is a brick wall. Usually it's best to make tile #0 your empty, undefined tile for sake of if statements. --- Kris Asick (Gemini) |
EnClave
Member #14,661
October 2012
|
I actully havent had any luck on the Working TileMap yet, its still doesent update as it should do, it only creates a wierd big Tile of 800, 600 because its set like that in the BitTile = al_create_bitmap(800, 600); Its extremly wierd, i dont know what to do anymore ive been experimenting with my code changed alot of values, switching locations of the updates but still nothing, just does the same thing, if anyone with sharper eyes and knowledge could spot something out i would really appreciate it, been working with this for 2 days now withouth any luck, also when i have Screen scrolling on my Game my Mouse event doesent work either, it works fine if i stay in place in the beginning of the game but when i start to move it doesent update as it should so it just lacks behind all the time, here is my code if anyone have the time to just look over it a quickie! 1
2#include<fstream>
3#include<string>
4#include<sstream>
5#include<iostream>
6#include<allegro5\allegro5.h>
7#include<allegro5\allegro_native_dialog.h>
8#include<allegro5\allegro_primitives.h>
9#include<allegro5\allegro_image.h>
10
11using namespace std;
12
13int loadmap(int Tiles[][30]);
14void updateBitTile(int Tiles[][30], ALLEGRO_BITMAP* BitTile, ALLEGRO_BITMAP* tiles, ALLEGRO_DISPLAY* display);
15bool Collision(int Tiles[][30], const int& x, const int& y);
16
17
18#define ScreenWidth 1024
19#define ScreenHeight 768
20
21int pos_y = ScreenWidth / 2;
22int pos_x = ScreenHeight / 2;
23
24
25// %%%%% COLLISION OF MOVEMENT HITTING BOX %%%%%//
26bool Collision(float x, float y, float ex, float ey, int width, int height)
27{
28 if(x + width < ex || x > ex + width || y + height < ey || y > ey + height)
29 {
30 return false;
31 }
32 return true;
33}
34
35int state = NULL;
36
37// %%%%% CAMERA SCROLLING %%%%%//
38
39void cameraUpdate(float *cameraPosition, float x, float y, int width, int height)
40{
41 cameraPosition[0] = -(ScreenWidth / 2) + (x + width / 2);
42 cameraPosition[1] = -(ScreenWidth / 2) + (y + height / 2);
43
44 if(cameraPosition[0] < 0)
45 cameraPosition[0] = 0;
46 if(cameraPosition[1] < 0)
47 cameraPosition[1] = 0;
48
49}
50
51
52int main()
53{
54 // %%%%% IMPORTANT SETTINGS %%%%%//
55 ALLEGRO_DISPLAY *display;
56 const float FPS = 60.0;
57 const float frameFPS = 10.0;
58 enum Direction { DOWN, LEFT, RIGHT, UP };
59
60 // %%%%% ERROR CODES, ALLEGRO AND DISPLAY %%%%%//
61 if(!al_init())
62 al_show_native_message_box(NULL, "Error", NULL, "Could not Initialize Allegro", NULL, NULL);
63
64 display = al_create_display(ScreenWidth, ScreenHeight);
65
66 if(!display)
67 al_show_native_message_box(NULL, "Error", NULL, "Could not create Allegro Display", NULL, NULL);
68
69
70 // %%%%% WINDOW SETTINGS %%%%%//
71
72 al_set_new_display_flags(ALLEGRO_WINDOWED);
73 al_set_window_position(display, 200, 200);
74 al_set_window_title(display, "PRE-alpha Test");
75
76 ALLEGRO_COLOR playerColor = al_map_rgb(255, 0, 255);
77
78 // %%%%% Movement SPEED %%%%%//
79 bool done = false, draw = true, active = false;
80 float x = 512, y = 384, moveSpeed = 3;
81 int dir = DOWN, sourceX = 64, sourceY = 96;
82 float cameraPosition[2] = { 0, 0 };
83
84 // %%%%% ADDONS %%%%%//
85 al_init_primitives_addon();
86 al_install_keyboard();
87 al_init_primitives_addon();
88 al_install_mouse();
89 al_init_image_addon();
90
91
92 // %%%%% PNGS AND OTHER THINGS TO INSTALL %%%%%//
93
94 ALLEGRO_EVENT_QUEUE* queue = NULL;
95 ALLEGRO_BITMAP *enemy1 = al_load_bitmap("Zanm1.png");
96 ALLEGRO_BITMAP *player = al_load_bitmap("player.png");
97 al_convert_mask_to_alpha(player, al_map_rgb(255, 0, 255));
98 al_convert_mask_to_alpha(enemy1, al_map_rgb(255, 0, 255));
99
100 queue = al_create_event_queue();
101 ALLEGRO_KEYBOARD_STATE KeyState;
102 ALLEGRO_TRANSFORM camera;
103 ALLEGRO_BITMAP* BitTile = NULL;
104 ALLEGRO_BITMAP* tiles = NULL;
105
106
107 tiles = al_load_bitmap("test.png");
108 if (!tiles)
109 {
110 cout << "Bad Tiles.png\n";
111 return -1;
112 }
113
114 int Counter = 0;
115 int OffsetX = 0;
116 int OffsetY = 0;
117
118 int Tiles[40][30];
119
120 for (int x = 0; x < 40; ++x)
121 {
122 for (int y = 0; y < 30; ++y)
123 {
124 Tiles[x][y] = 0;
125 }
126 }
127
128 if (loadmap(Tiles) == -1)
129 {
130 return -1;
131 }
132 BitTile = al_create_bitmap(800, 600);
133
134 updateBitTile(Tiles, BitTile, tiles, display);
135
136
137
138 // %%%%% EVENTS installation & TIMERS %%%%%//
139 ALLEGRO_TIMER *timer = al_create_timer(1.0 / FPS);
140 ALLEGRO_TIMER *frametimer = al_create_timer(1.0 / frameFPS);
141
142 ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
143 al_register_event_source(event_queue, al_get_keyboard_event_source());
144 al_register_event_source(event_queue, al_get_timer_event_source(timer));
145 al_register_event_source(event_queue, al_get_timer_event_source(frametimer));
146 al_register_event_source(event_queue, al_get_display_event_source(display));
147 al_register_event_source(event_queue, al_get_mouse_event_source());
148
149 // %%%%% TIMER, NO installations UNDER THIS %%%%%//
150 al_start_timer(timer);
151 al_start_timer(frametimer);
152
153 // %%%%% Beginning of Events %%%%%//
154 while(!done)
155 {
156 ALLEGRO_EVENT events;
157 al_wait_for_event(event_queue, &events);
158 al_get_keyboard_state(&KeyState);
159
160 // %%%%% TILE MAP IN THE EVENT & TIMER CODE %%%%%//
161
162 if(events.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
163 {
164 done = true;
165 }
166 else if (events.type == ALLEGRO_EVENT_TIMER)
167 {
168
169 }
170
171 // %%%%% KEYBOARD INPUT AND EVENTS AND PLAYER IMAGE AND CAMERA SCROLLING FOR CHARACTER %%%%%//
172
173 if(events.type == ALLEGRO_EVENT_KEY_UP)
174 {
175 switch(events.keyboard.keycode)
176
177 {
178 case ALLEGRO_KEY_ESCAPE:
179 done = true;
180 }
181 }
182
183
184 else if(events.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
185 {
186 done = true;
187 }
188
189 // %%%%% MOUSE %%%%%//
190 else if(events.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
191
192 {
193 if(events.mouse.button & 1)
194 draw = !draw;
195 else if (events.mouse.button & 2)
196 draw = !draw;
197 }
198
199 else if(events.type == ALLEGRO_EVENT_MOUSE_AXES)
200 {
201 pos_x = events.mouse.x;
202 pos_y = events.mouse.y;
203 }
204
205 // %%%%% KEYBOARD %%%%%//
206 else if (events.type = ALLEGRO_EVENT_TIMER)
207 {
208 if(events.timer.source == timer)
209 {
210 active = true;
211 if(al_key_down(&KeyState, ALLEGRO_KEY_S))
212 {
213 y += moveSpeed;
214 dir = DOWN;
215 }
216 else if(al_key_down(&KeyState, ALLEGRO_KEY_W))
217 {
218 y -= moveSpeed;
219 dir = UP;
220 }
221 else if(al_key_down(&KeyState, ALLEGRO_KEY_D))
222 {
223 x += moveSpeed;
224 dir = RIGHT;
225 }
226 else if(al_key_down(&KeyState, ALLEGRO_KEY_A))
227 {
228 x -= moveSpeed;
229 dir = LEFT;
230 }
231
232 else
233 active = false;
234
235 if(Collision(x, y, 400, 400, 32, 32))
236 {
237 if(dir == 0)
238 y -= moveSpeed;
239 else if(dir == 1)
240 x += moveSpeed;
241 else if(dir == 2)
242 x -= moveSpeed;
243 else if(dir == 3)
244 y += moveSpeed;
245 }
246
247
248 cameraUpdate(cameraPosition, x, y, 96, 64);
249 al_identity_transform(&camera);
250 al_translate_transform(&camera, -cameraPosition[0], -cameraPosition[1]);
251 al_use_transform(&camera);
252
253 }
254
255
256 else if(events.timer.source == frametimer)
257 {
258
259 if(active)
260 sourceX += al_get_bitmap_width(player) / 4;
261
262 else
263 sourceX = 64;
264
265 if(sourceX >= al_get_bitmap_width(player))
266 sourceX = 0;
267
268 sourceY = dir;
269 }
270
271 draw = true;
272 }
273
274
275 if(al_event_queue_is_empty(queue) &&draw)
276
277 {
278
279 al_clear_to_color(al_map_rgb(0, 0, 0));
280 al_draw_bitmap(BitTile, 0-OffsetX, 0-OffsetY, NULL);
281 al_draw_bitmap_region(enemy1, 0, 0, 92, 150, 400, 400, NULL);
282 al_draw_bitmap_region(player, sourceX, dir * al_get_bitmap_height(player) / 4, 64, 96, x, y, NULL);
283 al_draw_filled_rectangle(pos_x, pos_y, pos_x + 30, pos_y + 30, al_map_rgb(150, 150, 150));
284
285 al_flip_display();
286 }
287
288
289
290 // %%%%% GAME UI SHELL %%%%%//
291 /*al_draw_rectangle(1, 1, 800, 100, al_map_rgb(255, 50, 50), 9.0);*/
292
293 // %%%%% Destroy ENDING %%%%%//
294 }
295 al_destroy_display(display);
296 al_destroy_timer(timer);
297 al_destroy_bitmap(player);
298 al_destroy_bitmap(enemy1);
299 al_destroy_event_queue(event_queue);
300 al_destroy_bitmap(tiles);
301 al_destroy_bitmap(BitTile);
302
303 return 0;
304}
305
306int loadmap(int Tiles[][30])
307{
308 int x(0), y(0);
309 int temp;
310 ifstream Map("Map1.txt");
311 if (Map.is_open())
312 {
313 while(Map >> temp)
314 {
315 Tiles[x][y] = temp;
316 ++x;
317 if (x == 40)
318 {
319 x = 0;
320 ++y;
321 }
322 }
323 } else {
324 cout << "Bad Map1.txt\n";
325 return -1;
326 }
327 Map.close();
328 return 0;
329}
330
331void updateBitTile(int Tiles[][30], ALLEGRO_BITMAP* BitTile, ALLEGRO_BITMAP* tiles, ALLEGRO_DISPLAY* display)
332{ //creates a bitmap from tiles instead of drawing all tiles seperately, fucking awesome ryte?
333 al_set_target_bitmap(BitTile);
334 for (int x = 0; x < 40; ++x)
335 {
336 for (int y = 0; y < 30; ++y)
337 {
338 /*switch (Tiles[x][y])
339 {
340 case 0:
341 al_draw_bitmap_region(tiles, 0, 0, 32, 32, x*32, y*32, NULL);
342 break;
343 case 1:
344 al_draw_bitmap_region(tiles, 32, 0, 32, 32, x*32, y*32, NULL);
345 break;
346 } */
347 al_draw_bitmap_region(tiles, Tiles[x][y]*32, 0, 32, 32, x*32, y*32, NULL);
348 }
349 }
350 al_set_target_bitmap(al_get_backbuffer(display));
351
352 // al_save_bitmap("Screenshot.png", BitTile);
353}
354bool Collision(int Tiles[][30], const int& x, const int& y)
355{
356 if (Tiles[x][y] == 0)
357 return true;
358 return false;
359}
|
Kris Asick
Member #1,424
July 2001
|
When I get EXTREMELY stuck with a problem like this, I like to add keyboard-sensitive stepping in my code. In your case, what this would mean is adding some routines to your tilemap rendering code so that it only draws one tile, shows the result on-screen, then waits for you to press a key. Then it draws the next tile, waits for a keypress, repeat until you press a specific key to signal the program to stop running. This would at least let you visually see how your tiles are being rendered one by one and you may be able to tell what the trouble is as a result. --- Kris Asick (Gemini) |
J-Gamer
Member #12,491
January 2011
|
You don't need extra code to do that, just a debugger " There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo |
|
1
2
|