Как программировать компьютерные игры (с изображениями)

Оглавление:

Как программировать компьютерные игры (с изображениями)
Как программировать компьютерные игры (с изображениями)
Anonim

У вас есть идея компьютерной игры и вы хотите воплотить ее в жизнь? Или вы когда-нибудь задумывались, как пишутся компьютерные игры? Из этой статьи вы узнаете, как написать три базовые компьютерные игры на Python. Вам потребуется базовое понимание Python и общих концепций программирования для разработки вашей первой игры.

Шаги

Часть 1 из 3: создание текстовой игры

5692759 1
5692759 1

Шаг 1. Выберите язык программирования

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

  • Для чего в основном используется язык?

    Некоторые языки программирования, такие как JavaScript, предназначены для использования в Интернете, в то время как другие, такие как Python, C или C ++, предназначены для запуска компьютерных программ. Для своей игры выберите язык с более широким спектром использования, такой как Python, C, C ++ или JavaScript.

  • Насколько сложно учиться?

    Хотя написание программы должно быть достаточно простым после некоторой практики на любом нормальном языке программирования (т. Е. Не на языке, специально разработанном для сбивания с толку, как Malbolge), некоторые из них более дружелюбны для новичков, чем другие. Java и C, например, потребуют от вас более глубокого понимания концепций программирования, чем что-то вроде Python, который известен своим более доступным и прямым синтаксисом.

  • Где я могу это использовать?

    Вероятно, вы хотите, чтобы люди в разных системах, таких как Linux, Mac или Windows, могли играть в вашу игру. Поэтому вам не следует использовать язык, который поддерживается только в нескольких системах, например Visual Basic, который поддерживается только в Windows.

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

5692759 2
5692759 2

Шаг 2. Подготовьте компьютер

Вам понадобятся два основных компонента: текстовый редактор, в котором вы будете писать свой код, и компилятор, который вы будете использовать, чтобы превратить его в игру. Если вы хотите следовать примеру из этой статьи, вам следует установить Python и научиться запускать программы. Если вы хотите, вы можете настроить IDE (интегрированную среду рабочего стола), которая объединяет редактирование, компиляцию и отладку в одной программе. IDE Python называется IDLE. Но вы также можете просто использовать любой текстовый редактор, поддерживающий простой текст, например Блокнот для Windows, TextEdit для macOS или Vim для Linux.

5692759 3
5692759 3

Шаг 3. Напишите код для приветствия игрока

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

  • Это делается с помощью функции print () в Python. Чтобы попробовать, откройте новый файл с расширением.py, введите в него следующий код, сохраните и запустите:

    print («Добро пожаловать в игру по угадыванию чисел!») print («Введите целое число от 1 до 1000:»)

5692759 4
5692759 4

Шаг 4. Сгенерируйте случайное число

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

  • Python не имеет встроенной функции случайных чисел, но у него есть стандартная библиотека (это означает, что пользователю не нужно устанавливать ничего лишнего), которая есть. Итак, перейдите в начало вашего кода (перед функциями print ()) и введите строку import random.
  • Используйте случайную функцию. Он называется randint (), находится в библиотеке случайных чисел, которую вы только что импортировали, и принимает минимальное и максимальное значение, которое может иметь число в качестве аргумента. Так что вернитесь к концу вашего кода и введите следующую строку:

    rightNum = random.randint (0, 1000)

5692759 5
5692759 5

Шаг 5. Получите информацию от игрока

В игре игрок хочет что-то сделать или с чем-то взаимодействовать. В текстовой игре это возможно путем ввода текста. Теперь, когда у нас есть случайное число, наши следующие строки кода должны попросить игрока ввести свое наилучшее предположение.

  • Поскольку введенный вами код печатает инструкцию по вводу числа игроку, он также должен читать введенное число. Это делается с помощью input () в Python 3 и raw_input () в Python 2. Вам следует писать на Python 3, поскольку Python 2 скоро устареет. Добавьте в свой код следующую строку, чтобы сохранить ввод игрока в переменной с именем number:

    userNum = input ()

5692759 6
5692759 6

Шаг 6. Превратите ввод игрока в пригодный для использования тип данных

Игрок ввел число - что теперь?

  • Сделайте ввод игрока числом. Это может показаться странным, потому что они только что ввели число. Но есть веская причина: Python предполагает, что весь ввод - это текст или «строка», как это называется в программировании. Этот текст содержит номер, который вы хотите получить. В Python есть функция, которая преобразует строку, содержащую только число, в число внутри. Тип:

    userNum = int (userNum)

5692759 7
5692759 7

Шаг 7. Сравните номер игрока с правильным номером

Как только игрок введет свое число, вам нужно будет сравнить его с тем, которое было сгенерировано случайным образом. Если числа не совпадают, ваша игра может заставить игрока попробовать другое число. Если числа совпадают, вы можете сказать игроку, что он угадали правильно, и выйти из программы. Это делается с помощью следующего кода:

в то время как userNum! = rightNum: userNum = int (input ())

5692759 8
5692759 8

