|
|
This thread is locked; no one can reply to it.
|
1
2
|
| [A5] Pointless Thread about what I have been attempting |
|
Specter Phoenix
Member #1,425
July 2001
|
Just sitting here goofing around with things I've not really dabbled with. I attempted tile mapping for the first time this morning. Tile sheet: Screenshot of Test Running: Code for it (used ugly globals and terrible practices, but I was in a hurry so I did it sporadic) :
1#include <allegro5/allegro.h>
2#include <allegro5/allegro_image.h>
3#include <fstream>
4#include <vector>
5#include <iostream>
6
7using namespace std;
8
9const int BLOCK_SIZE = 32;
10vector <ALLEGRO_BITMAP*> tiles;
11
12int loadCounterX = 0, loadCounterY = 0, mapSizeX, mapSizeY;
13
14void loadMap(const char* filename, int map[][100])
15{
16 ifstream openfile(filename);
17 if(openfile.is_open())
18 {
19 openfile >> mapSizeX >> mapSizeY;
20 while(!openfile.eof())
21 {
22 openfile >> map[loadCounterX][loadCounterY];
23 loadCounterX++;
24
25 if(loadCounterX >= mapSizeX)
26 {
27 loadCounterX = 0;
28 loadCounterY++;
29 }
30 }
31 }
32 else
33 {
34 cout << "Cannot open map.txt. " << endl;
35 }
36}
37
38void drawMap(int map[][100],vector<ALLEGRO_BITMAP*>spr);
39
40int main()
41{
42 al_init();
43 al_install_keyboard();
44 al_init_image_addon();
45
46 int map[100][100];
47 loadMap("map.txt", map);
48
49 ALLEGRO_BITMAP *sprite;
50 ALLEGRO_DISPLAY *display;
51 ALLEGRO_EVENT_QUEUE *event_queue;
52 ALLEGRO_TIMER *timer;
53
54 const int FPS = 60;
55 const int SCREEN_W = 640;
56 const int SCREEN_H = 480;
57
58 timer = al_create_timer(1.0/FPS);
59 display = al_create_display(SCREEN_W, SCREEN_H);
60 event_queue = al_create_event_queue();
61
62 sprite = al_load_bitmap("tilesheet.png");
63 int tileOffset = 0;
64 for(int i = 0; i < 2; i++)
65 {
66 for(int j = 0; j < 2; j++)
67 {
68 tiles.push_back(al_create_sub_bitmap(sprite, i * BLOCK_SIZE, j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE));
69 tileOffset = tileOffset + BLOCK_SIZE;
70 }
71 }
72
73 bool redraw = true;
74 bool doexit = false;
75
76 al_register_event_source(event_queue, al_get_display_event_source(display));
77 al_register_event_source(event_queue, al_get_timer_event_source(timer));
78 al_register_event_source(event_queue, al_get_keyboard_event_source());
79
80 al_clear_to_color(al_map_rgb(0, 0, 0));
81 al_flip_display();
82 al_start_timer(timer);
83
84 while(!doexit)
85 {
86 ALLEGRO_EVENT ev;
87 al_wait_for_event(event_queue, &ev);
88
89 if(ev.type == ALLEGRO_EVENT_TIMER)
90 {
91 redraw = true;
92 }
93 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
94 {
95 break;
96 }
97 else if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
98 {
99 switch(ev.keyboard.keycode)
100 {
101
102 }
103 }
104 else if(ev.type == ALLEGRO_EVENT_KEY_UP)
105 {
106 switch(ev.keyboard.keycode)
107 {
108 case ALLEGRO_KEY_ESCAPE:
109 doexit = true;
110 break;
111 }
112 }
113
114 if(redraw && al_is_event_queue_empty(event_queue))
115 {
116 redraw = false;
117 al_clear_to_color(al_map_rgb(0, 0, 0));
118 drawMap(map, tiles);
119 al_flip_display();
120 }
121 }
122
123 return 0;
124
125}
126
127void drawMap(int map[][100], vector<ALLEGRO_BITMAP*>spr)
128{
129 for(int i = 0; i < mapSizeX; i++)
130 {
131 for(int j = 0; j < mapSizeY; j++)
132 {
133 if(map[i][j] == 0)
134 al_draw_bitmap(spr[0], i * BLOCK_SIZE, j * BLOCK_SIZE, 0);
135 if(map[i][j] == 1)
136 al_draw_bitmap(spr[1], i * BLOCK_SIZE, j * BLOCK_SIZE, 0);
137 if(map[i][j] == 2)
138 al_draw_bitmap(spr[2], i * BLOCK_SIZE, j * BLOCK_SIZE, 0);
139 if(map[i][j] == 3)
140 al_draw_bitmap(spr[3], i * BLOCK_SIZE, j * BLOCK_SIZE, 0);
141 }
142 }
143}
Just can't figure why it seems to have the grey lines across it. Not bad for a first time though. Even have a semi-working game done too, Global Destruction. I have to tweak some of the things in the code and remove a couple of things, then I'll post the code here too.
|
|
Trent Gamblin
Member #261
April 2000
|
See what you can do SP? Good job. I think the problem is that your grass tile goes one line into the grey part (guessing that because there's also a black pixel on the edge where the diagonal black lines top pixel is in the tile sheet.)
|
|
weapon_S
Member #7,859
October 2006
|
Depressing Specter Phoenix said: Even have a semi-working game done too, Global Destruction. Already the name's good. References
|
|
pkrcel
Member #14,001
February 2012
|
That seems actually as trentsays, you're having pixels bleed from the neighboring tiles (the gray ones in the grass and the black ones in the frame). Still, I can't get WHY from your code....to me seems spot on for the task It is unlikely that Google shares your distaste for capitalism. - Derezo |
|
LennyLen
Member #5,313
December 2004
|
p.s. if(map[i][j] == 0) al_draw_bitmap(spr[0], i * BLOCK_SIZE, j * BLOCK_SIZE, 0); if(map[i][j] == 1) al_draw_bitmap(spr[1], i * BLOCK_SIZE, j * BLOCK_SIZE, 0); if(map[i][j] == 2) al_draw_bitmap(spr[2], i * BLOCK_SIZE, j * BLOCK_SIZE, 0); if(map[i][j] == 3) al_draw_bitmap(spr[3], i * BLOCK_SIZE, j * BLOCK_SIZE, 0); could be replaced with: al_draw_bitmap(spr[map[i][j]], i * BLOCK_SIZE, j * BLOCK_SIZE, 0);
|
|
Specter Phoenix
Member #1,425
July 2001
|
@LennyLen As for the images, I'll have to try the 0.5 offset because I noticed the grey walls going up and down had a black speck on each one. So upon noticing that I decided to draw the grass and vertical wall on top of the map and found that it is actually on the top of each texture and not the bottom like we thought. {"name":"606880","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/0\/c0388ad27e6ec1693aa4bb5f864233c4.png","w":802,"h":632,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/0\/c0388ad27e6ec1693aa4bb5f864233c4"} [REVISION]
|
|
naraku9333
Member #14,728
November 2012
|
Your code works for me unchanged with this map 10 10 3 1 1 1 3 1 1 1 1 3 2 0 0 0 2 0 0 0 0 2 2 0 0 0 2 0 0 0 0 2 2 0 0 0 2 0 0 0 0 2 3 1 1 1 3 1 1 1 1 3 2 0 0 0 2 0 0 0 0 2 2 0 0 0 2 0 0 0 0 2 2 0 0 0 2 0 0 0 0 2 2 0 0 0 2 0 0 0 0 2 3 1 1 1 3 1 1 1 1 3
{"name":"47058783.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/a\/7ab2d353a3840d48c502494acffa37e0.png","w":640,"h":508,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/a\/7ab2d353a3840d48c502494acffa37e0"}
|
|
Specter Phoenix
Member #1,425
July 2001
|
Odd, I copied and pasted your map text and still get the grey lines. Maybe it is just an issue with Ubuntu 12.04 and Allegro 5.1.4 {"name":"606882","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/1\/51b500b33131b4309c9e4e09db97059f.png","w":802,"h":632,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/1\/51b500b33131b4309c9e4e09db97059f"}
|
|
Kris Asick
Member #1,424
July 2001
|
I was gonna post a response earlier, until I realized I didn't have a solution. The problem is a rounding error with the nearest-neighbour texture filtering going on, combined with how Allegro offsets pixels by 0.5f by default so that the middle of each pixel is drawn. Apparently, your video card is rounding the vertical result in the wrong direction. You MIGHT be able to solve the problem by offseting your pixels by tiny decimal amounts, like 0.0001f, but this could also affect other players. Adding in linear filtering would theoretically solve this problem too, but linear filtering in Allegro works with the scaling system so I have no idea if it will apply properly to an unscaled image, nor which mode you need to use to accomplish that, MIN or MAG. You may wanna go through your graphics card settings instead first to see if there's any texture related options that could be to blame. --- Kris Asick (Gemini) |
|
Peter Wang
Member #23
April 2000
|
Kris Asick said: Allegro offsets pixels by 0.5f by default It don't.
|
|
Kris Asick
Member #1,424
July 2001
|
It doesn't? Where the heck did I read that then... ...or wait... that would actually make more sense to Specter's problem because his textures are starting up by 1 pixel, so if for some obscure reason it's rounding a precise value of 0 down to the next lowest pixel... Hmm... maybe adding 0.0001f really would solve all the problems? --- Kris Asick (Gemini) |
|
Trent Gamblin
Member #261
April 2000
|
I had a video card that would do something similar with the top left dot of every tile drawn... I updated my drivers and that fixed it.
|
|
Specter Phoenix
Member #1,425
July 2001
|
I'm using Gimp 2.8 to do the images and I thought it started its pixels at 0. Either way I tried doing an offset of 0.5 and 1 and it didn't fix it. Sadly my laptop is an old piece of shit and has (according to Sysinfo): Quote: Intel Corporation Mobile GM965/GL960 Integrated Graphics Controller so I don't know if a new driver would help or even if they have a new driver.
|
|
Neil Walker
Member #210
April 2000
|
Kris, the 0.5 offset is when drawing primitives. I think. Neil. wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie |
|
Trent Gamblin
Member #261
April 2000
|
Direct3D stuff is offset by 0.5 behind the scenes, but that is just to make it match OpenGL so user code is compatible. Unless you know a lot about D3D you don't even know about this. The 0.5 thing people talk about is with some non-filled primitives like lines and rectangles. When you specify x and y of a line you're specifying the center of the line. So if you want a 1 pixel thick line, you specify the center (by adding 0.5) and 1 for thickness. But it's not always 0.5 you want. If you want a 1.5 thick line you'd specify 0.75 offsets. The lines "grow out" in both directions away from the center you give.
|
|
Kris Asick
Member #1,424
July 2001
|
Quote: Intel Corporation Mobile GM965/GL960 Integrated Graphics Controller
...I pity you... But yeah, for graphics processing those chipsets are both a POS, which is funny considering they support all the features of DirectX 10 among other things. I've also learned that the texture quality and accuracy of the graphics component of those chipsets is erratic at best, so even if you do come up with a solution, it could result in inaccuracies on mid-to-high end graphics software, or just other chipsets in general. Normally, I would suggest plopping in something half-decent, but considering it sounds like you're on a laptop, I dunno what to suggest. --- Kris Asick (Gemini) |
|
Elias
Member #358
May 2000
|
That screenshot looks just like it is supposed to look if something was adding 0.5 pixels offsets. Maybe try with the OpenGL driver. -- |
|
Specter Phoenix
Member #1,425
July 2001
|
Elias said: That screenshot looks just like it is supposed to look if something was adding 0.5 pixels offsets. Maybe try with the OpenGL driver. Problem is that I tried compensating for it and set the tileOffset to .5 and even 1, but the image still looked the same every time I ran the program. Last I knew Gimp didn't add a .5 offset though.
|
|
Elias
Member #358
May 2000
|
Yes, don't add any offset yourself. Put this before the al_create_display: al_set_new_display_flags(ALLEGRO_OPENGL);
-- |
|
Specter Phoenix
Member #1,425
July 2001
|
Oh, I thought it was something I had to compensate for in my tileOffset code. Either way not only does al_set_new_display_flags(ALLEGRO_OPENGL); not fix it, but it also does that on my desktop. My laptop is: Desktop:
|
|
Elias
Member #358
May 2000
|
Oh, you're using linux, then it already was using OpenGL. Looks like you found a bug - we do not support interlaced .png files. I didn't even know those existed. So, just re-save tilesheet.png in Gimp without interlacing and it should work. -- |
|
Specter Phoenix
Member #1,425
July 2001
|
Oh okay, I thought having all those options checked really didn't effect that png file. Thanks for pointing that out Elias Well as promised, here is the source code for Global Destruction and believe me the title is way cooler sounding than the actual game, which is rather lame. I found that interlace pngs will cause the application using them to crash with different errors so had to go back and redo them without interlacing. Here is the compressed directory with Code::Blocks file and everything used and un-used.
|
|
naraku9333
Member #14,728
November 2012
|
Two things, in sprite.cpp I added a check on num as I was getting subscript out of range errors. 33void SPRITE::randDraw(int num)
34{
35 int tileOffset = 0;
36 for(int i = 0; i < frames; i++)
37 {
38 anim.push_back(al_create_sub_bitmap(sprite, tileOffset, 0, w, h));
39 tileOffset = tileOffset + w;
40 }
41 if(num < anim.size())
42 al_draw_bitmap(anim[num], x, y, 0);
43}
And in main line 225 I had to change CENTER to CENTRE.
|
|
kazzmir
Member #1,786
December 2001
|
<edit> Oh boy, I didn't even read the post directly above mine. Double-kill^wpost! You have a bug in SPRITE::randDraw(int) where you try to access an element of anim[] that doesn't exist. I added a cout call that shows the size of num, frames, and the size of the anim[] vector. They end up being the same number but since anim[] is 0-based it is one number too large. void SPRITE::randDraw(int num) { int tileOffset = 0; for(int i = 0; i < frames; i++) { anim.push_back(al_create_sub_bitmap(sprite, tileOffset, 0, w, h)); tileOffset = tileOffset + w; } if (num >= frames){ std::cout << "Num is " << num << " frames is " << frames << " Anim length is " << anim.size() << std::endl; } al_draw_bitmap(anim[num], x, y, 0); } Prints this Num is 4 frames is 4 Anim length is 4
|
|
Specter Phoenix
Member #1,425
July 2001
|
What number is being higher than 4? According to my test code all three numbers should be 0 to 4 (5 entries). Should have 5 colored ship sprites (0 to 4), randomly pick between those to draw each redraw. Where did I mess up at? GNU never complained about that once when I compiled and ran it.
|
|
|
1
2
|