' B I G Y A R D S ' - - - - - P A R A M E T E R S - - - - - GLOBAL SHOOTIT,XSHOOT,YSHOOT SHOOTIT=-1 BALLS=26 HOLES=3 REPULSION=0.01 DRAG=0.01 FRICTION=0.01 GRAVITY=0 'BOUNDARIES BALL_SIZE=9 B_RI=159-BALL_SIZE B_LE=0 B_UP=0 B_LO=127-BALL_SIZE CHARACTER=64 ' - - - - - I N I T - - - - - GLOBAL REPULSION,DRAG,FRICTION,GRAVITY GLOBAL B_RI,B_LE,B_UP,B_LO,BALL_SIZE,BALLS,HOLES GLOBAL VOICE_,CHARACTER N=BALLS+2 DIM PX(N),PY(N),VX(N),VY(N) CALL SETUP_OBJECTS(BALLS,HOLES,N,PX(),PY()) RANDOMIZE TIMER TOUCHSCREEN ' - - - - - S E T U P - - - - - SUB SETUP_OBJECTS(BALLS,HOLES,N,PX(),PY()) CALL SETUP_BALLS_S(PX(),PY()) CALL SETUP_BALLS_G(70,60,0.5,BALLS,N,PX(),PY()) CALL SETUP_HOLES(HOLES,N,PX(),PY(),160-BALL_SIZE,128-BALL_SIZE) END SUB SUB SETUP_BALLS_S(PX(),PY()) FOR I=0 TO 1 SPRITE I,0,0,CHARACTER SPRITE I PAL I+1 PX(I)=10+20*I PY(I)=60 NEXT I END SUB SUB SETUP_BALLS_G(X,Y,D,BALLS,N,PX(),PY()) PI2=PI*2 PSTEP1=PI2/6 PSTEP2=PI2/12 PSTEP3=PI2/24 FOR J=2 TO BALLS+2 SPRITE J,0,0,63+J IF J=2 THEN PX(2)=X PY(2)=Y ELSE IF J>2 AND J<9 THEN AJ=(J-3)*PSTEP1 PX(J)=X+9*COS(AJ) PY(J)=Y+9*SIN(AJ) ELSE IF J<21 THEN AJ=(J-3)*PSTEP2 PX(J)=X+18*COS(AJ) PY(J)=Y+18*SIN(AJ) ELSE AJ=(J-3)*PSTEP3*3 PX(J)=X+27*COS(AJ) PY(J)=Y+27*SIN(AJ) END IF NEXT J END SUB SUB SETUP_HOLES(HOLES,N,PX(),PY(),W,H) 'HOLES HAVE A FIXED POSITION AND A NEGATIVE REPULSION (ATTRACTION) (ON SPRITE HIT) D=(H*2+H*2)/(HOLES+1) C=160/128 FOR I=0 TO HOLES I2=I+N+1 P=I*D X=0 Y=0 CALL WRAPMAP(P,128-BALL_SIZE,128-BALL_SIZE,X,Y,1) X=X*C SPRITE I2 PAL 7 SPRITE I2,X,Y,CHARACTER NEXT I END SUB SUB WRAPMAP(P,W,H,X,Y,S) WH=W+H P2=(P MOD (2*WH-4))-WH*2+INT(H*1.5+1)+S X=ABS(P2+S)-INT(H*0.5) Y=ABS(P2+W)-INT(W*0.5) CALL CLAMP(X,0,W-1) CALL CLAMP(Y,0,H-1) END SUB ' - - - - - M A I N L O O P - - - - - DO CALL PHYSICS (N,VX(),VY(),PX(),PY()) REM CALL USER_INPUT(PX(),PY()) CALL DRAW (N,PX(),PY()) WAIT VBL LOOP SUB DRAW(N,PX(),PY()) IF TOUCH THEN SPRITE 0,PX(0),PY(0), PLAY 0,90,1 SOUND 0 XDIS=(SPRITE.X(0)-SPRITE.X(1))/10 YDIS=(SPRITE.Y(0)-SPRITE.Y(1))/10 XSHOOT=XDIS YSHOOT=YDIS FOR III=1 TO 10 SPRITE 50+III,PX(0)-III*XDIS+4,PY(0)-III*YDIS+4,16 NEXT III SHOOTIT=SQR(XDIS*XDIS+YDIS*YDIS)/1.5 ELSE IF SHOOTIT>-1 THEN SPRITE 0,SPRITE.X(1)+SHOOTIT*XSHOOT,SPRITE.Y(1)+SHOOTIT*YSHOOT, SHOOTIT=-1 WAIT 7 ELSE SPRITE OFF 0 SPRITE OFF 50 TO 60 END IF END IF FOR I=1 TO N IF SPRITE.X(I)<>-32 THEN SPRITE I,PX(I),PY(I), NEXT I END SUB SUB USER_INPUT(PX(),PY()) IF TOUCH THEN PX(0)=TOUCH.X-BALL_SIZE*0.5 PY(0)=TOUCH.Y-BALL_SIZE*0.5 END IF END SUB SUB PLAYSOUND(N) IF N=0 THEN PLAY VOICE_,30 SOUND 0 VOLUME VOICE_,7, ADD VOICE_,1,0 TO 2 ELSE IF N=1 THEN PLAY 3,30 SOUND 2 VOLUME VOICE_,15, END IF END SUB ' - - - - - P H Y S I C S - - - - - SUB PHYSICS(N,VX(),VY(),PX(),PY()) FOR I=0 TO N FX=0 FY=0 CALL PHYSICS_LOOP(I,FX,FY,VX(I),VY(I),PX(I),PY(I),PX(),PY()) NEXT I END SUB SUB PHYSICS_LOOP(I,FX,FY,VX,VY,PX,PY,PX(),PY()) CALL FORCES (I,FX,FY,VX,VY,PX,PY,PX(),PY()) CALL MOTION ( FX,FY,VX,VY,PX,PY) CALL COLLISION(I,FX,FY,VX,VY,PX,PY) END SUB SUB FORCES(I,FX,FY,VX,VY,PX,PY,PX(),PY()) DX=VX DY=VY CALL UNIT_VECTOR(DX,DY) 'BOUNCE_L (LINEAR), BOUNCE_Q (QUADRATIC) (SUBPROGRAM PARAMETERS ARE THE SAME) CALL BOUNCE_Q(I,FX,FY,VX,VY,PX,PY,PX(),PY(),REPULSION) CALL FORCE(FX,VX,DX,GRAVITY,FRICTION,DRAG) CALL FORCE(FY,VY,DY,GRAVITY,FRICTION,DRAG) END SUB SUB FORCE(F,V,D,MG,MF,MD) CALL GRAVITY(F,MG) CALL FRICTION(F,D,MF) CALL DRAG(F,V,MD) END SUB SUB GRAVITY(F,M) ADD F,M END SUB SUB FRICTION(F,D,M) ADD F,-D*M END SUB SUB DRAG(F,V,M) ADD F,-SGN(V)*MIN( M*V*V, MIN(ABS(V),100)) END SUB SUB MOTION(FX,FY,VX,VY,PX,PY) ADD VX,FX ADD VY,FY ADD PX,VX ADD PY,VY END SUB SUB COLLISION(I,FX,FY,VX,VY,PX,PY) CALL C_WALL(FX,VX,PX,B_LE,B_RI) CALL C_WALL(FY,VY,PY,B_UP,B_LO) END SUB SUB C_WALL(F,V,P,B1,B2) IF PB2 THEN V=-ABS(V) END SUB SUB BOUNCE_L(I,FX,FY,VX,VY,PX,PY,PX(),PY(),M) 'BALL COLLISIONS WITH LINEAR REPULSIVE FORCE IF SPRITE HIT(I) THEN IF HIT<50 THEN D=0 DX=PX-SPRITE.X(HIT) DY=PY-SPRITE.X(HIT) ADD FX,DX*M ADD FY,DY*M END IF END IF END SUB SUB BOUNCE_Q(I,FX,FY,VX,VY,PX,PY,PX(),PY(),M0) 'BALL COLLISIONS WITH QUADRATIC REPULSIVE FORCE 'THE GRAVITATION FORMULA BUT NEGATIVE IF SPRITE HIT(I) THEN IF HIT<50 THEN D=0 M=M0 DX=PX-SPRITE.X(HIT) DY=PY-SPRITE.Y(HIT) CALL MAG_SQ(DX,DY,D) CALL INVERT(D) CALL EXCEPTIONS(M,DX,DY,I,VX,VY) 'CONVERTOR: UNIT VECTOR (*SQR(D)), EXPONENTIAL (*D), AMOUNT (*M): CLAMPED AGAINST NUCLEAR FORCES C=SQR(D)*MIN(10,MAX(-0.1,D*M)) ADD FX,DX*C ADD FY,DY*C END IF END IF END SUB SUB EXCEPTIONS(M,DX,DY,I,VX,VY) IF HIT=0 AND I<>1 OR I=0 THEN EXIT SUB IF HIT<=BALLS+2 THEN M=M*4000 CALL PLAYSOUND(0) ELSE 'BALL IN HOLE M=-5 IF ABS(DX)<=5 AND ABS(DY)<=5 THEN IF I>1 THEN SPRITE OFF(I) CALL PLAYSOUND(1) ELSE VX=VX*10 VY=VY*10 END IF END IF END IF END SUB ' - - - - - T O O L S - - - - - SUB CLAMP(V,L,H) V=MIN(H,MAX(L,V)) END SUB SUB UNIT_VECTOR(DX,DY) D=0 CALL MAG(DX,DY,D) CALL INVERT(D) DX=DX*D DY=DY*D END SUB SUB MAG(X,Y,M) M=SQR(X*X+Y*Y) END SUB SUB MAG_SQ(X,Y,D) D=X*X+Y*Y END SUB SUB INVERT(V) IF V<>0 THEN V=1/V ELSE V=0 END SUB SUB POLAR(I1,I2) 'A LITTLE BIT OF MATH TO GET AN ANGLE AND A LENGTH FROM A SET OF COORDINATES 'CONVERTS THE CARTESIAN (X,Y) TO THE POLAR (RADIUS,ANGLE) 'CODE EXPLANATION '1 SET A TO INPUT 1 '2 SET B TO INPUT 2 '3 I1 TO THE LENGTH OF THE VECTOR (PYTHAGORAS) '4 IF THE LENGTH VARIABLE (I1) SUPPORTS DIVISIONS '5 I2 TO THE ANGLE OF THE VECTOR: ATAN2 MADE WITH ACOS IN A UNIT CIRCLE AND SGN(B) (NOT 0) '6 IF THE LENGTH IS ZERO WE MAY AS WELL HAVE NO ANGLE AT ALL A=I1 B=I2 I1=SQR(A*A+B*B) IF I1>0 THEN I2=ACOS(MIN(1,MAX(-1,A/I1))) * (1+2*(B>=0)) ELSE I2=0 END IF END SUB #1:MAIN PALETTES 0438342000302010003F2F1A000D0905 0E2B261100072A15003F2A1500152A00 #2:MAIN CHARACTERS 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 80000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 387CFEFEFE7C38000010387C38100000 387CFEFEFE7C38000000000000000000 387CFEFEFE7C38000010283828280000 387CFEFEFE7C38000030283028300000 387CFEFEFE7C38000010282028100000 387CFEFEFE7C38000030282828300000 387CFEFEFE7C38000038203020380000 387CFEFEFE7C38000038203020200000 387CFEFEFE7C38000010203828100000 387CFEFEFE7C38000028283828280000 387CFEFEFE7C38000038101010380000 387CFEFEFE7C38000038101050200000 387CFEFEFE7C38000028283028280000 387CFEFEFE7C38000020202020380000 387CFEFEFE7C38000028545444000000 387CFEFEFE7C3800000024342C240000 387CFEFEFE7C38000010282828100000 387CFEFEFE7C38000030283020200000 387CFEFEFE7C3800001824242C1C0000 387CFEFEFE7C38000030283028280000 387CFEFEFE7C38000018201008300000 387CFEFEFE7C38000038101010100000 387CFEFEFE7C38000028282828380000 387CFEFEFE7C38000028282828100000 387CFEFEFE7C38000000445454280000 387CFEFEFE7C38000028281028280000 387CFEFEFE7C38000028281010100000 387CFEFEFE7C3800003C08103C000000 #15:MAIN SOUND 3F00200014F900001F002000090F0000 1C0060601CFB00002C0060601CF90000 1C0060601CF900003800505000000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000