По-моему мы зря отделяем изучение «языка программирования» от «умения программировать». Так же точно иностранные языки не учат отдельно от языковых конструкций. Взять к примеру правило ряда в английском языке. Правильно перевести эту конструкцию можно только зная про эту самую конструкцию, при этом знание самих слов английского языка является сугубо вспомогательной задачей.
Так же и с программированием — мне очень сложно представить как компетентные (я надеюсь) преподаватели будут объяснять назначение конструкций for или if без объяснения таких базовых понятий как алгоритм, цикл, ветвления. Изучение иностранных языков начинается с изучения алфавита. Конечно в этом плане программирование воспринимать легче, потому что зачастую база одна и та же, только в разных представлениях.
Все когда-либо изучаемые мной науки начиналсь с самых азов, постепенно усложняясь и так далее.
В общем мне кажется, что само выражение «изучать языки программирования» построенно немного не компетентно, видно какие желания стоят за этими словами.
А еще товарищ Обама записал крутое «рекрутинг» видео, и некоторое время назад (несколько дней назад, не больше недели) была открыта подписка на какие-то мини курсы введения в программирование. Ссылка на видео вот и там же в описании ссылка на проект «помоги другу научиться программировать»
Вы немного не так мой комментарий поняли, мне лично не нужно снимать ночью или в клубах. Меня этот вопрос интересует с сугубо технической точки зрения (и только применительно к фототехнике серии NX) — указано много характеристик, а про съемку в ночное время суток или при недостаточном освещении нет. Вот
В статье вы упомянули, что «лучше купить хороший фикс». А как вообще обстоят дела с фиксами у NX?
Я всегда с опаской относился к объективам с такой низкой светосилой (но ни в этой, ни в предыдещей статье не нашел информации о съемке при недостаточном освещении). Люди любят фотографировать ночью, в клубах и на концертах. Встроенной вспышки наверняка не всегда хватает, а в случае с концертом вообще не понятно, как дополнительно осветить сцену. На NX-экосистему, её оптику и с этой стороны неплохо было бы взглянуть
Кстати к вопросу о соотнесении похожих точек на разных изображениях — есть метод Корреляции Цифровых Изображений, суть которого в общем то та же, только используется он для точных определений деформации деталей и других изделий, но в частности применим и для определения оптического потока. Только формулы немного другие (которых я не нашел в вашей статье). Самая известная и широко используемая формула:
В основе, опять же, лежит интенсивность пикселей. Только берется не точка и ее окрестность, а целые куски изображений, чаще всего квадратные. Потом по этой формуле определяем корреляцию между этим «куском» и подобластью на исходном изображении и определяем, куда переместился тот или иной «кусок».
В OpenCV готовой реализации полного алгоритма нет, но есть функция MatchTemplate, в которой реализованы некоторые из формул определения корреляции. Только «кусков» изображений будет не одно, как на примере, а много (тот же самый принцип dense и sparse), и корреляция считается не по всей картинке, а по относительно небольшим областям.
В итоге получаем матрицу перемещения точек, которая показывает координаты перемещения точек на изображении.
Кстати с помощью дополнительных вычислений можно повысить точность до 1/100 пикселя.
Разумеется, этот метод совершенно не применим на низкоконтрастных изображениях.
Это даунсайд юнити, а не программистов. Как уже сказали, для юнити вполне приемлимо определять важные переменные как public, чтобы иметь доступ к ним напрямую из инспектора. Более того, это позволяет менять значение переменных прямо при выполнении Гейм превью, что в другом случае было бы невозможно. К сожалению, private переменные в инспекторе не отображаются и та же история с геттерами и сеттерами. То есть их (private, protected, {get; set;} нельзя поменять не залезая в код.
В общем для юнити паблик переменные это нормальная практика. (Конечно если предполагается, что значения менять будем прямо из инспектора)
На выходной файл язык написания там никак не влияет кстати. Веб версию в любом случае можно будет открыть только с помощью плагина Unity Web Player. Поэтому «на JavaScript позволяет писать» — реально позволяет только писать.)
Пример с вики простейший, Program это просто главный класс, а Main — точка входа в программу. Главное в примере — показать возможность устанавливать любую Стратегию. Если вызвать метод SetStrategy извне, Program не будет знать, какую именно стратегию ему подсунули — он будет работать с ней как с объектом, реализующим интерфейс IStrategy. В Main просто эксплицитно устанавливается начальная стратегия.
Он точно знает когда какую стратегию надо использовать.
Как раз таки нет. Если скормить нашему Program любую Стратегию через SetStrategy, он не будет знать какой класс скрывается за этим интерфейсом.
В то время как используя
MyMotor thisMotor = GetComponent<MyMotor>();
С интерфейсом точно так же, через GetComponent
Как я понимаю, подобной независимости в примере из вики можно добиться, сделав чтобы в классе Program происходил перебор всех имеющихся скриптов(экземпляров классов) и из них выбирался поддерживающий нужный нам интерфейс?(мы опять же знаем что он всего один на данном игровом объекте) Или я чего-то не так понял?
Вы опять путаете «каноническое» программирование и программирование в юнити.
Класс наследник должен реализовать все методы родителя.
В вашем примере наследник ничего не должен. Компилятор не выдаст ошибок или предупреждений, если вы унаследуете MyMotor и не переопределите методы. В этом случае очень просто запутаться.
Пустые (никак не пере объявленные методы) нужны например если мы заменили Мотор на другой Мотор, который в данной ситуации не должен реализовать прыжок, или мы захотели Мотор от одного моба повесить на другого.
В таком случае тут точно логическая нестыковка — у моба есть метод Jump, но он ничего не делает — это совсем не то, чего я ожидаю от подобной реализации. Непрыгающие мобы, по-хорошему, должны иметь другой тип (интерфейс). Наличие методов это как соглашение — «У тебя есть методы, значит каждым из них ты что-то делаешь». Если вам придется отдать подобный код в чужие руки, то возникнет много нестыковок.
И самое главное, дайте мне ссылку на статью про то как пользоваться интерфейсами. Можно ли потом в переменной одного типа хранить экземпляры разных классов?
Мы создаем переменную типа InterfaceName и можем хранить в ней все объекты, реализующие этот InterfaceName. И при этом не возникнет ситуации, когда методы можно будет оставить пустыми — компилятор не позволит. Смысловая нагрузка останется, логичность выполнения работы программы тоже. Такое использование интерфейсов полностью описывает паттерн Strategy, ссылки на wiki и вики.
Вот в этом то и соль интерфейсов, в одной переменной можно хранить ссылки на любые объекты, реализующие интерфейс. Вместо класса MyMotor у вас будет интерфейс IMovable допустим. Тогда и переменная MyMotor myLittleMotor превратится в IMovable myLittleMotor.
Плюс ко всему в C# очень здорово сделана модель событий, и события можно определять в интерфейсе.
Просто получается, что у меня в гейм объекте будет полноценный объект MonoBehavior со всеми кишками и костями, хотя в данном случае этого совершенно не требуется — нам нужны только конкретные методы.
В случае, если требуется заставить некоторые классы реализовать определенные методы, логичней пользоваться интерфейсами. Ваш вариант обладает небольшим «логическим» недостатком — фактически все методы вашего класса уже реализованы, только с пустым телом (методы затычки). В случае, когда суперкласс должен содержать только нереализованные методы, обычно выделяется интерфейс. И даже если опустить факт, что методы реализованы, но пустые (что безусловно аукнется позже), использование наследования в данном случае делает код менее гибким, ведь все еще действует ограничение на наследование от одного класса.
Так же не понятно, как быть с пустыми методами, которые не были переопределены в подклассе. Если я вижу у объекта метод Jump, то предполагаю, что он реализован и обладает какой-то логической нагрузкой. И я очень удивлюсь, если вызывая метод ничего не будет происходить.
Несколько «слов» в коде сделают наши скрипты независимыми и взаимозаменяемыми. Вообще надо делать все скрипты не зависимыми друг от друга.
В вашем случае объект, наследующийся от MyMotor обязательно будет наследовать MonoBehavior, то есть обладать всеми свойствами игрового объекта. Если я захочу сделать полноценного консольного монстра, который не будет находится в списке гейм объектов в игровом поле, а спокойно себе выполнять функции Move, Jump и прочее в консоли — я не смогу сделать это адекватно (без лишних в данном случае свойств и методов), поскольку я уже буду зависеть от реализации класса MonoBehavior.
В общем полиморфизм в данном случае точно лучше было бы сделать с помощью интерфейса, а не суперкласса. Это один из принципов ООП, предложенной знаменитой бандой четверых. Composition over inheritance — «Предпочитай композицию, а не наследование»
Подведем итоги:
1. Крайне не желательно оставлять методы с пустым телом, если предполагается, что подклассы переопределят эти методы. В этом случае нужно использовать абстрактный класс.
2. Если наш абстрактный класс не содержит ничего, кроме абстрактных методов, то логичней выделить эти методы в интерфейс.
Насколько мне известно, на AS3 и Adobe Flash в частности пишутся интерфесы в Scaleform. А каким способом соединения флеш и 3Д контента пользовались вы? Интересно посмотреть на техническую сторону процесса, почитать о преимуществах и недостатках использования выбранных инструментов разработки.
Вы просто очень шустро комментируете :)
Китайцы нашли в зарубежных операционных системах фатальный недостаток…
Так же и с программированием — мне очень сложно представить как компетентные (я надеюсь) преподаватели будут объяснять назначение конструкций for или if без объяснения таких базовых понятий как алгоритм, цикл, ветвления. Изучение иностранных языков начинается с изучения алфавита. Конечно в этом плане программирование воспринимать легче, потому что зачастую база одна и та же, только в разных представлениях.
Все когда-либо изучаемые мной науки начиналсь с самых азов, постепенно усложняясь и так далее.
В общем мне кажется, что само выражение «изучать языки программирования» построенно немного не компетентно, видно какие желания стоят за этими словами.
А еще товарищ Обама записал крутое «рекрутинг» видео, и некоторое время назад (несколько дней назад, не больше недели) была открыта подписка на какие-то мини курсы введения в программирование. Ссылка на видео вот и там же в описании ссылка на проект «помоги другу научиться программировать»
Я всегда с опаской относился к объективам с такой низкой светосилой (но ни в этой, ни в предыдещей статье не нашел информации о съемке при недостаточном освещении). Люди любят фотографировать ночью, в клубах и на концертах. Встроенной вспышки наверняка не всегда хватает, а в случае с концертом вообще не понятно, как дополнительно осветить сцену. На NX-экосистему, её оптику и с этой стороны неплохо было бы взглянуть
В основе, опять же, лежит интенсивность пикселей. Только берется не точка и ее окрестность, а целые куски изображений, чаще всего квадратные. Потом по этой формуле определяем корреляцию между этим «куском» и подобластью на исходном изображении и определяем, куда переместился тот или иной «кусок».
В OpenCV готовой реализации полного алгоритма нет, но есть функция MatchTemplate, в которой реализованы некоторые из формул определения корреляции. Только «кусков» изображений будет не одно, как на примере, а много (тот же самый принцип dense и sparse), и корреляция считается не по всей картинке, а по относительно небольшим областям.
В итоге получаем матрицу перемещения точек, которая показывает координаты перемещения точек на изображении.
Кстати с помощью дополнительных вычислений можно повысить точность до 1/100 пикселя.
Разумеется, этот метод совершенно не применим на низкоконтрастных изображениях.
В общем для юнити паблик переменные это нормальная практика. (Конечно если предполагается, что значения менять будем прямо из инспектора)
Как раз таки нет. Если скормить нашему Program любую Стратегию через SetStrategy, он не будет знать какой класс скрывается за этим интерфейсом.
С интерфейсом точно так же, через GetComponent
Вы опять путаете «каноническое» программирование и программирование в юнити.
В вашем примере наследник ничего не должен. Компилятор не выдаст ошибок или предупреждений, если вы унаследуете MyMotor и не переопределите методы. В этом случае очень просто запутаться.
В таком случае тут точно логическая нестыковка — у моба есть метод Jump, но он ничего не делает — это совсем не то, чего я ожидаю от подобной реализации. Непрыгающие мобы, по-хорошему, должны иметь другой тип (интерфейс). Наличие методов это как соглашение — «У тебя есть методы, значит каждым из них ты что-то делаешь». Если вам придется отдать подобный код в чужие руки, то возникнет много нестыковок.
Мы создаем переменную типа
InterfaceName
и можем хранить в ней все объекты, реализующие этотInterfaceName
. И при этом не возникнет ситуации, когда методы можно будет оставить пустыми — компилятор не позволит. Смысловая нагрузка останется, логичность выполнения работы программы тоже. Такое использование интерфейсов полностью описывает паттерн Strategy, ссылки на wiki и вики.MyMotor
у вас будет интерфейсIMovable
допустим. Тогда и переменнаяMyMotor myLittleMotor
превратится вIMovable myLittleMotor
.Плюс ко всему в C# очень здорово сделана модель событий, и события можно определять в интерфейсе.
Просто получается, что у меня в гейм объекте будет полноценный объект MonoBehavior со всеми кишками и костями, хотя в данном случае этого совершенно не требуется — нам нужны только конкретные методы.
Так же не понятно, как быть с пустыми методами, которые не были переопределены в подклассе. Если я вижу у объекта метод Jump, то предполагаю, что он реализован и обладает какой-то логической нагрузкой. И я очень удивлюсь, если вызывая метод ничего не будет происходить.
В вашем случае объект, наследующийся от MyMotor обязательно будет наследовать MonoBehavior, то есть обладать всеми свойствами игрового объекта. Если я захочу сделать полноценного консольного монстра, который не будет находится в списке гейм объектов в игровом поле, а спокойно себе выполнять функции Move, Jump и прочее в консоли — я не смогу сделать это адекватно (без лишних в данном случае свойств и методов), поскольку я уже буду зависеть от реализации класса MonoBehavior.
В общем полиморфизм в данном случае точно лучше было бы сделать с помощью интерфейса, а не суперкласса. Это один из принципов ООП, предложенной знаменитой бандой четверых. Composition over inheritance — «Предпочитай композицию, а не наследование»
Подведем итоги:
1. Крайне не желательно оставлять методы с пустым телом, если предполагается, что подклассы переопределят эти методы. В этом случае нужно использовать абстрактный класс.
2. Если наш абстрактный класс не содержит ничего, кроме абстрактных методов, то логичней выделить эти методы в интерфейс.
И да, спасибо за статью, очень занимательно