[A5] Pointless Thread about what I have been attempting
Specter Phoenix

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:
606876

Screenshot of Test Running:
{"name":"606875","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/e\/8e486e77b94eae78ff1606cfc6e58799.png","w":642,"h":512,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/e\/8e486e77b94eae78ff1606cfc6e58799"}606875

Code for it (used ugly globals and terrible practices, but I was in a hurry so I did it sporadic) :

#SelectExpand
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

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

Depressing :( Not because of the content, but the form. Giving yourself credit is also an art. I suck at it too I'm trying to improve that too I'm definitely getting better at it, just like you >_>
The line might also be an artefact from linear filtering sampling over the bound... maybe. Or from the new floating point screen coordinates[1], where you should use an offset of 0.5.

Even have a semi-working game done too, Global Destruction.

Already the name's good. ;D

References

  1. There has to be a better name.
pkrcel

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 ???

LennyLen

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

@LennyLen
I used to have it like that, but once the map showed grey lines I wanted to do it individually to rule out the drawing code. (Figured I had typed out the spr[map[i][j]]wrong, but it didn't fix it and just forgot to change it back).

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"}606880

[REVISION]
Well tried an offset of .5 and 1 but still have the lines. Even removed the offset and still changed nothing in that regard.

naraku9333

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"}47058783.png

Specter Phoenix

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"}606882

Kris Asick

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.

Peter Wang

Allegro offsets pixels by 0.5f by default

It don't.

Kris Asick

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? :o

Trent Gamblin

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

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

Kris, the 0.5 offset is when drawing primitives. I think.

Trent Gamblin

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
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. :-/

Elias

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

Yes, don't add any offset yourself. Put this before the al_create_display:

al_set_new_display_flags(ALLEGRO_OPENGL);

Specter Phoenix

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:
OS = Ubuntu 12.04
Allegro = 5.1.4
Graphic = Intel 965GM

Desktop:
OS = Ubuntu 12.04
Allegro = 5.1.4
Graphic = nVidia GeForce 8600

Elias

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

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

Two things, in sprite.cpp I added a check on num as I was getting subscript out of range errors.

sprite.cpp#SelectExpand
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

<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

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.

kazzmir

It looks like most of your sprites have 4 frames in them, not 5.

main.cpp:    straggler.setData(32, 32, 0, rand() % 6 + 1, 4);
main.cpp:    wolverine.setData(32, 32, 0, rand() % 6 + 1, 4);
main.cpp:                               aiShip.setData(32, 32, 0, (rand() % 6 + 1), 4);
main.cpp:                aiShip.setData(32, 32, 0, (rand() % 6 + 1), 4);
main.cpp:                straggler.setData(32, 32, 0, (rand() % 6 + 1), 4);
main.cpp:                straggler.setData(32, 32, 0, (rand() % 6 + 1), 4);
main.cpp:                wolverine.setData(32, 32, 0, (rand() % 6 + 1), 4);
main.cpp:                wolverine.setData(32, 32, 0, (rand() % 6 + 1), 4);

Specter Phoenix

Oh, I forgot to change that. My first plan was to have 4 different ship sprites and the player sprite and at the last minute I changed to 1 player sprite and 1 AI sheet with 5 colors. Thought I had changed it everywhere, but obviously not. Thanks for pointing that out :).

[REVISION]
Now just learn to do a splash screen, do a high score screen, and make the animation for the explosion better. I may have Global Destruction finished one of these days.

Thread #611486. Printed from Allegro.cc