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

Уроки

Perry Como и Present Perfect Веселого Рождества

05.01.2021 14:11:03 | Автор: admin

Дорогие друзья! Merry Christmas, Счастливого Рождества, и с наступившим-таки Новым Годом!

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

Во многих музыкальных рождественско-новогодних плейлистах есть очень нежная и вдумчивая песня I Know What God Is в исполнении американского певца итальянского происхождения Perry Como. Один из лучших голосов прошлого столетия, попеременно делившего первенство с Фрэнком Синатрой. Уникальный проникновенный баритон и особая манера исполнения сделали Перри Комо любимцем нации.

Песня I Know What God Is была написана и исполнена в послевоенные годы и этот факт особенно подчеркивает смысл текста.

Но, как вы знаете, училка это диагноз. И слушая ее недавно, я поймала себя на мысли, что она является прекрасной иллюстрацией к случаям употребления Present Perfect.

Эта временнАя форма представляет, пожалуй, наибольшую сложность для изучающих английский. Зачем оно, чем англичан не устраивало старое доброе Past Simple? Да еще и преподаватели стращают этим have/has + V3

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

I have written an essay. Я написаЛА сочинение.

He has finished his work. Он закончиЛ работу.

Но в английском языке Present Perfect входит в группу настоящих времен.

???

Чтобы в этом непотребстве разобраться, давайте просто услышим то, что говорит нам эта временнАя форма своим названием:

Present. Настоящее.

Perfect. Совершённое. (По большом счету, совершЕнное и совершЁнное в русском языке одно и то же).

То есть это время нам говорит о чем-то, что было совершено. Perfect.

И имеет какое-то отношение к настоящему. Present.

Не очень пока понятно?

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

Понятно, что это третья форма глагола.

Но, оказывается, далеко не все знают, что это вообще такое.

1 форма это настоящее время. I write Я пишу.

2 форма прошедшее. I wrote Я написала.

А 3я?

А это то, что называется (вспоминаем школьный курс русского) страдательным причастием прошедшего времени.

То есть written написанный, done сделанный, eaten съеденный, learned - выученный finished законченный.

Да, и еще вспомним, что have это глагол 1 формы, то есть настоящего времени.

А теперь переводим:

I have written an essay. Я имею (вот оно, настоящее!) написанным (вот оно, совершенное!) сочинение.

He has finished his work. Он имеет (вот оно, настоящее!) законченной (вот оно, совершенное!) работу.

Логично?

Ну, а теперь еще один важный момент. Когда же это самое Present Perfect употреблять.

И тут можно прочитать километры пояснений типа Действие совершено в прошлом, но имеет отношение к настоящему блаблабла

Но как-то эти объяснения не особо помогают, правда?

Тогда я поделюсь с вами одним лайфхаком.

Present Perfect употребляется тогда, когда эту мысль можно продолжить либо самостоятельно при помощи вводного слова следовательно, либо при помощи вопроса собеседника И чё?:

I have written an essay, (Следовательно/И чё?) могу его сдать и получить зачет.

He has finished his work, (Следовательно/И чё?) он может пойти домой.

И вот это-то свойство Present Perfect прекрасно иллюстрирует эта песня. Там в каждой строчке Перри Комо делает эти выводы при помощи следовательно.

Давайте посмотрим:

I have heard the wild bird's sing. / имею услышанным

So I know what freedom is.

Я слышал пение дикой птицы.

(Следовательно)

Поэтому я знаю, что такое свобода.

I have looked into the eyes of a child. / имею увиденным

So I know what faith is.

Я смотрел в глаза ребенка.

(Следовательно)

Так что я знаю, что такое вера.

I have seen a rainbow. / имею увиденным

So I know what beauty is.

Я видел радугу.

(Следовательно)

Поэтому я знаю, что такое красота.

I have planted a tree. / имею посаженным

So I know what hope is.

Я посадил дерево.

(Следовательно)

Так что я знаю, что такое надежда.

I have held a helping hand. /имею удержанной

So I know what kindness is.

Я держал руку помощи.

(Следовательно)

Поэтому я знаю, что такое доброта.

I have seen a blossom burst into bloom. / имею увиденным

So I know what glory is.

Я видел, как распускается цветок.

(Следовательно)

Так что я знаю, что такое великолепие.

I have lost a friend. / имею потерянным

So I know what sorrow is.

Я терял друга.

(Следовательно)

Так что я знаю, что такое печаль.

I have knelt down in prayer. / имею коленопреклоненным

So I know what peace is.

Я преклонял колени в молитве.

(Следовательно)

Так что я знаю, что такое мир.

I have seen a mother at her crib. / имею увиденным

So I'm sure of the meaning of love.

Я видел мать у колыбели.

(Следовательно)

Поэтому я уверен в смысле любви.

I have seen and I have felt these things. / имею увиденным и почувствованным

And now I know what God is!

Я видел и чувствовал все это.

(Следовательно)

И теперь я знаю, что такое Бог!

А в заключение я предлагаю вам насладиться этой замечательной песней. Веселого Рождества!

https://www.youtube.com/watch?v=834Sc1WNqpI

P.S. I have carefully read this article. Я внимательно прочитал эту статью ( = имею прочитанной). (Следовательно/И чё?) So now I know everything about Present Perfect. Следовательно, я знаю всё о Present Perfect.

_____________________________

Оксана Сударева

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

Более 30 лет в профессии.

А еще у меня два кота:-)

P.S. Уважаемые читатели, если у вас есть вопросы по тексту или любые другие касаемо изучения английского, котов, жизни и проч. - пожалуйста, пишите в личку, комментарии могу пропустить!

