'YELLOW GOLF-BALL PLANET ATOM PARTICLES ' - - - - - P A R A M E T E R S - - - - - BALLS=9 HOLES=3 REPULSION=0.05 DRAG=0.01 FRICTION=0.01 GRAVITY=0 'BOUNDARIES BALL_SIZE=17 B_RI=159-BALL_SIZE B_LE=0 B_UP=0 B_LO=127-BALL_SIZE ' - - - - - I N I T - - - - - GLOBAL REPULSION,DRAG,FRICTION,GRAVITY GLOBAL B_RI,B_LE,B_UP,B_LO,BALL_SIZE,BALLS,HOLES 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(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,3 SPRITE I PAL I+1 SIZE 2 PX(I)=10+20*I PY(I)=60 NEXT I END SUB SUB SETUP_BALLS_G(BALLS,N,PX(),PY()) DIV=0 FOR J=2 TO BALLS+2 FOR I=0 TO DIV SPRITE J,0,0,3 SPRITE J SIZE 2 PX(J)=70+DIV*17 PY(J)=60+I*20-DIV*10 INC J IF J>BALLS+2 THEN EXIT SUB NEXT I INC DIV DEC J 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 SIZE 2 SPRITE I2,X,Y,3 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()) 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), ELSE SPRITE OFF(0) 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 ' - - - - - 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 D=0 DX=PX-SPRITE.X(HIT) DY=PY-SPRITE.X(HIT) ADD FX,DX*M ADD FY,DY*M 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 D=0 DX=PX-SPRITE.X(HIT) DY=PY-SPRITE.Y(HIT) CALL MAG_SQ(DX,DY,D) CALL INVERT(D) IF HIT<=BALLS+2 THEN M=M0*4000 ELSE 'BALL IN HOLE M=-10 IF ABS(DX)<=2 AND ABS(DY)<=2 THEN SPRITE OFF(I) END IF '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 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 0038342000302010003F2F1A000D0905 002B261100072A15003F2A1500292A1A #2:MAIN CHARACTERS 00000000000000000000000000000000 071F3F7F7FFFFFFF0000000000000000 E0F8FCFEFEFFFFFF0000000000000000 020C1F35787ED77F0103010A07012885 50FC3EA78DD76F84F05CFE7FFFEFFF7F 000000008080C040000000008080C0C0 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000070000000000000000 00000000000000E00000000000000000 00000000000000000000000000000000 00000103070F1F3F0000000000000000 0F7FFFFFFFFFFFFF0000000000000000 F0FEFFFFFFFFFFFF0000000000000000 000080C0E0F0F8FC0000000000000000 00000000000000000000000000000000 FFFFFF7F7F3F1F070000000000000000 FFFFFFFEFEFCF8E00000000000000000 FAFEFDED7E3D3F12078102120142030D 358B5BCF9EBB2FBEFF7FFF7FFFEFFFDE C0C0C0C080800000C0C0C0C080800000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000101010000000000000000 1F3F7FFFFFFFFFFF0000000000000000 F8FCFEFFFFFFFFFF0000000000000000 00000000008080800000000000000000 3F7F7F7FFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FCFEFEFEFFFFFFFF0000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 08000000000000000703000000000000 DC30000000000000BCF0000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 01010100000000000000000000000000 FFFFFFFFFF7F3F1F0000000000000000 FFFFFFFFFFFEFCF80000000000000000 80808000000000000000000000000000 FFFFFFFF7F7F7F3F0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFEFEFEFC0000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 07000000000000000000000000000000 E0000000000000000000000000000000 00000000000000000000000000000000 3F1F0F07030100000000000000000000 FFFFFFFFFFFF7F0F0000000000000000 FFFFFFFFFFFFFEF00000000000000000 FCF8F0E0C08000000000000000000000