февраль 1, 2022

Bastilude by Marco's Retrobits

Добавить в
Мои игры
Торрент
Скачать

Бастилия

БАЗОВАЯ 10-строчная видеоигра для Sinclair ZX Spectrum

Марко Варезио (Marco’s Retrobits) https://retrobits.itch.io/

Блог на английском языке: https://retrobits.altervista.org/

Блог на итальянском языке: https://somebitsofme.altervista.org/

Канал YouTube: https://www.youtube.com/channel/UCWTxG8paNsOUEU5mPcNklXA

Играть онлайн/ссылка для скачивания: https://retrobits.itch.io/bastilude

Видео игрового процесса:

Bastilude (Basic Hastilude) — видеоигра в жанре экшн, написанная всего из 10 строк на языке программирования BASIC для домашнего компьютера Sinclair ZX Spectrum.

Это мое участие в конкурсе BASIC 10 Liner Contest 2022 года, категория PUR-80 (максимум 80 символов в логической строке, разрешены сокращения).

Вдохновением для Bastilude послужила аркадная игра Joust, разработанная Williams и впервые выпущенная в 1982 году.

Игровой процесс

========

Игрок управляет (с большим воображением) рыцарем верхом на зеленом драконе. Цель состоит в том, чтобы сбросить рыцарей противника верхом на пурпурных драконах в рыцарском поединке или спешке. Победителем поединка становится всадник, чья верховая лошадь в момент контакта выше. Столкновение равной высоты отталкивает персонажей друг от друга. Уровень сложности постепенно увеличивается по мере того, как противники побеждаются и становятся быстрее.

При запуске программы отображается титульный экран.

Вы можете начать игру, нажав любую клавишу. Клавиши «o» и «p» управляют горизонтальным направлением дракона.и скорость, а клавиша «z» заставляет дракона летать. Одновременно принимается только одна команда, так что вы можете либо управлять горизонтальной скоростью и направлением, либо взмахивать крыльями дракона.

В нижней части экрана программа отслеживает количество оставшихся жизней и счет игрока, а также высокий балл. Также отображается краткое напоминание об элементах управления.

Описание программы

===================

Переменные

---------

C Позиция игрока X

Позиция R-игрока Y

X Позиция игрока X на экране (целая часть C)

Y Позиция игрока Y на экране (целая часть R)

Горизонтальная скорость игрока V

Вертикальная скорость игрока W

B Позиция оппонента X

Позиция оппонента Y

H Позиция соперника X на экране (целая часть B)

G Позиция соперника Y на экране (целая часть A)

F Горизонтальная скорость противника

E Вертикальная скорость противника

L Осталось жизней

S Текущий счет

Высокий балл

Z Случайное число 0<=Z<1

Итератор цикла

Список программ

---------------

1 ЯРКО 1: ГРАНИЦА 6: БУМАГА 0: CLS: ДЛЯ i=1 ДО 7: ПЕЧАТЬ В i+6,i+6;ЧЕРНИЛА i;"БАСТИЛУДА": СЛЕДУЮЩИЙ i: ПУСТЬ r=21: ПУСТЬ c= 15: ЕСЛИ PEEK 25102=128, ТО ПУСТЬ t=0

2 INK 4: LET v=0: LET w=1: LET a=10: LET b=15: LET e=.2: LET f=-.2: LET g=0: LET h=0: LET l=2: LET s=0: ПЕРЕЙТИ SUB 10: ПАУЗА 0: ГРАНИЦА 6: CLS: ПЕРЕЙТИ SUB 10

3 LET x=INT c: LET y=INT r: LET g=INT a: LET h=INT b: НАПЕЧАТАТЬ y,x;CHR$(61+SGN v+(v=0));INK 3;AT g,h;CHR$(61+SGN f+(f=0)): ЕСЛИ h<>x ТО ПЕРЕХОДИМ К 6

