After reading this, I thought, hmmm, that sounds a like a neat idea! There's a screen shot there of a raycaster. So how many lines of code (semicolon delimited for all you cheaters) would it take to make a game in allegro?
#include<allegro.h> void main(void) { BITMAP *backbuffer=NULL; int playing=1; allegro_init(); install_keyboard(); install_timer(); set_gfx_mode(GFX_AUTODETECT,640,480,0,0); create_bitmap(SCREEN_W,SCREEN_H); while(playing) { main loop in here} return; } END_OF_MAIN();
So whats that? 11 or 12? That leaves 8 entire lines to play with! Comeon who's up to the challenge?
Semicolon delimiter? Eek. Lose the call to install_timer, and combine the buffer declaration with create_bitmap (what; you can't do that in C? Heh heh ). And check for key[KEY_ESC] instead of playing. And lose the newline right before END_OF_MAIN(), and the blank line after the #include. Brings it down to 9 lines, with 11 to play with.
create_bitmap() should return a variable to something, I presume ...
main() should return int.
Here's my offering:
1 | #include <allegro.h> |
2 | int main(void) { |
3 | int x[10]={320,320}, y[10]={460,460,-1,-1,-1,-1,-1,-1,-1,-1}, c[10]={11-12,14-12}, lives=5, i; |
4 | allegro_init(); |
5 | install_keyboard(); |
6 | set_gfx_mode(GFX_AUTODETECT,640,480,0,0); |
7 | while (lives > 0 && !key[KEY_ESC]) { |
8 | x[0] = (x[0] + 640 + (!!key[KEY_RIGHT] - !!key[KEY_LEFT]) * 4) % 640; |
9 | if ((y[1] -= 10) < 0) x[1]=x[0], y[1]=y[0]; |
10 | for (i = 2; i < 10; i++) { |
11 | x<i> = y<i>++ >= 0 ? (x<i> + 639 + (rand()&2)) % 640 : rand() % 640; |
12 | if (MAX(ABS(x<i>-x[1]), ABS(y<i>-y[1])) < 20) y<i> = -1-rand()%64; |
13 | if (y<i> >= y[0]) y<i> = -1-rand()%64, lives--; |
14 | } |
15 | for (i = 0; i < 10; i++) if (y<i> >= 0) circlefill(screen, x<i>, y<i>, 8, c<i>+12); |
16 | rest(40); |
17 | for (i = 0; i < 10; i++) if (y<i> >= 0) circlefill(screen, x<i>, y<i>, 8, 0); |
18 | } |
19 | return 0; |
20 | } END_OF_MAIN(); |
heh. cool... Its got problems though when the ball that is fired reaches the line of balls, all the balls reset (or so it seems).
Right - I was still working on it. You happened to get the first, severely broken version. Trust me to be overzealous
Finalised now
Bruce Perry; that's some damn nice work!
To tell you the truth, I didn't think anyone would be able to do it (and have it still look like a game).
heh teh collision detection is a bit loose. but I like it
And it's actually sortof fun too!
Do you want to see my "game" that does more or less the exact same thing? No less than 539 lines!
Here's another 20 line game:
1 | #include <allegro.h> |
2 | int main(int argc, char** argv) { |
3 | float speed_x = 0, speed_y = 0, gravity = 1.0, accel = 2.5, pos_x=320,pos_y=200, d; |
4 | int obj_x[10], obj_y[10],a, init = 1, ships = 4, score = 0, count = 0; |
5 | BITMAP *buffer; |
6 | allegro_init(), set_color_depth(16), set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0), install_keyboard(), install_timer(), clear(screen), buffer = create_bitmap(SCREEN_W, SCREEN_H), clear(buffer); |
7 | while (ships && !key[KEY_ESC]) { |
8 | clear(buffer), circlefill(buffer, (int)pos_x, (int) pos_y, 10, makecol(200,200,200)); |
9 | if ((init = (count <= 0))) for (a=0; a < 10; a++) obj_x[a] = rand()%SCREEN_W, obj_y[a] = rand()%SCREEN_H, count = 5, textout_centre(buffer, font, "Get Ready", 320, 100, makecol(230,230,230)); |
10 | pos_x = (pos_x > SCREEN_W && speed_x > 0.0) ? -10 : (pos_x < 10 && speed_x < 0.0) ? SCREEN_W : pos_x + speed_x; |
11 | pos_y = (pos_y > SCREEN_H && speed_y > 0.0) ? -10 : (pos_y < 10 && speed_y < 0.0) ? SCREEN_H : pos_y + speed_y; |
12 | speed_x = MID(-14.0, speed_x + (key[KEY_LEFT] ? (-accel) : (key[KEY_RIGHT] ? accel : 0)), 12.0); |
13 | speed_y = MID(-14.0, speed_y + (key[KEY_UP] ? (-accel) : (key[KEY_DOWN] ? accel : 0)) + gravity, 12.0); |
14 | for (a=0; a < 10; a++) |
15 | if ((d = obj_x[a] >= 0 ? ((pos_x - obj_x[a]) * (pos_x - obj_x[a]) + (pos_y - obj_y[a]) * (pos_y - obj_y[a])) : -10) >=0) |
16 | circlefill(buffer, obj_x[a], obj_y[a], 10, a >=5 ? makecol(200,0,0) : makecol(0,200,0)), ships -= (a>=5 && d < 400)? 1 : 0, count -= (a<5 && d < 400)? 1 : 0, score += (a<5 && d < 400)? 10 : 0,obj_x[a] = d < 400 && d >=0 ? -1 : obj_x[a]; |
17 | rest(60), textprintf_centre(buffer, font, 320, 10, makecol(100,100,230), "Score:%04i Ships: %02i", score, ships), blit(buffer, screen, 0,0,0,0,SCREEN_W, SCREEN_H); |
18 | if (init) init = 0, rest(1200); |
19 | } return 0; |
20 | } END_OF_MAIN(); |
Collect all the green balls. Don't hit the red balls. You can hit up to 4 red balls before it's game over... unlimited number of dynamic generated levels.
Oh, and if I only count the semicolons, I could get it down to 14 lines.
main() should return int.
Nice game though. Much less subtle abuse of Teh Almighty Comma
miran: don't worry - supposing I wanted to extend my game, there's only so far I could go without a complete rewrite. Small hacks are like that. Your game is bound to be more extensible, and the code more readable
Nice game though. Much less subtle abuse of Teh Almighty Comma
Hm.
Ok, if you have to nitpick... I changed my code, it's still 20 lines and uses now less (cheat) commata than yours
1 | #include <allegro.h> |
2 | int main(int argc, char** argv) { |
3 | float speed_x = 0, speed_y = 0, gravity = 1.0, accel = 2.5, pos_x=320,pos_y=200, d; |
4 | int obj_x[10], obj_y[10],a, ships = 4, score = 0, count = 0; |
5 | BITMAP *buffer = allegro_init() ? NULL : install_keyboard() ? NULL : install_timer() ? NULL : set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0) >= 0 ? create_bitmap(SCREEN_W, SCREEN_H) : NULL; |
6 | while (ships && !key[KEY_ESC]) { clear(buffer); |
7 | circlefill(buffer, (int)pos_x, (int) pos_y, 10, makecol(200,200,200)); |
8 | if (count <= 0) textout_centre(buffer, font, "Get Ready", 320, 100, makecol(230,230,230)); |
9 | pos_x = (pos_x > SCREEN_W && speed_x > 0.0) ? -10 : (pos_x < 10 && speed_x < 0.0) ? SCREEN_W : pos_x + speed_x; |
10 | pos_y = (pos_y > SCREEN_H && speed_y > 0.0) ? -10 : (pos_y < 10 && speed_y < 0.0) ? SCREEN_H : pos_y + speed_y; |
11 | speed_x = MID(-14.0, speed_x + (key[KEY_LEFT] ? (-accel) : (key[KEY_RIGHT] ? accel : 0)), 12.0); |
12 | speed_y = MID(-14.0, speed_y + (key[KEY_UP] ? (-accel) : (key[KEY_DOWN] ? accel : 0)) + gravity, 12.0); |
13 | for (a=0; a < 10; a++) { if ((d = obj_x[a] >= 0 ? ((pos_x - obj_x[a]) * (pos_x - obj_x[a]) + (pos_y - obj_y[a]) * (pos_y - obj_y[a])) : -10) >=0) { circlefill(buffer, (count <= 0) ? obj_x[a] = rand()%SCREEN_W : obj_x[a], (count <= 0) ? obj_y[a] = rand()%SCREEN_H : obj_y[a], 10, a >=5 ? makecol(200,0,0) : makecol(0,200,0)); |
14 | ships -= (a>=5 && d < 400)? 1 : 0, count -= (a <5 && d < 400)? 1 : 0, score += (a <5 && d < 400)? 10 : 0, |
15 | obj_x[a] = d < 400 && d >=0 ? -1 : obj_x[a];}} |
16 | rest(60); |
17 | textprintf_centre(buffer, font, 320, 10, makecol(100,100,230), "Score:%04i Ships: %02i Remaining: %i", score, ships, count <= 0 ? count = 5 : count), blit(buffer, screen, 0,0,0,0,SCREEN_W, SCREEN_H); |
18 | } return 0; |
19 | } END_OF_MAIN(); |
And please, don't force me to change that code again
and combine the buffer declaration with create_bitmap (what; you can't do that in C? Heh heh ).
You can combine the buffer decl with create_bitmap
Yeah.
Managed to cut one more line
BITMAP *buffer = allegro_init() ? NULL : install_keyboard() ? NULL : install_timer() ? NULL : set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0) >= 0 ? create_bitmap(SCREEN_W, SCREEN_H) : NULL;
I'd call that ?: abuse, but hey, it works, right
How about it? A competition in who makes the best game with 20 lines of code?
My "de-commat" version also has a bug during level increase, so I suggest you guys use my first version.
I'd call that ?: abuse, but hey, it works, right
You have to scramble some eggs
Oh, and with 40 lines of code, you might even be able to do a cool game without cheating (both Bruce and I cheated by using commata...
Using the trinary op is IMHO not really cheating. I mean, the allegro overhead itself is pretty high (if you don't use trinary ops, that is)
return 0; can be omitted in both C++ as well as C99.
I think that would be a neat contest, maybe if the rules were a little less strict like 100 lines maybe. This would force people to be creative and learn to write effecient code!
Efficient? I think you mean "condensed"! It's still a fun exercise ...
Interestingly enough, all the 20 liners written so far have actually been 19 lines; since they're semicolon delimeted the "int main(){" doesn't count as a line.
Well, neither does #include <allegro> but the need for a return after it implies that it should be counted as a line anyway, I guess ...
20 lines... just enough to fit in my comment describing the purpose of the main function ^_^ Be happy we aren't competing in fattest documentation >:)
Just realized that by a literal interpretation of "semicolon delimited" a for (;;) statement requires 3 lines ... heh, but you can fit "squeeze" a program by fitting statements like "x = 2" into "if (x=2) the_next_line; ... so we can rewrite bruce's program like this:
1 | #include <allegro.h> |
2 | int main(void) { |
3 | int x[10]={320,320}, y[10]={460,460,-1,-1,-1,-1,-1,-1,-1,-1}, c[10]={11-12,14-12}, lives=5, i; |
4 | if (allegro_init()>=0&&install_keyboard()>=0&&set_gfx_mode(GFX_AUTODETECT,640,480,0,0)>=0){ |
5 | while (lives > 0 && !key[KEY_ESC]) { if (x[0] = (x[0] + 640 + (!!key[KEY_RIGHT] - !!key[KEY_LEFT]) * 4) % 640) if ((y[1] -= 10) < 0) if (x[1]=x[0], y[1]=y[0]) for (i = 2; |
6 | i < 10; |
7 | i++) if (x<i> = y<i>++ >= 0 ? (x<i> + 639 + (rand()&2)) % 640 : rand() % 640) if (MAX(ABS(x<i>-x[1]), ABS(y<i>-y[1])) < 20) if(y<i> = -1-rand()%64) if (y<i> >= y[0]) if (y<i> = -1-rand()%64, lives--); |
8 | for (i = 0; |
9 | i < 10; |
10 | i++) if (y<i> >= 0) circlefill(screen, x<i>, y<i>, 8, c<i>+12); |
11 | rest(40); |
12 | for (i = 0; |
13 | i < 10; |
14 | i++) if (y<i> >= 0) circlefill(screen, x<i>, y<i>, 8, 0); }} |
15 | return 0; |
16 | } END_OF_MAIN(); |
Edit: My snippet is messed up, but hopefully you get the point.
I think we rather change the contest to "what game can you squeeze in into 20 lines and 20 columns?
Oh yeah; that's definitely the coolest idea. You just get a grid of 20 by 20 characters to fill up, and try to make a game ... and there is no such thing as cheating. Perhaps it would be more interesting to go 100x15 or something, though.
Do we want to do a compo around this? It could be fun!
Heh. That idea is great
Why not 80x25? That would be one textmode screen full of code
It is a good idea,. but why limit it to certain dimensions if all that means is a certain number of characters? 100x15 means a total of 1500 characters. 80x25 means a total of 2000 characters. So why not make the contest a total character contest instead of a dimensional contest?
I dunno ... I thought the dimensional thing added a neat little cuteness / originality; it's essentially the same as a char-count but more restricting and encourages a bit more interesting results by forcing the coder to focus on the graphical appearance of the code itself ...
thats true, but to maximize your winning chances, you would have to write as much code on one line as possible. in the end, you will have 25 lines of completely filled code. it wouldnt be hard for me to write some code, take out all the tabs, make sure every line ends at exactly 80 characters, and only have 1 space between every token. the dimensions dont force me to do anythign except have a certain number of characters.
I was working on atwo player pong last night too bad I was too tired to finish
But its at like 22 lines (pretty much finished, just need to fix a bug...)
Restricting to lines and columns might work if you discount headers, since #includes need their own lines, right? I like the character count idea better ... and Spellcaster's source code gives me a headache. Crafty use of ?: though
You should see mine... Lots of &&, || and ()
edit: well, It USED to have lots of &&, || and ()... But writing code on 2 hours (in 48) of sleep is a bad idea.
Nice work SC and BP; see if I can get mine done tonight... it won't be 20 lines though; maybe 30
well.. Heres my entry
1 | #include <allegro.h> |
2 | |
3 | int main(void) { int x=320,y=240,dx=-1,dy=1,p1y=240,p2y=240,p1p=0,p2p=-1; |
4 | BITMAP *buff = (BITMAP *)(NULL,srand(time(NULL)),allegro_init(),install_keyboard(),set_gfx_mode(GFX_AUTODETECT,640,480,0,0)); |
5 | buff = create_bitmap(640, 480); |
6 | while(!key[KEY_ESC] && !key[KEY_Q]) { clear(buff); |
7 | (x-2 <= 0 || x+2 >= 640) ? dx = -dx : ((y-2 <= 0 || y+2 >= 480) ? dy = -dy : 0); |
8 | ((x += dx), (y += dy)); |
9 | (0 <= x-2 && x-2 <= 10) ? ( (p1y-12 <= y+2 && y+2 <= p1y+12) ? (dx = -dx) : (++p2p, (x=320), (y=rand()%480)) ) : 0; |
10 | (630 <= x+2 && x+2 <= 640) ? ( (p2y-12 <= y+2 && y+2 <= p2y+12) ? (dx = -dx) : (++p1p, (x=320), (y=rand()%480)) ) : 0; |
11 | if(key[KEY_UP] && p2y > 12) p2y-=2; |
12 | if(key[KEY_DOWN] && p2y < 468) p2y+=2; |
13 | if(key[KEY_W] && p1y > 12) p1y-=2; |
14 | if(key[KEY_S] && p1y < 468) p1y+=2; |
15 | textprintf_centre(buff, font, 320, 2, makecol(200,200,200), "%03i %03i", p1p, p2p); |
16 | vline(buff, 320, 0, 480, makecol(255,255,255)); |
17 | vline(buff, 10, p1y-10, p1y+10, makecol(255,255,255)); |
18 | vline(buff, 630, p2y-10, p2y+10, makecol(255,255,255)); |
19 | circlefill(buff, x-2, y-2, 2, makecol(255,255,255)); |
20 | blit(buff, screen, 0, 0, 0, 0, 640, 480); |
21 | } return 0; |
22 | } END_OF_MAIN(); |
It doesn't make the requirements (and is a bit buggy...). But I like it
[edit]new version (w00t. It still doesn't quite make it nonnus) oops.. that should be 20...
[edit2] hmmmm.. I can shorten those 3 vlines to a for and 1 vline... sould I
EDIT: Here's my shooter; its 22 lines though, very light on the comma's (only one line uses comma's, the allegor line) No collision detection, but you can shoot your little gun
1 | #include <allegro.h> |
2 | int main(void) { BITMAP *backbuffer=NULL; |
3 | int i=0,sprites[6][6]={ {150,180,0,30,1,0},{30,0,0,0,0,0},{100,10,10,0,1,10},{75,20,-10,0,1,10},{150,30,10,0,1,10},{210,40,-10,0,1,10}}; |
4 | allegro_init(),install_keyboard(), set_gfx_mode(GFX_AUTODETECT,320,200,0,0); |
5 | backbuffer=create_bitmap(SCREEN_W,SCREEN_H); |
6 | while(!key[KEY_ESC]) { clear_bitmap(backbuffer); |
7 | if (key[KEY_A] && sprites[1][5]<=0) {sprites[1][0]=sprites[0][0]; |
8 | sprites[1][5]=37;} |
9 | if (key[KEY_RIGHT] && sprites[0][0]<310) sprites[0][0]+=5; |
10 | if (key[KEY_LEFT] && sprites[0][0]>15) sprites[0][0]+=-5; |
11 | for(i=2;i<6;i++) { if(sprites<i>[2]>0 && sprites<i>[0]<300) sprites<i>[0]+=sprites<i>[2]; |
12 | else if(sprites<i>[2]<0 && sprites<i>[0]>20) sprites<i>[0]+=sprites<i>[2]; |
13 | else sprites<i>[2] *= -1; |
14 | circlefill(backbuffer,sprites<i>[0],sprites<i>[1],4,50);} |
15 | if(sprites[1][5] >0) { sprites[1][5]--; |
16 | sprites[1][1]=(sprites[1][5]* 5); |
17 | circlefill(backbuffer,sprites[1][0],sprites[1][1],4,50);} |
18 | circle(backbuffer,sprites[0][0],sprites[0][1],4,3); |
19 | blit(backbuffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); |
20 | rest(30);} |
21 | return 0; } |
22 | END_OF_MAIN(); |
Nice pong TF; cheat on the comma's (like everyone else) in your allegro init code and you can get it under 20
can anyone say FORTRAN? Ahhh, Flashback, Flashback.....columns 1-9 ahhhh....
Jay
COMEON PEOPLE!!! We Wanna see more! You know you want to!
1 | #include <allegro.h> |
2 | volatile int clicker = 0; |
3 | void ClickerThing(void) {clicker++;} END_OF_FUNCTION(ClickerThing) |
4 | void main(void) |
5 | { |
6 | int x = 320, y = 240, x_speed = 0, y_speed = 0; |
7 | BITMAP *buff; |
8 | srand(time(NULL)); |
9 | allegro_init(), install_keyboard(), install_timer(), set_color_depth(16), set_gfx_mode(GFX_AUTODETECT,640,480,0,0); |
10 | buff = create_bitmap(640, 480); |
11 | LOCK_FUNCTION(ClickerThing) LOCK_VARIABLE(clicker) install_int(ClickerThing, 10); |
12 | while (!key[KEY_ESC]) { while((clicker = (clicker > 0)?-1:0) && !key[KEY_ESC]) { |
13 | clear(buff), textout_centre(buff, font, "Hello World", x, y, makecol(255-(x>>2), 0, 255-(y>>1))); |
14 | x_speed = (x_speed > 5 || x > 540)?x_speed-1 :(x_speed < -5 || x < 100)?x_speed+1 :x_speed+rand()%3-1; |
15 | y_speed = (y_speed > 5 || y > 460)?y_speed-1 :(y_speed < -5 || y < 20)?y_speed+1 :y_speed+rand()%3-1; |
16 | x+=x_speed; |
17 | y+=y_speed; |
18 | blit(buff, screen, 0, 0, 0, 0, 640, 480); } } |
19 | remove_int(ClickerThing), destroy_bitmap(buff), allegro_exit(); |
20 | } END_OF_MAIN() |
Mine doesn't have much in the way of gameplay...
BUT mine is the only one (so far) that has a cleanup routine and runs the same speed on all computers.
(don't look at the while line, it's not nice...)
--- Edit ---
Ok ok, that's not a game at all, but now i've modifided it... it's now as obfuscated as all hell (unintentionally I might add), but now it's a game.
The faster you are moving the more points you get. Dodge the circles.
1 | #include <allegro.h> |
2 | volatile int clicker = 0; |
3 | void ClickerThing(void) {clicker++;} END_OF_FUNCTION(ClickerThing) |
4 | void main(void) { int x = 320, y = 240, x_speed = 0, y_speed = 0, lives = 10, score = 1, i, e[8] = {0, 0, 0, 0, 0, 0, 0, 0}; |
5 | BITMAP *buff; |
6 | srand(time(NULL)), allegro_init(), install_keyboard(), install_timer(), set_color_depth(16), set_gfx_mode(GFX_AUTODETECT,640,480,0,0); |
7 | buff = create_bitmap(640, 480); |
8 | LOCK_FUNCTION(ClickerThing) LOCK_VARIABLE(clicker) install_int(ClickerThing, 5); |
9 | while (!key[KEY_ESC] && lives>0) { while(lives>0 && (clicker = (clicker > 0)?-1:0) && !key[KEY_ESC]) { |
10 | clear(buff), triangle(buff, x, y, x, y+10, x+16, y+5, makecol(255-(x>>2), 0, 255-(y>>1))); |
11 | x_speed = (x_speed > 5 || x > 600)?x_speed-1 :(x_speed < -5 || x < 20)?x_speed+1 :x_speed-key[KEY_RIGHT]+key[KEY_LEFT]; |
12 | y_speed = (y_speed > 5 || y > 440)?y_speed-1 :(y_speed < -5 || y < 20)?y_speed+1 :y_speed-key[KEY_DOWN]+key[KEY_UP]; |
13 | y = ((i=8) && (x=x+x_speed) && (score = (score+(abs(x_speed)+ABS(y_speed))/2)))?y+y_speed :0; |
14 | while(i-- > 0){ e<i> = (e<i> < 20)?600+rand()%40 :e<i>-2; |
15 | circle(buff, e<i>, (i%2)?(e<i>*3)%440+20:460-(e<i>*3)%440, 5, makecol(150, 150, 0)); |
16 | e<i> = (e<i>-5 < x+16 && e<i>+3 > x && ((i%2)?(e<i>*3)%440+15:455-(e<i>*3)%440) < y+10 && ((i%2)?(e<i>*2)%440+25:465-(e<i>*3)%440) > y)?lives-- :e<i>; } |
17 | textprintf(buff, font, 5, 5, makecol(0, 180, 0), "Score: %6d Lives: %2d", score, lives); |
18 | blit(buff, screen, 0, 0, 0, 0, 640, 480); } } |
19 | remove_int(ClickerThing), destroy_bitmap(buff), allegro_exit(); |
20 | } END_OF_MAIN() |
Well, my game is 19 lines long right now, if I tallied correctly. I've only a bit more left before it's playable. Unfortunately, it's bed time.
And I'll be lucky if I can remember how it works tomorrow though.
The name of the game is "20 Lines", and it's a dandy.
If I can think of something more original than Pong.. I'll post it
Ohhh.. maybe Plinko
Here's my 20 lines:
1 | #include <allegro.h> |
2 | static volatile float timer = 0.0f, score = 0.0f, highscore = 0.0f, r = 15.0f, clickCounter = 0.0f, x=160.0f, y=195.0f, vx=0.0f, vy=0.0f; |
3 | static void timer_f() { timer += 1.0f; } END_OF_STATIC_FUNCTION(timer_f); |
4 | void main() { |
5 | BITMAP *buffer; |
6 | allegro_init(), install_keyboard(), install_timer(), install_mouse(), set_color_depth(16), set_gfx_mode(GFX_AUTODETECT_WINDOWED, 320, 240, 0, 0), clear(screen), buffer = create_bitmap(SCREEN_W, SCREEN_H), clear(buffer), text_mode(-1); |
7 | LOCK_VARIABLE(timer) LOCK_FUNCTION(timer_f) install_int_ex(timer_f, BPS_TO_TIMER(40)); |
8 | while (!key[KEY_ESC]) { while (timer = (timer>0.0f) ? -1.0f : 0.0f) { if ((clickCounter = (clickCounter == 0.0f) ? (mouse_b ? 10.0f : 0.0f) : (clickCounter-1.0f) == 10.0f) && mouse_b && ((x - mouse_x)*(x - mouse_x) + (y - mouse_y)*(y - mouse_y) <= r*r)) vy = 12.0f, vx = (x - mouse_x)/1.5f, score += 1.0f; |
9 | x += (vx *= 0.995f); |
10 | vx = (x < r || x > SCREEN_W) ? (-vx) : (vx); |
11 | y -= ((vy >= 1.0f) ? (vy *= 0.85f) : ((vy <= -1.0f) ? (vy /= 0.88f) : ((vy > 0.0f) ? (vy = -1.0f) : ((vy < 0.0f) ? (vy = 1.0f) : (0.0f))))); |
12 | (y > 195.0f) ? (y = 195.0f, vx *= 0.85f, (vy = (vy >= -1.0f) ? (0.0f) : (-0.7f*vy)), (highscore = (score > highscore) ? (score) : (highscore)), score = 0.0f) : (y); } |
13 | clear_to_color(buffer, makecol(212,218,255)); |
14 | textprintf(buffer, font, 0, 0, makecol(0,0,0), "score = %03d, high score = %03d", (int)score, (int)highscore); |
15 | circlefill(buffer, (int)x, (int)y, (int)r, makecol(255,255,255)); |
16 | rectfill(buffer, 0, 210, SCREEN_W-1, SCREEN_H-1, makecol(0,200,0)); |
17 | draw_sprite(buffer, mouse_sprite, mouse_x, mouse_y); |
18 | blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); } |
19 | remove_int(timer_f), destroy_bitmap(buffer); |
20 | } END_OF_MAIN(); |
Keep the ball in the air for as long as you can...
EDIT: fixed a little bug...
heh. The flash version is fun too... though I bet its more lines of code!
Here's my first attempt:
1 | #include <allegro.h> |
2 | int main() { |
3 | int p_y=240, x[25], y[25], size[25], i, delay=0, lives=10; |
4 | BITMAP *buffer=NULL; |
5 | if (!allegro_init() && set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) ); |
6 | if (!install_keyboard() && (buffer=create_bitmap(640, 480))) srand(time(0)); |
7 | for (i=0; i<20; i++) |
8 | ((x<i>=rand()%640+640)|(y<i>=rand()%480)|(size<i>=rand()%20+5)); |
9 | while (!key[KEY_ESC]) { |
10 | key[KEY_UP]&&p_y>0 ? p_y=(p_y-2):(key[KEY_DOWN]&&p_y<480? p_y=(p_y+2):0); |
11 | for (i=0; i<20 && lives>0; i++) { |
12 | x<i> -= 13-size<i>/2+(delay++)/16384; |
13 | if ((x<i>-5)*(x<i>-5)+(y<i>-p_y)*(y<i>-p_y) <= (size<i>+5)*(size<i>+5)) |
14 | ((x<i>=rand()%640+640) | (y<i>=rand()%480) | --lives); |
15 | if (x<i> < 0) ((x<i>=rand()%640+640) | (y<i>=rand()%480)); |
16 | circlefill(buffer, x<i>, y<i>, size<i>, size<i>/2); |
17 | } |
18 | circlefill(buffer, 5, p_y, 4, 15); |
19 | textprintf(buffer, font, 200, 2, 15, "Lives: %d Score: %d", lives, delay); |
20 | blit(buffer, screen, 0, 0, 0, 0, 640, 480); |
21 | clear(buffer); |
22 | rest(10); |
23 | } |
24 | return 0; |
25 | } END_OF_MAIN() |
The code has the following features:
- It fits in 80x25
- No commas except for variable definitions
- Each line has only one semicolon or bracket {}, except for the semicolons inside the for () expression.
- An indentation scheme.
- And hopefully no warnings under -Wall
There is no newline at the end of file!
EDIT:
Actually there are 3 warnings on lines 8, 14 and 15...
heh. Mine's only got one warning with -W and -Wall on line 4
Now try using -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations -Wno-system-headers. (Also try without -Wno-system-headers if you're a masochist.)
ooohhhh... and 1 more on line 3... ouch. that hurt.
edit: Quit editing while I'm posting. Its getting anoying
edit2:
tf.c:3: warning: no previous declaration for `_mangled_main'
tf.c: In function `_mangled_main':
tf.c:4: warning: left-hand operand of comma expression has no effect
still ouch. and I can't do a bloody thing about _mangled_main.
edit3: Also tried removing -Wno-system-headers. Nothing changed.
EDIT:
Actually there are 3 warnings on lines 8, 14 and 15...
Good thing I said "hopefully"!
Actually when I compile with MinGW 2.0, I get no warnings under -Wall, and a warning on line 5 with -W.
int main(void); int main(void) { ...
I found -Wno-system-headers was necessary, because one of the earlier flags made it warn for lots of stuff in allegro.h. I suppose it depends on the GCC version.
As for line 5, I always use { }. Personally I don't think they should have removed that warning - you might have written the following by accident:
while (...); { ... }
Miran: Awesome game. That should ship with every copy of windows!
Here's my entry:
1 | #include<allegro.h> |
2 | int main(void){ |
3 | int posx[10]={65,120,180,240,305,360,420,480,540,600},posy[10]={-200,-200,-200,-200,-200,-200,-200,-200,-200,-200},colour[10],dy[10]={1,2,3,3,2,1,2,1,1,2},cx=320,cy=460,score=0,time=2000; |
4 | if(allegro_init()>=0 && install_keyboard()>=0 && install_timer()>=0 && install_mouse>=0 && set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0) >=0){ |
5 | BITMAP *backgr=create_bitmap(SCREEN_W,SCREEN_H); |
6 | for(int n=0 ; n<10 ; n++) colour[n]=makecol(rand()%255,rand()%255,rand()%255); |
7 | while(!key[KEY_ESC]) { clear(backgr); |
8 | for(int n=0 ; n<10 ; n++, posy[n]+=dy[n]){ circlefill(backgr,posx[n],posy[n],2,colour[n]); |
9 | if(posy[n]>480){ posy[n]=rand()%100-300; |
10 | posx[n]=rand()%600+20; } |
11 | if(posx[n]>cx && posx[n]<cx+50 && posy[n]>cy && posy[n]<cy+20){ score+=dy[n]; |
12 | posy[n]=-100; }} |
13 | cx+= key[KEY_LEFT]*10 - key[KEY_RIGHT]*10; |
14 | rectfill(backgr,cx,cy,cx+50,cy+20,makecol(255,200,100)); |
15 | textprintf_centre(backgr,font,SCREEN_W/2,2,makecol(0,255,255),"Score: %d Time Left: %d",score,(time--)/10); |
16 | blit(backgr,screen,0,0,0,0,SCREEN_W,SCREEN_H); |
17 | while(!key[KEY_ESC] && time<0){}; |
18 | rest(15); }} |
19 | }END_OF_MAIN(); |
Just catch as many balls as you can.
Miran - that is a really cool game; good idea!
As for line 5, I always use { }.
Who is that directed at?
Who is that directed at?
ROFLMAO Now that really made me laugh.
Now if it were line 25 we could narrow it down a little, but line 5 in this thread? No chance.
ja.. IIRC I have a while on line 5, but I also have brakets sooo... And whats weird, is Ben seems to think that all those extra -W's will change the messages i get... but neither 2.95.4 or 3.2 makes a difference sooo. heh.
What's weirder, is that if I set a DGA mode in X, my player two score starts off with 1, but If I set a Xwindow full screen mode, player 2's score starts off at 0... Pain in the royal A$$.
Allright heres my entry, Nibbles/Snake 19 lines, or 20 if you count the comment on the top
1 | //Wow, i still have room for comments, Nibbles/Snake Game in 20 lines... |
2 | #include <allegro.h> // ... By Hard Rock |
3 | int main(void) { |
4 | int alive = 1,x = 100, y = 100, direction = 0,score = 0; |
5 | allegro_init(); |
6 | install_keyboard(); |
7 | install_timer(); |
8 | set_gfx_mode(GFX_AUTODETECT,320,200,0,0); |
9 | hline(screen,0,8,screen->w,4); |
10 | while (alive && !key[KEY_ESC]) { //Main Loop |
11 | textprintf_centre(screen, font, 100, 0, 1, " Your Score is %d",score ); |
12 | if(x < 0 || x > screen->w || y < 9 || y > screen->h) break; //Hits end and our snake is dead, was gonna do alive = 0, but what the heck. break works too |
13 | key[KEY_UP] ? direction = 0: key[KEY_DOWN] ? direction = 1 : key[KEY_RIGHT] ? direction = 2 : key[KEY_LEFT] ? direction = 3 : NULL; //Check which buttons are pressed and where to go |
14 | direction ==0 ? y = y -1 : direction ==1 ? y = y + 1 : direction ==2 ? x = x +1 : direction == 3 ?x = x-1:NULL; |
15 | if(getpixel(screen,x,y) == 1) alive = 0; |
16 | putpixel(screen,x,y,1); |
17 | rest(10); |
18 | score++; |
19 | } return 0; |
20 | } END_OF_MAIN(); |
I could probably cheat and drop a lot more lines, but it works fine as is... well maybe is should make the score a long.................. becuase it wont take long for the int to overfill.
So you can just drop comments then and change it.., easily yourself if you want.
Well, after seeing that Hard Rock has done a nibbles/snake game, I don't know if my entry is going to be very impressive, but here goes. It's one of those 15-square puzzles. Enjoy!
1 | #include <allegro.h> |
2 | int main() { |
3 | int cells[16] = { 12, 5, 10, 6, 2, 4, 11, 7, 13, 3, 0, 8, 14, 1, 15, 9 }, i, zp, c, cp, quit = 0; |
4 | allegro_init(); |
5 | install_mouse(); |
6 | set_gfx_mode(GFX_AUTODETECT_WINDOWED, 320, 240, 0, 0); |
7 | show_mouse(screen); |
8 | while(!(mouse_b & 2) && !quit) { |
9 | for(i = 0; i < 16; i++, zp = cells<i> ? zp : i) |
10 | textprintf(screen, font, 64 + i % 4 * 48, 32 + i / 4 * 48, cells<i>, "%d ", cells<i>); |
11 | if((c = getpixel(screen, mouse_x, mouse_y)) && mouse_b & 1) { |
12 | for(i = 0; i < 16; i++) |
13 | cp = (c == cells<i> ? i : cp); |
14 | if(vector_length_f(zp % 4 - cp % 4, zp / 4 - cp / 4, 0) < 1.01) |
15 | cells[zp] = c, cells[cp] = 0; |
16 | } |
17 | for(i = 0, quit = 1; i < 14; i++) |
18 | quit = cells<i> > cells[i + 1] ? 0 : quit; |
19 | } |
20 | } END_OF_MAIN(); |
It's 20 lines, and it's pretty much normal C-style indenting except for the fact that all of the lines are stuck together, and ignoring that little commanated 14th line that I hope no one notices
[EDIT]
By the way, are we going to do the whole 80x25 screen thing? I think it would be pretty damn cool. The rules are straightforward enough... let's say one file, must fit in 80x25 screen, absolutely no exceptions, no external files, and we post them in a thread in a week or so? What do you guys say? If whoever suggested the idea doesn't want to, I'll organize it
goodbytes... quit is not initialized set it to 0 otherwise sometimes it will just exit immediately like it did to me.
lines of code (semicolon delimited for all you cheaters)
Ok, by strict interpretation of the rules, my game is 16 lines long.
The name of the game is "20 Lines". Interesting fact (to me anyway) is that it only one variable is created in the process (and a second one use used for static data).
NO cheating here. I would not stoop to the level of using commas!
No warnings are generated during compilation using -W -Wall.
And yes, I wrote it all by hand. Thank Bill Gates for VC.NET which easily lets me see which ( [ { pair with } ] )...
The controls are a bit laggy, I never got around to updating that portion of the code.
View it here: [url http://www.leverton.cc/misc/20lines.html]
http://www.leverton.cc/pics/20lines.png
You my friend are officially insane. Welcome to the club.
I ddin't think it would be possible to do a tetris clone.. But here you've proved me wrong.
One thing though. The fact that it's windowed scores against it the XWIN driver is slower than the GDI driver.
edit: Oh, so the controlls really are laggy? ok. I thought that was the fault of the driver. I know my pong is laggy in windowed mode...
Well, there's no reason it cannot be full screen. Just AUTODETECT_FULLSCREEN and set real screen size. Also, on the final buffer->screen blit, you wouldn't have to do a SCREEN_W,SCREEN_H as that would do a lot of extra black space.
The main reason it's laggy is that I only allow the Key's to be pressed at certain times, that way they blocks don't just slide around like crazy. It works fine on my XP 1800 PC, but is a bit laggy on my C333 running FreeBSD.
so your code draws it all centered or something? So setting a large mod wouldn't do anything weird?
edit: Guess not. The controlls are much better now
ja. that should work. I still think you need counseling.
You should think about submitting that to the ioccc one year.
edit:
w00t. and it only took an hour. I've slimmed down and unhackified (lots less comma hack) my pong a bit, here for your enjoyment tfpong 2.0beta1:
/*1 */int main(void) { int i=0,x=320,y=rand()%480,dx=-1,dy=1,p1y=240,p2y=240,p1p=0,p2p=0,y1d=10,y2d=470, xs[] = {320, 10, 630}, *y1s[] = { &y1d, &p1y, &p2y }, *y2s[] = { &y2d, &p1y, &p2y }; /*2 */ BITMAP *buff = (allegro_init() == 0 && install_keyboard() == 0 && set_gfx_mode(GFX_AUTODETECT,640,480,0,0) == 0) ? create_bitmap(SCREEN_W, SCREEN_H) : NULL; /*3 */ while(buff && !key[KEY_ESC] && !key[KEY_Q]) { clear(buff); /*4 */ ( ((x += dx) | (y += dy)) && (y-2 <= 0 || y+2 >= 480) ) ? (dy = -dy) : ( ( (x-2 <= 10) && (p1y-12 <= y-2 && y+2 <= p1y+12)) ? (dx = -dx) : ( (x-2 <= 10) ? (++p2p, (x=320), (y=rand()%480)) : ( ( (x+2 >= 630) && (p2y-12 <= y-2 && y+2 <= p2y+12)) ? (dx = -dx) : ( (x+2 >= 630) ? (++p1p, (x=320), (y=rand()%480)) : 1)))); /*5 */ (key[KEY_UP] && p2y > 12) ? (( (key[KEY_DOWN] && p2y < 468) ? (p2y+=2) : 1) && (p2y-=2)) : ( (key[KEY_DOWN] && p2y < 468) ? (p2y+=2) : 1); /*6 */ (key[KEY_W] && p1y > 12) ? (( (key[KEY_S] && p1y < 468) ? (p1y+=2) : 1) && (p1y-=2)) : ( (key[KEY_S] && p1y < 468) ? (p1y+=2) : 1); /*7 */ textprintf_centre(buff, font, 320, 2, makecol(200,200,200), "%03i %03i", p1p, p2p); /*8 */ for(i=0; i < 3; ++i) vline(buff, xs<i>, (*y1s<i>)-10, (*y2s<i>)+10, makecol(255,255,255)); /*9 */ circlefill(buff, x-2, y-2, 2, makecol(255,255,255)); /*10*/ blit(buff, screen, 0, 0, 0, 0, 640, 480); /*11*/ } return 0; /*12*/}END_OF_MAIN();
notes: This new version should be equivelent to the last, including the same bugs, as its the same code, just reoganized a bit.
Bravo Matthew! Line 7 is the longest line of code I have ever seen. I was trying to think of how to do Tetris clone in that amount of space. You must have really been 'in the zone' for this one!
EDIT: We've got a two player pong, a tetris, snakes, a couple of shooters, a bouncy ball game, a tile puzzle, some shooters... come on people, Who's going to take us into THE THIRD DIMENSION??
THE THIRD DIMENSION
Funny you should mention that...
1 | #include <allegro.h> |
2 | #include <math.h> |
3 | class Vector {public: float x, y, z; Vector& operator*=(float l) { x*=l, y*=l, z*=l; return *this;}} Origin; |
4 | void fd_planes(int x, int y, int *u, int *v, int *z) { Vector Direction = {(x-160)/120.0f,(y-100)/120.0f,1}, Intersect; |
5 | Direction *= 1.0f/sqrt(Direction.x*Direction.x + Direction.y*Direction.y + Direction.z*Direction.z); |
6 | float t = ((Direction.y>0?1:-1)*550-Origin.y)/Direction.y; |
7 | Intersect.x = Origin.x + Direction.x*t, Intersect.y = Origin.y + Direction.y*t, Intersect.z = Origin.z + Direction.z*t; |
8 | *u = (int)(fabs(Intersect.x)*0.3); |
9 | *v = (int)(fabs(Intersect.z)*0.3); |
10 | ((t = (Intersect.x-Origin.x)*(Intersect.x-Origin.x) + (Intersect.z-Origin.z)*(Intersect.z-Origin.z)) <= 1.0E-6) ? (*z = 0) : (t = 50000.0/sqrt(t), *z = (int)(t > 63 ? 63 : t));} |
11 | static volatile int timer = 0; |
12 | static void timer_f() { ++timer; } END_OF_STATIC_FUNCTION(timer_f); |
13 | void main() { int deltaz = 32, u=0, v=0, z=0, i,j; |
14 | BITMAP *buffer, *texture; |
15 | allegro_init(), install_keyboard(), install_timer(), set_color_depth(16), set_gfx_mode(GFX_AUTODETECT_WINDOWED, 320, 200, 0, 0), clear(screen), buffer = create_bitmap(SCREEN_W, SCREEN_H), clear(buffer), texture = create_bitmap(256,256); |
16 | for (i=0; i<256; i++) for (j=0; j<256; j++) putpixel(texture, i, j, (i&j)|(~i^j)); |
17 | LOCK_VARIABLE(timer) LOCK_FUNCTION(timer_f) install_int_ex(timer_f, BPS_TO_TIMER(25)); |
18 | Origin.x = 0.0f, Origin.y = 0.0f, Origin.z = 0.0f; |
19 | while (!key[KEY_ESC]) { while ((timer = (timer>0) ? -1 : 0)) { --timer, Origin.z += (float)deltaz; } |
20 | for (int y=0; y<SCREEN_H; ++y) { for (int x=0; x<SCREEN_W; ++x) { fd_planes(x,y,&u,&v,&z), putpixel(buffer, x, y, makecol((getr(getpixel(texture, u&255, v&255))*(int)z)>>6, (getg(getpixel(texture, u&255, v&255))*(int)z)>>6, (getb(getpixel(texture, u&255, v&255))*(int)z)>>6));}} |
21 | blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); } |
22 | } END_OF_MAIN(); |
It's not exactly 20 lines, it's 22 but two of them are includes. Also it is in C++ not C and I cheated big time on this one with the commas and all that. It's impossible to make a raytracer in 20 lines whithout cheating. Oh yeah, it's a raytracer so it should be pretty slow on low end machines...
Very impressive so far! Too bad I couldn't run Miran's code...
Why not? Do you have a slow machine or does the code not work/compile?
Nothing you can fix:
eglebbk@huygens: ~/Program/20>g++ -W -Wall miran.cc -o miran `allegro-config --libs` miran.cc: In function `void _mangled_main()': miran.cc:13: warning: unused variable `int c' eglebbk@huygens: ~/Program/20>./miran ld.so.1: ./miran: fatal: libstdc++.so.2.10.0: open failed: No such file or directory Killed
I'll try on my own Linux box later.
The machine I'm on now probably is too slow too...
Worked for me. It was a bit slow, But it shul be fine in Full screen mode. Yup. the ESC key reacts alot quicker in full screen mode
goodbytes... quit is not initialized set it to 0 otherwise sometimes it will just exit immediately like it did to me.
No, it's... it's... damn.
Blame that on untested code changes.
p.s. Miran and Matthew, you are el337 h4XX0r5.
Anyone done TicTacToe already? No? Fine here's mine
I spend about an hour on that one. It'd be nice if I could add some AI to it - I have three whopping lines left to play with afterall;D!
More if I'm allowed to use 20 ;'s in my code.
So who'se going to post the first RPG?
1 | #include <allegro.h> |
2 | #include <time.h> |
3 | #define DRAWTILE(c) rect(screen, c/3*33, c%3*33, c/3*33+33, c%3*33+33, 0), b[c/3][c%3]?circlefill(screen, (c/3)*33+16, (c%3)*33+16, 10, b[c/3][c%3]==1?4:1):0 |
4 | #define CHECKROW(x1,y1,x2,y2,x3,y3) ( (b[x1][y1]+b[x2][y2]+b[x3][y3])? ( (b[x1][y1]+b[x2][y2]+b[x3][y3])/3 ):0 ) |
5 | int main(void) { int b[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}}, moves = 0, done = 0,drawme = 1, c; |
6 | srand(time(NULL)), allegro_init(),install_keyboard(),install_timer,install_mouse(),set_gfx_mode(GFX_AUTODETECT, 99,99,0,0), clear_to_color(screen, 15), text_mode(-1), show_mouse(screen); |
7 | while (moves<9 && !key[KEY_ESC] && !done) { |
8 | if (moves&1) { do {c = (rand()>>8)%9; |
9 | } while (b[c/3][c%3]); |
10 | b[c/3][c%3]=-1, moves++, drawme=1; |
11 | } else {(mouse_b)? b[mouse_x/33][mouse_y/33]==0?b[mouse_x/33][mouse_y/33]=1, moves++:0:0;} |
12 | done = CHECKROW(0,0, 0,1, 0,2) || CHECKROW(1,0, 1,1, 1,2) || CHECKROW(2,0, 2,1, 2,2) || CHECKROW(0,0, 1,0, 2,0) || CHECKROW(0,1, 1,1, 2,1) || CHECKROW(0,2, 1,2, 2,2) || CHECKROW(0,0, 1,1, 2,2) || CHECKROW(2,0, 1,1, 0,2); |
13 | scare_mouse(), drawme ? DRAWTILE(0), DRAWTILE(1), DRAWTILE(2), DRAWTILE(3), DRAWTILE(4), DRAWTILE(5), DRAWTILE(6), DRAWTILE(7), DRAWTILE(8), DRAWTILE(9), drawme = 0: 0, unscare_mouse(); |
14 | } |
15 | done ? textprintf_centre(screen, font, 45, 45, 14, moves&1?"You win!":"You lose!"),readkey():0; |
16 | return 0; |
17 | } END_OF_MAIN() |
EDIT: fixed some minor bugs.
Doesn't work in Windows, at least not on my box. Had to change the window size to 120x120...
Ah, yes - Allegro has this limit that doesn't allow you to make a window of less than 100 pixels!
I'll update it later to a larger window size. Just changing the dimensions in set_gfx_mode probably means you're toast if you move the mouse off the plaing board (no range checks).
Yesterday I was a bit inspired by you guys, and so I made a little game. It's your standard "ship plummeting ever faster down the endless tunnel" game. Fun for a diversion at least.
Get it here: http://www3.sympatico.ca/ppridham/misc/games/LongWayDown.zip
Yes, it's all written in main(), because it was originally going to be done in 20 lines, but I decided to just add as much as I needed to give it a wee bit of polish.
Ok, an updated version of my TicTacToe:
1 | #include <allegro.h> |
2 | #include <time.h> |
3 | #define DRAWTILE(c) rect(screen, c/3*(SCREEN_W/3), c%3*(SCREEN_H/3), c/3*(SCREEN_W/3)+(SCREEN_W/3), c%3*(SCREEN_H/3)+(SCREEN_H/3), 0), b[c/3][c%3]?circlefill(screen, (c/3)*(SCREEN_W/3)+(SCREEN_W/6), (c%3)*(SCREEN_H/3)+(SCREEN_H/6), (SCREEN_W/10), b[c/3][c%3]==1?4:1):0 |
4 | #define CHECKROW(x1,y1,x2,y2,x3,y3) ( (b[x1][y1]+b[x2][y2]+b[x3][y3])? ( (b[x1][y1]+b[x2][y2]+b[x3][y3])/3 ):0 ) |
5 | int main(void) { int b[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}}, moves = 0, done = 0,drawme = 1, c; |
6 | srand(time(NULL)), allegro_init(), install_keyboard(),install_timer,install_mouse(),set_gfx_mode(GFX_AUTODETECT, 256,256,0,0), clear_to_color(screen, 15), text_mode(-1), show_mouse(screen); |
7 | while (moves<9 && !key[KEY_ESC] && !done) { |
8 | if (moves&1) { do {c = (rand()>>8)%9; |
9 | } while (b[c/3][c%3]); |
10 | b[c/3][c%3]=-1, moves++, drawme=1; |
11 | } else {(mouse_b)? b[mouse_x/(SCREEN_W/3)][mouse_y/(SCREEN_H/3)]==0?b[mouse_x/(SCREEN_W/3)][mouse_y/(SCREEN_H/3)]=1, moves++:0:0;} |
12 | done = CHECKROW(0,0, 0,1, 0,2) || CHECKROW(1,0, 1,1, 1,2) || CHECKROW(2,0, 2,1, 2,2) || CHECKROW(0,0, 1,0, 2,0) || CHECKROW(0,1, 1,1, 2,1) || CHECKROW(0,2, 1,2, 2,2) || CHECKROW(0,0, 1,1, 2,2) || CHECKROW(2,0, 1,1, 0,2); |
13 | if (drawme||done||(moves==9)) {scare_mouse(), DRAWTILE(0), DRAWTILE(1), DRAWTILE(2), DRAWTILE(3), DRAWTILE(4), DRAWTILE(5), DRAWTILE(6), DRAWTILE(7), DRAWTILE(8), DRAWTILE(9), unscare_mouse(), drawme = 0;} |
14 | } if (done||(moves==9)) { textprintf_centre(screen, font, SCREEN_W/2, SCREEN_H/2, 2, done?moves&1?"You win!":"You lose!":"Draw!"),readkey(); } |
15 | return 0; |
16 | } END_OF_MAIN() |
And a game for two players: fox and geese.
Move teh geese with the left and right arrow keys, then move the fox with the QWAS keys. The fox wins if it reaches the other side of the board, the geese win if they reach it. Could use some more finess, but it's ok for now
#include <allegro.h> #define DRAWTILE(c) rectfill(screen, c/8*(SCREEN_W/8), c%8*(SCREEN_H/8), c/8*(SCREEN_W/8)+(SCREEN_W/8), c%8*(SCREEN_H/8)+(SCREEN_H/8), ((c%8)&1)^((c/8)&1)?0:15), circlefill(screen, goose[0]%8*(SCREEN_W/8)+SCREEN_W/16, goose[0]/8*(SCREEN_H/8)+SCREEN_H/16, SCREEN_W/32, 4), circlefill(screen, goose[1]%8*(SCREEN_W/8)+SCREEN_W/16, goose[1]/8*(SCREEN_H/8)+SCREEN_H/16, SCREEN_W/32, 4), circlefill(screen, goose[2]%8*(SCREEN_W/8)+SCREEN_W/16, goose[2]/8*(SCREEN_H/8)+SCREEN_H/16, SCREEN_W/32, 4), circlefill(screen, goose[3]%8*(SCREEN_W/8)+SCREEN_W/16, goose[3]/8*(SCREEN_H/8)+SCREEN_H/16, SCREEN_W/32, 4), circlefill(screen, fox%8*(SCREEN_W/8)+SCREEN_W/16, fox/8*(SCREEN_H/8)+SCREEN_H/16, SCREEN_W/32, 1), rect(screen, goose[sgoose]%8*(SCREEN_W/8), goose[sgoose]/8*(SCREEN_H/8), goose[sgoose]%8*(SCREEN_W/8)+(SCREEN_W/8)-1, goose[sgoose]/8*(SCREEN_H/8)+(SCREEN_H/8)-1, 14) int main(void) { int goose[4] = {63,61,59,57}, sgoose = 0, fox = 4, turn = 0, done = 0, drawme = 1, c; allegro_init(), install_keyboard(), install_timer, install_mouse(),set_gfx_mode(GFX_AUTODETECT, 256,256,0,0), clear_to_color(screen, 15), text_mode(-1), show_mouse(screen); while (!key[KEY_ESC] && !done) { turn ? ( (fox%8!=7) ? fox-=((goose[0]==fox+9||goose[1]==fox+9||goose[2]==fox+9||goose[3]==fox+9)?0:(9*key[KEY_S])), drawme |= !((key[KEY_S])?turn=0:1):0,(fox%8!=0) ? fox-=((goose[0]==fox+7||goose[1]==fox+7||goose[2]==fox+7||goose[3]==fox+7)?0:(7*key[KEY_A])), drawme |= !((key[KEY_A])?turn=0:1):0, (fox%8!=0 && fox>8) ? (fox +=((goose[0]==fox-9||goose[1]==fox-9||goose[2]==fox-9||goose[3]==fox-9)?0:(9*key[KEY_Q])), drawme |= !((key[KEY_Q])?turn=0:1)):0, (fox%8!=7 && fox>8) ? (fox +=((goose[0]==fox-7||goose[1]==fox-7||goose[2]==fox-7||goose[3]==fox-7)?0:(7*key[KEY_W])), drawme |= !((key[KEY_W])?turn=0:1)):0 ):( sgoose=( sgoose + (key[KEY_TAB]?(drawme=1):0) )&3, (goose[sgoose]%8!=0 && goose[sgoose]>8) ? (goose[sgoose] += (goose[sgoose]-9==fox?0:9*key[KEY_LEFT]), drawme |= ((key[KEY_LEFT])?turn=1:0)):0, (goose[sgoose]%8!=7 && goose[sgoose]>8) ? (goose[sgoose] += (goose[sgoose]-7==fox?0:7*key[KEY_RIGHT]), drawme |= ((key[KEY_RIGHT])?turn=1:0)):0); if (drawme) for(c=0;c<64;c++){ scare_mouse(), DRAWTILE(c), unscare_mouse(), drawme = 0; } rest(50); done = (fox>56 || (goose[0]<8 && goose[1]<8 && goose[2]<8 && goose[3]<8) ) ? 1:0; } while(keypressed()) readkey(); done?textprintf_centre(screen, font, SCREEN_W/2, SCREEN_H/2, 2, (fox>56)?"Fox wins!":"Geese win!"), readkey():0; return 0; } END_OF_MAIN()
Matthew: Heh, I never knew MSVC had a 2048 character per line limit ... but now that I tried to copy paste your program into it, now I know! ... see what useful information I get from this site?
Goodbytes: I'd love to have a 25x80 compo! Judging from the programs already written, I think we'd see some cool stuff ...
Goodbytes: I'd love to have a 25x80 compo! Judging from the programs already written, I think we'd see some cool stuff ...
That sounds like an invitation! Well, then it's official... and one day, I will be the Contest Ruler of Allegro!!!!! hey... there's no evil smiley. That is unfortunate.
Anyways... okay then.
there's no evil smiley. That is unfortunate.
well... hopefully http://strangesoft.net/kefka.gif will suffice!
there's no evil smiley.
Sure there is.
It just doesn't work
What are you talking about? It works fine http://strangesoft.net/Evil.gif
Weird ... it shows up in your post, but not mine Not for me, anyway. Doubly weird because I can see my Kefka. Oh well. EDIT: I just realized that smiley has a different url
#3? MUAHAHAHA!
Matthew's #4!?!
O__________-_-_-_-_-_-_-__________O
20 semicolon-delimited lines, and semicolons within the brackets of a 'for' don't count. No expressions contain commas (though parameter lists and initialisation lists do). I'm basically playing by the same rules as Matthew.
Use the mouse to change direction. The up and down arrow keys let you speed up or slow down, but you'll always be moving forwards. Shoot the blobs with the left mouse button or space. You die if you hit five blobs (like that'll ever happen when they move so slowly).
There is one known problem, namely that space may begin to distort after a long while playing. This hasn't come up for me, but then, I haven't played it for long. The necessary cross products and vector normalisations would use up extra lines There also seems to be a bug in Allegro whereby the mouse goes weird if you hold keys down, but this only affects Linux.
Enjoy
heh. just use my link, I think I have enough bandwidth. Like I care.
Matthew's #4!?!
I'm getting close to 4000 posts. heh.
edit: Dude ben! Not bad, though, after a few seconds theres no more moving stars.. Thats a fairly lame screen saver http://strangesoft.net/Evil.gif
I say screen saver cause somehow the keys do nothing, and well... I see no ship.
edit2:
EDIT: I just realized that smiley has a different url
MUAHAHAHAHAHA!!!!!
edit3: OOOOHhhhhh.. the mouse.. heh. ooops.
Tom: try the mouse. See my above edits.
I much prefer a keyboard interface! Or maybe a joystick. (or my Sidewinder... )
MUAHAHAHAHAHA!!!!!
20 cent royalties (EDIT: I'll make a mint considering how much you're using it lately ). Plus now I get to waste your bandwidth! http://www.allegro.cc/go.php?http://strangesoft.net/Evil.gif
I had more ideas for smilies, but I still don't know why "evil" refuses to work while all the other images will
maybe rename the immage? so its not a capital E? I don't know.
so its not a capital E?
Explain this then.
Anyway, Goodbytes, can we make it a character count contest instead? A lot of rows will get eaten up if you use more than a couple of #include's ...
w0w. not a clue. hah. thats weird. could it be Matthews go.php? or the anonymizer? Or just more lame geocities crap?
edit: #includes didn't count for this contest, why should it for another? I dont think #includes should be counted. #defines yes. But #includes no.
I much prefer a keyboard interface! Or maybe a joystick. (or my Sidewinder... )
Does anyone remember TeleHack? Well, several people (OK, I can only think of one person actually ) requested mouse support. So here it is
[EDIT] Oh by the way, I forgot to mention... THE ABOVE GAME IS 3D
heh. About your note about the sfx... You should keep it real time, and mix the shots in real time so they echo and do all sorts of cool stuff! Sure youd need a Quad Hammer system... But It'd at least sound cool
I can apply an echo to a prerendered wav just as easily as I can apply an echo to an expensively generated stream.
nooooo... a nice echo, 3d sound that will work with my 4.1 setup! now that would be cool. Especially with this new game! you turn around, and your laser ball sounds like its coming from behind you!!!! Shweeeeet. You know, but dynamic like, so as you turn its "panned" between my 2 stereo channels!!! MAUAUAUAUHAHAHAhackcooughhhwheezzzseeee... hm.
Anyway, Goodbytes, can we make it a character count contest instead? A lot of rows will get eaten up if you use more than a couple of #include's ...
Ha, are you kidding me?
That's the price we pay for using our precious, precious STL.
http://www.allegro.cc/go.php?http://www.geocities.com/chrisrbarry/smilies/EvilLarge.gif
Actually, you may be able to convince me yet, but the insane, unreadable 80x25 format was going to be a contest highlight.
VERY NICE BP!!! I especially like the 'milky way' strip of higher star density. Nice. I was waithing for some one to use the allegro 3d math routines (did everyone forget about the polygon drawing routines too??)
Thanks for the comments
The polygon routines require more setting up, especially if you want to clip the polygons and make them look right as they begin to go behind the camera. They're also a bit buggy, and the workaround (basically you have to shrink the clipping rectangle since some of the routines overrun to the right) takes up space. I decided on balance that gameplay should come before all that stuff.
But yeah, have at it. I'm probably not gonna do any more games for this, but I too would like to see the polygon routines used effectively
ben.. I need a favor... I want to know how to mix samples correctly, and other DSP stuff.. I was playing a little while ago with getting my audio player to do some funky fx, but I never did get it right... could you explain some of this stuff to me?
I couldn't resist. Lame compared to some of yours, but oh well I think we should put up a suggestion that in Alleg5 the use of void functions is banned :-)
1 | /* 1 */ // My sincerest apologies for the readability of this program :-) |
2 | /* 2 */ #include <allegro.h> |
3 | /* 3 */ #include <stdlib.h> |
4 | /* 4 */ |
5 | /* 5 */ int main() { |
6 | /* 6 */ int targets[10][3], score = 0, mouse_down = 0, init = 1; |
7 | /* 7 */ BITMAP *back; |
8 | /* 8 */ if (!allegro_init() && !set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0) && !install_keyboard() && (install_mouse() > 0) && (back = create_bitmap(320, 200))) while (!key[KEY_ESC]) { for (int i = 0; i < 10; i++) { if (targets<i>[0] && !init) { if ((mouse_b & 1) && !mouse_down && mouse_x >= targets<i>[1] && mouse_x < targets<i>[1] + 10 && mouse_y >= targets<i>[2] && mouse_y < targets<i>[2] + 10) { targets<i>[0] = 0; |
9 | /* 9 */ score++; |
10 | /* 10 */ } else rectfill(back, targets<i>[1], targets<i>[2], targets<i>[1]+9, targets<i>[2]+9, makecol(255, 0, 0)); |
11 | /* 11 */ } if (++targets<i>[1] > 320 || init) targets<i>[0] = (targets<i>[1] = (init) ? -20 * i : -100) && (targets<i>[2] = (rand() % 180) + 10); |
12 | /* 12 */ } init = (mouse_down = mouse_b & 1) && 0; |
13 | /* 13 */ textprintf_ex(back, font, 10, 10, makecol(255, 255, 0), makecol(0, 0, 0), "score: %d", score); |
14 | /* 14 */ line(back, mouse_x - 3, mouse_y - 3, mouse_x + 3, mouse_y + 3, makecol(0, 200, 0)); |
15 | /* 15 */ line(back, mouse_x - 3, mouse_y + 3, mouse_x + 3, mouse_y - 3, makecol(0, 200, 0)); |
16 | /* 16 */ blit(back, screen, 0, 0, 0, 0, 320, 200); |
17 | /* 17 */ clear(back); |
18 | /* 18 */ rest(10); |
19 | /* 19 */ } return 0; |
20 | /* 20 */ } END_OF_MAIN(); |
Tom, that's a big, big subject... I can tell you how to mix, change volume, and resample (cheaply), but anything more complicated would require more than one post on allegro.cc. This could help immensely.
To mix (assuming 16-bit signed values):
for (i = 0; i < length; i++) dest<i> = MID(-0x8000, src1<i> + src2<i>, 0x7FFF); /* Ask Bob about more efficient ways to clip */
To convert to/from unsigned, which Allegro wants:
for (i = 0; i < length; i++) dest<i> ^= 0x8000;
To change volume:
for (i = 0; i < length; i++) dest<i> = src<i> * volume_factor;
Note that if you halve the volume, you actually quarter the energy present in the wave.
To resample:
float j = 0; for (i = 0; i < dest_length; i++) { dest<i> = src[(int)j]; j += delta; /* 1.0 identity; 0.5 halve speed / one octave down; 2.0 double speed / one octave up */ }
That'll sound pretty rough, and you can improve it with linear interpolation and stuff. Hope that helps a bit
Hein: full marks for originality. It's quite hard [EDIT] Forgot to say, your code is a hell of a lot more readable than mine
That's the price we pay for using our precious, precious STL ... Actually, you may be able to convince me yet
The duck's code just above uses four headers. That's a lot of real estate!
To mix (assuming 16-bit signed values):
hmmm... so, what if I want to have the intensity (volume whatever) of one to be more than the other? Kinda like one is fading out or in?
edit:
Oh, and since Its for my 1337 audio player lib, the input plugin gets to set the output plugin's format.. so depending on the file (or input plugin... only the ogg and wav input plugins currently set a mode different than 44.1khtz 16bit signed stereo), we can have a 44.1 khtz 16bit unsigned Stereo pcm stream, or a 8 khtz 8bit signed mono pcm stream.
linear interpolation
um... you've seen my math skills. Look at my awesome collision detection above.
edit2: uugghhh... math notation hurts my head... (all those phunky symbols at the dsp link...)
That's a lot of real estate!
Headers don't count
Hein: full marks for originality.
Ja. Look at my originality! Its pong, just with more bugs!
Headers don't count
#include <rpg.h>
eh. this was 20 lines of code. the contents of the header should be included in the 20 lines. And anyways who posted an entry with that? I could swear I have all of them...
Ah, but it should be
#include "rpg.h"
Let's say that system headers don't count
Tom: all you do is multiply the sources differently:
dest<i> = src1<i>*vol1 + src2<i>*vol2;
Since you have a choice, go for signed. It's easier. Linear interpolation:
float j; for (i = 0; i < dest_length; i++) { int ji = (int)j; dest<i> = src[ji] + (src[ji+1]-src[ji])*(j-ji); j += delta; }
Not exactly an efficient implementation, but the maths is there.
cough maybe we should stop discussing DSP in this thread
You can count headers and I'm still under 20. But that 80 character count per line is bogus.
uuugghhh... Stupid computer. Stupid cat... Just finished writing the previous version of this message when XP decides to blue screen. SOme crappy error about IRQL_NOT_LESS_OR_EQUAL_TO or something. Soo, as with last time I seen that I opened up my case to see whats up... And I tell ya, a half hout later, I was finaly finished putting it all back to gether after ripping everything out to clean. IT was not a pretty sight. I swear there was enough cat fur in there to create another cat.
*cough* maybe we should stop discussing DSP in this thread
Oh, that 'Linear interpolation' is for resamplign right? hmm, Alsa-lib seems to do that for me if my card doesn't support the exact htz. Ohhh.. I need to add a cd input plugin maybe a ac3 or a52 plugin as well just to test to see if my code can easily handle more than 2 channels. (It should be easy. )
Well somebody was interested in more 3D stuff, so I stuffed a crude voxel terrain engine into ~16 lines of code (actually ~15 if you get rid of the constant string definition on line 2 or perhaps 14 if you also get rid of lmap_c[][] and just use the map bitmap). Not really a game, but perhaps of some interest; you still have ~5 lines left to make a game out of it.;)
Same usual stuff: Only one semicolon or bracket {} per line, discounting the semicolons inside a for() expression. No commas except for variable definition and lists of parameter arguments in functions.
The engine is set for 32 bit color, which you can change to 15/16/24 bit. Arrow keys to move around. You can also try changing the voxel resolution setting from 3 to 0 to 7. And no optimizations (mostly due to trying to stuff the code), so it may be a bit slow.
1 | #include <allegro.h> |
2 | const char *mapfile = "map.bmp"; /* 512x512 grayscale height map */ |
3 | int main() { |
4 | int p_x = 128<<16, p_y=128<<16, heading = 0, vox_res = 3 /* 0-7 */, lmap_c[512][512], i, j, ht_fac[8] = {3200, 4000, 5336, 8000, 10000, 16000, 24000, 40000}, max_step[8] = {160, 200, 267, 400, 500, 800, 1200, 2000}, step_factor[8] = {6250, 5000, 3748, 2500, 2000, 1250, 833, 500}, sz=0, curr_col=0, curr_step=0, ray_angle=0, dray_angle=0, ray_angle2=0, tempscale=0, rz=0, drz=0, drz0=0, rx=0, ry=0, rx0=0, ry0=0, drx=0, dry=0, ddrx=0, ddry=0, col_ht=0, voxel_scale=0, voxel_scaler=0, altitude=0, ht=0; |
5 | BITMAP *buffer = NULL, *map = NULL; |
6 | set_color_depth(32); |
7 | if ((!allegro_init()) | (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) >=0) | (!install_keyboard()) && (buffer=create_bitmap(640, 480)) ) map = load_bmp(mapfile, NULL); |
8 | for (i=0; i<512; i++) for (j=0; j<512; j++) lmap_c[j]<i> = getr(getpixel(map, i, j))*16; |
9 | while (!key[KEY_ESC]) { |
10 | for ((p_x += !!key[KEY_UP] * fmul(32768, fixsin(heading))) | (p_y += !!key[KEY_UP] * fmul(32768, -fixcos(heading))) && (heading += ((4<<16) * !!key[KEY_LEFT] * -1) + ((4<<16) * !!key[KEY_RIGHT]) ) |(curr_col=0)|((altitude=(((fmul(((lmap_c[((p_y>>16)+1)&511][((p_x>>16)+1)&511]-lmap_c[((p_y>>16)+1)&511][((p_x>>16))&511])*(p_x&0xFFFF)+(lmap_c[((p_y>>16)+1)&511][((p_x>>16))&511]<<16))-((lmap_c[((p_y>>16))&511][((p_x>>16)+1)&511]-lmap_c[((p_y>>16))&511][((p_x>>16))&511])*(p_x&0xFFFF)+(lmap_c[((p_y>>16))&511][((p_x>>16))&511]<<16)),(p_y & 0xFFFF))+((lmap_c[((p_y>>16))&511][((p_x>>16)+1)&511]-lmap_c[((p_y>>16))&511][((p_x>>16))&511])*(p_x&0xFFFF)+(lmap_c[((p_y>>16))&511][((p_x>>16))&511]<<16)))>>16)+32)*ht_fac[vox_res])|(ray_angle=heading-(32<<16))|(ray_angle2=heading+(32<<16))|(dray_angle=(64<<16)/SCREEN_W)|(tempscale=fmul(92682,step_factor[vox_res])) ? ((drx = fmul(fixsin(ray_angle), tempscale)) |(rx = fmul(fixsin(ray_angle2), tempscale)) ? ((ddrx = (rx-drx)/SCREEN_W) |(rx0 = p_x) |(dry = fmul(fixcos(ray_angle), -tempscale))|(ry = fmul(fixcos(ray_angle2), -tempscale)) ? ((ddry = (ry - dry)/SCREEN_W)|(ry0 = p_y)|(drz0 = -16384) ? (voxel_scaler = -2 * drz0 / SCREEN_H) :0) :0) :0) : 0) ; curr_col < SCREEN_W; (curr_col++) | (drx += ddrx) | (dry += ddry)) for ((curr_step = 0) | (rx = rx0)|(rz = altitude)|(ry = ry0)|(drz = drz0)|(voxel_scale = 0)|(sz = SCREEN_H-1);curr_step < max_step[vox_res]; (curr_step++)|(rx+=drx)|(rz+=drz)|(ry+=dry)|(voxel_scale+=voxel_scaler)) for ((ht =((fmul(((lmap_c[((ry>>16)+1)&511][((rx>>16)+1)&511]-lmap_c[((ry>>16)+1)&511][((rx>>16))&511])*(rx&0xFFFF)+(lmap_c[((ry>>16)+1)&511][((rx>>16))&511]<<16))-((lmap_c[((ry>>16))&511][((rx>>16)+1)&511]-lmap_c[((ry>>16))&511][((rx>>16))&511])*(rx&0xFFFF)+(lmap_c[((ry>>16))&511][((rx>>16))&511]<<16)),(ry&0xFFFF))+((lmap_c[((ry>>16))&511][((rx>>16)+1)&511]-lmap_c[((ry>>16))&511][((rx>>16))&511])*(rx&0xFFFF)+(lmap_c[((ry>>16))&511][((rx>>16))&511]<<16)))>>16))|(col_ht=ht*ht_fac[vox_res]);col_ht>rz;(drz+=voxel_scaler)|(rz+=voxel_scale)|(sz--))(sz<0)?((curr_step=max_step[vox_res])? (void)0 :putpixel(buffer,curr_col,sz,makecol(ht/16,ht/16,ht/16))):putpixel(buffer,curr_col,sz,makecol(ht/16,ht/16,ht/16)); |
11 | blit(buffer, screen, 0, 0, 0, 0, 640, 480); |
12 | clear_to_color(buffer, makecol(0,0,0)); |
13 | } |
14 | return 0; |
15 | } END_OF_MAIN() |
You need to create a 512x512 grayscale bitmap (.bmp). Or you can copy the one below, and resave it as a bmp.
http://www.geocities.com/sichoy/map.jpg
[edit] I forgot to get rid of another line, so it's now 14 or 15 lines, depending on whether you keep the mapfile string.
There you go: fox&geese with bugfixes. Should run fine now.;D
Man, I spend too much time on these things, but it is fun.
If we do want a competition (even if we don't, I think someone should collect all the little gems posted here and upload them somewhere), the most sensible requirement IMHO would be to limit the size of the sourcefile to, say, 2kb, not counting whitespace and comments.
#include <allegro.h> #define DRAWTILE(c) rectfill(screen, c/8*(SCREEN_W/8), c%8*(SCREEN_H/8), c/8*(SCREEN_W/8)+(SCREEN_W/8), c%8*(SCREEN_H/8)+(SCREEN_H/8), ((c%8)&1)^((c/8)&1)?0:15), circlefill(screen, goose[0]%8*(SCREEN_W/8)+SCREEN_W/16, goose[0]/8*(SCREEN_H/8)+SCREEN_H/16, SCREEN_W/32, 4), circlefill(screen, goose[1]%8*(SCREEN_W/8)+SCREEN_W/16, goose[1]/8*(SCREEN_H/8)+SCREEN_H/16, SCREEN_W/32, 4), circlefill(screen, goose[2]%8*(SCREEN_W/8)+SCREEN_W/16, goose[2]/8*(SCREEN_H/8)+SCREEN_H/16, SCREEN_W/32, 4), circlefill(screen, goose[3]%8*(SCREEN_W/8)+SCREEN_W/16, goose[3]/8*(SCREEN_H/8)+SCREEN_H/16, SCREEN_W/32, 4), circlefill(screen, fox%8*(SCREEN_W/8)+SCREEN_W/16, fox/8*(SCREEN_H/8)+SCREEN_H/16, SCREEN_W/32, 1), rect(screen, goose[sgoose]%8*(SCREEN_W/8), goose[sgoose]/8*(SCREEN_H/8), goose[sgoose]%8*(SCREEN_W/8)+(SCREEN_W/8)-1, goose[sgoose]/8*(SCREEN_H/8)+(SCREEN_H/8)-1, 14) int main(void) { int goose[4] = {63,61,59,57}, sgoose = 0, fox = 4, turn = 0, done = 0, drawme = 1, c; allegro_init(), install_keyboard(), install_timer, install_mouse(),set_gfx_mode(GFX_AUTODETECT, 256,256,0,0), clear_to_color(screen, 15), text_mode(-1), show_mouse(screen); while (!key[KEY_ESC] && !done) { turn ? ( (fox%8!=7) ? fox-=((goose[0]==fox+9||goose[1]==fox+9||goose[2]==fox+9||goose[3]==fox+9)?0:(9*(key[KEY_S]?turn=0,drawme=1,-1:0))):0,(fox%8!=0) ? fox-=((goose[0]==fox+7||goose[1]==fox+7||goose[2]==fox+7||goose[3]==fox+7)?0:(7*(key[KEY_A]?turn=0,drawme=1,-1:0))):0,(fox%8!=0 && fox>8) ? (fox +=((goose[0]==fox-9||goose[1]==fox-9||goose[2]==fox-9||goose[3]==fox-9)?0:(9*(key[KEY_Q]?turn=0,drawme=1,-1:0)))):0, (fox%8!=7 && fox>8) ? (fox +=((goose[0]==fox-7||goose[1]==fox-7||goose[2]==fox-7||goose[3]==fox-7)?0:(7*(key[KEY_W]?turn=0,drawme=1,-1:0)))):0 ):( sgoose=( sgoose + (key[KEY_TAB]?(rest(100), drawme=1):0) )&3, (goose[sgoose]%8!=0 && goose[sgoose]>8) ? (goose[sgoose] += (goose[sgoose]-9==fox?0:9*(key[KEY_LEFT]?turn=1,drawme=1,-1:0))) :0, (goose[sgoose]%8!=7 && goose[sgoose]>8) ? (goose[sgoose] += (goose[sgoose]-7==fox?0:7*(key[KEY_RIGHT]?turn=1,drawme=1,-1:0))):0); if (drawme) for(c=0;c<64;c++){ scare_mouse(), DRAWTILE(c), unscare_mouse(), drawme = 0; } done = (fox>56 || (goose[0]<8 && goose[1]<8 && goose[2]<8 && goose[3]<8)) || ( (goose[0]+goose[1]+goose[2]+goose[3]==4*fox) && (abs(fox-goose[0])==7 || abs(fox-goose[0]==9)) ) ? 1:0; } while(keypressed()) readkey(); return done?textprintf_centre(screen, font, SCREEN_W/2, SCREEN_H/2, 2, (fox>56)?"Fox wins!":"Geese win!"), readkey(), 0:0; } END_OF_MAIN()
This is a little piece of a rpg.. the battle between the forces of good rabbits and evil rabbits. Who will win? (designed to be like a final fantasy like battle)
[edit added srand(NULL);]
#include <allegro.h> #include <string.h> #include <stdlib.h> /*01*/BITMAP *draw_char(BITMAP *buffer,int x,int y,int half_w,int half_h,int facing) {int gen[32]={half_w,0,half_w/4,-half_h/4,half_w/8,-half_h/2,half_w/8,-half_h*3/4,half_w/4,-half_h*3/4,half_w/2,-half_h/4,half_w*3/4,-half_h/4,half_w*3/4,-half_h/2,half_w,-half_h/2,half_w,-half_h*3/4,half_w/4,half_h/4,half_w/2,half_h*3/4,half_w,half_h*3/4,half_w,half_h,half_w/4,half_h,0,half_h/2},side1[32]={x+gen[0],y+gen[1],x+gen[2],y+gen[3],x+gen[4],y+gen[5],x+gen[6],y+gen[7],x+gen[8],y+gen[9],x+gen[10],y+gen[11],x+gen[12],y+gen[13],x+gen[14],y+gen[15],x+gen[16],y+gen[17],x+gen[18],y+gen[19],x+gen[20],y+gen[21],x+gen[22],y+gen[23],x+gen[24],y+gen[25],x+gen[26],y+gen[27],x+gen[28],y+gen[29],x+gen[30],y+gen[31]},side2[32]={x-gen[0],y+gen[1],x-gen[2],y+gen[3],x-gen[4],y+gen[5],x-gen[6],y+gen[7],x-gen[8],y+gen[9],x-gen[10],y+gen[11],x-gen[12],y+gen[13],x-gen[14],y+gen[15],x-gen[16],y+gen[17],x-gen[18],y+gen[19],x-gen[20],y+gen[21],x-gen[22],y+gen[23],x-gen[24],y+gen[25],x-gen[26],y+gen[27],x-gen[28],y+gen[29],x-gen[30],y+gen[31]}; /*02*/(facing)?polygon(buffer,16,side1,makecol(255,0,0)):polygon(buffer,16,side2,makecol(0,0,255)); /*03*/return buffer; /*04*/} void main() {BITMAP game_state={/*int 7*/0,(allegro_init()||install_timer()||install_keyboard()||set_gfx_mode(GFX_AUTODETECT_WINDOWED,320,200,0,0))?-1:50,text_mode(-1),40,100,80,100,/*pointers 4*/NULL,NULL,NULL,NULL,/*long int*/0,/*pointer*/NULL,/*int 3*/270,130,0},game_state2={/*int 7*/5,10,0,0,0,0,0,/*pointers 4*/NULL,NULL,NULL,NULL,/*long int*/0,/*pointer*/NULL,/*int 3*/0,0,0},*buffer=create_bitmap(320,200); /*05*/srand(time(NULL)); /*06*/while((game_state.cr>0||game_state.ct>0)&&memset(buffer->dat,0,320*200)&&game_state.h>0&&!key[KEY_DOWN]|(game_state.w=0)) while(game_state.w++<12)(game_state.w==1) ? textprintf(buffer,font,10,10,makecol(0,255,0),"Push [left] for magic"):(game_state.w==2) ? textprintf(buffer,font,10,20,makecol(0,255,0),"Push [up] for attack"):(game_state.w==3)?textprintf(buffer,font,10,30,makecol(0,255,0),"Push [Down] to Run"):(game_state.w==4)?((key[KEY_UP]&&game_state.seg==0&&game_state.ct>0)? game_state.seg=30*(game_state.id=1) : (key[KEY_LEFT]&&game_state.seg==0&&game_state.cr>0)? game_state.seg=15*(game_state.id=2) : (game_state.seg>0)? rest(game_state.seg--): (game_state.id==4)? game_state.id=(game_state.h-=(rand())%20) : (game_state.id==1)?(game_state.id=((game_state2.w-=(1+rand()%3))>0)?0*(game_state.seg=25)+4:(game_state.ct=-30)):(game_state.id==2)?(game_state.id=((game_state2.h-=(1+rand()%3))>0)?(game_state.seg=25)*0+4:(game_state.cr=-30)):rest(1)):(game_state.w==5)?((game_state.id==1)? line(buffer,game_state.ct+game_state.seg,game_state.cb+game_state.seg,game_state.ct+game_state.seg+20,game_state.cb+game_state.seg+20,makecol(255,200,200)): rest(1)):(game_state.w==6)?((game_state.id==2)?circle(buffer,game_state.cl,game_state.cr,game_state.seg,makecol(255,255,255)):rest(1)):(game_state.w==7)?(void)draw_char(draw_char(draw_char(buffer,game_state.ct,game_state.cb,20,20,TRUE),game_state.cl,game_state.cr,20,20,TRUE),game_state.x_ofs,game_state.y_ofs,20,20,FALSE):(game_state.w==8)?line(buffer,game_state.x_ofs-33,game_state.y_ofs+23,game_state.x_ofs-33+game_state.h,game_state.y_ofs+23,makecol(0,255,0)):(game_state.w==9)?line(buffer,game_state.ct+13,game_state.cb+23,game_state.ct+13+game_state2.w,game_state.cb+23,makecol(0,255,0)):(game_state.w==10)?line(buffer,game_state.cl+13,game_state.cr+23,game_state.cl+13+game_state2.h,game_state.cr+23,makecol(0,255,0)):(game_state.w==11)?(game_state.id==4)?line(buffer,game_state.x_ofs-20+game_state.seg,game_state.y_ofs+game_state.seg,game_state.x_ofs+game_state.seg,game_state.y_ofs+game_state.seg+20,makecol(255,200,200)):rest(1):blit(buffer,screen,0,0,0,0,320,200); /*07*/while(!key[KEY_ESC])(game_state.cr<0&&game_state.ct<0)? (textprintf_centre(screen,font,160,100,makecol(0,255,0),"You win! Push [Esc] to quit")):(textprintf_centre(screen,font,160,100,makecol(0,255,0),"You lose! Push [Esc] to quit")); } END_OF_MAIN()
Nice! But is it at all possible to win? I get trashed each time round...
hehe well it depends on your compiler..
since I forgot to use srand(time(NULL)); you will either win or lose depending on the sequence of number generated by rand()...
on my computer I win.. so.. hmm anyway its easy enough to add a srand(time(NULL)); with out pushing it past the limit.
Here's my game. It's some kind of space shoter, but with circles. You're the yellow circle and enemies are the red ones. You move with the arrows and shot a blue circle with the rigth control. If an enemy collides with you... you lose!
Compiles without any warning with -Wall
1 | #include <allegro.h> |
2 | |
3 | /* 1*/ volatile int counter; |
4 | /* 2*/ void handler(void){ |
5 | /* 3*/ counter++; |
6 | /* 4*/ } END_OF_FUNCTION(handler); |
7 | |
8 | /* 5*/ int main(int argc, char *argv[]){ |
9 | /* 6*/ int buffer, t=0, i, k, posx=10, posy=100, shot_posx=321, shot_posy=-1, enemy_posx[10]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, enemy_posy[10], enemies_destroyed=0; |
10 | /* 7*/ if ((srand(time(NULL)),allegro_init()) || install_keyboard() || install_int_ex(handler, BPS_TO_TIMER(100)) || set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0) || !(buffer=(int)create_bitmap(320, 200)) || (text_mode(-1),0) || (counter=0)) allegro_message("Error initializing\n"), exit(-1); |
11 | /* 8*/ while (!key[KEY_ESC] && !(k=0) && (clear((BITMAP *)buffer),1)){ |
12 | /* 9*/ while (counter > 0 && !(i=0) && (((shot_posx = shot_posx>320&&key[KEY_RCONTROL]?shot_posy=posy,posx+2:shot_posx),(posx += posx>8&&key[KEY_LEFT]?-1:posx<310&&key[KEY_RIGHT]?1:0),(posy += posy>20&&key[KEY_UP]?-1:posy<180&&key[KEY_DOWN]?1:0),shot_posx+=3,t--,counter--)||1)) |
13 | /*10*/ while (i++<10){ |
14 | /*11*/ if (enemy_posx[i-1]>=0) (enemy_posx[i-1]-=2, enemy_posy[i-1] += (rand()%4) ? (-1+rand()%3) : enemy_posy[i-1]==posy?0:enemy_posy[i-1]<posy?1:-1); |
15 | /*12*/ if (enemy_posx[i-1]>=0&&((enemy_posx[i-1]-posx)*(enemy_posx[i-1]-posx)+(enemy_posy[i-1]-posy)*(enemy_posy[i-1]-posy))<50) set_gfx_mode(GFX_TEXT, 0, 0, 0, 0), allegro_message("You have destroyed %d enemies\n", enemies_destroyed), exit(-1); |
16 | /*13*/ if (enemy_posx[i-1]>=0&&((enemy_posx[i-1]-shot_posx)*(enemy_posx[i-1]-shot_posx)+(enemy_posy[i-1]-shot_posy)*(enemy_posy[i-1]-shot_posy))<30) enemy_posx[i-1]=-1, shot_posx=330, enemies_destroyed++; |
17 | /*14*/ if (enemy_posx[i-1]<0 && t<=0) (enemy_posx[i-1]=320),(enemy_posy[i-1]=rand()%200),(t = 5+(rand()%15)),i=20; |
18 | /*15*/ } |
19 | /*16*/ while (k++<10) if (enemy_posx[k-1]>=0) circlefill((BITMAP *)buffer, enemy_posx[k-1], enemy_posy[k-1], 2, 12); |
20 | /*17*/ textprintf((BITMAP *)buffer, font, 0, 0, 15, "Enemies destroyed: %d", enemies_destroyed),circlefill ((BITMAP *)buffer, posx, posy, 5, 14),circlefill((BITMAP *)buffer, shot_posx, shot_posy, 2, 11), blit ((BITMAP *)buffer, screen, 0, 0, 0, 0, 320, 200); |
21 | /*18*/ } |
22 | /*19*/ return 0; |
23 | /*20*/ } END_OF_MAIN(); |
It was very funny to program, and I thing it's very funny to play
Note: 100% original. I didn't look at any of your programs until I've finished this.
You do know what the word funny means, right? And that think is spelled with a k?
Sorry 'bout that but I just had to...
BTW, I thought that whole funny business was a German thing or something...
Let's clarify...
"Funny" can mean either "causing laughter" or "strange".
"Fun" means "enjoyable".
Things that are funny can be fun, and vice versa, of course
... and you flame me for going on about "it's" ...
Just to complete the collection of 20 line interpretations of classic games, here's Pacman:
I think I followed the "rules". If not, fsck it.
You suck. I thought about doing a pacman.. But oh well.
Though, the rules say semi-colon delimited... But it brobably wouldn't be hard to fix...
Ooh, casting function pointers to get around the void return values... not portable I almost used raise(SIGABRT), which returns int, in my game, but in the end I didn't need it.
One or two bugs(?) in the game, namely that the whole background goes yellow whenever his mouth is closed, and the thingy doesn't stop moving when I let go of the keys (I wish he would). Otherwise works well
he's not supposed to stop moving.. When was the last time you played pacman?
Well, I just joined {allegro.cc} tonight. I've been reading the forums for a while and decided it was time I gave my two cents, or in this case, my twenty lines. here goes...
1 | #include <allegro.h> |
2 | int main() { |
3 | if (!allegro_init()&&!install_keyboard()&&set_gfx_mode(GFX_AUTODETECT,640,480,0,0)) return 1; |
4 | int x=0,y=400,d=0,ngx=460,ngy=0,gc=0,t = -29,i=0; |
5 | for (;!key[KEY_ESC] && gc < 16 ;t++,rest(60)) { |
6 | circlefill(screen,x,y,8,0); |
7 | for (i=0;i<2;i++) circlefill(screen,180 + i *280 ,240,100,2); |
8 | for (i=0;i<15;i++) rectfill(screen,172 + (i%2) *8, 342+i*8,180+ (i%2) *8,342+i*8+8,15 ); |
9 | d = (d+256 +(key[KEY_LEFT] ? -4: 0)+(key[KEY_RIGHT] ? 4: 0)+((((x-180)*(x-180)+(y-240)*(y-240))>108*108) ? 0: 25 ) + ((((x-460)*(x-460)+(y-240)*(y-240))>108*108) ? 0: -25 ) )%256; |
10 | y = ((y + fixtoi(fixsin(itofix(d))*6) < 480)&&(y + fixtoi(fixsin(itofix(d))*6) > 0)) ? (y + fixtoi(fixsin(itofix(d))*6)) : y ; |
11 | x = ((x + fixtoi(fixcos(itofix(d))*6) < 640)&&(x + fixtoi(fixcos(itofix(d))*6) > 0)) ? (x + fixtoi(fixcos(itofix(d))*6)) : x ; |
12 | if (((x-ngx)*(x-ngx)<(4*4))&& ((y-ngy)*(y-ngy)<(150*150))){ |
13 | ngx = (ngx==180) ? ((ngy==0)? 180 : 460 ) : ((ngy==0)? 460: 180 ); |
14 | ngy = (ngy==0) ? 480 : 0; |
15 | gc++; |
16 | } circlefill(screen,x,y,8,1); |
17 | textprintf(screen,font,0,0,15,"Time: %i Laps Left: %i ",(t < 0) ? 0 : t, 4-(gc/4)); |
18 | } for(;!key[KEY_ESC];)textprintf_centre(screen,font,320,240,15,"Course Complete! Your time was: %i",t-1); |
19 | return 0; |
20 | } |
It is a top view car racing game. No opponent, just a time trial though. Figur eights around the two circles. I hope you enjoy
Bruce: I can't reproduce the yellow background problem. Maybe floodfill() got changed at some stage, although I tested both stable and unstable Allegros.
I couldnt get pacman to compile at all...
compiler says 3 times on line 4 too many arguments to function -- maybe i have an old version of allegro or gcc.....
This is the first thread that I've read on allegro.cc in about a week or two and I decided to try to do the challenge, It's not an rpg but its tile based...... I did some things that may be considered cheap and cheating but I kept my code under 20 lines (19 I think) and no line has more than one semi colon on it.... the actual .cpp file is just under 5kb....
if there is word wrap on here it might not be under 20 lines on here, but the .cpp file i have is under 20 with no more than 1 semicolon per line.....
anyways its a remake of an old game that I made (first game I ever made) on my b&w trs-80 model 4 computer with basic.....(it was in textmode)
Bricks & Money "fall", if you walk on the money -- you get a point and it disappears, if you walk on the bricks you die, esc quits, dont hold keys down -- tap them (sorry bout this, its hard to do good keyboard routines in a couple of lines -- for me anyways) It gets interesting once you're score is about 200 - 300, which is a while to wait...
Michael: compile Pacman as C, not C++. He uses some function pointers with "()" for the parameters; in C this means 'parameter number and types unknown', while in C++ it means 'no parameters'.
-Wstrict-prototypes is a good warning...
by the way I lied about my game -- the line with the for loop has two semicolons I think...
the .cpp file i have is under 20 with no more than 1 semicolon per line.....
oh cool no warnings this time... thanks BP! -- but it's tilebased -- since when is pacman tilebased?
And no fruit and when you beat it -- nothing happens and only one life -- heh sorry I'm a big pac-man fan.....(nitpick nitpick nitpick) but it should almost go without saying -- great job!
since when is pacman tilebased?
Since when isn't it?
since forever! -- the walls are always thin and the pathways wide -- if you can call that tilebased, maybe it is, but I dont see how at this point....
Pacman is one of the traditional tile based examples..
Pac-Man is soooo tile-based! Not terribly attractive tiles, but tiles all the same.
BTW, this thread is a good example of why we need pages in the forums. How's that coming, Matthew?
thats not the origonal pacman
just cause you can do it with tiles doesn't make it right -- if you look at it in the offical games it becomes very hard for me to divide it into tiles... maybe it is tilebased -- but I doub't it -- I have it on 2600 and 800XL (those are ataris)
edit: the walls arn't just tiles that have skinnier wall graphics, they're actually graphically offset as far as I can tell..... from what I've been looking at it would take more tiles than my atari had memory for if pacman is tile based them maybe some people are just better at hiding it than others cause it really doesnt seem like it is.
edit2: IMO you'd have to have 4 different tile sizes (on the same map) and a lot of tile graphics to do it right....
edit3: I'm starting to think maybe pacman is tilebased -- but I know that people have done it non tile based, and I know that this isn't the origonal pacman but it's very hard for me to see tiles in it for example, maybe you could show me how you would divide it into equal tiles...
http://www.geocities.com/michael_jensen419/level.gif
The original pacman:
http://roms2.mame.dk/png/puckman.png
Take a look at the rom, check the gfx set, and you'll see the individual tiles
Edit:
You can see the individual tiles, if you take a look at the IBM PC character set
Edit2:
http://web-wise-wizard.com/web-lookup-lists/dem/ascii-ibm/ascii_12.gif
what system is that from? it looks similar to the 800XL version but better gfx... can any one divide my gif into tiles? I do know that people have done pacman before without tiles, but i mean if you look at how the dots and the walls line (theres more than one pill in each tile space -- and i still cant divide my pic into tiles.....)
http://www.geocities.com/michael_jensen419/level2.gif
It's from the arcade version. You know, the original
Take a look at the PC characters I posted above. You can create the complete grid with them.
Awesome work sc! you proved me wrong -- I'm still at a loss on how the pic I posted is tile based -- the source is avilable but you have to have flash to look at it -- the game is at http://www.neave.com/webgames/pacman/ and how do they get more than one pill on a tile??? (all the tile based pacmans that I could tell were tile based had the pills way to far apart...)
another edit: -- I dont mean that it can't be made up of tiles b/c it can -- but I mean, can you impose like a grid on it (the pic I posted) of equal spacing to where it looks tilebased? (like 22x22 or 32 x 32 etc....)
There's just one pill in every tile.
Why do you think there are several? Take a look at the horizontal corridors to get an idea of the tile spacing.
Then simply assume that the pills are centered within a tile. Now draw a grid based on the pills. This will show you the tile layout.
Wow sc -- it works pretty good on the interior of the pic that I posted.... except -- on the outside walls there is like 1 pixel outside of the tiles but that could be an easy hack -- very awesome, the reason why I always thought there was more than one pill for tile is because they're sooo close together -- I didnt think that the tiles would be smaller than the sprites that the game uses (in the pic I posted they are...)
edit: To be more clear -- Until now I've thought that generally the tiles are the exact same height and width as the sprites that are being drawn on them, and in the pic that I was looking at they're not and it gives the effect (on my brain) that maybe its not tiled cause the pills look closer together cause the tiles are smaller...
I'm a bit late, but I just had to try this as well - here is my version of another classic game (not sure if it was done already):
edit: now no warnings with -W -Wall
edit: fixed bugs
#include <allegro.h> volatile int i,t=0,b=320,f=0,p[]={0,160,320},d[]={0,-1,1,0,0,0};void timer(void) {t++;}int main(void){if(!(allegro_init()||set_gfx_mode(GFX_AUTODETECT,640,480,0, 0)||install_timer()||install_int_ex(timer,BPS_TO_TIMER(100))||!install_mouse())) {clear(screen);for(i=0;i<480;i++)rectfill(screen,(i%40)*16,(i/40)*16,(i%40)*16+ 14,(i/40)*16+14,makecol(200,200,0));rest(4000);t=0;while(p[1]<400)if(f<t){for(i= 0;i<6;i+=2){if(i!=2)circlefill(screen,p[2],p[1],4,i?makecol(100,100,255):0);if(i <4)p[i+!i]+=d[i+!i];if(i<4&&getpixel(screen,p[2]+d<i>*5,p[1]+d[i+1]*5)){rectfill (screen,(p[2]+d<i>*5)&~15,(p[1]+d[i+1]*5)&~15,(p[2]+d<i>*5)|15,(p[1]+d[i+1]*5)| 15,0);d[i+!i]=-d[i+!i];p[i+!i]+=d[i+!i];}if(i)rectfill(screen,b-12,320,b+12,327 ,i==2?0:makecol(255,0,b/3));if(i==2)b=mouse_x;}f++;}}return 0;}END_OF_MAIN();
Guess which game it is first without running
I have less than 20 ; - and it all fits into 11 lines not longer than 80 chars
runs a little fast.... I wunder if compiling under djgpp and using moslo would help... -- it seems if i hit the ball once it slows down to a decent speed but its hitting it that first time when its going to speed of light that matters I suppose....
Yes, I put in rest(4000) because on my monitor it takes a few seconds to switch to fullscreen - and it messed up the timing code. It's fixed in the edited version.
heh. looks good (yet another game I considered to do... Oh well.)
I see, seems to work now -- was there paddle garbage in the old version too? You guys did way better than me on this as far as not cheating goes -- btw is what I did considered cheating??
edit: hehe -- so who can do a game in 10 lines!?;D
Mine is almost 10 I probably can get it to 10 If I really really try... But nah.
I see, seems to work now -- was there paddle garbage in the old version too?
You're right, I introduced garbage now - I edited it again to fix it. If I broke something else with that - I'm definitely not going to fix it in code formatted like that
awesome
First I want to say. These games everybody has written are sweet. Earlier I put my "car" racing game on this forum, but I've made a few changes.
Added an opponent, and with a some shadow fx it is now a bumper car/hover craft racing game.
Here it is if you care to take a look:
only twenty lines long... a few are pretty long though...
I hope you all enjoy;D;D;D
---------------------------------------------
ohhh i didnt know you were supposed to do figure 8s!!!! I thot it was a bug that you had to run two laps last time to get it to go down once...
Oh, sorry..
I forgot to mention that each lap is a figure 8 around the two circles.
<><><><><><><><><><><><><><><><><><><><><><><><><>
This thread is killing my browser!
I'd like to set up a webpage with links to the code everyone has posted in this thread. If you're at all interested, please send me a pm.:)
141 posts... What's the record?
Ok, everone send Evert your code if you have more to contribute. He will make a webpage or something with a download available.
Thread closed. He'll create a new one when he's all ready.