' - - - - - P A R A M E T E R S - - - - - N=0 N_ARRAY=15 REPULSION=0.01 DRAG=0.03 FRICTION=0.001 GRAVITY=1 SURFACE_REPULSION=5 X_GRAVITY=0 Y_GRAVITY=0.2 MOVEMENT_SPEED=1 THRUST=0.2 'BOUNDARIES BALL_SIZE=8 B_RI=159-BALL_SIZE B_LE=0 B_UP=0 B_LO=127-BALL_SIZE CHARACTER=127 ' - - - - - S E T U P - - - - - 'PHYSICS GLOBAL REPULSION,DRAG,FRICTION,GRAVITY,X_GRAVITY,Y_GRAVITY GLOBAL SURFACE_REPULSION,MOVEMENT_SPEED,THRUST GLOBAL B_RI,B_LE,B_UP,B_LO,CHARACTER GLOBAL VOICE_ VOICE_=0 DIM PX(N_ARRAY),PY(N_ARRAY),VX(N_ARRAY),VY(N_ARRAY) RANDOMIZE TIMER 'BALLS FOR I=0 TO N SPRITE I,,,CHARACTER SPRITE I SIZE 0 PAL 5 PX(I)=RND(140) PY(I)=RND(100) NEXT I 'TERRAIN GLOBAL SCROLL_X,SCROLL_Y SCROLL_X=0 SCROLL_Y=0 X=0 Y=0 XV=0 YV=0 LX=0 LY=0 CALL FULL_RENDER(INT(X),INT(Y)) TOUCHSCREEN ' - - - - - M A I N L O O P - - - - - 'COLLISION 'DETECTOR: USE A SPRITE WITH SPRITE HIT TO DETECT COLLISION ' : USE CELL.C TO GET THE STEEPNESS OF A SLOPE: ' - IF C>=16 AND C<=32 THEN SLOPE=(C MOD 16)*2 ' - SPRITE HIT WILL HANDLE THE AIR BLOCKS 'ACTUATOR: USE A FORCE INSTEAS OF VELOCITY CONTROL, JUST LIKE WITH THE BILLIARDS BALLS 'ALSO ADD A SPRITE MANAGER (TO SUB DRAW()) DO 'CALL TOUCH_INPUT(X,Y,MOVEMENT_SPEED) 'CALL INTERACTION(X_GRAVITY,Y_GRAVITY,GRAVITY) CALL PHYSICS (N_ARRAY,VX(),VY(),PX(),PY()) CALL DRAW (N_ARRAY,PX(),PY()) 'CALL GUNS(PX(),PY(),VX(),VY()) CALL MOVE(X,Y,XV,YV,PX(0),PY(0)) CALL DRAW_UPDATE(INT(X/8),INT(Y/8),LX,LY,21,17) WAIT VBL LOOP ' - - - - - M A I N S U B P R O G R A M S - - - - - SUB TOUCH_INPUT(X,Y,M) IF TAP THEN 'ADD X,SGN(TOUCH.X-80)*8*2 'ADD Y,SGN(TOUCH.Y-64)*8*2 END IF IF TOUCH THEN ADD X,(TOUCH.X-80)*0.1*M ADD Y,(TOUCH.Y-64)*0.1*M END IF SCROLL_X=X SCROLL_Y=Y END SUB SUB DRAW(N,PX(),PY()) FOR I=0 TO N SPRITE I,PX(I)-SCROLL_X,PY(I)-SCROLL_Y, 'SPRITE I,PX(I),PY(I),CHARACTER NEXT I END SUB SUB INTERACTION(X,Y,M) X=(TOUCH.X-80)/160 Y=(TOUCH.Y-64)/128 CALL SCALE(X,M) CALL SCALE(Y,M) END SUB SUB PLAYSOUND(N,M) IF N=0 AND M>1 THEN PLAY VOICE_,60 SOUND 0 VOLUME VOICE_,MIN(15,M*2), ADD VOICE_,1,0 TO 3 END IF END SUB ' - - - - - I N P U T - - - - - SUB PLAYERS END SUB SUB ENEMIES END SUB ' - - - - - M O V E - - - - - SUB MOVE(PX,PY,VX,VY,TX,TY) CALL MOVE_1D(PX,VX,TX,80) CALL MOVE_1D(PY,VY,TY,64) SCROLL 0,PX,PY SCROLL 1,PX,PY SCROLL_X=PX SCROLL_Y=PY END SUB SUB MOVE_1D(P,V,T,B) V=0.5*V+(T-B-P)*0.1 ADD P,V 'P=T-B END SUB ' - - - - - E F F E C T S - - - - - SUB DRAW_THRUSTER(X,Y,R) M=5 FOR I=0 TO M IN=M-I SX=X+RND(IN)-0.5*IN SY=Y-IN*4+RND(4)+5 '>CALL ROTATE(SX,SY,R,-X+2,-Y-42) SPRITE 30+I,SX,SY-15,15 SPRITE 30+I PAL 2 NEXT I END SUB SUB EXPLOSION(X,Y,R) 'PLACE A BUNCH OF SPRITES OF 1X AND 2X SIZE SWITCH THEM RANDOMLY 'BREAK BLOCKS INSIDE THE RADIUS RANDOMLY WITH A PROBABILLITY DEPENDING ON R 'DAMAGE PLAYERS INSIDE THE RADIUS WITH EXPONENTIAL DAMAGE FALOFF BASED ON R 'ANY SORT OF DAMAGE HAS EXPONENTIAL DAMAGE FALOFF DEPENDING ON R 'PLAY SOUND 'EXPLOSION EFFECTS SPRITES FXCOUNT=9 FOR I=0 TO FXCOUNT ANG=RND*2*PI LENG=RND*R '+INT(RND*R)*0 '+INT(RND*R)*0 '>CALL MSPRITE(40+I,X+INT(LENG*COS(ANG)),Y+INT(LENG*SIN(ANG)),84, 6,-1,-1,-1, 5,FXCOUNT) 'USE THE NEW NEW SPRITE HIT TO FIGURE OUT WHETHER OR NOT THE SPRITE IS AN ENEMY '>CALL SPRITEHIT(40+I,-1,-1,0,0,DIDHIT) IF DIDHIT THEN 'IF SPRITE HIT(40+I) THEN 'CALL SPRITECODE(HIT,0,0,SLAM) '>CALL SPRITEOFF(SLAM,-1,0,0) '>CALL ENEMYINIT(SLAM-2) END IF 'SPRITE 40+I PAL 6 NEXT I R1=R*0.5 'BREAK BLOCKS WITH A MANHATTAN PATTERN (DIAMOND SHAPE) FOR J=-R1 TO R1 FOR I=ABS(J)-R1 TO -ABS(J)+R1 '>CALL MINE(INT((X+I+MX)/8),INT((Y+J+MY)/8)) NEXT I NEXT J END SUB SUB FIRE(X,Y,R) CALL DRAW_THRUSTER(X,Y,R) END SUB SUB SPRITE_MANAGER 'FIND_SPRITE(P) 'P_SPRITES(ID)=P 'E_SPRITES(ID)=P 'FX_SPRITES(ID)=P END SUB SUB FIND_SPRITE(P) 'FIND FIRST AVAILABLE SPRITE (X=-32) FOR I=P TO P+63 IF SPRITE.X(I MOD 64)=-32 THEN EXIT NEXT I P=I MOD 64 END SUB ' - - - - - G U N S - - - - - SUB GUNS(PX(),PY(),VX(),VY()) 'GET X,Y (OBJECT + OFFSET TO BARREL) 'GET STATS OF GUN 'CALL GUN_FIRE(X,Y,DX,DY,S,P) IF TAP THEN CALL GUN_FIRE(PX(0),PY(0),0,0.5,2,PX(),PY(),VX(),VY()) END SUB SUB GUN_FIRE(X,Y,A,S,P,PX(),PY(),VX(),VY()) 'GET ID (SPRITE MANAGER) 'ID=10+BULLET ID=0 CALL FIND_SPRITE(ID) ID=10 A1=A-S*0.5+S*RND 'USE GOLDEN RATIO DISTRIBUTION PX(ID)=X PY(ID)=Y VX(ID)=COS(A1)*P VY(ID)=SIN(A1)*P SPRITE ID,X,Y,111 SPRITE ID PAL 1 END SUB ' - - - - - B G R E N D E R I N G - - - - - SUB FULL_RENDER(X,Y) CALL RECT(X,Y,21,17) END SUB SUB DRAW_UPDATE(X,Y,LX,LY,W,H) DIM XP(5),YP(5) CALL X_SHAPE(XP(), X,LX, X+W,LX+W) CALL Y_SHAPE(YP(), Y,LY, Y+H,LY+H) FOR I=0 TO 5 STEP 2 CALL RECTANGLE(XP(I),YP(I),XP(I+1),YP(I+1)) NEXT I LX=X LY=Y END SUB SUB X_SHAPE(XP(), X,LX,X2,LX2) IF (X>=LX) THEN CALL DEFINE4(XP(), LX2,X2,X,LX2) ELSE CALL DEFINE4(XP(), X,LX,LX,X2) END IF XP(4)=XP(0) XP(5)=XP(1) END SUB SUB Y_SHAPE(YP(), Y,LY,Y2,LY2) IF (Y>=LY) THEN CALL DEFINE4(YP(), Y,LY2,LY2,Y2) ELSE CALL DEFINE4(YP(), LY,Y2,Y,LY) END IF YP(4)=YP(2) YP(5)=YP(3) END SUB SUB DEFINE4(P(),P0,P1,P2,P3) P(0)=P0 P(1)=P1 P(2)=P2 P(3)=P3 END SUB SUB RECTANGLE(X1,Y1,X2,Y2) CALL RECT(X1,Y1,X2-X1,Y2-Y1) END SUB SUB RECT(X,Y,W,H) FOR IX=0 TO W-1 FOR IY=0 TO H-1 CALL LAND(X+IX,Y+IY) NEXT IY NEXT IX END SUB ' - - - - - T E R R A I N G E N E R A T I O N - - - - - SUB LAND(X,Y) YY=0 D=0 C=0 F=0 CALL HOW_STEEP2(INT(X),YY,D) CALL VECTERRAIN(X,Y, X*8,YY*8,1,D, C,F) IF C<>1 THEN FLIP F,0 CELL X,Y,C ELSE T=0 L=0 CALL GETCELL(X,Y,T,L) 'L=1 IF L THEN 'BORDER LINE 'D=0 'CALL HOW_STEEP(X,D) 'CELL X,Y,0 'FLIP D<0,0 'PAL MAX(0,T-1) IF T=1 THEN 'CELL X,Y,MAX(0,MIN(7,ABS(D)*4))+16*L CELL X,Y,0 ELSE CELL X,Y,2 END IF ELSE PAL MAX(0,T-1) FLIP RND(1),RND(1) 'BG 1 CELL X,Y,T 'BG 0 END IF END IF FLIP 0,0 PAL 0 END SUB SUB HOW_STEEP(X,D) Y1=0 Y2=0 CALL HILLS(X-0.5,Y1,0) CALL HILLS(X+0.5,Y2,0) 'CALL HILLS(X,Y1,0) 'CALL HILLS(X+1,Y2,0) D=Y2-Y1 END SUB SUB HOW_STEEP2(X,Y1,D) Y1=0 Y2=0 CALL HILLS(X-0.5,Y1,0) CALL HILLS(X+0.5,Y2,0) 'CALL HILLS(X,Y1,0) 'CALL HILLS(X+1,Y2,0) D=Y2-Y1 'TRACE X,INT(Y2),INT(Y1),INT(D) END SUB SUB GETCELL(X,Y,T,L) Y1=0 FOR I=0 TO 2 CALL HILLS(X,Y1,I) IF Y<=Y1 THEN EXIT NEXT I L=(INT(Y)>=INT(Y1)) 'IF L THEN TRACE INT(Y)-INT(Y1) T=I-L L=-L*(1+INT(Y)-INT(Y1)) END SUB SUB HILLS(X,Y,A) ''Y=A*100+(3*A+1)*SIN((A*A+5)*SIN(X))-(7*A*A+2)*SIN((4-A)*SIN(X)) Y=A*A*100+5+SIN((A*A+1)*0.2*X)*5+SIN(0.3*X)*5 'Y=A*100+SIN(0.1*X)*10 END SUB ' - - - - - V E C T O R T E R R A I N - - - - - SUB VECTERRAIN(CX,CY,X0,Y0,DX,DY,C,FLIPPED) 'CASES LINE 'STRAIGHT VERTICAL : FOR LEFT / RIGHT : CHECK IF EQUAL TO KNOWN X 'STRAIGHT HORIZONTAL : FOR TOP / BOTTOM : CHECK IF EQUAL TO KNOWN Y 'CASES BOX: '- NO COLLISION 'X SKIM CORNER (A SINGLE INTERSECTION) (IMPOSSIBLE) '- COLLIDE WITH RIB '- PASS THROUGH (LEFT + RIGHT / TOP + BOTTOM) '- TOP CORNER PASS (LEFT/RIGHT) '- BOTTOM CORNER PASS (LEFT/RIGHT) 'CELL BOX DEFINITION XA=CX*8 YA=CY*8 XB=XA+7+1 YB=YA+7+1 XC=0 YC=0 XD=0 YD=0 XCIN=0 YCIN=0 XDIN=0 YDIN=0 FLIPPED=0 C=0 XXC=0 XXD=0 YYC=0 YYD=0 'LEFT/RIGHT 'TOP/BOTTOM CALL LINE_BOX_FIND(DX,DY,X0,Y0,XA,XB,YA,YB,YC,YD,YCIN,YDIN) CALL LINE_BOX_FIND(DY,DX,Y0,X0,YA,YB,XA,XB,XC,XD,XCIN,XDIN) IF YCIN=0 AND YDIN=0 AND XCIN=0 AND XDIN=0 THEN C=1 EXIT SUB END IF CALL COORDS_ROUND(XA,YA, XC,XD,YC,YD, XXC,XXD,YYC,YYD) CALL PICK_CHARACTER(XXC,XXD,YYC,YYD, XC,XD,YC,YD, XCIN,XDIN,YCIN,YDIN, FLIPPED,C) 'CALL DEMO_VISUALS(XA,XB,XC,XD,YA,YB,YC,YD,XCIN,XDIN,YCIN,YDIN,FLIPPED,C,CX,CY,XXC,XXD,YYC,YYD) END SUB SUB DEMO_VISUALS(XA,XB,XC,XD,YA,YB,YC,YD,XCIN,XDIN,YCIN,YDIN,FLIPPED,C,CX,CY,XXC,XXD,YYC,YYD) 'INTERACTIVE DEMO VISUALS 'INTERSECTION INDICATORS IF CX=X_CELL AND CY=Y_CELL THEN IF YCIN THEN SPRITE 2,XA,YC,3 ELSE SPRITE OFF 2 IF YDIN THEN SPRITE 3,XB,YD,3 ELSE SPRITE OFF 3 IF XCIN THEN SPRITE 4,XC,YA,3 ELSE SPRITE OFF 4 IF XDIN THEN SPRITE 5,XD,YB,3 ELSE SPRITE OFF 5 'DISPLAY DEBUG INFO TEXT 0,0,STR$(ABS(YCIN))+STR$(ABS(YDIN))+STR$(ABS(XCIN))+STR$(ABS(XDIN)) TEXT 0,1,STR$(ABS(XXC))+STR$(ABS(XXD))+STR$(ABS(YYC))+STR$(ABS(YYD)) NUMBER 5,0,FLIPPED,1 PAL 3 FLIP FLIPPED,0 CELL 7,0,C FLIP 0,0 PAL 0 END IF PAL 3 FLIP FLIPPED,0 BG 1 CELL CX,CY,C BG 0 FLIP 0,0 PAL 0 END SUB SUB LINE_BOX_FIND(DX,DY,X0,Y0,XA,XB,YA,YB,YC,YD,YCIN,YDIN) CALL LINE_BOX_FIND_X(DX,DY,X0,Y0,XA,XB,YA,YB,YC,YD,YCIN,YDIN) END SUB SUB LINE_BOX_FIND_X(DX,DY,X0,Y0,XA,XB,YA,YB,YC,YD,YCIN,YDIN) IF DX<>0 THEN 'LINE X PARAMETERS A AND B LXA=DY/DX LXB=Y0-X0*LXA 'LEFT YC=XA*LXA+LXB YCIN=(YC>=YA AND YC<=YB) 'RIGHT YD=XB*LXA+LXB YDIN=(YD>=YA AND YD<=YB) ELSE 'LINE IS FULLY HORIZONTAL YC=Y0 YD=Y0 YCIN=0 YDIN=0 IF X0=XA THEN 'HITS EVERYWHERE ON THE CELL-BOX RIB 'YC=0 YCIN=-1 ELSE IF X0=XB THEN 'YD=0 YDIN=-1 END IF END IF END SUB SUB LINE_BOX_FIND_Y(DY,DX,Y0,X0,YA,YB,XA,XB,XC,XD,XCIN,XDIN) IF DY<>0 THEN 'LINE Y PARAMETERS A AND B LYA=DX/DY LYB=X0-Y0*LYA 'UP XC=YA*LYA+LYB XCIN=(XC>=XA AND XC<=XB) 'DOWN XD=YB*LYA+LYB XDIN=(XD>=XA AND XD<=XB) ELSE 'LINE IS FULLY HORIZONTAL XC=X0 XD=X0 XCIN=0 XDIN=0 IF Y0=YA THEN 'HITS EVERYWHERE ON THE CELL-BOX RIB 'XC=0 XCIN=-1 ELSE IF Y0=YB THEN 'XD=0 XDIN=-1 END IF END IF END SUB SUB COORDS_ROUND(XA,YA, XC,XD,YC,YD, XXC,XXD,YYC,YYD) XXC=XC-XA XXD=XD-XA YYC=YC-YA YYD=YD-YA CALL SLOPE_ROUND(XXC) CALL SLOPE_ROUND(XXD) CALL SLOPE_ROUND(YYC) CALL SLOPE_ROUND(YYD) END SUB SUB SLOPE_ROUND(V) 'INPUT VALUE RANGE: 0 TO 7 (PROBABLY INT) 'OUTPUT VALUE RANGE: 0,1,2 (INT) '01234567 '00011122 'TRACE V,INT(V/3) V=INT(V/3) CALL CLAMP(V,0,2) END SUB SUB PICK_CHARACTER(XXC,XXD,YYC,YYD, XC,XD,YC,YD, TOP_,BOTTOM_,LEFT_,RIGHT_, FLIPPED,C) IF BOTTOM_ AND TOP_ THEN FLIPPED=ABS(XCB2 THEN V=-ABS(V) END SUB SUB C_WALL_PUSH(F,V,P,B1,B2,S) IF P-SB2 THEN ADD F,MIN(-1,(B2-P+S)*0.05) END SUB SUB COLLISION_F(I,FX,FY,VX,VY,PX,PY,PX(),PY()) CALL BOUNCE(I,FX,FY,VX,VY,PX,PY,PX(),PY(),REPULSION) 'CALL C_WALL_PUSH(FX,VX,PX,B_LE,B_RI,SCROLL_X) 'CALL C_WALL_PUSH(FY,VY,PY,B_UP,B_LO,SCROLL_Y) END SUB SUB COLLISION_V(I,FX,FY,VX,VY,PX,PY,PX(),PY()) CALL C_TERRAIN(I,FX,FY,VX,VY,PX,PY,SURFACE_REPULSION) END SUB SUB BOUNCE(N,FX,FY,VX,VY,PX,PY,PX(),PY(),REPULSION) 'BOUNCE_L (LINEAR), BOUNCE_E (EXPONENTIAL) (SUBPROGRAM PARAMETERS ARE THE SAME) IF SPRITE HIT(N) THEN 'FOR I=0 TO UBOUND(PX) 'IF SPRITE HIT(N,I) THEN CALL BOUNCE_E(N,FX,FY,VX,VY,PX,PY,PX(),PY(),REPULSION) 'END IF 'NEXT I END IF END SUB SUB BOUNCE_L(I,FX,FY,VX,VY,PX,PY,PX(),PY(),M) 'BALL COLLISIONS WITH LINEAR REPULSIVE FORCE D=0 DX=PX-PX(HIT) DY=PY-PY(HIT) ADD FX,DX*M ADD FY,DY*M END SUB SUB BOUNCE_E(I,FX,FY,VX,VY,PX,PY,PX(),PY(),M0) 'BALL COLLISIONS WITH EXPONENTIAL REPULSIVE FORCE 'THE GRAVITATION FORMULA BUT NEGATIVE M=M0*4000 'M=-1 D=0 DX=PX-SPRITE.X(HIT) DY=PY-SPRITE.Y(HIT) CALL MAG_SQ(DX,DY,D) CALL INVERT(D) 'CONVERTOR: UNIT VECTOR (*SQR(D)), EXPONENTIAL (*D), AMOUNT (*M) 'IT'S CLAMPED AGAINST NUCLEAR FORCES C=SQR(D)*MIN(10,D*M) CALL PLAYSOUND(0,C) ADD FX,DX*C ADD FY,DY*C END SUB SUB C_TERRAIN_NEW(I,FX,FY,VX,VY,PX,PY,M) CALL COLLIDE2(VX,VY) END SUB SUB C_TERRAIN(I,FX,FY,VX,VY,PX,PY,M) X=INT((PX+4)/8) Y=INT((PY+4)/8) C=CELL.C(X,Y) SPRITE 63,X*8-SCROLL_X,Y*8-SCROLL_Y,C F=CELL.A(X,Y) AND %00011000 SPRITE.A 63,4 OR F IF SPRITE HIT(63,I) THEN IF C>=16 AND C<=32 THEN CALL COLLIDE(C,F,VX,VY) ELSE C=CELL.C(X,Y-1) IF C>=16 AND C<=32 THEN CALL COLLIDE(C,F,VX,VY) ELSE CALL COLLIDE(32,F,VX,VY) 'ADD FY,-M*0.1 'VX=-0.1*VX 'VY=-0.1*VY END IF END IF 'SPRITE I PAL 1 'ELSE 'SPRITE I PAL 5 END IF SPRITE OFF 63 END SUB SUB ALLIGN2(X,Y,RX,RY,PX,PY) M=X A=Y RM=RX RA=RY CALL POLAR(M,A) CALL POLAR(RM,RA) DA=A-RA IF NOT(ABS(DA)<=0.5*PI OR ABS(DA)>=1.5*PI) THEN RA=1.5*PI-RA NA=A+RA-2*PI*(RA<0)-0.5*PI M=-M*SIN(NA) X=COS(RA)*M Y=SIN(RA)*M END IF END SUB SUB ALLIGN(X,Y,RX,RY) M=X A=Y RM=RX RA=RY CALL POLAR(M,A) CALL POLAR(RM,RA) DA=A-RA IF NOT(ABS(DA)<=0.5*PI OR ABS(DA)>=1.5*PI) THEN RA=1.5*PI-RA NA=A+RA-2*PI*(RA<0)-0.5*PI M=-M*SIN(NA) X=COS(RA)*M Y=SIN(RA)*M END IF END SUB SUB COLLIDE2(VX,VY) 'SLOPE=(C MOD 16)*2*(1-2*(F/8)) 'DX=SLOPE 'DY=-8 X=SCROLL.X(0)+SPRITE.X(0) YY=SCROLL.Y(0)+SPRITE.Y(0) Y=0 D=0 FOR I=-1 TO 1 'FOR I=0 TO 0 CALL HOW_STEEP2(INT(X/8)+I,Y,D) 'DX=INT(D*2)*0.5 DX=D DY=-1 IF YY>Y THEN CALL ALLIGN(VX,VY,DX,DY) NEXT I END SUB SUB COLLIDE(C,F,VX,VY) 'SLOPE=(C MOD 16)*2*(1-2*(F/8)) 'DX=SLOPE 'DY=-8 X=SCROLL.X(0)+SPRITE.X(0) Y=0 D=0 FOR I=-1 TO 1 'FOR I=0 TO 0 CALL HOW_STEEP2(INT(X/8)+I,Y,D) 'DX=INT(D*2)*0.5 DX=D DY=-1 CALL ALLIGN(VX,VY,DX,DY) NEXT I EXIT SUB CALL UNIT_VECTOR(DX,DY) V=0 CALL UNIT_VECTOR2(VX,VY,V) IF 0 THEN DX=0 DY=0 END IF IF ABS(DX)-ABS(VY)<0.1 AND ABS(DY)-ABS(VX)<0.1 THEN TRACE TIMER DX=0 DY=0 END IF 'ADD VX,DX 'ADD VY,DY 'CALL UNIT_VECTOR(VX,VY) 'TRACE ACOS(VX)*SGN(VY) 'VX=VX*V 'VY=VY*V VX=(VX+DX)*V VY=(VY+DY)*V 'ADD FX,DX*M* MAX(0,-SGN(DX)*VX) 'ADD FY,DY*M* MAX(0,-VY) 'ADD FX,DX*M 'ADD FY,DY*M END SUB ' - - - - - C O N T R O L - - - - - SUB CONTROL(I,FX,FY,VX,VY,PX,PY) 'PLAYER IF I=0 THEN M=THRUST 'IF TAP THEN 'ADD FX,SGN(TOUCH.X-80)*8*2 'ADD FY,SGN(TOUCH.Y-64)*8*2 'END IF IF TOUCH THEN ADD FX,(TOUCH.X-80)*0.1*M ADD FY,(TOUCH.Y-64)*0.1*M END IF 'ELSE IF '- ENEMY (CONTROL) '- PROJECTILE (HIT DETECT) '- OBJECT (FUNCTION OF IT) END IF END SUB ' - - - - - T O O L S - - - - - SUB UNIT_VECTOR(DX,DY) D=0 CALL MAG(DX,DY,D) CALL INVERT(D) DX=DX*D DY=DY*D END SUB SUB UNIT_VECTOR2(DX,DY,M) D=0 CALL MAG(DX,DY,D) M=D CALL INVERT(D) DX=DX*D DY=DY*D END SUB SUB SCALE(V,S) V=V*S 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 SUB CLAMP(V,L,H) V=MIN(H,MAX(L,V)) END SUB ' - - - - - T R A S H B I N - - - - - SUB TRASH 'FROM SUB LAND(X,Y) 'D=0 'T=0 'CALL HILL_PITCH(X,D,0) 'PAL 3+(D<0)*2 'BG FILL X,0 TO X,31 CHAR 0 'CELL X,-D,1 'FOR I=0 TO 7 'TEXT X,I,MID$(STR$(D),I+1,1) 'NEXT I 'TRACE D 'BG 1 'CELL X,Y,32+MAX(0,MIN(8,ABS(D)*0.5)) 'BG 0 'FLIP X<0 XOR D<0,0 'CELL X,Y,2-(T=1)*(30+MAX(0,MIN(7,ABS(D)*4))) END SUB SUB HILL_PITCH(X,Y,A) 'Y=A*A*100+5 + SIN((A*A+1)*0.2* X )*5 + SIN(0.3* X )*5 'DERIVATIVE 'A=A*A*100+5 'B=(A*A+1)*0.2 'Y=A+ 5*SIN(B*X) + 5*SIN(0.3*X) 'Y'=0+ 5*COS(B*X) * (B*X) + 5*COS(0.3*X) * (0.3*X) 'Y'=5*(B*X)*COS(B*X) + 5*(0.3*X)*COS(0.3*X) B=(A*A+1)*0.2*X Y=5*B*COS(B) + 1.5*X*COS(0.3*X) END SUB 'CALL REFRESH(INT(X/8),INT(Y/8),LX,LY) SUB REFRESH(X,Y,LX,LY) DX=X-LX DY=Y-LY 'BX=X-(DX<0)*DY+DY 'BY=Y-(DY<0)*DX+DX IF DX>=0 THEN BX=X+20 PAL 3 ELSE BX=X-DX-1 DX=-DX PAL 4 END IF IF DY>=0 THEN BY=Y+16 PAL 3 ELSE BY=Y-DY-1 DY=-DY PAL 4 END IF 'CALL RECT(2+BX,2+Y,MIN(21,DX),11) 'CALL RECT(2+X,2+BY,15,MIN(17,DY)) CALL RECT(BX,Y,MIN(21,DX),17) CALL RECT(X,BY,21,MIN(17,DY)) 'CALL RECT(X,BY,MAX(0,21-DX),MIN(17,DY)) 'TRACE BX,Y,MIN(20,DX-1),16 'TRACE MIN(20,DX-1),MIN(16,DY-1) LX=X LY=Y PAL 0 END SUB #1:MAIN PALETTES 1F08042400382410002A1525002A1500 00302010000B0601003F2A15003F2A15 #2:MAIN CHARACTERS 00000000000000000000000000000000 EB5EF56EBF6FFAB7FFBFFFFFF7BFFDFF 8E3FE12AA14AFF6673EA5ED77EBD84DB 8E3FE12AA14AFF6673EA5ED77EBD84DB 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000080C00000000000000000 000000008080C0E00000000000000000 000080808040A0E0000000000080C0C0 8080C0C0E0E0D048000000808080E0F0 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000000000F88F00000000000000F0 000000008020FC630000000040C0E0FC 000000E03098648300000000C060F8FC 80404030D0D4EEF0008080C068E8B0FF 6020B018D8CCE62B80C0C0E0E0B0F8FC 7030B898ACD636EB80C0E0E0F0F8F8BC D018888CC4E2B16DE0E0F0F0F89CCEFE 98E46450F6CBDA7CE0F8F8FCF8BCBDFF 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 80402010080402010000000000000000 80C0406020301C070000000000000000 C070180C060201010000000000000000 C0603010180C07010000000000000000 8081414362361C000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 CA901275F48C7FEC3F7FFDFFFF7FFDFF C9CF87939DDABB853F3D7F7D73FFDDFF C6CABE948CC3C5E7393F5F7B7B3F3E1F 0E0D0D0C0A0E0A0D0302030305010507 00000000404070000000000040407000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 FCB9F168BF8E68BE075E7FDFFDFFBFFB 1C3970C9792ECB9903060F3FBFFD7FEF 1E1C3B34776ACAD60303040F0F1F3D3F 00000000004060000000000000406000 00000000004070000000000000407000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 FF872701BA3F97FD0078DCFFD7FF7EFF 030F31FEA809BF6400020E037FFEDFFF 0102020C0B2B770F0001010316170DFF 0000000001043FC6000000000203073F 00000000000000FF0000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000FFC31ED90000000000BEF7BE 00060200000000000006020000000000 0101020205060D0B0000010102010305 000000000103050B0000000000000207 000000000000000F0000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 3C7EFEFEFCF870000000010103070E3C 000E020200000000000E020200000000 00060202000000000006020200000000 01010101010101010000000000000000 00000000010101010000000000000000 00000000000000010000000000000000 #15:MAIN SOUND 3F00100013FF00001800846C003A0000 08006060000000002800303019FE0000 38002020000000003800505000000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000 00404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 40404040404040404040404040404040 250F0000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000