4 ЕСЛИ g=y-1, ТО ГРАНИЦА 3: СЛУЧАЙНО ВЫБЕРИТЕ: ПУСТЬ l=l-1: ПУСТЬ r=21: ПУСТЬ c=8+16*(h<15): ПУСТЬ v=0: BEEP .5, -23: НАПЕЧАТАТЬ y,x;" ": ПЕРЕЙТИ SUB 10: ПЕРЕЙТИ К 1+2*(l>-1)

5 ЕСЛИ y=g-1, ТО ГРАНИЦА 4: РАНДОМИЗАЦИЯ: ПУСТЬ s=s+1: ПУСТЬ a=RND*22: ПУСТЬ b=RND*32: ПУСТЬ e=ABS e+.05: ПУСТЬ f=ABS f+ .05: СИГНАЛ .1,12: ПЕЧАТЬ В g,h;" ":ПЕРЕД SUB 10: ПЕРЕЙТИ К 3

6 ПУСТЬ k$=INKEY$: ПУСТЬ v=v+.2*(k$="p")*(v<1)-.2*(k$="o")*(v>-. 8): ЕСЛИ e>.95, ТО ПУСТЬ e=.95

7 ПУСТЬ w=-1*(k$="z")*(y>0) +(k$<>"z")*(y<21)+(y=0): ПУСТЬ z= RND: ЕСЛИ y=g И h=x, ТО ПУСТЬ f=-f: ПУСТЬ v=-SGN f*ABS v

8 ПУСТЬ c=c+v: ПУСТЬ c=c-32*(c>=32)+32*(c<0): ПУСТЬ b=b+f: ПУСТЬ b=b-32*(b> =32)+32*(b<0): ПУСТЬ r=r+w

9 ПУСТЬ a=a+e*SGN(y-1-g)*(g>0)+(g=0): НАПЕЧАТАТЬ AT y,x;" ";AT g,h;" ": LET f=-f*(z<.05)+f*(z>=.05): ПЕРЕЙТИ К 3

10 LET t=t*(t>s)+s*(t<=s): ПЕЧАТЬ #1;БУМАГА 6;ЧЕРНИЛА 1;AT 0,0;"Sc:";s,"Hi:" ;t,"Жизни:";l,"p ^z": ГРАНИЦА 1: ВОЗВРАТ

Объяснение исходного кода

---------------------

Инициализация

Строки 1 и 2 отображают титульный экран и выполняют инициализацию переменных.

1 ЯРКО 1: ГРАНИЦА 6: БУМАГА 0: CLS: ДЛЯ i=1 ДО 7: ПЕЧАТЬ В i+6,i+6;ЧЕРНИЛА i;"БАСТИЛУДА": СЛЕДУЮЩИЙ i: ПУСТЬ r=21: ПУСТЬ c= 15: ЕСЛИ PEEK 25102=128, ТО ПУСТЬ t=0

2 INK 4: LET v=0: LET w=1: LET a=10: LET b=15: LET e=.2: LET f=-.2: LET g=0: LET h=0: LET l=2: LET s=0: ПЕРЕЙТИ SUB 10: ПАУЗА 0: ГРАНИЦА 6: CLS: ПЕРЕЙТИ SUB 10

Первые две строки исполняютсякаждый раз, когда начинается новая игра, но максимальный счет T должен быть определен и инициализирован нулем только один раз. Это делается путем проверки области переменных в памяти с помощью оператора PEEK в строке 1; 25102 (0x620E) — это, по сути, адрес, по которому ожидается идентификатор переменной высокой оценки (этот адрес был определен эмпирически, исходя из длины программы). При первом выполнении оператора PEEK 25102 были определены только переменная цикла I и переменные R и C, и это местоположение будет содержать значение терминатора 128 (0x80), поэтому переменная T определена и инициализирована до 0. При последующих выполнениях, ячейка будет содержать значение 116 (0x74), соответствующее коду символа «t», поэтому сравнение со 128 не удастся, и значение переменной T больше не будет установлено равным 0.

Игровой цикл

Настоящий игровой цикл начинается со строки 3.

