I was looking at some 10 liners in BASIC, and Jos'B's Waterworm interested me, so I took some time to figure out how it works.
I think I learned a couple little tricks from this one. (vpoking nametable, ifA, etc.), and I think there might be a few places to optimize the code a bit more, but I thought I'd share it here:
10 DEFINTA-Z:DIMM(15):A=256:D=6144:COLOR7,4,1:KEYOFF:SCREEN1,0,0:WIDTH32:'*Set Variables 11 FORI=384TO728:VPOKEI,VPEEK(I)ORVPEEK(I)/2:NEXT:'*Make the Thick Font 12 VPOKE8198,180:VPOKE8199,180:VPOKE8192,132:VPOKE8196,84:VPOKE8194,212:VPOKE8195,25:'*Set Character Colors 13 FORI=64TO111:READX:VPOKEI,X:NEXT:'Define Characters 4 through 13 in extended character set 20 CLS:LOCATE11,10:PRINT"WATERWORM":'* Title Screen Part 1 21 FORI=6432TO6463:VPOKEI,23:VPOKEI+64,23:NEXT:'*Draw Line via the Nametable (extended characters) 22 LOCATE2,3:PRINT"BASIC 10 LINER CONTEST 2020":LOCATE6,20:PRINT"by Jos'b from Spain" 30 IFNOT(STRIG(0))GOTO30:'*Wait for Spacebar to be pressed 31 CLS:S=0:C=0:L=2:F=8:P=6512:M(0)=P:M(1)=P:M(2)=P:VPOKEA,0:VPOKEB,0:'Val's A and B are used to make the "water effect", but these 2 pokes are unnecessary. 32 FORI=DTOD+31:VPOKEI,28:NEXT:'*Vpoke the nametable with the border character-Top row 33 FORI=0TO23:VPOKED+I*32,28:VPOKED+I*32+31,28:NEXT:'*Left and right side 34 FORI=D+736TOD+767:VPOKEI,28:NEXT:PLAY"v11t255m4100":'*Bottom row 40 IFVTHENFORI=1TOV*4:X=INT(704*RND(-TIME)+32):VPOKED+X,28:VPOKED+X+1,28:VPOKED+X+32,28:VPOKED+X+33,28:NEXT:'*If V (current level) is 1 or higher, then place random blocks in the stage by vpoking to the nametable. 49 '*Start of Main Game loop 50 VPOKEB,0:VPOKEA,49:'*Water effect - blank the old row then define the new rowof chr$(32) 51 VPOKEM(L),32:VPOKEM(L-1),13:VPOKEM(1),12:VPOKEP,F:'*Draw Worm - Erase, Tail, Body, Head 52 OS=S:Z=STICK(0):'*S is used for calculating current head position and direction, OS may mean "Old S". Read arrow keys 53 S=32*(Z=1)-(Z=3)-32*(Z=5)+(Z=7)-OS*(Z=0):P=P+S:'*Calculate new head position and direction 54 E=-VPEEK(P)*(S<>0)-32*(S=0):'*Read which character is on-screen at the current head position (collision test) 55 F=-8*(S=-32ORS=0)-9*(S=1)-10*(S=32)-11*(S=-1):'Calculate which head directionwill be used next 60 OC=C:C=-(C=0)*(INT(RND(-TIME)*768)+6144)-OC*(C<>0):J=VPEEK(C):IFJ<>32ANDOC=0THENC=0:GOTO60:'*Place the Heart in any blank space. IF space isn't blank, then try again (checks on every loop, so OC is used to keep it from placing hearts everywhere) 70 VPOKEC,3:'*Print the heart (every loop) 71 B=A:A=A+1+8*(A=263):'*Update values for water effect 72 FORI=LTO0STEP-1:M(I+1)=M(I):NEXT:M(0)=P:'*Shift the values in the array ahead by 1, then update M(0) with current head position 73 J=VPEEK(P):IFJ=3THENC=0:L=L+1:PLAY"eg":'*If you collect a heart, increase length by 1 and play a sound 74 IFL=15THENVPOKEM(L),32:VPOKEM(L-1),13:VPOKEM(1),12:VPOKEP,F:V=V+1:R=R+L*10:LOCATE11,10:PRINT"LEVEL";V:LOCATE11,11:PRINT"SCORE";R:GOTO30:'*If your length is 15, then update snake onscreen, end the level and goto next level 80 IF(E=32ORE=3)GOTO50ELSEPLAY"gc":VPOKEM(L),32:VPOKEM(L-1),13:VPOKEM(1),12:VPOKEP,F:LOCATE11,10:PRINT"GAME OVER":LOCATE11,11:PRINT"SCORE";R+L*10:'*If head is not over a blank space or a heart then update the snake onscreen and gameover 90 IFNOT(STRIG(0))GOTO90ELSER=0:V=0:GOTO20:'*Wait for Space to be pressed, then go to titlescreen 100 DATA60,126,219,153,255,189,153,129,252,22,51,127,127,51,22,252,129,153,189,255,153,219,126,60,63,104,204,254,254,204,104,63,0,24,36,66,66,36,24,0,0,0,24,36,36,24,0,0
Uncommented:
10 DEFINTA-Z:DIMM(15):A=256:D=6144:COLOR7,4,1:KEYOFF:SCREEN1,0,0:WIDTH32:FORI=384TO728:VPOKEI,VPEEK(I)ORVPEEK(I)/2:NEXT:VPOKE8198,180:VPOKE8199,180:VPOKE8192,132:VPOKE8196,84:VPOKE8194,212:VPOKE8195,25:FORI=64TO111:READX:VPOKEI,X:NEXT 20 CLS:LOCATE11,10:PRINT"WATERWORM":FORI=6432TO6463:VPOKEI,23:VPOKEI+64,23:NEXT:LOCATE2,3:PRINT"BASIC 10 LINER CONTEST 2020":LOCATE6,20:PRINT"by Jos'b from Spain" 30 IFNOT(STRIG(0))GOTO30ELSECLS:S=0:C=0:L=2:F=8:P=6512:M(0)=P:M(1)=P:M(2)=P:VPOKEA,0:VPOKEB,0:FORI=DTOD+31:VPOKEI,28:NEXT:FORI=0TO23:VPOKED+I*32,28:VPOKED+I*32+31,28:NEXT:FORI=D+736TOD+767:VPOKEI,28:NEXT:PLAY"v11t255m4100" 40 IFVTHENFORI=1TOV*4:X=INT(704*RND(-TIME)+32):VPOKED+X,28:VPOKED+X+1,28:VPOKED+X+32,28:VPOKED+X+33,28:NEXT 50 VPOKEB,0:VPOKEA,49:VPOKEM(L),32:VPOKEM(L-1),13:VPOKEM(1),12:VPOKEP,F:OS=S:Z=STICK(0):S=32*(Z=1)-(Z=3)-32*(Z=5)+(Z=7)-OS*(Z=0):P=P+S:E=-VPEEK(P)*(S<>0)-32*(S=0):F=-8*(S=-32ORS=0)-9*(S=1)-10*(S=32)-11*(S=-1) 60 OC=C:C=-(C=0)*(INT(RND(-TIME)*768)+6144)-OC*(C<>0):J=VPEEK(C):IFJ<>32ANDOC=0THENC=0:GOTO60 70 VPOKEC,3:B=A:A=A+1+8*(A=263):FORI=LTO0STEP-1:M(I+1)=M(I):NEXT:M(0)=P:J=VPEEK(P):IFJ=3THENC=0:L=L+1:PLAY"eg":IFL=15THENVPOKEM(L),32:VPOKEM(L-1),13:VPOKEM(1),12:VPOKEP,F:V=V+1:R=R+L*10:LOCATE11,10:PRINT"LEVEL";V:LOCATE11,11:PRINT"SCORE";R:GOTO30 80 IF(E=32ORE=3)GOTO50ELSEPLAY"gc":VPOKEM(L),32:VPOKEM(L-1),13:VPOKEM(1),12:VPOKEP,F:LOCATE11,10:PRINT"GAME OVER":LOCATE11,11:PRINT"SCORE";R+L*10 90 IFNOT(STRIG(0))GOTO90ELSER=0:V=0:GOTO20 100 DATA60,126,219,153,255,189,153,129,252,22,51,127,127,51,22,252,129,153,189,255,153,219,126,60,63,104,204,254,254,204,104,63,0,24,36,66,66,36,24,0,0,0,24,36,36,24,0,0
Для того, чтобы оставить комментарий, необходимо регистрация или !login