I have two questions here, so I'll address them individually.
1: In the game I am making, you need to press a key to fire a bullet. When I press the key though, it fires multiple bullets at once (which is bad because they need to be fired individually).
if (key[KEY_D]) player1newbullet();
Is the code I use to trigger firing a bullet. What's the best way to fix it?
2: My game runs at 16 bit colour depth (it always has, purely because I feel like it). The graphics for use in game are stored as bitmaps. When I try using 16-bit bitmaps in-game (they are 16-bit because there is no point in them being any more detailed, it won't show any more detail at 16-bit colour, obviously) they just show up as black squares the size of the bitmap. I can fix it by saving the bitmaps at any other colour depth (or indexed colour, which can be handy for the ones that only have a few different colours). As I said, I don't want to go to all the hassle of converting all my bitmaps to a different colour depth and since my game is skinnable by the end user I don't want them to have problems.
This sets the graphics mode:
set_color_depth(16); set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0;
This loads a graphic:
BITMAP *background; background = load_bitmap("background.bmp", NULL);
And this displays that graphic:
draw_sprite(buffer,background,0,0);
Finally, since I'm using double buffering, this creates the temporary buffer:
buffer = create_bitmap(640,480);
Any and all help with these problems would be greatly appreciated.
Thanks, Konedima.
1 | bool kb = false; |
2 | |
3 | if ( key[ KEY_D ] ) |
4 | { |
5 | if ( !kb ) |
6 | { |
7 | // just pressed |
8 | } |
9 | |
10 | kb = true; |
11 | } |
12 | else |
13 | { |
14 | if ( kb ) |
15 | { |
16 | // just released |
17 | } |
18 | |
19 | kb = false; |
20 | } |
if you're using c++:
1 | #include <vector> |
2 | |
3 | using namespace std; |
4 | |
5 | //////////////////////////////////////////////////////////////////////////////// |
6 | //////////////////////////////////////////////////////////////////////////////// |
7 | |
8 | class control_button_class |
9 | { |
10 | public: |
11 | bool pressed; |
12 | bool just_pressed; |
13 | bool just_released; |
14 | |
15 | int key_name; |
16 | |
17 | control_button_class(int al_key_n) |
18 | { |
19 | key_name = al_key_n; |
20 | pressed = false; |
21 | just_pressed = false; |
22 | just_released = false; |
23 | } |
24 | |
25 | void set_key(int al_key_n) |
26 | { |
27 | key_name = al_key_n; |
28 | } |
29 | |
30 | void update() |
31 | { |
32 | just_pressed = false; |
33 | just_released = false; |
34 | |
35 | if (!key[key_name] && pressed) { just_released = true; } |
36 | if (!key[key_name]) |
37 | { |
38 | pressed = false; |
39 | just_pressed = false; |
40 | } |
41 | |
42 | if (key[key_name] && !pressed) { just_pressed = true; } |
43 | if (key[key_name]) |
44 | { |
45 | pressed = true; |
46 | just_released = false; |
47 | } |
48 | } |
49 | }; |
50 | |
51 | |
52 | class controls_manager_class |
53 | { |
54 | public: |
55 | vector<control_button_class> button; |
56 | |
57 | controls_manager_class() |
58 | { |
59 | } |
60 | |
61 | void add_button(int al_key) |
62 | { |
63 | bool button_used = false; |
64 | for (int i=0; i<button.size(); i++) |
65 | { |
66 | if (button<i>.key_name == al_key) button_used = true; |
67 | } |
68 | if (!button_used) button.push_back(control_button_class(al_key)); |
69 | } |
70 | |
71 | void update() |
72 | { |
73 | for (int i=0; i<button.size(); i++) button<i>.update(); |
74 | } |
75 | |
76 | bool pressed(int al_key) |
77 | { |
78 | for (int i=0; i<button.size(); i++) |
79 | { |
80 | if (button<i>.key_name == al_key) return button<i>.pressed; |
81 | } |
82 | add_button(al_key); |
83 | return false; |
84 | } |
85 | |
86 | bool just_pressed(int al_key) |
87 | { |
88 | for (int i=0; i<button.size(); i++) |
89 | { |
90 | if (button<i>.key_name == al_key) return button<i>.just_pressed; |
91 | } |
92 | add_button(al_key); |
93 | return false; |
94 | } |
95 | |
96 | bool just_released(int al_key) |
97 | { |
98 | for (int i=0; i<button.size(); i++) |
99 | { |
100 | if (button<i>.key_name == al_key) return button<i>.just_released; |
101 | } |
102 | add_button(al_key); |
103 | return false; |
104 | } |
105 | |
106 | }; |
107 | |
108 | |
109 | controls_manager_class input_controller; |
110 | |
111 | #define pressed(x) input_controller.pressed(x) |
112 | #define just_pressed(x) input_controller.just_pressed(x) |
113 | #define just_released(x) input_controller.just_released(x) |
it's easy to use! just
if (just_pressed(KEY_D)) fire_bullet();
konedima, your avatar rocks!
int k = (keypressed() ? (readkey() >> 8) : 0); ... if(k == KEY_D) player1newbullet();
Why do you people keep insisting on using key[] in a way it wasn't designed for?
Also, the ordering of how you call set_gfx_mode and load_bitmap is very important. When using Allegro properly, there's really no reason to restrict to a specific color depth, unless you're using palette effects (which you're obviously not). You should try to use desktop_color_depth() whenever possible, otherwise you may get a bad speed hit from color conversions.
I'm having mixed success with your suggestions.
And by mixed, I mean none.
DanielH: That does nothing, basically. The bullets fire in shorter bursts but I need it to be that only one fires.
Mark Oates: When I put that in (where I thought it should be, I'm pretty new to C++ but I think I did it right), and I press the key, it doesn't do anything at all.
Paul whoknows: Thanks!
Kitty Cat: For the keys, that doesn't work. Like Mark's, the key presses don't do anything. And I did set it the colour depth to desktop_color_depth(), thanks for the advice. It's not any faster (it was never particularly slow, and I have to slow it down to keep it at a decent speed) and it doesn't fix my graphics problem. It still displays my 16 bit bitmaps as black.
You're going to have to show more code, then.
How much do you want?
Initialization (where you call set_gfx_mode, create_bitmap, load_bitmap, and stuff), and your input routine.
These are missing some parts inbetween, but all these bits are shown in the order they appear in the code.
Same for the rest of the graphics.
int player1size; int player1score;
Same for the rest of the global variables.
void loadgraphics(); void scoreforone();
Same for the rest of the functions.
1 | // Main section |
2 | int main() { |
3 | // Set up all the Allegro functions |
4 | allegro_init(); |
5 | install_keyboard(); |
6 | set_color_depth(desktop_color_depth()); |
7 | if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0)!=0) { |
8 | allegro_message("Unable to set graphics mode.",allegro_error); |
9 | } |
10 | set_window_title("War Pong"); |
11 | set_config_file("warpong.cfg"); |
12 | // Set the random seed |
13 | srand(time(NULL)); |
14 | // Create bitmap for buffer to go into |
15 | buffer = create_bitmap(640,480); |
16 | // Run loading functions |
17 | setvars(); |
18 | loadgraphics(); |
19 | makebats(); |
20 | scoreforone(); |
21 | scorefortwo(); |
22 | resetbullets(); |
23 | // Create new ball for start of new game |
24 | newball(); |
25 | // Go to the game loop |
26 | maingame(); |
27 | } |
28 | END_OF_MAIN() |
That's the entire main loop.
1 | // Player 1 input and display |
2 | void playerone(){ |
3 | draw_sprite(buffer,player1bat,0,player1y); |
4 | if (key[KEY_W]) player1y = player1y - 4; |
5 | if (key[KEY_S]) player1y = player1y + 4; |
6 | if (key[KEY_D]) player1newbullet(); |
7 | } |
8 | // Player 2 input and display |
9 | void playertwo(){ |
10 | draw_sprite(buffer,player2bat,620,player2y); |
11 | if (key[KEY_UP]) player2y = player2y - 4; |
12 | if (key[KEY_DOWN]) player2y = player2y + 4; |
13 | if (key[KEY_LEFT]) player2newbullet(); |
14 | } |
15 | |
16 | // General (non-player specific) input |
17 | void generalinput() { |
18 | if (key[KEY_ESC]) win = 3; |
19 | } |
Those are the only functions that take keyboard input.
If you need any more just ask.
Unless you're disabling color conversions, I see no reason why your graphics come out black. Though I can't see the code where you actually load the graphics.
As for input, you're mixing your logic and drawing. Something like this would work:
1 | // General input |
2 | void generalinput(int k) |
3 | { |
4 | // Player 1 |
5 | if (key[KEY_W]) player1y = player1y - 4; |
6 | if (key[KEY_S]) player1y = player1y + 4; |
7 | if (k == KEY_D) player1newbullet(); |
8 | |
9 | // Player 2 |
10 | if (key[KEY_UP]) player2y = player2y - 4; |
11 | if (key[KEY_DOWN]) player2y = player2y + 4; |
12 | if (k == KEY_LEFT) player2newbullet(); |
13 | |
14 | // General |
15 | if (k == KEY_ESC) win = 3; |
16 | } |
17 | |
18 | void drawthings() |
19 | { |
20 | draw_sprite(buffer,player1bat,0,player1y); |
21 | draw_sprite(buffer,player2bat,620,player2y); |
22 | } |
23 | ... |
24 | while(playing) { |
25 | while(speed_timer > 0) { |
26 | --speed_timer; |
27 | while(keypressed()) { |
28 | int k = readkey() >> 8; |
29 | generalinput(k); |
30 | } |
31 | } |
32 | |
33 | drawthings(); |
34 | } |
Note that player up-down movement will be continuous while the key is held down. If you don't want that, do this instead:
if (k == KEY_W) player1y = player1y - 4; if (k == KEY_S) player1y = player1y + 4; ... if (k == KEY_UP) player2y = player2y - 4; if (k == KEY_DOWN) player2y = player2y + 4;
While I have a look at that keyboard code here's an example of loading the graphics:
ball = load_bitmap("ball.bmp", NULL); background = load_bitmap("background.bmp", NULL);
They're all like that.
Edit: I generally don't work well with code other than my own, and when I implemented your changes, I can't seem to get it to work (and when I do, it just freezes on a black screen). This is what I've got:
1 | void maingame(){ |
2 | while (win <= 0){ |
3 | // Draw objects that always appear before we get into the stuff that moves |
4 | draw_sprite(buffer,background,0,0); |
5 | draw_sprite(buffer,logo,65,60); |
6 | draw_sprite(buffer,scoreone,40,190); |
7 | draw_sprite(buffer,scoretwo,400,190); |
8 | // Now the stuff that moves |
9 | workbullets(); |
10 | ballmove(); |
11 | while(playing){ |
12 | while(speed_timer > 0) { |
13 | --speed_timer; |
14 | while(keypressed()) { |
15 | int k = readkey() >> 8; |
16 | input(k); |
17 | } |
18 | } |
19 | |
20 | players(); |
21 | } |
22 | dodisplay(); |
23 | // Now we rest to make sure the game doesn't run too fast |
24 | rest(10); |
25 | } |
26 | } |
27 | |
28 | void input(int k){ |
29 | // Player 1 |
30 | if (key[KEY_W]) player1y = player1y - 4; |
31 | if (key[KEY_S]) player1y = player1y + 4; |
32 | if (k == KEY_D) player1newbullet(); |
33 | // Player 2 |
34 | if (key[KEY_UP]) player2y = player2y - 4; |
35 | if (key[KEY_DOWN]) player2y = player2y + 4; |
36 | if (k == KEY_LEFT) player2newbullet(); |
37 | // General |
38 | if (k == KEY_ESC) win = 3; |
39 | } |
40 | void players(){ |
41 | // Draw the bats |
42 | draw_sprite(buffer,player1bat,0,player1y); |
43 | draw_sprite(buffer,player2bat,620,player2y); |
44 | // Make sure the bats don't go off screen |
45 | if (player1y < 0) player1y = 0; |
46 | if ((player1y + player1size) > 480) player1y = (480 - player1size); |
47 | if (player2y < 0) player2y = 0; |
48 | if ((player2y + player2size) > 480) player2y = (480 - player2size); |
49 | } |
You're mixing logic and drawing again. And don't use rest() to time the game. The FAQ is your friend.
Now I'm getting somewhere (it works!) but the bats (using w,s,up,down) move very choppily and pressing esc or either of the shoot buttons don't register at all.
This is what I got:
1 | void maingame(){ |
2 | LOCK_VARIABLE(speeder); |
3 | LOCK_FUNCTION(increment_speeder); |
4 | install_int_ex(increment_speeder, BPS_TO_TIMER(60)); |
5 | while (win <= 0){ |
6 | // Draw objects that always appear before we get into the stuff that moves |
7 | draw_sprite(buffer,background,0,0); |
8 | draw_sprite(buffer,logo,65,60); |
9 | draw_sprite(buffer,scoreone,40,190); |
10 | draw_sprite(buffer,scoretwo,400,190); |
11 | while(speeder > 0) { |
12 | speeder--; |
13 | while(keypressed()) { |
14 | int k = readkey() >>8; |
15 | input(k); |
16 | } |
17 | workbullets(); |
18 | ballmove(); |
19 | players(); |
20 | } |
21 | drawbats(); |
22 | dodisplay(); |
23 | // Now we rest to make sure the game doesn't run too fast |
24 | rest(10); |
25 | } |
26 | } |
27 | |
28 | void input(int k){ |
29 | // Player 1 |
30 | if (key[KEY_W]) player1y = player1y - 4; |
31 | if (key[KEY_S]) player1y = player1y + 4; |
32 | if (k == KEY_D) player1newbullet(); |
33 | // Player 2 |
34 | if (key[KEY_UP]) player2y = player2y - 4; |
35 | if (key[KEY_DOWN]) player2y = player2y + 4; |
36 | if (k == KEY_LEFT) player2newbullet(); |
37 | // General |
38 | if (k == KEY_ESC) win = 3; |
39 | } |
40 | void players(){ |
41 | // Make sure the bats don't go off screen |
42 | if (player1y < 0) player1y = 0; |
43 | if ((player1y + player1size) > 480) player1y = (480 - player1size); |
44 | if (player2y < 0) player2y = 0; |
45 | if ((player2y + player2size) > 480) player2y = (480 - player2size); |
46 | } |
47 | void drawbats(){ |
48 | // Draw the bats |
49 | draw_sprite(buffer,player1bat,0,player1y); |
50 | draw_sprite(buffer,player2bat,620,player2y); |
51 | } |
Sorry, that doesn't work. Any other ideas?
Oops, my fault for misreading the manual. That was the test for ALT + key.
What happens if you change it to:
int k = readkey();
and then change the other checks to (for example):
if ((k >> 8) == KEY_ESC) win = 3;
I don't see why the shoot buttons and escape don't work. Have you traced them to see that they behave properly? As for the choppiness, that's probably because you're moving four pixels at a time. And you're using rest(10);, which is probably causing timing issues. Instead, use:
while(speeder <= 0) rest(1);
So it only rests when you have time to wait.
For whatever reason, now it is registering those key presses. And when I mean moving the bats is choppy, I mean that before I did all this they moved smoothly. And faster.
Sorry if I sound like I'm whining.
[edit]
Hmm, from a reread of your post, I'm not sure it means it all works or there are still problems.
[/edit]
konedima, does the following make any difference to the choppiness?
1 | void maingame(){ |
2 | int nspeed, k; // <------ added |
3 | LOCK_VARIABLE(speeder); |
4 | LOCK_FUNCTION(increment_speeder); |
5 | install_int_ex(increment_speeder, BPS_TO_TIMER(60)); |
6 | while (win <= 0){ |
7 | // Draw objects that always appear before we get into the stuff that moves |
8 | draw_sprite(buffer,background,0,0); |
9 | draw_sprite(buffer,logo,65,60); |
10 | draw_sprite(buffer,scoreone,40,190); |
11 | draw_sprite(buffer,scoretwo,400,190); |
12 | |
13 | // give some up some processing time if none is needed |
14 | if (speeder == 0) // <------ added |
15 | rest(1); // <------ added |
16 | nspeed = speeder; // <------ added |
17 | speeder = 0; // <------ added |
18 | while(nspeed > 0) { // <------ changed |
19 | nspeed--; |
20 | while(keypressed()) { |
21 | k = readkey() >>8; // <------ changed |
22 | input(k); |
23 | } |
24 | workbullets(); |
25 | ballmove(); |
26 | players(); |
27 | } |
28 | drawbats(); |
29 | dodisplay(); |
30 | } |
31 | } |
I'm good at not being clear .
All the input issues are fixed. The problems I have are that the bat (and sometimes the bullet) movement is very choppy (bullets appear to move back and forth occasionally) and that 16-bit bitmaps still don't work.
HardTranceFan, your code doesn't help, thanks anyway.
I've changed the code since I last posted it - I've moved all the drawing operations into one function, and out of their logic functions. Here's the main game loop:
1 | void maingame(){ |
2 | int nspeed, k; |
3 | LOCK_VARIABLE(speeder); |
4 | LOCK_FUNCTION(increment_speeder); |
5 | install_int_ex(increment_speeder, BPS_TO_TIMER(60)); |
6 | while (win <= 0){ |
7 | if (speeder == 0) |
8 | rest(1); |
9 | nspeed = speeder; |
10 | speeder = 0; |
11 | while(nspeed > 0) { |
12 | nspeed--; |
13 | while(keypressed()) { |
14 | k = readkey() >>8; |
15 | input(k); |
16 | } |
17 | workbullets(); |
18 | ballmove(); |
19 | players(); |
20 | } |
21 | quickdisplay(); |
22 | } |
23 | } |
If you attach the complete source, then some of the allegroids could have a look. It could be that you've overlooked an issue elsewhere in your program.
Or attach the binary and see if it occurs on other machines.
I'm weirdly overprotective of my source code (espcially since I plan on releasing it as open source when it's done). I could post it if I really had to, but I'd rather look for other alternatives. The only thing I can think of is that as mentioned before, the bats are moved up four pixels at a time (actually now it's eight). The program was probably running at a faster framerate before because I only had a rest(10) to slow it down, so that could have been it. I don't know how to fix it because if they move any slower, they won't move nearly fast enough.
Something else I've noticed during testing of the latest code is that if you shoot a bullet while moving the bat (by holding the key down), the movement stops until you let go and press down again. Is there any way to fix that?
Something else I've noticed during testing of the latest code is that if you shoot a bullet while moving the bat (by holding the key down), the movement stops until you let go and press down again. Is there any way to fix that?
Ahhh, I just noticed you have a :
while(keypressed()) { k = readkey() >>8; input(k); }
So while you hold down a key, it's going to remain within that loop until the key is released. It will update the co-ordinates, but not draw them to the screen.
Change the while to an if. I suspect this may fix your visual problem.
Nope, it doesn't.
So while you hold down a key, it's going to remain within that loop until the key is released.
No, because keypressed() only returns true when readkey() has a key waiting in the buffer.
Apologies, my interpretation of the manual was incorrect.
Back to the drawing board.
[edit]
Are you calling any key reading functions anywhere else in your code?
[/edit]
No key reading functions anywhere else.
Is there a quicker way to resolve this than forum tag?
Sorry, I didn't read the whole thread, just the first few posts. Why is readkey() better than key[] again? I don't see the point. As far as I can tell readkey() will return a keypress as soon as the user presses a key, then again after a short delay if the key is being pressed down and then again in regular intervals. Those two times can be changed in the OS's keyboard settings. Which means the player will be able to change the way how the game responds to keyboard input in the Windows control panel. Which as far as I can tell is not something most people would like.
For normal everyday keyboard input the key[] array is the way to go. The code snippets Daniel and Mark posted in the first two replies are what you want. Daniel's is very simple and should be easy to adapt while Mark's is a little more involved (but complete) and just requires some initialization...
it doesn't do anything at all
ah, you have to add
input_controller.update();
somewhere at the beginning of your main loop. Sorry I forgot to mention that.
[edit]
Damn, Mr Oates. Is that all that might have to be done?
[/edit]
Is there a quicker way to resolve this than forum tag?
If you attach the complete source, then some of the allegroids could have a look. It could be that you've overlooked an issue elsewhere in your program.
I'm weirdly overprotective of my source code (espcially since I plan on releasing it as open source when it's done). I could post it if I really had to, but I'd rather look for other alternatives.
I don't fully understand why you're protective of your source code, particularly as it's going to be in the public domain later on anyway. However, we're not here to discuss that. Looking at an alternative, I'd suggest debugging.
The sort of debugging I'm thinking of doesn't mean using a debugger and stepping through the code, but putting in a small amount of code, immediately before and after a function call, that appends a line of text with a timer on it into a log file. Run your program, and then go through log and see where there are large pauses between statements. Once the function is identified, do the same within that function, but for each command line. It's slow, but debugging is not a fast sport
To help you get the idea, here's a sample of the type of code I'm thinking about:
1 | #include <fstream> |
2 | void maingame(){ |
3 | // this creates an empty file every run. No point in appending to previous runs |
4 | ofstream fout("debugging.log"); |
5 | fout.close(); |
6 | |
7 | int nspeed, k, totalspeed = 0; // Added total speed |
8 | LOCK_VARIABLE(speeder); |
9 | LOCK_FUNCTION(increment_speeder); |
10 | install_int_ex(increment_speeder, BPS_TO_TIMER(60)); |
11 | while (win <= 0){ |
12 | totalspeed += speeder; // Added |
13 | if (speeder == 0) |
14 | rest(1); |
15 | nspeed = speeder; |
16 | speeder = 0; |
17 | while(nspeed > 0) { |
18 | nspeed--; |
19 | while(keypressed()) { |
20 | k = readkey() >>8; |
21 | fout.open("debugging.log", ios::app); // Added |
22 | fout << "before inpt(k)" << totalspeed + speeder << "\n";// Added |
23 | fout.close() // Added |
24 | input(k); |
25 | fout.open("debugging.log", ios::app); // Added |
26 | fout << "after inpt(k)" << totalspeed + speeder << "\n"; // Added |
27 | fout.close() // Added |
28 | } |
29 | workbullets(); |
30 | ballmove(); |
31 | players(); |
32 | } |
33 | quickdisplay(); |
34 | } |
35 | } |
It may not be the most eloquent or efficient method, but it works, and it's fairly quick to do.
Good luck
Damn, Mr Oates. Is that all that might have to be done?
Perhaps not. But it's clean, clear and managed completely in the background. you get these three wonderful functions:
pressed() just_pressed() just_released()
[edit] The only thing it doesn't do yet is time how long a button has been held down, or send triggers in regular intervals. But I'll add that in the future.
Why is readkey() better than key[] again?
Because for firing and quitting, he wants to know when the key is actually pressed, not if its down or up at a given point in time. Sure you could emulate it with a shadow key[] array or similar, memcpy'ing, and checking between the two arrays, but why hack in functionality that's already provided for you?
To be honest, I don't like revealing my source code because I never wanted my projects to be open source - it's just that Sourceforge has free hosting, no ads, etc.
I don't know if having all the extra source code will help (very little of it is relevant to the issue at hand). But, ask and ye shall recieve.
http://warpong.sourceforge.net/warpongc.cpp
By the way: I know there's probably a lot of bad stuff in there (I should give people an error message if one of the graphics doesn't exist) but I'll fix that up for the release version.
I don't fully understand why you're protective of your source code, particularly as it's going to be in the public domain later on anyway.
Something being open source does not imply in any way that it is in the public domain, though you're by no means the only one to think that it does.
Sure you could emulate it with a shadow key[] array or similar, memcpy'ing, and checking between the two arrays, but why hack in functionality that's already provided for you?
This does not emulate readkey(). Also note that readkey() does not tell you if a key was pressed and held down, or pressed multiple times in rapid succession. For normal game input I use key[] and a copy of the key[] array from the last timestep to detect key down and key up events (actually, I don't, I use a wrapper around either a keyboard or a gamepad so that I can use either without changing a line of code, but that uses key[] for the keyboard). Another reason to use key[] over readkey() has to do with modifier keys that you may (or may not) want to use like any other key. It depends very much on the situation (and the game in question) what is better. For a top-down RPG or dungeon crawler, I would (do) use key[]. For an RTS, I would (do) use readkey().
In this particular case, judging from the described intended behavior, readkey() does seem the more natural implementation. However, if he wants to fire the bullet only when the key is released again, then key[] is the proper (only) way to go.
Konedima,
I've got the solution to your problem. Thanks for providing your source - I used that plus the graphics from sourceforge to compile the game.
Anyway, the problem was that you were only checking for player movement keys if keypressed() was true. This causes a stutter at the start and a jutter along the way as it appears to use the OS key repeat settings.
So, I've modified the code as below:
1 | // Somewhere where you declare all your functions: |
2 | void movePlayers(); |
3 | |
4 | // Then... |
5 | |
6 | void maingame(){ |
7 | int nspeed, k; |
8 | LOCK_VARIABLE(speeder); |
9 | LOCK_FUNCTION(increment_speeder); |
10 | install_int_ex(increment_speeder, BPS_TO_TIMER(60)); |
11 | while (win <= 0){ |
12 | if (speeder == 0) |
13 | rest(1); |
14 | nspeed = speeder; |
15 | speeder = 0; |
16 | while(nspeed > 0) { |
17 | nspeed--; |
18 | while(keypressed()) { |
19 | k = readkey() >>8; |
20 | input(k); |
21 | } |
22 | workbullets(); |
23 | movePlayers(); // New |
24 | ballmove(); |
25 | players(); |
26 | } |
27 | quickdisplay(); |
28 | } |
29 | } |
30 | |
31 | void input(int k){ |
32 | // Player 1 |
33 | if (k == KEY_D) player1newbullet(); |
34 | // Player 2 |
35 | if (k == KEY_LEFT) player2newbullet(); |
36 | // General |
37 | if (k == KEY_ESC) win = 3; |
38 | } |
39 | |
40 | // The new move function checked independently of keypressed() |
41 | void movePlayers(){ |
42 | // Player 1 |
43 | if (key[KEY_W]) player1y = player1y - 8; |
44 | if (key[KEY_S]) player1y = player1y + 8; |
45 | // Player 2 |
46 | if (key[KEY_UP]) player2y = player2y - 8; |
47 | if (key[KEY_DOWN]) player2y = player2y + 8; |
48 | // General |
49 | } |
BTW, if you want some pointers to speeding up the bats but not the ball, easier ways to load your graphics, drop me a PM.
Huzzah! Finally, success! The input works perfectly, thanks for all your help.
HardTranceFan, did you have to modify the graphics from Sourceforge? Because if I recall, the graphics in the resources pack were 16 bit bitmaps, like I've been having trouble with.
No changes to graphics were required. I used the retrowar set of graphics.
[edit]
Sorry, my memory failed me - the graphics are just black quads. The graphics didn't work.
[/edit]
...which still leaves the graphics problem, which is thoroughly confusing by my amatuer standards.
It's your images that are the problem, not your code. I loaded and resaved them with MSPaint, and they worked fine.
MSPaint doesn't save 16 bit bitmaps. The only option above 8 bit is 24 bit.
I don't have a problem with 24 bit bitmaps.
I think Allegro doesn't support 16bit bitmaps. If you're concerned about filesize, use PNG or if you want to save even more space at the expense of quality, JPEG. There are add-ons available for loading both formats...
Now someone tells me.
Someone needs to rewrite the manual then. Under load_bmp(), it says 16bit.
I don't know, I might be wrong. But BMP as such is a very broad term. There can be many variants and almost certainly Allegro doesn't support all of them.
I think Allegro doesn't support 16bit bitmaps.
It should. I vaguely recall that there used to be a bug that prevented it from working sometime pre 4.2, but that should be fixed.
Haven't tested it recently though.
Is your avvie an example of what your game will look like? If so, it looks cool. Glad to see your problem is fixed. I just use 24-bit for everything, it's not too much trouble.
Is your avvie an example of what your game will look like?
Not if he's using the graphics from his sourceforge page.
Actually it supports many skins (the current tally is 5 in the latest release). Something that simple shouldn't take me too long to make, and it's cool, then why not?.
My avatar is only that simple because I'm lazy .
My avatar is only that simple because I'm lazy .
You want lazy? I didn't make my avatar, or this christmas version of it, or bother changing it back to the regular one once the holidays were over.
it probibly took more effor to type that.
Could we please stay on topic?
BTW, I've created a skin based on my avatar. It sucks, but compressed it's less than 10k and decompressed it's less than 100k.
Could we please stay on topic?
I thought the matter was resolved?
Not the graphics one - there's still debate about whether Allegro is meant to work with 16 bit bitmaps. If it isn't, I'll have to live with that. If it is, we have to figure out what's wrong.
If it is, we have to figure out what's wrong.
What did you use to create the graphics in the first place? I have several graphics apps, and not a single one of them can create 16bit Windows BMPs, only 8, 24 or 32bit.
Photoshop, and I have to admit none of the other programs I've tried can do it. But they load fine in other programs.
But they load fine in other programs.
I've noticed that as well. They work with all the programs I have, but not Allegro. I've also had the same problem with BMPs in the past, but after resaving them with another program they worked.
Just use 24bit BMPs. Your game isn't that graphics intensive, so they won't take up that much more space. If size is your real concern, then don't use BMPs at all, use PNGs or GIFs, both of which can be used with Allegro through the use of other libraries.
I might use another image format but I have absolutely no idea how to load the extra libraries and stuff. As Homer Simpson would say, "It's my first day".
Close enough, anyway.
It's no different from using the Allegro library. You either build the library, or copy the library files to your compilers lib directory, then include the libraries header into your code and use the functions.
All the ones I've used have come with documentation and examples as well.
This is probably a stupid question but if I add those libraries do I have to include any extra files with the end product?
On that note, what Allegro files do I have to include in the installer, if any?
there's still debate about whether Allegro is meant to work with 16 bit bitmaps.
No debate.
It should. I vaguely recall that there used to be a bug that prevented it from working sometime pre 4.2, but that should be fixed.
Haven't tested it recently though.
EDIT: tested it with your paddle2.bmp, works fine.
I think the debate is that you say it should, everyone else says it doesn't. Anyway, I'm trying using PNGs, but not having much luck.
Whenever I try to compile, I get lots of linker errors, like
[Linker error] undefined reference to `crc32'
[Linker error] undefined reference to `inflateReset'
And such.
See above edit. What version of Allegro are you using?
Anyway, if I say it should work and it doesn't, it's a bug and should be reported as such.
Version 4.2.1
As I said though, I'm trying PNGs, and having problems, could you stop arguing and help me with that?
I think the debate is that you say it should, everyone else says it doesn't.
I would still wager in favor of Evert.
Whenever I try to compile, I get lots of linker errors, like
[Linker error] undefined reference to `crc32'
[Linker error] undefined reference to `inflateReset'
Did you link with zlib, in addition to libpng and loadpng?
I now consider the discussion moot, I'm using PNG.
I fixed my earlier problem with PNG, too - I forgot to put zlib in the linker.
EDIT: Posted at the same time as Kitty Kat. Good advice, just a bit late.
could you stop arguing and help me with that?
With that attitude, no.
Sorry about my attitude. I try not to come off as sounding mean but due to the profession of someone I know I come into contact with squabbling kids far too often. Anyway, it's solved now.