3 LET x=INT c: LET y=INT r: LET g=INT a: LET h=INT b: PRINT AT y,x;CHR$(61+SGN v+(v=0));INK 3 ;AT g,h;CHR$(61+SGN f+(f=0)): ЕСЛИ h<>x, ТО ПЕРЕЙТИ К 6

Целая часть координат игрока и противника вычисляется и используется для ПЕЧАТИ их на экране. И игрок, и противники изображаются с помощью символов «<» (код 60) или «>» (код 62) в зависимости от их горизонтального направления (лицом влево или вправо).

Если X-координаты игрока и противника различаются, столкновения быть не может, и программа переходит к строке 6.

В противном случае, если противник находится вышеplayer (строка 4), игрок теряет одну жизнь и статус игры обновляется. Если жизней больше не осталось, программа переходит к строке 1, в противном случае игрок располагается в нижней строке экрана, и игровой цикл продолжается со строки 3.

4 ЕСЛИ g=y-1, ТО ГРАНИЦА 3: СЛУЧАЙНО ВЫБЕРИТЕ: ПУСТЬ l=l-1: ПУСТЬ r=21: ПУСТЬ c=8+16*(h<15): ПУСТЬ v=0: BEEP .5, -23: НАПЕЧАТАТЬ y,x;" ": ПЕРЕЙТИ SUB 10: ПЕРЕЙТИ К 1+2*(l>-1)

Если игрок находится выше противника (строка 5), игрок получает одно очко, в случайном месте появляется новый противник, а его горизонтальная и вертикальная скорости увеличиваются. Статус игры обновляется, и игровой цикл продолжается на строке 3.

5 ЕСЛИ y=g-1, ТО ГРАНИЦА 4: РАНДОМИЗАЦИЯ: ПУСТЬ s=s+1: ПУСТЬ a=RND*22: ПУСТЬ b=RND*32: ПУСТЬ e=ABS e+.05: ПУСТЬ f=ABS f+ .05: СИГНАЛ .1,12: ПЕЧАТЬ В g,h;" ":ПЕРЕД SUB 10: ПЕРЕЙТИ К 3

Строка 6 считывает состояние клавиатуры, и если нажата клавиша «o» (левая) или «p» (правая), соответственно обновляется горизонтальная скорость игрока V. Вертикальная скорость противника E ограничена таким образом, что она не может стать больше 0,95, иначе игрок не сможет выиграть поединок.

6 ПУСТЬ k$=INKEY$: ПУСТЬ v=v+.2*(k$="p")*(v<1)-.2*(k$="o")*(v>-. 8): ЕСЛИ e>.95, ТО ПУСТЬ e=.95

Строка 7 проверяет, нажата ли клавиша «z», и соответствующим образом обновляет вертикальную скорость игрока W. Если игрок поднимается и попадает в верхнюю часть экрана (Y=0), он «отскакивает» вниз.

Проверка коллизий завершена во второй части строки7: если игрок и противник занимают одну и ту же позицию, поединок считается ничьей, а горизонтальные скорости персонажей обновляются так, чтобы они двигались в противоположных направлениях.

7 ПУСТЬ w=-1*(k$="z")*(y>0) +(k$<>"z")*(y<21)+(y=0): ПУСТЬ z= RND: ЕСЛИ y=g И h=x, ТО ПУСТЬ f=-f: ПУСТЬ v=-SGN f*ABS v

Строка 8 обновляет позиции X игрока и противника (C и B) на основе горизонтальных скоростей V и F. Позиция игрока Y R обновляется на основе вертикальной скорости W.

8 ПУСТЬ c=c+v: ПУСТЬ c=c-32*(c>=32)+32*(c<0): ПУСТЬ b=b+f: ПУСТЬ b=b-32*(b> =32)+32*(b<0): ПУСТЬ r=r+w

В строке 9 координата Y противника A обновляется на основе вертикальной скорости E и положения игрока по Y; на самом деле противник пытается пролететь на одну позицию выше игрока, чтобы выиграть поединок. Затем оба персонажа стираются с экрана; они будут отображаться в обновленных координатах в следующей итерации игрового цикла. Чтобы добавить в игру некоторой непредсказуемости, с вероятностью 5% горизонтальное направление соперника инвертируется. Наконец, программа возвращается к началу игрового цикла в строке 3.

