Как сделать текстовый квест на python
Перейти к содержимому

Как сделать текстовый квест на python

  • автор:

Текстовый квест на Python с использованием Kivy

Пытаюсь сделать квест на Python с использованием Kivy. Сделал рабочую версию через терминал с управлением через ввод вариантов ответа: введите сюда описание изображения Далее сделал GUI с выводом в консоль по нажатию кнопок: введите сюда описание изображения Подскажите, пожалуйста, как мне запустить GUI вместе с основным кодом, чтобы нажатие кнопок GUI запускало команды первой программы? Или мне придется переписывать всю игру заново, в самом GUI опираясь на команды из kivy?

Отслеживать
задан 31 мар 2022 в 14:24
Thaise Smith Thaise Smith

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Данное взаимодействие должно было быть продумано изначально. В данный момент, самым простым решением будет запуск «движка игры» после запуска киви ( https://stackoverflow.com/questions/24664181/how-do-i-run-a-function-once-the-form-is-loaded-kivy ). Но перед этим, необходимо переопределить функции print & input таким образом, чтобы они взаимодействовали с интерфейсом киви.

Отслеживать
ответ дан 31 мар 2022 в 14:45
1,604 1 1 золотой знак 3 3 серебряных знака 13 13 бронзовых знаков
Спасибо, это то, что я искал 🙂
31 мар 2022 в 15:15

  • python
  • kivy
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.2.16.5008

Завершаем проект: текстовый квест

К этому моменту у тебя скорее всего уже готова предварительная версия квеста. В этой главе я расскажу, как сделать его немного технологичнее — добавить текстовую графику и музыку, а также разбить на несколько модулей для удобства поддержки.

Как добавить в квест графику?

Не смотря на то, что квест текстовый, в некоторых местах нам может захотеться вставить графику. Но чтобы квест выглядел аутентично, в качестве графики можно использовать ASCII Art.

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

 _ |\_ \` ..\ __,.-" =__Y= ." ) _ / , \/\_ ((____| )_-\ \_-` jgs `-----'`-----` `--`

Откуда взять такие картинки?

  • Можно взять из архива (https://www.asciiart.eu/) или просто поискать в интернете.
  • Можно воспользоваться одним из генераторов, которые умеют произвольную картинку превратить в ASCII Art, например, вот этот. Но скорее всего получится менее отчетливо, как минимум придется поискать картинку с белым или прозрачный фоном.

Вот это, например, Вупсень из генератора.

 ` ` `: / ./++oo/+ .s+ososyss: `-:/:.//+oss` .-:/:/. /+s+ `+/. /+++oy- //. /o+/-/o` +. /o+. o. . o++/+o` ./. /oooo- `-. //////+. `.`..-------.:sys. . ```````.+soo+ ..-+//-`````.:oo++s. `./-.ss:-````.--:++++/ `.``.-://:.-..`. ----::/+++ `. -------/. +s.` . --------:/. /ydho+:. `. - `:-------://. yhho+os/.`` ``.. . -----:://///://+osy+++osoo/. . /++++++++yo+++oy+os+` --------------/+++++++os++++yo++os` --------------:+++++++os++++ss+++s+ ---------------. /+++++ys+++oy+` .:---------------------://+oyo+++oyso` ::--------------::---:---:/o/+++ss+s/ `. -------::+osso/::/++//. /+++s+ `+o++/. osossssyyssssyysyys/. /. so+/osoo+///s+//+sssydo+ssshsssho. ` `.------` ``/////oo++/:://. -.` 

Вставляем ASCII в код: многострочный текст

Как вставить ASCII Art в код? Не разбивать же картинку на отдельные строки и выводить по одной?

Для этого нам пригодится многострочный текст, в отличие от обычного, в нем используются тройные кавычки.

image = """ >--O--< [^] /ooo\\ ______________:/o o\:______________ |=|=|=|=|=|=|:A|":|||:"|A:|=|=|=|=|=|=| ^"""""""""""""". . """"""""""""""^ \ / \. / ____ "---" ____ |\/\/|=======|*|=======|\/\/| :----" /-\ "----: /ooo\ #|ooo|# \___/ """ print(image)

Если в картинке встречается символ \ , картинка может слегка "поехать", дело в том, что обратный слэш используется для обозначения специальных непечатных символов (например, \n - это перенос строки), а обычный "бэкслэш" обозначается как \\ . Можно либо заменить все бэкслеши в коде на двойные, либо. поставить перед кавычками букву r . Тогда питон сделает это автоматически.

Другую проблему могут создать три двойные кавычки внутри картинки, но тут можно просто использовать одинарные для обозначения многострочной строки.

image = r''' >--O--< [^] /ooo\\ ______________:/o o\:______________ |=|=|=|=|=|=|:A|":|||:"|A:|=|=|=|=|=|=| ^"""""""""""""". . """"""""""""""^ \ / \. / ____ "---" ____ |\/\/|=======|*|=======|\/\/| :----" /-\ "----: /ooo\ #|ooo|# \___/ ''' print(image)

Кстати, совершенно неясно, почему Microsoft решила выбрать именно его в качестве разделителя у путей в файлах - постоянно приходится писать \\ , это называется экранированием. В других операционных системах используется обычный / , экранировать его не нужно.

Используем модули для упрощения кода

Если вставить много больших картинок в код, он станет большим, и работать с ним будет очень непросто. Но есть отличное решение - вынести все картинки в отдельный файл, или, другими словами свой собственный модуль. Раньше мы использовали встроенные модули, а теперь вот сможем сделать свои.

Все просто! Для этого в папке нашего проекта рядом с основным файлой квеста (пусть это будет quest.py ) нужно создать новый файл images.py .

В файл images.py поместим несколько переменных с картинками.

space_station = r''' >--O--< [^] /ooo\\ ______________:/o o\:______________ |=|=|=|=|=|=|:A|":|||:"|A:|=|=|=|=|=|=| ^"""""""""""""". . """"""""""""""^ \ / \. / ____ "---" ____ |\/\/|=======|*|=======|\/\/| :----" /-\ "----: /ooo\ #|ooo|# \___/ ''' bear = r""" _ _ : `.--.' ; _. _ .' `. _..--'"' `-._ : :_.-'" .`. : 6 6 : : '.; : : `..'; `: .----. :' ; `._Y _.' ' ; 'U' .' `. ; `: ;`-..___ `. .'`. jgs _: : : ```"''"'``. `. `. .' ;..' .' `.'` `. ' `. -'` """ 

А в главном с квестом quest.py будем их импортировать. С точки зрения питона модуль images - это просто файл images.py , а через точку можно обращаться в функциям и переменным из этого файла.

# images.py - наш файл с картинками import images # печатаем переменную bear из модуля images print(images.bear) # печатаем переменную space_station из модуля images print(images.space_station)

По аналогии в другие файлы можно выносить функции, помещая каждую часть квеста в отдельный файл. Например, можно выделить в файлы отдельные планеты, если в вашем квесте космонавт перелетает от одной планеты к другой и на каждой что-то происходит.

Добавляем звук

В прошлых уроках мы с тобой использовали встроенные модули math и random , а буквально на прошлом обзаце сделали собственный модуль с картинками. В помимо собственных и встроенных модулей в питон можно добавлять модули, написанные другими разработчиками. Мы поговорим об этом подробнее в следующих главах. А пока - мимолетное знакомство.

А что делать, если хочется добавить саундтрек? Ничего, просто добавить его! ��

Windows:

Если ты работаешь в Windows, то музыку в квест добавить достаточно просто. Для этого в питоне есть встроенный модуль, который называет winsound .

Но есть два нюанс: воспроизводить можно только файлы в формате wav (можно воспользоваться онлайн-конвертером).

import winsound winsound.PlaySound("ИМЯФАЙЛА.wav", winsound.SND_ASYNC) # начало квеста. 

Mac:

Аналогично windows, но winsound работать не будет, придется поставить сторонний модуль, например, simpleaudio . Для этого нужно запустить терминал (программа в MacOS) и ввести команду pip install --user simpleaudio .

После этого можно использовать его.

import simpleaudio sound = simpleaudio.WaveObject.from_wave_file("ИМЯФАЙЛА.wav") sound.play() # начало квеста. 

В примерах выше аудиофайл лежит в одной папке с вашей программой. Например, если файл с вашей программой сохранен на Рабочем столе, то и аудиофайл должен лежать на Рабочем столе.

Добавляем задержки

Иногда в квесте для нагнетения обстановки вам может понадобиться добавить задержку. Например, персонаж какое-то время пытается открыть дверь или ожидается итог напряженной схватки.

Сделать это можно, используя встроенный модуль time . Пример его использования ниже.

import time print("Сейчас будет перерыв 10 секунд.") time.sleep(10) print("10 секунд прошло, работаем дальше. ")

Завершаем квест

Итак, теперь ты уж точно готов взорвать индустрию своей игрой! ��

Обновленные критерии для самооценивания.

  • +5 баллов - программа запускается без ошибок.
  • +5 баллов - программа всегда работает корректно, если вводить допустимые данные.
  • +5 баллов - программа корректно работает даже если пользователь вводит недопустимые данные, в этом случае она просит повторить ввод.
  • +5 баллов - удобство интерфейса и понятность инструкций.
  • +5 баллов - проработанность сюжета.
  • +5 баллов - квест разбит на функции.
  • +5 баллов - наличие обратных переходов.
  • +5 баллов - наличие инвентаря и/или изменяемость карты в процессе игры.
  • +5 баллов - ASCII графика.
  • +5 баллов - квест разбит на несколько модулей.
  • +5 баллов - звуковое сопровождение.
  • +5 баллов - иногда используются задержки на несколько секунд.
  • +5 баллов - красивый, читаемый код.

Что дальше? Тестирование и обратная связь от пользователей.

Очень важно, чтобы результатами твоей работы пользовались реальные люди. Ведь в конечном итоге, программирование всегда позволяет нам решать проблемы и улучшать жизнь конкретных людей. А еще положительные отзывы дадут тебе толчок к дальнейшему саморазвитию!

А значит, чтобы стать хорошим программистом, тебе нужно общаться с твоими пользователями и собирать обратную связь..

Как только будешь +- уверен в работоспособности своего квеста, покажите его нескольким друзьям или одноклассникам, соберите и проанализируйте конструктивную обратную связь о них (что понравилось? что стоит изменить? что можно добавить в следующей версии?). Я уверен, что они будут в восторге!

Единственная проблема - для запуска твоего проекта нужен питон, но у нее есть простое решение. Просто зарегистрируйся и выложи весь код на сайт Repl.it, там можно загружать файлы по отдельности и скинь друзьям ссылку!

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

from replit import audio audio.play_file('audio.wav') # квест. 

Поздравляю, как только все получится, ты завершишь свой первый большой проект! ��

Я пишу текстовую игру на Python: первый прототип

Я пишу текстовую игру на Python: первый прототип. Изображение № 1.

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

Для тех, кто успел подзабыть за две недели суть того, что мы делаем, напомню. LAM-40 — это текстовая игра, где вы играете за человека, которому нужно успеть за девять часов получить справку на 40-м этаже загадочного государственного учреждения, переполненного бюрократами. Каждый этаж учреждения генерируется случайным образом: игроку попадаются бюрократы разного уровня, к каждому из которых нужно искать особый подход, чтобы пройти дальше и добраться до последнего этажа.

Примечание: весь код приводится для Python версии 3.0 и старше, а потому может не работать на более старых версиях.

Для начала давайте вспомним, какой код остался у нас с прошлого раза, и разберёмся, чем мы его хотим дополнить.

У нас есть простенький класс бюрократа, умеющего здороваться с игроком и обладающего двумя характеристиками — рангом и настроением. Задача на сегодня — создать простейший, бесконечно повторяющийся цикл «сражений» с бюрократами, что, по сути, и есть основная механика нашей игры. Получившийся у меня в итоге прототип занял 95 строк — начнём его разбирать по порядку (последняя пустая строка должна быть по стандартам PEP 8, но embed'ы её обрубают).

Строка 2: помимо random, в начале программы мы импортируем модуль sys. Из него нам понадобится функция exit() — возможность выйти из игры, пока что не указанная эксплицитно.

Строки 5–13, 16: я добавил списки положительных и отрицательных реакций бюрократов. Обратите внимание, как используются переносы. Дело в том, что, согласно PEP 8, максимальная длина строки должна быть 79 символов, иначе код будет слишком сложно читать. Именно поэтому для удобства каждое новое высказывание находится на новой строке и написано с тем же отступом, что и предыдущее. Ещё я добавил переменную ACTIONS типа данных string с основными действиями игрока (обычным вопросом, подкупом, мольбой, давлением и угрозой), чтобы не делать слишком длинной строку, где мы будем выводить все эти действия.

Строки 25, 34–44: у класса Bureaucrat появилась характеристика negative логического типа данных (то есть истина или ложь) со значением False. Она показывает, был ли ход игрока удачным — если нет, то её значение становится True, и игра предлагает нам совершить новое действие на том же самом бюрократе, а не создаёт нового бюрократа. Для того чтобы отобразить реакцию бюрократа на действие игрока, используются функции с говорящими названиями react_positively() и react_negatively(), которые меняют значение переменной negative и выводят случайную реакцию бюрократа на случившееся.

Строки 46–85: функция act() выводит на экран все возможные действия игрока и предлагает ему выбрать одно из них, введя первую букву слова. Именно для того, чтобы не загружать эту строку, мы вывели string со всеми действиями в отдельную переменную ACTIONS. Следом за этим идёт ветвление, и мы впервые в этом блоге используем ключевое слово elif — сокращение от else if. Оно задаёт условие помимо того, что указано в if, а блок с ним — следующие за выполнением этих условий действия. В нашем случае мы проверяем, что ввёл игрок. Если он ввёл строчную букву Q, выполнение программы завершится из-за упомянутой ранее функции sys.exit(). Если игрок введёт строчную букву W (wait), то ему выпадет новый бюрократ — это тоже пока что незадокументированная возможность. Если же игрок введёт какой-нибудь другой символ, то программа перейдёт в функцию react(), где ветвление выходит на новый уровень. На текущем этапе я сделал так, что для определённых сочетаний ранга и настроения бюрократа срабатывает лишь одно действие. Более того, есть непобедимые сочетания (например, высокий ранг и плохое настроение), в случае с которыми приходится вводить W, чтобы выпал следующий бюрократ.

Самая большая головная боль на первых порах — это использование ключевого слова self, когда вы ссылаетесь на функцию или характеристику класса внутри этого класса, и оператора сравнения == вместо оператора присваивания = рядом с условными операторами. Вероятно, и о том, и о другом вы будете забывать, так что следите за этим. Кстати, обратите внимание на ключевое слово and, которое используется рядом с операторами ветвления — оно обозначает, что должны выполняться оба условия, находящиеся рядом с ним.

Строки 87–94: наконец, в самом низу заканчивается описание класса и начинается логика основной программы. Мы создаём образец класса Bureaucrat, присваиваем его переменной bureaucrat и используем функцию с приветствием бюрократа. После этого запускаем бесконечный цикл, внутри которого запускаем функцию с выводом и вводом действий игрока, а также условное исполнение создания и приветствия нового бюрократа — в зависимости от того, каково текущее значение bureaucrat.negative. Обратите внимание на две вещи: оператор else при желании можно не использовать, а в случае с логическими типами данных в Python вместо оператора == применяют ключевое слово is.

Первый прототип LAM-40 готов. Конечно, он ещё далёк не то что от финальной, а даже от альфа-версии, поэтому нам предстоит порядочно поработать. Сейчас я вижу кучу проблем с этим прототипом, которые собираюсь устранить в следующий раз:

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

Не обойтись без элемента неожиданности в «сражениях» с бюрократами — иначе игра быстро наскучит. Вероятно, это также поможет избежать дикого ветвления, которое есть сейчас в нижней части кода.

Игре требуется больше разнообразия во фразах, характеристиках, действиях и прочем, а также в том, как всё это выводится, чтобы внести разнообразие в повествовательную часть.

Желательно описывать текстом все действия, что возможны в игре, в том числе выход из неё и ожидание.

Из возможных действий желательно сделать список, а не отдельный string, чтобы туда можно было при определённых условиях добавлять новые действия. Кроме того, на ввод нужно применить функцию upper(), чтобы не требовалось каждый раз вводить строчные буквы. Также надо сделать адекватную реакцию на неверно введённые символы.

В основной логике игры есть повторяющиеся две строчки, нарушающие правило DRY. Да и сам цикл не очень красив — пожалуй, стоит над ним подумать, когда он начнёт расширяться.

Куча мелочей вроде описания функции act(), комментариев к некоторым частям кода, использования sys.exit() и характеристики negative, которая тоже не очень изящное решение. Так что поищу ему альтернативу.

Как видите, работы предстоит полно. Надеюсь, к следующему разу игра примет уже более целостный вид. Если вам что-то непонятно, пишите комментарии под материалом и в социальных сетях — буду рад и любым другим отзывам. Если вы более опытный в программировании человек, чем я, то с удовольствием выслушаю содержательную критику. Спасибо, и до следующего раза!

Полные курсы Python на Codeacademy и Treehouse*

* — платные курсы, но есть пробный период

Развитие программистского мышления на Udacity

Учебники по Python на LearnPython.org и Python Course

Текстовый квест на языке python

Я собирался сделать текстовый квест на языке python, ранее не занимаясь этим (опыта в использовании python у меня нет) по заранее сделанному учеником 11 класса текстовому квесту.

Моей задачей было сделать такую же программу на ту же тему, но изменить сюжет и структуру программы.

Я подумал, что это будет легко - просто посмотрю, как кто-то сделал это так, перемещу эту часть вон туда, а ту вот сюда и совмещу с третей.

Тут то как раз таки и начались проблемы с не знанием операторов, значений символов и уровневых-логических зависимостей.

Вот код текстовой игры про подземелье ученика 11 класса:

print ("Dungeon quest") print ("*********************************************************") print ("Вы просыпаетесь ,в незнакомой комнате ,с похмелья у вас сильно болит голова ") print ("нажмите ,|1| чтобы осмотреться") a =int(input()) while a!=1 : a=int(input()) print ("*********************************************************") print ("*Вы осматриваете комнату*") print ("Вокруг темная , сырая комната , состоящая из заплесневелых холодных камней , в конце комнаты находится дверь , рядом с ней стоит единственный источник света - факел , он стоит на металлической подставке , закрепленной на стене.") print ("В комнате , неподалеку от вас ,есть небольшой старинный столик , на нем стоит потухшая свеча и лежит пистолет") print ("*********************************************************") print ("нажмите ,|1| чтобы продолжить") a =int(input()) while a!=1 : a =int(input()) print ("*********************************************************") print ("О НЕТ . КАК ЖЕ Я СРАЗУ НЕ ЗАМЕТИЛ-подумали про себя вы") print ("на вашу ногу в кандалы , от них идет цепь к стене") print ("Ну нет уж , так не пойдет , нужно выбираться отсюда!- подумали вы") print ("*********************************************************") print ("нажмите ,|1| чтобы продолжить") a =int(input()) while a!=1 : a =int(input()) print ("*********************************************************") print ("Варианты действий") print ("*********************************************************") print ("попробовать выдернуть цепь из стены - для действия нажмите |1|") print ("позвать на помощь - для действия нажмите |2|") print ("осмотреться вокруг и поискать что-нибудь в карманах - для действия нажмите |3|") print ("цепь не такая и толстая , может попробовать прокусить. - для действия нажмите |4|") print ("*********************************************************") b=int(input()) r=0 while b!=3 : while b>4 or b3 or b2 or a2 or a2 or b 

А вот мое начало кода, на котором все в принципе-то и застопорилось:

print ("Dungeon raid") print ("*************************************************") print ("Вы - матерый воин Гатс, жаждущий славы и богатства") print ("Недавно вами было взято задание - отправиться в жуткое подземелье ради спасения похищенной злым некромантом дочери графа Паулето") print ("Вам предстоит подготовить свое снаряжение и собрать рюкзак перед дорогой, взяв то, что поможет вам в борьбе со зловещим некромантом") print ("Нажмите |1| чтобы начать выбор экипировки") a =int(input()) while a!=1 : a=int(input()) print ("*************************************************") print ("Варианты действий") print ("*********************************************************") print ("Взять с собой тяжелый серебрянный двуручный меч - для действия нажмите |1|") print ("Надеть на себя волшебный мифриловый доспех - для действия нажмите |2|") print ("Положить в рюкзак лечебную эссенцию регерации жизни - для действия нажмите |3|") print ("Взять с собой связку отмычек - для действия нажмите |4|") print ("Засунуть в рюкзак лом - для действия нажмите |5|") print ("Положить в голенища своих сапог два легких стальных ножа - для действия нажмите |6|") print ("*********************************************************") b=int(input()) if b>6 or b6 or с6 or с 

Вот мой план создания игры:

Я предположил, если я обозначу каждый вариант из 6 за новую переменную b-c-a-d-f-g-e и напишу в условиях к каждому новому выбору что-то типа:

с не равно b - > далее d не равно b и c и тд., то получится далее запомнить выборы игрока и составить на их основе условие прохождения дальше или конца игры по типу:

Если игрок выбрал числа в такой то ситуации, что это числа 3-4-5 в любом порядке - > то он проходит, если нет - > проигрышь.

Но даже тогда остается проблема того, что каждый раз к выбору представлены 6 вариантов, а не 6 - уже выбранные.

К тому же, проблема еще в том, когда я пытаюсь ввести 3-ю переменную c (а отвечает за шаги, а b - первая переменная из 6 выборов) - > мне компилятор выдает ошибку такого рода, что я как-будто не могу ввести c и ее значения нет в программе, хотя я вроде бы указал ввод данных для c.

a =int(input()) if a==1 : c =int(input()) c!=b if с>6 or с

Короче говоря, если кто-то дочитал до этого момента и хоть что-то понял + хочет и может помочь - > пожалуйста, помогите.

А то я с часу до 8 думу думаю и пытаюсь как-то с операторами что-то придумать: while, if, else - хоть как-то что-то понятно, но с операторами While True,Elif, continue и break - вообще мрак полный.

Благо разобрался, что != значит не равно, а == равно.

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

Основные проблемы это:

1) Как сделать так, чтобы программа не предлагала к выбору уже ранее выбранный из 6 возможных вариантов выбор;

2) Как сделать так, чтобы программа запомнила все "цифры выбора" игрока и использовала дальше в программе как условие прохождения-не прохождения игры дальше;

3) Как ввести эту клятую третью переменную "С", в ситуации, когда нужно ввести сперва "A" -> а потом, если "А" == 1, то нужно ввести "С" и проверить ее на условия, а если "А" == 2, то просто продолжить чтение текста программы.

  • Python
  • Текстовая игра
  • Логическая игра
  • Запоминание переменных
  • Ввод данных
  • Python
  • Логические игры

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *