9. ПЕРВЫЕ ШАГИ К КОДОВОЙ ПРОГРАММЕ
Тог, кто уже пробовал свои силы в написании программ на Бейсике, наверняка заметил, что спрайты передвигаются по экрану не слишком быстро. И если в логических играх типа ОХОТА НА ЛИС или МАКСИТ этот недостаток почти незаметен, то в более динамичных ситуациях он может довести игрока до белого каления. Что же делать?
В фирменных программах с медлительностью спрайтов борются довольно просто: на Бейсике пишется только загрузчик, а все остальное - в машинных кодах. Однако то, что хорошо для профессионалов, не всегда подходит любителям. Даже если вы разберетесь со всеми тонкостями работы и не растопчете ногами свой home computer в процессе отладки программы, то время, потраченное на написание программы в кодах, явно не будет соответствовать результату.
Есть и другие способы заставить спрайты двигаться побыстрее. Самый легкий из них - использование готовых кодовых подпрограмм из пакетов Supercode и New Supercode. С их помощью можно добиться различных видов перемещения (скроллинга) экрана, множества звуковых эффектов, быстрой смены экранов (причем самыми разными способами), изменения цветовых атрибутов экрана и многого, многого другого. Существует множество версий Supercode. Мы пользовались Supercode версии II (см. [5]).
Программа Supercode
После загрузки пакета на экране появится яркая заставка с названием, а также информация о том, что пакет разбит на две части, каждая из которых содержит 76 подпрограмм. Нажав клавишу 1 (или 2), загрузим
требуемую половину, после чего можно обратиться к ее меню с помощью клавиши I. Меню состоит из строк типа 42 LASER ZAP.......63950
состоящих из номера подпрограммы, ее названия и начального адреса, с которого подпрограмма должна запускаться.
В нижней части экрана выводится информация о действиях, которые вы можете выполнить.
D - DEMO - демонстрация действия подпрограмм;
Р - PRINTER - вывод на принтер копии экрана;
I - INDEX - вызов на экран списка подпрограмм;
L - LOCATE - вывод на экран инструкции по перемешению подпрограмм;
J - JUMP PAGE# - переход к нужной странице списка;
С - CONTINUE - переход к следующей странице;
S - SAVE - вызов на экран инструкции по записи подпрограмм;
Q - QUIT - выход из программы Supercode, причем в ОЗУ компьютера она будет сохранена;
N - NUMBER - выбор номера подпрограммы.
В режиме меню нажатие любой цифровой клавиши устанавливает режим NUMBER, позволяющий набрать номер одной из имеющихся подпрограмм и познакомиться с подробной инструкцией о ее работе и размещении в памяти. Если вы захотите посмотреть подпрограмму в действии, нажмите клавишу Е (EXAMPLE), а для записи ее на ленту или дискету - Т (ТАРЕ). Имя, под которым будет записана кодовая подпрограмма, можно установить самому или же использовать фирменное. В последнем случае достаточно нажать Enter.
Перейдем к описанию программы игры ИГРАЛЬНЫЙ АВТОМАТ, для работы которой следует переписать из пакета Supercode на ленту или дискету следующие кодовые подпрограммы:
1 - PIXEL UP-SCROLL 22 - PIXEL BOX LEFT- SCROLL
42 - LASER ZAP
43 - UNI-NOTE SOUND-GEN
44 - DIAL-NOTE
69 - BORDER EFFECTS
Заметим, что на ленте они должны располагаться после программы игры. Несколько слов о самой игре. После загрузки программы и всех подпрограмм, на экране появится игровое поле, включающее в себя следующие элементы (рис. 9.1):
- три окна, в которых будут появляться различные цифры, причем выигрышными считаются только те их комбинации, где совпадают две. или три цифры (всего используются семьцифр -1,2, ..., 7);
продолжайте вводить цифры, пока не заполнится весь прямоугольник. Тогда число «сбросится», и можно будет вновь делать ставку;
- левый нижний прямоугольник синего цвета, где указывается размер вашего капитала в банке. Начальная сумма равна 100$;
- слева все ваши доходы символически представлены в виде столбика золотых монет достоинством в 50$ каждая. Если случится так, что вы все проиграете, программа издаст протяжный звук, и игра начнется вновь. Если же вам удастся набрать 20 монет (1000$), то об этом радостно просигнализирует вначале изменение цвета бордюра, а затем звуковой сигнал, после чего игра закончится, и можно будет попытать счастья еще раз;
- под тремя цифровыми окнами находится прорезь, откуда посыплются выигранные монеты по 50$ в том случае, если ставка была удачной.
А теперь скажем о том, как устанавливается выигрыш. Если числовая комбинация содержит 2 единицы, 2 двойки, 2 тройки и т. д., то ваша ставка умножается соответственно на 1, 2, 3 и т. д. Если же эта комбинация состоит только из единиц, двоек, троек, то ставка умножается соответственно на 1, 2, 3, а затем еще на 2. В случае удачной игры, сумма выигрыша появляется в левом верхнем углу игрового поля одновременно с монетой и сопровождается звуковым сигналом.
Программа 32. ИГРАЛЬНЫЙ АВТОМАТ.
5 CLEAR 58570
10 BORDER 0: PAPER 0: INK 7
11 CLS
22 PRINT AT 9,10;"Please wait"
23 PRINT AT 11,8;"Loading program"
25 REM - Load code program -30 FOR n=1 TO 6
40 INK 7: PRINT AT 13,12;"Code ";n
45 PRINT AT 0,0;
50 INK 0: LOAD ""CODE
60 NEXT n
61 CLS : PRINT AT 9,10;"Please wait!"
62 GO SUB 9000
63 GO SUB 1400
64 CLS
65 PRINT AT 13,12;"ПППППП": REM 6 space 70 REM ---------
90 DIM q(3): DIM c(3): DIM a$(3,16)
91 CLS
92 LET st1=2: LET st=2: LET no=0: LET rn=0 100 LET a$(1)="-GAME AUTOMAT-"
105 LET a$(2)="Sankt-Petersburg"
106 FOR n=0 TO 20
107 PRINT AT n,0; INK INT (RND*7+1);TAB 30
108 NEXT n
110 LET а$(3)="ПППППП1993"
150 PRINT AT 8,8; INK 3; "ПП"; INK 5;"ПППППППППППП";Ж 3;""
155 PRINT AT 10,8; INK 6;"ППППП"; INK 2;" "; INK 6;"ППППППП"
160 PRINT AT 12,14; INK 4;"ПППП"
200 FOR n=1 TO 3
210 PRINT AT 21,8; INK 0;a$(n)
220 FOR m=1 TO 16
230 RANDOMIZE USR 64001
240 NEXT m
250 NEXT n
260 FOR n=1 TO 56
265 RANDOMIZE USR 64001
270 NEXT n
320 REM ------------
330 POKE 63951,10 340 RANDOMIZE USR 63950
342 POKE 64648,7
343 POKE 64649,5
344 POKE 64649,150
345 POKE 64670,28
346 RANDOMIZE USR 64647 350 FOR n=1 TO 105
360 RANDOMIZE USR 64001 370 NEXT n
380 REM ------------
400 CLS
402 FOR n=0 TO 20 STEP 3
403 FOR m=0 TO 30 STEP 3
404 INK 6: PRINT AT n,m;"DE"
405 PRINT AT n+1,m;"FG"
406 NEXT m
407 NEXT n
408 PAUSE 80: INK 7: CLS
410 PLOT 0,0: DRAW 0,175: DRAW 255,0: DRAW 0,-175:DRAW -255,0
425 PRINT AT 0,7; INK 0;" "; PAPER 5; INK 0;TAB 30;PAPER 0;"
430 PLOT 40,0: DRAW 0,175
435 FOR n=19 TO 20
440 PRINT AT n,1; INK 6;"ABC"
445 NEXT n
450 PAPER 1: INK 6
455 FOR n=1 TO 3
460 PRINT AT 6+n,7;"ППППППП"
465 PRINT AT 11+n,7;"ППППППП"
470 NEXT n
475 PRINT AT 8,13;"$" 480 PRINT AT 13,8;"100ПП$" 482 PAPER 0
485 PLOT 120,40: DRAW 0,96: DRAW 96,0: DRAW 0,-96: DRAW -96,0
490 PLOT 216,112: DRAW 8,0: DRAW 0,-32: DRAW 3,0:DRAW 0,35: DRAW -11,0
495 FOR n=4 TO 1 STEP -1
500 CIRCLE 225,76,n
505 NEXT n
515 PLOT 135,84: DRAW 0,29: DRAW 20,0: DRAW 0,-29: DRAW -20,0 520 PLOT 159,84: DRAW 0,29: DRAW 20,0: DRAW 0,-29:DRAW -20,0 525 PLOT 183,84: DRAW 0,29: DRAW 20,0: DRAW 0,-29:DRAW -20,0 530 PLOT 137,56: DRAW 64,0: DRAW 0,5: DRAW -64,0:DRAW 0,-5 532 INK 5
535 FOR n=17 TO 23 STEP 3
540 LET x=n: LET y=8: GO SUB 1300
545 NEXT n
550 LET d$="ProgramПП~GAME AUTOMAT~.ППППAuthor Kapultsevich Igor,ППSaint-Petersburg, ПП1993. ППstart-ENTER, ППППEnd of game-E. ППППЛБО- 50$^DE- 50$. ППППППППП"
552 LET te=0: LET te1=0
553 LET st=2: LET st1=2: LET bank=100
554 REM ------------------
555 LET f$=""
556 PRINT AT 2,10;"ПП";AT 3,10;"ПП";AT 5,9;"ПППП"
557 IF bank=0 THEN POKE 64648,150: POKE 64649,70:POKE 64651,100: POKE 64670,28: RANDOMIZE USR 64647: GO TO 400
558 IF bank>=1000 THEN POKE 60029,18: POKE 60020,1:POKE 60006,70: RANDOMIZE USR 60000: POKE 63951,10: RANDOMIZE USR 63950: GO TO 400
559 PRINT AT 8,8; PAPER 1;"ППППП"
560 PRINT AT 7,7; FLASH 1; PAPER 1; INK 0; "ППППППП"; AT 8,7;" ";AT 8,13;"$";AT 9,7;"ППППППП"
565 LET e$=INKEY$
566 GO SUB 1500
567 IF e$="e" OR e$="E" THEN GO TO 400 570 IF e$="" THEN GO TO 565
575 IF CODE e$=13 THEN GO TO 600
580 IF CODE e$<48 OR CODE e$>57 THEN GO TO 565
585 LET f$=f$+e$: PRINT AT 8,8; PAPER 1; INK 6;f$
586 BEEP .1,15
587 IF LEN f$>4 THEN GO TO 600 590 GO TO 565
600 IF f$="" THEN GO TO 558 605 LET d=VAL f$
610 IF d<1 OR d>bank THEN BEEP .3,5: BEEP .3,0: LET f$="": GO TO 559
612 LET bank=bank-d
613 PRINT AT 13,8; PAPER 1; INK 6;"ППППП$";AT 13,8;bank 615 FOR n=0 TO 20 STEP 2: BEEP .01,n: NEXT n
620 PRINT AT 7,7; PAPER 1;"ППППППП"
625 PRINT AT 9,7; PAPER 1; "ППППППП"
630 PRINT AT 8,7; PAPER 1;" ";AT 8,13; INK 6;"$"
632 REM ---------------------
640 FOR n=1 TO 12
641 FOR m=1 TO 3
642 LET rn=rn+1: IF rn>150 THEN LET rn=1
643 LET a=VAL r$(rn)
646 LET x=14+m*3: INK 5: LET y=8: GO SUB 950+a*50
647 BEEP .0005,55: BEEP .0004,40
648 IF n>7 THEN PAUSE n-6
649 NEXT m
650 NEXT n
652 REM --------------
653 FOR n=1 TO 3
655 GO SUB 9900
660 LET a1=INT (rnd*141)
665 IF a1<36 THEN LET a=1: GO TO 700
667 IF a1>35 AND a1<66 THEN LET a=2: GO TO 700
669 IF a1>65 AND a1<91 THEN LET a=3: GO TO 700
670 IF a1>90 AND a1<111 THEN LET a=4: GO TO 700 672 IF a1>110 AND a1<126 THEN LET a=5: GO TO 700 674 IF a1>125 AND a1<136 THEN LET a=6: GO TO 700 676 IF a1>135 THEN LET a=7: GO TO 700
680 REM ---------
700 LET x=14+n*3: LET y=8: GO SUB 950+a*50
705 BEEP .0005,55: BEEP .0004,40
707 GO SUB 1500
710 LET q(n)=a
720 NEXT n
725 GO SUB 1600
999 STOP
1000 REM ----1----
1010 PRINT AT y,x;"4;CS/7"
1015 PRINT AT y+1,x;"CS/5"
1020 PRINT AT y+2,x;"4;CS/1"
1025 RETURN
1050 REM ----2----
1055 PRINT AT y,x;"4;CS/3"
1060 PRINT AT y+1,x;"4;CS/2"
1065 PRINT AT y+2,x;"5;CS/3"
1070 RETURN
1100 REM ----3----
1110 PRINT AT y,x;"4;CS/3"
1115 PRINT AT y+1,x;" CS/2"
1120 PRINT AT y+2,x;"4;CS/2"
1130 RETURN
1150 REM ----4----
1160 PRINT AT y,x;"4;4"
1170 PRINT AT y+1,x;"5;CS/2"
1180 PRINT AT y+2,x;" 5"
1190 RETURN
1200 REM ----5----
1210 PRINT AT y,x;"4;CS/3"
1220 PRINT AT y+1,x;"5;CS/3"
1230 PRINT AT y+2,x;"4;CS/2"
1240 RETURN
1250 REM ----6----
1260 PRINT AT y,x;"4:CS/3"
1270 PRINT AT y+1,x;"5;CS/3"
1280 PRINT AT y+2,x;"5;CS/2"
1290 RETURN
1300 REM ----7----
1310 PRINT AT y,x;"4;CS/3"
1320 PRINT AT y+1,x;" 5"
1330 PRINT AT y+2,x;" 5"
1340 RETURN
1400 REM -- Graphics -1410 FOR n=0 TO 55 1420 READ S 1430 POKE USR "A"+n,s 1440 NEXT n 1450 RETURN
1460 DATA 0,0,0,255,150,150,150,255
1465 DATA 0,0,0,255,239,239,239,255 1470 DATA 0,0,0,255,105,105,105,255 1475 DATA 3,12,59,59,122,125,218,215 1480 DATA 224,88,188,86,238,215,183,127 1485 DATA 238,213,123,116,63,63,12,3 1490 DATA 191,189,185,122,242,196,24,224
1495 REM ---------------------
1500 REM
1505 IF te1=8 THEN LET te1=0: LET te=te+1: PRINT AT 0,30;PAPER 0; INK 0;d$(te): IF te>(LEN d$)-1 THEN LET te=1 1510 LET te1=te1+1
1520 POKE 58679,30: POKE 58680,64: POKE 58682,24:POKE 58681,8: RANDOMIZE USR 58571 1530 RETURN
1600 REM ---- PROIGRAL? --1605 IF q(1)=q(2) AND q(2)=q(3) THEN LET wy=q(1)*d*2: GO TO 1640 1610 IF q(1)=q(2) OR q(2)=q(3) THEN LET wy=q(2)*d:GO TO 1640 1620 IF q(1)=q(3) THEN LET wy=q(1)*d: GO TO 1640 1635 GO TO 2030 1640 REM -----
1645 POKE 64702,200: POKE 64693,30: POKE 64682,200:RANDOMIZE USR 64675 1650 LET ko5=INT (wy/50)
1656 PRINT AT 2,10; INK 6;"DE";AT 3,10;"FG";AT 5,9; INK 7;wy: PAUSE 10
1657 INK 6: OVER 1 1660 FOR n=1 TO ko5 1670 FOR m=14 TO 19 1680 PRINT AT m,20;"DE" 1685 PRINT AT m+1,20;"FG" 1690 PAUSE 5
1995 PRINT AT m,20;"DE"
1996 PRINT AT m+1,20;"FG" 2000 NEXT m
2005 BEEP .005,50: BEEP .005,45: BEEP .005,40: PAUSE 5
2010 NEXT n
2015 OVER 0
2020 LET bank=bank+wy
2022 PRINT AT 13,8; PAPER 1; INK 6; "ППППП$" 2025 PRINT AT 13,8; PAPER 1; INK 6;bank
2030 REM -----------
2035 LET st1=INT (bank/50)
2040 IF st1>st THEN LET s=1: GO TO 2047
2045 IF St1<st THEN LET s=-1: GO TO 2047
2046 GO TO 555
2047 OVER 1: INK 6
2048 LET g=20 2050 LET st=st+s
2052 IF s=1 THEN LET g=21
2055 PRINT AT g-st,1;"ABC": BEEP .1,20-(g-st): PAUSE 10
2060 IF st<>st1 THEN GO TO 2050
2070 OVER 0
2080 LET st=st1
2090 GO TO 555
8999 STOP
9000 REM -- RND --9005 LET t$="": LET r$="" 9010 FOR n=1 TO 200
9020 LET a=INT (RND*7+1) 9030 LET t$=STR$ a 9040 LET r$=r$+t$ 9050 NEXT n 9060 RETURN
9899 REM ----RND generator----
9900 LET no=no+1.3415926: IF no>198 THEN LET no=no-194.768627 9902 LET n1=INT no
9905 LET rnd1=VAL (r$(n1)+r$(n1+1)+r$(n1+2)) 9910 LET rnd=rnd1/783 9920 RETURN
5 - установка системной переменной RAMTOP. Адрес 58570 определяется самой нижней границей кодовых подпрограмм (см. строку 1520);
10 - установка атрибутов экрана;
11 - очистка экрана;
22, 23 - вывод текста, предупреждающего о том, что сейчас с ленты магнитофона будут загружаться кодовые блоки;
30...60 - этот фрагмент программы обеспечивает последовательную загрузку с ленты шести кодовых подпрограмм. При этом строка 40 информирует вас о том, какой именно блок читается в данный момент, .а строка 45 устанавливает координаты слов Bytes:, которые появляются в процессе загрузки. Эти слова пишутся черным цветом по черному фону;
61 - экран очищается, выводится сообщение «Пожалуйста, подождите!»;
62 - обращение к подпрограмме, которая генерирует случайную последовательность из 200 чисел, необходимую для выработки комбинаций в окнах. Непривычный вид подпрограммы объясняется тем, что при загрузке кодовых подпрограмм нарушается нормальная работа RND-генератора в компьютере, но в то же время без случайных чисел обойтись нельзя;
63 - обращение к подпрограмме, формирующей графические символы: для монеты, стоящей на ребре - 4, для лежащей монеты - 3;
90 - задание рабочих массивов;
91...380 - эта часть программы выполняет функции заставки, обеспечивая медленное перемещение текста снизу вверх с использованием звуковых эффектов. Здесь применяются три кодовые подпрограммы, о которых будет сказано чуть позже;
106... 108 - устанавливаются номера INK, которые начнут действовать при движении текста через определенные знакоместа, окрашивая его в переливающиеся тона;
200...250 - в нижней части экрана черным цветом вводятся три надписи, затем во внутреннем цикле они подвергаются вертикальному перемещению (скроллингу) на 16 пикселей. Строка 230 включает подпрограмму вертикального скроллинга;
260...270 - три надписи медленно перемещаются вверх на 56 пикселей, последовательно окрашиваясь в цвета, установленные ранее в строках 106...108;
340 - включение кодовой подпрограммы «трель»;
342...346 - подготовка и включение кодовой подпрограммы, обеспечивающей звуковой эффект «глиссандо»;
350...370 - после короткой остановки в центре экрана три надписи продолжают медленное перемещение (скроллинг) вверх и в конце концов уходят за пределы экрана. Движение сопровождается окрашиванием строк текста (как в 260...270) разными цветами;
402...407 - заполнение всего экрана монетами (второй кадр заставки);
410...545 - на экран выводится изображение игрового поля, то есть устанавливаются окна, рисуются синие прямоугольники, прорезь для выпуска монет, а также выводится изображение двух монет «начального капитала» игрока в левой части поля. Подпрограмма 1300...1340 рисует три семерки в окнах, где затем будут появляться цифровые комбинации;
550 - задание текста, который будет выводиться в верхней части экрана в виде бегущей строки;
553 - задание начальных значений некоторых переменных;
557 - если в результате игры банк окажется пустым (bank = 0), то включается кодовая подпрограмма «глиссандо», и программа переходит на начало игры;
558 - если действия игрока были удачными и в банке оказалось более 1000$, то последовательно включатся кодовые подпрограммы «бордюр» и «трель», а затем произойдет переход на начало игры;
559 - если оба предыдущих условия не выполняются, то стирается надпись со ставкой;
560 - изображение синего прямоугольника, куда заносятся ставки, начинает «мигать»;
565...630 - эти строки обеспечивают ввод ставки, а подпрограмма 1500... 1530 перемещает окно в верхней части экрана (вместе с текстом);
632...650 - вывод случайных комбинаций цифр, создающих иллюзию вращения дисков игрального автомата;
652...720 - эта часть программы фиксирует в окнах автомата последнюю комбинацию цифр, которая и определяет, выиграли вы или проиграли. Последовательность условий определяет, насколько часто могут появляться единицы, двойки, тройки, и т. д. до семерки. Предусмотрено, что единицы и двойки выпадают чаще, а семерки - реже;
725 - безусловный переход на строку 1600, где начинается подпрограмма проверки комбинации цифр для определения выигрыша или проигрыша;
1000...1340 - подпрограмма печати цифр 1, 2, ...7;
1400... 1490 - подпрограмма ввода графических символов, формирующих монеты;
1500... 1530 - подпрограмма бегущей строки, использующая кодовый блок скроллинга окна влево;
1600...1620 - проверка выпавшей числовой комбинации - есть выигрыш или нет. Проверяются все четыре возможных варианта совпадений:
- первой и второй цифр;
- первой и третьей;
- второй и третьей;
- первой, второй и третьей.
Например, выигрыши принесут 116, 242, 433 или 222 доллара, а если все цифры окажутся разными, произойдет переход к строке 2030, откуда начинается подпрограмма, уменьшающая количество монет в. левом столбике;
1640... 1645 - формирование звукового сигнала;
1650...2010 - определяется, сколько монет должно быть выброшено в виде выигрыша. В левом верхнем углу показывается сумма выигрыша и рисуется монета;
2020 - к имеющейся у вас сумме добавляется выигрыш;
2030...2090 - изменение количества монет в левом столбике;
9000 - подпрограмма, вырабатывающая случайные числа для формирования комбинаций в окнах игрового автомата.