9 ПУСТЬ a=a+e*SGN(y-1-g)*(g>0)+(g=0): НАПЕЧАТАТЬ AT y,x;" ";AT g,h;" ": LET f=-f*(z<.05)+f*(z>=.05): ПЕРЕЙТИ К 3

Подпрограмма печати статуса игры

Подпрограмма в строке 10 сначала проверяет, превышает ли текущая оценка S максимальную оценку T, и соответствующим образом обновляет T. Затем он печатает текущий счет, высокий балл, количество оставшихся жизней игрока и напоминание об управлении игрой в момент времени t.он внизу экрана. Перед возвратом вызывающей стороне цвет границы восстанавливается до синего.

10 LET t=t*(t>s)+s*(t<=s): ПЕЧАТЬ #1;БУМАГА 6;ЧЕРНИЛА 1;AT 0,0;"Sc:";s,"Hi:" ;t,"Жизни:";l,"p ^z": ГРАНИЦА 1: ВОЗВРАТ

Подтверждение длины строк программы

---------------------------

Заменив каждый BASIC-токен одним символом и удалив лишние пробелы, каждая строка в итоговом исходном коде не превысит ограничение в 80 символов:

1B1:b6:C0:v:fi=1 F7:pIi+6,i+6;Xi;"БАСТИЛУДА":ni:lr=21:lc=15:uO25102=128 Glt=0

2X4:lv=0:lw=1:la=10:lb=15:le=.2:lf=-.2:lg=0:lh=0:ll=2:ls=0:h10: m0:b6:v:h10

3lx=Rc:ly=Rr:lg=Ra:lh=Rb:pIy,x;U(61+Fv+(v=0));X3;Ig,h;U(61+Ff+(f=0) ))):э<>x Gg6

4ug=y-1 Gb3:t:ll=l-1:lr=21:lc=8+16*(h<15):lv=0:Z.5,-23:pIy,x;" ":h10:g1+2*(l>-1)

5uy=g-1 Gb4:t:ls=s+1:la=T*22:lb=T*32:le=Ge+.05:lf=Gf+.05:Z.1,12:pIg, ч;" ":h10:g3

6lk$=XEY$:lv=v+.2*(k$="p")*(v<1)-.2*(k$="o")*(v>-.8): ue>.95 Gle=.95

7lw=-1*(k$="z")*(y>0) +(k$<>"z")*(y<21)+(y=0):lz=T:uy =g Yh=x Glf=-f:lv=-Ff*Gv

8lc=c+v:lc=c-32*(c>=32)+32*(c<0):lb=b+f:lb=b-32*(b>=32)+32 *(b<0):lr=r+w

9la=a+e*F(y-1-g)*(g>0)+(g=0):pIy,x;" ";Ig,h;" ":lf=-f*( z<.05)+f*(z>=.05):g3

10lt=t*(t>s)+s*(t<=s):p#1;C6;X1;I0,0;"Sc:";s,"Hi:";t,"Жизни :";l,"p ^z":b1:y

Поэтому Bastilude подходит для участия в конкурсе BASIC 10 Liner Contest в категории PUR-80.

Ссылки

Статья в Википедии о Joust: https://en.wikipedia.org/wiki/Joust_(video_game)

Руководство по Joust Atari 2600: https://archive.org/details/Joust_1982_Atari/

Как скачать Bastilude by Marco's Retrobits через торрент

Всего несколько простых шагов:

  • Устанавливаем программу μTorrent, через которую мы будем скачивать торренты
  • Выбираем и скачиваем подходящий торрент-файл репака Bastilude by Marco's Retrobits
  • Двойным кликом открываем скаченный файл, программа μTorrent запустится автоматически и предложит выбрать место для сохранения дистрибутива.
  • После того как репак скачается, запускайте его. Начнется установка и... это все, приятной игры!