Hey all,
I have a game in development and to add a more professional touch I want it so when certain messages appear to the player, and when the user pauses the game, etc, the following should happen:
1. a black rectangle at 50% opacity should fill the entire screen
2. text should be displayed at 100% opacity on top of said rectangle
3. the game should pause until a key [P] is pressed
I have #3 done as the following:
how would i go about drawing a large black opaque rectangle though - i don't know how to do opacity in allegro!
thanks for your help, cameron
Actually, you apparently don't want an opaque rectangle - opaque means 100% opacity . What you want is transcluency. Just look in the manual. A word of warning; trancluency is slow if you're using plain allegro! Since you're pausing the game you might get away with only doing the transcluent blit once, though, since the screen won't change.
To be specific, look up
BTW, the rest()s in your code concern me. You're not doing your game timing with rest(), are you?
try messin around with this stuff use a square spite or drawRectangle
/* Some one time initialisation code. */ COLOR_MAP global_trans_table; create_trans_table(&global_trans_table, my_palette, 128, 128, 128, NULL); ... if (get_color_depth() == 8) color_map = &global_trans_table; else set_trans_blender(128, 128, 128, 128); draw_trans_sprite(buffer, ghost_sprite, x, y);
makeacol32
Converts an RGBA color into a 32-bit display pixel format.
Description
int makeacol32(int r, int g, int b, int a);
drawRectangle
1 | // draw a rectangle |
2 | // since we use it three times in the editor, it would be nice to have |
3 | // a function for it. |
4 | void drawRectangle(BITMAP *bmp,int x, int y, int w,int h,int color, int style, int bgcolor) |
5 | { |
6 | w--; |
7 | h--; |
8 | if (style==0) |
9 | { |
10 | vline(bmp,x,y,y+h,color); |
11 | vline(bmp,x+w,y,y+h,color); |
12 | hline(bmp,x,y,x+w,color); |
13 | hline(bmp,x,y+h,x+w,color); |
14 | } |
15 | if (style==1) |
16 | { |
17 | rectfill(bmp,x,y,x+w,y+h,bgcolor); |
18 | vline(bmp,x,y,y+h,color); |
19 | vline(bmp,x+w,y,y+h,color); |
20 | hline(bmp,x,y,x+w,color); |
21 | hline(bmp,x,y+h,x+w,color); |
22 | } |
23 | |
24 | |
25 | // this is for our dialog. This draws a box with rounded corners. |
26 | if (style==2) |
27 | { |
28 | arc(bmp,x+10,y+10,itofix(64),itofix(128),10,255); |
29 | arc(bmp,x+10,y+h-10,itofix(128),itofix(192),10,255); |
30 | arc(bmp,x+w-10,y+10,itofix(0),itofix(64),10,255); |
31 | arc(bmp,x+w-10,y+h-10,itofix(192),itofix(256),10,255); |
32 | |
33 | |
34 | hline(bmp,x+10,y,x+w-10,255); |
35 | hline(bmp,x+10,y+h,x+w-10,255); |
36 | vline(bmp,x,y+10,y+h-10,255); |
37 | vline(bmp,x+w,y+10,y+h-10,255); |
38 | |
39 | floodfill(bmp,x+w/2,y+h/2,255); |
40 | |
41 | arc(bmp,x+10,y+10,itofix(64),itofix(128),8,bgcolor); |
42 | arc(bmp,x+10,y+h-10,itofix(128),itofix(192),8,bgcolor); |
43 | arc(bmp,x+w-10,y+10,itofix(0),itofix(64),8,bgcolor); |
44 | arc(bmp,x+w-10,y+h-10,itofix(192),itofix(256),8,bgcolor); |
45 | |
46 | |
47 | hline(bmp,x+10,y+2,x+w-10,bgcolor); |
48 | hline(bmp,x+10,y+h-2,x+w-10,bgcolor); |
49 | vline(bmp,x+2,y+10,y+h-10,bgcolor); |
50 | vline(bmp,x+w-2,y+10,y+h-10,bgcolor); |
51 | |
52 | floodfill(bmp,x+w/2,y+h/2,bgcolor); |
53 | } |
54 | } |
piccolo strikes again! Seriously, that's the clumsiest way to draw rectangles in Allegro that I've ever seen.
gnolam, yes, i am. this is my second game ever. (first was pong) i have a lot to learn.
piccolo i am confused as to how to use that.. (and why not just use rectfill() )
and thanks for all the help guys.
Implement that. Please. Friends don't let friends do rest() timing.
Exactly! Timed game loops saved two of my best games from the recycle bin!
gnolam, i have implemented the counter as you suggested, still not sure what to do in relation to the black-transparency screen problem. i looked at the docu, i guess i just don't know enough about allegro and it's functions to mess with it yet.
thanks guys. oh, and what is the primary benefits to doing this counter over rest()?
gnolam, i have implemented the counter as you suggested, still not sure what to do in relation to the black-transparency screen problem. i looked at the docu, i guess i just don't know enough about allegro and it's functions to mess with it yet.
Well, what's the problem?
thanks guys. oh, and what is the primary benefits to doing this counter over rest()?
The timer-based method actually works. rest() will, at best, work on one computer - yours.
Rest works like this:
//loop took 5 milliseconds rest(20) //rest for 20 milliseconds //total time: 25 milliseconds
Timed Loops work like this:
//loop took 5 milliseconds while (timer < loop_start+20){}; //waits until it was been at least 20 //milliseconds since the START of the loop //total time: 20 milliseconds
//loop took 5 milliseconds
rest(20) //rest for 20 milliseconds
//total time: 25 milliseconds
That's providing of course the loop takes 5 miliseconds, which it won't on all machines. Which is why you don't use rest() for timing.
thanks for the explanation. I'm now rest()-free.
il update you on the black screen thing tomorrow.. i'm off to bed.
1. a black rectangle at 50% opacity should fill the entire screen
An old-school (and cheap) way of getting this effect is to use dithering: turn alternate pixels black in a checkerboard pattern. If your resolution is high enough, the difference is not noticable unless you look closely. You could even make this an option.
that can be done something like this.
1 | |
2 | void do_trans(BITMAP *dest){ |
3 | int color = makecol(0,0,0); |
4 | int fourth_width = dest->w/4; |
5 | for(int y = 0; y <= dest->h; ++y) { |
6 | unsigned short *pixel_ptr = (unsigned short *)dest->line[y]; |
7 | int x = 0; |
8 | if( y & 1 ) { |
9 | ++x; |
10 | ++pixel_ptr; |
11 | } |
12 | for(; x <= fourth_width; ++x ) { |
13 | //*pixel_ptr = color; |
14 | pixel_ptr += 4; |
15 | } |
16 | } |
17 | } |
edited
Nope - that masks out alternate scanlines (and can therefore be optimised considerably). That could also work to achieve the same effect though..
yeah i fix the color from 255 0 255 to 0 0 0
A lot of the video cut scenes from mid-90's games such as Tomb Raider I used alternate scan lines to improve frame rate, it'd look much better with higher resolutions but still a bit dark. In other words, half the scan lines were black and built to stay that way.
That's providing of course the loop takes 5 milliseconds, which it won't on all machines. Which is why you don't use rest() for timing.
It's called an "example".
It's called an "example".
I'm aware of that. But your example doesn't explain very well why not to use rest().
Anything wrong with taking a screenshot of the game, tinting it, and displaying that?
As for code that will do this... ugh.. (/me goes to lookup random source code...)
Alright found it. Heres some code i found in old code and (lucky you) rewritten for your uses!
// If howMuch is 1, dest is turned black. If howMuch is 0, dest is left unchanged void shade(BITMAP *dest, float howMuch) { const int val = (int)(howMuch * 0xff); set_trans_blender(0xff, 0xff, 0xff, val); drawing_mode(DRAW_MODE_TRANS, 0, 0, 0); rectfill(dest, 0, 0, dest->w, dest->h, makeacol32(0xff, 0xff, 0xff, val)); drawing_mode(DRAW_MODE_SOLID, 0, 0, 0); }
Shesh I spend more time writing code in this little a.cc textbox then I do anywhere else.
Example usage:
Anything wrong with taking a screenshot of the game, tinting it, and displaying that?
It's much more work than just drawing a DRAW_MODE_TRANS rectfill() over the buffer?
[EDIT]
rectfill(dest, 0, 0, dest->w, dest->h, makeacol32(0xff, 0xff, 0xff, val));
... and that alpha is completely unnecessary.
The docs don't really say so I just put the alpha value everywhere I could. Never actually tested which one is actually used.