Подробнее..

Демонстративно вертим массивы для новичков

19.01.2021 22:21:19 | Автор: admin

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

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

Что такое массив?

Массив - это структура однотипных данных, расположенная в памяти одним неразрывным блоком.

Расположение одномерного массива в памятиРасположение одномерного массива в памяти

Многомерные массивы хранятся точно также.

Расположение двухмерного массива в памятиРасположение двухмерного массива в памяти

Знание этого позволяет нам по-другому обращаться к элементам массива. Например, у нас есть двухмерный массив из 9 элементов 3х3. Так что есть, как минимум два способа вывести его правильно:

1-й вариант (Самый простой):

int arr[3][3] {1, 2, 3, 4, 5, 6, 7, 8, 9};int y = 3, x = 3;for (int i = 0; i < y, ++i) {for (int j = 0; j < x; ++j) {  std::cout << arr[i][j];  }  std::cout << std::endl;}

2-й вариант (Посложнее):

int arr [9] {1,2,3,4,5,6,7,8,9};int x = 3, y = 3;for (int i = 0; i < y; ++i) {  for (int j = 0; j < x; ++j) {std::cout << arr[x * i + j]; // x - ширина массива    }  std::cout << std::endl;}

Формула для обращения к элементу 2-размерного массива, где width - ширина массива, col - нужный нам столбец, а row - нужная нам строчка:

arr[width * col + row]

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

А вот так можно работать с трехмерным массивом
int arr[8] {1,2,3,4,5,6,7,8};int x = 2, y = 2, z = 2;for (int i = 0; i < x; ++i) {for (int j = 0; j < y; ++j) {  for (int k = 0; k < z; ++z) {    std::cout << arr[x * y * i + y * j + k];    }    std::cout << std::endl;  }  std::cout << std::endl;} 

Этим способом можно обходить трехмерные объекты, например.

Формула доступа к элементам в трехмерном массиве, где height - высота массива, width - ширина массива, depth - глубина элемента(наше новое пространство), col - столбец элемента, а row - строка элемента:

arr[height * width * depth + width * col + row]

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

Алгоритмы обработки массивов

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

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

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

1) Зеркальное отражение.

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

int data[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};int newArray[3][4];int height = 3, width = 4;for (int i = 0; i < height; ++i) {for (int j = 0; j < width; ++j) {  newArray[i][j] = data[i][width - j - 1];  }}

По такому же принципу выполняется переворот изображения по вертикали.

int data[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};int newArray[3][4];int height = 3, width = 4;for (int i = 0; i < height; ++i) {for (int j = 0; j < width; ++j) {  newArray[i][j] = data[height - i - 1][j];  }}

2) Поворот изображения на 90 градусов.

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

Пошаговое выполнение алгоритмаПошаговое выполнение алгоритма

Такой алгоритм появился, когда я нарисовал график координат c точками.

График, приведший к решениюГрафик, приведший к решению
int data[3][2] = {1,2,3,4,5,6};int newArray[2][3];int height = 3, width = 2; // Размеры массива (изображения)int newHeight = width, newWidth = height;// Транспонируем матрицуfor (int i = 0; i < newHeight; ++i) {for (int j = 0; j < newWidth; ++j) {  newArray[i][j] = data[j][i];// data - массив изображения  }}// Зеркально отражаем по горизонтали матрицуfor (int i = 0; i < newHeight; ++i) {for (int j = 0; j < newWidth/2; ++j) {  int temp = newArray[i][j];    newArray[i][j] = newArray[i][newWidth - j - 1];    newArray[i][newWidth - j - 1] = temp;  }}

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

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

Заключение

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

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

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

Подробнее..

Моделирование дома в SketchUp и перенос его в Unity 3D

24.01.2021 00:17:21 | Автор: admin

Учебные материалы для школы программирования. Часть7

Spoiler

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

Сегодня, мы создадим здание и перенесем его в Unity. Хочу обратить ваше внимание на то, что для импорта готового здания, необходимо, чтобы SketchUp стоял на том же ПК. Без программы Unity не сможет импортировать модель.

Порядок выполнения

Откроем SketchUp и выберем шаблон Simple Template - Meters.

Выберем инструмент фигуры и нарисуем на земле квадрат по форме дома.

Теперь, выдавим его с помощью инструмента выдавить/вдавить (push/pull).

Сделаем стены. Для этого используем инструмент Сдвиг (Offset).

Повторим операцию ещё раз.

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

Лишние линии убираются инструментом Ластик (Erase).

Выдвигаем стены.

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

Нарисуем на стене квадрат и выделим его.

Нажимая Ctrl+C и Ctrl+V, копируем его по стене, привязывая к линии.

После копирования окон лишнии линии стираем.

С помощью инструмента Вдавить/выдавить вдавливаем окно до состояния "На грани" (On Face).

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

Вырежем дверь похожим образом.

Используем инструмент "Ведёрко" (Paint Bucket) для наложения текстур. Выберем подходящую текстуру и зальём пол с фундаментом.

Аналогично поступим со стенами.

Чтобы наложить текстуру на замкнутый контур, нажмём Shift, чтобы наложить на все плоскости, имеющие такую же текстуру Ctrl.

Текстура на стену легла не идеально. Перейдём в свиток Текстура-Позиция, и перетягивая красный ползунок мы изменим позицию текстуры, а зелёным её размер.

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

И красим инструментом "Ведёрко" остальные стены.

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

На одном из торцов дома создадим плоскость для крыши.

