Я никогда не использую "структуру" в C++.
я никогда не могу воображать сценарий, где Вы использовали бы структуру, когда Вы хотите членов парламента, не занимающих официального поста, если Вы преднамеренно не пытаетесь сбивать с толку.
кажется, что использование структур является большим количеством синтаксического признака того, как данные будут использоваться, но я просто сделал бы класс и попытался бы сделать это явным от имени класса, или через комментарии.
, Например,
class PublicInputData {
//data members
};
REPL = чтение цикла печати eval. Пройдите через процесс чтения-оценки.
READ: Clojure видит строку «(` a) »
, анализирует ее и в итоге получает структуру данных. Во время чтения макросы читателя раскрываются, и больше ничего не происходит. В этом случае читатель разворачивает обратную кавычку и заканчивает так:
user> (read-string "(`a)")
((quote user/a))
EVAL: Clojure пытается оценить этот объект. Правила оценки различаются в зависимости от того, на какой объект вы смотрите.
См. clojure.lang .Compiler / analysisSeq
в исходном коде Clojure, чтобы увидеть правила оценки для списков, или clojure.lang.Compiler / analysisSymbol
для символов. Там есть много других правил оценки.
Предположим, вы делаете это:
user> (user/a)
REPL выполняет это внутренне:
user> (eval '(user/a))
Clojure видит, что вы оцениваете список, поэтому он оценивает все элементы в списке. Первый (и единственный) элемент:
user> (eval 'user/a)
#<user$a__1811 user$a__1811@82c23d>
a
не является специальной формой, и этот список не нужно расширять макросом, поэтому символ a
ищется в пространстве имен user
, а результирующее значение здесь - fn
. Итак, вызывается fn
.
Но вместо этого у вас есть следующее:
user> (eval '((quote user/a)))
Clojure оценивает первый элемент в списке, который сам является списком.
user> (eval '(quote user/a))
user/a
Он оценил первый элемент в этом подсписке, quote
, который представляет собой особую форму, поэтому применяются особые правила, и он возвращает свой аргумент (символ a
) un- оценен.
Символ a
- это значение в этом случае, поскольку fn
было значением выше. Итак, Clojure рассматривает сам символ как функцию и вызывает его. В Clojure все, что реализует интерфейс Ifn
, можно вызывать как fn
. Так получилось, что clojure.lang.Symbol
реализует Ifn
. Символ, вызываемый как функция, ожидает один параметр, коллекцию, и ищет себя в этой коллекции. Он предназначен для использования следующим образом:
user> ('a {'a :foo})
:foo
Это то, что он пытается сделать здесь. Но вы не передаете никаких параметров, поэтому вы получаете сообщение об ошибке «Неверное количество аргументов, переданных в: Symbol» (он ожидает коллекцию).
Чтобы ваш код работал, вам потребуются два уровня eval
. Это работает, надеюсь, вы понимаете, почему:
user> (eval '((eval (quote user/a))))
Hello, world
user> ((eval (first l)))
Hello, world
Обратите внимание, что в реальном коде использование напрямую eval
обычно является очень плохой идеей. Макросы - безусловно лучшая идея. Я использую его здесь только для демонстрации.
Посмотрите Compiler.java
в исходном коде Clojure, чтобы увидеть, как все это разыграется. Это не так уж и сложно.
Использование символа как функции - не то же самое, что его оценка. Символы как функции работают так же, как ключевые слова как функции. Как это:
user=> (declare a)
#'user/a
user=> (def a-map {'a "value"})
#'user/a-map
user=> ('a a-map)
"value"
user=>
Это не то, как вы обычно используете символ. Они чаще используются для поиска переменных в пространстве имен и при генерации кода в макросе.
Чтобы разбить уровни косвенности, давайте определим «x» как 1 и посмотрим, что произойдет:
user=> (def x 1)
#'user/x
Использование ] def
, мы создали "var." Имя переменной - это символ user / x. Специальная форма def
возвращает саму var в repl, и это то, что мы видим напечатанным. Давайте попробуем получить эту переменную:
user=> #'x
#'user/x
Синтаксис # '
- это макрос чтения, который говорит: «Дайте мне переменную, на которую указывает следующий символ». И в нашем случае этот символ - «х». Мы получили тот же var, что и раньше. Переменные - это указатели на значения, и их можно разыменовать:
user=> (deref #'x)
1
Но переменную нужно найти, прежде чем ее можно будет разыменовать. Именно здесь вступает в игру вызываемость символов. Пространство имен похоже на карту, где символы являются ключами, а переменные - значениями, и когда мы явно называем символ, мы неявно ищем его переменную в нашем пространстве имен. Примерно так:
user=> ('x (.getMappings *ns*))
#'user/x
Хотя, на самом деле, это, вероятно, больше похоже на это:
user=> (.findInternedVar *ns* 'x)
#'user/x
И вот мы прошли полный круг в путешествии символа без кавычек:
user=> (deref (.findInternedVar *ns* 'x))
1
user=> x
1
Однако эти двое не полностью равны. Потому что вычислитель делает это для всех символов, включая deref
и * ns *.
Суть цитирования заключается в том, что вы по существу обходите весь этот механизм и просто получаете обратно простой символ. Как # '
Макрос чтения возвращает простые переменные, макросы чтения `и 'возвращают простые символы, с квалификацией пространства имен или без нее, соответственно:
user=> 'x
x
user=> `x
user/x
Мой ответ не соответствует ответ на методологию водопада, который вы искали, потому что я думаю, вам нужно будет изучить навыки программирования игр, прежде чем вы сможете планировать, проектировать, внедрять и тестировать его. Программирование игр ОЧЕНЬ отличается от бизнес-программирования и от целой другой области как таковой. Первое, что вам нужно будет изучить, - это язык программирования OpenGL ES . По сути, это 3D API, который позволяет рисовать трехмерные примитивы. Вам все равно нужно будет использовать это, если вы кодируете 2D-игру, поскольку это быстро из-за использования графического процессора для ускорения. В Google есть несколько хороших руководств, с которых вам следует начать.
Vector Math Если вы делаете что-либо в 3D, вам нужно будет изучить математику 3D-векторов, векторы в основном используются для всего в играх, направления взгляда камеры, положения символов, скорости, обнаружения столкновений и т. Д. 2D-векторы (x, y) минус Компонент z по-прежнему необходим для программирования 2D-игр.
Обнаружение столкновений Как я узнаю, когда мой мяч попадает в стену? Ответ - обнаружение столкновений. Существует множество форм обнаружения столкновений, таких как сфера со сферой, AABB , OOBB , выпуклая оболочка, треугольная сетка и т. Д.
AI Как заставить врага атаковать моего персонажа? Искусственный интеллект - еще одна большая область, необходимая для того, чтобы дать NPC / Врагам возможность принимать разумные решения. ИИ может быть простым, например, операторами if else, но для его эффективности обычно требуются конечные автоматы или нечеткая логика.
Поиск пути Если вы хотите переместить персонажа из точки A в точку B, избегая врагов и движущихся препятствий, вам нужно будет использовать алгоритм поиска пути. Звезда (A *) - одна из самых популярных.
График сцены Если вы хотите, чтобы на экране одновременно отображалось 10-20 + врагов, вам нужно будет закодировать граф сцены для управления динамическим отрисовкой, логикой и созданием и удалением ресурсов. Если вы не знаете, что такое полиморфизм, вам необходимо знать его, так как это важно для ваших игровых объектов, и он связан с графом сцены.
Физика Положение, скорость, ускорение, гравитация и лучи представлены с помощью векторов, и вам может потребоваться освежить свои знания математики, чтобы написать код для любой игры. Начнем со Второго закона движения Ньютона F = MA (Сила = Масса * Ускорение). Физический движок с открытым исходным кодом, такой как Bullet, ODE, Newton, Tokamak, упростит задачу, а это значит, что вам не нужно будет писать эти правила физики самостоятельно.
Objective-C ++ Это необязательно, но рекомендуется. Если вы не знаете C ++, это, по сути, смесь C ++ и Objective-C. Я предпочитаю использовать C ++ для ядра игры и программирования из-за скорости C ++ и доступности сторонних библиотек в C ++.
Звук Если вам нужен звук, вы можете просто пойти дальше и использовать простые аудиофреймы, которые предоставляет Apple, однако для трехмерного позиционного звука потребуется что-то лучшее. Я бы порекомендовал изучить FMOD SDK для iPhone. Как упоминал @Stowelly, FMOD требует лицензии на коммерческое распространение, но вы можете поискать и другие, не требующие лицензионных отчислений.
Используйте игровой движок В настоящий момент для iPhone доступны игровые движки, которые значительно упростят вам запуск игры. В вашем случае это будет быстрее, хотя вам все равно придется изучить концепции, о которых я упоминал выше.
Вот они. некоторые известные мне игровые движки:
Unity3D Вероятно, это самый популярный из известных мне движков. Unity - это игровой движок для ПК / Mac, который позволяет писать код на Mac и компилировать для Windows / Linux / Mac OS X. Я сомневаюсь, что корпус iPhone совместим напрямую с другими платформами, я бы предположил, что вы будете ограничены iPhone, если вы начали новый проект. Однако коммерческое развертывание этого движка стоит от 199 до 399 долларов.
Cocos2D Это движок для 2D-игр с открытым исходным кодом, который может быть полезен для многих игр. Стоит взглянуть. Размещено в коде Google.
Вот еще несколько вариантов: user => ((first l))
Превратите это в:
user => (def l `(~ a 1 2))
Здесь ~ преобразует символ a в соответствующую ему переменную, а обратная кавычка делает работу без кавычек.
В общем, вы должны понимать разницу между vars (которые связаны с чем-то) и символами (которые никогда ни с чем не связаны).
Я попытаюсь объяснить это (в надежде что мое объяснение вас больше не смущает):
user=> (def v "content")
#'user/content
-> определяет переменную в текущем пространстве имен под символом 'v (полностью квалифицированный' user / v, предполагая, что это текущее пространство имен), и связывает ее (переменная, не символ) к объекту "content".
user=> v
"content"
-> преобразует v в переменную и получает связанное значение
user=> #'v
#'user/v
-> разрешает в саму var
user=> 'v
v
-> ничего не разрешает, просто символ (к сожалению, REPL этого не указывает, печать 'v as v)
user=> `v
user/v
-> как вы уже цитировали, преобразуется в символ в текущем контексте (пространстве имен), но результатом остается символ (полностью определенный), а не var user / v
user=> '(v)
(v)
-> plain цитирование, ничего не разрешает
user=> `(v)
(user/v)
-> синтаксис-кавычка, то же самое, что и цитирование, но разрешает символы в символы, определяемые пространством имен
user=> `(~v)
("content")
-> разрешает символ в его var (который неявно разыменован), давая связанный с ним объект