|
An Allegro Game in 20 lines of code - Possible? |
Thomas Fjellstrom
Member #476
June 2000
|
What are you talking about? It works fine http://strangesoft.net/Evil.gif -- |
23yrold3yrold
Member #1,134
March 2001
|
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 One post-happy fella said: #3? MUAHAHAHA! Matthew's #4!?! -- |
Bruce Perry
Member #270
April 2000
|
1#include <allegro.h>
2#include <string.h>
3#include <stdlib.h>
4#include <math.h>
5/*01*/int main(int i,char**buffer){int firedelay=0,j,xi,yi,enemyend=64,lives=5;
6/*02*/float coord[4097][6]={{0,0,0,0,0,0},{0,0,0,0,0,0.002f}},q,a,z,d,redness,x,y,ca,sa;
7/*03*/MATRIX_f temp,camera={{{1,0,0},{0,1,0},{0,0,1}},{0,0,0}};
8/*04*/for(j=64;j<4096;j++)if((int)(a=rand()*((2*3.14159265358979323846f)/(RAND_MAX+1.0f)))|1)if((int)(z=coord[j][2]=rand()*(2/(RAND_MAX+1.0f))-1.0f)|1)if((int)(d=(float)sqrt(1.00001f-z*z)*4)|1)if((redness=0.5f+rand()/(float)RAND_MAX))coord[j][5]=(coord[j][3]=(coord[j][4]=pow(rand()*(1.0f/RAND_MAX),2)*170*(0.8f+0.2f*cos((coord[j][0]=(float)cos(a)*d)*2))*(0.8f+0.2f*cos((coord[j][1]=(float)sin(a)*d)*2)))*redness)*(2/redness-1);
9/*05*/for(j=2;j<enemyend;j++)for(i=0;i<3;i++)coord[j]<i>=((rand()&2)-1)*(100+rand()*(1000.0f/RAND_MAX));
10/*06*/for(allegro_init()||install_keyboard()||install_timer()||install_mouse()<0||set_gfx_mode(GFX_AUTODETECT,640,480,0,0)||!(buffer=(char**)create_bitmap(640,480))?abort():set_window_title((char*)"20 lines of code!");!key[KEY_ESC]&&enemyend>2&&lives>0;blit((BITMAP*)buffer,screen,0,0,0,0,640,480)){for(clear((BITMAP*)buffer);retrace_count&&enemyend>2&&lives>0;retrace_count--){for(i=0;i<3;i++)coord[0]<i>+=coord[0][i+3]=coord[0][i+3]*0.99f+camera.v[2]<i>*(0.003f+(!!key[KEY_UP]-!!key[KEY_DOWN])*0.002f-(30-(firedelay=MIN(firedelay+1,60)))*0.00008f);
11/*07*/for(get_mouse_mickeys(&xi,&yi);i<6;i++)coord[1][i-3]=(i==3?(j=((mouse_b&1)|key[KEY_SPACE])&&firedelay>=60):j)?coord[firedelay=0][i-3]+(coord[1]<i>=coord[0]<i>+camera.v[2][i-3]*0.6f):coord[1][i-3]+coord[1]<i>;
12/*08*/get_rotation_matrix_f(&temp,-yi*0.1f,xi*0.1f,0);
13/*09*/matrix_mul_f(&camera,&temp,&camera);
14/*10*/for(j=2;j<enemyend;j++)if((q=vector_length_f(coord[0][0]-coord[j][0],coord[0][1]-coord[j][1],coord[0][2]-coord[j][2]))<2.0f)memmove(&coord[j--],&coord[--enemyend],sizeof(coord[lives--]));
15/*11*/else for(i=0;i<3;i++)coord[j]<i>+=coord[j][i+3]=coord[j][i+3]*0.99f+(coord[0]<i>-coord[j]<i>)*0.002f/q;
16/*12*/for(j=2;j<enemyend;j++)if(vector_length_f(coord[j][0]-coord[1][0],coord[j][1]-coord[1][1],coord[j][2]-coord[1][2])<2.0f)memmove(&coord[j--],&coord[--enemyend],6*sizeof(float));
17/*13*/}for(j=64;j<4096;j++){apply_matrix_f(&camera,coord[j][0],coord[j][1],coord[j][2],&coord[4096][0],&coord[4096][1],&coord[4096][2]);
18/*14*/if(coord[4096][2]>=0.1f&&coord[4096][2]>=coord[4096][0]&&coord[4096][2]>=-coord[4096][0]&&coord[4096][2]>=coord[4096][1]&&coord[4096][2]>=-coord[4096][1])putpixel((BITMAP*)buffer,320+(int)(320*coord[4096][0]/coord[4096][2]),240+(int)(240*coord[4096][1]/coord[4096][2]),makecol((int)MIN(coord[j][3],255),(int)MIN(coord[j][4],255),(int)MIN(coord[j][5],255)));
19/*15*/}for(j=2;j<enemyend;j++){apply_matrix_f(&camera,coord[j][0]-coord[0][0],coord[j][1]-coord[0][1],coord[j][2]-coord[0][2],&coord[4096][0],&coord[4096][1],&coord[4096][2]);
20/*16*/if(coord[4096][2]>=0.1f&&coord[4096][2]>=coord[4096][0]&&coord[4096][2]>=-coord[4096][0]&&coord[4096][2]>=coord[4096][1]&&coord[4096][2]>=-coord[4096][1])ellipsefill((BITMAP*)buffer,320+(int)(320*coord[4096][0]/coord[4096][2]),240+(int)(240*coord[4096][1]/coord[4096][2]),(int)(320/coord[4096][2]),(int)(240/coord[4096][2]),14);
21/*17*/}apply_matrix_f(&camera,coord[1][0]-coord[0][0],coord[1][1]-coord[0][1],coord[1][2]-coord[0][2],&coord[4096][0],&coord[4096][1],&coord[4096][2]);
22/*18*/if(coord[4096][2]>=0.1f&&coord[4096][2]>=coord[4096][0]&&coord[4096][2]>=-coord[4096][0]&&coord[4096][2]>=coord[4096][1]&&coord[4096][2]>=-coord[4096][1])for(i=0;i<4;i++)if((int)(a=rand()*((2*3.14159265358979323846f)/(RAND_MAX+1.0f)))|1)if((int)(x=320+320*coord[4096][0]/coord[4096][2])|1)if((int)(y=240+240*coord[4096][1]/coord[4096][2])|1)if((int)(ca=cos(a)*320/coord[4096][2])|1)if((int)(sa=sin(a)*240/coord[4096][2])|1)line((BITMAP*)buffer,(int)x-ca,(int)y-sa,(int)x+ca,(int)y+sa,12);
23/*19*/}destroy_bitmap((BITMAP*)buffer);
24/*20*/return 0;
25}END_OF_MAIN()
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 -- |
Thomas Fjellstrom
Member #476
June 2000
|
heh. just use my link, I think I have enough bandwidth. Like I care. Quote: 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: Quote: EDIT: I just realized that smiley has a different url MUAHAHAHAHAHA!!!!! edit3: OOOOHhhhhh.. the mouse.. heh. ooops. -- |
Bruce Perry
Member #270
April 2000
|
Tom: try the mouse. See my above edits. -- |
Thomas Fjellstrom
Member #476
June 2000
|
I much prefer a keyboard interface! Or maybe a joystick. (or my Sidewinder... ) -- |
23yrold3yrold
Member #1,134
March 2001
|
Quote: 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 -- |
Thomas Fjellstrom
Member #476
June 2000
|
maybe rename the immage? so its not a capital E? I don't know. -- |
23yrold3yrold
Member #1,134
March 2001
|
Quote: 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 ... -- |
Thomas Fjellstrom
Member #476
June 2000
|
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. -- |
Bruce Perry
Member #270
April 2000
|
Tom said: 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 -- |
Thomas Fjellstrom
Member #476
June 2000
|
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 -- |
Bruce Perry
Member #270
April 2000
|
I can apply an echo to a prerendered wav just as easily as I can apply an echo to an expensively generated stream. -- |
Thomas Fjellstrom
Member #476
June 2000
|
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. -- |
Goodbytes
Member #448
June 2000
|
Quote: 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. |
nonnus29
Member #2,606
August 2002
|
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??) |
Bruce Perry
Member #270
April 2000
|
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 -- |
Thomas Fjellstrom
Member #476
June 2000
|
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? -- |
Hein Zelle
Member #217
April 2000
|
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 :-)
|
Bruce Perry
Member #270
April 2000
|
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 -- |
23yrold3yrold
Member #1,134
March 2001
|
Quote: 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! -- |
Thomas Fjellstrom
Member #476
June 2000
|
Quote: 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: Quote: 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...) Quote: That's a lot of real estate! Headers don't count Quote: Hein: full marks for originality. Ja. Look at my originality! Its pong, just with more bugs! -- |
23yrold3yrold
Member #1,134
March 2001
|
Quote: Headers don't count #include <rpg.h>
-- |
Thomas Fjellstrom
Member #476
June 2000
|
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... -- |
Bruce Perry
Member #270
April 2000
|
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 -- |
|
|