Попрошу заметить, что мы вышли из группы кликом по пустому месту на экране. Если плоскость маленькая, её можно увеличить инструментом "Растянуть" (Scale).

Рисуем на плоскости очертания крыши. Лишние линии можно стереть.

Инструметом Выдавить/вдавить придаём объем.

Используем "Сдвиг" на крыше, чтобы добавить объёма.

И вдавим плоскость немного внутрь.

Окрасим всё подходящими текстурами и удалим человека. Домик готов для импорта в Unity!

В настройках импорта в Unity надо выставить галочку Generate Colliders, а во вкладке Material Use External Materials.

При этом, импортируются все материалы и создадутся папки.

Теперь, у вас есть своя собственная модель дома, для использования в играх!

Подробнее..

Гравитационная комната в Unity 3D

16.01.2021 12:10:38 | Автор: admin

Учебные материалы для школы программирования. Часть4

Spoiler

Предыдущие уроки можно найти здесь:

  1. Spaceship

  2. Домино

  3. Flappy Bird

В первых публикациях я немного рассказывала про школу программирования, в рамках которой создавались проекты по Unity 3D. Знакомясь с нашими наработками, у многих возникали вопросы, которые нельзя оставить без внимания:

- Почему вы выбрали такую сложную программу? У детей нет в школах информатики, а значит, нет базовых знаний для освоения Unity.

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

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

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

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

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

- Почему такая простая графика?

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

Перейдем от вопросов к делу!

Гравитационная комната

На уроке учимся:

- Работать с вертекснои привязкои при перемещении объектов (см. функцию клавиши V в Unity);

- Работать с привязкои к мировому пространству через Configurable Joint;

- Знакомим с акселерометром и гравитацией в разрезе игровых движков;

- Повторяем работы с rigidbody и коллаидерами.

Порядок выполнения

Создается новыи проект, импортируется приложенныи ассет, создается новая сцена. На сцене создается куб размером примерно 7х7х7, затем его размер, с помощью инструмента scale, меняют примерно до 7х0.3х7.

Данную фигуру размножают, поворачивают на 90 градусов и привязывают по углам с зажатои клавишеи V так, чтобы получился закрытыи куб. У стенки, которая находится с положительнои стороны оси Z, выключаем компонент MeshRenderer, в итоге, одна из стенок становится прозрачнои. Переименовываем ее в "Комната" и закидываем остальные стены, пол и потолок. Затем, размер всеи комнаты можно менять с помощью scale.

Из сферы и цилиндров создаем подобие лампочки, на сферу накладываем материал со стандартным шеидером и эмиссиеи. Внутри сферы создаем point light, а стандартныи directional light со сцены удаляем. Чтобы задать нашеи лампочке ось вращения, создаем пустои объект на самои верхушке провода лампочки, называем его "ось лампочки", закидываем в него все объекты, относящиеся к лампочке.

На ось накладываем Configurable joint, при этом, автоматически добавится rigidbody. Необходимо зафиксировать положение оси в мире, установив transform X, Y и Z в положение Locked.

Устанавливаем камеру так, чтобы она нормально покрывала всю комнату, при этом в Transform камеры будет установлен угол 180 градусов по Y.

Также, на сцену добавляются объекты, к которым применяется MeshCollider -> Convex и Rigidbody с массои в районе 4-5 кг.

Пишем скрипт, которыи в Update() содержит всего одну строку:

и закидываем в любои объект на сцене, допустим, в камеру. Для того, чтобы игра работала на слабых устроиствах, закидываем скрипт Resolution туда же. Этот скрипт принудительно занижает разрешение рендера до 800х450 на устроиствах с экранами большего размера.

Далее, компилируем на Android уже известным нам, из предыдущего урока, способом. Проверяем. Если все выполнено верно, лампочка будет отклоняться вниз по отношению к устроиству в любом положении, пока еи не мешает потолок, а все объекты падают в ту сторону, в которую наклонен телефон.

Подробнее..

Деревья (плагин SpeedTree) на Unity 3D

24.01.2021 00:17:21 | Автор: admin

Учебные материалы для школы программирования. Часть6

Spoiler

Предыдущие уроки можно найти здесь:

  1. Spaceship

  2. Домино

  3. Flappy Bird

  4. Гравитационная комната

  5. Платформер

В Unity, в asset store, можно найти множество готовых объектов для будущей игры, но иногда, хочется сделать что-то своими руками. Для зданий, и других простых архитектурных объектов, мы часто использовали SketchUp, для "живых" анимированных объектов - Blender. На этом уроке, мы сами "вырастим" дерево в Unity!

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

  • Tinkercad - составление фигур из геометрических форм;

  • SketchUp - для более детально проработанных архитектурных объектов;

  • ZBrush - можно создавать сложные, крутые модели, а можно ограничиться "лепкой" колобка, что тоже очень занятно!

Но вернемся к теме занятия, и рассмотрим, как создать дерево с помощью плагина SpeedTree, включенного в дистрибутив Unity.

Порядок выполнения

Создадим новыи проект, в нем создадим терреин.

Добавим на него объект 3D Object Tree

Добавим дереву ветки, создав блок веток. Увеличим их количество примерно до 20 (интересующие параметры выделены синим). В каждом блоке изменяем параметр Frequency (цветом на скриншоте не выделен).

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

Далее, добавим к этим ветвям еще несколько веток.

Не забудем про листву.

Следующий шаг - выставление материалов.

Для деревьев важно выставлять материалы с помощью шеидера Nature. Импортируем стандартныи ассет Environment, он содержит готовые материалы. Материалы коры нужно назначить всем веткам. Если материал не подходит, Unity предложит использовать корректныи материал.

Жмем Apply и "переконвертирования" материала. Будьте осторожны, Unity часто вылетает на этом этапе.

Итак, дерево готово! Его можно разместить на терреине благодаря Mass Place Trees.

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

Подробнее..

Игровые механики на уроке геометрии или векторы на Unity 3D

20.04.2021 16:13:49 | Автор: admin

Учебные материалы для школы программирования. Часть16

Предыдущие уроки можно найти здесь:

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

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

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

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

Порядок выполнения

На примере создания 2D игры баскетбол, рассмотрим векторы (скорости, сил, локальнои и глобальнои систем координат). Разберем принципы представления систем координат и представления векторов. Также будет затронута работа с LineRenderer и многокамерность.

Поехали!

Создадим новыи проект и импортируем в него приложенныи ассет.
Ассет содержит в себе все ресурсы, необходимые для создания полноценного 2D приложения.

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

Конечно, необходимо выставить правильныи Order in layer у спраитов. Добавим мяч, применим к нему Circle collider и Rigidbody.

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

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

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Ball : MonoBehaviour {    public AudioSource hitSound;    public Rigidbody2D rig;    // Use this for initialization    void Start () {    }    // Update is called once per frame    void FixedUpdate() {    }    private void OnCollisionEnter2D(Collision2D other) {        if (other.relativeVelocity.magnitude > 1f) {            hitSound.Play();            hitSound.volume = Mathf.Clamp01(other.relativeVelocity.magnitude / 10);            rig.velocity *= 0.8f;        }    }}

В скрипте нет автопоиска Rigidbody, так что придется закинуть его руками. Если нажать на Play, наш мяч упадет, издавая звуки. Чтобы мяч отскакивал, создадим физическии материал и закинем его на коллаидер мяча.

Теперь подумаем о том, чтобы мяч показывал свое направление. Для этого создадим скрипт, которыи рисует стрелки: нам понадобятся два пустых объекта с LineRenderer, один в другом.

Создадим материал для стрелки:

И добавим скрипт, которыи будет выставлять вершины LineRenderer'ов, делая из них стрелки:

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Arrow : MonoBehaviour {   public Vector3 showVector;    public LineRenderer lrenderer1;    public LineRenderer lrenderer2;    Transform myTransform;    // Use this for initialization    void Start () {        //lrenderer1 = GetComponent<LineRenderer>();        myTransform = transform;    }   // Update is called once per frame    void Update () {        showVector = new Vector3(showVector.x, showVector.y, 0f);        lrenderer1.SetPosition(0, myTransform.position);        lrenderer1.SetPosition(1, myTransform.position + showVector);          if (showVector.magnitude >= 2f) { // длинная стрелка            lrenderer2.SetPosition(0, myTransform.position + showVector - showVector.normalized);        } else {            lrenderer2.SetPosition(0, myTransform.position + showVector * 0.5f);        }        lrenderer2.SetPosition(1, myTransform.position + showVector);        if (showVector.magnitude < 0.1f) {            lrenderer1.enabled = lrenderer2.enabled = false;        } else {            lrenderer1.enabled = lrenderer2.enabled = true;        }    }}

Закинем скрипт на объект-родитель стрелки и настроим его.

Теперь надо написать скрипт, которыи будет вектор скорости передавать в наш скрипт "показывания" стрелки. Он очень простои:

using System.Collections;using System.Collections.Generic;using UnityEngine;public class VectorVelocity : MonoBehaviour {    public Rigidbody2D rig;    public Arrow arrow;    // Use this for initialization    void Start () {     }    // Update is called once per frame    void Update () {        if (rig.bodyType == RigidbodyType2D.Dynamic) {            arrow.showVector =  rig.velocity / 5f;        }    }}

Закинем его на мяч, в скрипте укажем риджибади мяча и объект со скриптом стрелки.

Теперь вектор скорости показывается верно. Вектор скорости уменьшен в 15 раз, чтобы его было хорошо видно. А для того, чтобы было видно траекторию мяча - добавим ему Trail Renderer на любои привязанныи к мячу объект.

Теперь сделаем так, чтобы мяч можно было кидать. Для этого необходимо выставить ему тип Rigidbody как Kinematic и написать небольшои скрипт.

Листинг скрипта:

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.EventSystems;public class Spawner : MonoBehaviour {    public Rigidbody2D ball;    public TrailRenderer tr;    Quaternion oldRotation;    Vector3 oldPosition;    public bool readyToShoot = true;    // Use this for initialization    void Start () {        oldPosition = ball.transform.position;        oldRotation = ball.transform.rotation;    }    // Update is called once per frame    public void Respawn () {        ball.transform.position = oldPosition;        ball.transform.rotation = oldRotation;        ball.velocity = Vector3.zero;        ball.angularVelocity = 0;        ball.bodyType = RigidbodyType2D.Kinematic;        readyToShoot = true;        tr.Clear();    }    public void Shoot(Vector3 speed) {        if (!readyToShoot) {            return;        }        ball.bodyType = RigidbodyType2D.Dynamic;        ball.velocity = speed;        readyToShoot = false;    }}

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

Этот скрипт сам по себе ничего не делает. Чтобы он работал, необходимо организовать ввод. Создадим UI -> Panel на сцене, выставим панели нулевую альфу и установим на него скрипт TouchPanel.cs , приложенныи в проект.

Внутри панели должен лежать спраит со следующими параметрами (обратите внимание на привязку):

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

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

Готово!

P.S. Делитесь ссылкой на статью с коллегами, друзьями и любопытными учениками. Будет здорово, если вы попробуете провести один из уроков в своей школе или в кружке детского технического творчества, и напишите пару слов обратной связи о том, как прошел урок по Unity 3D. Успехов!

Подробнее..

Тир. Стрельба рейкастами на Unity 3D

06.05.2021 18:22:32 | Автор: admin

Учебные материалы для школы программирования. Часть17

Предыдущие уроки можно найти здесь:

В этом проекте рассмотрим процесс работы:

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

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

Порядок выполнения

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

Проект урока разбит на 2 части - тир и гранаты.

Тир

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

Внутри проекта есть скрипт DecalShooter, который создаёт декали, и в котором расположен весь код стрельбы, включая рейкаст. В нём будет вводиться код взаимодействия с мишенью.
Для начала, необходимо подготовить саму мишень. Ею служит цилиндр, который необходимо уменьшить по Y до состоянии платины, удалить CapsuleCollider и поставить MeshCollider с галочкой Convex. Дополнительно, на цилиндр устанавливается текстура мишени, внутри цилиндра создаётся point light, подсвечивающий мишень, и объект с AudioSource для воспроизведения звука, а на сам цилиндр устанавливается Rigidbody с обработкой коллизий типа Continius Dynamic и галочкой isKinematik. У AudioSource не забудьте убрать галочку PlayOnAwake и закинуть звук попадания в мишень.

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

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

using System.Collections;using System.Collections.Generic;using UnityEngine; public class Target : MonoBehaviour {    public GameObject light;    public Rigidbody rig;    public AudioSource src;     bool enabled = true;     // Use this for initialization     void Start() {        rig = GetComponent<Rigidbody>();        src = GetComponent<AudioSource>();     }     // Update is called once per frame     void Update() {     }     public void shoot() {        if (!enabled) {           return;        }         rig.isKinematic = false;         light.SetActive(false);         src.Play();         enabled = false;    } }

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

   if (Input.GetKeyDown(KeyCode.Mouse0)) {            time = 0.3f;             ShootSource.Play();             anim.Play("fire");             Muzzleflash.SetActive(true);            // Сама стрельба             RaycastHit hitInfo;            Vector3 fwd = transform.TransformDirection(Vector3.forward);                         if (Physics.Raycast(transform.position, fwd, out hitInfo, 100f)) {                GameObject go = Instantiate(                    DecalPrefab,                    hitInfo.point,                     Quaternion.LookRotation(                        Vector3.Slerp(-hitInfo.normal, fwd, normalization)                     )                ) as GameObject;                go.GetComponent<DecalUpdater>().UpdateDecalTo(                    hitInfo.collider.gameObject,                     true                );                Vector3 explosionPos = hitInfo.point;                Target trg = hitInfo.collider.GetComponent<Target>();                                if (trg) {                    trg.shoot();                }                                Rigidbody rb = hitInfo.collider.GetComponent<Rigidbody>();                                if (rb != null) {                    rb.AddForceAtPosition(fwd * power, hitInfo.point, ForceMode.Impulse);                    Debug.Log("rb!");                }             }            // Сама стрельба         }

Данный код пытается получить компонент из объекта hitInfo и, если это удаётся, вызывает методshoot. Мишень падает, свет от мишени выключается, звук попадания воспроизводится. Далее, желательно дать группе свободное задание по кастомизации своего проекта. Как альтернативу, можно предложить изменить код таким образом, чтобы мишень меняла цвет при попадании. Делается это заменой в Target строк:

light.SetActive(false);

на

light.GetComponent<Light>().color = Color.red;

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

Гранаты

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

Для начала, создадим другой скрипт - дальномер.

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI; public class Lenght :  MonoBehaviour {    public Text Dalnost;    float rasstoyanie = 0; // переменная для расстояния до цели     // Use this for initialization     void Start() {     }     // Update is called once per frame     void Update() {        RaycastHit hitInfo;                if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hitInfo, 200)) {            rasstoyanie = hitInfo.distance;            Dalnost.text = rasstoyanie.ToString();        }    }}

Скрипт закинем в FPScontroller/FirstPersonCharacter. В Canvas создадим текст, закинем его в скрипт.
В этом скрипте реализован простейший рейкаст, и на его примере мы разбираем, как рейкаст передаёт информацию в структуру и как нам получать из структуры эту информацию.
При срабатывании рейкаста мы выводим дальность на экран.

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

using System.Collections;using System.Collections.Generic; using UnityEngine;using UnityEngine.UI; public class Length :  MonoBehaviour {    public Text Dalnost;    float rasstoyanie = 0; // переменная для расстояния до цели     public GameObject sharik;     // Use this for initialization    void Start() {     }     // Update is called once per frame     void Update() {        RaycastHit hitInfo;                 if(Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), outhitInfo, 200)) {            rasstoyanie = hitInfo.distance;             Dalnost.text = rasstoyanie.ToString ();            if(Input.GetKeyDown(KeyCode.Mouse1)) {                GameObject go = Instantiate(                    sharik,                     transform.position + Vector3.Normalize(hitInfo.point - transform.position),                     transform.rotation                );                Rigidbody rig = go.GetComponent<Rigidbody>();                rig.velocity = Vector3.Normalize(hitInfo.point - transform.position) * 10;            }         }    } }

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

using System.Collections;using System.Collections.Generic;using UnityEngine; public class Grenade :  MonoBehaviour {    public Transform explosionPrefab;     void OnCollisionEnter(Collision collision) {        ContactPoint contact = collision.contacts[0];                // Rotate the object so that the y-axis faces along the normal of the surface        Quaternion rot = Quaternion.FromToRotation(Vector3.up, contact.normal);        Vector3 pos = contact.point;         Instantiate(explosionPrefab, pos, rot);        Destroy(gameObject);    }}

Закидываем на сцену гранату, на меш Body ставим коллайдеру Convex, добавляем гранате RIgidbody и наш скрипт. Получившуюся гранату добавляем в префаб и удаляем со сцены.

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

Создадим эффект взрыва. В нём должен быть свет от взрыва, AudioSource с галочкой PlayOnAwake и звуком взрыва, Spital Blend на 90 процентов переведённый в 3д и увеличенный радиус распространения звука.
Для правильной отработки всех эффектов и разлёта Rigidbody нужно создать ещё один скрипт. Его мы назовём Explosion:

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Explosion :  MonoBehaviour {    public float radius = 5.0f;    public float power = 10.0f;    public GameObject svet;    void Start() {        Destroy(svet, 0.1f);        Vector3 explosionPos = transform.position;        Collider[] colliders = Physics.OverlapSphere(explosionPos, radius);        foreach(Collider hit in colliders) {            Rigidbodyrb = hit.GetComponent<Rigidbody>();            if (rb != null) {                rb.AddExplosionForce(power, explosionPos, radius, 3.0f);            }        }    }}

Его нужно закинуть на эффект взрыва и создать префаб.
Данный префаб и используется в скрипте гранаты для создания взрыва.

Готово!

Подробнее..

История Airbnb Какие уроки можно из нее извлечь?

22.07.2020 12:20:51 | Автор: admin

Дураки учатся на своих ошибках, а умные на чужих. Теодор Рузвельт 25-й вице-президент США, 26-й президент США

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

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

Cпойлер
Если вы никогда не пользовались платформой Airbnb это площадка для поиска краткосрочной аренды жилья по всему миру.


Урок 1. Сделайте минимальный рабочий продукт (MVP) и получите первые оплаты как подтверждение своей идеи


В 2007 году Джо Геббиа и Брайан Чески решили поделиться свободным пространством в своей съемной квартире, чтобы оплатить аренду, сдавая 3 матраса и готовя завтрак. В этот момент в Сан-Франциско проходила крупная конференция и отели были переполнены.

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

Брайан и Джо не стали размещать свое объявление на Craigslist(интернет-площадка для размещения объявлений), а вместо этого сделали простой сайт блог с картами, которому дали символичное название AirBed & Breakfast (надувной матрас и завтрак).

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

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

Далее в команду основателей попадает Нейтан Блечарзик, задачей которого было улучшить сайт. Трое создателей начинают делать сервис для поиска соседей по комнате, но в какой то момент обнаруживают, что такой сервис Roommates.com уже существует и тогда они возвращаются к первоначальной идее AirBed & Breakfast.

Я не думаю что создатели были знакомы с продуктовым подходом, во всяком случае не в начале своего пути (всё-таки Эрик Рис написал книгу Lean Startup только в 2011 году), скорее всего так сложилось постольку поскольку, однако они действовали правильно создали MVP и протестировали на реальных пользователях.

Урок 2. Не опускайте руки не получив результата, для начала пересмотрите условия эксперимента. Неудача это всего лишь обратная связь.


Переделав сайт, они запускаются снова, но их ждет неудача AirBed & Breakfast не замечают. Тогда создатели принимают решение запуститься ещё раз во время крупной конференции. Они пробуют снова во время конференция SXSW 2008, но получают всего два букинга, один из которых сам Чески.

Тем не менее основатели настолько уверены в своей идее, что к лету 2008 года они упрощают интерфейс сайта так, чтобы можно было оформить аренду в три клика, и начинают поиск инвесторов. Инвесторам идея AirBed & Breakfast не нравится и они получают 9 отказов, а 7 инвесторов их полностью игнорируют.

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

Урок 3. Придумывайте и используйте нестандартные маркетинговые ходы.


Чески, Геббиа и Блечарзик продолжают упорно тестировать гипотезу о том, что когда отели переполнены люди будут арендовать матрасы и поворотным моментом становится запуск во время съезда Демократической партии США проходящей в Денвере, штат Колорадо в августе 2008 года.

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

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

Тем не менее этого было недостаточно, чтобы найти арендаторов для всех комнат, и им приходит на ум необычная идея основатели были дизайнерами и они решили сделать хлопья Obama O's и Capn McCain's с рекламой AirBed & Breakfast. Хотя идея показалась нелепой(как они сами признавались мы не могли представить чтобы Марк Цукерберг на заре своей карьеры и сидел и клеил упаковки с хлопьями), однако они решили попробовать.

Вот как выглядели хлопья:




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

Один из инвесторов, который отказал AirBed & Breakfast, до сих пор хранит пачку хлопьев как напоминание того, что он не смог разглядеть потенциал этого стартапа.

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

Урок 4. Привлекайте умный капитал


В конце 2008 года они получают $20 000 от Пола Грэкхема из Ycombinator и первые три месяца 2009 года обучаются и совершенствуют свой продукт в акселераторе, нанимают первого программиста.

В марте 2009 года официально сокращают название до Airbnb и уходят от модели аренды матраса к аренде всей комнаты/квартиры целиком.

После его окончания акселерации Airbnb начинают расти, что говорит о том что менторство и финансирование усиливают хорошую идею.

Урок 5. Побывайте в шкуре своего клиента, чтобы найти узкие места и точки роста


В середине 2009 года компания уже зарабатывает $200 баксов в неделю, но растет очень медленно и тогда Гебиа и Чески начинают снимать комнаты, которые вставлены на Airbnb в Нью-Йорке, чтобы оценить качество предложений и чтобы взглянуть на сервис глазами покупателя.

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

Гебиа и Чески арендуют фотоаппарат за $5000 и посещают все объекты в Нью-Йорке чтобы сделать качественные фото и разместить их на сайте. Это приводит к тому что количество бронирований увеличивается в 2-3 раза, а выручка в Нью-Йорке удваивается и летом 2010 года Airbnb запускает программу, которая позволяет хозяевам нанимать профессионального фотографа за счет Airbnb в крупных городах.

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

Урок 6. Спам не стыдно. Спам это маркетинговый хак (Growth Hacking)


В конце 2009 года Airbnb отчаянно нуждался во входящем трафике и Craigslist был одним из мест где можно было найти людей которые не хотели останавливаться в отеле, а искали что-то более интересное.

Airbnb не афишируют что они занимались спамом, но один из пользователей Дэйв Гуден, обнаружив странный рост количества пользователей Airbnb провел эксперимент: он разместил объявление на Craigslist и получил email от женщины, которая написала, что ей очень нравится его квартира и предложила разместиться на Airbnb чтобы найти больше арендаторов, так как по её мнению это сайт с растущим трафиком.

Чтобы исключить то, что ему действительно написала одна из восхищенных пользователей Airbnb, Дейв, используя таргетинг на пользователей Craigslist, разослал несколько email c предложением разместить комнаты для аренды на своем сайте и пообещал, что сам разместит их на Сraigslist. Затем он разместил одну из комнат на Сraigslist и получил точно такое же письмо с предложением разместиться на Airbnb, затем он разместил ещё две комнаты и получил то же самое письмо, что подтвердило что Airbnb активно рос за счет Craigslist.

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

Урок 7. Собирайте трафик с других платформ предлагая пользователям большую ценность.


В начале 2010 года Airbnb сделали специального бота, который позволял хозяевам, размещая объявление на Airbnb, копировать и на Craigslist.

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

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

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

Урок 7. Отслеживайте инциденты и используйте их как пиар, а так же как возможность улучшить свою платформу


Летом 2011 года, вскоре после того как Airbnb привлекли очередной раунд инвестиций дом одного из пользователей Airbnb был разграблен.

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

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

Урок 8. Чтобы не конкурировать по цене давайте больше ценности


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

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

Заключение


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

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

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

Туториал по FASM (Windows x32 APIWin32API), Hello world!

29.05.2021 00:21:04 | Автор: admin

Коротко о FASM, ассемблере, WinAPI

  • Что такое FASM? - Это компилятор ассемблера (flat assembler).

  • Что такое ассемблер? - это машинные инструкции, то есть команды что делать процессору.

  • Что такое Windows API/WinAPI? - Это функции Windows, без них нельзя работать с Windows.

    Что дают WinAPI функции? - Очень много чего:

  • Работа с файлами.

  • Работа с окнами, отрисовка картинок, OpenGL, DirectX, GDI, и все в таком духе.

  • Взаимодействие с другими процессами.

  • Работа с портами.

  • Работа с консолью Windows

  • И еще очень много интересных функций.

Зачем нужен ассемблер?

На нем можно сделать все что угодно, от ОС до 3D игр.

Вот плюсы ассемблера:

  • Он очень быстрый.

  • На нем можно сделать любую программу.

А вот минусы ассемблера:

  • Долго делать программу. (относительно)

  • Сложен в освоении.

Что нужно для программирования на ассемблере (FASM)?

Установка компонентов (если можно так назвать)

Архив FASM-а распаковуем в C:\\FASM\ или любой другой, но потом не забудьте настроить FASMEditor.

Архив FASMEdit-a распаковуем куда-то, в моем случае C:\\FASM Editor 2.0\

Архив OlyDbg распаковуем тоже куда-то, в моем случае C:\\Users\****\Documents\FasmEditorProjects\

Настройка FASM Editor-a

Для этого его нужно запустить.

Сразу вас приветствует FASM Editor соей заставкой.

Теперь вам нужно зайти в вкладку "Сервис" (на картинке выделил синим) -> "Настройки..."

Жмем на кнопку с названием "..." и выбираем путь к файлам или папкам.

Теперь мы полностью готовы. К началу.

Пишем "Hello world!" на FASM

В Fasm Editor нужно нажать на кнопку слева сверху или "файл" -> "новый". Выбираем любое, но можно выбрать "Console"

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

format PE Console ; говорим компилятору FASM какой файл делатьentry start ; говорим windows-у где из этой каши стартовать программу.include 'win32a.inc' ; подключаем библиотеку FASM-а;можно и без нее но будет очень сложно.section '.data' data readable writeable ; секция данныхhello db 'hello world!',0 ; наша строка которую нужно вывестиsection '.code' code readable writeable executable ; секция кодаstart: ; метка стартаinvoke printf, hello ; вызываем функцию printf    invoke getch ; вызываем её для того чтоб программа не схлопнулась  ;то есть не закрылась сразу.    invoke ExitProcess, 0 ; говорим windows-у что у нас программа закончилась  ; то есть нужно программу закрыть (завершить)section '.idata' data import readable ; секция импорта        library kernel, 'kernel32.dll',\ ; тут немного сложней, объясню чуть позже                msvcrt, 'msvcrt.dll'    import kernel,\  ExitProcess, 'ExitProcess'            import msvcrt,\  printf, 'printf',\          getch, '_getch'

На самом деле из всей этой каши текста, команд всего 3: на 16, 18, 21 строках. (и то это не команды, а макросы. Мы к командам даже не подобрались)

Все остальное это просто подготовка программы к запуску.

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

Самое интересное то что программа весит 2КБ. (Можно сократить и до 1КБ, но для упрощения и так пойдет)

Разбор: что значат этот весь текст?

На 1 строчке: "format PE Console" - это строчка говорит FASM-у какой файл скомпилировать, точнее 1 слово, все остальные слова это аргументы (можно так сказать).

PE - EXE файл, программа.

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

Но есть кроме это остальные:

  • format MZ - EXE-файл НО под MS-DOS

  • format PE - EXE-файл под Windows, аналогично format PE GUI 4.0

  • format PE64 - EXE-файл под Windows, 64 битное приложение.

  • format PE GUI 4.0 - EXE-файл под Windows, графическое приложение.

  • format PE Console - EXE-файл под Windows, консольная программа. (просто подключается заранее консоль)

  • format PE Native - драйвер

  • format PE DLL - DLL-файл Windows, поясню позднее.

  • format COFF - OBJ-файл Linux

  • format MS COFF - аналогично предыдущему

  • format ELF - OBJ-файл для gcc (Linux)

  • format ELF64 - OBJ-файл для gcc (Linux), 64-bit

Сразу за командой (для компилятора) format PE Console идет ; это значит комментарий. К сожалению он есть только однострочный.

3 строка: entry start

  • Говорим windows-у где\в каком месте стартовать. "start" это метка, но о метках чуть позже.

5 строка: include 'win32a.inc'

  • Подключает к проекту файл, в данном случае "win32a.inc" он находиться в папке INCLUDE (в папке с FASM). этот файл создает константы и создает макросы для облегчения программирования.

8 строка: section '.data' data readable writeable

  • Секция данных, то есть программа делиться на секции (части), к этим секциям мы можем дать разрешение, имя.

Флаг "data" (Флаг это бит\байт\аргумент хранившей в себе какую-то информацию) говорит то что эта секция данных.

Флаги "readable writeable" говорят то что эта секция может читаться кем-то и записываться кем-то.

Текст '.data' - имя секции

10 строка: hello db 'hello world!',0

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

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

'hello world!' - наша строка в кодировке ASCII

Что значит ",0" в конце строки? - это символ с номером 0 (или просто ноль), у вас на клавиатуре нет клавиши которая имела символ с номером 0, по этому этот символ используют как показатель конца строки. То есть это значит конец строки. Просто ноль записываем в байт после строки.

12 строка: section '.code' code readable writeable executable

Флаг "code" - говорит то что это секция кода.

Флаг "executable" - говорит то что эта секция исполняема, то есть в этой секции может выполняться код.

Все остальное уже разобрали.

14 строка: start:

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

15 строка: invoke printf, hello

  • Функция printf - выводит текст\число в консоль. В данном случае текст по адресу "hello"

Это штото на подобие команды, но это и близко не команда ассемблера, а просто макрос.

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

Например, макро команда invoke делиться на такие команды: (взят в пример команда с 15 строки)

push hellocall [printf]

Не переживайте если нечего не поняли.

17 строка: invoke getch

  • getch - функция получения нажатой кнопки, то есть просто ждет нажатия кнопки и потом возвращает нажатую кнопку.

20 строка: invoke ExitProcess, 0

  • ExitProcess - WinAPI функция, она завершает программу. Она принимает значение, с которым завершиться, то есть код ошибки, ноль это нет ошибок.

23 строка: section '.idata' data import readable

Флаг "import" - говорит то что это секция импорта библиотек.

24-25 строки:

library kernel, 'kernel32.dll',\  msvcrt, 'msvcrt.dll'
  • Макро команда "library" загружает DLL библиотеки в виртуальную память (не в ОЗУ, вам ОЗУ не хватит чтоб хранить всю виртуальную память).

Что такое DLL объясню позже.

kernel - имя которое привязывается к библиотеке, оно может быть любым.

Следующий текст после запятой: 'kernel32.dll' - это имя DLL библиотеки который вы хотите подключить.

Дальше есть знак \ это значит что текст на следующей строке нужно подставить в эту строку.

То есть код:

library kernel, 'kernel32.dll',\  msvcrt, 'msvcrt.dll'

Заменяется на:

library kernel, 'kernel32.dll', msvcrt, 'msvcrt.dll'

Это нужно потому что у ассемблера 1 строка это 1 команда.

27-28 строка:

import kernel,\  ExitProcess, 'ExitProcess'

import - Макро команда, которая загружает функции из DLL.

kernel - Имя к которой привязана DLL, может быть любым.

ExitProcess - Как будет называться функция в программе, это имя будет только в вашей программе, и по этому имени вы будете вызывать функцию. (WinAPI функция)

'ExitProcess' - Это имя функции которое будет загружено из DLL, то есть это имя функции которое прописано в DLL.

Дальше думаю не стоит объяснять, вроде все понятно.

Что такое DLL библиотека?

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

Подводим итог

На ассемблере писать можно не зная самого языка, а используя всего лишь макро команды компилятора. За всю статью я упомянул всего 2 команды ассемблера это push hello и call [printf] . Что это значит расскажу в следующей статье.

Подробнее..
Категории: Assembler , Туториал , Уроки , Winapi , Fasm , Windowsapi

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru