Русский
Русский
English
Статистика
Реклама

Разработка игр

Перевод Портируем Quake 3 на Rust

14.06.2021 20:18:14 | Автор: admin


Команда поклонников Rust сайта Immutant усердно трудилась над C2Rust, фреймворком для миграции программ, который существенно упрощает их перевод на Rust. Мы стремились везде, где можем, добиться автоматической оптимизации безопасности получаемого кода Rust. В иных случаях делали этот процесс простым для самостоятельной реализации программистами в дальнейшем. Однако для начала потребовалось создать надежное средство переноса, которое позволит людям свободно использовать Rust.

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

Подготовка: исходники Quake 3


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

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

$ make release

Сборка ioquake3 создает несколько библиотек и исполняемых файлов:

$ tree --prune -I missionpack -P "*.so|*x86_64". build     debug-linux-x86_64         baseq3            cgamex86_64.so          # клиент             qagamex86_64.so         # игровой сервер            uix86_64.so             # ui         ioq3ded.x86_64              # исполняемый файл выделенного сервера         ioquake3.x86_64             # основной исполняемый файл         renderer_opengl1_x86_64.so  # модуль рендеринга opengl1         renderer_opengl2_x86_64.so  # модуль рендеринга opengl2

Клиентскую, серверную и UI библиотеки можно собрать в виде Quake VM либо как нативные общие библиотеки x86. Мы предпочли второй вариант. Переносить VM на Rust и использовать версии QVM было бы существенно проще, но задачей было протестировать C2Rust максимально тщательно.

Сосредоточились мы на UI, игровом сервере, клиенте, модуле рендеринга OpenGL1 и основном исполняемом файле. Можно было также перевести модуль OpenGL2, но мы решили его не трогать, так как он активно использует файлы шейдеров .glsl, которые система сборки включает в исходники Си в виде строковых литералов. Конечно, можно было добавить поддержку скрипта кастомной сборки для встраивания кода GLSL в строки Rust после транспиляции, но нас остановило отсутствие надежного автоматического способа транспилировать эти автогенерируемые временные файлы.

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

Транспиляция


Чтобы сохранить используемую в Quake 3 структуру каталогов и не прибегать к изменению ее исходного кода, нужно было создать в точности такие же двоичные файлы, что и в нативной сборке, то есть четыре общие библиотеки и один двоичный файл. Поскольку C2Rust использует для сборки файлов Cargo, каждому исполняемому файлу требуется собственный контейнер Rust с соответствующим файлом Cargo.toml. Чтобы C2Rust на выходе создал для каждого исполняемого файла контейнер, ему нужно предоставить список двоичных файлов вместе с соответствующими им объектными или исходными файлами, а также вызов компоновщика, определяющего прочие детали, такие как зависимости.

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

В большинстве инструментов, создающих такую базу данных, подобное ограничение присутствует преднамеренно, например cmake с CMAKE_EXPORT_COMPILE_COMMANDS, bear и compiledb. Насколько нам известно, единственным инструментом, включающим команды компоновки, является build-logger из CodeChecker, который мы не задействовали только потому, что узнали о нем после написания собственных оберток (приводятся ниже). Это означало невозможность использовать файл compile_commands.json, создаваемый любым типовым инструментом для транспиляции мультибинарной программы Си.

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

$ make release

Мы добавили обертки для перехвата процесса сборки:

$ make release CC=/path/to/C2Rust/scripts/cc-wrappers/cc

Обертки создают каталог с файлами JSON, по одному файлу за вызов. Второй скрипт агрегирует все эти файлы в новый compile_commands.json, который содержит уже и команды компиляции, и команды сборки. Мы расширили C2Rust для считывания компонующих команд из базы данных и создания отдельного контейнера для каждого связанного двоичного файла. Кроме того, теперь C2Rust считывает зависимости каждого исполняемого файла и автоматически добавляет их в файл build.rs его контейнера.

В качестве облегчения процесса все исполняемые файлы можно собрать за раз, если они будут находиться в одном рабочем пространстве. C2Rust производит высокоуровневый файл рабочего пространства Cargo.toml, позволяя собирать проект одной командой cargo build в каталоге quake3-rs:

$ tree -L 1. Cargo.lock Cargo.toml cgamex86_64 ioquake3 qagamex86_64 renderer_opengl1_x86_64 rust-toolchain uix86_64$ cargo build --release

Исправление недочетов


При первой попытке собрать переносимый код возникла пара проблем с исходниками Quake 3, которые C2Rust не мог корректно обработать или не обрабатывал совсем.

Указатели на массивы


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

int array[1024];int *p;// ...if (p >= &array[1024]) {   // error...}

Стандарт Си (загляните, например, в C11, Section 6.5.6) допускает указатели на элемент, выходящий за границу массива. Проблема же в том, что Rust это запрещает даже при получении только адреса элемента. Примеры этого шаблона мы нашли в функции AAS_TraceClientBBox.

Компилятор Rust также отметил похожий, но уже действительно ошибочный пример в G_TryPushingEntity, где условие представлено как >, а не >=. После этого условия выходящий за границы указатель разыменовывался, что являлось реальной ошибкой безопасности памяти.

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

Члены динамических массивов


На первый проверочный запуск игры Rust отреагировал паникой:

thread 'main' panicked at 'index out of bounds: the len is 4 but the index is 4', quake3-client/src/cm_polylib.rs:973:17

Заглянув в cm_polylib.c, мы заметили разыменовывание поля p в следующей структуре:

typedef struct{intnumpoints;vec3_tp[4];// переменный размер} winding_t;

Поле p здесь это более ранняя несовместимая с C99 версия члена массива переменной длины, которая до сих пор принимается gcc. C2Rust распознает членов динамических массивов с синтаксисом С99 (vec3_t p[]) и реализует простую эвристику для попутного обнаружения более ранних версий этого шаблона (массивов с размером 0 и 1 в конце структур; в исходниках ioquake3 мы нашли несколько таких).

Панику удалось устранить, изменив вышеприведенную структуру на синтаксис C99:

typedef struct{intnumpoints;vec3_tp[];// переменный размер} winding_t;

Реализация автоматического исправления этого шаблона для общих случаев (массивы с размером не 0 или 1) оказалась бы слишком сложной, поскольку пришлось бы различать членов стандартных массивов от членов массивов с произвольными размерами. Вместо этого мы рекомендуем корректировать исходный код Си вручную как сделали сами в случае с ioquake3.

Связанные операнды во встроенном ассемблере


Еще одним источником сбоев был встроенный в Си код ассемблера из системного заголовка /usr/include/bits/select.h:

# define __FD_ZERO(fdsp)                                            \  do {                                                              \    int __d0, __d1;                                                 \    __asm__ __volatile__ ("cld; rep; " __FD_ZERO_STOS               \                          : "=c" (__d0), "=D" (__d1)                \                          : "a" (0), "0" (sizeof (fd_set)           \                                          / sizeof (__fd_mask)),    \                            "1" (&__FDS_BITS (fdsp)[0])             \                          : "memory");                              \  } while (0)

Он определяет внутреннюю версию макроса __FD_ZERO. Это определение вызывает редкий граничный случай встроенного ассемблерного кода gcc: связанные входные/выходные операнды разного размера.

Выходной операнд =D (_d1) привязывает регистр edi к переменной _d1 в качестве 32-битного значения, в то время как 1 (&__FDS_BITS (fdsp)[0]) привязывает тот же регистр к адресу fdsp->fds_bits в качестве 64-битного указателя. gcc и clang исправляют это несоответствие, взамен используя 64-битный регистр rdi и затем усекая его значение перед присваиванием к _d1. Rust же по умолчанию использует семантику LLVM, которая оставляет этот случай неопределенным. В отладочных сборках (не релизных, которые работали корректно) оба операнда присваивались регистру edi, обуславливая преждевременное усечение указателя до 32 бит еще до достижения встроенного кода ассемблера, что и вызывало сбои.

Поскольку rustc передает встроенный ассемблерный код Rust в LLVM с минимальными изменениями, мы решили исправить этот частный случай в C2Rust. Для этого мы реализовали новый контейнер c2rust-asm-casts, корректирующий проблему через систему типов Rust с помощью типажа (trait) и вспомогательных функций, которые автоматически расширяют и усекают значения связанных операндов до внутреннего размера, достаточного для хранения обоих операндов.

Вышеприведенный код корректно транспилируется в следующее:

let mut __d0: c_int = 0;let mut __d1: c_int = 0;// Ссылка на выходное значение первого операндаlet fresh5 = &mut __d0;// Внутреннее хранилище для первого связанного операндаlet fresh6;// Ссылка на выходное значение второго операндаlet fresh7 = &mut __d1;// Внутреннее хранилище для второго операндаlet fresh8;// Входное значение первого операндаlet fresh9 = (::std::mem::size_of::<fd_set>() as c_ulong).wrapping_div(::std::mem::size_of::<__fd_mask>() as c_ulong);// Входное значение второго операндаlet fresh10 = &mut *fdset.__fds_bits.as_mut_ptr().offset(0) as *mut __fd_mask;asm!("cld; rep; stosq"     : "={cx}" (fresh6), "={di}" (fresh8)     : "{ax}" (0),       // Приведение входных операндов к внутреннему типу хранилища       // с дополнительным нулевым или знаковым расширением       "0" (AsmCast::cast_in(fresh5, fresh9)),       "1" (AsmCast::cast_in(fresh7, fresh10))     : "memory"     : "volatile");// Приведение операндов к внешнему типу (с выведением типов) и усечениеAsmCast::cast_out(fresh5, fresh9, fresh6);AsmCast::cast_out(fresh7, fresh10, fresh8);

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

Выравнивание глобальных переменных


Последним источником сбоев была следующая глобальная переменная, где хранится константа SSE:
static unsigned char ssemask[16] __attribute__((aligned(16))) ={"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00"};

На данный момент Rust поддерживает атрибут выравнивания для типов структур, но не глобальных переменных, то есть элементов static. Мы продолжаем искать универсальный способ решения этой проблемы в Rust или C2Rust, но для ioquake3 пока что решили ее вручную с помощью небольшого патча. Этот патч заменяет Rust-эквивалент ssemask на:

#[repr(C, align(16))]struct SseMask([u8; 16]);static mut ssemask: SseMask = SseMask([    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0,]);

Запуск quake3-rs


Выполнение cargo build --release генерирует двоичные файлы, но все они генерируются в target/release с использованием структуры каталогов, не распознаваемой бинарником ioquake3. Мы написали скрипт, который создает символические ссылки на текущую директорию, чтобы дублировать верную структуру каталогов (включая ссылки на файлы .pk3, содержащие ресурсы игры):

$ /path/to/make_quake3_rs_links.sh /path/to/quake3-rs/target/release /path/to/paks

Путь /path/to/paks должен указывать на каталог, содержащий файлы .pk3.

Ну а теперь пора запускать игру! При запуске нужно передать команду +set vm_game 0 и пр., чтобы загрузить эти модули как общие библиотеки Rust, а не ассемблерный код QVM, а также команду cl_renderer, чтобы использовать OpenGL1.

$ ./ioquake3 +set sv_pure 0 +set vm_game 0 +set vm_cgame 0 +set vm_ui 0 +set cl_renderer "opengl1"

Иии



Перед нами рабочая Rust-версия Quake3!



Вот видео, в котором мы транспилируем игру, загружаем ее и недолго тестируем игровой процесс:


Транспилированный исходный код лежит в ветке transpiled нашего репозитория. Там также есть ветка refactored, содержащая те же файлы, но уже с примененными командами рефакторинга.

Инструкции по транспиляции


Если вы захотите повторить аналогичный процесс переноса и запуска Quake 3, то имейте в виду, что вам понадобятся либо оригинальные ресурсы игры, либо скачанные из интернета демоверсии таких ресурсов. Помимо этого, потребуется установить C2Rust (минимальная необходимая ночная версия Rust на момент написания это nightly-2019-12-05, но мы рекомендуем заглянуть в репозиторий C2Rust или на сайт crates.io на предмет наличия последней):

$ cargo +nightly-2019-12-05 install c2rust

а также копии репозиториев C2Rust и ioquake3:

$ git clone git@github.com:immunant/c2rust.git$ git clone git@github.com:immunant/ioq3.git

В качестве альтернативы установке c2rust вышеприведенной командой вы можете собрать C2Rust вручную с помощью cargo build --release. В обоих случаях вам все равно потребуется репозиторий C2Rust, так как там находятся скрипты оберток компилятора, необходимые для транспиляции ioquake3.

Мы предоставляем скрипт, который автоматически транспилирует код Си и применяет патч ssemask. Чтобы его использовать, выполните из верхнего уровня репозитория ioq3следующую команду:

$ ./transpile.sh </path/to/C2Rust repository> </path/to/c2rust binary>

Эта команда должна создать подкаталог quake3-rs, содержащий код Rust, где можно будет последовательно выполнять cargo build --release и остальные ранее описанные шаги.


Подробнее..

SpaceShooter на Phaser 3

17.06.2021 14:15:17 | Автор: admin

Здравствуйте! Это перевод курса (ссылка на оригинал в конце статьи), который охватывает создание космического шутера с помощью Phaser 3. Курс будет состоять из 5 частей, в каждой из которых будет решаться определенная задача при создании проекта. Перед началом прохождения курса желательно знать основы JavaScript.

Шаг первый. Настроить веб-сервер

Первое, что необходимо сделать, это настроить веб-сервер. Несмотря на то, что фазерные игры запускаются в браузере, к сожалению нельзя просто запустить локально html-файл непосредственно из файловой системы. При запросе файлов по протоколу http, безопасность сервера позволяет получить доступ только к тем файлам, которые вам разрешены. При загрузке файла из локальной файловой системы (file://) ваш браузер сильно ограничивает его по очевидным причинам безопасности. Из-за этого нам нужно будет разместить нашу игру на локальном веб-сервере. Вы можете использовать любой удобный для вас веб-сервер, будь то OpenServer или какой-либо другой.

Шаг второй. Создать необходимы файлы и папки

Найдите где ваш веб-вервер размещает файлы сайтов и создайте в нём папку с вашим проектом. Назовите его как вам будет удобно. Внутри проекта создайте файл index.html. Наш индексный файл - это место, где объявим местоположение фазерного скрипта и остальных игровых скриптов.

Далее нам нужно создать две новые папки: content (спрайты, аудио и др.) и js (фазерные и игровые скрипты). Теперь внутри папки js нужно создать 4 файла: SceneMainMenu.js, SceneMain.js, SceneGameOver.js, и game.js.

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

структура проекта в начале работыструктура проекта в начале работы

Теперь нужно загрузить контент для нашего проекта в папку content. Вы можете создать и загрузить свои собственные файла, либо воспользоваться готовыми (здесь).

Необходимый контент:

Sprites (images)

  • sprBtnPlay.png (Кнопка "Play")

  • sprBtnPlayHover.png (Кнопка "Play" когда мышь наведена)

  • sprBtnPlayDown.png (Кнопка "Play" когда кнопка нажата)

  • sprBtnRestart.png (Кнопка "Restart")

  • sprBtnRestartHover.png (Кнопка "Restart" когда мышь наведена)

  • sprBtnRestartDown (Кнопка "Restart" когда кнопка нажата)

  • sprBg0.png (фоновый слой звезд с прозрачностью вокруг звезд)

  • sprBg1.png (еще один фоновый слой звезд)

  • sprEnemy0.png (первый анимированный враг)

  • sprEnemy1.png (второй не анимированный враг)

  • sprEnemy2.png (третий анимированный враг)

  • sprLaserEnemy.png (выстрел лазера врагом)

  • sprLaserPlayer.png (выстрел лазера игроком)

  • sprExplosion.png (анимация взрыва)

  • sprPlayer.png (спрайт игрока)

Audio (.wav files)

  • sndExplode0.wav (первый звук взрыва)

  • sndExplode1.wav (второй звук взрыва)

  • sndLaser.wav (звук выстрела лазера)

  • sndBtnOver.wav (звук наведения мышки на кнопку)

  • sndBtnDown.wav (звук нажатия на кнопку)

Шаг третий. Загрузка фреймворка

Теперь необходимо загрузить актуальную версию самого Phaser. Это можно сделать здесь. В своем проекте вы можете использовать из phaser.js или phaser.min.js файл. Разница в том, что phaser.js имеет более удобный формат для чтения, но он и больше весит. Если вы не собираетесь вносить, какие-либо изменения в исходный код библиотеки, то можно использовать phaser.min.js. Он предназначен для распространения и сжимается для уменьшения размера файла. Загрузите файл в нашу папку js в проекте.

Шаг четвертый. Index.html

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

Откройте index.html и введите следующий код:

<!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <meta lang="en-us">    <title>Space Shooter</title>    <script src="js/phaser.js"></script> <!-- название файла должно соответствовать тому, который вы решили использовать. -->  </head>  <body>    <script src="js/Entities.js"></script>    <script src="js/SceneMainMenu.js"></script>    <script src="js/SceneMain.js"></script>    <script src="js/SceneGameOver.js"></script>    <script src="js/game.js"></script>  </body></html>

Обратите внимание на порядок подключения скриптов. Порядок очень важен, так как JavaScript интерпретируется сверху вниз. Мы будем ссылаться на код из файлов сцен (с приставкой Scene) в файле game.js.

Шаг пятый. Инициализация игры

Откройте game.js и создайте объект следующим образом:

var config = {}

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

type: Phaser.WEBGL,width: 480,height: 640,backgroundColor: "black",physics: {  default: "arcade",  arcade: {    gravity: { x: 0, y: 0 }  }},scene: [],pixelArt: true,roundPixels: true

Пока что, внутри нашего объекта конфигурации, мы говорим нашей игре, что она должна визуализироваться с помощью WebGL, а не с помощью обычной технологии рендеринга Canvas. Далее, параметры width и height, устанавливают ширину и высоту нашей игры, которые будет занимать наша игра на странице. Свойство backgroundColor устанавливает черный цвет фона. Следующее свойство, physics, определяет физический движок, который будет использоваться, а именно arcade. Аркадная физика хорошо работает, когда нам нужно базовое обнаружение столкновений без каких-либо особенностей. Внутри physics, мы также устанавливаем гравитацию (gravity) для нашего физического мира. Следующее свойство scene, мы определяем массивом, который заполним немного позже. Наконец, мы хотим, чтобы Phaser обеспечивал четкость пикселей (pixelArt и roundPixels) точно так же, как ностальгические видеоигры, которые мы знали и полюбили.

scene: [  SceneMainMenu,  SceneMain,  SceneGameOver],

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

var game = new Phaser.Game(config);

Файл game.js завершен! В итоге он должен выглядеть следующим образом:

var config = {    type: Phaser.WEBGL,    width: 480,    height: 640,    backgroundColor: "black",    physics: {      default: "arcade",      arcade: {        gravity: { x: 0, y: 0 }      }    },    scene: [        SceneMainMenu,        SceneMain,        SceneGameOver    ],    pixelArt: true,    roundPixels: true}var game = new Phaser.Game(config);

Шаг шестой. Создание классов сцен

Давайте откроем SceneMainMenu.js и добавим в него следующий код:

class SceneMainMenu extends Phaser.Scene {  constructor() {    super({ key: "SceneMainMenu" });  }  create() {    this.scene.start("SceneMain");  }}

Здесь мы объявляем класс SceneMainMenu, который расширяет Phaser.Scene. Внутри данного класса есть две функции: constructor и create. Конструктор вызывается немедленно, при создании класса (подробнее с этим вы можете ознакомиться изучив принципы ООП). Внутри конструктора мы выполняется одна строчка кода:

super({ key: "SceneMainMenu" });

что фактически означает:

var someScene = new Phaser.Scene({ key: "SceneMainMenu" });

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

this.scene.start("SceneMain");

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

Теперь надо закончить оставшиеся классы в файлах SceneMain.js и SceneGameOver.js.

SceneMain.js:

class SceneMain extends Phaser.Scene {  constructor() {    super({ key: "SceneMain" });  }  create() {}}

SceneGameOver.js:

class SceneGameOver extends Phaser.Scene {  constructor() {    super({ key: "SceneGameOver" });  }  create() {}}

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

Шаг седьмой. Загрузка игровых ресурсов

На этом шаге, в классе SceneMain нам нужно добавить новую функцию под названием preload. Эта функция должна быть размещена между функциями constructor и create. Теперь класс должен выглядеть следующим образом:

class SceneMain extends Phaser.Scene {  constructor() {    super({ key: "SceneMain" });  }  preload() {    }  create() {    }}

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

this.load.image("sprBg0", "content/sprBg0.png");

Где первый параметр это imageKey. По нему далее в коде мы будем обращаться к загруженной картинке. А второй параметр - это путь к месту, где лежит файл изображения. Давайте загрузим остальные изображения, которые пригодятся нам для создания игры. После загрузки всех изображений, функция preload будет выглядеть следующим образом:

preload() {  this.load.image("sprBg0", "content/sprBg0.png");  this.load.image("sprBg1", "content/sprBg1.png");  this.load.spritesheet("sprExplosion", "content/sprExplosion.png", {    frameWidth: 32,    frameHeight: 32  });  this.load.spritesheet("sprEnemy0", "content/sprEnemy0.png", {    frameWidth: 16,    frameHeight: 16  });  this.load.image("sprEnemy1", "content/sprEnemy1.png");  this.load.spritesheet("sprEnemy2", "content/sprEnemy2.png", {    frameWidth: 16,    frameHeight: 16  });  this.load.image("sprLaserEnemy0", "content/sprLaserEnemy0.png");  this.load.image("sprLaserPlayer", "content/sprLaserPlayer.png");  this.load.spritesheet("sprPlayer", "content/sprPlayer.png", {    frameWidth: 16,    frameHeight: 16  });}

Обратите внимание, что в некоторых местах мы загружаем не image, а spritesheet. Это означает, что мы загружаем анимацию, а не статическое изображение. Spritesheet - это изображение с несколькими кадрами, расположенными бок о бок. Также в spritesheet мы определяем третьим аргументом ширину и высоту кадра в пикселях.

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

this.load.audio("sndExplode0", "content/sndExplode0.wav");this.load.audio("sndExplode1", "content/sndExplode1.wav");this.load.audio("sndLaser", "content/sndLaser.wav");

Шаг восьмой. Немного кода для анимации.

После того, как мы загрузили контент, нам нужно добавить немного больше кода для создания анимации. Теперь в функции create() класса SceneMain создадим анимации:

this.anims.create({  key: "sprEnemy0",  frames: this.anims.generateFrameNumbers("sprEnemy0"),  frameRate: 20,  repeat: -1});this.anims.create({  key: "sprEnemy2",  frames: this.anims.generateFrameNumbers("sprEnemy2"),  frameRate: 20,  repeat: -1});this.anims.create({  key: "sprExplosion",  frames: this.anims.generateFrameNumbers("sprExplosion"),  frameRate: 20,  repeat: 0});this.anims.create({  key: "sprPlayer",  frames: this.anims.generateFrameNumbers("sprPlayer"),  frameRate: 20,  repeat: -1});

Нам также нужно добавить звуки к какой-то переменной или объекту, чтобы мы могли ссылаться на него позже. Если существует более одного звука (скажем, три звука взрыва), я добавляю массив в качестве значения свойства explosions. Давайте добавим объект звукового эффекта:

this.sfx = {  explosions: [    this.sound.add("sndExplode0"),    this.sound.add("sndExplode1")  ],  laser: this.sound.add("sndLaser")};

Позже мы сможем воспроизводить звуковые эффекты с нашего объекта, например:

this.scene.sfx.laser.play();

Нам также придется загрузить некоторые изображения и звуки для главного меню и экрана Game Over. Открывайте SceneMainMenu.js и создайте функцию предварительной загрузки (preload()) внутри класса SceneMainMenu. Внутри новой функции предварительной загрузки добавьте следующее, чтобы добавить наши кнопки и звуки:

Теперь мы можем вернуться к игре в браузере, и черный прямоугольник все еще должен отображаться. Откройте инструменты разработки в браузере, который вы используете. Если вы используете Chrome или Firefox, вы можете просто нажать F12, чтобы открыть его. Посмотрите во вкладке Консоли (Console), чтобы убедиться в отсутствии ошибок (они отображаются красным цветом.) Если вы не видите ошибок, мы можем приступить к добавлению игрока!

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

Прежде чем добавить космический корабль игрока в игру, мы должны добавить новый файл в нашу папку js под названием Entities.js. Этот файл будет содержать все классы для различных сущностей в нашей игре. Мы будем классифицировать игрока, врагов, лазеры и т. д., как сущности. Обязательно также добавьте ссылку на Entities.js в index.html перед SceneMainMenu.js. После этого откройте файл и объявите новый класс с именем Entity.

class Entity {constructor(scene, x, y, key, type) {}}

Как вы можете увидеть, мы сразу определяем параметры которые будет принимать конструктор класса. Каждый из параметров, которые мы добавили в конструктор, будет важен, потому что мы будем расширять класс для всех сущностей, которые мы создадим. Очень похоже на то, как мы расширили Phaser.Scene когда мы начали эту игру. Теперь мы расширим класс Entity:

class Entity extends Phaser.GameObjects.Sprite

Как всегда при расширении класса, нам нужно будет добавить super в наш конструктор. Поскольку игрок, враги и различные снаряды, которые мы добавляем, будут иметь одни и те же базовые свойства, это помогает нам не добавлять избыточный, дублирующий код. Таким образом, мы унаследуем свойства и функции базового класса Phaser.GameObjects.Sprite для всех наших сущностей.

Все наши сущности будут иметь одинаковые базовые свойства (scene, x, y, key и type, которую мы будем использовать для извлечения определенных сущностей, если нам это понадобится.) Давайте добавим super в наш конструктор, который должен выглядеть следующим образом:

super(scene, x, y, key);

После добавления ключевого слова super в конструктор на следующей строке добавьте строки:

this.scene = scene;this.scene.add.existing(this);this.scene.physics.world.enableBody(this, 0);this.setData("type", type);this.setData("isDead", false);

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

К настоящему времени вы должны знать, как добавить класс. Добавьте его сразу после класса Entity и назовите его Player и убедитесь, что он расширяет Entity. Добавьте конструктор в класс Player с параметрами: scene, x, y и key. Затем добавьте ключевое слово super в конструктор, предоставив ему следующие параметры:

super(scene, x, y, key, "Player");

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

this.setData("speed", 200);

Мы также хотим добавить небольшой фрагмент кода для воспроизведения анимации игрока:

this.play("sprPlayer");

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

moveUp() {  this.body.velocity.y = -this.getData("speed");}moveDown() {  this.body.velocity.y = this.getData("speed");}moveLeft() {  this.body.velocity.x = -this.getData("speed");}moveRight() {  this.body.velocity.x = this.getData("speed");}

Эти функции позволяют перемещаться игроку с установленной скоростью на экране по координатам x и y.

Эти функции будут вызваны в функции update(). Добавьте функцию update() непосредственно под функцией moveRight. Внутри функции обновления пропишите:

this.body.setVelocity(0, 0);this.x = Phaser.Math.Clamp(this.x, 0, this.scene.game.config.width);this.y = Phaser.Math.Clamp(this.y, 0, this.scene.game.config.height);

Теперь мы закончили с классом игрока! В данном случае скорость игрока будет равна нулю. Если ни одна из клавиш перемещения не нажата, игрок останется неподвижным. Следующие две строки кода обновления игрока гарантируют, что игрок не сможет выйти за пределы экрана. На этом этапе мы можем создать экземпляр игрока в функции create главной сцены. Добавьте следующее в функцию создания главной сцены:

this.player = new Player(  this,  this.game.config.width * 0.5,  this.game.config.height * 0.5,  "sprPlayer");

Именно здесь мы создаем экземпляр игрока. Мы можем обратиться к игроку в любом месте SceneMain. Затем игрок располагается в центре холста. Если вы попытаетесь запустить игру, вы все равно не увидите, как игрок двигается. Это происходит потому, что сначала мы должны добавить функцию обновления в SceneMain и добавить проверки движения. Поскольку this.player теперь добавлен, теперь мы можем добавить функцию обновления. Добавьте функцию обновления прямо под функцией создания главной сцены и добавьте внутрь следующее:

this.player.update();if (this.keyW.isDown) {  this.player.moveUp();}else if (this.keyS.isDown) {  this.player.moveDown();}if (this.keyA.isDown) {  this.player.moveLeft();}else if (this.keyD.isDown) {  this.player.moveRight();}

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

this.keyW = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W);this.keyS = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S);this.keyA = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A);this.keyD = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D);this.keySpace = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);

Если мы запустим наш код сейчас, игрок должен иметь возможность перемещаться с помощью клавиш W, S, A, D. В следующей части мы добавим возможность для игрока стрелять лазерами (которые будут использовать клавишу пробела.)

Шаг десятый. Добавление врагов

Давайте теперь откроем Entities.js и добавим классы врагов. В самом низу Entities.js под классом игрока добавьте три новых класса, называемых ChaserShip, GunShip и CarrierShip:

class ChaserShip extends Entity {  constructor(scene, x, y) {    super(scene, x, y, "sprEnemy1", "ChaserShip");  }}class GunShip extends Entity {  constructor(scene, x, y) {    super(scene, x, y, "sprEnemy0", "GunShip");    this.play("sprEnemy0");  }}class CarrierShip extends Entity {  constructor(scene, x, y) {    super(scene, x, y, "sprEnemy2", "CarrierShip");    this.play("sprEnemy2");  }}

Классы ChaserShip, GunShip и CarrierShip должны расширить класс Entity, который мы создали ранее. Затем мы вызываем конструктор с соответствующими параметрами. Для каждого класса врагов под ключевым словом super добавьте следующее:

this.body.velocity.y = Phaser.Math.Between(50, 100);

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

Затем вернитесь к SceneMain.js. Нам нужно будет создать группу, чтобы удерживать наших врагов, лазеры, стреляющие врагами, и лазеры, стреляющие игроком. В функции create после установки строки this.keySpace добавьте:

this.enemies = this.add.group();this.enemyLasers = this.add.group();this.playerLasers = this.add.group();

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

this.time.addEvent({  delay: 100,  callback: function() {    var enemy = new GunShip(      this,      Phaser.Math.Between(0, this.game.config.width),      0    );    this.enemies.add(enemy);  },  callbackScope: this,  loop: true});

Если мы попробуем запустить игру сейчас, то увидим множество врагов-боевых кораблей, движущихся вниз. Теперь мы дадим нашим противникам возможность стрелять. Во-первых, мы должны создать еще один класс под названием EnemyLaser сразу после класса игрока. Откройте Entities.js. Вражеский лазер также должен расширить класс Entity.

class EnemyLaser extends Entity {  constructor(scene, x, y) {    super(scene, x, y, "sprLaserEnemy0");    this.body.velocity.y = 200;  }}

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

this.shootTimer = this.scene.time.addEvent({  delay: 1000,  callback: function() {    var laser = new EnemyLaser(      this.scene,      this.x,      this.y    );    laser.setScale(this.scaleX);    this.scene.enemyLasers.add(laser);  },  callbackScope: this,  loop: true});

Обратите внимание, что мы присваиваем описанное выше событие переменной this.shootTimer. Мы должны создать новую функцию внутри GunShip под названием onDestroy. onDestroy - это не функция, используемая Phaser, поэтому вы можете назвать ее как угодно. Мы будем использовать эту функцию, чтобы уничтожить таймер стрельбы, когда враг будет уничтожен. Добавьте функцию onDestroy в наш класс GunShip и добавьте внутрь следующее:

if (this.shootTimer !== undefined) {  if (this.shootTimer) {    this.shootTimer.remove(false);  }}

Когда вы запустите игру вы должны увидеть:

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

delay: 1000,

Теперь вернитесь обратно в Entities.js, нам нужно будет добавить немного кода в конструктор класса ChaserShip:

this.states = {  MOVE_DOWN: "MOVE_DOWN",  CHASE: "CHASE"};this.state = this.states.MOVE_DOWN;

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

Теперь мы можем добавить функцию обновления в класс ChaserShip. Функция обновления - это то, где мы будем кодировать ИИ для класса корабля-охотника. Сначала мы закодируем разведданные для вражеского истребителя, так как это немного сложнее. Перейдите обратно к Entities.js, а в функции обновления класса ChaserShip добавьте следующее:

if (!this.getData("isDead") && this.scene.player) {  if (Phaser.Math.Distance.Between(    this.x,    this.y,    this.scene.player.x,  this.scene.player.y  ) < 320) {    this.state = this.states.CHASE;  }  if (this.state == this.states.CHASE) {    var dx = this.scene.player.x - this.x;    var dy = this.scene.player.y - this.y;    var angle = Math.atan2(dy, dx);    var speed = 100;    this.body.setVelocity(      Math.cos(angle) * speed,      Math.sin(angle) * speed    );  }}

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

if (this.x < this.scene.player.x) {  this.angle -= 5;} else {  this.angle += 5;} 

Чтобы породить корабль-охотник, нам придется вернуться на SceneMain.js и добавьте новую функцию под названием getEnemiesByType. Внутри этой новой функции добавьте:

getEnemiesByType(type) {  var arr = [];  for (var i = 0; i < this.enemies.getChildren().length; i++) {    var enemy = this.enemies.getChildren()[i];    if (enemy.getData("type") == type) {      arr.push(enemy);    }  }  return arr;}

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

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

на:

var enemy = null;if (Phaser.Math.Between(0, 10) >= 3) {  enemy = new GunShip(  this,  Phaser.Math.Between(0, this.game.config.width),0);} else if (Phaser.Math.Between(0, 10) >= 5) {  if (this.getEnemiesByType("ChaserShip").length < 5) {    enemy = new ChaserShip(    this,    Phaser.Math.Between(0, this.game.config.width),0);}} else {  enemy = new CarrierShip(  this,  Phaser.Math.Between(0, this.game.config.width),0);}if (enemy !== null) {  enemy.setScale(Phaser.Math.Between(10, 20) * 0.1);this.enemies.add(enemy);}

Проходя через этот блок, мы добавляем условие, которое выбирает один из наших трех классов врагов: GunShip, ChaserShip или CarrierShip, который будет создан. Установив переменную enemy, мы затем добавляем ее в группу enemies. Если CarrierShip выбран для нереста, мы проверяем, чтобы было не более пяти ChaserShip, прежде чем нерестить еще один. Прежде чем добавить врага в группу, мы также применяем к нему случайную шкалу. Поскольку каждый враг расширяет наш класс Entity, который, в свою очередь, расширяет Phaser.GameObjects.Sprite мы можем установить масштаб для врагов, как и для любого другого Phaser.GameObjects.Sprite.

В функции обновления нам нужно обновить врагов в группе this.enemies. Для этого в конце функции обновления добавьте следующее:

for(vari=0;i<this.enemies.getChildren().length;i++){varenemy=this.enemies.getChildren()[i];enemy.update();}

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

Шаг одиннадцатый. Дадим игроку возможность стрелять

Вернитесь к классу Player и в конструкторе добавьте:

this.setData("isShooting",false);this.setData("timerShootDelay",10);this.setData("timerShootTick",this.getData("timerShootDelay")-1);

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

if(this.getData("isShooting")){  if(this.getData("timerShootTick")<this.getData("timerShootDelay")){    // каждое обновление игры увеличивайте timerShootTick на единицу, пока мы не достигнем значения timerShootDelay    this.setData("timerShootTick",this.getData("timerShootTick")+1);  } else{//когда "ручной таймер" срабатывает:    varlaser=newPlayerLaser(this.scene,this.x,this.y);    this.scene.playerLasers.add(laser);    this.scene.sfx.laser.play();//воспроизвести звуковой эффект лазера    this.setData("timerShootTick",0);  }}

Единственное, что нам осталось сделать, это добавить класс лазера игрока в наш Entities.js файл. Мы можем добавить этот класс прямо под классом Player и перед классом EnemyLaser. Это позволит сохранить наши классы, связанные с игроком, и наши классы, связанные с врагами, вместе. Создайте конструктор внутри класса PlayerLaser и добавьте в него тот же код, что и в классе EnemyLaser. Затем установите отрицательный знак в том месте, где мы установили значение скорости. Это приведет к тому, что лазеры игроков будут двигаться вверх, а не вниз. Лазерный класс игрока теперь должен выглядеть так:

classPlayerLaserextendsEntity{constructor(scene,x,y){super(scene,x,y,"sprLaserPlayer");this.body.velocity.y=-200;}}

Последнее, что нам нужно сделать, чтобы позволить игроку стрелять, - это вернуться к SceneMain.js и добавьте следующее условие под нашим кодом движения:

if(this.keySpace.isDown){this.player.setData("isShooting",true);} else{this.player.setData("timerShootTick",this.player.getData("timerShootDelay")-1);this.player.setData("isShooting",false);}

Мы закончили с добавлением возможности стрелять лазерами как для игрока, так и для врагов!

Шаг двенадцатый. Немного оптимизации

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

Чтобы добавить отбраковку усеченного конуса, нам придется перейти к функции обновления главной сцены. В настоящее время у нас должен быть реализован цикл for, в котором мы обновляем врагов:

for (var i = 0; i < this.enemies.getChildren().length; i++) {var enemy = this.enemies.getChildren()[i];enemy.update();}

После строки enemy.update(), нужно добавить следующий код:

if(enemy.x<-enemy.displayWidth||enemy.x>this.game.config.width+enemy.displayWidth||enemy.y<-enemy.displayHeight*4||enemy.y>this.game.config.height+enemy.displayHeight){    if(enemy){      if(enemy.onDestroy!==undefined){      enemy.onDestroy();      }      enemy.destroy();    }}

Мы также можем добавить то же самое для вражеских лазеров и лазеров игрока:

for(vari=0;i<this.enemyLasers.getChildren().length;i++){varlaser=this.enemyLasers.getChildren()[i];laser.update();if(laser.x<-laser.displayWidth||laser.x>this.game.config.width+laser.displayWidth||laser.y<-laser.displayHeight*4||laser.y>this.game.config.height+laser.displayHeight){if(laser){laser.destroy();}}}for(vari=0;i<this.playerLasers.getChildren().length;i++){varlaser=this.playerLasers.getChildren()[i];laser.update();if(laser.x<-laser.displayWidth||laser.x>this.game.config.width+laser.displayWidth||laser.y<-laser.displayHeight*4||laser.y>this.game.config.height+laser.displayHeight){if(laser){laser.destroy();}}}

Шаг тринадцатый. Столкновения объектов

Чтобы добавить столкновения, мы перейдем к нашему SceneMain.js и взглянем на нашу функцию create. Нам нужно будет добавить то, что называется коллайдером, ниже события появления нашего врага. Коллайдеры позволяют добавить проверку столкновения между двумя игровыми объектами. Таким образом, если происходит столкновение между двумя объектами, будет вызван указанный вами обратный вызов, и вы получите два экземпляра, которые столкнулись в качестве параметров. Мы можем создать коллайдер между лазерами игрока и врагами. В коде мы напишем это так:

this.physics.add.collider(this.playerLasers,this.enemies,function(playerLaser,enemy){});

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

if(enemy){  if(enemy.onDestroy!==undefined){  enemy.onDestroy();  }  enemy.explode(true);  playerLaser.destroy();}

Если мы запустим это, то получим ошибку, так как explode - это не функция. Впрочем, не беспокойтесь, мы можем просто вернуться в Entities.js и посмотреть на класс Entity. В классе Entity нам нужно добавить новую функцию под названием explode. Мы будем принимать canDestroy в качестве единственного параметра этой новой функции. Параметр canDestroy определяет, будет ли при вызове explode объект уничтожен или просто установлен невидимым. Внутри функции explode мы можем добавить:

explode(canDestroy){  if(!this.getData("isDead")){    //устанавливаем анимацию взрыва для текстуры    this.setTexture("sprExplosion");//это относится к тому же ключу анимации, котрый мы добавляли в this.anims.create ранее        this.play("sprExplosion");//запускаем анимацию    //использовать случайный звук взрыва который мы определиливthis.sfxвSceneMain    this.scene.sfx.explosions[Phaser.Math.Between(0,this.scene.sfx.explosions.length-1)].play();    if(this.shootTimer!==undefined){      if(this.shootTimer){      this.shootTimer.remove(false);      }    }    this.setAngle(0);    this.body.setVelocity(0,0);    this.on('animationcomplete',function(){      if(canDestroy){      this.destroy();      } else{      this.setVisible(false);      }    },this);    this.setData("isDead",true);  }}

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

if(!this.player.getData("isDead")){  this.player.update();  if(this.keyW.isDown){  this.player.moveUp();  }  elseif(this.keyS.isDown){  this.player.moveDown();  }  if(this.keyA.isDown){  this.player.moveLeft();  }  elseif(this.keyD.isDown){  this.player.moveRight();  }  if(this.keySpace.isDown){  this.player.setData("isShooting",true);  }  else{  this.player.setData("timerShootTick",this.player.getData("timerShootDelay")-1);  this.player.setData("isShooting",false);  }}

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

Шаг четырнадцатый. Финальные действия

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

Мы начнем с добавления фона прокрутки. Фон прокрутки будет иметь несколько слоев с разной скоростью. Во-первых, давайте перейдем к нашему Entities.js. В нижней части файла мы можем добавить новый класс, прокручивающий фон. Ему не нужно ничего расширять.

class ScrollingBackground {  constructor(scene, key, velocityY) {      }}

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

this.scene = scene;this.key = key;this.velocityY = velocityY;

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

this.layers = this.scene.add.group();

Теперь создадим функцию createLayers и добавим внутри следующий код для создания спрайтов из ключа изображения:

for (var i = 0; i < 2; i++) {  var layer = this.scene.add.sprite(0, 0, this.key);  layer.y = (layer.displayHeight * i);  var flipX = Phaser.Math.Between(0, 10) >= 5 ? -1 : 1;  var flipY = Phaser.Math.Between(0, 10) >= 5 ? -1 : 1;  layer.setScale(flipX * 2, flipY * 2);  layer.setDepth(-5 - (i - 1));  this.scene.physics.world.enableBody(layer, 0);  layer.body.velocity.y = this.velocityY;  this.layers.add(layer);}

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

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

Затем мы можем вызвать createLayers в нижней части нашего конструктора.

this.createLayers();

Теперь мы можем вернуться в SceneMain.js и инициализируйте фон прокрутки. Вставьте следующий код перед созданием this.player и добавьте его после определения this.sfx.

this.backgrounds=[];for(vari=0;i<5;i++){//создание пяти слоев фона  varbg=newScrollingBackground(this,"sprBg0",i*10);  this.backgrounds.push(bg);}

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

if(this.layers.getChildren()[0].y>0){  for(vari=0;i<this.layers.getChildren().length;i++){  varlayer=this.layers.getChildren()[i];  layer.y=(-layer.displayHeight)+(layer.displayHeight*i);  }}
for (var i = 0; i < this.backgrounds.length; i++) {this.backgrounds[i].update();}

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

Мы можем закончить, добавив наше главное меню и экран GameOver. Перейдите к SceneMainMenu и удалите строку, которая начинается с SceneMain. Однако прежде чем мы продолжим, мы должны создать объект звукового эффекта для SceneMainMenu. Добавьте следующее в самую верхнюю часть функции create:

this.sfx={btnOver:this.sound.add("sndBtnOver"),btnDown:this.sound.add("sndBtnDown")};

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

this.btnPlay=this.add.sprite(this.game.config.width*0.5,this.game.config.height*0.5,"sprBtnPlay");

Чтобы запустить SceneMain, нам нужно сначала установить наш спрайт как интерактивный. Добавьте следующее непосредственно ниже, где мы определили this.btnPlay:

this.btnPlay.setInteractive();

Поскольку мы настроили наш спрайт как интерактивный, теперь мы можем добавлять указатели на события, такие как over, out, down и up. Мы можем выполнить код, когда каждое из этих событий запускается мышью или нажатием клавиши. Первое событие, которое мы добавим, - это pointerover. Мы изменим текстуру кнопки на наше изображение sprBtnPlayHover.png, когда указатель находится поверх кнопки. Добавьте следующее после того, как мы установили нашу кнопку как интерактивную:

this.btnPlay.on("pointerover",function(){this.btnPlay.setTexture("sprBtnPlayHover");//установка текстуры для кнопкиthis.sfx.btnOver.play();//проигрывание звука при наведении на кнопку},this);

Теперь мы можем добавить событие pointerout. В этом случае мы сбросим текстуру обратно к обычному изображению кнопки. Добавьте следующее в разделе где мы определяем указатель на событие:

this.btnPlay.on("pointerout", function() {  this.setTexture("sprBtnPlay");});

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

Далее мы можем добавить событие pointerdown. Здесь мы изменим текстуру кнопки запуска на sprBtnPlayDown.png.

this.btnPlay.on("pointerdown",function(){this.btnPlay.setTexture("sprBtnPlayDown");this.sfx.btnDown.play();},this);

Затем мы можем добавить событие pointerup для сброса текстуры кнопки после нажатия.

this.btnPlay.on("pointerup",function(){this.setTexture("sprBtnPlay");},this);

Мы можем дополнить логику внутри нашего события pointerup, чтобы начать основную сцену. Окончательное событие pointerup должно выглядеть следующим образом:

this.btnPlay.on("pointerup",function(){this.btnPlay.setTexture("sprBtnPlay");this.scene.start("SceneMain");},this);

Когда мы запускаем игру и нажимаем кнопку воспроизведения, теперь она должна начать главную сцену!

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

this.title=this.add.text(this.game.config.width*0.5,128,"SPACESHOOTER",{fontFamily:'monospace',fontSize:48,fontStyle:'bold',color:'#ffffff',align:'center'});

Чтобы центрировать заголовок, мы можем установить начало текста на половину ширины и половину высоты. Мы можем сделать это, написав следующее под определением title:

this.title.setOrigin(0.5);

На этом статья заканчивается. Это моя первая статья на Хабре и я старался максимально точно донести смысл оригинала. Если вы заметите где-то неточности или ошибки, напишите в комментариях и мы это обсудим.

Ссылка на оригинал статьи

Ссылка на исходники оригинала

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

Подробнее..

Игра, стоившая мне рассудка Китайская трещотка

15.06.2021 18:13:51 | Автор: admin

Хабр, у меня от тебя нет секретов.

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

Моя граничащая с безумием уверенность в том, что материал вообще оглашать стоит вызвана, в первую очередь, тем, что я уже публиковался на ваш суд однажды, шесть лет тому назад, и тот мой опыт, мягко говоря, удался. По крайней мере в моих собственных глазах. С другой стороны, свое дерзновение я могу оправдать в том числе и тем, что я полтора года назад и правда сошел с ума вплоть до медикаментозного вмешательства, доковырявшись-таки до грани со своей выдуманной игрой, которую писал. Хотите послушать историю никому не известного программиста о мирах, лежащих за стеной здравомыслия?

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


Однажды -
Только ты повеpь -
Маятник качнется в пpавильную стоpону
И вpемени больше не будет.

01 - Гражданская Оборона - Солнцеворот.mp3

Ищущим правильного ответа на просторах сети я сразу рекомендую набрать "основные цвета в рисовании" и испытать когнитивный диссонанс, который испытал когда-то и я. Кивнуть в знак согласия со мной был шанс лишь у тех, кто либо ну очень хорошо слушал учителя по рисованию в первом классе, либо закончил художественную школу. Когда я впервые сам узнал об этом парадоксе, пытаясь оседлать самоучитель по рисованию для детей (мы ведь все должны развиваться прежде всего в тех областях, где меньше всего что-либо из себя представляем, не так ли?), изумлению моему не было предела. Причем самым поразительным для меня оказалось то, что это было не какое-нибудь ортогональное смещение привычного RGB на желтый, фиолетовый и любой другой еще, а настоящий удар под дых - два цвета были правильными, а один - нет. Однако в конце концов через тернии многочисленных попыток я нашел-таки ключ к этой несостыковке и обязательно поделюсь им с вами, но, уж простите, не сейчас. Сейчас лишь намекну, вдруг вы сами хотите сделать для себя это открытие. Все дело в точке отсчета.

От ее выбора часто зависит куда больше, чем кажется нам на первый взгляд. Помните школьные задачки по физике на сохранение потенциальной и кинетической энергии в замкнутой системе? Ну, те, в которых предмет изначально находится на определенной высоте и если за начало вертикальной координаты принять уровень земли, то тело по умолчанию обладает потенциальной энергией, если же нулем выбрать его стартовую вертикальную позицию - то нет. Если не помните, придется поверить мне на слово - такие задачи есть. Разумеется, в этих упражнениях сделанный выбор на решение никак не влияет - ответ остается тем же. Хотя если так по совести-то разобраться, то как так? Асимметричная же ситуация складывается: в одном случае на то, чтобы упасть на землю, у тела в запасе нет энергии вовсе, а чуть по-другому взгляни - есть еще как.

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

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

Вы знаете как сходят с ума?

Я не сказать, что прямо таки жаждал этот опыт освоить, но коль скоро однажды на какое-то время по ту сторону стены здравого рассудка оказался, позвольте мне побыть для вас странствующим бардом и рассказать что происходит там, за стеной. Когда человек впервые сталкивается с так называемым "психозом", он сам не способен этого понять. Его мозг не может без посторонней помощи диагностировать, что сломался. Уж не знаю какими try/catch там все в сознании обернуто, но абсолютно любая идея, которая приходит в этот момент бедняге в голову, тут же становится для него истиной. Можете сами почитать, это называется "отключение критического мышления". Представьте на секунду, что весь невообразимый сонм if'ов в вашем мировоззрении переключился намертво в положение true. Мне в этот момент повезло спалить только процессор, жесткий диск до самого последнего момента усердно фиксировал все происходящее, поэтому и сейчас я помню если не каждую свою мысль, то уж все свои логические построения точно. В общей сложности я бился в душевном припадке около пяти дней, так что передумать и поверить я успел очень многое и почти во все.

Поначалу идеи похожи на редкие капли, падающие в колодец сознания - кап, кап, кап. Вопросом возникновения мыслей и их ловлей на этапе зарождения занимается, если что, буддизм. Потом все чаще, одна за другой, мысли начинают приходить к тебе в голову все быстрей, причем порой в наибсурднейшей форме, но их адекватность ты уже не способен оценить, каждая принимается за аксиому. Частота увеличивается, напор становится все более и более бурным, к тому же уже полученные "знания" никуда не исчезают из оперативной памяти болезненного рассудка, они как шарики в арканоиде, у которого запечатали пропасть снизу, отражаются от стенок сознания и возвращаются в игровое поле, бодаясь там с новыми и новыми идеями, коих поток и так, сам по себе, грозит вот-вот перегреть биологический процессор ума. Мысли наползают друг на друга, сталкиваются, отталкиваются, слипаются, схватываясь в диковинные симбиозы. Тут тебе и видео, которым ты не управляешь, и концепции, сопоставлять которые ты бы в жизни не додумался, и даже "откровения" о том как этот мир устроен на случай, если ты захочешь что-нибудь эдакое новое изобрести. Короче, как вы понимаете, при таком обильном выборе я обещаю, что не буду натирать вам сознание банальными атомарными идеями типа "точка на плоскости листа бумаги - это на самом деле прямая, перпендикулярная поверхности этого листа". Последовавший за этой вспышкой месяц, проведенный среди таких же гениев, как и я, обошелся без пустых переливаний из пустого в порожнее с соседями по палате, я лежал и методично перебирал весь накопленный мною энтропийный архив всевозможных сочетаний мыслей, стараясь расплести целиком нагроможденную кипу мутировавших в моем уме понятий и оставить только действительно стоящие и более или менее адекватные на мой взгляд экземпляры, в беспристрастности которых я, тем не менее, сомневаюсь до сих пор. Я потому, собственно, их вам и принес. Я и в процессе пытался достучаться до Хабра, как заправской Эйнштейн, но что-то меня не поняли (ну надо же!) и по паре фраз, брошенных мною нехотя, гения во мне не признали.

Эта история начинается с того, что я читал книгу "Искусство геймдизайна" Джесси Шелла. Автор в конце своего труда просил передавать ему всяческие приветы, так что, мистер Шелл, здравствуйте, мой Вам большой привет. Спасибо за книгу, я прочитал ее почти что на одном дыхании. "Почти что" потому что... ну вы поняли. Реальность начала искажаться в момент прочтения 28ой главы, в которой новоиспеченным игроделам предлагается поработать над презентацией их игры. Автор этой без сомнения потрясающей книги, будучи чистым геймдизайнером без художественных и технических отклонений, говорит о привлечении внимания инвестора к будущему, еще не начатому проекту. Мне же, инди-разработчику, мечтающему о полной, в том числе финансовой, независимости производства, было куда интереснее создать материал, стимулирующий интерес широкой общественности к уже готовому и выпущенному релизу. Как нельзя кстати пришелся к месту и такой термин как "Речь в лифте" - паттерн проектирования монолога, позволяющий наточить выдающиеся грани описания вашего детища до состояния японской катаны, разрезающей, как известно, шелк на лету.

И вот еду я в лифте с Биллом Гейтсом. Рассказываю ему такой, рассказываю про свою игру, вижу, что он проникается, глаза его начинают гореть, не дослушав и половины, он восклицает: "Отлично! Великолепно! Куда надо нажать? Где можно скачать?" А я ему такой: "Я Вам не скажу". Он: "Почему?" А я ему: "Так мы же с Вами не в "Я пиарюсь".

Готовя план продвижения еще не выпущенной игры, я зашел как-то на Reddit, чтобы поискать там соответствующие мобильному геймдеву сообщества, и в своих изысканиях накликал себе несколько вкладок. Сперва прошелся по более мелким из их числа, в самом конце открыл наиболее крупное, судя по количеству подписчиков, коммьюнити. И вижу вдруг краем глаза на этой странице табличку такую всплывшую. Не глядя на нее, думаю: "Ну, понятно, наверное предупреждение, мол, "Осторожно, тут много людей, не флудите, премодерация, вход только с высокой кармой". Перевожу на нее взгляд и брови мои медленно начинают ползти вверх, там написано: "Это сообщество насчитывает более N тысяч участников, начните новый тред и вы наверняка найдете себе среди них собеседников".

Привыкший к тому, что с трибуны говорить надо строго по делу, а лучше и не говорить вовсе, я был, мягко говоря, озадачен таким подталкиванием в совершенно противоположном направлении. Подумал: "Серьезно? То есть хоть кто-нибудь, да прочитает все, что я напишу?" Я, признаться, эту-то статью создавал так: зафиксировал текстом все, чем хотел поделиться, затем попытался (безуспешно) сжать каждый абзац до одного предложения, чтобы суть был концентрированная, как у Ницше (хотя куда мне), а тут - на тебе - такое приглашение.

Хабр тогда активно выходил на англоязычную платформу, вслед за первым роликом спустя некоторое время в моем мысленном телеэфире начали крутить другой видеоряд, похожий, но с иной концовкой, как это сейчас бывает принято в сфере рекламного дизайна. В этом видео парень рассказывает своей девушке эту же историю, говорит: "Еду я в лифте с Биллом Гейтсом, рассказываю ему про свою недавно выпущенную игру, рассказываю, вижу он заинтересовался, кивает одобрительно. Наконец закончил я перечислять достоинства релиза и говорю ему: "Но ссылку я Вам, разумеется, не покажу". Повисает пауза, девушка делает огромные удивленные глаза и спрашивает: "А он чего?" На что парень отвечает: "А он так хмыкнул и говорит: "Правильно, ты же не в "Я пиарюсь".

Надо понимать, что устная и письменная речь сильно отличаются друг от друга.

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

Так вот представьте, что вы едете в лифте со всем Хабром. У вас есть, скажем, 12 секунд. Но из-за того, что Хабр письменный, на самом деле вам достаточно будет и одной. И неважно как долго вы будете к этому моменту готовиться, Хабр будет стоять и ждать вас, продолжая делить с вами кабину, окруженную едущей шахтой. В тот же момент когда пост будет опубликован, ось t исчезнет, событие свершится, вы либо за эту бесконечно малую величину времени убедите всех в том, что ваша игра - шедевр, либо нет. Но, знаете, учитывая эту особенность письменной формы повествования, я бы воспользовался мнимо единственной единицей вашего внимания так же, как первым и последним запросом, гарантированно исполняемым с помощью волшебства джинном. Попросил бы еще желаний, выпалил бы: "Хабр, позволь я поведаю тебе о своей игре за 12 секунд. Первой я хочу воспользоваться так же, как и нулевой, а за вторую рассказать тебе о..." и далее по тексту. Ваша история может длиться хоть вечность, было бы лишь вам что повествовать. И точно так же, как одну-единственную секунду можно развернуть аж в целых 12, пусть и немного схитрив в кратковременное течение ее, не возбраняется делать и наоборот: долгие годы труда сворачивать в один-единственный момент - момент публикации.

А знаете что на самом деле я бы сказал Биллу Гейтсу, если бы оказался с ним в одном лифте? Я бы сказал: "Билл Гейтс, сэр, помните Вашу книгу "Дорога в будущее", которую Вы опубликовали в 1995 году? У вас там есть глава про положительно и отрицательно раскручивающиеся спирали. Так вот, сэр, Вы используете неправильную терминологию. Эти спирали называются системами с положительной и отрицательной обратной связью, мы их в МЭИ на ТАУ проходили".

Я поясню на всякий случай о чем идет речь. Десятый и одиннадцатый класс я учился в лицее 1502 при МЭИ (Владимир Львович, здрасьте). До последнего моего учебного года в нем, это образовательное учреждение имело одну любопытную преференцию - его выпускные экзамены считались вступительными в МЭИ. То есть итоговые работы писались в родных стенах, под надзором привычных и ни капельки не страшных уже преподов, а результат считался как полноценно заполненные твоими каракулями листы, содержимое которых было натужно извергнуто в чужеродных аудиториях под контролем незнакомых, демонических в своей неопределенной строгости педагогов. Это на выходе.
На входе же, при наборе в лицей, были вступительные экзамены - просто перевестись в него из обыкновенной школы было нельзя. Но для тех, кто очень хотел поступить, существовал межшкольный факультатив (МШФ) - платные вечерние занятия, на которых за деньги его родителей любого желающего готовы были натаскивать по экзаменационным предметам, было бы лишь у него желание учиться. Разумеется, поступали и те, кто на МШФ не ходил. И, разумеется, не все, кто посещал МШФ, - поступали.
В середине же этой цепочки, во время учебы, был Супермарафон - ежегодная серия творческих и интеллектуальных конкурсов, а также спортивных состязаний. Соревновались между собой все без исключения классы - с 9ых по 11ые, у мероприятия был общелицейский масштаб, длилось оно почти полгода - весь второй семестр. Победители классом ехали за границу, второе место - куда-то по России, третье - экскурсия где-нибудь в Москве. Все это за счет лицея. Ну и там компьютерные классы, спортзалы, мебель, преподавательский состав.

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

И надо же было такому случиться, что именно в год моего выпуска уговор с МЭИ отменили. Теперь ты должен был отдельно писать выпускные экзамены в лицее, а отдельно - ехать в институт и сдавать там вступительные, наравне со всеми остальными. Но я помню как Чудов, желая успокоить общественность, выступил с заявлением, сказав, что "какие-нибудь преференции все равно будут". "Может быть на балл больше всем лицеистам", "может еще что".
"Я сделаю все, - сказал наш директор. - Чтобы, при прочих равных условиях, из двух абитуриентов, один из которых закончил пятнадцать-ноль-два, а другой - нет, комиссия зачисляла именно наших лицеистов".
Престиж лицея удалось спасти. Положительно разворачивающаяся спираль не развернулась в отрицательную. Я знаю это потому что через пару лет "пятнадцать-ноль-два" отстроил себе на своей территории собственный бассейн. А ведь могло случиться и так, что из-за отмены одного-единственного преимущества, на МШФ в будущем пришло бы меньше народу, в результате чего что-нибудь в середине пришлось бы урезать, престиж бы упал, на следующий год школьников, желающих поступить, оказалось бы еще меньше, а дальше по цепочке ситуация начала бы скатываться к нулю.

(Автор, все уже почти забыли в чем там изначально суть была-то)

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

Те, кто читал мою дебютную статью на Хабре "Семь итераций наивности...", возможно, помнят, что там в повествовании, ближе к концу, наступает такой момент, когда я говорю "Однако чем ближе был релиз, тем меньше мне требовалось моральных сил на то, чтобы закончить. Проект набрал вес и как снежный ком чуть ли не сам по себе катился к выпуску. Его по-прежнему надо было каждый вечер толкать, но выпуск был просто неизбежен."
Попрощаемся сразу с теми, кто, как и я, любит изучить явление с самых предтеч и сейчас ушел эту самую мою статью с самого-пресамого начала читать. Они к нам не скоро вернутся, уж поверьте. Да, тот проект в какой-то момент набрал такую критическую массу, что совокупная обратная связь всех предыдущих шагов начала сама меня толкать садиться каждый день за работу над игрой. Но наша задача - получить этот эффект от всего-навсего одного-единственного, наименьшего шага. Для этого нам и понадобится обещанный мною вам про равноправие RGB и RYB ключ.

Я долгое время бился над этим вопросом в своей голове так и сяк, рассматривал градиент всех цветов на мониторе в виде квадрата и круга. Но в итоге решение оказалось до ужаса простым: чтобы увидеть нужную картину, достаточно было всего лишь передвинуть все три ползунка, отвечающих за один базовый цвет каждый, максимально вправо. Произведя эту нехитрую операцию, вы обнаружите, что шкалы теперь такие: желтая, розовая и голубая. Просто мы привыкли к тому, что #000000 - это черный, а #FFFFFF - это белый. Стоит же принять за точку отсчета полную противоположность, как, глядите ка, все встает на свои места - сотни поколений художников не могли ошибаться. Просто мы пляшем от черного монитора, а живопись - от белого листа.

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

В тот момент, когда вы делаете первый шаг, вы оказываетесь не в единице, а в минус единице. Но шагаете вы при этом не из нуля. Позади вас минус бесконечность - это вся ваша предыдущая жизнь, из которой вы только что на оси разработки материализовались. А впереди - ноль - это момент выпуска вашего продукта. Расстояние до нуля из вашей минус единицы не так важно, главное в этой величине вовсе не объем, а одно-единственное свойство - оно конечно. Как только в объективной реальности было произведено инициализирующее процесс разработки действие, вы оказались на отрезке между -1 и 0 (чуть-чуть правее левой границы интервала) и теперь выпуск игры неизбежен, ведь вы скатываетесь в точку публикации сами собой. Вам осталось всего лишь плыть по течению в этом направлении. То, что по игре не сделано еще практически ничего превращается в то, что она уже готова. И открою вам секрет, ваша игра и вправду уже написана, нарисована и даже выпущена. В будущем. Или в вашей голове. Зависит от вашей точки зрения на всю эту ситуацию.

Чем меньше шаг в изначальной системе координат, тем больше он при отрицании - всем известно, что самое сложное - начать. Положительная обратная связь от этого действия вроде как вообще стремится к нулю; переворачиваем - стремится к бесконечности. И это действительно так, ведь, как я уже сказал, желания у вас на первых порах хоть отбавляй. Так вот расслабьтесь, игра уже выпущена. Если вы решились хоть на одно действие, вам теперь не отвертеться. Остается только максимально четко представить себе этот момент - момент явления вашей игры общественности - и с честью и мнимой горечью принять тот факт, что ноль в вашей системе координат существует: рано или поздно публикация произойдет.

Так ничего и не написалось?

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

Дело все в том, что вы должны представлять не деньги, которые принесет вам игра - так вы забегаете вперед при уже перевернутых понятиях (мысленно пропустили ноль) и в результате оказываетесь в минусе в изначальной системе координат (все уже сделано, всем уже понравилось, теперь вы мысленно тратите заработанные деньги). Не момент самого релиза, поскольку в нем вы со своей игрой никому не нужны, да и момент этот из-за премодерации сторами весьма размазанным получается (я писал об этом в дебютной статье).
Вы должны мысленно оказаться в моменте публикации новости о том, что вы свою игру наконец-то завершили. Где вы собираетесь об этом сообщить? Разместить на Youtbe'е ролик с геймплеем (это самое сложное пока что)? Рассказать друзьям в Facebook'е, что игру наконец-то дописали? Накатать простыню на Хабре о том, как семь раз спотыкались по неопытности об очевидные не вам вещи? Запостить на Reddit'е свою gamedev-стори? Или пожаловаться на Pikabu сколько вечеринок пропустили из-за своего каторжного труда? Да все вместе. А знаете как это сделать в один момент? Используйте китайскую трещотку.

Вы ведь, как и я, будучи программистом, наверняка любите мастерить всякое для души? Вот и создайте скрипт, который, подобно подожженной связке петард, за 12 секунд разошлет подготовленные вами материалы по всем интересующим вас площадкам. Бах, бах, бах, бах - с интервалом в 3 секунды китайская трещотка сделала свое дело, вы можете выдохнуть, дальше от вас ничего уже не зависит. Все произошло в один-единственный момент - в тот, в который вы нажали кнопку запуска скрипта. Но главное, что на самом деле вы можете не утруждать себя и никакую программу для этого не писать - зачем вам перебирать DOM в поисках поля ввода, преодолевать капчу и отлаживать свой скрипт пробными публикациями? Сделайте это вручную, ведь время можно легко сворачивать и разворачивать, главное чтобы материалы были у вас уже готовы. Пусть 12 секунд превратятся в 12 минут, все равно весь этот интервал времени в итоге равен одному моменту.
И самое интересное, что этот момент на протяжении всего пути из минус единицы в ноль будет вновь и вновь наступать. Вы успеете устать уже от собственной неопубликованной статьи и переписать ее снова и снова. Вы уберете то, от чего успели отказаться в своей игре и добавите то, что придумали добавить. Главное, что у вас уже будет с описанием игры статья.

Чтобы показать как это работает, я признаюсь вам честно, что прямо сейчас пишу эти строки (ноябрь 2020), хотя у меня еще даже не создан проект в IDE. Есть только четкое представление что и где я о нем расскажу, какой игра в итоге будет. Именно за счет отсутствия совершенной на данный момент работы, я легко могу встать на место того, кто никогда до этого момента ничего о моей игре не слышал. Я пока еще не вложился в нее, не полюбил каждую виньетку ее функционала и потому могу спокойно постулировать те особенности, которые у игры точно будут, самые крупные из них, мечтать по сути письменно, пребывая в уверенности что рано или поздно все это в жизнь воплощу. Я точно знаю, что даже начав с конца и написав сперва обзор еще не выпущенного релиза, причем так, будто он уже состоялся, обязательно в итоге приду в свой собственный ноль, где это окажется правдой. Статью-то мне теперь уже жалко будет выбросить.

Вы, может быть, не верите мне, когда я говорю, будто мироздание устроено так, что положительная обратная связь автоматически есть у любого вашего действия? Извольте. Чем больше вы играете в какую-либо игру, тем сильнее жалеете ее бросить. А если вы еще и задонатили, то теперь-то уж точно на крючке - не бросать же аккаунт, деньги вложены. А деньги - это энергия. Так просто они ниоткуда не берутся и никуда не пропадают, ведь все мы вместе с ними находимся в замкнутой системе (не считая некоторых оговорок по выпуску новых купюр). Поэтому было бы классно как-то автоматизировать шаги навстречу выпуску игры, чтобы с каждым днем положительной обратной связи становилось все больше. Еще лучше было бы приладить для этого внешний денежный поток, который бы работал на вас помимо собственной воли. Ну а уж кибернетизированная материальная лавина - и вовсе вполне реалистичная сказка, которую мы с вами можем легко себе изобрести.

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

В своей дебютной игре я, сам того не подозревая, сделал систему алгебраической прогрессии, которая работала мне во вред. Лотерея с призами выпадала после первой победы, после двух подряд, затем после трех, после четырех и так до бесконечности. В итоге редко кто выбивал все подарки, исчерпав полностью сундук с сокровищами. Когда требование доходило до сплошной серии величиной в двадцать побед, у многих людей просто-напросто опускались руки. Но, сам того не подозревая, я использовал в этой ситуации древний вселенский паттерн, который, несмотря на свое засилье почти уже во всех сферах нашей жизни, все еще таит в себе немало загадок. Этот паттерн называется "Пирамида". Верхушка его - единица, второй слой - два элемента, третий - три, четвертый, не поверите, - четыре, думаю, дальше вы сами. Однако, бьясь в умственных конвульсиях, я вдруг понял, что у этой "пирамиды", имеющей в качестве горизонтальной оси сами элементы, есть и вертикальное измерение, смысловое. Единица - это господство, два элемента - противостояние, три - циркуляция, четыре - основание, дальше у меня в уме идет совсем уже мутная какая-то эзотерическая хрень, я пока с ней не разобрался.

Я предлагаю вам весь тот запас положительной обратной энергии, которую вы получите от первого шага, направить на незамысловатое действие - просто сделайте еще два. Ну что вам стоит? Игра ведь уже выпущена, не о чем беспокоиться. На этом втором, составном уровне почему бы нам с вами не задуматься о противостоянии двух ключевых понятий в нашем релизе? Маркетинг мы уже решили с помощью китайской трещотки, поэтому идем от обратного дальше: по моему сугубо личному мнению игра рождается в непрерывной борьбе двух начал - графики и геймплея. Вам повезло, если вы одинаково хорошо подкованы и в том, и в другом. Возможно, вы, как Фил Фиш, больше художник, а программирование для вас - прикладное увлечение.

Видели, кстати, фильм (в том числе) об этом Филе Фише? "Indie game" называется, там у этого художника-геймдизайнера спрашивают: "А в чем, собственно, смысл вашей игры? Что в ней можно делать?" А он такой: "Ну, понимаете, это как бы такой опыт, здесь можно пойти тудааа, сюдааа". И показывают нам как проект его виснет на каком-то gamecon'е раз за разом, что неудивительно - с разработчиком-то он незадолго до этого разругался. Сознаюсь: я искренне дал гению этого Фила шанс, купил его этот FEZ на своем Xbox 360, но игра чего-то у меня так и не запустилась, еще и сама консоль глюкнула как-то неприятно, хрустнула, я подумал "ну его" и от греха подальше удалил, так что созданный им для меня опыт я, несмотря на все свои, в том числе денежные, усилия, так и не получил в итоге.

Скорей всего вы, как и я, больше программист нежели художник. Не отчаивайтесь по этому поводу, графика имеет линейную ценность - на каждый типовой рисунок из ряда уходит одинаковое количество времени. Программирование же, на мой взгляд, интереснее - оно сложнее в силу того, что иерархично - чтобы сделать кучу объектов одного типа вам достаточно написать всего один родительский класс, а дальше клепайте сущности (хоть целые их классы) сколько вам влезет. Если бы художники могли так же, они бы озолотились. Хотя, подождите ка, вы знаете кто такой Энди Уорхол? На самом деле на заре игростроя так оно с графикой и было - вспомните Sub-Zero и Scorpion'а - самая знаменитая парочка двух графических потомков одного родительского экземпляра, различающихся лишь цветом. Но суть у них еще как разн. Функционал, смысловое наполнение, по моему скромному мнению, важнее внешней привлекательности.

Поэтому не отчаивайтесь если графики толком у вас нет и в ближайшем будущем она вряд ли появится. Вы же и в программировании так же пишете, с помощью абстракции: "Так, тут у нас получение координат" - вызвали пока еще не существующую getСoords() и пошли дальше, подробно распишете потом, внутри этой функции. Главное сейчас, что у вас есть идея, есть мечта, есть видение того какой ваша игра должна быть, представьте ее во всю силу своей фантазии, бросьте на это максимальное количество ресурсов своего воображения и смело ставьте галочку напротив первого шага - ноль обозначен, игра уже готова. Теперь можно расслабиться и позволить себе скатиться по шкале времени к моменту запуска китайской трещотки. Поздравляю вас.

Как думаешь, Хабр, это шизофрения?

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

Подробнее..

Запускаем DOOM на лампочке

14.06.2021 16:14:45 | Автор: admin
image


В DOOM уже поиграли на пианино и на клавиатуре, на тесте на беременность (кстати, это был фейк) и на паяльнике, на самолёте, банкомате, принтере и осциллографе.

Пришло время для лампочек.

imageВнутри лампочки TRDFRI RGB GU10 (IKEA model: LED1923R5) хакеры из Next-Hack нашли модуль Silicon lab's MGM210L RF module с 108кб оперативки и запустили на нем DOOM. Исследователям-хакерам пришлось попотеть над оптимизацией использования оперативки, потому что оригинальный DOOM требует 4мб, но они смогли.

Модуль имеет только 1 МБ внутренней флэш-памяти, поэтому умельцы добавили внешнюю флэш-память SPI для хранения файла WAD, который можно загрузить с помощью YMODEM. Процессор: 40-MHz Cortex M4.



image

Лампочка в разборе

image

Дисплей: 1.8 TFT 160128 SPI

image

Блок-схема железа

image

Схема токов

image

Блок питания

image

Прототип платы

image

Несущая плата

image

Клавиатура

image

Микроконтроллер, усановленный на несущую плату.

image

Система в сборе.

Фичи проекта:

  • Основан на прекрасном Doomhack's GBA Doom Port с некоторыми дополнениями Kippykip.
  • Поддерживает полную версию Doom Shareware WADS.
  • Полный движок Vanilla Render, включая Z-depth lighting. Однако составные текстуры имеют MIP-карту.
  • Реализовано поведение монстров и распространение звука.
  • Поддержка Sound FX.


Ограничения проекта:

  • Музыка.
  • Воспроизведение демо из-за несовместимости.
  • Полный WAD DOOM Не тестировал.
  • Требуется отладка.
  • Мультиплеер не реализован.
  • Оптимизация производительности.
  • Читы не проверяли, наверно с багами.


Инженеры недавно сделали обновление в репозитории Github и удалили mip-отображение на составных текстурах без потери производительности, поэтому графика будет более детальной, чем то, что показано в демонстрационном видео.

Условия DOOM-challenge:



  • Найдите готовое устройство, не предназначенное для игры в Doom или в другие игры.
  • Выбранное устройство должно иметь микроконтроллер с разумно ограниченной вычислительной мощностью и/или памятью в соответствии с минимальными требованиями DOOM (DOOM работает с приемлемой частотой кадров даже на 486 @ 33MHz [1], оборудованном 4MB RAM). В качестве примера мы должны исключить современные цифровые камеры, которые имеют систему на несколько сотен МГц на кристалле, с несколькими десятками мегабайт оперативной памяти.
  • Мы должны использовать именно тот микроконтроллер, который встроен в выбранное устройство. Замена невозможна. Никакого дополнительного микроконтроллера добавить нельзя. Тем не менее, разгон (например, даже если он ограничен только некоторыми периферийными устройствами или шинами) возможен при условии, что нам не нужны какие-либо методы охлаждения.
  • Для хранения файлов WAD можно добавить дополнительную флеш-память или карту памяти.
  • Можно добавить цветной дисплей, если на выбранном стандартном устройстве его нет. Разрешение должно быть достаточно высоким, чтобы можно было прилично играть в Doom. Например, экран 3216 пикселей слишком мал, но 128x64 может быть достаточно. С другой стороны, слишком большие разрешения, безусловно, потребуют очень мощного микроконтроллера, вопреки правилу 2.
  • Устройство ввода может быть любым, поэтому для этой цели можно добавить дополнительную электронику.
  • При необходимости блок питания можно заменить.
  • Мы хотели, чтобы движок был максимально приближен к исходному (ванильному) условно-бесплатному ПО Doom. Возможность играть в эпизоде 1 на карте 1 условно-бесплатной игры Doom (E1M1) это минимальная цель, даже если мы не скрываем, что мы мечтали иметь возможность сыграть полную условно-бесплатную версию без ограничений на всех картах.
  • К звуку требований нет, но звуковые эффекты были бы действительно плюсом. Если реализовано, то на аудиоподсистему ограничений нет.
  • Мультиплеер не обязателен


Тест на беременность




Принтер Canon Proxima




Осциллограф




Банкомат




DOOM в DOOM




Пианино




Minecraft




Валидатор билетов




Микроволновка


image

iPod Mini




Калькулятор




Apple Watch




MacBook Pro Touch Bar




Kodak DC260 Digital Camera from 1998




На клавиатуре




На билборде




На электронной книге




На самолёте




Porsche 911




Vectrex




Паяльник




PS


Как тебе такое, AlexeyNadezhin?

zhovner, ждём DOOM на FlipperZero.

image
Подробнее..

Перевод Запускаем DOOM на лампочке

14.06.2021 18:13:31 | Автор: admin
image


В DOOM уже поиграли на пианино и на клавиатуре, на тесте на беременность (кстати, это был фейк) и на паяльнике, на самолёте, банкомате, принтере и осциллографе.

Пришло время для лампочек.

imageВнутри лампочки TRDFRI RGB GU10 (IKEA model: LED1923R5) хакеры из Next-Hack нашли модуль Silicon lab's MGM210L RF module с 108кб оперативки и запустили на нем DOOM. Исследователям-хакерам пришлось попотеть над оптимизацией использования оперативки, потому что оригинальный DOOM требует 4мб, но они смогли.

Модуль имеет только 1 МБ внутренней флэш-памяти, поэтому умельцы добавили внешнюю флэш-память SPI для хранения файла WAD, который можно загрузить с помощью YMODEM. Процессор у лампочки 40-MHz Cortex M4.



image

Лампочка в разборе

image

Дисплей: 1.8 TFT 160128 SPI

image

Блок-схема железа

image

Схема токов

image

Блок питания

image

Прототип платы

image

Несущая плата

image

Клавиатура

image

Микроконтроллер, усановленный на несущую плату.

image

Система в сборе.

image

Фичи проекта:

  • Основан на прекрасном Doomhack's GBA Doom Port с некоторыми дополнениями Kippykip.
  • Поддерживает полную версию Doom Shareware WADS.
  • Полный движок Vanilla Render, включая Z-depth lighting. Однако составные текстуры имеют MIP-карту.
  • Реализовано поведение монстров и распространение звука.
  • Поддержка Sound FX.


Ограничения проекта:

  • Музыка.
  • Воспроизведение демо из-за несовместимости.
  • Полный WAD DOOM Не тестировал.
  • Требуется отладка.
  • Мультиплеер не реализован.
  • Оптимизация производительности.
  • Читы не проверяли, наверно с багами.


Инженеры недавно сделали обновление в репозитории Github и удалили mip-отображение на составных текстурах без потери производительности, поэтому графика будет более детальной, чем то, что показано в демонстрационном видео.

Условия DOOM-challenge:



  • Найдите готовое устройство, не предназначенное для игры в Doom или в другие игры.
  • Выбранное устройство должно иметь микроконтроллер с разумно ограниченной вычислительной мощностью и/или памятью в соответствии с минимальными требованиями DOOM (DOOM работает с приемлемой частотой кадров даже на 486 @ 33MHz [1], оборудованном 4MB RAM). В качестве примера мы должны исключить современные цифровые камеры, которые имеют систему на несколько сотен МГц на кристалле, с несколькими десятками мегабайт оперативной памяти.
  • Мы должны использовать именно тот микроконтроллер, который встроен в выбранное устройство. Замена невозможна. Никакого дополнительного микроконтроллера добавить нельзя. Тем не менее, разгон (например, даже если он ограничен только некоторыми периферийными устройствами или шинами) возможен при условии, что нам не нужны какие-либо методы охлаждения.
  • Для хранения файлов WAD можно добавить дополнительную флеш-память или карту памяти.
  • Можно добавить цветной дисплей, если на выбранном стандартном устройстве его нет. Разрешение должно быть достаточно высоким, чтобы можно было прилично играть в Doom. Например, экран 3216 пикселей слишком мал, но 128x64 может быть достаточно. С другой стороны, слишком большие разрешения, безусловно, потребуют очень мощного микроконтроллера, вопреки правилу 2.
  • Устройство ввода может быть любым, поэтому для этой цели можно добавить дополнительную электронику.
  • При необходимости блок питания можно заменить.
  • Мы хотели, чтобы движок был максимально приближен к исходному (ванильному) условно-бесплатному ПО Doom. Возможность играть в эпизоде 1 на карте 1 условно-бесплатной игры Doom (E1M1) это минимальная цель, даже если мы не скрываем, что мы мечтали иметь возможность сыграть полную условно-бесплатную версию без ограничений на всех картах.
  • К звуку требований нет, но звуковые эффекты были бы действительно плюсом. Если реализовано, то на аудиоподсистему ограничений нет.
  • Мультиплеер не обязателен


Тест на беременность




Принтер Canon Proxima




Осциллограф




Банкомат




DOOM в DOOM




Пианино




Minecraft




Валидатор билетов




iPod Mini




Калькулятор




Apple Watch




MacBook Pro Touch Bar




Kodak DC260 Digital Camera from 1998




На клавиатуре




На билборде




На электронной книге




На самолёте




Porsche 911




Vectrex




Паяльник




PS


Как тебе такое, AlexeyNadezhin?

zhovner, ждём DOOM на FlipperZero.

image
Подробнее..

Перевод Матёрый программист

12.06.2021 00:22:22 | Автор: admin
image

1. Матёрый программист


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

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

Но путь матёрого программиста может оказаться ловушкой, в которую можно попасться.

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

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

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

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

Я думаю, что нужно учитывать два фактора: во-первых, матёрость и продуктивность может вызвать выгорание, что в конечном итоге сказывается на вашей производительности, или это может просто сделать кодинг неприятным, так что вы будете тратить на него меньше часов. Большинство матёрых программистов хвастаются тем фактом, что они могут сделать столько же за 6 часов, сколько они делали за 14 часов. Но эти 14 часов были ВЕСЕЛМИ, вы так долго кодили, потому что вам это нравилось, вы не могли заснуть ночью, потому что вы хотели больше писать код; теперь эти 6 часов неприятны, потому что вместо того, чтобы разворачивать собственное решение, вы просто связываете вместе несколько пакетов java и perl. Во-вторых, продуктивность не единственная цель. Мы пишем код, чтобы выполнить какую-то задачу и заработать деньги, но мы также пишем код, потому что нам это нравится, и на самом деле быть менее продуктивным, но получать большее удовольствие от кодинга может быть чистым + EV. (EV в покере это сокращение от expected value означающего математическое ожидание от розыгрыша руки или определенного действия.)

2. Здоровое противодействие продюсера


Многие программисты, выполняющие обычную работу по кодингу, ненавидят вмешательство продюсера (или корпоративного руководства, или издателя, или кого-то еще). Этот человек навязывает глупые графики и не позволяет нам выполнять функции, которые мы хотим выполнять, и мы их ненавидим! Эти кодеры хотят иметь возможность составлять свое собственное расписание, выбирать свои собственные задачи и быть свободными.

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

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

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

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

3. Стандарты кодинга


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

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

Другим большим преимуществом стандартов кодинга является создание метаязыка, который меньше, чем базовый язык, и обеспечивает соблюдение определенных инвариантов. Поступая так, вы снова уменьшаете пространство, которое мозг должен учитывать. Например, вы можете потребовать, чтобы все макросы C вели себя как функции (например, не использовали области видимости и не объявляли переменные). Теперь, когда я вижу одного, я знаю, что мне не нужно беспокоиться об этих вещах. Или вы можете потребовать, чтобы глобальные переменные никогда не извлекались из внешнего источника и были доступны только через функции, называемые GetGlobal_blah. На самом деле не имеет значения, что они собой представляют, если они просты, ясны, единообразны и строго соблюдаются, потому что, только если они полностью надежны, вы можете перестать думать о них.

4. Ловушка перезрелого программиста


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

Я считаю, что они/мы в основном ошибаются.

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

Это почти всегда неправильно. Лимпить АА почти всегда неправильно, открытие 72o с UTG почти всегда неверно возможно, вы провели некоторый анализ и решили, что это правильно за этим столом в данный момент (например, лимпить АА, потому что люди, стоящие за вами, атакуют лимперов слишком много, и они думают, что вы никогда не будете лимпить АА, поэтому они легко застрянут). Это не правильно.

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

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

То же самое и в кодинге. Перезрелый программист знает ценность инкапсуляции некоторой функциональности в структуру + помощники (или класс), но они думают, что достаточно умны, могут решить не делать этого в данном конкретном случае. Нет! Неправильно. Я имею в виду, что, может быть, вы действительно правы в данном конкретном случае, но для принятия этого решения не следует использовать энергию вашего мозга, и вы будете делать это несколько раз неправильно.

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

То же самое происходит с принятием жизненных решений. Стандартный набор клише:

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

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

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

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

Подпишись, чтобы не пропустить События

16.06.2021 20:20:54 | Автор: admin

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

В примерах в статье про автоматы я использовал следующую конструкцию:

Game.Event.Invoke("joystick_updated", input);

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

public static class Game{    public static FSM Fsm = new FSM();    public static EventManager Event = new EventManager();       public static ObservableData Data = new ObservableData();...

В этих примерах можно увидеть некоторые вольности в деталях реализации. При масштабировании проекта, например, придется отказаться от статического контекста и на основе класса Game реализовать компоненты, назовем их претенциозно MonoBehaviourPro с подобной структурой для сложных подсистем, и передавать ее в качестве контекста автомату и компонентам этих подсистем. Я намеренно сглаживаю эти углы для большей наглядности примера. Сегодня мы рассмотрим класс с многострадальным названием EventManager, так как он является зависимостью ObservableData и без него мы не сможем двинуться дальше. По ссылке можно увидеть полную реализацию класса EventManager, принцип его работы предельно прост. Мы храним список делегатов c произвольной сигнатурой, подписанных на события со строковым ключом.

Важно, что мы работаем с Generic-структурой, поэтому следует помнить о Type safety. Тип аргумента при отправке события должен соответствовать сигнатурам функций, подписанных на него. Также, можно заметить, что EventManager отдельно хранит binds и binds_global и имеет отдельный интерфейс для работы с ними. Это реализация, специфичная для Unity. Дело в том, что там существует система сцен, позволяющая подгружать или выгружать сцены и объекты. И разница между этими двумя словарями в том, что первый очищается при выгрузке сцены. В идеальном мире мы всегда подписываем объект в Awake и отписываем его в OnDestroy. В таком случае можно было бы обойтись одним binds, не очищая его никогда. Каждый объект подписывается и отписывается в рамках своего жизненного цикла и разве что при переходе между сценами происходило бы немного лишней работы над поштучным отписыванием выгружаемых объектов. Но такой подход не прощает ошибок, выгруженный подписчик в лучшем случае сразу сломает вызов делегата и будет найдена, а в худшем - станет причиной утечки памяти. Так что, в качестве "защиты от дурака" лучше при переходе явно отписывать все, что не было обозначено как Global.

Итак, интерфейс EventManager cводится к 5 методам:

        public void Bind<T>(string name, Action<T> ev)        public void BindGlobal<T>(string name, Action<T> ev)        public void Unbind<T>(string name, Action<T> ev)        public void UnbindGlobal<T>(string name, Action<T> ev)                  public void Bind(string name, Action ev)        public void BindGlobal(string name, Action ev)        public void Unbind(string name, Action ev)        public void UnbindGlobal(string name, Action ev)                  public void Invoke<T>(string name, T arg)                  public void Invoke(string name)

Мы можем подписываться на события и отправлять их. И все это с аргументом произвольного типа. В примере из статьи про FSM мы передавали ввод с джойстика в автомат и, если состояние предусматривает такую возможность, передавали в EventManager событие изменения положения джойстика , на которое может подписаться компонент, управляющий положением игрока(Или потомок MonoBehaviourPro, какой нибудь PlayerController, который передаст информацию о вводе в свой автомат, и если игрок в состоянии SPlayerDriving , будет передавать ввод с джойстика уже автомобилю, за рулем которого он сидит, а если в SPlayerClimbing, джойстик будет двигать игрока перпендикулярно нормали плоскости, по которой он движется, с соответствующей анимацией. Но это уже более сложные примеры, не будем на этом задерживаться). Или же, на входе в состояние игры SWin мы можем отправить событие level_done, а на него подписать анимацию экрана победы, конфетти, и чего там еще ваш ГД придумает.

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

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

Эта статья - вторая в серии:
- Разделяй и властвуй Использование FSM в Unity
- Подпишись, чтобы не пропустить События

Подробнее..

Принцип работы EditorScript

21.06.2021 00:15:47 | Автор: admin

Всем привет. С вами я, stalker320, и сегодня я хотел бы рассказать про написание служебных скриптов, запускающихся в редакторе. Всем желающим прочесть - добро пожаловать под кат


EditorScript - это такой скрипт, который можно запустить по нажатию комбинации Ctrl+Shift+X прямо из движка. Он может исполнять различные служебные функции. К примеру создать необходимую структуру каталогов в проекте.

toolextends EditorScriptvar folders: PoolStringArray = [# Наши папки к созданию"res://assets/textures/",# Их определяет разработчик"res://assets/fonts/",# Просто напишите сюда все конечные пути, что хотите создать"res://resources/","res://addons/","res://scenes/","res://scripts/singletons/","res://scripts/resources/","res://scripts/editor_scripts/"]var placeholder: Resource = load("res://placeholder.tres")# Ресурс-пустышка для сохранения структуры файлов. По желаниюfunc _run() -> void: # Входная функция этого скриптаvar dir = Directory.new()for folder in folders: # проход по списку папокif !dir.dir_exists(folder):var err = OKerr = dir.make_dir_recursive(folder)if err != OK:prints("Error", err)returnelse:if !dir.file_exists(folder.plus_file("placeholder.tres")):# Создаём файл плейсхолдера для гита если не существуетerr = ResourceSaver.save(folder.plus_file("placeholder.tres"), placeholder)if err != OK:prints("Error", err) returnelse:# Говорим что создали (не обязательно)prints("Making", folder)prints("Making", folder.plus_file("placeholder.tres"))print("Successful. Structure created or already exists.")return

К сожалению я освоил их не очень хорошо, поэтому создать генератор какого-нибудь API для дальнейшего моддинга игры фанатами пока не вышло. (Хотя создать необходимую структуру файлов вышло, а это значит, что кто-либо другой может расширить функционал через словарь и создавать необходимые скрипты). Кроме того, чтобы создавать нужную структуру файлов прямо в редакторе, через метод get_scene() можно взаимодействовать и с самой сценой (Достойные примеры скриптов и сцен, к сожалению, отсутствуют).

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

Спасибо за внимание. Не думаю, что буду писать статьи в дальнейшем очень часто, но у меня есть идеи, о чём можно написать.

Подробнее..

Недельный геймдев 22 13 июня, 2021

16.06.2021 00:20:01 | Автор: admin

Из новостей на этой неделе: стала доступна превью версия Unreal Engine 4.27 с включёнными в движок Bink Video и Bink Audio, Unity выпустили новый стартовый пак, вышла новая версия движка Diligent Engine 2.5, Activision выпустили расширение для Windows для просмотра USD-файлов, разработчики Cascadeur получили дополнительные 1.5 миллиона долларов на развитие продукта, PolyHertz выпустил новый скрипт UnChamfer Pro для 3ds Max, Khronos запускают программу сертификации 3D-просмотровщиков.

Из интересностей: подробный доклад от Insomniac про работу со светом в Marvels Spider-Man, занятная механика для VR игры, полезный доклад от Риотов про то, как они балансят и нерфят персонажей.

Обновления/релизы/новости

Стала доступна превью версия Unreal Engine 4.27

Из ключевого:

  • Oodle и Bink теперь встроены в движок.

  • Улучшения по части Open XR.

  • Path Tracer теперь в бетке.

  • Куча улучшений GPU Lightmass: запекания, теней, поддержки mGPU.

  • Обновление Niagara: версионность модулей, новый дебагер, куча улучшений UX/UI.

  • Оптимизировали рендеринг на мобильных платформах. Ключевые направления оптимизаций: Distance Field Shadows, Fast Approximate Anti-Aliasing (FXAA), Temporal Anti-Aliasing (TAA).

  • Изменения по части Datasmith, особенно в Datasmith Exporter Plugin для ArchiCAD.

  • Огромное число изменения инструмента для синематиков и виртуального продакшена.

Bink Video и Bink Audio теперь доступны в Unreal Engine бесплатно

Epic Games выпустили последние изменения по интеграции технологии RAD Game Tools (которые приобрела в начале этого года) в Unreal Engine. Доступно в Unreal Engine 4.27 и Unreal Engine 5.

Bink Video и Bink Audio кроссплатформенные видео и аудио кодеки с упором на производительность.

Разработчики Cascadeur получили дополнительные 1.5 миллиона долларов от Nekki

Спустя 2 месяца после выхода в ранний доступ этот инструмент для анимаций насчитывает уже 80000 пользователей. Команда, тем времени, из 25 разработчиков должна вырасти до 30. Компания планирует достичь двух важных этапов к полноценному релизу в 2022:

  1. Улучшить по максимуму уникальные инструменты Deep Physics с поддержкой AI.

  2. Функциональные возможности Cascadeur должны быть расширены дополнительными стандартными инструментами.

Unity выпустили новый стартовый пак

Набор содержит бесплатные и легковесные базовые контроллеры персонажей от первого и третьего лица для последней версии Unity 2020 LTS и более поздних версий с использованием Cinemachine и Input System.

Старые версии Unity также могут работать с паком, но, вероятно, нужно будет что-то дотюнить.

МФТИ и Gaijin Entertainment запускают магистерскую программу (4 семестра) по программированию игр

Заявку нужно подать до 30 июня. Обучение очное.

Вышла новая версия движка Diligent Engine 2.5

В этой версии:

  • Трассировка лучей теперь включена на Metal.

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

  • Несколько контекстов позволяют выполнять асинхронные вычисления и параллельный рендеринг.

  • Запросы на RT позволяют бросать лучи из обычных шейдеров (пиксельные, вычислительные и т. д.).

Activision выпустили расширение с открытым исходным кодом для Windows для просмотра USD

Проект доступен на GitHub под лицензией Apache 2.0 и позволяет пользователям Windows взаимодействовать с USD файлами (всё более широко используемым отраслевым форматом, созданным Pixar) прямо в Windows Explorer.

Первую версию браузера ассетов добавят в Blender 3.0

Пользователи давно ждут нечто подобное.

Epic Games поделились кратким руководством для тех, кто хочет познакомиться с Unreal Engine 5

В 16-страничной pdf-ке разобраны основные вопросы и приведены полезные ссылки. Ничего того, что есть в онлайн документации, но зато всё кратко и сжато. Как раз подойдёт для ознакомления.

PolyHertz выпустил новый скрипт UnChamfer Pro для 3ds Max

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

BuildBox решили поменять прайс на свой движок после негодования клиентов

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

Ранее компания изменила прайс, помомо подписки захотели процент процент с ревенью: 30%, если у вас план Plus, 10%, если у вас PRO план. Вовремя одумались.

Faceware Technologies запустили Faceware Studio PLE, новую бесплатную версию Faceware Studio, программы для мокапа в реальном времени

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

Вышла бетка Kinetix Advanced

Облачный инструмент позволяет сгенерировать 3d-анимацию из .MP4 видео.

Можно попробовать бесплатно, преобразовав 60-секундное видео. За 15 евро в месяц можно конвертировать до 3 минут видео и иметь доступ ко всем инструментам, которые предлагает Kinetix, а за 120 евро в месяц 30 минут видео.

Khronos запускают программу сертификации 3D-просмотровщиков

Консистентное отображение на различных платформах повышает доверие потребителей. CGTrader и Sketchfab уже подписались.

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

Интересные статьи/видео

4 полезных совета по работе с Substance Painter для новичков

  1. Маски ваши лучшие друзья.

  2. Будьте рассказчиком. Недостаточно просто навесить текстурки, важно понимать, как эти объекты будут смотреться рядом с другими.

  3. Нужно понимать/осознавать как свет и игровые движки влияют на ваши текстуры.

  4. Создайте свою собственную библиотеку материалов.

На этой неделе Epic Games обсудили новую систему глобального освещения Lumen из Unreal Engine 5

Специалисты рассказали, что это такое, как включить, и что технология из себя предоставляет.

Полезный доклад от Риотов про то, как они балансят и нерфят персонажей

Не смотрите на оценки под видео, контент норм. Там приведены реальные данные и метрики и, что самое главное, докладчик рассказывает, как они принимают решения на основе этих данных.

Подробный доклад от Insomniac про работу со светом в Marvels Spider-Man

Разное

Разбор VFX из фильма Поколение Вояджер (2021)

Подробнее..

Свой ремейк ZX игры Reskue в Steam

12.06.2021 16:15:59 | Автор: admin

Да, понимаю, что это игра про учёных, но это не игра про немого учёного с монтировкой с цифрой 3, которую все ждут. Что вышло за 4 года разработки.

Официальное описание: Научная станция в глубоком космосе перестала отвечать на запросы. Что там произошло? Вы агент, прибывший выяснить, что случилось и Ваша задача спасти важное открытие, сделанное на станции.

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

Заправьте свой корабль радиоактивным топливом и спасите ученых. Берегите себя, науку и удачи!

Это ретро экшен, требующий достаточной быстроты, либо ловкости, либо хитрости от игрока. Есть несколько тактик прохождения игры. Кроме арсенала в 10 видов оружия, каждое из которых накладывает особый эффект на врага и имеет несколько режимов стрельбы, есть ещё и хитрость в виде ловушек или предметов сильно отвлекающих противника. некоторых настолько что игрок будет почти невидим для врагов. Даже на нормальной сложности игра не будет лёгкой прогулкой по которой игрока будут водить за ручку и обьяснять Press F to Win. Однако если вам игра покажется слишком лёгкой уровень сложности можно повысить.

В самой игре заложена и пара "пасхалок" напоминающих о спектруме. Я не скажу где они однако одна из них содержит пару обьектов из Boulder dash, а другая ещё что-то.

Ключевые обновления:

  • Добавлен режим хотсита - кооп (. затем kp9) и версус (. затем kp7). (Игра на 2 клавиатурах и/или джойстиках). Cетевая игра увы возможна только через Steam remote play.

  • Все почти враги теперь анимированы (новое видео пока не готово)

  • Внешний интерфейс (USER GUI) доработан. (Инвентарь, выбранное оружие, датчик жизни, кулдаун, селектор оружия.)

  • Встроенная игровая справка по F2 с описанием тактики поведения и арсенала.

Ключевые особенности

  • Редактор карт поддерживает импорт карт M2K (mission 2000), Rescue+ с реального ZX-Spectrum. Карты будут работать если их копировать программой HOBETA.

  • Мультиязычность и кроссплатформенность.

  • Высокая скорость работы даже на устаревших компьютерах.

Подсказка: Максимально просто игру можно пройти вдвоем - Один из игроков должен выбрать ученого при начале совместной игры.

Игра нетребовательная идёт почти на всём. Требования: 64бит и OpenGL 3.3 и хотя бы 30 мб места.

Steam Ранний доступ.

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

Я ранее писал статью на DTF и если кто хочет просто попробовать игру Reskue или M2K или Colony (очень ранняя версия) может скачать их ниже.

Видео новее пока нет. если только про кооператив и версус ссылка под видео. С тех пор игра была сильно переработана но я пока не осилил трейлер.

Хотсит на русском.

Новый трейлер на польском.

Я на вопросы иногда делаю выпуски видеоответов. Реже чем надо было бы, но делаю. https://www.youtube.com/watch?v=JJAe2b-kTgs - Руководство о портировании готовой игры на Love в Android APK (с подписью) для Linux. В блоге разработчика (devblog) бывают и арты и рисунки и другая всячина.

Игра написана с нуля и сохранившая в основном идею оригинала (Rescue od Mastertronic) и схожесть с Spectrum играми (тайлы, цветовая гамма, некоторая хардкорность геймплея и некоторые команды в Lua движке.). От оригинальной игры не используется ничего, перерисовано все что возможно. Изначально я делал ремейк собственной игры M2K (mission2000), затем понял что на основе движка могу сделать новую игру что и начал в 2019, вдохновили меня в коллективе confa-gd на конкурсе Джем победы на это. Канал по игре.

C чего всё начиналось:

Это оказался прекрасный фундамент для применения множества идей как Sci-fi так и просто современных удобств геймплея каждую из которых пришлось делать самому, т.к. движок мой авторский на Love framework. Я постарался бережно развить идею так как ранее с ограничениями платформы ее развить было бы значительно сложнее. Я с трудом нашел нескольких художников и аниматоров и за ещё 2 года и 16К получилась эта игра. Отдельная история и целая лекция получилась по работе со Steamworks чтобы игра попала в магазин, это заняло целых полгода в основном доработки тексту. Я даже не думаю что она вообще когда то отобьется и будет кормить меня и принесет мне хоть что то. мне просто хотелось возродить частичку классики так как я её вижу и сделать ее доступной всем.

Также я веду небольшой ютуб и телеграм каналы без мемасиков и приколов посвященный Linux для домашнего использования. Сборка в основном для тестирования Windows игр предназначена. Сам я выбрал Mint c Mate DE немного новостей немного взаимопомощи.

N.B. Людям, которые ждут, что один человек почти в одно лицо накодит им Ведьмака 3 в 3D за денек, прошу выйти из чата. Этим методом получатся только игры для Gry z kosza (польская передача об очень плохих играх).

Мне просто хочется, чтобы в эту игру можно было сыграть и через много лет спустя, я думаю Steam с нами всеми надолго и игра там точно проживёт много лет. Да название я написал в духе названия mortal kombat. А почему нет?

Также я время от времени обновляю код движка на github. У меня там несколько проектов.

Подробнее..

Перевод Предупреждение для разработчиков о грядущих критических изменениях в движке

16.06.2021 14:10:53 | Автор: admin

Поддержка движка отстает, а исправление положения - задача не из легких

Разработчик программного обеспечения Unity Джош Питерсон рассказал нам о будущем поддержки .NET в широко используемом движке для разработки игр.

Согласно опросу, проведенному в конце прошлого года, использование C# в разработке игр является одной из основных причин популярности C#, но его реализация в Unity несколько беспорядочна.

Обработчик сценариев C# использует Mono, но разработчики также могут использовать .NET Framework при работе в Windows. Mono - это старая реализация .NET с открытым исходным кодом, созданная до того, как Microsoft выпустила .NET Core. Microsoft получила контроль над Mono вместе с Xamarin в 2016 году, и Mono теперь имеет много общего кода с .NET Core, но он все равно остается отдельным продуктом, в котором по-прежнему в некоторых сценариях используется рантайм.

Unity поддерживает собственный форк Mono, который, по словам Питерсона, примерно на два года отстает от upstream кода. Сейчас команда обновляет его до последней версии кода из upstream репозитория Mono - изменение, в котором он уверен на 95%, что оно попадет в следующий релиз, Unity 2021.2. Он добавил, что эта работа улучшит производительность и исправит ошибки, но сама по себе не привнесет никаких новых фич .NET - хотя она закладывает фундамент для фич, которые будут добавлены в будущем.

Тем не менее, Питерсон ожидает, что в Unity 2021.2 будет добавлена поддержка .NET Standard 2.1, но на этот раз с 75% уверенностью. Версии .NET Standard определяют набор API, которые должна поддерживать реализация .NET. Сложный аспект .NET Standard 2.1 заключается в том, что .NET Framework навсегда застрял на .NET Standard 2.0. Питерсон говорит: Хотя .NET Framework не поддерживает .NET Standard 2.1, библиотеки классов Mono его поддерживают, поэтому мы должны быть в состоянии выстроить хороший мост к экосистеме на основе .NET Core.

Это обновление не может произойти быстро, поэтому некоторые разработчики разочарованы таким медленным прогрессом. Предпринимаются ли какие-либо подвижки в направлении отказа от Mono в пользу полной интеграции .NET? Особенно сейчас, когда .NET становится настолько кроссплатформенным, - спросил пользователь в августе прошлого года. К числу востребованных фич относятся Span<T>, представленный в C# 7.2, и оператор диапазона, представленный в C# 8.0. Microsoft выпустила C# 8.0 в сентябре 2019 года, и внедрение полного набора фич в Unity заняло много времени. Пользователи также обеспокоены отставанием в производительности .NET в Unity.

Питерсон говорит, что поддержка C# 8.0 в 2021 году по-прежнему будет реализована на основе Mono. Он также выразил надежду, что C# 9.0, выпущенный Microsoft в ноябре 2020 года, также будет поддерживаться, но это зависит от добавления фич в Mono и IL2CPP (который преобразует код .NET в C++ для компиляции), в чем его уверенность снизилась до 50%, сказал он.

Что касается перехода на .NET Core, это вряд ли будет скоро. Питерсон сказал, что Unity, вероятно, откажется от .NET 5 в пользу .NET 6, который является предстоящим релизом с долгосрочной поддержкой. Даже тут он заметил, что похоже, что JIT рантайм здесь будет Mono, но он не уверен в этом и добавил, что нам может потребоваться перейти непосредственно к CoreCLR в целях поддержки .NET 6.

Одна из проблем заключается в том, что функция редактора Unity, называемая перезагрузкой домена (domain reloading), которая сбрасывает состояние сценария, зависит от функции (AppDomains), которой нет в .NET Core. Питерсон говорит, что это может быть реализовано другим способом, но это будет критическое изменение. Для разработчиков игр .NET 6 в любом случае станет критическим изменением, поскольку любые сборки, скомпилированные с использованием mscorlib.dll из экосистемы .NET Framework, не будут работать и должны быть перекомпилированы.

Сложность, связанная с .NET Standard, .NET Framework, .NET Core и Mono, является проблемой для разработчиков Unity и показывает, что унификация .NET, которую затеяла Microsoft, на самом деле является длительным процессом, а не тем, что может произойти в одночасье с выпуском .NET 5.0 в прошлом году.

Единственное, что меня волнует, это поддержка .NET 6. Самая большая проблема, с которой я столкнулся, заключалась в низкой производительности редактора и длительном времени итерации по мере увеличения размера проекта. В настоящее время я отказался от Unity, потому что его было слишком неудобно использовать, и перешел на Unreal, - сказал другой пользователь, добавив, что Mono скоро станет историей, и у него нет будущего.

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


В преддверии старта курса "Unity Game Developer. Professional" приглашаем всех желающих посетить бесплатный двухдневный интенсив в рамках которого мы разработаем все необходимые инструменты и архитектуру для диалоговой системы (чтобы наш персонаж мог общаться с неигровыми персонажами), реализуем инвентарь, добавим в игру торговцев и создадим систему квестов. Всего два занятия и практически готовая RPG у вас в кармане.

Подробнее..

Открылся набор в Indie Games Accelerator и Indie Games Festival от Google Play

14.06.2021 12:13:27 | Автор: admin

Indie Games Accelerator и Indie Games Festival две программы для независимых (инди) разработчиков мобильных игр, организованных командой Google Play. Программы направлены на то, чтобы помочь небольшим игровым студиям и разработчикам стать популярнее в Google Play независимо от того, на какой стадии находятся их проекты.

В этом году обе программы пройдут в онлайн-формате, заявки принимаются до 1 июля подробности под катом.

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

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

Indie Games Accelerator: обучение и менторская поддержка

Эта программа разработана для начинающих инди-разработчиков, которые работают над прототипами будущих игр или делают тестовые релизы.

Проекты, которые пройдут отбор и станут участниками акселератора, смогут присоединиться к 12-недельной образовательной программе, а также получат возможность поработать над своими проектами вместе с экспертами из Google, крупных игровых студий и венчурных фондов. Rovio, Game Insight, Zynga, Play Ventures, Unity Technologies, Belka Games с полным списком менторов и условиями участия можно ознакомиться здесь.

В этом году в акселерационной программе участвуют более 70 стран, заявки на Indie Games Accelerator из России, Украины и Беларуси будут приниматься впервые!

Indie Games Festival: промо-кампании для финалистов

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

Основные критерии отбора: инновационность, увлекательность и дизайн. Среди призов: фичеринг на Google Play и промо-кампании для 3 игр-победителей стоимостью 100 000 евро.

Условия участия: в программе участвуют 29 стран Европы, включая Россию, Украину и Беларусь; максимальное количество человек в команде 50, игра должна быть выпущена на Google Play не ранее 3 марта 2020 г. Подробнее с правилами участия и критериями отбора можно ознакомиться здесь.

В прошлом году в финал конкурса прошло три проекта из России: My Diggy Dog 2 от King Bird Games, Color Spots от UX Apps и Tricky Castle от Team Tricky подать заявку можно до 1 июля.

Подробнее..

We need to go deeper как пасхалка в приложении Delivery Club сократила субъективное время ожидания еды

11.06.2021 16:11:37 | Автор: admin


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

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

Сашин скриншот того, как всё начиналось.

Саша:
У меня есть свой небольшой проект словесно-карточная игра Кто из нас? На одном из очередных разборов игры родилась мысль, что можно внутри игры спрятать ещё одну игру. Люди найдут её и скажут: Ого, я играл в одну, а сейчас играю в совершенно другую. Но игра, которую я делаю, не настолько популярна, поэтому если туда прятать ещё одну игру, то её просто никто не увидит. Возникла вторая идея. Я работаю в Delivery Club, и у нас миллионы пользователей, у которых есть общая проблема время ожидания заказа. Нужно либо сокращать время доставки, либо как-то развлечь пользователя, пока он ожидает. И я пошёл по второму пути: придумал решение в виде небольшой игры внутри основного приложения.
Дизайн для первого прототипа змейки сделала девушка Саши, а звуки Саша создал сам в интернет-синтезаторе.


Прототипы первых экранов.

Уже в январе ребята буквально за полдня в коворкинге написали MVP на Swift и SpriteKit. Там были крупные кнопки и небольшой игровой экран, как в тетрисе. В финальной версии от кнопок на экране отказались: из-за того, что они плоские, а не объёмные, как на настоящей консоли, змейкой было неудобно управлять.
Саша:
Мы собрались с Сахеем и начали писать приложение в духе лучших стартапов. Заказали пиццу. Пива там не было, поэтому мы пили кофе. За один день у нас был готов прототип, который уже выполнял свою задачу. Игра запускалась, был первый квадратик, который начинал ездить. Он поедал эмодзи, змейка росла; врезавшись в стенку, она умирала. Осталось её только докрутить: добавить включение и выключение звука, доработать экраны начала и конца игры. Этим мы занялись уже в свободное время дома.
Сахей:
Очень понравился этот режим стартапа. Обычно на работе есть все спецификации и документация протоптанная тропинка, по которой ты идёшь. А тут был полный полёт мысли. Мы ещё хотели изначально поменять рендеринг на SwiftUI или на UIKit, но не стали так извращаться, SpriteKit отлично подходил для нашей задачи. Он оптимизирован под отрисовку спрайтов. Если в UIKit 100-200 вьюшек, то FPS очень сильно проседает, а в SpriteKit нет. Но мы фана ради хотели попробовать.


Разработка MVP.

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

Финальную версию змейки пришлось достаточно сильно упростить ребята увлеклись и придумали много дополнительных возможностей. Решили оставить простой и красивый вариант, чтобы не отвлекать пользователя от основной функции приложения.
Саша:
Когда Лера показала свой дизайн, у нас с Сахеем загорелись глаза. Мы такие: Вау! Можно же настолько красиво и современно всё сделать! У нас появилась куча новых идей. Можно нарабатывать опыт у змейки с каждой игрой и набирать очки, за них покупать змейке какой-то апгрейд, типа шапочки или щита, чтобы она врезалась в стенку, а у неё на одну жизнь больше было. Но всё-таки история со змейкой должна была где-то кончиться, чтобы дойти до релиза. И мы решили упростить игру, чтобы не смещать фокус с основного функционала Delivery Club.
Лера:
На самом деле, когда в работе есть много рутинных задач, и внезапно кто-то приходит и предлагает сделать игру, это очень воодушевляет. Поэтому мы сразу активно включились в историю со змейкой и стали делать супер-красивые дизайны, продумывать механики. Все механики не были добавлены в финальный релиз ещё и потому, что вначале мы хотели всё проверить. Просто потратить кучу времени на разработку и сделать фичу, которую потом нашли бы три человека, было бы странно. Поэтому мы сошлись на простом решении, которое можно было быстро сделать, запустить и посмотреть реакцию пользователей. Если это окажется интересным, мы будем развивать игру: делать рейтинги, баллы и так далее.
Георгий:
После того, как ребята реализовали версию под iOS, мы принялись адаптировать приложение под Android. Разработка велась на Kotlin, всё сделали нативно, без использования сторонних библиотек. В конечном итоге версию под Android получилось написать всего за четыре дня. Идея была творческой и разнообразила череду рутинных задач.
Реализацию Android-версии Змейки можно посмотреть на GitHub.



Промежуточные варианты дизайна экранов.

18 мая змейку добавили в приложение Delivery Club. Чтобы в неё поиграть, нужно потрясти телефон на экране с заказом. Мы нигде не писали про пасхалку, но уже сейчас в неё играют 5-7 тысяч человек в день со средним временем игры 3 минуты 10 секунд. Нескольким тысячам пользователей игра скрасила минуты ожидания заказа. Надеемся, теперь игроков станет больше.

А если после прочтения у вас появились собственные идеи для пасхалок в Delivery Club, принимайте участие в нашем конкурсе. Лучшие идеи будут опубликованы на N + 1 и, возможно, реализованы в нашем приложении.
Подробнее..

Морской бой на Java для новичков. Level 1

17.06.2021 10:17:44 | Автор: admin

Всем привет!

Статья посвящена тем, кто только врывается в увлекательный мир программирования на Java и ищет применения своим знаниям. Классно, что вы теперь знаете, как создавать переменные, методы и массивы, но, конечно, хочется писать "полезные" для человечества программы, а не выполнять многочисленные мелкие упражнения и задачи, хотя без этого тоже никуда. В общем, будем дополнять теорию практикой. Поехали!

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

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

  2. Одновременно в игре могут участвовать только два человека.

  3. В самом начале игроки "представляются" - программа "спрашивает" (предлагает пользователям ввести), какие у них имена

  4. У каждого игрока есть своё поле - квадрат 10х10 клеток

  5. Затем игроки по очереди расставляют свои корабли. Как и в "бумажной" версии - каждый может поставить 4 однопалубных корабля, 3 двухпалубных, 2 трехпалубных и 1 четырёхпалубный.

  6. Корабли можно располагать только по горизонтали или по вертикали.

  7. Игроки не видят расположение кораблей друг друга.

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

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

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

    Второй вариант, если игрок не попал ни в какой корабль, то ход переходит второму игроку.

  10. Таким образом, как описано в пункте 8, передавая ход друг другу, игроки пытаются как можно раньше уничтожить корабли друг друга. Тот, кто первым, одолеет флотилию врага - победитель. Программа печатает поздравление и прекращает свою работу.

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

Как и в любом Java приложении нам потребуется класс (не умаляя общности назовём его Main), в котором будет объявлен, я думаю уже всем известный, метод main.

public class Main {public static void main(String[] args) {  //your code will be here}}

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

Опираясь на пункты 1-3 утвержденного сценария, реализуем функционал приложения, который будет предлагать игрокам ввести свои имена. Здесь нам придётся использовать класс java.util.Scanner, который умеет считывать введенные значения в консоли.

public class Main {    static Scanner scanner = new Scanner(System.in);    public static void main(String[] args) {        System.out.println("Player 1, please, input your name");        String player1Name = scanner.nextLine();        System.out.println("Hello, " + player1Name + "!");        System.out.println("Player 2, please, input your name");        String player2Name = scanner.nextLine();        System.out.println("Hello, " + player2Name + "!");    }}

Подробнее о коде:

В строке 2 создаем статичное свойство класса Main scanner.

Нестатический метод nextLine() класса Scanner (строки 6 и 11) обращается к консоли и возвращает строку, которую он еще не считывал.

После получения имени пользователей, программа выводит приветствие в консоль - "Hello, {username} !"

В консоли будем видеть следующее, если запустим код сейчас.

Player 1, please, input your nameEgorHello, Egor!Player 2, please, input your nameMaxHello, Max!

Поговорим о том, как мы будем отображать поле боя и заполнять его кораблями. Пожалуй, что наиболее логичным будет использование двумерного массива char[][] buttlefield. В нем мы будем отображать расположение кораблей. Договоримся, что удачное попадание в корабль противника будем отображать символом #. Неудачный выстрел будем помечать символом *. Таким образом изначально, массив будет проинициализирован дефолтовым для примитива char значением ('\u0000'), а в процессе игры будет заполняться символами # и *.

public class Main {static final int FILED_LENGTH = 10;    static Scanner scanner = new Scanner(System.in);public static void main(String[] args) {    System.out.println("Player 1, please, input your name");    String player1Name = scanner.nextLine();    System.out.println("Hello, " + player1Name + "!");    System.out.println("Player 2, please, input your name");    String player2Name = scanner.nextLine();    System.out.println("Hello, " + player2Name + "!");        char[][] playerField1 = new char[FILED_LENGTH][FILED_LENGTH];    char[][] playerField2 = new char[FILED_LENGTH][FILED_LENGTH];    char[][] playerBattleField1 = new char[FILED_LENGTH][FILED_LENGTH];    char[][] playerBattleField2 = new char[FILED_LENGTH][FILED_LENGTH];}}

Подробнее о коде:

В строке 2 мы создаем константу FIELD_LENGTH, которая будет содержать размер поля - согласно требованию 4 - проинициализируем FIELD_LENGTH значением 10.

В строках 14-18 создаем двумерные массивы char. playerFiled1 и playerField2 - массивы, в которые будем записывать расположение кораблей каждого игрока. Размеры массивов равны размерам поля - логично, ведь эти двумерные массивы фактически отображают поля.

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

public class Main {    static final int FILED_LENGTH = 10;    static Scanner scanner = new Scanner(System.in);    public static void main(String[] args) {        System.out.println("Player 1, please, input your name");        String player1Name = scanner.nextLine();        System.out.println("Hello, " + player1Name + "!");        System.out.println("Player 2, please, input your name");        String player2Name = scanner.nextLine();        System.out.println("Hello, " + player2Name + "!");        char[][] playerField1 = new char[FILED_LENGTH][FILED_LENGTH];        char[][] playerField2 = new char[FILED_LENGTH][FILED_LENGTH];        fillPlayerField(playerField1);        fillPlayerField(playerField2);    }}private static void fillPlayerField(char[][] playerField) {// your code will be here}

Метод fillPlayerField должен быть статическим (static), так как вызываться он будет из метода main, который по определению должен быть статическим. fillPlayerField не будет возвращать никакого значения (void). В этом методе будет реализована логика по получению координат корабля от пользователя и запись в массив playerField нового корабля.

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

Приведу вывод программы в консоль, который мы ожидаем увидеть после создания метода fillPlayerField:

Расставляем 4-палубный корабль. Осталось расставить: 1Input x coord: 1Input y coord: 11. Horizontal; 2. Vertical ?1

Наконец-то приступаем. На данный момент имеем:

private static void fillPlayerField(char[][] playerField) {    // your code will be here}

Нам нужно расставить корабли с палубами от 4 до 1. Здесь дело идёт к циклу. Предлагаю без лишнего пафоса использовать for. Заметим, кораблей с одинаковым числом палуб может быть несколько, поэтому нам нужно ещё как-то контролировать, чтобы пользователь мог разместить лишь определенное число кораблей с заданным количеством палуб (см. бизнес требование 5) - эта задача также эффективно решается с помощью цикла - без пафоса также используем for.

private static void fillPlayerField(char[][] playerField) {// i - счётчик количества палуб у корабля    // начинаем расстановку с корабля, которого 4 палубы, а заканчиваем кораблями с одной палубой    for (int i = 4; i >= 1; i--) {      // см. подробнее о коде под этой вставкой    for (int k = i; k <= 5 - i; k++) {          System.out.println("Расставляем " + i + "-палубный корабль. Осталось расставить: " + (q + 1));        // some your code here        }    }}

Подробнее о коде:

На 5 строчке мы создаём цикл for (int k = 0; k <= 5 - i; k++). Объясню, откуда такая магия. Нам нужно как-то понимать, сколько кораблей каждого типа (с определенным количеством палуб) пользователь может поставить.

Мы можем создать еще один двумерный массив, в котором мы захардкодим что-то в духе:

int[][] shipTypeAmount = {{1, 4}, {2, 3}, {3, 2}, {4, 1}};

Мы бы в первом цикле (см. строку 4) перебирали значение количества палуб, потом искали бы в двумерном массиве, какое количество кораблей соответствует данному типу. На мой взгляд, такое решение качественное, однозначно, если бы мы писали коммерческую программу, то сделали бы именно так, но сейчас такая красота выглядит сложной - оставим это как задачу со звёздочкой, для тех, кто захочет "причесать" свой код.

Я же предлагаю отметить особенность, что сумма количества кораблей и количества палуб - величина постоянная. Действительно, 1 + 2 = 5; 2 + 3 = 5; 3 + 2 = 5; 4 + 1 = 5 . Поэтому, зная количество палуб у корабля (зная тип корабля), мы можем посчитать, сколько кораблей такого типа может быть установлено одним играком. Например, 5 - 1 = 4 - таким образом, каждый игрок может поставить 4 однопалубных корабля. В цикле for на строке 6 реализована проверка условия цикла "лайтовым" способом - на основе этого интересного свойства.

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

private static void fillPlayerField(char[][] playerField) {        for (int i = 4; i >= 1; i--) {            // растановка самих кораблей            for (int k = i; k <= 5 - i; k++) {                System.out.println("Расставляем " + i + "-палубный корабль. Осталось расставить: " + (q + 1));                System.out.println("Input x coord: ");                x = scanner.nextInt();                System.out.println("Input y coord: ");                y = scanner.nextInt();                System.out.println("1 - horizontal; 2 - vertical ?");                position = scanner.nextInt();                // если корабль располагаем горизонтально              if (position == 1) {                    // заполняем '1' столько клеток по горизонтали, сколько палуб у корабля                    for (int q = 0; q < i; q++) {                        playerField[y][x + q] = '1';                    }                }                            // если корабль располагаем вертикально                if (position == 2) {                  // заполняем столько клеток по вертикали, сколько палуб у корабля                    for (int m = 0; m < i; m++) {                        playerField[y + m][x] = '1';                    }                }              // печатаем в консоли поле игрока, на котором будет видно, где игрок уже поставил корабли              // о реализации метода - см. ниже                printField(playerField);            }        }    }

Подробнее о коде:

Корабль помечаем символом '1' столько раз, сколько палуб он имеет - если корабль четырёхпалубный, то он займёт 4 клетки - помечаем 4 клетки значением '1'.

Нам неоднократно потребуется печатать поля игроков, либо поля их выстрелов по вражескому флоту. Для того, чтобы сделать это - создаём метод printField.

static void printField(char[][] field) {        for (char[] cells : monitor) {            for (char cell : t) {              // если значение дефолтовое (в случае char - 0), значит в данной клетке              // корабль не установлен - печатаем пустую клетку                if (cell == 0) {                    System.out.print(" |");                } else {   // если клетка непустая (значение отличается от дефолтового),                  //тогда отрисовываем сожержимое клетки (элемента массива)                    System.out.print(cell + "|");                }            }            System.out.println("");            System.out.println("--------------------");        }    }

На экране метод будет так отображать расстановку кораблей:

 | | | | | | | | | |-------------------- |1|1|1|1| | | | | |-------------------- | | | | | | | | | |-------------------- | | | | | | | | | |-------------------- | | | | | | | | | |-------------------- | | | | | | | | | |-------------------- | | | | | | | | | |-------------------- | | | | | | | | | |-------------------- | | | | | | | | | |-------------------- | | | | | | | | | |--------------------

Вот игроки уже заполнили свои корабли на карте, и теперь мы можем приступить к реализации пунктов 8-10 бизнес-требований заказчика.

Логику по получению от пользователя координат выстрела, обработки выстрела и передачи хода опишем в методе playGame. Дабы придерживаться (или пока только стараться) принципа single responsobility - не забываем делить логику на методы (1 функциональность - 1 метод, но тоже держим себя в руках, код, в котором 100500 однострочных методов тоже не комильфо) - примерно из этих соображений получились еще методы handleShot и isPlayerAlive. Реализация обоих приведена ниже

/*** Метод реализует логику игры: выстрел и передача хода.*/private static void playGame(String player1Name, String player2Name, char[][] playerField1, char[][] playerField2) {        // "карты" выстрелов - создаём двумерные массивы, которые содержат все выстрелы  // удачные (#) и неудачные (*)  char[][] playerBattleField1 = new char[FILED_LENGTH][FILED_LENGTH];        char[][] playerBattleField2 = new char[FILED_LENGTH][FILED_LENGTH];  // вспомогательные переменные, которым будут присваиваться значения текущего игрока -   // игрока, чья очередm делать выстрел. Сначала играет первый игрок, прошу прошения  // за тавтологию        String currentPlayerName = player1Name;        char[][] currentPlayerField = playerField2;        char[][] currentPlayerBattleField = playerBattleField1;  // внутри цикла происходит смена очередности игроков, выстрел, его обработка.  // код внутри цикла выполняется до тех пор, пока "живы" оба игрока - пока у двух игроков  // "частично" цел (ранен) ещё хотя бы один корабль        while (isPlayerAlive(playerField1) && isPlayerAlive(playerField2)) {          // принимаем от пользователя координаты выстрела            System.out.println(currentPlayerName + ", please, input x coord of shot");            int xShot = scanner.nextInt();            System.out.println(currentPlayerName + ", please, input y coord of shot");            int yShot = scanner.nextInt();          // обрабатываем выстрел и получаем возвращаемое значение метода handleShot            int shotResult = handleShot(currentPlayerBattleField, currentPlayerField, xShot, yShot);            // если выстрел неудачный, и не один корабль не повреждён, то очередь переходит к следующему игроку          if (shotResult == 0) {                currentPlayerName = player2Name;              currentPlayerField = playerField1;              currentPlayerBattleField = playerBattleField2;            }        }    }/**    * Метод обрабатывает выстрел. Если выстрел удачный, то есть снаряд достиг цели -    * в клетку записывается значение '#' (отображается к в массиве игрока, так и в массиве соперника),    * а также на экран выводится сообщение 'Good shot!'. В этом случае метод возвращает значение 1.    * В случае неудачного выстрела - в массив battleField записывается значение '0' в элемент [y][x], и    * и возвращается значение 0.    * Возвращаемые значения нам нужны для того, чтобы в методе, внутри которого вызывается метод handleShot,    * мы могли понимать, успешно или неуспешно прошёл выстрел. На основе этого мы принимаем решение, * переходит ход к другому игроку или нет.    */    private static int handleShot(char[][] battleField, char[][] field, int x, int y) {        if ('1'.equals(field[y][x])) {            field[y][x] = '#';            battleField[y][x] = '#';            System.out.println("Good shot!");            return 1;        }        battleField[y][x] = '*';        System.out.println("Bad shot!");        return 0;    }/***Метод определяет, не проиграл ли еще игрок. Если у игрока остался хотя бы    * один "раненный" корабль, тогда пользователь продолжает игру.    * То есть, если на карте у игрока остался хотя бы один символ '1', которым мы отмечали    * корабли, то игра продолжается - возвращается значение true. Иначе false.*/    private static boolean isPlayerAlive(char[][] field) {        for (char[] cells : field) {            for (char cell : cells) {                if ('1' == cell) {                    return true;                }            }        }        return false;    }

Думаю, что к комментариям в коде мне добавить нечего. Единственное, обращу внимание на тонкий момент. Мы привыкли в математике к записи (x, y) - где первой идёт координат абсцисс, а второй - координата ординат. Казалось бы, чтобы обратиться к элементу двумерного массива (иногда срываюсь и называю в тексте элемент клеткой, но суть не меняется) нужно написать arr[x][y], но это будет неверно, и чтобы это доказать воспользуемся неопрвергаемым методом пристального взгляда. Для примера рассмотрим следующий двумерный массив:

int[][] arr = {{1, 2}, {7, 4}, {8, 3, 5, 9}, {1}}System.out.println(arr[0][1]); // ?System.out.println(arr[1][0]); // ?

Теперь вопрос из квиза "Программирование и мир" - что выведется на консоль в строках 3 и 4?
Вспоминаем, что двумерный массив - это не совсем таблица (нам так проще его воспринимать и детектировать его в задачах) - это "массив массивов" - вложенные массивы. Если в одномерных целочисленных массивах элементом является целое число, то в случае двумерного массива - элементом является массив (а в случае трёхмерного массива - элементом является двумерный массив). Таким образом, первый индекс указывает, какой по счёту массив мы выбираем. Второй индекс указывает, какой элемент по счёту мы выбираем в выбранном ранее массиве. Запись arr[1][2] указывает, что мы обращаемся к элементу с индексом 2 (то есть 3 по порядку) в массиве с индексом 1 (или второму по порядку). Соответсвенно, в строке 3 в консоль выведется значение 2, а в строке 4 - 7.

Постепенно подбираемся к концу. Что нам осталось реализовать?

  1. Вывод имени победителя

  2. Проверка клетки, которую пользователь указал как начало корабля

Первое кажется проще, стартанём с него. Потопали в метод playGame - как вы помните, там есть цикл while, в условии которого есть проверка - живы ли еще оба игрока. Напомню, что если игрок "мёртв", то есть у него не осталось ни одного корабля, то игра прекращается, а выживший игрок считается победителем. Собственно, единственное, что добавилось - строчка 36 - вызов метода System.out.println()

/*** Метод реализует логику игры: выстрел и передача хода.*/private static void playGame(String player1Name, String player2Name, char[][] playerField1, char[][] playerField2) {// "карты" выстрелов - создаём двумерные массивы, которые содержат все выстрелы    // удачные (#) и неудачные (*)    char[][] playerBattleField1 = new char[FILED_LENGTH][FILED_LENGTH];    char[][] playerBattleField2 = new char[FILED_LENGTH][FILED_LENGTH];    // вспомогательные переменные, которым будут присваиваться значения текущего игрока -     // игрока, чья очередm делать выстрел. Сначала играет первый игрок, прошу прошения    // за тавтологию    String currentPlayerName = player1Name;    char[][] currentPlayerField = playerField2;    char[][] currentPlayerBattleField = playerBattleField1;    // внутри цикла происходит смена очередности игроков, выстрел, его обработка.    // код внутри цикла выполняется до тех пор, пока "живы" оба игрока - пока у двух игроков    // "частично" цел (ранен) ещё хотя бы один корабль    while (isPlayerAlive(playerField1) &amp;&amp; isPlayerAlive(playerField2)) {      // перед каждым выстрелом выводим в консоль отображение всех выстрелов игрока      printField(currentPlayerBattleField);        // принимаем от пользователя координаты выстрела        System.out.println(currentPlayerName + ", please, input x coord of shot");        int xShot = scanner.nextInt();        System.out.println(currentPlayerName + ", please, input y coord of shot");        int yShot = scanner.nextInt();        // обрабатываем выстрел и получаем возвращаемое значение метода handleShot        int shotResult = handleShot(currentPlayerBattleField, currentPlayerField, xShot, yShot);        // если выстрел неудачный, и не один корабль не повреждён, то очередь переходит к следующему игроку          if (shotResult == 0) {            currentPlayerName = player2Name;              currentPlayerField = playerField1;              currentPlayerBattleField = playerBattleField2;        }    }  System.out.println(currentPlayerName + " is winner!");}

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

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

Окрестность с радиусом одна клетка. Красным кругом помечена стартовая клетка - начало корабля.Окрестность с радиусом одна клетка. Красным кругом помечена стартовая клетка - начало корабля.

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

Какие нюансы есть в этом алгоритме? Снова посмотрим на рисунок.

Неэффективность нашего простого алгоритма. Некоторые клетки проверяем несколько раз.Неэффективность нашего простого алгоритма. Некоторые клетки проверяем несколько раз.
private static int validateCoordForShip(char[][] field, int x, int y, int position, int shipType) {        // если пользователь хочет расположить корабль горизонтально  if (position == 1) {            for (int i = 0; i < shipType - 1; i++) {if ('1' == field[y][x + i]                                || '1' == field[y - 1][x + i]                                || '1' == field[y + 1][x + i]                                || '1' == field[y][x + i + 1]                                || '1' == field[y][x + i - 1]|| (x + i) > 9) {                    return -1;                }            }        } else if (position == 2) {          // если пользователь хочет расположить корабль вертикально            for (int i = 0; i < shipType - 1; i++) {                if ('1' == field[y][x + i]                        || '1' == field[y - 1][x + i]                        || '1' == field[y + 1][x + i]                        || '1' == field[y][x + i + 1]                        || '1' == field[y][x + i - 1]|| (y + i) > 9) {                    return -1;                }            }        }        return 0;    }

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

private static void fillPlayerField(char[][] playerField) {        for (int i = 4; i >= 1; i--) {            // растановка кораблей            for (int k = i; k <= 5 - i; k++) {                System.out.println("Расставляем " + i + "-палубный корабль. Осталось расставить: " + (q + 1));              // иницализируем переменную начальным значением              int validationResult = 1;            while (validationResult != 0) {              System.out.println("Input x coord: ");            x = scanner.nextInt();            System.out.println("Input y coord: ");            y = scanner.nextInt();            System.out.println("1 - horizontal; 2 - vertical ?");            position = scanner.nextInt();                  // если координата не прошла валидацию (проверку), то метод возвращает отрицательное// значение, конечно, оно не равно нулю, поэтому пользователю придётся ввести координаты                  // ещё раз                  validationResult = validateCoordForShip(playerField, x, y, position, i);                }            // если корабль располагаем горизонтально              if (position == 1) {                // заполняем '1' столько клеток по горизонтали, сколько палуб у корабля                for (int q = 0; q < i; q++) {                    playerField[y][x + q] = '1';                }            }                        // если корабль располагаем вертикально            if (position == 2) {                  // заполняем столько клеток по вертикали, сколько палуб у корабля                for (int m = 0; m < i; m++) {                    playerField[y + m][x] = '1';                }            }              // печатаем в консоли поле игрока, на котором будет видно, где игрок уже поставил корабли              // о реализации метода - см. ниже            printField(playerField);        }    }}

Вот мы и написали игру "Морской бой" - level 1. Начали с простого - простых конструкций, идей и методов. Один класс, нет коллекций - только массивы. Оказывается на циклах и массивах можно написать игру.

Мы удовлетворили все требования бизнеса. Доигрывая до конца, получили отличную оценку от заказчика, он полностью доволен приложением. Ждём, когда он опробует игру и вернётся снова за апгрейдом. А тут и будет level - 2.

Всем спасибо, всегда рад обратной связи!

Подробнее..

Команда Xbox представила самую большую линейку эксклюзивных игр в истории

15.06.2021 10:13:02 | Автор: admin

Недавно команда Xbox провела онлайн-мероприятие Xbox & Bethesda Games Showcase, показав самую масштабную игровую линейку за всю историю существования Xbox. В рамках шоу было продемонстрировано и анонсировано 30 игр от партнёров и внутренних студий, 27 из которых станут частью каталога Xbox Game Pass.

Самые крупные, эксклюзивные игры

Во время презентации команда Xbox анонсировала несколько горячо ожидаемых проектов от Xbox Game Studios и Bethesda, которые будут доступны в каталоге Xbox Game Pass в день релиза:

Forza Horizon 5(Xbox Series X|S, Xbox One, Windows 10, Steam) 9ноября2021года

Вас ждет невероятное приключение. Играя в Forza Horizon 5 исследуйте яркие и постоянно меняющиеся ландшафты открытого мира Мексики с безграничным, увлекательным вождением на сотнях лучших в мире автомобилей. Это долгожданное продолжение выйдет 9 ноября 2021 года на консолях Xbox Series X|S и Xbox One, ПК на Windows 10 и Steam, а также в каталоге Xbox Game Pass, включая консоли и ПК. Исследуйте яркие, постоянно меняющиеся пейзажи Мексики с безграничными возможностями для вождения!

Halo Infinite(Xbox Series X|S, Xbox One, Windows 10) Конец2021года

Сегодня 343 Industries представила мировую премьеру многопользовательского режима игры Halo Infinite. Легендарный многопользовательский бой Halo возвращается в новом виде благодаря сезонным обновлениям, новым режимам и картам, а также контенту, ориентированному на игровое сообщество. Игроки смогут исследовать бесконечные боевые возможности, смешивая и сочетая богатое разнообразие оружия и снаряжения на карте, чтобы испытать уникальный геймплей, в котором отчетливо ощущается дух Halo. Игра будет доступна в каталоге Xbox Game Pass в день релиза для ПК и консолей. Впервые многопользовательская игра Halo будет распространяться по моделиfreetoplay, приглашая миллионы игроков на консолях Xbox и ПК вступить в бой.

Starfield(XboxSeriesX|S,Windows10) 11 ноября 2022 года

Starfield первая за 25 лет новая игровая вселенная, разработанная в Bethesda Game Studios создателями The Elder Scrolls V: Skyrim и Fallout 4. В этой ролевой игре нового поколения, действие которой происходит в космосе, вы сможете создать любого персонажа и исследовать вселенную, наслаждаясь абсолютной свободой. Отправляйтесь в путь и раскройте величайшую тайну человечества. Присоединяйтесь к Созвездию и раньше других узнавайте обо всём, что касается Starfield, включая интервью с командой разработки и подробности создания проекта.

REDFALL(Xbox Series X|S, Windows 10) Лето2022года

Redfall шутер с видом от первого лица для совместной игры в открытом мире. Над игрой работает Arkane Austin знаменитые авторы Prey и Dishonored. Как принято у Arkane, Redfall совмещает в себе тщательно продуманный мир, креативные механики и ставший визитной карточкой студии уникальный игровой процесс.

S.T.A.L.K.E.R. 2 Heart of Chernobyl(Xbox Series X|S) 28апреля2022года

Отмеченная многочисленными наградами игровая серия для ПК, полюбившаяся миллионам игроков, дебютирует на консолях нового поколения в игре S.T.A.L.K.E.R. 2. Испытайте уникальное сочетание шутера от первого лица, захватывающего симулятора и хоррора. Чернобыльская зона отчуждения это уникальная, опасная и постоянно меняющаяся среда. Она обещает немало артефакты невероятной ценности могут стать вашими, если вы осмелитесь на них претендовать. С другой стороны, цена, которую вы можете заплатить, не меньше, чем ваша собственная жизнь. Испытайте острые ощущения в день релиза игры с подпиской Xbox Game Pass.

Пополнение каталогаXboxGamePass

Игры от внутренних студий и партнёров, которые появятся в каталоге Xbox Game Pass начиная с этого года:

  • Yakuza: Like a Dragon(Консоли и ПК) Доступно сегодня

  • Microsoft Flight Simulator(Xbox Series X|S) 27июля2021года

  • Hades(ПК и Консоли) 21 августа 2021 года

  • Back 4 Blood(ПК и Консоли) 12 октября 2021 года

  • Age of EmpiresIV (ПК) 28октября2021года

  • Among Us(Консоли) 2021 год

Также в конце этого года и начиная со следующего фанаты Xbox смогут сыграть в такие горячо ожидаемые проекты, какAtomicHeart,FarCry6,Battlefield2042,APlagueTale:Requiem,TwelveMinutes,TheAscent,TheOuterWorlds2,TheElderScrollsOnline|ConsoleEnhanced,Contrabandи многие другие.

Все игровые анонсы мероприятия Xbox & Bethesda Games Showcase доступныздесь. Актуальные новости об Xbox читайте в нашем русскоязычном блогеXbox Wire.

Подробнее..

Немного про нашу стратегию развития экосистемы XBOX и существующие достижения

16.06.2021 10:13:29 | Автор: admin

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

В воскресенье прошло первое в своем роде мероприятиеXbox & Bethesda Showcase, на котором мы представили одну из самых масштабных и лучших игровых линеек. А перед этим глава Xbox Фил Спенсер и руководитель Microsoft Сатья Наделлаобсудили значение игрдля Microsoft и для всего мира. Мы также поделились новостями о том, как Xbox Game Pass меняет наши возможности узнавать новое, общаться и играть, и о том, как Xbox и игры от всех 23 студий появятся на ещё большем количестве экранов.

Мы верим, что игры и интерактивные развлечения это не только оборудование и программное обеспечение. Не только пиксели. Это люди. Игры объединяют людей, уверен Спенсер. Они наводят мосты и укрепляют связи, создают взаимную эмпатию между пользователями по всему миру. Радость и игроки вот почему мы здесь.

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

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

Мы верим, что Microsoft может сыграть важную роль в демократизации игр и определении будущего индустрии интерактивных развлечений. Есть три основных аспекта, в которых у нас есть конкурентное преимущество. Первый: наше лидерство в облачных вычислениях. Второй: ресурсы для формирования сервиса подписки Xbox Game Pass. И третий: фокус на поддержке разработчиков.

Мы движемся дальше в нашем квесте, в котором хотим достучаться до миллиардов игроков и сегодня представляем новые слагаемые успехаXbox Game Passи рассказываем, что ждёт Xbox в будущем:

XboxGamePass расширяет возможности новых открытий, общения и игры

  • Обладатели подписки Xbox Game Pass пробуют на 30% больше жанров и на 40% больше игр. Более 90% подписчиков признались, что с удовольствием играли в те игры, которые не стали бы пробовать без Game Pass.

  • После включения своих игр в библиотеку Xbox Game Pass партнеры видят в среднем восьмикратный прирост вовлеченности игроков.

  • При покупке игр или дополнительного игрового контента из каталога Xbox Game Pass или за его пределами, подписчики тратят на 50% больше средств, чем те, кто не пользуется подпиской.

  • Подписка Xbox Game Pass стала настоящим инструментом открытия новых игр, платформой для взаимодействия игрового сообщества и способствовала повышению продаж. Вот несколько свежих инсайтов, которыми мы хотим поделиться сегодня:

    • После запуска партнерской программыEA Play в подписке Xbox Game Pass Ultimateнаши пользователи стали активнее использовать сервис EA. В сравнении с данными до интеграции подписка EA Play стала намного активнее использоваться на платформах Microsoft. Количество часов игры выросло более чем на 200%. В результате невероятное портфолио игр EA привлекло миллионы новых поклонников на платформе Xbox.

    • Новая играOutridersот студии Square Enix была включена в подписку Xbox Game Pass и заняла первую строчку в топ-10 цифровых продаж на Xbox за апрель. Миллионы игроков познакомились с этой игрой именно благодаря подписке.

    • За премьерную неделюMLB: The Show 21стала крупнейшей спортивной игрой года и второй крупнейшей спортивной игрой всех времен на Xbox. Подписка Xbox Game Pass подарила ей миллионы новых поклонников и существенно расширила игровую базу Major League Baseball. Кроме того, MLB: The Show 21 получила титул 1 по продажам платных игр на Xbox за апрель.

Xbox и подпискаXboxGamePass появятся на большем количестве экранов

  • Совместно с международными производителями телевизоров ведется работа над внедрением возможностей Xbox непосредственно в подключаемые к Интернету телевизоры без использования дополнительного оборудования (за исключением геймпада).

  • Xbox разрабатывает новые специальные предложения для подписки Xbox Game Pass, чтобы еще больше игроков по всему миру смогли насладиться самыми захватывающими и увлекательными играми на различных устройствах, независимо от их местоположения и финансовых возможностей.

  • Xbox работает с телекоммуникационными провайдерами над новыми моделями покупки, такими как Xbox All Access, которая позволяет потребителям приобрести консоль и Xbox Game Pass за низкую ежемесячную плату, вместо того, чтобы платить всю сумму сразу.

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

  • В следующие несколько недель для обладателей подписки Xbox Game Pass Ultimate в некоторых регионах будет открытоблачный сервис в браузере. Пользователи браузеров Edge, Chrome и Safari окажутся в одном клике от игры практически на любом устройстве!

  • Мы находимся на завершающей стадии обновления наших центров обработки данных Microsoft по всему миру оборудованием последнего поколения на базе Xbox Series X. Это значит, что пользователи совсем скоро увидят более высокую скорость загрузки, улучшение скорости смены кадров и смогут насладиться играми, оптимизированными для Xbox Series X|S.

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

Невероятная линейка игр

  • Игры для Xbox разрабатывают более 23 студий со всего мира, и мы хотим добавлять по крайней мере по одной новой first party игре в библиотеку Xbox Game Pass раз в квартал. Ролевые игры, шутеры, стратегии, приключенческие игры и многое другое все это создается нашими first party командами, чтобы обеспечить постоянный поток интересного эксклюзивного контента.

  • Наша программа для независимых разработчиков ID@Xbox принесла участникам более 2 миллиардов долларов США с момента своего создания, за всё время её существования было выпущено более 2000 игр и еще много проектов на подходе. Эта модель теперь используется в программеID@Azure, которая позволяет независимым разработчикам создавать продукты на базе облачных технологий. Обе эти программы позволяют открыть новые таланты из различных уголков мира.

Как заметил Фил Спенсер, команда понимает, что прохождение миссии будет непростым, и впереди у нас долгий путь. Однако он верит, что только Microsoft способна помочь каждому обрести радость и общение в играх, поскольку компания может использовать свой глобальный масштаб, доступ к технологическим инновациям, финансовые ресурсы и богатое наследие в индустрии видеоигр.

Подробнее..

Уходя гасите всех или Шаверму из Шамблера, пожалуйста

13.06.2021 00:06:46 | Автор: admin
Einmal Dner mit Shambler und scharf bitte (MFX)Einmal Dner mit Shambler und scharf bitte (MFX)

К сожалению, несмотря на то, что код движка Quake I обобществлён и сейчас принадлежит сообществу (community), то есть, открыт под GPL, этого нельзя сказать про ресурсы (текстуры, уровни, модели персонажей и NPC). Как мне кажется, именно поэтому сама игра Quake ушла в тень, в то время как популярности idTech 2/3/4 может угрожать разве что открытый Unreal Engine. Так или иначе, примерно года с 2000, я если что и слышал про игру Quake I, так только воспоминания о былом. И был полностью уверен, что её жизнь закончена, а искать её надо на сайтах abadonware.

Но буквально несколько лет назад я обнаружил, что Quake I не умерла, а достаточно активно поддерживается и развивается энтузиастами; в основном на данный момент сконцентрированными на сайте Func_MSGBOARD (https://www.celephais.net/board) и вокруг Quaddicted (https://www.quaddicted.com/). В каком смысле развивается? Нет, движок не заставляет людей покупать новую видеокарту, не выходит режим Battle Royale, всё более-менее по-старому singleplayer shooter, эпизоды (кампании) и отдельные уровни. Просто выходят новые карты, новые текстуры, новые модели, иногда превращаясь в локальные революции.

Почему сообществом был выбран именно Quake I, а не более продвинутые Quake II или Quake III? По-видимому из-за того, что у уровней Quake I есть свой узнаваемый стиль, несмотря на эклектичность самой игры вспомним, в оригинальной версии есть уровни трёх типов: Base, Medieval и Runic. В разных эпизодах уровни, выполненные в разных стилях практически произвольно смешиваются, но на одном уровне дизайнеры придерживаются одного стиля. Сейчас эти уровни выглядят как pixel art, хотя, конечно, им не являются. Так или иначе, но у Quake III есть свой особый стиль и очень сильные ограничения. А что ещё любят творческие люди, как не преодолевать препятствия, создавая шедевры?

Наиболее рекомендуемым движком для современных уровней является Quakespasm (http://quakespasm.sourceforge.net/). В нём расшиты разные ограничения оригинала, ведь размеры уровней сильно подросли, а вот картинка в стиле pixel art бережно сохранена.

Из чего состоит типичный уровень? Конечно, первое это визуал, архитектура зданий, ландшафт; второе gameplay, то, как расставлены монстры, оружие, как запланировано прохождение; третье, вишенка на торте это секреты. Меня в современных картах больше всего привлекает архитектура и визуальные стили, поэтому дальше будут картинки!

Как вы помните, в оригинальном Quake I всего три стиля в зелёно-бурых тонах плюс ещё несколько сине-коричневых уровней где-то ближе к концу. А вот в неофициальных уровнях со временем добавились ещё стили Honey, IKblue/IKwhite, egypt, Zerstrer, Copper и другие... За последние 10 лет коллектив FuncMap выпустил несколько сборников, посвящённых этим стилям.

Honey

Honey это "канализация", огромные заполненные туманом подземные пространства, зелёная Мория. Родоначальник стиля одноимённый уровень, выпущенный в 2012 году автором czg (https://www.quaddicted.com/reviews/honey.html).

В 2014 году коллектив Func_Msgboard выпустил первый совместный проект, который был посвящён этой теме (https://www.quaddicted.com/reviews/func_mapjam1.html).

Как обычно, все уровни разные по качеству, но есть совершенно профессионально сделанные (авторы Skacky, Sock и Ionous/MFX).

IKblue/IKwhite

1000 cuts из сборника Func Map Jam 2 (автор Sock)1000 cuts из сборника Func Map Jam 2 (автор Sock)

Этот стиль развитие оригинальных уровней, выполненных в синих тонах (E2M5, E3M6, E4M7). В 1997 году Iikka Kernen добавил органично выглядящие в Quake текстуры в арабо-персидских тонах, и выпустил три уровня: Temple of the Thousand-Faced Moon, Halls of the Shambler God и Homecoming (их можно найти на Quaddicted).

An Angel Was Heard To Cry Over The City Of Celephais из сборника Func Map Jam 2 (автор Skacky)An Angel Was Heard To Cry Over The City Of Celephais из сборника Func Map Jam 2 (автор Skacky)

А в 2014 году вышел шедевральный сборник Func Map Jam 2 IKblue/IKwhite Theme (https://www.quaddicted.com/reviews/func_mapjam2.html). В нём замечательный "зеркальный" уровень Skacky (см картинку выше и прохождение https://www.youtube.com/watch?v=Qfwblog7iQs), восхитительная архитектура Death By a Thousand Cuts (автор Sock) и совершенно удивительный Einmal Dner mit Shambler und scharf bitte за авторством MFX (он на первой картинке, обязательно посмотрите его прохождение и критику, даже если не собираетесь проходить самостоятельно https://www.youtube.com/watch?v=NNlJDTUwHC8 )

Совсем недавно, в январе 2021 года вышел сборник Blue Monday Jam (https://www.quaddicted.com/reviews/bluemonday_v2.html). Он тоже довольно интересный, но такого бешеного восторга как Jam 2 у меня не вызвал, возможно я просто привык к этим красотам. В любом случае, рекомендую посмотреть и хотя бы найти секрет стартового уровня.

Egypt

Вообще говоря, на Quaddicted много разных уровней с египедскими темами. Да и самих тем несколько. Но меня поразили последние творения, базирующиеся на популярном нынче моде Arcane Dimensions.

Nyarlathotep's Sand Castle (автор Sock)Nyarlathotep's Sand Castle (автор Sock)

Первая это творение Sock Nyarlathotep's Sand Castle (https://www.quaddicted.com/reviews/ad_scastle1d.html).

Imhotep's Legacy (автор Heresy)Imhotep's Legacy (автор Heresy)

Вторая Imhotep's Legacy (https://www.quaddicted.com/reviews/ad_heresp2.html).

Arcane Dimensions

Это пожалуй наиболее популярный на сегодня мод, то есть, собрание скриптов, текстур и моделей, хотя есть и другие. Он разрабатывался и разрабатывается под руководством Sock. Цель мода сделать менее эклектичным вид Wizard/Medieval уровней Quake I. Например, изменены модели аптечек, добавлены монстры (часть монстров точно из Hexen II, про других, увы, не знаю), сделана разрушаемость части предметов.

Grendel's Blade (автор Sock)Grendel's Blade (автор Sock)

И тут я бы хотел упомянуть "вертикальный" уровень Sock Grendel's Blade (https://www.quaddicted.com/reviews/ad_grendel1h.html) и огромную, красивейшую, но дико тормозящую компьютер карту Tears of the False God, автор Bal.

Tears of the False God (автор Bal)Tears of the False God (автор Bal)

Этот уровень интересен, светел, красив и далеко не каждый компьютер его сможет потянуть. Но все могут посмотреть прохождение на YouTube. Кстати, ружьё указывает на аптечку из Arcane Dimensions, ящик с патронами оттуда же.

Заключение

За эти 25 лет Quake I не умер, а даже "воспарил" вместо мрачных подземных катакомб уровни стали светлыми, более открытыми, появилось множество "летающих островов" с интересным освещением, красочным небом. Современные уровни открыты и в другом смысле: как правило описания сопровождаются подписью "The map source is included." культура Free Software распространяется и на художественные произведения. Это прекрасно.

Я не ставил перед собой задачи полностью и досконально проследить историю развития уровней Quake I, да и невозможно это в рамках одной статьи. Я даже не смог рассказать и о четверти всех достойных прохождения уровнях с Quaddicted. Да и скриншоты не могут показать уровни во всей их красе. Поэтому берите всё более-менее современное, то есть где-то после 2010 года с четырьмя-пятью сердечками это, как правило, прекрасные произведения искусства.

Other dimensions await you...

Подробнее..

ОТЦ ИГРОВОЙ ИНДУСТРИИ. КРИС АВЕЛЛОН ЧАСТЬ 23. OBSIDIAN ENTERTAINMENT

16.06.2021 06:09:59 | Автор: admin

Внимание! Внимание! Внимание! Внимание! Внимание! Внимание!

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

Когда в товарищах согласья нет,

На лад их дело не пойдет,

И выйдет из него не дело, только мука.

И. А. Крылов

Это текстовая адаптация моего видео, так что если вам по какой-либо причине удобнее смотреть не проблема.

Итак, надворе 2003год. Почти все главные разработчики покинули Black Isle иинициировали основание новой студии. Нодело это бюрократичное инебыстрое, поэтому Крис взялся снова помочь Snowblind. Насей раз онбыл приглашен для написания сюжета идиалогов. Hack and Slash Action RPG, носящая название Champions of Norrath: Realms ofEverQuest, попадет наприлавки только через год, 10февраля 2004 года, ибудет очень высоко оценена. Издания хвалили игру заграфику иодно излучших исполнений геймплея вжанре, атакже заего разнообразность.

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

Глава первая. BioWare

Впервую очередь BioWare получила признание благодаря своимРПГ. Став именитым разработчиком вжанре после первых врат Балдура, студия набралась амбиций, ив1999 году унее вразработке находилось 4 (!) игры. Шуточный шутер MDK 2, игра хорошая, нонас сейчас особо неинтересует, иBaldurs Gate IIвышли в2000. Авот наоставшейся паре остановимся поподробнее.

ИBaldurs Gate, иBaldurs Gate IIбыли отличными играми, однако опыт настольной D&D передавали, мягко говоря, невполной мере. Тогда, в1999 году, разработчики поставили перед собой цель создать игру, максимально точно передающую дух родоначальника, вкоторой будет интересная сюжетная кампания, легкий для освоения конструктор приключений ивозможность играть посети сдругими людьми как восновной сюжет, так ив пользовательские наработки. Выбор места действия пал наНевервинтер.

В1991 году Stormfront Studios запустила всети интернет-провайдера AOL первую вмире графическую MMORPG под названием Neverwinter Nights. Ксвоему закрытию в1997 году она привлекла фантастические натот момент 100 тысяч пользователей. BioWare решила заманить фанатов ММО ив1999 году выкупила права наразработку.

Neverwinter Nights должна была выйти в2000 году надвижке, создававшемся для MDK 2, однако оннеподошел, истудии пришлось разрабатывать еще один движок, уже третий засвою, четырехлетнюю на тот момент, историю.

Aurora Engine делали срасчетом напростоту создания контента, поэтому, когда техническая часть была готова, процесс значительно ускорился, однако завремя разработки игра успела устареть графически. Решив, что все должно быть навысшем уровне, сотрудники начали создавать дополнительные визуальные эффекты, что влияло на уже существующую часть игры. Благодаря новому движку, разработчики сумели добавить вигру вид оттретьего лица. Правда воплощен онбыл криво, нодаже такой онбыл вновинку для жанра, апосле того как игрок налюбуется видами, можно переключиться наклассическую изометрию. Витоге почти все старые наработки пришлось перелопатить, всвязи счем последние полгода разработки студия провела всостоянии кранча. Изначально игра должна была выйти под издательством Interplay, однако юридический скандал внутри компании внес свои коррективы, истех пор BioWare не сотрудничала сInterplay, аиздательством стала новая Atari, которая натот момент называлась Infogrames.

Так или иначе игра увидела свет 18июня 2002 года. Все журналисты сошлись вомнении сбольшинством игроков втом, что уигры отличный сюжет, все ролевые механики выполнены на высоте, графика радует глаз, аAurora Toolset, представляющий изсебя инструментарий для создания собственных приключений простой иудобный виспользовании. Подтверждением этому стало бескрайнее множество фанатских историй, лучшие изкоторых позже вошли врасширенное издание вкачестве дополнений косновной игре.

Иснова вернемся в1999год. Тогда BioWare вела переговоры сLucasArts. Последние предложили канадцам создать РПГ вовселенной Звездных Войн. Навыбор было два варианта: игра, действие которой происходит вовремя второго эпизода, который тогда как раз снимали; или за4000 лет дособытий кинофраншизы. ВBioWare решили выбрать второй вариант, так как ондавал гораздо больше простора для творчества.

В2000 году началась разработка. Движком стал Aurora Engine, который вовремя работы над игрой постоянно модифицировался под нужды геймдизайнеров. Вконце концов, онполучил столько изменений, что было решено изменить иназвание этой версии движка наOdyssey Engine. Пожалуй, главным техническим нововведением стал фиксированный вид оттретьего лица. Изгеймплейных изменений впервую очередь вглаза бросался сеттинг далекой-далекой галактики, плюс Star Wars: Knights ofthe Old Republic стала первой РПГ BioWare, работавшей ненаправилах чистой D&D (вданном случае использовалась ролевая система настолки по звездным войнам, которая всвою очередь являлась модифицированной системой D&D).

Вобщем ицелом получилась стандартная для BioWare игра: эпос об избранном, что может спасти весь мир или уничтожить его, приправленный щепоткой побочных заданий иукрашенный вишенкой ввиде компаньонов, каждый изкоторых готов рассказать свою историю тому, кто будет терпеливым, нонастойчивым. Во всем этом смогли убедиться пользователи Xbox 15 июля 2003 года, аПК-Бояре еще через 4 месяца 19ноября 2003.

Возможно, игра быполучила чуть более сдержанные отзывы, еслибы неодно но: она была не только хорошей, ноипозвездным войнам. Совсех сторон были слышны восторженные отзывы фанатов вселенной, жанра, студии. Это сделало KotOR третьей самой высоко оцененной игрой в истории BioWare (93/100), уступив лишь Mass Effect 2 (94/100) иBaldurs Gate II (95/100).

Еще доокончания разработки первой части LucasArts решила продлить серию, нобыло жесткое условие: игра должна быть готова кдекабрю 2005 года к самому рыбному месяцу перед выходом наэкраны заключительного, третьего эпизода приквелов. Это означало, что наразработку есть всего 16 месяцев. BioWare отказалась, но, узнав отом, что давние коллеги изBlack Isle переехали вновую студию, посоветовала обратиться кним.

Глава вторая. Obsidian компания одного чердака

12июня 2003 года. Obsidian Entertainment официально зарегистрирована.

7 человек, вчисле которых было 5 основателей, а именно Фергюс Уркхарт, Крис Авеллон, Крис Паркер, Даррен Монахан иКрис Джонс, обустроили свой первый офис. Располагался онначердаке уФергюса. Представители LucasArts позвонили ему, предложив создать продолжение кеще невышедшему первому KotORу, начто тутже получили согласие.

Первые несколько недель работа велась вслепую, так как никто неиграл воригинал, аLucasArts предоставить его дозаключения контракта немогла. Вкороткие сроки было накидано несколько концептов, аАвеллон написал простецкий сюжет отом, как избранный спомощью Служанки свергает матриархат воглаве сКреей.

Наш первый офис был чердаком Фергюса, аего жена, Марго, была более чем терпеливой поотношению кнашим занятиям икогда яговорю терпеливой, тоскорее имею ввиду самаритянкой. Тоесть она могла даже принести нам поесть. Начердаке было жарко, онпах разработчиками (незнаю, как она переносила запах). Асдесятком компьютеров, разогревающихся допиковой точки, онвременами превращался впарилку. Крис Авеллон

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

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

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

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

Благодаря контракту студия смогла арендовать небольшой офис неподалеку инанять еще 20 человек вкоманду. Работа велась, а обозначенная вдоговоре дата стремительно приближалась. Вкакой-то момент стало очевидно, что Obsidian попыталась откусить значительно больше, чем сможет прожевать. Вырезать начали все: от небольших строчек диалога доцелой планеты роботов. Вырезался даже контент, который уже был озвучен. Янепроверял, нодумаю, что завсю историю индустрии ни одна игра неподвергалась такой безжалостной зачистке, носроки есть сроки, ибольше времени укоманды небыло, так что нажертвы пришлось идти.

Star Wars: Knights ofthe Old Republic II The Sith Lords вышла 6декабря 2004 года наXbox, и8февраля 2005 наPC. Самое интересное, что игра получила 85 баллов наметакритике, что сродни чуду, учитывая техническое состояние проекта иего наполненность. Ближе кконцу игры из-за вырезанных диалогов иквестов повествование становилось рваным, ачто происходило вфинале немогли понять даже люди сдокторской степенью. Но, несмотря наэто, игроки икритики смогли разглядеть неограненный алмаз влице философии Силы Авеллона. Иименно благодаря игрокам сейчас каждый желающий может пройти туигру, которую хотели создать вObsidian. Весь вырезанный контент вместе созвучкой остались вфайлах игры, разработчики нестали ихудалять, так как неизвестно было, как наэто отреагирует игра. В2012 году Team-Gizka выкатила насуд общественности The Sith Lords Restored ContentMod. Нестану перечислять, что мод вернул вигру, наэто нехватит ичаса, ноесли после моего рассказа вызахотели пройти данное, непобоюсь этого слова, произведение, настоятельно рекомендую играть с восстановленным контентом.

Концепт-арт ктретьей частиКонцепт-арт ктретьей части

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

Долго ждать новый контракт непришлось. Atari, наконец, созрела насиквел Neverwinter Nights. BioWare была занята созданием Jade Empire иMass Effect, поэтому снова подсобила Obsidian своей рекомендацией. Разработка велась намодифицированном движке отKotORа, получившем название Electron Engine. Теперь можно было набрать до4 сопартийцев, каждым изкоторых мог управлять непосредственно игрок.

Авеллон написал для игры диалоги иквесты напарников. Последние были особенно фееричны: укаждого сопартийца были свои ценности и идеалы, иесли ваши действия импротиворечат жди беды. Линейка квестов напарника вконце концов могла привести кбитве стенка настенку, где одну сторону возглавлял игрок, адругую его бывший союзник. Однако основной сюжет писал неКрис, апотому кампания вышла более плоской посравнению спервой частью, ну, асовторым KotOrом нестоит даже сравнивать. В остальномже игра похорошела нафоне оригинала. Увеличился простор для тактики, абаталии стали массивнее засчет большего состава партии ивозможности управления каждым персонажем. Расширились исредства для отыгрыша, аопыт D&D воспроизвели еще точнее. Также всоставе игры был улучшенный редактор приключений. Весь этот праздник ролевика омрачало только одно: техническое состояние игры, скоторым уже вовторой раз засовсем непродолжительную историю Obsidian было, мягко говоря, не все гладко.

Neverwinter Nights 2 появилась наполках магазинов 31октября 2006 года иполучила относительно небольшие, померкам наших товарищей, 82 балла. Ругали игру, как уже было отмечено, заплохую техническую реализацию изанеприветливость кновичкам вжанре. Через год, 9октября 2007, вышел первый аддон под названием Neverwinter Nights 2: Mask ofthe Betrayer. Сюжетно оноказался гораздо лучше, чем основная игра, нопоплатился заэто ролевым отыгрышем иполучил теже 82 балла. Еще через год, 18ноября 2008 года, вышло второе ипоследнее дополнение, именуемое Neverwinter Nights 2: Storm of Zehir. Оно создавалось совсем небольшой группой разработчиков, так как остальная команда переключилась наследующий проект, окотором мысейчас и поговорим. Шторм Зехира мог похвастаться только хорошей музыкой иполучил73 балла.

Глава третья. Obsidian кладбище перспективных проектов

Obsidian нанимала все новых иновых сотрудников, и предыдущий офис стал тесен. Тогда компания перебралась вновое здание, в котором базируется досихпор. Втедалекие нулевые студия была независимой. Это хорошо для творчества, ноплохо для бюджета, денег постоянно нехватало, поэтому студия тоидело презентовала свои идеи разным издателям. Летом 2006 года кФергюсу Уркхарту обратилась SEGA спредложением сделать ролевую игру.

Унас был шестистраничный питч. Помню, что начинался онсовполне сюжетного описания Alpha Protocol. Азаканчивался чем-то вроде Выодновременно Джейсон Борн, Джеймс Бонд иДжек Бауэр, надерите задницу плохим парням, пользуясь крутыми гаджетами! Крис Паркер

НаObsidian в индустрии начали навешивать ярлык студии, которая может сделать отличное, но забагованное продолжение существующей серии. Компания очень хотела отмыться от такого описания, поэтому предложила SEG(A)е непросто новый IP, аигру вновом жанре: шпионская РПГ, начто последняя согласилась. Obsidian ликовала Alpha Protocol должен был стать первой игрой, права накоторую будут принадлежать ей. Однако незадолго доподписания договора сорвалась другая сделка: Disney обратилась кобсидианам сзаказом на(внимание!) приквел кБелоснежке. Игра должна была стать РПГ про гномов. Каждый изсеми владел своими способностями, анамиссию можно было брать только двух. Необходимо было комбинировать способности для эффективного изничтожения противников ирешения головоломок, азакончиться игра должна была изгнанием антагониста влегендарное волшебное зеркало Белоснежки.

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

Кнесчастью уигрового подразделения Disney сменился менеджер, ипроект был отменен. Чтобы непроизводить сокращения, Obsidian пришлось изменить договор сSEGA, иправа наAlpha Protocol были проданы вместе сподписанием контракта надва споловиной года разработки.

Месяцы шли, аработа стояла. Как обычно, возникли проблемы, причем нетолько технические: Unreal Engine 3, накотором разрабатывалась игра, еще небыл завершен, аразработчикам нехватало опыта всоздании стелса и стрельбы. Все еще небыло решено, накого изикон шпионских боевиков будет похож главный герой, иусугублялось это тем, что упроекта досих пор небыло ведущего дизайнера. Так продолжалось полгода. SEGA тогда как раз получила права наразработку игр во вселенной чужих. Увидев, что производство Alpha Protocolа встало, SEGA предложила отложить шпионское РПГ исделать РПГ выживание.

Крис Авеллон иЭрик Фенстермакер стали разрабатывать прототип. Витоге остановились начем-то среднем между фильмами Чужой иЧужие. Отпервого взяли атмосферу безысходности инеизвестности, аотвторого многочисленные перестрелки сксеноморфами. Наочередной планете ведется колонизация. В ходе исследований учеными найден инопланетный космопорт, вкоторый тутже была отправлена экспедиция. Стех пор связь сколонией прервалась. Безымянный герой под нашим управлением вэтот момент пролетает недалеко отпланеты, ему поступает приказ расследовать причину радиомолчания. При подлете кколонии корабль выходит изстроя, ипротагонист вместе сэкипажем совершает аварийную посадку. Теперь игроку предстоит обустроить базу, набрать людей иулететь с планеты.

Сюжет довольно банален, нописал его Авеллон, а значит, стоило ожидать множество моральных выборов иинтересных напарников. Но, пожалуй, самым интересным вовсем этом была игровая концепция. Решения, принятые вдиалогах, влияли насудьбу компаньонов инастроение вкоманде. Сценарист Эрик Фенстермакер привёл впример ситуацию снападением лицехвата:

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

Каждый NPC имел собственные моральные установки ишкалу паники, ивзависимости отэтих параметров онмог слушаться ваших приказов илинет. Еслиже неигровой персонаж погибал входе миссии, тоэто сконцами. Выживших вигре было строго ограниченное количество, что делало ихглавным исамым ценным ресурсом. Новсе это лирика, ведь в2009 году многообещающий симбиоз чистокровной РПГ иSurvival Horrorа под названием Aliens: Crucible был отменен.

УSEGA начались проблемы сфинансами, она закрыла несколько своих подразделений. Когдаже Obsidian отправили свои наработки ипопросили увеличить бюджет, имбыло отказано, апроект отменен. Вместо этого SEGA сделала ставку надва шутера: Alienvs. Predator, который оказался довольно проходной игрой, окоторой все сразу забыли, иAliens: Colonial Marines. Ивот эту игру помнят многие. Она стала всвоем роде легендарной, ведь нидо, нипосле этого свет невидывал ниодной игры вовселенной чужих, которая былабы хуже. Однако для Obsidian все было нетак плохо, как могло показаться напервый взгляд: SEGA решила, что Alpha Protocol достаточно перспективный проект, чтобы довести его доконца.

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

1. Паркур, из-за которого дизайн локаций получался перегруженным.

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

3. Линейные погони намотоцикле. Создание таких этапов было делом очень трудоемким при том, что стемой игры они вязались довольно слабо.

4. Неигровой женский персонаж поимени УлиБой. На нее потратили столько сил ивремени, что еепортрет висит рядом сдругими персонажами игры вкомнате, посвященной Alpha Protocolу, вофисе Obsidian. Кроме этого оней ничего неизвестно.

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

Вобщем, игра вышла смини-играми, которые Скажем так, они хотябы короткие Мэтт Маклин.

Ули БойУли Бой

Благодаря собранию уразработчиков появилось цельное видение игры: приключение вдухе Джейсона Борна снеобычными злодеями. На сборку игры устудии было полгода, очень короткий срок померкам индустрии, однако пока основной костяк Obsidian занимался игрой почужим, оставшаяся часть команды отладила движок, создала концепты персонажей инаписала базу для отладки стелса истрельбы. Поэтому, когда игра получила четкий курс разработки, процесс пошел насверхзвуковой скорости. Сюжет получился довольно стандартным для шпионского боевика, новотличие отдругих игр ифильмов жанра, онбыл нелинейным. Авеллон смог расписать огромное количество параллельных развитий событий, что позволило довольно короткому, по меркам жанра РПГ, проекту расцвести в реиграбельности. Вигре была сцена, имеющая такое количество комбинаций персонажей, что работа над ней одной заняла уаниматора 20 дней. Еще одной фишкой было то, что почти закаждое внутриигровое решение персонаж получал пассивный навык, зависящий отвыбора игрока. Засчет этого каждое следующее прохождение ощущалось иным нетолько сюжетно, ноигеймплейно.

Всентябре 2009 года разработка была завершена. Конечно, оставалось много вещей, которые можно было доделать, улучшить, но таков был договор. Obsidian связалась сSEGA, информируя отом, что игру можно отправлять впечать, нопредставитель издателя ответил: вэтом году мывыпускать игру небудем. Доподлинно неизвестно почему так произошло, носамым реалистичным предположением является то, что SEGA побоялись конкуренции нарынке. Осенью 2009 года выходили Call ofDuty: Modern Warfare 2 иUncharted 2, ананачало 2010 года был запланирован релиз Mass Effect 2, Battlefield: Bad Company 2 иTom Clancys Splinter Cell Conviction.

Близилсямай. Разработчики посвоему обыкновению стали угадывать, какой балл получит игра. Мывсегда обсуждаем, как, понашему мнению, будет оценена игра, перед еезапуском, говорит Крис Паркер. Мывсе ожидали, что [Alpha Protocol] получит около80. Мызнали, что уигры есть некоторые проблемы, мывсё это понимали, нодумали, что если люди смогут просто преодолеть эти вещи, токонтент справится. Однако, когда игра вышла 1июня 2010, ихвсех ждало разочарование. Оценка остановилась на73 баллах уверсии игры для ПК, ина63 уконсольных. Восновном журналисты ругали игру затупой искусственный интеллект, закривой стелс истрельбу, за однокнопочный рукопашный бой, акположительной стороне относили только РПГ элементы ивариативность. Но современем мнение обигре уобщественности менялось. Возможно, игроки все же решили посмотреть, что изменится навтором прохождении, аможет люди смогли разглядеть тот шарм, который вAlpha Protocolе несомненно есть. Отсебя могу сказать, что игра действительно хороша как шпионский боевик. Благодаря тому, что отваших действий ивыборов зависит сюжет, можно почувствовать себя настоящим шпионом, которому необходимо моментально принимать решения и выбираться излюбой передряги нетолько посредством собственных умений, нои разнообразных гаджетов. Аразве игры существуют незатем, чтобы мымогли почувствовать себя вшкуре того, кем никогда нестанем?

Глава четвертая. Fallout

Как яуже упоминал, в2003 году Interplay развалилась начасти. Чтобы хоть как-то оставаться наплаву, компания распродавала все, чем еще совсем недавно была известна. Втом числе в2007 году были проданы права наFallout иконическую для Black Isle серию. Новым владельцем стала Bethesda Softworks, впервую очередь известная тогда своими РПГ Morrowind иOblivion. Результатом стала Action RPG в открытом мире. Вышедший 28октября 2008 года Fallout 3 фанаты оригинальных частей восприняли очень болезненно. Отсатиры наамериканское общество в постапокалипсисе остался только постапокалипсис, отсложных моральных выборов остались только выборы, аотинтересных побочных квестов свариативностью не осталось даже вариативности. Нобыла уигры идругая сторона, благодаря которой серия обзавелась толпой новых фанатов, акритики ставили девятки издесяти атмосфера, то, что Bethesda всегда передавала навысшем уровне. Ну, аблагодаря тому, что основной игровой процесс сводился кпострелушкам, игра стала гораздо более массовой, чем ее изометрические отцы. Впервуюже неделю продажи исчислялись миллионами копий. Bethesda решила ковать железо, пока горячо, носама она уже была занята разработкой The Elder Scrolls V: Skyrim, поэтому нестала ходить далеко ипредложила сделать спин-офф тем, кто создал оригинал, тоесть Obsidian.

Договор был заключен. Наразработку снова было дано очень мало времени, вэтот раз 18 месяцев. Место действия было решено перенести назападное побережье. Проблемы незаставили себя долго ждать. Fallout 3 был написан надвижке GameBryo, скоторым вObsidian был знаком лишь один человек. Вкупе сочень коротким сроком наразработку это вылилось встандартные для наших коллег реки багов нарелизе, которые потом еще много лет будут править мододелы. Сценаристом, как нетрудно догадаться, стал Авеллон. Напротяжении долгих 10 лет Крис вынашивал идеи для отмененной Fallout: Van Buren, и, наконец, они пригодились. Он, как обычно, написал отличный сюжет, вкотором нет нихороших, ниплохих, только пустошь илюди, которые выживают, как могут. Особенно хорошо получились компаньоны. Многие считают, что это самые интересные напарники завсю историю игровой индустрии.

Нонеодним Авеллоном богаты. Возглавил разработку Джош Сойер. Онсмог наоснове третьего Falloutа, который был скорее шутером, нежели ролевой игрой, сделать полноценную РПГ систему. Если кконцу Fallout 3 игрок был машиной для убийств, которая истреляет метко излюбого типа оружия, иносить насебе может гору, имину обезвредит, исоюзника подлечит, идаже робота починит, тов New Vegasе создать персонажа, который может все невозможно, и, как ивлюбой классической РПГ, необходимо отыгрывать нетолько мировоззрение, ноиспециализацию персонажа.

Fallout: New Vegas оказался наприлавках 19октября 2010, анапротяжении всего следующего года выходили дополнения, которые ничуть неуступали основной игре. Однако, как яуже сказал, багов снова было немерено, поэтому Вегас, несмотря навсе его положительные стороны, вцелом приняли хуже, чем третью часть. Но, как ипроисходит почти совсеми играми Obsidian, современем все больше ибольше людей начинало ценить то, что находится загранью технического исполнения.

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

Глава пятая. Укротители Kickstarter

В2010 году попросьбе Square Enix Obsidian начала разработку Dungeon SiegeIII. Для нас эта игра важна тем, что для нее разработчики впервые написали свой собственный движок, названный Onyx Engine. Игра вышла 20июня 2011 года. Отзывы были, мягко говоря, несамые лучшие.

Еще в2006 году вObsidian зародилась идея проекта под названием Defiance. Питч прорабатывался вплоть до2011 года, когда был представлен Microsoft. Компанию игра заинтересовала, нопоказалась имслишком стандартной чуть меньше чем через три года должен был выйти Xbox One, иMicrosoft надеялась создать вместе сObsidian игру, которая сможет продвигать сразу все фишки новой консоли. Obsidian согласилась переработать концепцию ичерез некоторое время презентовала демоверсию Stormlands, созданную надвижке уже упомянутого Dungeon SiegeIII. Предполагаемая игра представляла собой Action RPG снапарниками идиалоговым колесом, давящей атмосферой иинтересными механиками. Главная особенность игровой вселенной магические штормы, которые оставляли засобой горы трупов, новыжившие получали магические способности. Microsoft подписала контракт, иразработка пошла вполную силу.

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

Игру предполагалось делать наUnreal Engine 4, однако, как ивслучае сосвоим предшественником, ондолжен был выйти вместе сновым поколением консолей, что существенно тормозило технический процесс. Тем временем владельцы кресла исполнительного продюсера состороны Microsoft постоянно менялись. Каждый считал своим долгом предлагать все новые иновые механики, которые, поего мнению, вполной мере раскрылибы потенциал Xbox.

Вот какую концепцию предложилиMicrosoft: представьте, что выиграете вВедьмака, может быть сдругом. Что произойдет, если вопределённый момент времени появится гигантское существо, которое высможете увидеть нарасстоянии? Ионо появится нетолько для вас, нодля всех людей, играющих вданный момент. Ивывсе спешите кэтому монстру, возле которого расположен лабиринт. Втот момент, когда выпроходите сквозь лабиринт, игра подбирает лобби для рейда на40 человек, которые собираются сразить монстра. Фергюс Уркхарт

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

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

Вмарте 2012 года Фергюсу Уркхарту позвонили изMicrosoft, ипотенциально самая дорогая игра Obsidian была отменена. Студии повезло, что вэтот момент уних был еще один контракт. В разработке находилась ролевая игра South Park: The Stick ofTruth. Еслибы не она, тостудиябы просто обанкротилась. Однако без потерь все равно не обошлось. Были проведены самые масштабные вистории компании сокращения, входе которых было уволено около 30 человек, втом числе инженер, которого наняли только вчера. Стало понятно, что если вближайшие 6 месяцев Obsidian не получит финансирование, тоэто станет для нее концом.

Тем временем вDouble Fine, студии еще одного известного деятеля игровой индустрии, Тима Шейфера, произошло чудо. Его кампания наKickstarter побила все мыслимые инемыслимые рекорды. Доэтого момента считалось, что кикстартер это платформа для любителей, благодаря которой они могут собрать небольшую сумму денег насвою деятельность узаинтересованного круга лиц, аконечная сумма редко достигала иотметки всто тысяч долларов. Кампания Шейфера же завершилась сборами вколоссальные для независимого проекта 3,3 миллиона долларов.

Тим ШейферТим Шейфер

Авеллон идругие, вдохновившись примером Double Fine, предложили Фергюсу собрать денег насобственный проект темже способом. Это позволило быпроинвестировать встудию самим игрокам, анеиздателям, заинтересованным исключительно ввыгоде, ане втворчестве. Однако Уркхарт такую идею нехотел даже рассматривать, ему казалось, что это проявление слабости, которую оннехотел показывать своей аудитории. Поэтому все, кто неработал над игрой поюжному парку, были отправлены создавать ипрезентовать питчи крупным издателям. Компания успела предложить Ubisoft игру поMight & Magic, Activision игру поSkylanders, Bethesdе предлагали свою версию Prey 2, иеще десятки других проектов были предложены десяткам студий. Везде они получали отказ. Понимая, что никто незахочет издавать игру, откоторой уже успела отказаться Microsoft, Крис Авеллон предложил переработать концепцию Stormlands. Так появился прототип под названием Fallen. Вместе сним студия обошла всех издателей повторому кругу, однако ответ оставался неизменным.

Уркхарт уже начал приглашать назавтраки штатного юриста, чтобы обсудить, как лучше закрыть студию, когда Джош Сойер иАдам Бреннеке выдвинули ультиматум: либо они запускают кикстартер-кампанию под эгидой Obsidian, либо создают свою собственную студию изапускают кампанию черезнее. Фергюс сдался, иКрис Авеллон, Адам Бреннеке иДжош Сойер начали работу. Всем было очевидно, что нужно создать то, что они умели лучше всего изометрическуюРПГ.

Параллельно сразработкой игры, получившей рабочее название Project Eternity, Авеллон успел поработать еще над двумя сторонними проектами. Уже вмае 2012, когда Obsidian металась отиздателя киздателю, упредыдущего владельца Torment кончились права. И, пока была такая возможность, торговую марку купил наш старый знакомый Брайан Фарго. Зная, как важна эта вселенная Крису, онвстретился сним, чтобы убедиться, что тот нанего невобиде. Разговорившись, Брайан предложил Авеллону поработать над Wasteland 2, которая как раз находилась вразработке после успешной кикстартер-кампании. В ходе сотрудничества Крис отвечал задизайн двух локаций: Хайпула иАГЦентра, чьи квесты были связаны между собой, вконце которых необходимо было сделать Авеллоновский выбор между двухзол. Игра вышла 18сентября 2014, критики оценили еенанеплохие 81 балл.

Спустя ровно год Фарго пригласит Авеллона поработать над еще одной игрой. Вэтот раз над духовным наследником Planescape: Torment, ради которого год назад ипокупалась лицензия. Крис выступил сценаристом иконсультантом по вселенной. Кикстартер-кампания собрала 4,2 миллиона, вкоторый раз закрепив успех Kickstarterа как площадки для независимых разработчиков, ноэто будет потом. Игра выйдет 28февраля 2017 иполучит теже 81 балл, что инедавный соотечественник.

Новернемся вObsidian. 10сентября приготовления были закончены, инаофициальном сайте компании пошел обратный отсчет, который должен был завершиться через 4 дня. 14сентября в10:00 по местному времени Адам Бреннеке опубликовал страницу игры накикстартере. Уже наследующий день было собрано больше миллиона долларов, акконцу кампании, 16октября, цифра вплотную приблизилась к4 миллионам.

Рассказывать всю историю создания явам небуду по двум причинам:

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

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

Джейсон Шраер скнигойДжейсон Шраер скнигой

Насамом деле спасла студию неPillars ofEternity, азнаменитая вРоссии Mail.ru Group. Она подписала договор сObsidian на создание танкового экшена Armored Warfare. Инеизвестно, как сложиласьбы история, еслибы неэтот контракт. Так классическая РПГ стала лицом компании, аПроект Армата подушкой финансовой безопасности, если сколоннами что-то случится.

Pillars of Eternity вышла 26марта 2015 года ипродалась очень неплохим для изометрической РПГ тиражом в 1,5 миллиона копий, атакже получила неплохие оценки и89 баллов по метакритику.

Наконец поговорим опоследней игре, вработе над которой Авеллон принимал участие вObsidian. Fallen, откоторой отказались все издатели, была переработана ещераз. Так появилась концепция игры Tyranny, которая заинтересовала Paradox Interactive. Перед своим уходом Авеллон успел поработать над лором этой игры, что явно на ней отразилось. Игра так итолкала назлодейства. Однако внепосредственной разработке Крис участия непринимал. Вышла Tyranny 10ноября 2016 года, продалась тиражом внеплохие 500 тысяч копий, однако издатель влице Paradox Interactive остался неслишком доволен таким числом. Критики оценили игру на80 баллов.

Итак. Виюне 2015 года Крис Авеллон покинул Obsidian Interactive. За20 лет виндустрии онуспел поработать над множеством проектов, почти все изкоторых были сделаны либо вBlack Isle, либо вместе свыходцами изBlack Isle. Нонастала пора ему двигаться дальше, навстречу новым проектам иновым разработчикам. Так Крис стал если непервым, тосамым известным игровым сценаристом-фрилансером. Опричинах ухода ничего известно небыло

Глава шестая. Темная сторона Obsidian

Опричинах ухода ничего известно небыло вплоть до мая 2018 года. Спустя три года после своего увольнения Крис приоткрыл завесу тайны, ипод приоткрыл яподразумеваю водопад из сточных жидкостей, который полился наглав Obsidian.

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

ВBlack Isle Фергюс был непросто руководителем студии, онимел довольно много контроля над проектами ифинансированием, при этом, благодаря его высокому положению вInterplay, оннаходился ближе киздателю, нежели кразработчику. Уркхарт был одним излюдей, которые принимали решения, контролировали финансы, выдвигали требования, могли приостанавливать выплаты, атакже требовать вырезать что-то изигры или сместить сроки. Obsidian стала такойже студией-разработчиком, которыми Фергюс привык помыкать, ноонплохо это перенёс. Контроль пропал, его требования игнорировались, исчезли рычаги давления. Теперь грубое поведение с собственными сотрудниками могло привести кобмену взаимными воплями, которые было слышно даже этажом ниже, авразговоре сиздателями Уркхарт, бывало, просто вешал трубку. Крис идругие владельцы знали обэтом, потому что он приходил кним ихвастался тем, как положил трубку вразговоре сглавой студии или продюсером. Довольно симптоматично, что Obsidian крайне редко работает с одним итемже издателем дважды. Количество издателей, которые нехотят иметь дел сруководством Obsidian, очень велико.

И так небольшое количество времени, отведенное наразработку Knights ofthe Old Republic II, сократилось из-за того, что Крис Паркер настоял натом, чтобы он отвечал заразработку интерфейса. Наэто были потрачены десятки часов, однако конечный результат неслишком отличался оттого, что было впервой части.

УКриса Джонса вобиходе слово невозможно встречалось непозволительно часто. Если выудивлялись, почему KotOR2 неумеет автоматически считывать файлы сохранений (как это могла сделать любая RPG наконсолях иPCотBioWare), томожете поблагодарить заэто Джонса иего любимое слово невозможно.

УКриса (Авеллона) был проект под названием Defiance. Онбыл зарублен Паркером, который его возненавидел (как ненавидел и самого Авеллона). Паркер поставил ультиматум, заявив, что небудет участвовать вэтом, если они продолжат обсуждать игру или дадут еёразработке ход, Фергюс прислушался ипошёл напопятную. После того, как стало ясно, что проект непродвинется, Авеллон попросил Фергюса дать ему разрешение нареализацию игры запределами Obsidian, нополучил отказ. Крис понимает, что это было его право, однако онпотратил огромное количество времени на Defiance иему было обидно, что игра никогда небудет создана.

Есть очень известная виндустрии байка отом, что Bethesda невыплатила миллион долларов Obsidian из-за того, что Fallout: New Vegas недобрал наметакритике одного балла дообговоренного значения, зачто многие игроки повесили набетезду ярлык жадного издателя. Крисже показывает ситуацию сдругой стороны: разработчики недобрали всего один балл илишились выплаты, однако Bethesda вообще необязана была платить. Издатель добавил премию уже после заключения контракта. Она невходила вдоговор ибыла оговорена только насловах. Предложив премию, Bethesda пыталась мотивировать Obsidian выполнять свою работу лучше, нодаже это непомогло. Авеллон не разделяет желание фанатского сообщества повесить вину наBetehsda, поскольку та несделала ничего плохого, скорее наоборот.

Катарина изDungeon Siege III вообще недолжна была появиться вигре, поскольку еёобраз был чрезвычайно сексистским ипошлым. Фергюс Уркхарт не унимался, требуя сделать еёсексуальнее, поэтому разработчики пошли отпротивного исоздали максимально объективированную героиню свыставленной напоказ сексуальностью. Ких удивлению, Уркхарт одобрил концепт.

После выхода Dungeon Siege III Авеллона попросили занять пост руководителя питча для потенциальной Dungeon Siege IV. Просьба исходила неотФергюса, аиз-за Фергюса. Настрадавшись сУркхартом, команда разработчиков обратилась кАвеллону спросьбой стать буфером между ними иCEO. Поскольку Фергюс решал многое напроекте, уразработчиков возникали очень большие сложности сполучением одобрения различных элементов. Авеллон согласился занять роль руководителя проекта, потому что команде, очевидно, нужна была помощь, однако онсомневался втом, что дела обстоят настолько плохо, как ему поведали. Спустя две недели работы онпонял, что всё насамом деле куда хуже, чем сотрудники описывали. Более того, этим проблемы не ограничивались. Несмотря нато, что наличие буфера немного помогло, выявились другие сложности. УФергюса выработалась тенденция неожиданно менять своё мнение относительно элементов, которые онранее уже одобрил, начём команда теряла много времени. Иногда ондаже забывал, что одобрил их, азатем, увидев результат, заявлял, что ему это ненравится ичто оннемог дать этому ход. Подобная ситуация обстояла ссюжетом игры. Крис икоманда сражались засвою версию истории ивитоге получили одобрение наеёнаписание, однако спустя несколько дней, когда Авеллон уже сообщил разработчикам хорошие новости иони продолжили развивать идею, Фергюс забыл освоём решении изаявил: Почему этот сюжет, анемой? Яэтого неодобрял. После того, как Уркхарту доказали, что он действительно позволил команде работать над этой версией истории, тот просто заявил, что передумал. Вслед заэтим Крис почувствовал, что подвёл команду ине справился, утратив контроль над ситуацией, несмотря налучшие намерения. Осознав, что насамом деле ничего неизменил инеулучшил ситуацию, Крис покинул пост руководителя проекта. Вскоре умер исам питч, что, помнению Авеллона, клучшему. Идея звучала хорошо, нопроцесс работы выдавливал изнеё всю жизнь. Всё обернулось пустой тратой времени исил.

Авеллон несчитает, что всё, очём просила Microsoft вовремя разработки Stormlands, было невыполнимо. Лишь некоторая часть запросов оказалась чрезмерно сложна. Несмотря нато, что многое можно было обсудить исгладить углы, руководство Obsidian отвечало жёстким Нет набольшинство запросов. Учитывая такую реакцию, неудивительно, что Microsoft современем перестали делать запросы. Врезультате игра была отменена. Отмена Stormlands нанесла серьёзный урон студии. Много людей было уволено из-за того, что несколько человек приняли неверные решения. Среди уволенных людей были те, кто вообще неимел никакого отношения кStormlands, но потерял работу из-за отмены игры. Когда Крис попрощался суходящими коллегами и вернулся вофис, оказалось, что одного человека передумали увольнять. Это была девушка сресепшена. Сестра Фергюса.

Проект духовного наследника Planescape: Torment носил рабочее название Last Rites ипланировался задолго дотого, как Брайан Фарго зарегистрировал торговую марку Torment для будущей Tides ofNumenera. Фергюс знал, что IPвскоре будет свободна идолжен был купить название Torment для проекта Obsidian, номесяцы проволочек привели ктому, что Фарго ихобогнал. Авеллона очень расстроило, что Фергюс подвёл студию, когда должен был действовать решительно, ивитоге упустил важную торговую марку.

Работа Авеллона над Wasteland 2 велась поконтракту, аденьги ушли наподдержку Obsidian, которой было необходимо покрывать долги. Фергюс иКрис обговорили график иколичество дней, которые Авеллон будет проводить вinXile, основываясь насумме оплаты. Всередине работы над Wasteland 2 Уркхарт передумал иотменил рабочие часы Авеллона вinXile. Крис показал ему расписанный график, накоторый тот согласился, упомянул все договорённости и данные обещания, однако аргументы непомогли. Онпросто хотел, чтобы Авеллон вернулся вObsidian наполный рабочий день, аобещания идоговорённости его не волновали.

Крису было позволено работать над Tides ofNumenera только потому, что inXile лицензировала уObsidian инструментарий, предназначенный для изометрической игры набазе Unity Engine, который студия разработала для Pillars ofEternity. Пока компания получала чеки засвою технологию, Авеллон мог трудиться над проектом inXile. При этом Крис работал над Torment всвоё личное время, не отбирая рабочие часы уObsidian. Фергюс пытался снизить долю Авеллона заTorment вдвое, ноунего не вышло, потому что Крис лично обговорил детали сБрайаном Фарго ещё дотого, как Уркхарт попытался взять финансовую сторону сделки под личный контроль. Когда речь зашла обоплате Авеллона, Фергюс назвал сумму вдвое ниже той, которую предложил ему Фарго. Крис ответил, что детали его персональной оплаты уже обговорены.

Самым большим потрясением было то, когдасотрудники компании (невладельцы, именно сотрудники) начали возвращать чеки сзарплатой, чтобы спасти Obsidian отбанкротства. Нокак только деньги начали поступать вбанк иситуация стала налаживаться после сурового периода, расходы компании вдруг стали расти. Для Криса эта ситуация была некомфортной, поэтому кмоменту, когда денег вбанке снова было вдостатке, онпредложил расплатиться стеми людьми, которые отдали свои чеки для спасения компании. В ответ наэто совладельцы промолчали. Тогда Авеллон повторил, что необходимо вернуть людям ихденьги, начто Уркхарт ответил: Мыникогда необещали, что вернём ихобратно. Крис считал, что возвращение денег это некакая-то формальность, ато, что попросту нужно сделать, потому что это правильно. В ответ Фергюс пожелал прекратить обсуждение данного вопроса. Ксчастью, нашёлся другой совладелец, который убедил Уркхарта согласится сАвеллоном. Крису стыдно даже засам факт того, что это обсуждение имело место быть, поскольку, поего мнению, компании нужно было провести выплаты сразуже, когда проблема с деньгами была решена.

Ноапофеозом стал уход Криса изкомпании. После того как онувидел, насколько управленческий взгляд Уркхарта несовпадает сего собственным, онначал задавать неудобные вопросы. Среди них была просьба сделать финансы компании более прозрачными, вопрос почему, когда насчету компании были деньги, Фергюс свободно тратил их, редко интересуясь мнением совладельцев, атакже интерес Криса кчленам семьи Фергюса, находящимся вплатежной ведомости. Вконце концов, Уркхарт сказал: похоже, ты нехочешь быть совладельцем. Эта фраза звучала каждый раз, когда кто-то пытался ему перечить, ночаще всего вкачестве меры устрашения. После снятия Криса сдолжности совладельца, которым онбыл, наминуточку, все 12 лет существования компании, онподал наувольнение, ивот тут началось самое интересное.

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

Понимая, что уменя есть семейные проблемы идолги (мама Криса проходила химиотерапию для излечения отрака), они попытались использовать всё это как рычаги давления, чтобы яподписал менее выгодное для меня соглашение орасторжении отношений, согласно которому мне запрещалось работать над играми жанра RPG, атакже обязалобы меня хранить молчание относительно всего, что может иметь отношение кObsidian, включая компании, с которыми связана студия или вкоторых еёгенеральный директор имеет процент (Fig, Zero Radius, Dark Rock Industries идругие). Это включало невозможность подвергать критике игры, над которыми яработал моя критика ксобственным проектам обычно довольно прямолинейна иневысказывать еёмне несвойственно.

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

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

Эта попытка давления заставила меня пересмотреть некоторые жизненные аспекты. Поняв, что долги [за лечение матери] могут влиять намои решения, ясосредоточился натом, что стал работать так тяжело, как это возможно, дабы компенсировать себе сумму [выходного пособия], которую Obsidian пытались удержать как рычаг, заставляя меня подписать договор. Имне удалось.

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

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

Кроме того, понимая, что возмещения ущерба завсё вышеозначенное янеполучу, япообещал себе, что больше никогда небуду работать над чем-либо, что принесёт финансовую выгоду Фергюсу идругим владельцам компании. Если моё молчание для них настолько важно, значит, янедолжен молчать, поскольку ятак инеподписал тот договор. Проще говоря, мне очень сильно нравятся разработчики, трудящиеся в Obsidian, яработаю ипереписываюсь сомногими изтех, кто остался там, иябы судовольствием поработал сними вбудущем. Ясчитаю, что увысшего руководства Obsidian имеются серьезные недостатки, скоторыми необходимо что-то сделать, и янесобираюсь отказываться отсвоих слов. Крис Авеллон

Эпилог

Насамом деле неслишком важно, кто вэтой ситуации прав, акто виноват, нонаданном примере мычетко можем понять, что происходит, когда разработчики ируководство компании неподдерживают друг друга. ВObsidian полно людей, знающих свое дело, нокаждый раз ихработа принимается вразы хуже, чем моглабы, небудь вней багов, которые просто неуспевают починить из-за плохого менеджмента. Яговорю обэтом, потому что буквально пару месяцев назад мыстали свидетелями того, как одни изталантливейших разработчиков ударили вгрязь лицом из-за недобросовестного пиара иплохого менеджмента (я, конечно, говорю оситуации сCDProject Red икиберпанком, когда большая часть претензий сообщества легла наплечи разработчиков). Поэтому прежде, чем обвинять кого-то внекомпетентности, стоит самому разобраться в вопросе.

Однажды Лебедь, Рак да Щука

Везти с поклажей воз взялись,

И вместе трое все в него впряглись;

Из кожи лезут вон, а возу всё нет ходу!

Поклажа бы для них казалась и легка:

Да Лебедь рвется в облака,

Рак пятится назад, а Щука тянет в воду.

Кто виноват из них, кто прав, судить не нам;

Да только воз и ныне там.

Подробнее..

То, чего не может быть самые необычные версии обычных игровых консолей

17.06.2021 12:20:28 | Автор: admin


Мы с вами давно привыкли к тому, что на протяжении своего жизненного цикла игровые консоли остаются практически неизменными. Да, они подвергаются рестайлингу, выходят в разных комплектациях и лимитированных версиях, приуроченных к громким релизам или юбилею платформы, и даже могут получить более мощную начинку. Однако в общем и целом модификации одной и той же приставки идентичны по функционалу и не имеют принципиальных различий, а ситуации вроде той, что произошла с PlayStation 3, когда последующие ревизии консоли лишились аппаратного блока для запуска игр с PS2, являются скорее исключением, нежели правилом.

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

Теория гибрида: консольные эксперименты Sega


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

Sega SC-3000



8-битный игровой компьютер Sega SC-3000

Первые эксперименты со скрещиванием разнообразных девайсов Sega начала еще в 1983 году, выпустив 8-битный компьютер SC-3000, способный запускать игры для оригинальной домашней системы SC-1000 и позволяющий своему владельцу создавать простенькие программы. Хотя девайс был доступен в ограниченном числе стран (помимо Японии, SC-3000 официально продавался только в Австралии, Франции, Италии, Финляндии и Новой Зеландии), гибридная игровая консоль оказалась достаточно востребованной, показав даже лучшие результаты, чем ее предшественница.

Приставка-компьютер выпускалась в двух основных модификациях: кроме базовой версии, оснащенной встроенной мембранной клавиатурой довольно низкого качества, существовала и более дорогая SC-3000H, получившая полноценную механику.


Sega SC-3000H с механической клавиатурой

По характеристикам Sega SC-3000 и SC-1000 были практически идентичны: оба девайса были построены на базе процессора Zilog Z80A и использовали графическую подсистему от Texas Instruments TMS9918A с 16 КБ видеопамяти. Ключевое отличие между устройствами заключалось в объеме оперативной памяти: Sega SC-3000 несла на борту 2 КБ RAM вместо 1, как у SC-1000.

Помимо этого, количество оперативной и видеопамяти памяти у SC-3000 можно было увеличить с помощью картриджей BASIC разных типов, на которых также было записано программное обеспечение, необходимое для работы домашнего компьютера. Всего существовало 4 разновидности картриджей:

  • BASIC Level II A не добавлял дополнительной памяти;
  • BASIC Level II B добавлял системе 4 КБ RAM и 16 КБ VRAM;
  • BASIC Level III A добавлял 18 КБ RAM и 16 КБ VRAM;
  • BASIC Level III B добавлял 32 КБ RAM и 16 КБ VRAM.

В 1984 году для Sega SC-3000 был выпущен аддон Super Control Station SF-7000, расширяющий возможности оригинального устройства. Super Control Station добавлял компьютеру дополнительные 64 КБ оперативной памяти, 8 КБ ПЗУ, параллельный порт Centronics и последовательный порт RS-232, а также флоппи-дисковод.


Sega SC-3000H с подключенным к ней Super Control Station SF-7000

В отличие от самой гибридной консоли особой популярностью аддон не пользовался, прежде всего из-за дороговизны: на старте за устройство просили $600, то есть, почти вдвое больше, чем за сам SC-3000. Кроме того, дисковод Super Control Station был рассчитан не на доступные 3.5-дюймовые дискеты, а на более редкие 3-дюймовые, что делало данный девайс еще менее привлекательным в глазах конечного пользователя.

Sega Teradrive и Amstrad Mega PC



ПК со встроенной игровой консолью Sega Teradrive

Воодушевившись успехом SC-3000, в 1991 году Sega предприняла очередную попытку скрестить ПК и игровую консоль. На этот раз гибрид, выпущенный эксклюзивно для японского рынка и получивший название Teradrive, объединил в себе IBM PC на базе процессора Intel 80286 и популярную приставку Sega Mega Drive. Всего свет увидели 3 модели Teradrive, отличающиеся друг от друга объемом оперативной памяти и конфигурацией накопителей данных. Топовая модификация Model 3 несла на борту 2.5 МБ RAM, винчестер на 30 МБ и поставлялась с предустановленной операционной системой DOS/V (специальная версия DOS, поддерживающая японские иероглифы). В отличие от обычных IBM PC, системный блок Teradrive имел на корпусе слот под стандартные картриджи Sega Mega Drive.

Два года спустя Sega совместно с Amstrad выпустила более совершенную версию Teradrive, ориентированную на международный рынок и получившую название Mega PC.


Гибридный ПК Amstrad Mega PC

Гибридные ПК, выполненные на базе CPU Motorola 68000 или Intel/AMD 80386sx, оснащались 1 МБ оперативной памяти с возможностью расширения до 16 МБ, жестким диском на 40 МБ и дискретной графической подсистемой от Western Design Center WD90C11A-LR SVGA с 256 КБ VRAM на борту и возможностью расширения до 512 КБ.

И Teradrive, и Mega PC закономерно провалились в продажах. Причиной этого оказалась неадекватная цена за сравнительно слабое даже по тем временам железо. Так, например, имея на руках $2000, которые просили за Mega PC на старте, вы могли собрать куда более мощный ПК с Intel 80486DX, на котором можно было комфортно работать и играть, так что для большинства потребителей покупка такого гибрида попросту не имела смысла. Результат вполне закономерен: оба ПК были сняты с производства уже в год релиза, а анонсированный Amstrad Mega PC Plus на базе Cyrix Cx486SLC так и не увидел свет.

Victor Wondermega и JVC XEye



Игровая консоль с функцией караоке Victor Wondermega RG-M1

С момента изобретения караоке обрело невероятную популярность в Стране восходящего солнца, став неотъемлемой частью японской культуры, поэтому появление консоли Victor Wondermega RG-M1, разработанной Sega совместно c JVC, было лишь вопросом времени. Гибридный аппарат, дебют которого состоялся в 1992 году, объединял в себе игровую консоль Sega Mega Drive, аддон Mega CD и продвинутый аудиоплеер, оснащенный высококачественным цифровым сигнальным процессором от JVC, MIDI-выходом и парой 3.5-миллиметровых разъемов Audio Jack для подключения микрофонов.

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


Дисковод Wondermega получил стильную светодиодную подсветку

Дело в том, что все модификации Wondermega поддерживали работу с Sega 32X, однако из-за особенностей конструкции консоли аддон попросту блокировал крышку дисковода после подключения. Чтобы решить эту проблему, Victor предложила покупателям услугу по апгрейду консоли, который сводился к замене стандартной крышки CD-ROM на специальную версию с боковым вырезом. Воспользоваться данным сервисом можно было вплоть до 2013 года, то есть, даже спустя 20 лет после релиза аппарата.


После установки аддон Sega 32X блокировал дисковод консоли

Через год JVC выпустила обновленную версию Victor Wondermega RG-M2. Вторая модель подверглась рестайлингу (однако проблема с Sega 32X так и не была решена) и получила поддержку беспроводных геймпадов, подключаемых к приставке с помощью фронтального ИК-порта. Впрочем, при желании владельцы консоли могли использовать и классические контроллеры, благо порты DE-9 никуда не делись, а лишь были перемещены на заднюю панель.


Wondermega RG-M2 с беспроводным геймпадом

Весной 1994 года свет увидела специальная версия Wondermega RG-M2 для США разработкой и дистрибуцией которой занималась уже сама JVC. Устройство получило название XEye и во многом уступало оригиналу. Первая партия консолей лишилась ИК-порта для беспроводных геймпадов и разъема S-Video, место которого занял 9-контактный AV-порт, а более поздние модификации приставок JVC XEye остались без поддержки аддона Sega 32X.


JVC XEye для американского рынка

Увы, проект Wondermega оказался провальным, причем как и в случае с Teradrive и Mega PC, главной причиной фиаско оказалась ценовая политика компании: купить Sega Mega Drive и Sega CD было куда дешевле, нежели чудо-агрегат от JVC (70 тысяч йен против 82 тысяч), а музыкальные системы с поддержкой караоке и так были у большинства поклонников данного развлечения.

Aiwa СSD-GM1



Игровой бумбокс Aiwa СSD-GM1

Плодом сотрудничества Sega с японской компанией Aiwa, специализирующейся на производстве бытовой электроники, стала портативная стереосистема Aiwa СSD-GM1, выпущенная ограниченным тиражом в Японии в 1994 году. Девайс вышел во всех отношениях странным: если покупатель той же Wondermega получал в свое распоряжение универсальный аппарат в монолитном корпусе, то в случае с СSD-GM1 консоль Sega Mega Drive была вынесена в независимую док-станцию, подключаемую к основному устройству с помощью идущего в комплекте кабеля. Сам же бумбокс заменял собой Sega CD, позволяя запускать на Mega Drive игры на оптических дисках.


Док-станция и стереосистема соединялись с помощью кабеля

Как и в случае с Wondermega, Aiwa СSD-GM1 поддерживала Sega 32X, так что владелец системы мог подключить этот аддон, чтобы поиграть в немногочисленные эксклюзивы и улучшенные версии оригинальных проектов для Mega Drive. Однако из-за неудачного расположения слота для картриджей, в который вставлялся Sega 32X, собранный воедино девайс необходимо было каждый раз класть набок.

Хотя Aiwa СSD-GM1 была не особо востребована среди геймеров на релизе, сейчас этот артефакт весьма ценится коллекционерами: найти полный комплект на том же eBay совсем непросто, а если таковой и удастся отыскать, будьте готовы выложить за него не менее 5 тысяч долларов.

Hitachi Hi-Saturn MMP-1000NV



Hi-Saturn MMP-1000NV игровая консоль для автомобилистов

В числе стратегических партнеров Sega, получивших права на создание собственных версий игровой консоли Saturn, была и Hitachi, занимавшаяся разработкой процессора и дисковода для игровой консоли. Среди нескольких моделей приставок, выпущенных японской корпорацией, особого внимания заслуживает Hi-Saturn MMP-1000NV, также известная под именем Game & Car Navi Hi-Saturn.

Как можно догадаться по расширенному названию, данный аппарат был ориентирован на геймеров-автолюбителей. К MMP-1000NV можно было подключить портативный ЖК-монитор, ТВ-тюнер и спутниковый навигатор с поддержкой картографического ПО Naviken, которые продавались отдельно, и запитать систему через прикуриватель с помощью специального адаптера. Также Hi-Saturn можно было использовать и в качестве аудиосистемы с функцией караоке, причем эта версия приставки обзавелась полноценным мультиплексором.


Реклама Hi-Saturn MMP-1000NV на развороте японского журнала

Несмотря на богатый функционал, Hi-Saturn MMP-1000NV не пользовалась особой популярностью, ведь даже за ее базовую версию просили почти $1500, тогда как за портативный дисплей пришлось бы отдать еще $440. Стоит ли возможность скоротать время за видеоиграми в пробке подобных затрат? Для большинства автомобилистов ответ на этот вопрос оказался вполне очевиден.

Fuji Divers 2000 CX-1



Игровой телевизор Fuji Divers 2000 CX-1 со встроенной Sega Dreamcast

В мае 2000 года Sega сделала невозможное, выпустив совместно с Fuji практически идеальный геймерский телевизор, обладать которым мечтал, наверное, каждый фанат Dreamcast. Речь идет об уникальном моноблоке Fuji Divers 2000 CX-1, выполненном в форме головы бессменного маскота Sega ежика Соника, главного героя серии игр Sonic the Hedgehog.


Корпус Fuji Divers 2000 CX-1 напоминал голову ежика Соника

Помимо футуристичного дизайна, Fuji Divers 2000 CX-1 отличался весьма богатым функционалом. Это был отнюдь не просто моноблок со встроенной игровой консолью, а самый что ни на есть полноценный Smart TV! Телевизор имел полный набор сетевых интерфейсов и поддерживал работу с клавиатурой и веб-камерой Dreameye, которые поставлялись в комплекте, благодаря чему его владелец мог с комфортом серфить в Интернете и даже участвовать в видеоконференциях, используя фирменное ПО Dream Passport 3 от Sega.

Счастливые обладатели Fuji Divers 2000 CX-1 также отмечали превосходное качество цветного 14-дюймового кинескопа и встроенных стереодинамиков, что помогало с головой погрузиться в игровой процесс.


Комплектация Fuji Divers 2000 CX-1 была весьма богатой

К сожалению, гибридный игровой телевизор был выпущен ограниченным тиражом и только для японского рынка. Так что если вы вдруг захотите приобрести подобное чудо в свою коллекцию, будьте готовы отдать за него от 3 до 5 тысяч долларов США.

Sega Fish Life



Виртуальный аквариум Sega Fish Life

Однако самой дорогой модификацией Dreamcast оказался аппарат под названием Sega Fish Life, предназначенный для запуска всего одной игры. Специальная версия консоли вышла в 2000 году и была ориентирована на рестораны и отели. В комплект стоимостью 6 тысяч долларов США, помимо самой приставки, входил разработанный Sega 15-дюймовый сенсорный LCD-монитор.

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


Совсем как настоящая, ведь правда?

Увы, Fish Life оказался слишком дорог даже для предприятий HoReCa. В общей сложности Sega удалось реализовать около 300 комплектов оборудования, а большую часть тиража впоследствии пришлось утилизировать.

Страсти по Nintendo: инновации, интриги и предательства


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

Sharp Famicom Titler



Famicom Titler самая навороченная 8-битная консоль

Если вы полагаете, что выпуск PRO-версий консолей на закате поколения является ноу-хау Sony, то жестоко ошибаетесь: именно Nintendo стала первопроходцем на этом поприще, представив в 1989 году игровую систему Famicom Titler прокаченную версию оригинальной NES, разработанную совместно с Sharp.

На момент релиза Famicom Titler являлась самой технологичной 8-битной игровой системой из представленных на рынке, поистине опередив свое время. Консоль умела генерировать RGB-видеосигнал, выводя на телевизор картинку, сопоставимую по сочности и четкости с изображением, генерируемым игровыми автоматами на базе PlayChoice-10. В свою очередь, полный набор видео- и аудио- входов и выходов, среди которых присутствовал и S-Video, позволял подключать к приставке камкордер и видеомагнитофон, записывать игровой процесс на видеокассеты и использовать Famicom Titler для видеомонтажа.


Задняя панель Famicom Titler

С помощью встроенного программного обеспечения пользователь мог добавлять к видео субтитры (для ввода букв на корпусе консоли был предусмотрен миниатюрный сенсорный дисплей, причем аппарат умел распознавать рукописный текст, преобразуя его в печатные символы), записывать аудиокомментарии с помощью поставляемого в комплекте микрофона, и накладывать на видеоряд клипарты из богатой коллекции, сохраненной во внутренней памяти устройства. Таким образом каждый владелец Famicom Titler мог без особого труда создавать эффектные видеооткрытки и забавные клипы без специальных знаний и дорогостоящего оборудования.

Ничего не напоминает? Фактически Sharp Famicom Titler предвосхитил появление социальных сетей, сторис и летсплеев. Другое дело, что в конце 80-х все это являлось лишь смутным концептом: тогда мало кто мог себе представить, что в будущем сетевые технологии позволят передавать файлы и потоковое видео на колоссальные расстояния, а ведь именно возможности свободного обмена информацией между людьми и не хватало для популяризации такого функционала. Как следствие, в своих последующих игровых системах Nintendo отказалась от дальнейших экспериментов подобного толка, всецело сосредоточившись на совершенствовании игровых систем.

Sharp Famicom TV C1, Sharp NES TV и Sharp SF-1 SNES TV



Игровой телевизор Sharp Famicom TV C1

В отличие от Sega, Nintendo никогда не стремилась скрестить бульдога с носорогом. Очевидно, менеджеры компании прекрасно понимали, что аудитории пользователей ПК и домашних консолей мало пересекаются, а создать производительный и, вместе с тем, доступный комбайн, который бы устроил всех, в принципе невозможно. Идея же игрового телевизора напрашивалась сама собой, так что появление проекта Sharp Nintendo Television не заставило себя долго ждать.

Первой ласточкой в рамках данной концепции стал Sharp Famicom TV C1, вышедший в 1983 году и продававшийся в Японии под официальным названием My Computer TV C1. Линейка цветных телевизоров со встроенной NES включала в себя две модели с диагональю экрана 14 и 19 дюймов. Моноблоки поставлялись с предустановленными приложениями JR GRAPHIC и TV NOTE. Также к каждому телевизору прилагался мультикартридж с урезанными версиями игр Donkey Kong Jr. и Donkey Kong Jr. Math. На тот момент это был единственный лицензионный мультикартридж для игровой системы Famicom.

Релиз версии Sharp Famicom TV C1 для США, получившей название Sharp NES TV, состоялся в августе 1989 года. Игровые телевизоры получили обновленный дизайн корпуса, который оказался не самым удачным: пластиковые ножки, призванные обеспечить устойчивость системы, были слишком хрупкими и быстро ломались.


Sharp NES TV отличался весьма хрупкими ножками

В следующем поколении консолей Nintendo вновь обратилась к Sharp, и в 1990 году свет увидели две модели игровых телевизоров Super Famicom Naizou TV SF1 (SF1 SNES TV) с диагональю экрана 14 и 21 дюйм. За пределами Японии моноблоки официально не продавались.


Телевизор Super Famicom Naizou TV SF1 со встроенной SNES

С проектом Sharp Nintendo Television связан интересный факт. В силу технологических особенностей моноблоки выдавали заметно лучшую картинку, нежели обычные NES и SNES. Из-за этого в рекламе и пресс-релизах Nintendo использовала скриншоты, полученные именно с помощью игровых телевизоров, поскольку они смотрелись значительно эффектнее. Конечно, подобное лукавство не идет ни в какое сравнение с современными махинациями с пререндеренными сценами, выдаваемыми за реальный геймплей, однако даже здесь Nintendo оказалась законодателем мод.

SNES-CD (Nintendo PlayStation)



Полумифическая Nintendo PlayStation во плоти

Долгое время SNES-CD окутывал ореол таинственности. Вокруг этого устройства ходило немало слухов и спекуляций, а многие эксперты и коллекционеры и вовсе считали консоль выдумкой. Так продолжалось вплоть до 2015 года, когда наконец был обнаружен единственный уцелевший из 200 выпущенных прототипов уникальной приставки, созданной ныне непримиримыми конкурентами Sony и Nintendo.

Обретение SNES-CD иначе, как чудесным, не назовешь. Один из бывших сотрудников Advanta Corporation, Терри Диболд, после банкротства компании выкупил часть ее имущества, выставленного на аукцион, всего за $75. Среди приобретенного по дешевке хлама было и нечто весьма необычное, больше похожее на фейк. Странная находка представляла собой игровую консоль, оснащенную слотом для картриджей и CD-приводом, и идущую в комплекте с геймпадом, облик которого один в один повторял дизайн стандартного контроллера для SNES. Вот только на всем перечисленном гордо красовалась надпись PlayStation.


SNES-CD в сравнении с оригинальными Super Famicom и PlayStation

А история была такова. Понимая, насколько перспективным может оказаться использование оптических дисков в качестве носителей данных для игровых консолей, Nintendo в конце 80-х стала искать партнера для реализации подобного проекта, обретя его в лице Sony. В 1989 году две японских компании начали разработку модификации SNES со встроенным CD-приводом, получившую кодовое название PlayStation. Официальный анонс инновационной игровой системы состоялся 28 мая 1991 года в рамках выставки Consumer Electronics Show, прошедшей в Чикаго, став чуть ли не главной сенсацией мероприятия. А уже на следующий день Nintendo объявила о прекращении сотрудничества с Sony и заключении договора с голландской компанией Philips.

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


Кен Кутараги, отец PlayStation и главный интриган игрового подразделения Sony

Превентивный удар, призванный выбить почву из под ног потенциального конкурента, возымел диаметрально противоположный эффект. Тогдашний президент Sony, Норио Ога, после такого публичного предательства буквально впал в ярость, чем и воспользовался Кен, убедив начальство, что компания сможет без труда отомстить бывшему партнеру. Норио дал добро на создание игрового подразделения Sony Computer Entertainment, которое и возглавил Кутараги, а всего через 3 года состоялся релиз первой Sony PlayStation.

В то же время Nintendo и Philips так и не сумели довести задуманное до конца, в итоге прекратив сотрудничество. А единственным живым напоминанием об этом проекте осталась мертворожденная Nintendo PlayStation, стоимость которой ныне составляет около 300 тысяч долларов США именно за такую цену уникальная консоль была продана на аукционе Heritage, прошедшем в 2020 году в Далласе (штат Техас), некоему коллекционеру, пожелавшему остаться неизвестным.

iQue Player



iQue Player лицензионная китайская консоль Nintendo

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

iQue Player представляла собой локализованную версию Nintendo 64 для рынка Китая, выпускаемую компанией iQue, основанной тайваньским инженером Вэй Йеном при участии японского игрового гиганта. Консоль представляла собой массивный геймпад, внутри которого была спрятана вся аппаратная начинка. Как и оригинал, iQue Player использовал SoC R-4300i, однако из-за различий в архитектуре и прошивке, что было следствием миниатюризации устройства, приставка не могла запускать игры для оригинальной Nintendo 64.

Еще одна интересная особенность iQue Player заключалась в необычном подходе к дистрибуции видеоигр. Последние распространялись через своеобразный аналог современного Nintendo eShop iQue Club. Поскольку на физических носителях игры для этой консоли не выходили вообще, а интернет (не говоря уже о eCommerce) тогда еще не был достаточно развит, геймерам приходилось посещать киоски iQue Depot, где они могли приобрести скретч-карты iQue Ticket с кодами активации понравившихся игр, подключить консоль к сети и скачать дистрибутив на проприетарную флеш-карту iQue Card объемом 64 МБ, заменявшую собой классический картридж (одна из них поставлялась в комплекте с приставкой).

Счастливые обладатели домашнего интернета могли воспользоваться веб-сервисом iQue@Home, чтобы приобрести и загрузить желаемые игры онлайн. С одной оговоркой: для этого было необходимо иметь еще и ПК под управлением 32-разрядной системы Windows, поскольку сама iQue Player выходить в сеть не умела, а драйверы для консоли не поддерживали 64-битные версии ОС.

Все эти сложности закономерно обеспечили приставке оглушительный провал: iQue Player продалась рекордно низким тиражом около 12 тысяч устройств, при этом для нее было портировано всего 14 игр из богатой игротеки Nintendo 64, что также не способствовало росту популярности девайса. Последним релизом на злополучной игровой системе стала Animal Crossing, вышедшая в 2006 году.

Panasonic Q



Мультимедийный центр Panasonic Q шикарный и недоступный

В отличие от прямых конкурентов в лице PlayStation 2 и Xbox, Nintendo GameCube нельзя было использовать в качестве домашнего мультимедийного центра. Поскольку консоль поддерживала исключительно проприетарные оптические диски стандарта mini-DVD, эту проблему было невозможно решить одним лишь обновлением прошивки: полноразмерные накопители попросту не влезали в миниатюрный дисковод.

Чтобы исправить это недоразумение, Nintendo заключила партнерский договор с Panasonic, благодаря чему в конце 2001 года на свет появился мультимедийный центр Panasonic Q. Цельнометаллический девайс, напоминавший по своему дизайну этакий SWAG-осциллограф, поддерживал воспроизведение DVD, VCD, Audio CD и MP3 CD, включая самописные, также позволяя запускать любые игры для оригинального GameCube и Game Boy с помощью модифицированной версии Game Boy Player Q (оригинальное устройство не подходило к станции Panasonic из-за форм-фактора). Кроме всего прочего, Panasonic Q мог похвастаться качественной аудиоподсистемой, поддерживал Dolby Digital 5.1 и DTS, и имел отдельный выход под сабвуфер.

Благодаря всему перечисленному гибридная консоль пользовалась (и продолжает пользоваться) популярностью среди коллекционеров, однако рядовые покупатели не оценили столь роскошный агрегат: по всему миру было реализовано менее 100 тысяч устройств. В результате Panasonic Q был снят с производства уже в конце 2003-го года, всего через пару лет после релиза.

Заурядная экзотика: нестандартные консоли от Sony


На фоне конкурентов Sony выглядит несколько консервативно. В портфолио компании практически нет устройств, при виде которых хочется воскликнуть: Да кто вообще мог такое придумать?. Тем не менее и в линейке PlayStation присутствуют несколько не совсем обычных консолей, заслуживающих упоминания в рамках данного материала.

Sony PlayStation Hi-Fi Edition



Аудиофильская PlayStation это как обычная PlayStation, только аудиофильская

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

Бизнес-модель крупных платформодержателей давно является секретом Полишинеля: всем прекрасно известно, что консоли реализуются практически по себестоимости (а иногда и в убыток), тогда как основную прибыль их производители получают благодаря продажам эксклюзивов и 30%-ой комиссии, взимаемой с продаж игр от сторонних издателей. Самое сложное в данной ситуации найти баланс между стоимостью производства устройства и его привлекательностью в глазах целевой аудитории, чего Sony, на радость аудиофилам, сделать не удалось.

Вступая на доселе неизведанную территорию игровой индустрии компания самую малость перестраховалась, установив в первые модели PlayStation (а это SCPH1000 для реализации на территории Японии, SCPH1001, ориентированные на американский рынок, и SCPH1002, предназначенные для продаж в Евросоюзе) топовый 16-битный сигма-дельта ЦАП АКМ AK4309AVM от Ashahi Kasei Microsystems и оснастив консоль полноценными RCA-разъемами, обеспечивающими превосходное качество передачи аудиосигнала.

В результате домашняя игровая приставка за $400 зазвучала значительно лучше, чем аудиосистемы за несколько тысяч долларов США. Благодаря этому первые ревизии PlayStation остаются востребованными среди меломанов и по сей день: поскольку таких устройств было выпущено достаточно много, приобретение б/у консоли все еще остается самым доступным способом приобщиться к миру Hi-Fi.

Sony PlayStation One



Бандл PlayStation One Combo

В 2000 году, на закате поколения, Sony выпустила компактную версию своей первой игровой консоли, получившую название PlayStation One. Данная модель отличалась от толстушки существенно меньшими габаритами (38 193 144 мм против 45 260 185 мм), улучшенной прошивкой и отсутствием последовательного порта для локального мультиплеера. Однако главной фишкой PlayStation One являлась возможность подключения 5-дюймового жидкокристаллического дисплея со встроенными динамиками, который можно было приобрести как в составе бандла PSone COMBO, так и отдельно.


LCD-дисплей для PSone можно было приобрести и отдельно от консоли

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



ЖК-дисплей PlayStation One в сложенном состоянии

Также Sony выпустила специальные блоки питания для подключения приставки к автомобильному прикуривателю и адаптер, позволяющий выводить консоль в Интернет посредством сотового телефона своеобразный мобильный гейминг начала нулевых. Однако перечисленные девайсы практически не продавались за пределами Японии: хотя PlayStation One и показала отличные результаты, обойдя на старте продаж не только предыдущие ревизии оригинальной консоли, но и свою старшую сестру, PlayStation 2, большинство геймеров продолжали воспринимать приставку сугубо в качестве домашней игровой системы.

Sony PSX



Мультимедийная игровая станция Sony PSX

Аббревиатура PSX является не только кодовым именем первого поколения игровых приставок Sony, но и названием уникального устройства 3 в 1, релиз которого состоялся в декабре 2003 года. PSX представлял собой продвинутый CD/DVD-плеер, оснащенный винчестером на 160 ГБ (5000-я серия) или 250 ГБ (7000-я серия), и способный запускать игры для PlayStation и PlayStation 2 благодаря 90-нанометровому гибридному чипу EE+GS, объединявшему в себе, как можно догадаться по названию, Emotion Engine и Graphics Synthesizer для оригинальных приставок.

Мультимедийный комбайн был совместим со всеми официальными геймпадами и картами памяти, выпускаемыми Sony, а старшие модели PSX, DESR-5700 и DESR-7700, также получили поддержку синхронизации с PlayStation Portable, что позволяло переносить между устройствами фото, видео и музыкальные файлы. К сожалению, за пределами Японии PSX не продавались.

Sony BRAVIA KDL22PX300



Телевизор Sony BRAVIA KDL22PX300 со встроенной PlayStation 2

В отличие от Nintendo, Sony не нуждалась в партнерах для создания гибридных устройств: когда компания задумала выпустить собственный моноблок, то взяла за основу линейку телевизоров BRAVIA.

Sony BRAVIA KDL22PX300 с диагональю 22 дюйма и разрешением 720p (1366 на 768 пикселей) вышел в 2010 году. От собратьев игровой телевизор отличало массивное основание, являющееся ничем иным, как модифированной игровой консолью PlayStation 2. Помимо игр, встроенная приставка поддерживала воспроизведение CD, CD-R, CD-RW, DVD, DVD-R и DVD-RW. Добавьте сюда возможность просматривать видеозаписи в большинстве популярных форматов непосредственно с флешки, а также поддержку IPTV, и на выходе вы получите универсальную мультимедийную систему, способную стать отличным приобретением даже сегодня. Тем более, что на вторичном рынке этот девайс все еще можно найти по адекватной цене.



Облачные серверы от Маклауд быстрые и безопасные.

Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!

Подробнее..

Бесплатный онлайн-фестиваль Хочу в геймдев

18.06.2021 20:15:41 | Автор: admin

Приглашаем наонлайн-фестиваль "Хочу в геймдев", который проводится в рамках Russian Creativity Week и состоится8, 9 и 11 июля 2021 г.

Организатор - Центр развития компетенций в бизнес-информатике Высшей школы бизнеса НИУ ВШЭ.

Участие для всех абсолютно бесплатное, нужна только предварительная регистрация.

Вас ждет:

3 дня посвященные геймдеву;

4 лекции от экспертов игровой индустрии;

16 участников пройдут отбор и представят идеи своих игр в прямом эфире - вы можете быть одним из них.

100000 грантами призовой фонд от издательства Geeky House и Zavod Games.

Подробности и регистрация на сайте:https://games.hse.ru/lecture/

Подать свою игру на питч можно здесь, до 1 июля 23:59:https://docs.google.com/forms/d/e/1FAIpQLSfvI5WH8T6M-hgcNEkSJ3pOC3umlfyu25FYvlpdaldjFOPByg/viewform

Подробнее..

Категории

Последние комментарии

© 2006-2021, personeltest.ru