Шаг 8. Дайте игроку обратную связь

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

  • Конечно, вы могли бы просто сказать игроку, правильное ли его число или нет. Но при таком подходе игроку, возможно, придется угадать 1000 раз в худшем случае, что было бы очень скучно.
  • Так что скажите игроку, слишком ли мало их или слишком много. Это значительно сократит количество их догадок. Если, например, игрок сначала угадает 500, а игра отвечает: «Слишком большое. Попробуйте еще раз», то вместо 1000 возможных чисел будет только 500. Это делается с помощью if-конструкций, поэтому замените print («Wrong. Попробуй еще раз. ") С одним.
  • Имейте в виду, что проверка того, совпадают ли два числа, выполняется с помощью ==, а не с помощью =. = присваивает значение справа от него переменной слева от него!
  • if userNum <rightNum: print ("Слишком мало. Повторите попытку:") if userNum> rightNum: print ("Слишком велико. Повторите попытку:")

5692759 9
5692759 9

Шаг 9. Протестируйте свой код

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

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

    import random print («Добро пожаловать в игру по угадыванию чисел!») print («Введите целое число от 1 до 1000:») rightNum = random.randint (0, 1000) userNum = input () userNum = int (userNum) while userNum! = rightNum: if userNum <rightNum: print ("Слишком мало. Попробуйте еще раз:") if userNum> rightNum: print ("Слишком велико. Повторите попытку:") userNum = int (input ()) print ("Вы угадали правильно.")

5692759 10
5692759 10

Шаг 10. Подтвердите ввод

У игрока не должно быть возможности нарушить вашу игру, просто введя неправильный код. «Подтверждение ввода» означает, что игрок ввел правильную вещь перед ее обработкой.

  • Снова откройте игру и попробуйте ввести что-нибудь, кроме числа. Игра завершится с ошибкой ValueError. Чтобы избежать этого, вы можете реализовать способ проверки, было ли введено число.
  • Определите функцию. Поскольку проверка ввода довольно долгая, и вам нужно делать это несколько раз, вы должны определить функцию. Он не принимает аргументов и возвращает число. Сначала напишите def numInput (): вверху вашего кода, непосредственно под случайным импортом.
  • Получите вход игрока один раз. Используйте функцию input () и присвойте результат переменной inp.
  • Если игрок вводит не число, попросите его ввести число. Чтобы проверить, является ли строка числом, используйте функцию isdigit (), которая допускает только целое число, поэтому вам не придется проверять это отдельно.
  • Если введено число, преобразуйте его из строки в число и верните результат. Используйте функцию int () для преобразования строки в целое число. Это сделает преобразование в основном коде ненужным, и вы должны удалить его оттуда.
  • Замените все вызовы input () в основном коде вызовами numInput ().
  • Код функции numInput () будет выглядеть так:
  • def numInput (): inp = input (), но не inp.isdigit (): print («Вам сказали ввести целое число! Введите целое число:») inp = input () return int (inp)

5692759 11
5692759 11

Шаг 11. Протестируйте игру еще раз

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

Попробуйте ввести текст, когда программа запрашивает у вас номер. Теперь вместо выхода с сообщением об ошибке программа снова запросит у вас номер

5692759 12
5692759 12

Шаг 12. Предложите перезапустить игру, когда она закончится

Таким образом, игрок сможет играть в вашу игру дольше, не перезагружая ее постоянно.

  • Поместите весь код, кроме импорта и определения функции, в цикл while. Установите в качестве условия True: это всегда будет истинным, поэтому цикл будет продолжаться вечно.
  • Спросите игрока, хотят ли он играть снова после того, как правильно угадали номер. Используйте функцию print ().
  • Если они ответят «Нет», прекратите смотреть. Если они ответят еще на что-нибудь, продолжайте. Выход из цикла выполняется с помощью оператора break.
  • Переместите «Добро пожаловать в игру по угадыванию чисел» за пределы цикла while. Вероятно, игрок не хочет, чтобы его приветствовали каждый раз, когда он играет в игру. Переместите инструкцию print («Добро пожаловать в игру по угадыванию чисел!» Над while True:, чтобы она была напечатана только один раз, когда пользователь запустит первую игру.
5692759 13
5692759 13

Шаг 13. Протестируйте игру

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

  • Обязательно ответьте и «Да», и «Нет» хотя бы один раз, чтобы убедиться, что оба варианта работают. Вот как должен выглядеть ваш код:

    import random def numInput (): inp = input (), но не inp.isdigit (): print ("Вам было сказано ввести целое число! Введите целое число:") inp = input () return int (inp) print («Добро пожаловать в игру по угадыванию чисел!») While True: print («Введите целое число от 1 до 1000:») rightNum = random.randint (0, 1000) userNum = numInput () while userNum! = RightNum: if userNum <rightNum: print ("Слишком мало. Повторите попытку:") if userNum> rightNum: print ("Слишком велико. Повторите попытку:") userNum = numInput () print ("Вы угадали правильно.") print ("У вас хотите снова сыграть? Введите "Нет", чтобы выйти. ") if input () ==" No ": break

5692759 14
5692759 14

Шаг 14. Напишите другие текстовые игры

Как насчет написания текстового приключения в следующий раз? Или викторину? Будь креативным.

Кончик: Иногда полезно заглянуть в документацию, если вы не знаете, как что-то делается или как используется функция. Документацию Python 3 можно найти по адресу https://docs.python.org/3/. Иногда поиск в Интернете того, чем вы хотите заниматься, также дает хорошие результаты.

Часть 2 из 3: создание игры с 2D-графикой

5692759 15
5692759 15

Шаг 1. Выберите графическую библиотеку

Создание графики очень сложно, и большинство языков программирования (включая Python, C ++, C, JavaScript) обеспечивают лишь минимальную поддержку графики в ядре или стандартных библиотеках или даже не поддерживают ее. Поэтому вам придется использовать внешнюю библиотеку, чтобы иметь возможность создавать графику, например Pygame для Python.

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

В этой статье мы будем использовать Python с Cocos2D, чтобы показать, как создать простой 2D-платформер. Некоторые из упомянутых концепций могут отсутствовать в других игровых движках. Обратитесь к их документации для получения дополнительной информации.

5692759 16
5692759 16

Шаг 2. Установите выбранную вами графическую библиотеку

Cocos2D для Python прост в установке. Вы можете получить его по адресу https://python.cocos2d.org/index.html или запустив sudo pip3 install cocos2d, если вы используете Linux.

5692759 17
5692759 17

Шаг 3. Создайте новый каталог для вашей игры и мультимедиа

В игре вы будете использовать такие вещи, как изображения и звуки. Храните эти вещи в том же каталоге, что и программа. Этот каталог не должен содержать ничего другого, чтобы вы могли легко увидеть, какие активы у вас есть в игре.

5692759 18
5692759 18

Шаг 4. Создайте новый файл кода в новом каталоге

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

В этом примере мы создадим файл с именем main.py, который будет содержать весь наш код

5692759 19
5692759 19

Шаг 5. Создайте игровое окно

Это основная предпосылка для игры с графикой.

  • Импортируйте необходимые подмодули cocos2d: cocos.director, cocos.scene и cocos.layer. Это делается с помощью from subModuleName import *, где имя субмодуля - это субмодуль, который вы хотите импортировать. Разница между from… import * и import… заключается в том, что вам не нужно ставить имя модуля перед всем, что вы используете из этого модуля с первым.
  • Определите подкласс MainMenuBgr ColorLayer. Это в основном означает, что любой созданный вами фон главного меню будет вести себя как цветной слой с некоторыми внесенными вами изменениями.
  • Запустите кокосовый директор. Это откроет вам новое окно. Если вы не установите заголовок, окно будет иметь тот же заголовок, что и имя файла (main.py), что не будет выглядеть профессионально. Разрешите изменять размер окна, задав для параметра resizable значение True.
  • Определите функцию showMainMenu. Вы должны поместить код для отображения главного меню в функцию, потому что это позволит вам легко вернуться в главное меню, снова вызвав функцию.
  • Создайте сцену. Сцена пока состоит из одного слоя, который является объектом определенного вами класса MainMenuBgr.
  • Запустите эту сцену в окне.
  • from cocos.director import * from cocos.scene import * from cocos.layer import * class MainMenuBgr (ColorLayer): def _init _ (self): super (MainMenu, self)._ init _ (0, 200, 255, 255) def showMainMenu (): menuSc = Scene (MainMenuBgr ()) Director.run (menuSc) Director.init (caption = "IcyPlat - простой платформер", resizable = True) showMainMenu ()

5692759 20
5692759 20

Шаг 6. Добавьте в окно главное меню

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

  • Импортируйте cocos.menu (снова с инструкцией from) и pyglet.app (на этот раз с импортом).
  • Определите MainMenu как подкласс Menu.
  • Установите выравнивание главного меню. Вы должны установить вертикальное и горизонтальное выравнивание отдельно.
  • Создайте список пунктов меню и добавьте их в меню. У вас должны быть как минимум пункты меню «Начать игру» и «Выйти». Каждый пункт меню следует заключать в квадратные скобки. Каждый элемент должен иметь метку и функцию обратного вызова, которая определяет, что происходит, когда игрок щелкает по нему. Для элемента «Начать игру» используйте функцию startGame (вы скоро ее напишете), для элемента «Выйти» используйте «pyglet.app.exit» (уже существует). Создайте собственное меню, вызвав self.create_menu (menuItems).
  • Определите startGame (). Просто введите пропуск в определение, вы замените его, когда напишете настоящую игру.
  • Перейдите в то место в коде, где вы создали сцену menuSc, и добавьте к ней объект MainMenu.
  • Теперь весь ваш код должен выглядеть следующим образом:

    from cocos.director import * from cocos.menu import * from cocos.scene import * from cocos.layer import * import pyglet.app class MainMenuBgr (ColorLayer): def _init _ (self): super (MainMenuBgr, self)._ init _ (0, 200, 255, 255) class MainMenu (Menu): def _init _ (self): super (MainMenu, self)._ init _ ("") self.menu_valign = CENTER self.menu_halign = CENTER menuItems = [(MenuItem ("Начать игру ", startGame)), (MenuItem (" Quit ", pyglet.app.exit))] self.create_menu (menuItems) def startGame (): pass def showMainMenu (): menuSc = Scene (MainMenuBgr ()) menuSc.add (MainMenu ()) Director.run (menuSc) Director.init (caption = "IcyPlat - простой платформер", resizable = True) showMainMenu ()

5692759 21
5692759 21

Шаг 7. Протестируйте свой код

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

Код из инструкции должен открывать окно с заголовком «IcyPlat - простой платформер». Фон светло-голубой, и вы можете изменить размер окна. Когда вы нажимаете «Начать игру» в меню, ничего (пока) не должно происходить. Когда вы нажмете «Выйти», окно закроется

5692759 22
5692759 22

Шаг 8. Создайте спрайт

Спрайт - это «игровой объект» или двухмерное изображение. Спрайты могут быть внутриигровыми объектами, значками, фоновыми декорациями, персонажами и всем остальным, что вы можете представить с помощью изображения в игре. Мы начнем с создания спрайта для персонажа, с которым игрок может взаимодействовать.

  • Импортируйте подмодуль cocos.sprite с выражением from-import-expression.
  • Найдите изображение, представляющее спрайт. Вы не можете отобразить спрайт, если у вас нет для него изображения. Вы можете нарисовать один или получить его в Интернете (однако следите за лицензиями, если вы планируете опубликовать свою игру). Для этого примера перейдите на https://opengameart.org/content/tux-classic-hero-style и сохраните изображение-p.webp" />
  • Создайте слой как новый объект класса ScrollableLayer. Затем создайте спрайт как объект Sprite и установите его позицию на (8, 250). Для справки точка (0, 0) находится в нижнем левом углу. Это довольно много, но это гарантирует, что пингвин не застрянет во льду.
  • Добавьте спрайт к слою спрайта.
  • Создайте новую сцену из слоя спрайта и запустите ее.
  • def startGame (): figLayer = ScrollableLayer () fig = Sprite ('pingu.png') fig.position = (75, 100) figLayer.add (fig) # gameSc = Scene (figLayer) Director.run (gameSc)

  • Запустите код. Вы должны увидеть маленькую фигурку пингвина (или что-то еще, что вы нарисовали) на черном фоне после того, как нажмете Начать игру.
5692759 23
5692759 23

Шаг 9. Придумайте свой пейзаж

В большинстве игр ваши спрайты не должны просто плавать в пустоте. Они действительно должны стоять на какой-то поверхности, а вокруг них что-то есть. В 2D-играх это часто делается с помощью набора плиток и карты плиток. Набор плиток в основном говорит о том, какие существуют квадраты поверхности и квадраты фона и как они выглядят.

  • Создайте набор плитки. Набор плиток для этой игры будет очень простым: одна плитка для льда и одна плитка для неба. Ледяная плитка, используемая в этом примере, взята из CC-BY-SA 3.0.
  • Создайте изображение набора плитки. Это изображение всех плиток, которые должны быть одинакового размера (отредактируйте их, если это не так) и имеют размер, который вы хотите видеть в игре, рядом друг с другом. Сохраните изображение как icyTiles.png.
  • Создайте описание набора плиток. Это файл XML. XML-файл содержит информацию о том, насколько велики плитки в изображении набора плиток, какое изображение использовать и где найти, какой из них находится. Создайте XML-файл с именем icyTiles.xml с приведенным ниже кодом:

         
    
5692759 24
5692759 24

Шаг 10. Создайте мозаичную карту вашего ландшафта

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

  • Узнайте, сколько строк и столбцов нужно. Для этого разделите размер экрана на размер плитки как по горизонтали (столбцы), так и по вертикали (строки). Число округлить в большую сторону; для этого вам понадобится функция математического модуля, поэтому добавьте из math import ceil к import в верхней части кода.
  • Откройте файл для записи. Это приведет к удалению всего предыдущего содержимого файла, поэтому выберите имя, которого еще нет ни у одного файла в каталоге, например levelMap.xml.
  • Запишите открывающие теги в файл.
  • Сгенерируйте тайловую карту по алгоритму. Вы можете использовать тот, который указан в приведенном ниже коде, или можете придумать его самостоятельно. Обязательно импортируйте функцию randint из модуля random: она требуется для работы приведенного ниже кода, и все, что вы придумаете, вероятно, также потребует случайных целых чисел. Кроме того, не забудьте положить плитки неба и льда в разные слои: лед твердый, небо - нет.
  • Запишите закрывающие теги в файл и закройте файл.
  • def generateTilemap (): colAmount = ceil (800/16) * 3 # (ширина экрана / размер плитки) * 3 rowAmount = ceil (600/16) # высота экрана / размер плитки tileFile = open ("levelMap.xml", " w ") tileFile.write ('\ n / n / n') iceHeight = randint (1, 10) для i в диапазоне (0, colAmount): tileFile.write ('') makeHole = False, если randint (0, 50) == 10 and i! = 0: # не допускать дыр в точке появления makeHole = True для j в диапазоне (0, rowAmount): if makeHole: tileFile.write ('\ n') else: if j <= iceHeight: tileFile.write ('\ n') else: tileFile.write ('\ n') iceHeight = randint (iceHeight-5, iceHeight + 5) if iceHeight <0: # ограничивает слишком низкое положение плиток iceHeight = randint (1, 5) if iceHeight> rowAmount: # ограничить слишком большое количество плиток iceHeight = randint (int (rowAmount / 2) -5, int (rowAmount / 2) +5) tileFile.write ('\ n') tileFile.write ('\ n / n') для i в диапазоне (0, colAmount): tileFile.write ('') для j в диапазоне (0, rowAmount): tileFile.write ('\ n') tileFile.write ('\ n ') tileFile.write (' / n / n ') tileFile.close ()

5692759 25
5692759 25

Шаг 11. Отобразите мозаичную карту

Импортируйте все из cocos.tiles, а затем перейдите в функцию startGame для этого.

  • В начале функции startGame сгенерируйте карту листов, используя функцию, которую вы для нее определили.
  • Создайте новый менеджер прокрутки. Сделайте это прямо под линией, где вы добавляете спрайт на его слой.
  • Создайте новый слой, содержащий тайлы, который будет загружен из тайловой карты levelMap.xml, созданной вашей функцией generateTilemap.
  • Добавьте нетвердый слой, сплошной слой и слой спрайта в диспетчер прокрутки точно в этом порядке. Вы можете добавить z-позицию, если хотите.
  • Вместо того, чтобы создавать сцену из слоя спрайтов, создайте ее из диспетчера прокрутки.
  • Ваша функция startGame теперь должна выглядеть так:

    def startGame (): generateTilemap () # fig = Sprite ('pingu.png') fig.position = (8, 500) figLayer = ScrollableLayer () figLayer.add (fig) # tileLayer = load ('levelMap.xml') solidTiles = tileLayer ['solid'] nsoliTiles = tileLayer ['not_solid'] # scrMang = ScrollingManager () scrMang.add (nsoliTiles, z = -1) scrMang.add (solidTiles, z = 0) scrMang.add (figLayer, z = 1) # gameSc = Scene (scrMang) Director.run (gameSc)

5692759 26
5692759 26

Шаг 12. Протестируйте свой код

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

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

5692759 27
5692759 27

Шаг 13. Добавьте элементы управления

У игрока есть гораздо больше способов взаимодействия с программой в 2D-игре, чем в текстовой игре. Обычный включает в себя перемещение фигуры при нажатии правильной клавиши.

  • Импортируйте все из cocos.mapcolliders и из cocos.actions. Также импортируйте ключ из pyglet.window.
  • «Объявить» какие-то глобальные переменные. Глобальные переменные распределяются между функциями. На самом деле вы не можете объявлять переменные в Python, но вы должны сказать, что глобальная переменная существует в основном коде, прежде чем использовать ее. Вы можете присвоить 0 как значение, потому что функция позаботится о присвоении правильного значения позже. Так что добавьте в выражения импорта:

    # "объявление" глобальных переменных keyboard = 0 scrMang = 0

  • Настройте функцию startGame:

    • Скажем, вы используете глобальные переменные keyboard и scrMang. Сделайте это, написав глобальную клавиатуру scrMang в верхней части функции.
    • Заставьте окно прослушивать события клавиатуры.
    • Скажите фигуре действовать на основе PlatformerController. Скоро вы реализуете этот PlatformerController.
    • Создайте коллайдер карты для обработки столкновений между твердыми плитками и фигурой.

    def startGame (): global keyboard, scrMang generateTilemap () # fig = Sprite ('pingu.png') fig.position = (8, 250) figLayer = ScrollableLayer () figLayer.add (fig) # tileLayer = load ('levelMap.xml ') solidTiles = tileLayer [' solid '] nsoliTiles = tileLayer [' not_solid '] # keyboard = key. KeyStateHandler () director.window.push_handlers (keyboard) # fig.do (PlatformerController ()) mapcollider = RectMapCollider (velocity_on_bump) = 'слайд') fig.collision_handler = make_collision_handler (mapcollider, solidTiles) # scrMang = ScrollingManager () scrMang.add (nsoliTiles, z = -1) scrMang.add (solidTiles, z = 0) scrMang.add (figLayer, z = 1) # gameSc = Scene (scrMang) Director.run (gameSc)

  • Создайте платформер-контроллер. Это то, что будет перемещать фигуру в соответствии с вашими нажатиями клавиш.

    • Определите контроллер платформеров как подкласс Action.
    • Определите скорость движения, скорость прыжка и силу тяжести.
    • Определите функцию запуска. Эта функция вызывается один раз при подключении к фигурке контроллера платформеров. Он должен установить скорость равной 0 как по оси x, так и по оси y.
    • Определите ступенчатую функцию. Это будет повторяться во время работы сцены.
    • Укажите пошаговой функции использовать глобальные переменные keyboard и scrMang.
    • Получите и измените скорость. Сохраните скорости x и y в отдельных переменных. Установите для скорости x значение 1 или -1 (в зависимости от того, была ли нажата левая или правая клавиша), умноженное на скорость движения. Добавьте гравитацию к скорости y. Умножьте это на время простоя, чтобы он работал так же на более медленных устройствах. Если нажата клавиша пробела и фигура стоит на земле, прыгайте, изменяя скорость y на скорость прыжка.
    • Рассчитайте, куда должна переместиться фигура. Затем позвольте обработчику столкновений отрегулировать это положение, если оно находится внутри твердой плитки. Наконец, переместите фигуру в новое отрегулированное положение.
    • Установите фокус диспетчера прокрутки на фигуру. Это заставляет камеру двигаться разумным образом при движении фигуры.

    class PlatformerController (Action): global keyboard, scrMang on_ground = True MOVE_SPEED = 300 JUMP_SPEED = 500 GRAVITY = -1200 def start (self): self.target.velocity = (0, 0) def step (self, dt): global keyboard, скроллер, если dt> 0.1: # ничего не делать во время простоя до большого return vx, vy = self.target.velocity vx = (keyboard [key. RIGHT] - keyboard [key. LEFT]) * self. MOVE_SPEED vy + = self. GRAVITY * dt, если self.on_ground и клавиатура [key. SPACE]: vy = self. JUMP_SPEED dx = vx * dt dy = vy * dt last = self.target.get_rect () new = last.copy () new.x + = dx new.y + = dy self.target.velocity = self.target.collision_handler (last, new, vx, vy) self.on_ground = (new.y == last.y) self.target.position = new.center scrMang.set_focus (* new.center)

5692759 28
5692759 28

Шаг 14. Протестируйте свой код

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

5692759 29
5692759 29

Шаг 15. Создайте концовку игры

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

  • Внутри контроллера платформер, после установки фокуса, получите координаты x и y фигуры. Если позиция y меньше 0, вызовите функцию finishGame () (вы напишете ее позже) с аргументом «Game Over». Если позиция по оси x больше, чем размер экрана, умноженный на 3 (раньше вы устанавливали это как размер уровня).

    posX, posY = self.target.position, если posY <0: finishGame ("Game Over") return if posX> 800 * 3: # level size finishGame ("Level Completed") return

  • Определите класс finishMenu. Он должен быть похож на класс главного меню, который вы определили ранее, но вместо пустой строки в качестве заголовка он должен использовать переменный текст, который функция _init_ принимает в качестве аргумента. Пункты меню должны быть помечены как «Повторить попытку» и «Выйти», но функции, которые они вызывают, останутся прежними.

    class FinishMenu (Menu): def _init _ (self, text): super (FinishMenu, self)._ init _ (text) self.menu_valign = CENTER self.menu_halign = CENTER menuItems = [(MenuItem («Попробовать снова», startGame)), (MenuItem ("Выйти", pyglet.app.exit))] self.create_menu (menuItems)

  • Определите функцию finishGame (). Он должен принимать текст в качестве аргумента. Он должен создать сцену из фона главного меню, FinishMenu с текстовым аргументом, передаваемым в это меню. Затем он должен запустить эту сцену.

    def finishGame (текст): menuSc = Scene (MainMenuBgr ()) menuSc.add (FinishMenu (текст)) Director.run (menuSc)

5692759 30
5692759 30

Шаг 16. Добавьте кредиты

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

  • Создайте файл CREDITS и введите туда все ваши кредиты, например:

    Пингвин: Кельвин Теньокрыл, под CC0 Ice block: Michał Banas digit1024 на opengameart.org под CC-BY-SA 3.0

  • Вернитесь к своему коду Python и импортируйте Label из cocos.text.
  • Определите подкласс Credits Layer. В его функции _init_ прочтите файл CREDITS и сделайте текстовую метку в правильной позиции из каждой строки в нем.

    class Credits (Layer): def _init _ (self): super (Credits, self)._ init _ () credFile = open ("CREDITS", "r") creds = credFile.read () creds = creds.split ("\ n ") для i в диапазоне (0, len (creds)): credLabel = Label (creds , font_size = 32, anchor_x =" left ", anchor_y =" top ") credLabel.position = 25, 500- (i +1) * 40 self.add (credLabel)

  • Перейдите в свой класс главного меню и добавьте пункт меню с надписью «Credits», который вызывает функцию showCredits при нажатии.
  • Определите подкласс BackToMainMenuButton из Menu. Сделайте это меню с одним элементом, помеченным «Назад», который вызывает функцию showMainMenu. Это «меню», которое больше похоже на кнопку, должно быть выровнено по вертикали снизу и по горизонтали вверху.

    class BackToMainMenuButton (Menu): def _init _ (self): super (BackToMainMenuButton, self)._ init _ ("") self.menu_valign = BOTTOM self.menu_halign = LEFT menuItems = [(MenuItem ("Back", show)] selfMenu. create_menu (menuItems)

  • Определите функцию showCredits. Он должен создать сцену из слоя MainMenuBgr и слоя Credits и запустить эту сцену.

    def showCredits (): credSc = Scene (MainMenuBgr ()) credSc.add (Credits ()) credSc.add (BackToMainMenuButton ()) Director.run (credSc)

5692759 31
5692759 31

Шаг 17. Проверьте свой код

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

    from cocos.director import * from cocos.menu import * from cocos.scene import * from cocos.layer import * from cocos.sprite import * from cocos.tiles import * from cocos.mapcolliders import * from cocos.actions import * from cocos.text import Label import pyglet.app from pyglet.window import key from math import ceil from random import randint # "объявление" глобальных переменных keyboard = 0 scrMang = 0 class MainMenuBgr (ColorLayer): def _init _ (self): super (MainMenuBgr, self)._ init _ (0, 200, 255, 255) class MainMenu (Menu): def _init _ (self): super (MainMenu, self)._ init _ ("") self.menu_valign = CENTER self.menu_halign = CENTER menuItems = [(MenuItem ("Начать игру", startGame)), (MenuItem ("Credits", showCredits)), (MenuItem ("Quit", pyglet.app.exit))] self.create_menu (menuItems) class Credits (Layer): def _init _ (self): super (Credits, self)._ init _ () credFile = open ("CREDITS", "r") creds = credFile.read () creds = creds.split ("\ n") для i в диапазоне (0, len (creds)): credLabel = Label (creds , font_size = 32, anchor_x = "left", anchor_y = "top") credLabel.position = 25, 500- (i + 1) * 40 self.add (credLabel) class BackToMainMenuButton (Menu): def _init _ (self): super (BackToMainMenuButton, self)._ init _ ("") self.menu_valign = BOTTOM self.menu_halign = LEFT menuItems = [(MenuItem ("Back", showMainMenu))] self.create_menu (menuItems) class FinishMenu (Menu): def _ self, text): super (FinishMenu, self)._ init _ (text) self.menu_valign = CENTER self.menu_halign = CENTER menuItems = [(MenuItem («Попробовать еще раз», startGame)), (MenuItem («Quit», pyglet. app.exit))] self.create_menu (menuItems) class PlatformerController (Action): global keyboard, scrMang on_ground = True MOVE_SPEED = 300 JUMP_SPEED = 500 GRAVITY = -1200 def start (self): self.target.velocity = (0, 0) def step (self, dt): global keyboard, scroller if dt> 0.1: # ничего не делать во время простоя слишком большое return vx, vy = self.target.velocity vx = (keyboard [key. RIGHT] - keyboard [key. LEFT]) * self. MOVE_SPEED vy + = self. GRAVITY * dt, если self.on _ground и клавиатура [key. SPACE]: vy = self. JUMP_SPEED dx = vx * dt dy = vy * dt last = self.target.get_rect () new = last.copy () new.x + = dx new.y + = dy self.target.velocity = self.target.collision_handler (last, new, vx, vy) self.on_ground = (new.y == last.y) self.target.position = new.center scrMang.set_focus (* new.center) posX, posY = self.target.position, если posY <0: finishGame ("Game Over") вернуть, если posX> 800 * 3: # размер уровня finishGame ("Level Completed") return def finishGame (text): menuSc = Scene (MainMenuBgr ()) menuSc.add (FinishMenu (text)) Director.run (menuSc) def showCredits (): credSc = Scene (MainMenuBgr ()) credSc.add (Credits ()) credSc.add (BackToMainMenuButton ()) Director.run (credSc) def generateTilemap (): colAmount = ceil (800/16) * 3 # (ширина экрана / размер плитки) * 3 rowAmount = ceil (600/16) # высота экрана / размер плитки tileFile = open ("levelMap.xml", "w") tileFile.write ('\ n / n / n') iceHeight = randint (1, 10) для i в диапазоне (0, colAmount): tileFile.write ('') makeHole = Ложь, если рандом int (0, 50) == 10 и i! = 0: # не допускать дыр в точке появления makeHole = True для j в диапазоне (0, rowAmount): if makeHole: tileFile.write ('\ n') else: if j <= iceHeight: tileFile.write ('\ n') else: tileFile.write ('\ n') iceHeight = randint (iceHeight-5, iceHeight + 5) if iceHeight <0: # ограничить перемещение плиток low iceHeight = randint (1, 5) if iceHeight> rowAmount: # ограничить слишком высокое значение тайлов iceHeight = randint (int (rowAmount / 2) -5, int (rowAmount / 2) +5) tileFile.write ('\ n ') tileFile.write (' / n / n ') для i в диапазоне (0, colAmount): tileFile.write (' ') для j в диапазоне (0, rowAmount): tileFile.write (' / n ') tileFile.write ('\ n') tileFile.write ('\ n / n') tileFile.close () def startGame (): глобальная клавиатура, scrMang generateTilemap () # fig = Sprite ('pingu.png') fig.position = (8, 250) figLayer = ScrollableLayer () figLayer.add (fig) # tileLayer = load ('levelMap.xml') solidTiles = tileLayer ['solid'] nsoliTiles = tileLayer ['not_solid'] # keyboard = key. KeyStateHandler () Director.window.push_handlers (keybo ard) # fig.do (PlatformerController ()) mapcollider = RectMapCollider (velocity_on_bump = 'slide') fig.collision_handler = make_collision_handler (mapcollider, solidTiles) # scrMang = ScrollingManager () scrMang.add (nsoli)Tilesr, nsoli. add (solidTiles, z = 0) scrMang.add (figLayer, z = 1) # gameSc = Scene (scrMang) Director.run (gameSc) def showMainMenu (): menuSc = Scene (MainMenuBgr ()) menuSc.add (MainMenu ()) Director.run (menuSc) window = Director.init (caption = "IcyPlat - простой платформер", resizable = True) showMainMenu ()

  • Всего это 168 строк и 152 строки, если вы только посчитаете код. Кажется, это много, но для такой сложной игры это на самом деле небольшая сумма.
5692759 32
5692759 32

Шаг 18. Готово

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

Часть 3 из 3: Публикация игры

5692759 52
5692759 52

Шаг 1. Запишите зависимости

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

5692759 53
5692759 53

Шаг 2. Убедитесь, что у вас есть разрешение на использование всех медиафайлов

Это относится ко всей графике, включая 3D-модели, музыку, диалоги, музыку, библиотеки и фреймворки, которые вы использовали для своей игры. Все, что вы не писали сами.

  • Часто есть некоторые условия, например, необходимость указывать автора или делиться модификациями носителя по той же лицензии. Иногда вы сможете использовать графику без указания авторов, если вы не взимаете плату за игру. Если вам нужно указать автора, сделайте это на хорошо видном месте, например, на вкладке «Авторы» в вашей игре.
  • Существуют также носители с заявленными авторскими правами и без указания лицензии, иногда с текстом вроде «Все права защищены». В этом случае вы должны получить явное разрешение от автора, прежде чем включать его в свою игру.
  • Библиотеки обычно выпускаются по лицензиям, которые позволяют использовать их в качестве библиотеки. Заметным исключением является GPL без исключения связи: такая лицензия позволяет использовать ее только в программе с определенными лицензиями. И вы всегда должны читать хотя бы основные положения лицензии, чтобы убедиться, что все, что вы делаете с носителем или библиотекой, разрешено.

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

5692759 54
5692759 54

Шаг 3. Определитесь с условиями, на которых вы хотите опубликовать свою игру

Вы будете продавать свою игру? Вы хотите, чтобы другие могли использовать ваши изображения и идеи? Хотя вы должны быть осторожны с носителями, которые вы используете в своем проекте, обычно вы можете решить, как вы хотите разрешить другим использовать вашу игру. Вы можете использовать лицензию Creative Commons CC0, чтобы выпустить свою игру в общественное достояние. Чтобы разрешить распространение и модификацию при определенных условиях с сохранением некоторых прав, попробуйте стандартную общественную лицензию Gnu (GPL) или лицензию Berkeley Software Distribution (BSD). Или вы можете сделать свое программное обеспечение несвободным, что означает, что никому не разрешается распространять или изменять его без вашего разрешения.

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

5692759 55
5692759 55

Шаг 4. Решите, как вы хотите опубликовать свою игру

У каждого метода есть свои преимущества и недостатки, поэтому решать вам придется самостоятельно.

  • Размещение на сайте:

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

  • Создание пакета для менеджера пакетов:

    Существуют различные менеджеры пакетов, такие как apt, Yum и Homebrew, которые упрощают установку приложений в средах Linux и Linux. Все они имеют разные форматы упаковки. Преимущество пакетов в том, что они автоматически устанавливают все зависимости (если вы их правильно настроили). Таким образом, игроку нужно только установить ваш пакет и затем начать игру. Проблема в том, что на разных платформах существует множество разных менеджеров пакетов, поэтому вам придется поработать над предоставлением пакетов для всех наиболее распространенных.

5692759 56
5692759 56

Шаг 5. Обратите внимание на вашу программу

Рассмотрите возможность загрузки вашей программы в крупный репозиторий пакетов, например те, которые поддерживаются Ubuntu и Debian, чтобы упростить установку. Также размещайте сообщения на соответствующих форумах, например, в разделе проектов GameDev или в составе tigSource. Но не огорчайтесь, если ваши первые игры не станут знаменитыми. Если у вас есть представление, что она нравится многим, ваша игра может стать широко известной.

подсказки

  • Будьте терпеливы и готовы учиться. Иногда программирование может утомлять!
  • Если вам интересно, как что-то сделано в другой игре, и игра имеет открытый исходный код, вы можете посмотреть ее исходный код.
  • При поиске медиа постарайтесь найти контент, который находится в общественном достоянии. Ищите изображения и музыку «Creative Commons» или «Public Domain» и используйте такие веб-сайты, как https://opengameart.org или
  • Не копируйте основные фрагменты кода без проверки лицензии. Часто это запрещено, а если нет, то обычно требует указания авторства.
  • При продвижении игры не рассылайте спам и не размещайте посты в неподходящих местах. Это может заблокировать вас на странице, просто раздражает и навредит вашей репутации.

Рекомендуемые: