Java Android. Урок 16 (“Делаем игру Salvador”)

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

Что тут есть:

  • Рельеф, который при движении влево или вправо никогда не кончается; он подобно Земному шару, если идти по экватору – придёшь в ту же точку, откуда вышел.
  • Сначала генерирует точка сбора каждого инопланетянина. После его группировки он появляется, а затем через несколько секунд он самовзрывается.
  • Движение всех объектов на экране согласовано в относительном движении игрока
  • Движение игрока выполнено с учетом физики движение (есть скорость движения, есть учёт ускорения/торможения, есть учет сопротивления воздуха). Это позволяет создавать эффект инерционного движения, когда при смене направления движения корабль игрока не мгновенно начинает лететь в обратную сторону, а сначала замедляется, и лишь потом разгоняется в обратную сторону.

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

Инициализацию параметров игрока делаем так:

К координатам игрока я добавил переменные, которые будут хранить его скорость и ускорение, а также их предельные значения (у игрока не должна бесконечно возрастать скорость, иначе это будет противоречить канонам физики). Заметьте, предел ускорения по X и Y различны, оно и понятно – двигатели нашего корабля развивают разную мощность по вертикали и горизонтали))). Тут ещё не мешало бы вспомнить школьный курс физики и математики, что

, где:

L – перемещение объекта

L0 – начальная координата

V0 – начальная скорость

a – ускорение

t – время

Однако, увы, эта формула будет для нас не пригодна, т.к. у нас нет показателя времени – t. Связано это как раз с тем, что обновление экрана мы выполняем квантами времени, как помните,- 25 раз в секунду. Т.е. с точки зрения математики мы обладаем не параметром t, а параметром ∂t (дифференциал t). Исходя из этого и перемещение объекта будем определять через совершенное за единицу времени перемещение. Так и поступим. Изменим для начала метод onButtonDown() как и было это в домашнем задании – он теперь будет определять не какие-то тестовые координаты, а именно само ускорение. С точки зрения моделирования это так и есть – как в автомобиле, чем сильнее нажимаем на педаль газа, тем с большим ускорением разгоняемся. Добавим ещё один параметр с радиусом кнопки, чтобы более универсально можно было настраивать параметры размеров интерфейса.

Разумеется при вызовах тоже нужно это учесть:

Сам расчет расстояния перемещения выведен туда, где он более всего логичен – в метод вызываемый 25 раз в секунду:

Сначала мы находим текущую скорость от ускорения. Затем изменение расстояние от этой скорости, тут вроде должно быть понятно. Подчеркиваю, метод вызывается 25 раз в секунду, по этому с точки зрения динамического моделируемого процесса, мы имеем расчет параметров за единицу времени ∂t. Просто она в математике стремится к нулю, а в жизни для игрока уже всё что чаще 24 кадров в секунду уже незаметно и кажется непрерывным движением, и этого оказывается достаточным. С таким ∂t идеально точный математический расчет траектории мы конечно же не получим, но визуально мы разницы не заметим. Далее в коде идут условия, по которым я ограничиваю и текущую скорость и координаты чтобы корабль игрока не вышел за пределы игрового поля или не развил скорость, при которой уже станет не понятным что на экране вообще происходит. После этого я умножаю на числовую константу ускорение и скорость. Это таким образом я создал эффект сопротивления воздуха, т.е. если игрок отпустит кнопку управления, то через какое-то время его корабль сам плавно остановится. Если бы это был космос, где нет сопротивления воздуха, то корабль летел бы сколь угодно долго пока не столкнулся бы с каким-либо объектом, но в нашей игровой реальности, пардон, виртуальности, условия другие.

Но с этим методом ещё не всё, давайте сразу же добавим в него и ещё кое что:

Основное предназначение этой части кода – управление трансформацией инопланетных объектов. Для каждого объекта выполняется сначала метод run(), далее посмотрим что он делает. Затем определяется тип объекта, что это ещё только группирующийся/взрывающийся объект или уже готовый инопланетянин. Тут же определяется, что если группировка уже завершена, то нужно на этом месте создать инопланетянина, а сам группирующийся объект удалить из списка игровых объектов. Если инопланетянин “прожил” некоторый лимит времени, то должен удалиться из списка игровых объектов, но в этот же момент на этом же месте нужно создать взрыв ( метод explosion() ).

Заметьте, я не сразу прямо в цикле объектов gameObjects удаляю “старый” объект из списка и добавляю туда новый, а изначально создал два временных списка, один для удаления, другой для добавления, и делаю работу над ними уже после выполнения основного цикла. Делается это для того, чтобы не получилось исключительной ситуации. Если циклом перебираем список, и сам цикл зависим от этого массива, то менять состав этого списка внутри этого цикла строго нельзя (иначе результат такого функционала может стать не предсказуемым) !

Завершает метод всё тот же invalidate(), который запускает цепочку системных вызовов по обновлению экрана и запуску метода onDraw().

Претерпел изменения класс GameObject (изменил немного формат некоторых методов). Конструктор теперь не содержит начальных координат, т.к. они генерятся в burn() дочернего класса GroupingParts и больше генерить их пока негде; в конструктор добавлен тип:

Дочерние классы:

Заметьте выполнения класса explosion() также как и burn() только координаты при этом не генерятся и лимиты наоборот, а так всё тоже самое.

Инициализация местности немного изменена (понижена), а инициализация объектов теперь использует тип:

Заметьте, инициализируется группирующийся объект, который (как я вначале написал) после схлопывания удаляется и создаётся одновременно новый уже типа Alien. Сгенерировал сразу 100 объектов чтобы оценить будет ли хромать производительность.

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

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

Рельеф Земли теперь изображается с учетом того, что она якобы круглая, т.е. летим в одну сторону, вылетаем из другой (циклически повторяется). Для этого пришлось сделать её отображение с учетом этого:

Тут было два очевидных варианта решения, либо оставить всё как есть и адаптировать под существующий функционал, либо математически представить её действительно круглой (ввести полярную систему координат и измерять не координатами по x и y, а углами alpha и beta. Но расчеты в полярной системе потребовали бы вычисления косинусов и синусов в вещественных числах, а это существенно забрало бы вычислительных ресурсов. В связи с этим, если вы ещё раз посмотрите на код объектов, то увидите, что вычисление координат при отрисовке претерпело явные изменения. Для рельефа же потребовалось сделать не только цикл его отрисовки, но и два цикла дорисовки на случай, если мы подлетаем к краю рельефа (слева или справа) – визуально он не должен обрываться, а должен дорисовываться его началом до границ экрана, создавая иллюзию циклической поверхности, вроде экватора планеты. Но делать три цикла подряд тут как-то некрасиво, по этому я сделал цикл в цикле.

По факту получилось даже лучше, чем планировалось:

Задание по уроку:

1. Снова оптимизируйте отрисовку рельефа так, чтобы его куски за пределами экрана не отрисовывались. Аналогично оптимизируйте отрисовку объектов и частей группировки / взрыва.

2. Самостоятельно разберите вопрос рисования текста на холсте.

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

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

Урок 15 Урок 17

El Vinto, 2023 (Copyright)

Java Android. Урок 17 (“Делаем игру Salvador”)

Итак, отключаем тестовый процесс самоликвидации инопланетян, просто закомментировав эту строку (мало ли ещё пригодится, а оно так):

Перенесём парочку полезных методов генерации диапазона чисел из GroupingParts в GameObject, т.к. теперь эти метода мы будем использовать ещё как минимум и в классе Alien:

Добавим в Alien аналогичные игроку свойства для перемещения:

Реализуем ещё не задействованный от родительского класса метод run(). Если помните, он вызывается для каждого объекта 25 раз в секунду (до этого тоже вызывался для Alien, просто был “пустым” из родительского класса, заглушкой):

Теперь этот метод в Alien устраивает хаос, причём в прямом смысле этого слова. Мы получаем броуновское движение:

Добавим в класс GameObject заглушку-метод contact() который будет вызываться аналогично run() (и вместе с ней 25 раз в секунду):

Для класса Alien выполним реализацию:

Здесь всё просто – мы находим разницу между координатами игрока и объекта, и если она меньше некой допустимой, значит будем запускать цикл взрыва объекта (переменная waitToExplosion как раз и создана в Alien для этого).

По формуле тоже просто – вспоминаем школу, геометрию, теорему Пифагора:

Заметьте как я нахожу разницу координат по X – у меня стоит знак плюс. Это не ошибка, дело в том, что изначально я спозиционировал игровой процесс в относительном движении (только по X) игрока и всего остального, таким образом его координата всегда будет противоположной всем остальным объектам игры. Также необходимо пройти условия, когда объекты оказываются на границе рельефа местности, когда, например, у одного относительная координата -5000 и у другого 5000, но тут нужно просто из суммы вычесть константу.

Чтобы выполнить взрыв мне будет достаточно просто добавить это в уже существующее условие:

Результат будет очевиден, но придётся хорошенько погоняться за объектами, и это оказалось задачей не из простых))):

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

Теперь выполним то, что должно создавать текст и убирать его по прошествии некоторого времени (в данном случае 2 сек):

В результате получится как-то так:

Задание по уроку:

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

2. Импортируйте шрифт из игры “Быки и коровы”, которую мы делали и используйте его для п.1

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

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

Урок 16 Урок 18

El Vinto, 2023 (Copyright)

Java Android. Урок 18 (“Делаем игру Salvador”)

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

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

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

Сделаем для всего, что связано с игроком отдельный класс и дадим ему имя Gamer:

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

Для инопланетян отрисовка идёт тоже несколько по другому:

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

Метод getR() (расчет расстояния от инопланетянина до игрока) работает на первый взгляд немного странно. Можно заметить, что dx, dy и r – это не локальные переменные метода, а всего класса, при этом метод ещё этот r и возвращает в качестве результата. Всё дело в том, что я использую его и тут и ещё далее сразу для двух функционалов.

Всплывающий текст с бонусами – это такой же игровой объект, как и инопланетяне и группирующиеся объекты:

Ракеты – тоже игровой объект:

Вызываемый метод normalizeCords() – это оптимизация расчета координат реализованная в родительском классе:

Paint для отображения бонусных очков шрифтом из прошлых циклов уроков, мы делаем так – за это отвечает Typeface:

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

Задание по уроку:

1. Сделайте так, чтобы у корабля игрока отображался хвост

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

3. Сделайте функционал уничтожения инопланетян, если луч бластера примерно входит в область инопланетянина.

По результатам домашнего задания должно получиться как-то так:

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

Урок 17 Урок 19

El Vinto, 2023 (Copyright)

Шаверма по-домашнему. Как я делаю

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

Для шавухи потребуется следующее:

  • 500 гр. куриного филе
  • 200 гр. сметаны
  • 100 мл уксуса
  • 2 луковицы среднего размера
  • 50 мл растительного масла (обычное для жарки)
  • 4 дольки чеснока
  • Половина лимона
  • Красный молотый перец чили (по вкусу, я кладу много)
  • Обычная приправа для курицы или индейки
  • Обычный тонкий лаваш (я покупаю длинный и режу на 4 части)
  • Один большой помидор
  • Половина свежего огурца
  • Соль

Маринад:

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

Жарить

Казалось бы, что тут такого пожОрить куру, ан нет. Делю это так. На обычной газовой конфорке, сколько ватт она не знаю, врубаю на полную катушку. Беру большую сковороду, подливаю 3 столовых ложки растительно масла, кладу туда всё что мариновалось, прямо всё содержимое через край и уже на сковороде начинаю перемешивать. По прошествии минут пяти, маринад начнёт шипеть и благоухать уксусом. Вытяжка не помешает тому, у кого проблемы с таким запахом или какие-то проблемы с уксусом в целом. Я обхожусь так, т.к. так легче контролировать процесс жарки. Через минут 15-20, когда кура будет уже готова, подливки должно оставаться ещё на сковороде много, теперь она там будет мешать, но(!) пригодится далее для другого:

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

это значит, что она уже полностью готова. Ошмётки лимона можно вынуть, мелко порезать и замешать обратно. Жарка закончена.

Салат-соус

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

Заворачивание

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

Вылить на неё 2 столовые ложки подливы (которую сливали; именно по этому она уже должна быть пригодна к употреблению). Эта подлива не даст лавашу пересохнуть и сделает его ещё более мягким. Теперь у вас есть от силы минуты 3 чтобы лаваш не размяк. Быстро кладете по середине мясо:

После этого быстро салат:

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

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

Через пару минут приоткрыть гриль и снова той же подливой немного смазать (на фото я слегка переборщил):

Снова закрыть гриль, там всё сразу зашипит, а лишняя подлива начнёт стекать в сборник. Значит делаем всё правильно. Закрываем, периодически наблюдая степень прожарки и готовности. Тут кому как нравится. После этого получаем простую домашнюю шавуху:

Java Android. Урок 19 (“Делаем игру Salvador”)

Продолжаем практическое изучение Java Android на примере игры Salvador. На этом уроке и в его домашнем задании будем делать следующее, т.е. заставку к игре:

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

Для начала добавим переменную roundTime класса GameEngine, которая будет фиксировать прошедшее в раунде время. Также добавим переменную mainGameLogic, которая будет определять логику игры, т.к. что сейчас у нас на экране, игровой процесс, заставка или ещё что-то иное:

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

Класс Alien теперь умеет работать с несколькими подтипами:

Сам метод поведения Alien тоже изменился:

Начальная инициализация объектов теперь начинается с группировки корабля игрока, а логика игры – заставка:

Заметьте, теперь информация о будущем объекте после группировки передаётся прямо в конструктор GroupingParts.

Основной код метода 1/25 секунды тоже поменялся, и чтобы уже определиться, переименовал его в mainStrob():

тут дальше следует череда разного рода действий заставки возникающих как только время раунда достигает нового значения 2000 мс, 3000 мс и т.д., тут то группируется корабль игрока, потом группируется инопланетянин, через 4 сек это стреляет в того ракетой, через 4.4 сек наш стреляет бластером в этого и т.д.

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

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

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

А в стробе просто делаю так:

“300” – это та самая граница в которую корабль упирается слева или справа.

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

Задание по уроку:

1. Сделайте другие подюниты класса Alien

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

3. Добавьте на отображением суммы бонусов отображение времени раунда.

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

Урок 18 Урок 20

Java Android. Урок 20 (“Делаем игру Salvador”)

На этом уроке цель будет сделать как-то так:

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

Отображение ландшафта на сканере я делаю так:

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

Задание по уроку:

1. Аналогично отображению рельефа, сделайте отображение на сканере игрока и всех инопланетян

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

3. Добавьте на отображением суммы бонусов отображение времени раунда.

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

Урок 19 Урок 21

«Кроссворд» (Жанр: Комедия)

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

– Ты забыла принести мне кроксворд,- демонстративно искривив названия слова «кроссворд», сказал Валентин.
– Ну да, забыла. Попробуй всё упомни,- ответила она, немного подняв взгляд кверху.
– За это тебе штраф пятьсот рублей! – пошутил он.
– Ага, сейчас только отксерю.
– Если бы ты умела ксерить, то сейчас работала бы в офисе с солидной зарплатой, а то всё на меня взвалила.
– Ты думаешь в офисе работники только ксерят? Там наверно ещё чего-нибудь делать нужно.
– Нет, в офисе даже должность такая есть, ксерун называется, а если это девушка, то ксерунья или ксерульщица, в зависимости от квалификации.
– Да нет, я была у нас в завод управлении в офисе, нет там должностей таких.
– Откуда тебе известно, что нет; ты же туда только за зарплатой ходишь. Надо было тебе не заклёпщицей идти, хоть бы на новые обои денег насобирали.
– Валентин, ну хватит, на вот лучше принесла кроссворд тебе, поодгадывай, свежий; и ещё вот котлеты поешь.
– Что свежий, кроссворд или котлеты, не понял.
– И то и другое.- Немного улыбнувшись произнесла она.
– Ну ладно, давай посмотрим что тут.- Он сдвинул старые очки на нос и стал вчитываться.
– Гуля, вот смотри, пять по горизонтали – наука по разведению собак, слово из девяти букв, что это?
– Ой, слушай, на языке вертится. А, может это слово «собачатье», собак же разводят?
– Ну-ка, сейчас проверим. Ага, подходит!
– Так, а три по вертикали – мужчина, намеревающийся жениться, пять букв, кто это?
– Ну, Валентин, откуда мне знать. Вон, у нашей соседки сын женился, так она ему с первого дня рога ставит. Так кто он? Рогач, получается.
– Так-так, погоди. А что, подходит. Вот, Гуля, тебе нужно было кроссворд отгадывать, а не мне!
– Давай ещё, семь по горизонтали – человек, управляющий транспортным средством, восемь букв, а?
– Ну, сложные вопросы пошли. Леха – брат Светы, ну кудрявый такой, на троллейбусе работает, так кто он?
– Ну, Гуля, кто он, его все кудрявым так и зовут; дай-ка проверю. Слушай, а подходит, да, «кудрявый»!
– Ну вот и пиши! Сейчас мы с тобой всё отгадаем!
Гуля улыбаясь заинтересованно села рядом с Валентином и стала тоже читать вопросы. Её охватил задор, и она стала уже предвкушать вид полностью отгаданного кроссворда.
– А вот, смотри, что такое слово двенадцать по вертикали, пять букв? Сейчас точно отгадаем!
– Это, это, сейчас посмотрим…Так,- Квантовая частица, из которой состоит конденсат Бозе-Эйнштейна.
Валентин медленно стал надувать щеки, похлопал авторучкой себе по подбородку несколько раз, перевёл взгляд на Гулю, которая уже наверно в шестой раз пыталась прочитать правильно вопрос и понять в нём хотя бы одно слово, ещё раз взглянул на кроссворд. Он ждал когда нужная мысль его посетит, но она никак не посещала его. Он медленно нашпиговал на вилку часть котлеты, машинально поместил её в рот, не отрывая взгляда от вопроса, поднёс было ручку к газете чтобы что-то написать. В этот момент Гуля уже в надежде, что он знает ответ немного улыбнулась и даже открыла рот, но Валентин отвел руку и снова задумался, одновременно с этим Гуля рот обратно закрыла и опять стала серьезно вчитываться в вопрос. Её длинный и слегка задранный нос ходил вслед за её взглядом то вправо, то влево, и лишь иногда маячил вверх-вниз, когда она вчитывалась в очередное слово.
– Хрень какая-то! – Наконец прервав тишину вспылил Валентин.- Гуля, вот какого чёрта ты мне такие кроссворды на ночь глядя даёшь, да ещё за едой, а?!
– Ну, Валя, ну что ты так разошёлся? Да выбрось ты этот кроссворд! Давай другое что-нибудь посмотрим! А гляди, «хрень» подходит для ответа!
– Да мне просто интересно, какого лешего ты мне решила перед сном настроение испортить?! Что подходит? Ты видишь вторая буква «у» от слова «кудрявый», а в хрени вторая буква «р»!
– Ну, Валя, ну ошиблись они значит. Знаешь бездари какие кроссворды составляют? ЕГЭ сдаст и думает уже профессор, и идёт в журнал работать. А ошибок поналепит, что потом у людей настроение пропадает. Выбрось ты этот кроссворд в мусорку! Знала бы, не дала тебе его отгадывать. Давай вон лучше телик посмотрим, там говорят Илон Маск свою бандуру опять поставил, запускать будет, людей там тьма собралось…
– Да на кой ляд мне смотреть на бандуру Маска, лучше котлет ещё принеси, надо срочно едой стресс снять…

El Vinto, 2023