The 512 bytes code challenge
BlitzMax Forums/BlitzMax Programming/The 512 bytes code challenge
| ||
Hi Blitzmax coders and welcome to a fun, educational code challenge! Similar to the previous 255 bytes challenge, this one only pushes the limit a bit farther, allowing plenty of creative code and amazing effects! Here's my entry, the Red 3D Cloud (512 bytes) p=512 h=256 Graphics p,p m=1000 a#=0.004 v=w=0 Local f#[p*p] For j=0To p*p-1 f[j]=Rand(9,h)Next b:TPixmap=CreatePixmap(p,p,6) Repeat z#=1.3 s=1 e=p-240 For j=s To e-1 For i=0 To p-1 c=f[i+j*p] x#=(i-h)/z y#=(j-c)/z+h+Rand(-3,3) v=x w=y If x>=0 And x<p And y>=0 And y<p b.pixels[v*4+w*b.pitch]=c Next z=z/1.0081Next For j=e-1 To s Step -1 For i=0 Until p f[i+j*p]=f[i+(j-1)*p]*0.999Next Next f[j*p]=Rand(80,220) For i=1 Until p f[i+j*p]=f[i-1+j*p]+Rand(-m,m)*a Next DrawPixmap b,0,0 Flip;Until KeyHit(27) |
| ||
Yeah it's an oldie but it's one of my faves... UNLIMITED BOBS! (512 Bytes -- I'm still on 1.26 so let me know if it flakes out on 1.28!) Liked the Red 3D Cloud by the way, remz -- kinda therapeutic :D |
| ||
(512 Bytes -- I'm still on 1.26 so let me know if it flakes out on 1.28!) works OK on 1.28 |
| ||
Okay, so I couldn't do decent blobby objects in 256 bytes, but here's a nice realtime blobby-object plasma in 511 bytes (not including carriage returns, line feeds, indentation or comments.) The numbers commented on the end of each line is a character count for the line.Const O=60,B=1024,M=768,Z=512,S=256,W=511,N#=0.2'48 Graphics B,M,32'15 For R#=1To W Step N'19 A#=R*R/B'8 SetColor A,A,A'14 DrawOval R/2,R/2,Z-R,Z-R'24 Next'4 H:TImage=CreateImage(Z,Z)'25 GrabImage(H,0,0)'16 Local C[O],D[O],E[O],F[O],K#[O]'31 For G=0To O-1'13 C[G]=Rand(0,B)'14 D[G]=Rand(0,M)'14 E[G]=Rand(0,4)-2'16 F[G]=Rand(0,4)-2'16 K[G]=C[G]'9 Next'4 SetBlend 4'10 Repeat'6 Cls'3 For G=0To O-1'13 C[G]:+E[G]'10 D[G]:+F[G]'10 If C[G]<0 Or C[G]>B Then E[G]=-E[G]'35 If D[G]<0 Or D[G]>M Then F[G]=-F[G]'35 K[G]:+N'7 SetColor B-K[G],Z-C[G],Z-D[G]'29 'multi SetRotation K[G]'16 DrawImage H,C[G],D[G]'21 Next'4 Flip 1'6 Until KeyHit(27)'16 'Alternative palettes 'SetColor K[G]/2,S-C[G]/3,D[G]/2'31 'hotpink 'SetColor K[G]/2,C[G]/3,S-D[G]/2'32 'yellow 'SetColor K[G],S-C[G]/3,S-D[G]'30 'redyellow 'SetColor B-K[G],Z-C[G],S-D[G]'29 'redyellowmulti 'SetColor B-C[G],Z-D[G],S-K[G]/2'31 'redyellowpinkgreen 'SetColor S-K[G],Z-C[G],B-D[G]'29 'blues 'SetColor K[G],S-C[G]/3,S-D[G]/3'32 'hotpink red 'SetColor S-C[G]/2,D[G]/3,K[G]/2'32 'bluegreen 'SetColor C[G]-D[G],S-K[G],C[G]'31 'blue and pink 'SetColor K[G]-C[G],C[G]-D[G],D[G]'34 'multi 'SetColor K[G]-C[G]-D[G],C[G]-D[G],K[G]'40 'blues At the end there you can see some alternative ways to generate colors. I liked the multicolored one currently produced, and at 1024x768 anything from 40 to 100 objects looks good. At the start of the code, the first constant O is the number of blobby objects (currently 60 to give a fairly even density), the constant B is the screen width and M is the screen height. If you change the resolution you may want to change the number of objects to compensate for the change in distribution density. Changing the DrawOval to a DrawRect will give you inverted blob fields which looks quite different. Also it could do with a SeedRnd(Millisecs()) near the start otherwise I think you get the same behavior and colors each time - but there's no bytes free. Also the colors seem to drift toward a blue/green palette after a while for some reason, but hey. Each object covers a 512x512 area, which is 262,144 pixels per object in 32-bit color, or about 1.05 megabytes per object. For 60 objects there are about 15.7 million rendered pixels per frame, and approximately 63 megabytes graphics rendered per frame (although a fair amount is clipped). Every pixel is also doing blending operations and since blending is done on a per-color-component basis, there are actually up to 63 million color-blend calculations per frame. The maximum total rendered per second is about 3.7 billion pixels. Fortunately since not every object is fully on-screen at the same time, it runs smoothly on my ATI X1600 card - which has texture rendering throughput of about 2 billion texels per second. I am not sure if it's going at 60fps or 30. So it'll depend on your graphics card as to whether it runs fast enough. And finally, press Escape to exit ;-) |
| ||
^ awesome. |
| ||
Loved that plasma! Can you slow it down? Maybe: ? E[G]=Rand(1,2)-2 F[G]=Rand(1,2)-2 |
| ||
If you don't mind going beyond the 512 byte limit, you can convert the arrays to all Floats and then specify something like E[G]=(FloatRnd()-0.5)*Speed and the same for F[G]. The C and D arrays (x and y positions) must be float also. Then you can make it really slow if you want to. Another aspect of how it moves is the rotation around the corner of each object. Currently a constant N is shared between two parts of the program. For the loop with the drawing of ovals the Step should really be 0.5 but it doesn't hurt when it's down at 0.2, since that value is also the rotation speed. You can change K[G]:+N to something like K[G]:+0.1 to slow down the rotation, since K is the rotation angle array. |
| ||
Thanks! Do you have a website? |
| ||
Hi, no I don't have a website yet. I want to make one, actually a few, but I know it will take quite a lot of time and effort and I need some decent content to make it about, so I'm focussing on programming at the moment. Then when I am ready with a game or at least a demo I will put up a website. I am waiting also for someone else to write another 512-byte effect. Come on guys and gals! ;-) |
| ||
Well I just added the Framework command to my entry (still under 512 bytes source!) in order to get the exe size down too... BRL.GLMax2D produces a smaller exe than BRL.D3D7Max2D but there's a weird stippling effect with the former. Here's a zip containing both versions -- if you've got time then let me know if you see the difference too as I'm wondering whether to post a bug report. [Piccies no longer needed] |
| ||
if you've got time then let me know if you see the difference too as I'm wondering whether to post a bug report. Tested them both on my Win XP machine, they both look exactly the same. What's that decompressing thing with your exe? An EXE packer? |
| ||
hmm.. OpenGL shows a transparent triangle covering half the screen, and dx7 only shows one cirlce (bob?); yet continues to count up. |
| ||
What's that decompressing thing with your exe? An EXE packer? Yup -- ANDpakk2. Seems to pack smaller than UPX at the expense of some decompression time. Tested them both on my Win XP machine, they both look exactly the same. Ah. Must be a driver issue here then (integrated GFX FTW!) -- makes sense as it's fine fullscreen. hmm.. OpenGL shows a transparent triangle covering half the screen, and dx7 only shows one cirlce (bob?); yet continues to count up. Now that's not good! (I added some screenshots to my previous post -- the second is what it's supposed to look like.) Do you mind me asking what OS and GFX card you're using? You can see from the source above (have you tried compiling it, incidentally?) that I am not doing anything particularly esoteric. Thanks for the feedback, chaps. |
| ||
Ok I got another one, even with on-screen instruction ;) The Random Tree. 512 bytes. Click the mouse to generate a random tree! w=512 Graphics w,w Global b#=0.75,p#=33,z#=150,v#=0.0073,d=0,e=1,t=0 n#=0 g=200 Repeat SeedRnd(e) t:+1 p:+Sin(t)*0.08 Cls r(256,w,z,-90) DrawText"Click",0,0 Flip() GCCollect() If MouseHit(1) t=-50 e:+1 Until KeyHit(27) Function r(x#,y#,l#,a#) If d>14 Return d:+1 c#=Cos(a)*l s#=Sin(a)*l x2#=x+c y2#=y+s If d<5 SetColor 150,99,40 Else h#=Rnd(0.4,1) SetColor 0,255*h,0 DrawLine x,y,x2,y2 w#=Rnd(0.3,1) r(x+c*w,y+s*w,l*b,a-Rnd(p-20,p+20)) w=Rnd(0.3,1) r(x+c*w,y+s*w,l*b,a+Rnd(p-20,p+20)) d:-1 EndFunction |
| ||
WOOT! |
| ||
Sledge, it looks as though your window on the left there looks like it has dithering switched on, which suggests it may be a 16-bit display. Remz - that is very cool indeed, great to see a realtime fractal in motion! |
| ||
Nothing as groovy as fractals and blobs... 511 bytes. Left/Right and Space to play. x=995p=360Type t Field a=Rand(0,360),d#=300EndType w=512 Graphics w,w HideMouse()c=256s=0q=0h=0e:TList=New TList Repeat If Rand(1000)>x z=New t e.addlast(z) If KeyDown(37)a:-2 If KeyDown(39)a:+2 a=(p+a)Mod p If KeyDown(32) And Not h h=11 If h h:-1 f#=Cos(a)g#=Sin(a) Cls DrawText s,9,9 l=20If h=10 l=w DrawLine c,c,c+f*l,c+g*l For i:t=EachIn e m=i.a k#=i.d If h=10 And Abs(a-m)<400/k s:+5x:-1e.remove i DrawOval c+k*Cos(m),c+k*Sin(m),10,10 i.d:-0.5If i.d<5 q=1 Next Flip Until KeyHit(27)Or q;Notify s |
| ||
Oh... my best so far is 300 :-p |
| ||
Do you mind me asking what OS and GFX card you're using Windows XPSP2 ATI Radeon 7500 @remz:Thats amazing! EDIT: Left is OpenGL, right is DirectX. You might have to look closely to see the triangle (it starts at the top left corner) ![]() |
| ||
I just thought of something for the plasma thingy; you should play around with different shapes (maybe create an anim image?) I would try that, but I'm about to fall asleep on my keyboard, so night! |
| ||
Been there done that. ;-) |
| ||
Sledge, it looks as though your window on the left there looks like it has dithering switched on, which suggests it may be a 16-bit display. You know, that's the very first thing I thought so I had a look at my display properties and -- yup -- 32-bit. But I took another look just now and it was set to bloody 16-bit! I've been running a few fullscreen apps on and off recently so I guess one of 'em stiffed me I FEEL SUCH A FOOL! @Plash: Thanks for that. Between ATI and Vista (imagine having both!) a bright and glorious future for the PC is assured. 'Grab and paste a portion of the screen mate? Grab and paste a portion of the screen mate? Nah mate. You're mad mate. You're asking for the uuuuuurf!' |
| ||
'Grab and paste a portion of the screen mate? Grab and paste a portion of the screen mate? Nah mate. You're mad mate. You're asking for the uuuuuurf!' /me is lost. |
| ||
I'm saying that if ATI hate writing GFX drivers so much then they're probably in the wrong business. What Windows scheme is that in your screenies, by the way? |
| ||
Cute game, Brucey, I got 130. ;-\ |
| ||
What Windows scheme is that in your screenies, by the way? http://lassekongo83.deviantart.com/art/Lakrits-Visual-Style-59440359 |
| ||
This one's not very amazing.... 511 chars.. Right to turn (right), and Up for forward.. The idea is to navigate to the bottom right corner (which would have been the "exit" had I had more space to work with... Thanks to DavidDC for the "mod 4" tweak :-) Anyhoo... have fun :-) |
| ||
|
| ||
@WARPY. Press Play on tape. _ |
| ||
Here's one, Type based, 505'ish [EDIT] made a small change to let the C() method of the world object take a parameter, because otherwise I could have just used new() |
| ||
Excellent Peter! |
| ||
Nice bubbly particle effect, Peter. |
| ||
@ImaginaryHuman Awesome! But how to stop it from going to the blue palette? |
| ||
Trying to squeeze that effect into 512 bytes wasn't very easy. I had to make multiple use of some of the variables for things which shouldn't really be tied together. The palette values are being calculated based on the coordinates of the objects and the angle of rotation. It might be preferable to have an entirely separate array for color values per object and to then animate those values as you wish. Since the objects basically are bouncing off the edges of the screen (even though they appear to move beyond the screen due to rotation), their coordinates should generally increase up to a point and then decrease again so it shouldn't drift towards green/blue and then stay there. I think possibly it is due to the red component being based on the rotation angle, and there not being any cap on the maximum angle value. It just keeps adding more to the angle so once it goes over 360 it just keeps on going. If you simply change the red color calculation to `(B-K[G]) Mod 256` or something like that you should see the red component being retained, although it's going to jump when it wraps around from 255 to 0. It might be preferable to implement some kind of sine-wave type of color animation, e.g. component=128*Sin(Angle). You'll notice that in the demo it's `B-` the angle which subtracts the angle from 1024, so you might need to play around with it to get the values into a range that appeals to you. And yes feel free to make it your next screensaver because I don't plan to make screensavers - just had too many difficulties trying to get it to work on a Mac since Apple requires the use of their Objective C framework. I am going to make a blobby-object game at some point, though. |
| ||
just had too many difficulties trying to get it to work on a Mac since Apple requires the use of their Objective C framework Had a long look into this recently, but we need a way to compile in such a way as to have the end-product a special object file (rather than an executable). Requires a custom appstub, more work on BMK, and a bit more time understanding the compiler flags. I got as far as having everything (stub+mod) except the bmk changes working. But it seems a lot of effort for something so niche. |
| ||
Yes, I looked into it a bit but not quite at that depth, since I didn't quite understand what was needed. My impression was you have to write it in Objective C and use Apple's libraries to open the screen and do timing and stuff so I just gave up on it. If it can't be almost entirely written in BlitzMax I'm not interested. It seemed like a lot of difficult effort just to make a screensaver. A screensaver can be really cool and fun and get fast results, but not when it's hard to implement. I did sort of get one working on Windows and I noticed many other people have released them for Windows, since Windows makes it relatively easy to do, but even there I had problems getting the preview window to be consistent. So I gave up. These days screensavers aren't even really screen savers and the whole point is that they show up when you're NOT at your computer, so I don't see the point, but I think they're really cool to actually play around with (options etc) when used for that purpose. |
| ||
left/right, esc to quit |
| ||
Cool brucey, I got 2824 on my first attempt. I seem to remember seeing a simple game like this somewhere before. Good job. |
| ||
some pretty cool stuff. here's mine. simple, no chance of "winning" hehe. SuperStrict Global scx:Int=256 Global scy:Int=256 Graphics scx,scy Global x:Int,y:Int,c:Int Global colr:Int,colg:Int,colb:Int,frame:Int While Not AppTerminate() For x=0 To scx-1 For y=0 To scy-1 colr=(Sin((((Sin(x)*Cos(y)))*360)+frame)/2)+1 colg=(Sin((((Cos(x)*Sin(y)))*360)+frame)/2)+1 colb=(Sin((((Sin((x+y)/1)*Cos((x+y)/2)))*360)+frame)/2)+1 SetColor colr*255,colg*255,colb*255 Plot x,y Next Next Flip frame=frame+10 Wend [edit] Entry 2. Both of these done at work. this one is inspired by something Chris C did a few days back, decided to code my own version. Pretty easy to put walls in :-) Global a=256,b=256,e#,cb,ob=1,c#,w#[2,a,b] Graphics a,b i=CreateImage(a,b,1,10) SetBlend 2 While AppTerminate()=0 p:TPixmap=LockImage(i) w[ob,MouseX(),MouseY()]=Sin(MilliSecs())*2 For x=1 To a-2;For y=1 To b-2;c=((w[ob,x+1,y]+w[ob,x-1,y]+w[ob,x,y+1]+w[ob,x,y-1])/2-w[cb,x,y])*0.999;w[cb,x,y]=c;Next;Next For x=1 To a-2;For y=1 To b-2;e=(((w[cb,x+1,y]-w[cb,x,y+1])*0.9)+1)*200;WritePixel p,x,y,e+(Int(e) Shl 16);Next;Next UnlockImage i DrawImage i,0,0 ob=cb;cb=(cb+1) Mod 2 Flip 0 Wend I *hope* this one works for you all, i have problems with pixmaps so I get a black screen (including the fix slows it down and isn't required if the problem is with my machine.) |
| ||
Imaginary: How does that blob code of yours work? I could spend a half an hour trying to figure it out, but I'm sure you can describe exactly what it's doing in a couple seconds. I can see you're drawing something with ovals, copying it and then blitting it about with lightblend, but are they blurry ovals with an exponential falloff or what? |
| ||
Is it this and/or this ? |
| ||
Tony: Well that exponential falloff thing is what I thought he might be doing, but it's not obvious from his code that it is in face what he's doing. I'm not sure how drawing a bunch of ellipses arrives at that, unless maybe he's drawing over the same pixels a ton of times in a wasteful manner to generate the graphic. (I say wasteful, but I realise it might have been the way that required the least amount of code, and since it's only done once speed may not be an issue.) I was thinking about exploring this effect for use in my Space Beetles game, cause a bunch of blue blobs merging and seperating would look a lot like some nebula I was planning on having in the background but might be more interesting to look at than a repeating scroll. (On the other hand, it might be too distracting, but maybe if I made it move slowly enough...) |
| ||
Yes, read the tutorial as linked to by TonyG, it will explain how the curvature of the gradient is different to a linear curve and how that is what is required in order to produce a curved boundary. You will notice that if you just draw ovals at decreasing radius' and for each oval you also increase the color value by 1, you're going to get a linear gradient and when you do a lightblend (ADD) of two such images together you do NOT get a blobby-object behavior. You get very angular linear areas of merging like straight tunnels or like the parting of an ocean, but nothing at all curved. To produce the curvature of the blobby contour you have to modify the gradient to be based on *some* kind of a curved increase rather than linear. It doesn't have to be squared but in my case that seemed to produce a good enough result - different subgenre's of blobby objects seem to have different formula to calculate the falloff amount at a given radius, but squaring is ok. The way that the blobby objects behave is produced *entirely* from the fact that the gradient is curved. I draw a bunch of ovals with linearly decreasing size to make sure there are as many levels as possible to create a smooth progression, but as the size decreases linearly the amount of change in the color changes following a squared curve. At the middle of the blob image the colors are being added by about 1 per radius but it levels out to create a curve the further you get. ie the further you get from the center, the quicker the color diminishes. When you then add two such images together, the result of all the additions, given that the gradient is curved not linear, results in a curved result rather than a linear one, and basically is what you'd consider a blobby object behavior - ie the closer one object gets to the center of another, the more intensity there is and thus the curve appears spacially instead of just in terms of intensity. Basically, blobby objects are simply `particles` of energy with an energy field around them, and similar to gravity the energy falls off increasingly quickly the further you get from the center, rather than linearly. When you put two particles near to each other, the `value` at any position in the field is simply the sum (addition) of the energy fields of both objects at that coordinate. The addition is done by the lightblend drawing and the squared fall-off energy field values are precalculated per-pixel into images (pixel arrays), making it possible for graphics hardware to render an entire blob field as a single quad, which it is very good at. This isn't really my invention as such, as blobby objects are done quite a bit already, but doing blobby objects in 2D by precalculating the fields into images and using the hardware to render it fast is (i think) my invention. And yes there is lots of overdraw from the ellipses - I've since made a function which goes through each pixel once in x-y loops and just figures out the amount of energy at each pixel. I'm not sure it's really any faster. Does that explain it? It's not that advanced really, it's just clever. |
| ||
That's what I thought you were doing. The only thing that's confusing me though is why there's such big flat colored areas. I can see the glowing dots moving about the the falloff around them, but when they approach another dot suddenly there's a big clipped region. I guess maybe that's to do with color 128 being decently far out from the center of the dot cause it looks like your gradient is spherelike inverse exponential instead of like a regular exponential curve where the center dot would be far higher than the pixels neighboring it. Also it seems like you're color shifting the dots as they move about as well and fading them out at some points. |
| ||
That demo does fade and change the colors which causes the energy field values to be scaled, and since the additions are done on a per-component basis you see different changes in the Red, Blue and Green channels separately. I think you're referring to what happens when the result of the additions produces a value >255. The value will be clipped. There isn't enough dynamic range, is all. Ideally for the blobs to be accurate and perfect you'd need a floating point buffer and would make sure that values can be added several times higher than the maximum energy in a given object. The flat areas are just the areas where the values have been clipped due to too much brightness, which in part is due to too many objects. Reduce the object count and you'll see less of it, but wherever a blob's edge overlaps another blobs center you'll start to see clipping. |
| ||
I thought you might be blitting the scene over itself or using a special blob shape to get that effect. Didn't seem like a the few blobs there seemed to be could make such large flat areas by themselves. But maybe there's more there than it looks like and the only points I see moving around are ones that happen to not have any others nearby. |
| ||
You guys are mental - some crazy shit in this thread! :) |
| ||
I'm glad I ran Brucey's sample, I was thinking about doing that, after seeing a youtube video today of some people in a theatre simulating that game. |
| ||
Can I kick it? - 512 bytes - click the ball to keep it in the air - with motion blur :) - including hiscore! |
| ||
Sswift, yeah, it's just based on the number of objects. 80 is actually a lot and you see the general effect better with like 20 objects. |