MODE 22 ORIGIN 1024,384 VDU 23,1,0;0;0;0; ON ERROR OSCLI "REFRESH ON": MODE 22: END REM particle max, firework max pMAX%=50 FireWorkMax%=10 REM firework structure DIM p{(FireWorkMax%) x,y,z,xv,yv,zv,px(pMAX%),py(pMAX%),pz(pMAX%),pxv(pMAX%),pyv(pMAX%),pzv(pMAX%),r%,g%,b%,frameDelay%,pSize,hasExploded%,fade%} REM speed constants baselineYSpeed=4.0 maxYSpeed=4.0 GRAVITY=0.05 delay%=ABS(INKEY(-256)=87) REM initialize all fireworks FOR a%=0 TO FireWorkMax% PROCinitFW(a%) NEXT REM isometric constants zs=SQR(2) r2=SQR(2) REM only update screen after everything is drawn *REFRESH OFF REM main loop REPEAT REM loop to rotate isometric view FOR a=0 TO (PI*2) STEP PI/1000 CLS xs=COS(a) ys=SIN(a) REM Draw x axis in red, y axis in green, z axis in blue GCOL 1 PROCDrawLine(0,0,0,400,0,0) GCOL 2 PROCDrawLine(0,0,0,0,400,0) GCOL 4 PROCDrawLine(0,0,0,0,0,400) REM update fireworks PROCmoveFW REM update display and pause if space pressed *REFRESH REPEAT REM no delay on SDL as graphics is slower IF delay% WAIT 1 UNTIL NOT INKEY(-99) NEXT UNTIL FALSE END REM initialize a firework object to starting location DEF PROCinitFW(i%) p{(i%)}.x=-400+RND(800) p{(i%)}.y=-200+RND(400) p{(i%)}.z=0 p{(i%)}.xv=-3+RND(1)*5 p{(i%)}.yv=-3+RND(1)*5 p{(i%)}.zv=baselineYSpeed+(RND(1)*maxYSpeed) REM explosion starting colour, fade causes explosion colour to fade out p{(i%)}.r%=RND(255) p{(i%)}.g%=RND(255) p{(i%)}.b%=RND(255) p{(i%)}.fade%=100 REM firwork waits until frameDelay=0 p{(i%)}.frameDelay%=RND(200) p{(i%)}.pSize=1.0+RND(1)*3 p{(i%)}.hasExploded%=0 ENDPROC REM update firework and explosions position and plot particles DEF PROCmoveFW LOCAL i%,j% FOR i%=0 TO FireWorkMax% REM set colour to yellow for firework and rgb for explosion GCOL 3 IF p{(i%)}.hasExploded%=0 THEN COLOUR 3,255,255,0 ELSE COLOUR 3,p{(i%)}.r%,p{(i%)}.g%,p{(i%)}.b% ENDIF REM if firework is visible then update IF p{(i%)}.frameDelay%<=0 THEN REM update main firework co-ordinates p{(i%)}.x+=p{(i%)}.xv p{(i%)}.y+=p{(i%)}.yv p{(i%)}.z+=p{(i%)}.zv p{(i%)}.zv-=GRAVITY REM plot main firework particle PROCplotParticle(p{(i%)}.x,p{(i%)}.y,p{(i%)}.z) REM if firwork has exploded then update explosion co-ordinates IF p{(i%)}.hasExploded%=1 THEN FOR j%=0 TO pMAX% p{(i%)}.px(j%)+=p{(i%)}.pxv(j%) p{(i%)}.py(j%)+=p{(i%)}.pyv(j%) p{(i%)}.pz(j%)+=p{(i%)}.pzv(j%) p{(i%)}.pzv(j%)-=GRAVITY REM plot explosion particles PROCplotParticle(p{(i%)}.px(j%),p{(i%)}.py(j%),p{(i%)}.pz(j%)) NEXT REM decrement fade counter, if 0 then initialize a new firework p{(i%)}.fade%-=1 IF p{(i%)}.fade%<0 THEN PROCinitFW(i%) REM fade explosion rgb color values IF p{(i%)}.r%>0 THEN p{(i%)}.r%-=1 IF p{(i%)}.g%>0 THEN p{(i%)}.g%-=1 IF p{(i%)}.b%>0 THEN p{(i%)}.b%-=1 ENDIF REM if firework has not exploded and has reached maximum height then trigger explosion IF p{(i%)}.zv<0 AND p{(i%)}.hasExploded%=0 THEN REM update main firework particle to be part of explosion p{(i%)}.hasExploded%=1 p{(i%)}.xv=-5+RND(1)*9 p{(i%)}.yv=-5+RND(1)*9 p{(i%)}.zv=-5+RND(1)*9 REM set explosion position to match main firework and randomize explosion particle velocities FOR j%=0 TO pMAX% p{(i%)}.px(j%)=p{(i%)}.x p{(i%)}.py(j%)=p{(i%)}.y p{(i%)}.pz(j%)=p{(i%)}.z p{(i%)}.pxv(j%)=-5+RND(1)*9 p{(i%)}.pyv(j%)=-5+RND(1)*9 p{(i%)}.pzv(j%)=-5+RND(1)*9 NEXT ENDIF ELSE p{(i%)}.frameDelay%-=1 ENDIF NEXT ENDPROC REM draw a line in isometric viewport DEF PROCDrawLine(px1,py1,pz1,px2,py2,pz2) MOVE px1*xs+py1*ys,pz1*zs+(py1*xs-px1*ys) DRAW px2*xs+py2*ys,pz2*zs+(py2*xs-px2*ys) ENDPROC REM draw a rectangle in isometric viewport DEF PROCplotParticle(px1,py1,pz1) RECTANGLE FILL px1*xs+py1*ys,pz1*zs+(py1*xs-px1*ys),8,8 ENDPROC