jdummy2d alpha-23aug2012 copyright 2012 by jabberx http://jdummy2d.sourceforge.net Контакты: twitter:n00rp ===================================== 0. Об этом документе ===================================== ВНИМАНИЕ: На сайте обычно лежит более свежая версия этого документа, поэтому читайте оттуда, если у вас есть такая возможность. Проверяйте отдельно, не изменилась ли версия jdummy2d и при необходимости устанавливайте обновления. Учтите, что проект jdummy2d находится в стадии alpha - значит, всё еще может содержать серьезные ошибки. Сообщайте о найденных ошибках сюда: https://sourceforge.net/p/jdummy2d/tickets/ Убедитесь, что вы прочли или хотя бы просмотрели весь этот документ, прежде чем начать пользоваться jdummy2d. Однако если вам не терпится попробовать jdummy2d в работе, см.:1.0 Быстрый старт ===================================== 1. Введение: ===================================== Здравствуй, дорогой русский и не русский разработчик игр. Для English-версии воспользуйся Google Translate, позже я сделаю перевод, но пока его нет, извини. Перед тобой jdummy2d — один из лучших программных пакетов для программирования двухмерных игр. Его ключевые особенности: - полученные игры одинаково работают на Windows/Linux/Mac OS/Android - нет необходимости качать дополнительный софт (JDK, SDK, IDE, плагины) - всё что нужно для создания jar и apk файлов уже входит в самораспаковывающийся архив весом всего лишь около 20 мегабайт - невероятная простота языка, сравнимая с простотой BASIC ===================================== Содержание: 1 Введение 1.0 Быстрый старт 1.1 Для кого предназначен этот пакет 1.2 Для кого этот пакет НЕ предназначен 1.3 Пара слов о совместимости 1.4 Структура проекта и компиляция 1.4-1 Модульный вариант структуры проекта 1.5 Подписывание и установка игры на Android 1.5-1 Смена иконки в apk 1.6 Лицензия jdummy2d 2 Структура программы на jdummy2d 3 Команды и типы 3.1 О типах коротко 3.2 Выход и отладочные сообщения 3.3 Окно 3.4 Фигуры 3.5 Повороты фигур 3.6 Изображения 3.7 Шрифты и вывод текста 3.7-1 Отступление. Зачем все эти заморочки с режимами 3.8 Звуки 3.9 Музыка 3.10 Спрайтлисты 3.11 Продвинутая отрисовка спрайтов 3.12 Пара советов об анимации 3.13 Тайминг 3.14 Ввод 3.14-1 Продвинутый ввод 3.15 Конверсии 4 Типы 4.1 Объявления переменных и массивы 4.2 Строки 4.3 Android Preferences (сохранение/загрузка данных) 4.4 Арифметические операции 4.5 Векторы 4.6 Цвета 5 Ветвление, циклы 6 Функции 6.1 Область видимости 7 Разное 7.1 Трюки 7.2 Очистка памяти 7.3 Чтение внутренних файлов 7.4 Чтение внешних файлов, запись внешних файлов, другие операции с файлами и папками (COMING SOON) 7.5 Чтение и запись локальных файлов 7.6 Работа с сетью (COMING SOON) 7.7 Комментарии 7.8 Ошибки 7.9 Разбиение строчек кода Приложение: Список клавишных констант Приложение: Математика (Math) Приложение: Случа йные числа (Random): Что внутри jdummy2d Благодарности Содержимое bat-файлов на случай утери ====================================== 1.0 Быстрый старт: ------------------ 1) Запустите распаковщик jdummy2d, укажите путь C:\ 2) Зайдите в C:\jdummy2d\examples 3) Выберите папку с примером, зайдите в неё. 4) Запустите make-all.bat 5) Запустите game.jar или run-console.bat, чтобы поиграть на компьютере 6) Запустите android-install.bat, чтобы установить на подключенное устройство 7) Зайдите в папку source, откройте main.txt, поизучайте, подправьте, повторите шаги 4-6, наблюдайте изменения. Примечание: Если вы распаковали jdummy2d в другой каталог, для запуска примеров вам понадобится подправить пути в bat-файлах этих примеров. Ничего не меняйте и не удаляйте из папки jdummy2d и вложенных папок. 1.1. Для кого предназначен этот пакет: -------------------------------------- Для того, кто не желает ни пользоваться конструкторами игр, ни погружаться в дебри ООП и Java. Для того, кто хочет тратить минимум времени на обучение кодингу, на установку и освоение разных IDE, SDK и библиотек. 1.2. Для кого этот пакет НЕ предназначен: ----------------------------------------- Для опытных программистов и начинающих, желающих обмазаться ООП и стать "серьезными" программистами. 1.3. Пара слов о совместимости ---------------------------- Приставка j означает Java. Да, вы будете делать java-игры, поэтому у вас должна стоять java (просто JRE, не обязательно JDK). Если вы играли в Майнкрафт, то она у вас стоит. Кросс-платформенными являются ИГРЫ, которые вы делаете с помощью jdummy2d. Сама же разработка пока может вестись только из-под OS Windows. Пакет jdummy2d включает в себя всё необходимое для создания игры, которая будет одинаково работать на Windows/Linux/Mac OS и даже Android 2.3.1 и выше. Конечно, если твоя игра использует PC-клавиатуру, то для Android взамен придется сделать некоторые области экрана активными. Можно также на всякий случай обработать клавиши телефонного DPAD аналогично стрелочным клавишам PC-клавиатуры, но для полной совместимости (у некоторых планшетов, например, вообще четыре кнопки - меню, громкость+/- и включение) желательно всё-таки ввести активные области. Проверить, есть ли у устройства, на котором запущена игра, клавиатура, можно в любой момент с помощью команды HAS_KEYBOARD(), которая возвращает TRUE или FALSE. Таким образом можно понять, запущена ли игра на Android-устройстве. Для игр, которые используют только мышь разница между Android и PC лишь в том, что в Android версии команда "установить позицию курсора" пропускается, т.к. там его нет, а также в невозможности изменить разрешение экрана в Android. Для desktop-ов генерируется jar-файл, для Android-девайсов - apk-файл. 1.4 Структура проекта и компиляция ---------------------------------- Вы можете взять пример проекта и использовать в качестве шаблона нового проекта. Если хотите создать новый проект вручную: для проекта создайте отдельную папку. В этой папке создайте еще две папки: source и data В папке source создайте текстовый файл main.txt В папке data создайте папку assets - сюда будете класть все файлы, они будут "внутренними" файлами программы - шрифты, звуки, картинки, ваши уровни. Откройте main.txt в своём любимом текстовом редакторе (я рекомендую Notepad++) и вставьте туда следующий шаблон: (поставьте синтаксис Smalltalk) COLOR MYCOLOR FUNC INIT() MYCOLOR = NEW COLOR(1,0,1,1) /* отступы не обязательны */ ENDFUNC /* они для удобства чтения */ FUNC CYCLE() CLS(MYCOLOR) ENDFUNC Это шаблон программы, которая ничего не делает кроме как: 1) объявляет переменную типа COLOR с названием MYCOLOR 2) инициализирует её новым цветом R=1,G=0,B=1,A=1 3) Каждый кадр заливает окно этим цветом Шаблон может быть и проще: FUNC INIT() ENDFUNC FUNC CYCLE() ENDFUNC Такая программа не будет даже очищать окно. Теперь скопируйте в проект файл make.bat из любого примера. Содержимое make.bat продублировано также в конце этого документа. Откройте его и подправьте. Пути: ----- Set PROJECT=D:\projects\myprojects Set JDUMMY=C:\jdummy2d Первый путь - путь к вашему проекту, второй - путь, куда вы распаковали jdummy2d. Флаг компиляции Android: ------------------------ Компиляция для Android занимает довольно много времени, поэтому есть смысл отключить её на время. Для этого надо отредактировать make.bat: В строчке MakeAndroid=yes замените yes на no. После этого будет обновляться только game.jar и компиляция будет проходить очень быстро. Когда захотите обновить apk-файл игры, не забудьте снова включить компиляцию Android-варианта, заменив no на yes в make.bat. Вы можете также скопировать свой make.bat, переименовать копию в make-desktop и отключить там MakeAndroid. В примерах используются два отдельных файла - make-all.bat и make-desktop.bat (в make-all - yes, в make-desktop - no). Каждый раз, когда вы меняете что-то в папке assets, вы должны пересобирать (make) проект. Имя приложения: --------------- В make.bat вы найдете строчку: Set Appname=MyApp Параметр Appname в файле make.bat влияет на имя приложения в Android и одновременно на имя пакета, так что постарайтесь, чтобы оно было уникальным. На одно Android-устройство нельзя установить две разные игры с одним именем - одна будет стирать другую, поэтому менять имя для разных проектов обязательно. (Всё это не касается desktop-версий). В этой версии jdummy2d в названии не допускаются: пробелы, кириллица или спецсимволы. Т.е. только буквы английского алфавита. После запуска make.bat если не возникнет никаких ошибок, в папке проекта появятся файлы game.jar и game.apk (для Android). Ошибки будут выведены в окно и продублированы в файл error.log. 1.4-1 Модульный вариант структуры проекта ----------------------------------------- Этот вариант пригоден, если ваш проект большой и содержит много кода. Если вы разбираетесь в составлении bat-файлов, то можете придумать более удобный вариант модульности, чем мой. Предлагаемый же мной выглядит так: Шаблонный main.txt переименуйте в a1.txt и добавьте пустую строчку в конце этого файла. Таким образом, a1.txt должен содержать: 1) все объявления глобальных переменных 2) функцию INIT (из неё можно вызвать любую функцию из другого файла, чтобы произвести инициализацию там, а файл a1.txt оставить коротким) 3) функцию CYCLE (то же самое) Все остальные файлы могут называться как угодно, кроме main.txt, лишь бы расширение было .txt и в конце каждого файла должна быть пустая строчка. В каждом файле можно держать одну или несколько функций. Разбивать функции нежелательно, хотя если вы назовёте первый файл myfunc-01.txt а второй myfunc-02.txt, то это должно сработать. Можно также разбить a1.txt на несколько файлов: a1.txt, a2.txt, a3.txt. Но это еще не всё. Чтобы модульная структура работала, вы должны 1) Положить в папку source (рядом со всеми исходниками) файл combine.bat (его содержимое продублировано в конце этого документа): @ECHO OFF del %1\main.txt type %1\*.txt >> %1\all move %1\all %1\main.txt Запускать его вручную нет смысла. 2) В make-*.bat файлы, после строчки Set Appname=YourAppName добавить две строчки (если их там еще нет, если есть, то пусть остаются всегда): CALL %PROJECT%\source\combine.bat %PROJECT%\source >%PROJECT%\error.log CLS Вот это всё, что надо сделать для того, чтобы использовать модульную структуру. Если вы захотите вернуться к обычной монолитной структуре (всё в main.txt), удалите из папки source все файлы, включая combine.bat, кроме main.txt. Из make-*.bat те две строчки убирать не нужно, они не повредят. 1.5 Подписывание и установка игры на Android -------------------------------------------- Подключите устройство и включите режим отладки: Настройки-Приложения-Разработка Перед установкой приложение нужно подписать. Для этого вы должны иметь хранилище ключей с ключом, знать пароль от хранилища и ключа. Чтобы создать своё хранилище, зайдите в папку jdummy2d\GEN_KEYSTORE и запустите файл genkeystore.bat. Вам будут задавать разные вопросы, просить придумать и подтвердить пароли. В конце концов появится файл KEYSTORE, это ваше хранилище Не забудьте пароли к нему (вы можете нажать Enter, когда попросят второй пароль и у вас будет одинаковый пароль к хранилищу и к алиасу). Здесь больше информации по созданию хранилища (если у вас что-то не получится): http://docs.oracle.com/javase/6/docs/technotes/tools/windows/keytool.html Создайте файл android-install.bat (его содержимое есть в конце этого документа). Подправьте его - исправьте пути, имя хранилища, пароли. Если вам не хочется возиться с созданием собственного хранилища, скопируйте в свой проект файлы release.keystore и android-install.bat из любого примера и подправьте в android-install.bat только пути. После запуска android-install.bat ваше приложение подпишется и установится на Android-устройство (если это устройство подключено и драйвера установлены). Если же устройство не подключено, вы можете позже вручную установить подписанное приложение через SD-карточку или через USB-режим передачи файлов. Возможно, перед запуском android-install.bat вам захочется изменить иконку вашего приложения: 1.5-1 Смена иконки в apk ------------------------ В этой версии jdummy2d если вы захотите сменить иконку, вам придется делать это каждый раз вручную с помощью 7zip: Откройте game.apk в 7z File Manager (7zip.org, если у вас его нет): ПКМ -> 7zip -> открыть архив. Войдите в папку res, там вы увидите папки drawable-*. Перетащите все эти папки куда-нибудь, откройте каждую и замените ic_launcher.png (это и есть иконка) на свою иконку, соблюдая размер и имя: ic_launcher.png. Каждый раз, когда вы пересоберёте приложение, вы должны будете открыть game.apk через 7zip и перетащить эти папки обратно в папку res архива. Вы должны делать это до того, как запустите android-install.bat, то есть сразу после make-all.bat. 1.6 Лицензия jdummy2d --------------------- jdummy2d полностью бесплатен для коммерческого и некоммерческого использования. ===================================== 2. Структура программы на jdummy2d: ===================================== jdummy2d претерпел значительные изменения в структуре. Здесь больше нет GOTO, GOSUB и прочих радостей, так что учитесь использовать циклы, если вы, по моему шуточному совету, не стали их учить, осваивая dummy2d. Еще одно нововведение - функции. Базовая программа состоит из объявлений и двух функций с кодом. Вы можете создавать и свои функции. Начало программы: Здесь происходит объявление глобальных переменных. Загрузить картинки или звуки здесь нельзя, но некоторые переменные (простые, типа INT, FLOAT) здесь можно сразу и инициализировать. FUNC INIT() Инициализация игры. Вызывается автоматически. Можно вызвать и самостоятельно. Здесь можно выполнить любые рассчеты и присвоить глобальным переменным значения, а также загрузить картинки и звуки. Создавать новые переменные здесь нет смысла (см. ниже про область видимости). ENDFUNC FUNC CYCLE() Главный цикл, который автоматически будет выполняться каждый кадр. Создаваемые здесь переменные будут локальными, т.е. временными. Реинициализация имеющихся переменных здесь возможна (перед именем опускать тип). Вся игровая логика и отрисовка происходит здесь. Этот цикл не стоит самостоятельно пытаться сделать бесконечным. Он сам будет вызываться каждый кадр автоматическим образом. ENDFUNC ===================================== 3. Команды и типы ===================================== 3.1 О типах коротко: -------------------- Сложные: IMAGE, SHEET, SPRITE, SOUND, MUSIC, VECTOR, COLOR Простые: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOL, STR Ниже все типы будут рассмотрены более детально. Имя переменных не должно состоять из INT STR LONG и т.п. 3.2 Выход и отладочные сообщения: --------------------------------- EXIT() - закрыть игру DEBUG(STR сообщение) - вывести сообщение в консоль (полезно для отладки на PC при запуске игры из командной строки через java -jar jarname.jar) 3.3 Окно: --------- CLS(COLOR c) - очистка экрана указанным цветом. Разумно выполнять в начале цикла. CLS(BLACK) SCREEN(w,h,fullscreen) - устанавливает размер окна и, по возможности, полноэкранный режим (эта возможность пока на экспериментальной стадии и может давать сбои). SCREEN(800,480,FALSE). На Android-устройствах команда не имеет смысла - там всегда используется весь экран GETW() - получает ширину экрана/окна в пикселах GETH() - получает высоту экрана/окна в пикселах Следующие команды не имеют смысла на Android, но работают для desktop: SETCURSORPOS(X,Y) - установить позицию курсора Примечание: позиция курсора рассчитывается по-другому: верхний левый угол это 0,0, нижний правый угол это GETW(),GETH(). HIDECURSOR() - спрятать курсор SHOWCURSOR() - показать курсор 3.4 Фигуры: ----------- ВНИМАНИЕ: начало координат - в центре экрана! SHAPE_LINES() - установить режим фигуры. Эта команда объявляет начало рисования линий. одновременно можно объявить только один режим. перед объявлением другого режима текущий надо завершить END_SHAPE() - завершение текущего режима фигуры. Нужно обязательно завершать режим, даже если вы не собираетесь больше объявлять другие режимы. Кроме того, перед тем как рисовать изображения или спрайты, режим фигур также нужно завершать (нельзя смешивать рисование линий и изображений, линий и точек и т.д.) SETCOLOR(COLOR c) - устанавливает цвет для режима, которым будут рисоваться линии, точки и прочие фигуры. SETCOLOR(GREEN) SHAPE_CIRCLES() - режим незалитые круги SHAPE_FCIRCLES() - режим залитые круги SHAPE_RECTS() - режим прямоугольники SHAPE_FRECTS() - режим залитые прямоугольники SHAPE_TRIS() - режим треугольники SHAPE_FTRIS() - режим залитые треугольники SHAPE_POINTS() - режим точки LINE(x, y, x2, y2) - рисует линию. убедитесь, что режим SHAPE_LINES() установлен CIRCLE(x,y,radius) - рисует круг. должен быть установлен режим SHAPE_CIRCLES() FCIRCLE(x,y,radius) - рисует залитый круг. должен быть установлен режим SHAPE_FCIRCLES() RECT(x,y,w,h) - рисует прямоугольник. должен быть установлен режим SHAPE_RECTS() FRECT(x,y,w,h) - рисует залитый прямоугольник. должен быть установлен режим SHAPE_FRECTS() TRI(x1,y1,x2,y2,x3,y3) - рисует треугольник. должен быть установлен режим SHAPE_TRIS() FTRI(x1,y1,x2,y2,x3,y3) - рисует залитый треугольник. должен быть установлен режим SHAPE_TRIS() POINT(x,y) - рисует точку 3.5 Повороты фигур: ---------------------- Чтобы нарисовать что-то, например, квадрат под углом, используется матрица. Сначала применяется трансформация TRANSLATE и/или ROTATE, затем рисуются фигуры, затем матрица сбрасывается - RESET). MATRIX_TRANSLATE(x,y) - сдвигает центр системы координат MATRIX_ROTATE(угол) - поворачивает систему координат относительно текущего центра MATRIX_RESET() - обнуляет поворот и сдвиг 3.6 Изображения: ---------------- Перед тем как любым способом рисовать изображения, надо включить режим: BEGIN_SPRITES() Не забудьте его выключить в конце цикла: END_SPRITES() Не смешивайте режимы рисования фигур и изображенй. !!!ВАЖНО: размеры изображений должны быть кратны 2: 16,32,64,128 и т.д. Это значит, что например, 512х512 - прокатит, а 511х127 - нет. IMAGE image1 - объявление. Инициализация возможна через функцию IMAGE_LOAD, но только внутри другой функции (например, INIT). Инициализация: image1 = IMAGE_LOAD(STR имяфайла, BOOL сглаживание(опционально)) - загружает картинку, определяя заранее будет ли она сглаживаться при скейлинге/повороте (TRUE). Если FALSE то не будет, FALSE можно и не писать. Поддерживаются png с полупрозрачностью. DRAW(IMAGE im, X, Y) - рисует картинку im в позиции X, Y (выравнивание по нижнему левому углу картинки) DRAW(IMAGE im,X,Y,W,H,xc1,yc1,xc2,yc2) - рисует часть картинки. W,H - размеры, xc1,yc1 - координаты верхнего левого угла в картинке, xc2,yc2 - координаты нижнего правого угла. Координаты даются в соотношении к размеру картинки. Например, чтобы нарисовать всю картинку: DRAW(im1,0,0,32,32,0,0,1,1) Чтобы нарисовать верхнюю правую часть картинки, условно поделенной на 4 части: DRAW(im1,0,0,32,32,0.5f,0,0.5f,0.5f). Этот вариант функции DRAW можно использовать для рисования спрайт-шитов, но есть способ попроще. 3.7 Шрифты и вывод текста: -------------------------- jdummy2d использует т.н. bitmap-fonts, шрифт можно сгенерировать с помощью программ Hiero или BMFont, шрифт желателен белый, можно с обводкой. Hiero можно взять здесь: http://code.google.com/p/libgdx/downloads/detail?name=hiero.jar&can=2&q SET_FONT(STR имя без расширения) - устанавливает шрифт. Шрифт (.fnt и .png) должен лежать в папке assets проекта. SET_FONT("myfont"). В jdummy2d уже включен шрифт impact с обводкой, так что делать свой шрифт и вызывать эту команду не обязательно Поскольку шрифты это по сути спрайты, перед выводом текста, надо включить режим рисования спрайтов: BEGIN_SPRITES(). Не забудьте потом выключить: в одном цикле на каждое включение режима должно быть выключение. 3.7-1 Отступление. Зачем все эти заморочки с режимами: ------------------------------------------------------ Используется аппаратное ускорение, OpenGL. Команды отрисовки посылаются на видеокарту. Видеокарте в общем-то по-барабану, 100 спрайтов/фигур нарисовать за раз или 1000. Но ей не по-барабану сколько раз вы к ней обратитесь за кадр. Если вы будете теребить её по 500 раз мелкими просьбами типа "А нарисуй 2 спрайта... А теперь 1 буковку", то FPS вашей игры упадёт ниже плинтуса. Когда вы начинаете режим, все ваши команды, так сказать, упаковываются в один конверт, а когда вы этот режим завершаете, конверт отправляется видеокарте. В конверт нельзя класть команды разного типа. Отдельные конверты: для точек, для линий, для треугольников, для спрайтов. FONT_SCALE(FLOAT x,FLOAT y) - установить масштаб шрифта по ширине и высоте 0.5f - уменьшение в 2 раза, 2.0f - увеличение итд. FONT_SCALE(2.0f,2.0f) FONT_COLOR(COLOR c) - установить цвет(закраску) шрифта. в качестве цвета можно указывать предустановленные (см. colors.png). FONT_COLOR(WHITE) PRINT(STR соообщение, X, Y) - вывести текст текущим шрифтом PRINT("Hello!",-50,0) PRINTW(STR длинный текст с \n переносами строк,X,Y,макс_ширина) - выводит текст и переносит строчки, если встречен перенос или если длина строччки превышает макс_ширину ALIGN(i) где i - 0, 1 или 2. устанавливает выравнивание текста. Эффект заметен, когда текст не вмещается в одну строчку. 0 - выравнивание по левому краю, 1 - по центру, 2 - по правому краю 3.8 Звуки: ---------- Объявление SOUND s1 Инициализация s1 = SOUND_LOAD("test.wav") s1.PLAY() или s1.PLAY(0.5f) - вполсилы s1.LOOP() или s1.LOOP(0.3f) - в треть силы s1.PLAY(vol,pitch,pan) - играть с определенной громкостью, высотой и панорамированием. То же доступно и для LOOP PLAY и LOOP возвращают ID звука (тип LONG), который нужен для команд SETVOL, SETPITCH, SETPAN и STOP. Пример: LONG id = s1.PLAY() s1.SETVOL(id,0.5f) - похожим образом вызываются команды SETPITCH и SETPAN s1.STOP(id) pitch должен лежать в пределах 0.5f-2.0f (>1 - выше, <1 - ниже). pan - от -1.0f до +1.0f vol (громкость) - от 0.0f до 1.0f 3.9 Музыка: ----------- Объявление MUSIC m1 ... Инициализация m1 = MUSIC_LOAD("theme.ogg") (должны поддерживаться также mp3, но ogg надежней). m1.PLAY() - начать проигрывание m1.PAUSE() - приостановить проигрывание m1.STOP() - остановить m1.SETVOL(float) - сменить громкость m1.SETLOOP(TRUE или FALSE) - определяет повторять музыку после окончания или нет m1.PLAYING() - возвращает TRUE, если музыка в данный момент проигрывается. FLOAT f = m1.GETPOS() - получает текущую позицию в миллисекундах 3.10 Спрайтлисты: ---------------- И этот способ - разрезка изображения и получение массива спрайтов. Для этого существует воспомогательный класс SHEET и функция IMAGE_SPLIT. Вот пример для Спрайтлиста размером 128х128, содержащего 4 спрайта по 64х64: SHEET[][] sheet = IMAGE_SPLIT(image1,64,64) - получаем массив спрайтов. DRAW(sheet[0][0],50,-15) - здесь рисуем верхний левый спрайт DRAW(sheet[0][1],150,5) - здесь рисуем верхний правый спрайт DRAW(sheet[1][1],-20,0) - здесь рисуем нижний правый спрайт Естественно, строчку SHEET[][] sheet надо вынести в начало программы, а строчку sheet = IMAGE_SPLIT(image1,64,64) - перенести в функцию INIT. 3.11 Продвинутая отрисовка спрайтов: ------------------------------------ Еще один воспомогательный класс - SPRITE. Он содержит встроенные функции поворота, смещения, скейлинга, закраски, зеркального отражения, сдвига и собственную функцию отрисовки, поэтому отлично подойдет для "сложных" случаев. SPRITE mysprite = NEW SPRITE(sheet[1][0]) - скармливаем ему кусочек картинки SPRITE mysprite = NEW SPRITE(image1) - либо целую картинку mysprite.SETPOS(-10,20) - устанавливаем позицию mysprite.SETANGLE(25) - устанавливаем угол поворота mysprite.SCALE(2.0f) - увеличиваем в два раза mysprite.FLIP(TRUE,FALSE) - отражаем только по оси X mysprite.OFFSET(0.1f,0.15f) - сдвигаем пиксели вниз на 10% и вправо на 15% mysprite.TINT(YELLOW) - подкрашиваем желтым цветом mysprite.DRAW() - рисуем его. Чтобы не создавать отдельных переменных, которые хранят позицию спрайта, можно вместо SETPOS использовать MOVE - сдвиг. mysprite.MOVE(10,15) - сдвигаем вправо на 10 и вверх на 15 пикселей. mysprite.GETW() - получить ширину спрайта mysprite.GETH() - получить высоту спрайта mysprite.GETX() - получить X спрайта mysprite.GETY() - получить Y спрайта Экспериментальное: mysprite.CENTERX() - получаем x-координату центра спрайта mysprite.CENTERY() - получаем y-координату центра спрайта Нет нужды переинициализировать спрайт, чтобы назначить ему другое изображение: mysprite.ASSIGN(sheet[1][1]) - назначаем другой кусочек Спрайтлиста спрайту. 3.12 Пара советов об анимации: ------------------------------ Вам придется реализовать собственную систему анимации, которая подойдет именно вам. Например, это можно основать на счетчике, который будет увеличиваться внутри функции CYCLE на DELTA и приводить к смене переменной, после превышения некоторого порога, эта переменная хранит индекс[ы] кадра. 3.13 Тайминг: ------------- GETDELTA() - выдаёт время, прошедшее между отрисовкой двух кадров. Пример: FLOAT delta = GETDELTA() С этой величиной вы должны связать все передвижения, частоту смены кадров анимаций и т.д. GETFPS() - выдаёт скорость кадров Пример: INT fps = GETFPS() PRINT(TXT(fps),-GETW()/2,GETH()/2) - печатает скорость кадров в левом верхнем углу. SLEEP(N) - задержка на N миллисекунд. задержка в 15 мс снижает скорость кадров до ~60, разгружает процессор, снижает энергопотребление на Android-устройствах, снимает сглаз и порчу. CAPFPS(60) - почти то же самое, что и SLEEP(15). обрезает скорость кадров до 60. Разница лишь в том, что если цикл будет занимать слишком много времени, обрезки не будет, чтобы повысить скорость кадров. GETTIME() - получить системное время (в миллисекундах). 3.14 Ввод: ---------- KEYSTATE(INT k) - узнать нажата ли клавиша. вернет TRUE, если нажата. Список клавиш приведен ниже. KEYSTATE(KEYS.ENTER) BUTTONSTATE(INT b) - узнать нажата ли кнопка мыши. вернет TRUE, если нажата. b может быть BUTTONS.LEFT, BUTTONS.RIGHT или BUTTONS.MIDDLE. HAS_KEYBOARD() - возвращает TRUE, если у устройства есть хардварная клавиатура. GETX() - получает позицию курсора по оси Х (INT) GETY() - получает позицию курсора по оси Y (INT) Примечание: позиция курсора рассчитывается по-другому: верхний левый угол это 0,0, нижний правый угол это GETW(),GETH(). Следующие команды работают только в Android-устройствах с акселлерометром: GETAX() - получает значение акселлерометра по оси Х (FLOAT) GETAY() - получает значение акселлерометра по оси Y (FLOAT) GETAZ() - получает значение акселлерометра по оси Y (FLOAT) 3.14-1 Продвинутый ввод: ------------------------ Если вас не устраивает KEYSTATE/BUTTONSTATE, если вы хотите получать больше более детальных сообщений о вводе, вам придётся создать после функции CYCLE еще несколько функций (на выбор). Все эти функции должны возвращать значение: TRUE, если вы обработали ввод, FALSE, если нет. Это значит, что если вы напишете RETURN FALSE, сообщение об этом событии будет повторяться. Созданные вами функции будут автоматически вызываться, когда будет приходить соответствующее сообщение. Внутри этих функций вы должны обработать входящие параметры (нажатая/отпущенная клавиша, номер(pointer) пальца на мультитач-скрине и т.п.). Вот шаблоны: Нажатие клавиши: FUNC KEYDOWN(INT KEYCODE) RETURNS BOOL RETURN TRUE ENDFUNC Отпущение клавиши: FUNC KEYUP(INT KEYCODE) RETURNS BOOL RETURN TRUE ENDFUNC Отпущение клавиши с символом (получаем символ): FUNC KEYTYPED(CHAR CH) RETURNS BOOL RETURN TRUE ENDFUNC Нажатие кнопки мыши или пальца на экран: FUNC TOUCHDOWN(INT x, INT y, INT pointer, INT button) RETURNS BOOL RETURN TRUE ENDFUNC Отпущение кнопки мыши или пальца с экрана: FUNC TOUCHUP(INT x, INT y, INT pointer, INT button) RETURNS BOOL RETURN TRUE ENDFUNC Движение мыши с зажатой кнопкой/пальца по экрану: FUNC TOUCHDRAGGED(INT x, INT y, INT pointer) RETURNS BOOL RETURN TRUE ENDFUNC Движение мыши: FUNC TOUCHMOVED(INT x, INT y) RETURNS BOOL RETURN TRUE ENDFUNC Кручение колёсика мыши (положительное или отрицательное значение): FUNC SCROLLED(INT amount) RETURNS BOOL RETURN TRUE ENDFUNC 3.15 Конверсии: --------------- TXT(i) - превращает любое число или цвет или вектор в строку VAL(s) - превращает строку в целое число, возвращает -1 если невозможно. VALF(s) - превращает строку в число с плавающей точкой, возвращает -1.0f если невозможно Вектор или цвет достать обратно из строки нельзя. GETINT(floatvalue) - возвращает целое число. полезно для некоторых функций, таких как SLEEP, т.к. они принимают только INT, но не FLOAT. =================== 4 Типы: =================== BYTE - байт. от -127 до +128 и SHORT - 16 битное число от -32767 до +32768 используются редко, в основном для экономии памяти. Скорость они не увеличивают. CHAR - символ. объявляется в одинарной кавычке: CHAR mychar='@' Может быть приплюсован к строке. Может быть получен из строки, см. ниже. INT - 32 битное число со знаком. от -2147483647 до 2147483648 LONG - 64-битное число целое со знаком. Очень большие числа, используется редко. BOOL - TRUE или FALSE (условие выполняется, условие не выполняется). FLOAT - 32-битное число с плавающей точкой. Обязательный префикс значений - f DOUBLE - 64-битное число с плавающей точкой (повышенной точности). Суффикс - d Когда мы пишем число с точкой (FLOAT), мы должны заканчивать его буквой f: 1.0f, 100.25f и т.п., иначе возникнет ошибка. Для DOUBLE - d: 2.0d и т.п. 4.1 Объявления переменных и массивы: ------------------------------------ INT MYINT Объявления с одновременной инициализацией: INT MYINT = 5 Массивы: INT[] MYINT Как видим, здесь тип выглядит не как INT, а как INT[], это отличает массивы от простых переменных. Этот тип можно указывать в функциях как возвращаемое значение или как входящий параметр. Массив с инициализацией размера: INT[] MYINT = NEW INT[100] Массив с инициализацией значений: INT[] MYINT = {1,2,-5,302} Доступ к ячейкам массива: MYINT[6] = 4 PRINT(TXT(MYINT[9])) Отложенная инициализация: Вверху программы: INT[] MYINT В коде функции INIT: MYINT = NEW INT[100] Если не произвести инициализацию и попытаться обратиться к переменной или к ячейке массива, может произойти ошибка. Еще раз: Инициализация, это присвоение значения: MYINT = {3,4} Объявление - присвоение имени и типа: INT[] MYINT Можно объединять объявление и инициализацию INT[] MYINT = {3,4} Но нельзя делать этого с изображениями (IMAGE) и звуками. Их нужно инициализировать уже в коде функции INIT или в любой другой функции. Динамические массивы удобны, но они тормозят, особенно на Android-устройствах и без них легко обойтись, поэтому в jdummy2d их нет. Заранее определяйтесь с тем, насколько большим может стать ваш массив. Держите индекс последней заполненной ячейки и увеличивайте его после добавления величин в массив. Получение длины массива (пригодится, если его сгенерировала и вернула функция): MYINT.LENGTH (заметьте, в отличие от получение длины строки, здесь () скобки не используются). 4.2 Строки: ----------- STR - строка. Инициализируется в двойных кавычках: mystring = "test" mystring.LENGTH() - возвращает длину строки mystring Строки нельзя сравнивать через == или !=. Сравнение строк: mystring.DIFFERS("te_t") выдаст FALSE mystring.DIFFERS("test") выдаст TRUE Получение символа из строки: mystring.GETCHAR(1) - получить второй символ Строки можно складывать с помощью +: mystring = mystring + mystring2 + "test" "\n" - перенос строки. Замена: mystring = mystring.REPLACE("st","nt") - в mystring вместо "test" теперь будет "tent". Получение части строки: STR newstr = mystring.MID(1,3) - начиная от второго символа получить три символа. newstr теперь должен содержать "ent". Второй параметр можно опустить: newstr = mystring.MID(1) - строка будет получена от второго символа до конца. Разбиение строки заключается в объявлении массива строк и его заполнении с помощью встроенной в строку функции SPLIT. Разделитель указывается в качестве параметра: (напомню, что mystring содержит "tent") STR[] strings = mystring.SPLIT("n") - разбиваем по символу "n" (разделитель может состоять и из нескольких символов или быть пробелом, например) PRINT(TXT(strings.LENGTH)) - узнаём длину. Эта команда выведет число 2 PRINT(strings[0],0,15) выведет "te" PRINT(strings[1],0,30) выведет "t" Еще пример, в котором разбивается строка и по очереди печатается каждая ячейка: STR test = "big string:divided with:colons" STR[] splitted = test.SPLIT(":") FOR (INT I=0;I> << >> и << - битовые сдвиги, используются для быстрого деления на числа, кратные 2. Присвоения: = += -= /= *= 4.5 Векторы: ------------ Векторы бывают полезны для разных математических вычислений. В jdummy2d используются двухмерные векторы. Их использование не обязательно (можно обойтись собственными функциями на основе синусов, косинусов, корней итп), но они значительно упрощают разработку. Объявляется вектор похожим с массивом образом - с использованием слова NEW VECTOR vec = NEW VECTOR(0,0) - объявление и инициализация вектора vec.X - доступ к x координате vec.Y - доступ к y координате Дальнейшие операции изменяют вектор vec.NORM() - нормализация vec.MUL(vec2 или float) - умножение vec.ADD(vec2 или float,float) - сложение vec.CROSS(vec2 или float,float) - кросс-продукт vec.DOT(vec2) - дот-продукт vec.ROT(float angle) - поворот вектора на угол (в градусах) vec.SET(float,float) - установка новых значений vec.EQU(vec2,float epsilon) - приблизительное сравнение, приблизительность определяется величиной epsilon. TRUE, если vec равен vec2 vec.DIST(vec2 или float,float) - расстояние между векторами vec.DIST2(vec2 или float,float) - квадратное расстояние между векторами vec.SUB(vec2 или float,float) - вычитание vec.COPY() - получить копию вектора, чтобы не изменять его в дальнейшнем vec.LEN() - длина вектора vec.LEN2() - квадратная длина вектора vec.LERP(vec2, alpha) - линейная интерполяция между этим вектором и другим сила интерполяции определяется величиной alpha - от 0.0f до 1.0f vec.ANGLE() - получить угол вектора Пример копирования вектора: VECTOR vec1 = NEW VECTOR(0.33f,-2.2f) VECTOR vec2 vec2 = vec1.COPY() Операции можно объединять в цепочку: vec2.MUL(0.5f).ROT(12).NORM() Это аналогично строчке, т.к. как сказано выше, операции изменяют вектор: vec2 = vec2.MUL(0.5f).ROT(12).NORM() Чтобы этого не происходило, нужно делать копию: vec3.MUL(vec2.COPY().MUL(0.5f).LEN()) - после этой операции vec2 останется неизменным. 4.6 Цвета: ---------- Список предустановленных цветов - в файле colors.png, где можно сразу на них и посмотреть. объявляем новые цвета так (можно писать в глобальных переменных, в начале программы и сразу инициализировать): COLOR mycolor1 = NEW COLOR(1,0.5f,0,1) Параметры в скобках это величины R(красный) G(зеленый) B(синий) и Alpha(прозрачность) в пределах 0.0f - 1.0f. После инициализации появляется также доступ к отдельным параметрам цвета: mycolor1.r, mycolor1.g, mycolor1.b и mycolor1.a Их можно считывать или менять. ==================== 5. Ветвления, циклы: ==================== Всё осталось как в dummy2d. В примерах: FOR: ---- FOR (INT A=0; A<10; A+=1) ...пока A<10, A будет увеличиваться а цикл повторяться NEXT FOR (INT I: MYINTARR) - принимаются массивы любых типов ...цикл пройдет по всем ячейкам массива MYINTARR, ...значения будут доступны по переменной I NEXT IF...THEN...ELSEIF...THEN...ELSE...ENDIF: ----------------------------------------- Сначала пару слов о сравнениях. Допустимые варианты: > < == != >= <= (больше, меньше, равно, не равно, больше-равно, меньше-равно) Сочетания условий: || && ! (или, и, не) Алиасы (другой вариант этих команд): OR AND NOT Используйте скобки, чтобы по-разному комбинировать условия. IF (A>B) THEN ... ENDIF IF (A>B OR B>C) THEN ... ELSEIF (A>10) THEN ... ELSE ... ENDIF WHILE...WEND: ------------- WHILE (A==5) ...пока A==5, повторять цикл WEND DO...REDO: ---------- DO ...то же, что и WHILE, но выполнится хотя бы один раз, т.к. проверка - в конце REDO (R<5) SELECT...CASE...BREAK...DEFAULT...: ----------------------------------- SELECT(X) - допускаются целые числа, байты CASE 1: PRINT("1!",0,0) BREAK CASE 2: PRINT("2!",0,0) BREAK DEFAULT: PRINT("not 1 and not 2",0,0) BREAK ENDSELECT Примечание: если вы внутри CASE использовали команду RETURN (возврат из функции), то BREAK после этого ставить не надо. Воспомогательные команды: ------------------------- BREAK - прервать цикл FOR/WHILE/DO/SELECT CONTINUE - пропустить дальнейший код и продолжить выполнение текущего FOR/WHILE/DO/SELECT ========== 6. Функции: ========== Шаблон функции FUNC FUNCNAME(PARAMTYPE paramname, PARAMTYPE paramname, ....) RETURNS RETURNTYPE ... RETURN var ENDFUNC RETURNS RETURNTYPE (FLOAT, INT итп) - указывает на то, что функция что-то возвращает. В таком случае в теле функции должна быть доступна команда RETURN var, которая собственно и возвращает результат функции. Если не указывать RETURNS, функция ничего не возвращает, но команду RETURN можно использовать, чтобы прервать функцию. Пример функций: --------------- FUNC MAX(INT A, INT B) RETURNS INT IF (A>B) THEN RETURN A ELSE RETURN B ENDIF ENDFUNC FUNC MYCLS1() CLS(BLACK) ENDFUNC FUNC MYCLS2(COLOR C) CLS(C) ENDFUNC Функции можно размещать в любом месте программы. Вложение функций недопустимо. 6.1 Область видимости: --------------------- Это касается в основном объявления переменных. Переменные, _объявленные_ внутри функций, видны только этим самым функциям. Переменные, объявленные в начале программы видны всем функциям. Перменные, объявленные внутри ветвлений типа IF, FOR, WHILE и т.п. видны только в пределах этих ветвлений. ============== 7. Разное ============== 7.1 Трюки: ----------- Запрет ресайза окна на десктопах (выполнять в цикле, можно через раз): IF (GETW()!=800 AND GETH()!=480) THEN SCREEN(800,480,false); ENDIF 7.2 Очистка памяти: -------------------- Иногда полезно удалить неиспользуемое большое изображение, например: image1.DISPOSE() - после этого image1 станет недоступен для использования. То же самое нужно делать с неиспользуемыми звуками и музыкой: mysound.DISPOSE() main_music.DISPOSE() Удаляем большой массив: myintarray = NULL 7.3 Чтение внутренних файлов: ------------------------------ Для чтения внутренних файлов (из ваших ассетов) есть две функции: STR bigstring = READ_TXT(имя_файла) - весь файл читается в одну строку BYTE[] bytearray = READ_BYTES(имя_файла) - подходит для бинарных файлов, получаем массив байтов. 7.4 Чтение внешних файлов, запись внешних файлов, другие операции с внешими файлами и папками: -------------------------------------------------- COMING SOON и надо ли это? 7.5 Чтение и запись локальных файлов: ------------------------------------- Локальные файлы это файлы рядом с game.jar. На Android это пользовательские папки. Если вам нужно сохранить небольшое количество переменных на Android, используйте Android Preferences (см. 4.3). LREAD_TXT(filename) возвращает строку из файла, который лежит рядом с game.jar. LREAD_BYTES(filename) возвращает массив байтов BYTES[] из бинарного файла, который лежит рядом с game.jar. Для записи используются следующие функции: LWRITE_TXT(STR filename, STR s) LWRITE_BYTES(STR filename, BYTE[] b) Эти две функции не перезаписывают файл, а добавляют к нему: LAPPEND_TXT(STR filename, STR s) LAPPEND_BYTES(STR filename, BYTE[] b) Пример: BYTES[] BARR = LREAD_BYTES("data.dat") FOR (BYTE by: BARR) ...делаем что-то с каждым байтом (by) NEXT Пример: STR FPSTR = TXT(GETFPS()) + "\n" LAPPEND_TXT("fpslog.txt",FPSTR) 7.6 Работа с сетью: -------------------- COMING SOON 7.7 Комментарии: ---------------- // это комментарий Комментарии допускаются только в виде отдельных строчек. 7.8 Ошибки: ----------- И как с ними бороться. "Possible lost of precision" Случается: когда используем FLOAT в строчке, присваеваемой INT-переменной. Решение: а) перед FLOAT-значением пишем (int). б) или Math.round(FLOAT-значение) Если не можете справиться с какой-то ошибкой, создайте тикет на сайте проекта. Не забудьте приложить ваш проект (очищенный с помощью clean.bat). 7.9 Разбиение строчек кода: --------------------------- Нельзя просто сделать перенос. Вот пример правильно сделанного переноса на jdummy2d: INT[] MAP = {129,54,52,62,31,50,30,42,41,55,56,76,59,29,47,32, _ _ 34,35,36,38,39,40,74,66,61,45,51,33,46,48,53,49, _ _ 8,9,10,11,12,13,14,15,16,7,252} Пробел должен быть только с одной стороны: в конце строчки пробел ставится перед знаком подчеркивания, в начале разбитой строчки - после. Перед началом разбитой строчки не должно быть никаких отступов. В конце разбиваемой строчки после подчеркивания не должно быть никаких отступов или пробелов ===================================== Приложение: Список клавишных констант ===================================== В программе можно использовать как имена так и соответствующие числа. Рекомендуется всё же, использовать имена. Не забывайте использовать префикс - KEYS. - KEYS.A, KEYS.LEFT и т.д. Учтите что здесь также указаны и клавиши, которые доступны только на устройствах андроид (CALL/ENDCALL/DPAD_*/MENU/CAMERA/VOLUME_*/SOFT_*/NUM_* - в зависимости от модели), на джойстиках (BUTTON_*), на медиа-клавиатурах (MEDIA_*). Цифровые PC-клавиши предварены префиксом NUM_* и нет различий между NUMPAD и цифровыми клавишами, что под рядом F1-F12. ANY_KEY = -1 - чтобы проверить, нажата ли вообще какая-нибудь клавиша NUM_0 = 7 NUM_1 = 8 NUM_2 = 9 NUM_3 = 10 NUM_4 = 11 NUM_5 = 12 NUM_6 = 13 NUM_7 = 14 NUM_8 = 15 NUM_9 = 16 A = 29 ALT_LEFT = 57 ALT_RIGHT = 58 APOSTROPHE = 75 AT = 77 B = 30 BACK = 4 BACKSLASH = 73 C = 31 CALL = 5 CAMERA = 27 CLEAR = 28 COMMA = 55 D = 32 DEL = 67 BACKSPACE = 67 FORWARD_DEL = 112 DPAD_CENTER = 23 DPAD_DOWN = 20 DPAD_LEFT = 21 DPAD_RIGHT = 22 DPAD_UP = 19 CENTER = 23 DOWN = 20 LEFT = 21 RIGHT = 22 UP = 19 E = 33 ENDCALL = 6 ENTER = 66 ENVELOPE = 65 EQUALS = 70 EXPLORER = 64 F = 34 FOCUS = 80 G = 35 GRAVE = 68 H = 36 HEADSETHOOK = 79 HOME = 3 I = 37 J = 38 K = 39 L = 40 LEFT_BRACKET = 71 M = 41 MEDIA_FAST_FORWARD = 90 MEDIA_NEXT = 87 MEDIA_PLAY_PAUSE = 85 MEDIA_PREVIOUS = 88 MEDIA_REWIND = 89 MEDIA_STOP = 86 MENU = 82 MINUS = 69 MUTE = 91 N = 42 NOTIFICATION = 83 NUM = 78 O = 43 P = 44 PERIOD = 56 PLUS = 81 POUND = 18 POWER = 26 Q = 45 R = 46 RIGHT_BRACKET = 72 S = 47 SEARCH = 84 SEMICOLON = 74 SHIFT_LEFT = 59 SHIFT_RIGHT = 60 SLASH = 76 SOFT_LEFT = 1 SOFT_RIGHT = 2 SPACE = 62 STAR = 17 SYM = 63 T = 48 TAB = 61 U = 49 UNKNOWN = 0 V = 50 VOLUME_DOWN = 25 VOLUME_UP = 24 W = 51 X = 52 Y = 53 Z = 54 META_ALT_LEFT_ON = 16 META_ALT_ON = 2 META_ALT_RIGHT_ON = 32 META_SHIFT_LEFT_ON = 64 META_SHIFT_ON = 1 META_SHIFT_RIGHT_ON = 128 META_SYM_ON = 4 CONTROL_LEFT = 129 CONTROL_RIGHT = 130 ESCAPE = 131 END = 132 INSERT = 133 PAGE_UP = 92 PAGE_DOWN = 93 PICTSYMBOLS = 94 SWITCH_CHARSET = 95 BUTTON_CIRCLE = 255 BUTTON_A = 96 BUTTON_B = 97 BUTTON_C = 98 BUTTON_X = 99 BUTTON_Y = 100 BUTTON_Z = 101 BUTTON_L1 = 102 BUTTON_R1 = 103 BUTTON_L2 = 104 BUTTON_R2 = 105 BUTTON_THUMBL = 106 BUTTON_THUMBR = 107 BUTTON_START = 108 BUTTON_SELECT = 109 BUTTON_MODE = 110 COLON = 243 F1 = 244 F2 = 245 F3 = 246 F4 = 247 F5 = 248 F6 = 249 F7 = 250 F8 = 251 F9 = 252 F10 = 253 F11 = 254 F12 = 255 Здесь файл обрезается (максимальный размер README на sourceforge ограничен). Для полной версии скачайте этот файл. ===================================== Приложение: Математика (Math): ===================================== Используется стандартный java класс Math. В виде таблицы можно посмотреть здесь: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Math.html Префикс Math, все функции пишутся маленькими буквами, пример: DOUBLE S = Math.sin(0.5f) Константы: DOUBLE E The DOUBLE value that is closer than any other to e, the base of the natural logarithms. DOUBLE PI The DOUBLE value that is closer than any other to pi, the ratio of the circumference of a circle to its diameter. Функции: тип возвращаемого значения имя функции параметры DOUBLE abs(DOUBLE a) Returns the absolute value of a DOUBLE value. FLOAT abs(FLOAT a) Returns the absolute value of a FLOAT value. INT abs(INT a) Returns the absolute value of an INT value. LONG abs(LONG a) Returns the absolute value of a LONG value. DOUBLE acos(DOUBLE a) Returns the arc cosine of an angle, in the range of 0.0 through pi. DOUBLE asin(DOUBLE a) Returns the arc sine of an angle, in the range of -pi/2 through pi/2. DOUBLE atan(DOUBLE a) Returns the arc tangent of an angle, in the range of -pi/2 through pi/2. DOUBLE atan2(DOUBLE y, DOUBLE x) Converts rectangular coordinates (x, y) to polar (r, theta). DOUBLE ceil(DOUBLE a) Returns the smallest (closest to negative infinity) DOUBLE value that is not less than the argument and is equal to a mathematical integer. DOUBLE cos(DOUBLE a) Returns the trigonometric cosine of an angle. DOUBLE exp(DOUBLE a) Returns Euler's number e raised to the power of a DOUBLE value. DOUBLE floor(DOUBLE a) Returns the largest (closest to positive infinity) DOUBLE value that is not greater than the argument and is equal to a mathematical integer. DOUBLE IEEEremainder(DOUBLE f1, DOUBLE f2) Computes the remainder operation on two arguments as prescribed by the IEEE 754 standard. DOUBLE log(DOUBLE a) Returns the natural logarithm (base e) of a DOUBLE value. DOUBLE max(DOUBLE a, DOUBLE b) Returns the greater of two DOUBLE values. FLOAT max(FLOAT a, FLOAT b) Returns the greater of two FLOAT values. INT max(INT a, INT b) Returns the greater of two INT values. LONG max(LONG a, LONG b) Returns the greater of two LONG values. DOUBLE min(DOUBLE a, DOUBLE b) Returns the smaller of two DOUBLE values. FLOAT min(FLOAT a, FLOAT b) Returns the smaller of two FLOAT values. INT min(INT a, INT b) Returns the smaller of two INT values. LONG min(LONG a, LONG b) Returns the smaller of two LONG values. DOUBLE pow(DOUBLE a, DOUBLE b) Returns the value of the first argument raised to the power of the second argument. DOUBLE random() Returns a DOUBLE value with a positive sign, greater than or equal to 0.0 and less than 1.0. DOUBLE rint(DOUBLE a) Returns the DOUBLE value that is closest in value to the argument and is equal to a mathematical integer. LONG round(DOUBLE a) Returns the closest LONG to the argument. INT round(FLOAT a) Returns the closest INT to the argument. DOUBLE sin(DOUBLE a) Returns the trigonometric sine of an angle. DOUBLE sqrt(DOUBLE a) Returns the correctly rounded positive square root of a DOUBLE value. DOUBLE tan(DOUBLE a) Returns the trigonometric tangent of an angle. DOUBLE toDegrees(DOUBLE angrad) Converts an angle measured in radians to an approximately equivalent angle measured in degrees. DOUBLE toRadians(DOUBLE angdeg) Converts an angle measured in degrees to an approximately equivalent angle measured in radians. ===================================== Приложение: Случайные числа (Random): ===================================== RND(INT RANGE) - получить случайное число RANDOMIZE() - выбрать случайное зерно RANDOMIZE(LONG SEED) - установить зерно Пример: RND(1000) - вернёт число INT от 0 до 999 Используется также стандартный java класс Random Префикс random (это созданный заранее экземпляр класса), Пример: random.nextInt(100) - вернет число от 0 до 99 Описание других функций: INT next(int bits) Generates the next pseudorandom number. BOOL nextBoolean() Returns the next pseudorandom, uniformly distributed boolean value from this random number generator's sequence. nextBytes(BYTE[] bytes) Generates random bytes and places them into a user-supplied byte array. DOUBLE nextDouble() Returns the next pseudorandom, uniformly distributed double value between 0.0 and 1.0 from this random number generator's sequence. FLOAT nextFloat() Returns the next pseudorandom, uniformly distributed float value between 0.0 and 1.0 from this random number generator's sequence. DOUBLE nextGaussian() Returns the next pseudorandom, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence. INT nextInt() Returns the next pseudorandom, uniformly distributed int value from this random number generator's sequence. INT nextInt(INT n) Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence. LONG nextLong() Returns the next pseudorandom, uniformly distributed long value from this random number generator's sequence. setSeed(LONG seed) Sets the seed of this random number generator using a single long seed. ===================================== Что внутри jdummy2d: ===================================== 1) урезанный компилятор java от Sun 2) пре-комплиированные jar и apk файлы (для desktop и для Android) 3) содержащие обертку над libgdx (java-библиотека, автор - Mario Zechner), 4) программа-транслятор из jdummy2d в java код, совместимый с обёрткой 5) утилита для упаковки (7z) 6) утилиты для ковыряния Android пакетов: dex2jar, smali, baksmali, apktool 7) разные Android утилиты от Google 8) batch-файл jdm.bat, который всем заправляет 9) возможно, что-то еще забыл упомянуть 10) этот мануал ===================================== Благодарности: ===================================== Благодарю авторов Java, Android, libgdx, 7z, Python, cxfreeze, dex2jar, smali, apktool, Windows и Notepad++, без которых jdummy2d не появился бы на свет в своем текущем виде. ===================================== Содержимое make-all.bat (на случай утери) замените Set MakeAndroid=yes на Set MakeAndroid=no и вы получите make-desktop.bat, который будет работать намного быстрее, но генерировать только desktop-версию игры ===================================== @ECHO OFF Set PROJECT=C:\jdummy2d\EXAMPLES\HelloWorld Set JDUMMY=C:\jdummy2d Set MakeAndroid=yes Set Appname=HelloJDummy2d CALL %PROJECT%\source\combine.bat %PROJECT%\source >%PROJECT%\error.log CLS cd %JDUMMY% ECHO Compiling, please wait... IF %MakeAndroid% == yes ( ECHO NOTE: You're compiling to Android, this will take a long while. ECHO Next time run make-desktop.bat if you only want desktop version, ECHO this will be much faster. ) CALL jdm %PROJECT% %MakeAndroid% >javac\general.log cd %PROJECT% ECHO Showing errors if any: type error.log ECHO -- no more errors -- IF %MakeAndroid% == yes ( Set PATH=%JDUMMY%\javac\dx;%PATH% move gamea.jar game.apk ECHO Unpaking default apk-file java -jar %JDUMMY%\javac\dx\apktool.jar d -f %PROJECT%\game.apk >"%JDUMMY%\javac\smal.log" ECHO Renaming app %JDUMMY%\javac\rena.exe %PROJECT%\game\smali\com\jdummy2d %Appname% %JDUMMY%\javac\rena.exe %PROJECT%\game\res\values %Appname% mkdir %PROJECT%\game\temp move %PROJECT%\game\AndroidManifest.xml %PROJECT%\game\temp\AndroidManifest.xml %JDUMMY%\javac\rena.exe %PROJECT%\game\temp %Appname% move %PROJECT%\game\temp\AndroidManifest.xml %PROJECT%\game\AndroidManifest.xml ren %PROJECT%\game\smali\com\jdummy2d %Appname% ECHO Packing back renamed app java -jar %JDUMMY%\javac\dx\apktool.jar b game newgame.apk >"%JDUMMY%\javac\smal.log" del game.apk move newgame.apk game.apk ) ECHO done PAUSE ===================================== Содержимое run-console.bat ===================================== java -jar game.jar (Запуск с консолью может понадобиться для того, чтобы читать отладочные сообщения, выдаваемые командой DEBUG, а также ошибки во время выполнения). ===================================== Содержимое android-install.bat Для установки на устройство либо для подписывания apk-файла, чтобы позже установить на устройство вручную. Здесь используется KEYSTORE - файл хранилища из примера HelloWorld tytyty - это пароли к хранилищу и к ключу (одинаковые). Если вы захотите использовать своё хранилище, вы должны положить его в папку проекта и изменить android-install.bat, вписав имя файла хранилища и пароли ===================================== @ECHO OFF Set PROJECT=C:\jdummy2d\EXAMPLES\HelloWorld Set JDUMMY=C:\jdummy2d Set Appname=HelloJDummy2d ECHO signing... %JDUMMY%\javac\bin\jarsigner -keystore KEYSTORE -storepass tytyty -keypass tytyty %PROJECT%\game.apk key move %PROJECT%\game.apk %PROJECT%\game.zip copy %JDUMMY%\javac\zipalign.exe %PROJECT%\zipalign.exe ECHO veriyfing... zipalign -v 4 game.zip game2.zip move %PROJECT%\game2.zip %PROJECT%\game.apk del game.zip del zipalign.exe ECHO uninstalling from device... CALL %JDUMMY%\javac\adb\adb -d uninstall com.%Appname% ECHO installing to device... CALL %JDUMMY%\javac\adb\adb -d install -r %PROJECT%\game.apk PAUSE ===================================== Содержимое android-uninstall.bat Для удаления вашей игры с устройства ===================================== @ECHO OFF Set PROJECT=C:\jdummy2d\EXAMPLES\HelloWorld Set JDUMMY=C:\jdummy2d Set Appname=HelloJDummy2d ECHO uninstalling from device... CALL %JDUMMY%\javac\adb\adb -d uninstall com.%Appname% PAUSE ===================================== Содержимое clean-project.bat Для удаления всех файлов, которые сгенерировали make-*.bat файлы ===================================== @ECHO OFF ECHO Cleaning project del error.log del game.jar del game.apk rd /s /q game PAUSE ===================================== Содержимое combine.bat описание см. в п.1.4-1 ===================================== @ECHO OFF del %1\main.txt type %1\*.txt >> %1\all move %1\all %1\main.txt