Here's an improved version of the game, with "forced timing" and power-up items, in 16 lines.
Please tell me if it works well, and if it's playable (or fun).
Do you think it's good enough for the 20-lines challenge ?
Rules of the game:
- Click on the ball to keep it in the air. Each time you click it, you score 1 point.
- If the ball hits the ground, you loose and your score goes back to zero.
- Click the ball to start a new game, and another one, and another one, till insanity ensues.
Regularly, "power-up" items fall from the sky:
-Green "i" (inflate): makes the ball 10% bigger, thus easier to control.
-Green "P" (Protection): The ground turns green, and you won't loose the next time the ball hits it.
-Blue "G" (Gravity): reduces the gravity and slows down the pace of the game.
-Blue "?" (Random): gives you a random item in this list, or does nothing.
-Pink "5" : adds 5 points to your score.
-Pink "10": adds 10 points to your score.
-Red "D" (deflate): Avoid it! It reduce the ball size by 20%.
-Red "W" (wobble): Avoid it too! It makes the ball very hard to control.
Good luck!
set window on:set window title "Juggler - Keep it in the air!":autocam off:sync on:sync rate 0:c$="DARKBASIC":ink rgb(255,255,255),0:box 0,0,80,64:ink rgb(255,0,0),0:text 0,0,c$:box 0,100,63,115:ink rgb(0,0,255),0:text 0,24,c$
box 192,100,255,115:ink rgb(0,255,0),0:text 0,12,c$:box 128,100,191,115:text 204,100,"G ?":ink rgb(255,0,255),0:text 0,36,c$:box 64,100,127,115:text 140,100,"i P":ink rgb(255,255,0),0:text 0,48,c$:text 12,100,"W D 5 10"
get image 1,0,0,79,63:make object sphere 1,60:texture object 1,1:dim t#(4):for i=2 to 9: get image i,-64+i*32,100,-33+i*32,115:make object cylinder i,20:texture object i,i:zrotate object i,90:position object i,0,-50,0:next i
make object plain 999,640,10:position object 999,320,475,0:backdrop on:color backdrop 0:x#=320:y#=440:s#=1:g#=1:bn=2:by#=499:ot#=timer():t#(0)=20:t#(1)=20:t#(2)=20:t#(3)=20:t#(4)=20:randomize timer()
position camera 320,240,400:roll camera left 180:turn camera left 180:set point light 0,0,0,200
do
inc x#,(xd#*g#*lt#)+(w#*cos(wf#)):inc y#,yd#*g#*lt#:vl#=466-(s#*30.00):if g#<1:inc g#,0.0005*lt#:endif:if w#>0:dec w#,0.01*lt#:wf#=wrapvalue(wf#+10.0*lt#):else:w#=0:endif
if y#>vl#:if p=0:if n>nb:nb=n:endif:n=0:g#=1:s#=1:w#=0:scale object 1,100,100,100:endif:p=0:color object 999,rgb(255,255,255):y#=vl#:yd#=yd#*-0.66:if abs(yd#)<1:yd#=0:endif:else:if y#<vl#:yd#=yd#+(0.6*g#*lt#):endif:endif
if x#<(s#*30.00) or x#>640-(s#*30.00):dec x#,xd#:xd#=xd#*-1:else:xd#=xd#*0.99:if abs(xd#)<0.1:xd#=0:endif:endif
if mouseclick()=1 and clk=0:dsx#=x#-mousex():dsy#=y#-mousey():clk=1:if (dsx#*dsx#)+(dsy#*dsy#)<900*(s#*s#):inc n:yd#=-10:xd#=dsx#/(2.0*s#):yrd#=dsy#/10.0:endif:endif:if mouseclick()=0:clk=0:endif
position object 1,x#,y#,0:xrotate object 1,wrapvalue(yrd#*abs(xd#)):Fix Object Pivot 1:zrotate object 1,wrapvalue(xd#):Fix Object Pivot 1
inc by#,lt#:if by#>500:by#=-50:bx#=rnd(600)+20:bn=rnd(7)+2:endif:position object bn,bx#,by#,0:xrotate object bn,wrapvalue(by#*-3.14):if bx#<x#: bxc#=bx#+10:else:bxc#=bx#-10:endif:if by#<y#: byc#=by#+10:else:byc#=by#-10:endif
if ((bxc#-x#)*(bxc#-x#))+((byc#-y#)*(byc#-y#))<900*(s#*s#) and n>0:by#=490:bv=bn:if bv=9:bv=rnd(7)+2:endif:if bv=2:w#=3:endif:if bv=3 and s#>0.4:dec s#,0.2:scale object 1,100*s#,100*s#,100*s#:endif:if bv=4 or bv=5:inc n,(bn-3)*5:endif
if bv=6 and s#<2:inc s#,0.1:scale object 1,100*s#,100*s#,100*s#:endif:if bv=7:p=1:color object 999,rgb(0,255,0):endif:if bv=8:g#=0.5:endif:endif
text 10,10,"Best: "+str$(nb)+" / Current: "+str$(n):inc nt:if nt=5:nt=0:endif:t#(nt)=timer()-ot:ot=timer():lt#=(t#(0)+t#(1)+t#(2)+t#(3)+t#(4))/100.0:sync
loop
Remstart
This is Juggler, a little game for DBC (and probably DBPRO) in 16 lines.
The rules are simple:
- Click on the ball to keep it in the air. Each time you click it, you score 1 point.
- If the ball hits the ground, you loose and your score goes back to zero.
- Click the ball to start a new game, and another one, and another one, till insanity takes over.
Regularly, "power-up" items fall from the sky:
-Green "i" (inflate): makes the ball 10% bigger, thus easier to control.
-Green "P" (Protection): The ground turns green, and you won't loose the next time the ball hits it.
-Blue "G" (Gravity): reduces the gravity and slows down the pace of the game.
-Blue "?" (Random): gives you a random item in this list, or does nothing.
-Pink "5" : adds 5 points to your score.
-Pink "10": adds 10 points to your score.
-Red "D" (deflate): Avoid it! It reduce the ball size by 20%.
-Red "W" (wobble): Avoid it too! It makes the ball very hard to control.
Remend
Remstart
Code comments:
Line 1 to 4: Set up the game window, generate textures and objects, initialize some variables.
line 5: position and roll the camera so that 3D coords match 2d coords, and move light too.
Line 7: Update movement variables
Line 8: Y axis management (what happens when the ball is in the air or when it hits the ground)
Line 9: X axis management (lateral movement and bounces)
Line 10: Mouse click. Calculate if the cursor is on the ball. If so, compute new ball movement
Line 11: Display and rotate the ball
Line 12: Power-up item movement
Line 13 and 14: what happens when the ball hit an item (the item number determines the effect)
Line 15: Score display, compute mean loop duration for "forced timing", sync
Line 16: Loop!
Main variables:
x#,y#,xd#,yd#: ball position and movement
vl#: vertical limit for y# -> "ground level"
s#: ball scale (1=normal;0.8 = 20% smaller)
g#: gravity (1=normal;0.5=half gravity)
w#,wf#: Wobble factor (for horizontal oscillations -> item 2)
bn,bx#,by#: item number and position
bxc#,byc#: the closest item corner from the ball (for collision)
n,nb: score, best score
t#(0->4), lt#: last five loop durations, mean loop duration
General notes:
-The game is in pseudo-2D: all 3D objects move only on X and Y axis, and camera is positionned
and otated so that 3D units match pixels (in 640x480 only). This way, there's no need to convert
the mouse position from 2D to 3D...
-To check in the mouse is on the ball, I calculate its distance from the center:
-> (mouseX-ball X)²+(mouseY-ball Y)² <= ball radius²
The ball radius is equal to 30*scale, so I use (30*s#)*(30*s#) <=> 900*(s#*s#).
-To check if the ball hits a "power-up" item, I do the same. But as the items are roughly rectangular on
screen, I replace the mouse position in the formula by the closest item corner from the ball.
Notes on "forced timing"
"Forced timing" (I know the term isn't correct here) is used to ensure that the objects move
at (more or less) the same speed on all computers. Each movement is multiplicated by a factor
which is ideally equal to 1 on the reference computer, superior to 1 on slower cpu, and inferior
to 1 on faster ones.
Ex: the base movements for this game has been designed for a sync rate = 50. "sync rate 50" means
each loop is 20ms long. So, with "sync rate 0", the forced timing factor is equal to [loop duration]/20.0 .
If your CPU is twice as fast as mine and can loop in only 10ms, the factor will be 0.5 and each
movement (in one loop) will be half as long as those on the reference CPU => they will be smoother,
but not faster.
And as the loop durations are irregular (if Windows does something in the background, for example),
I use the mean duration of the five last loops to avoid chaotic behaviours. That's why the "forced
timing" factor is equal to ((t1+t2+t3+t4+t5)/5.0)/20.0 <=> (t1+t2+t3+t4+t5)/100.0 .
remend
Ideas: memories of things which did not occur yet...