forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Проекты на MidletPascal (http://forum.boolean.name/forumdisplay.php?f=88)
-   -   The Maze (http://forum.boolean.name/showthread.php?t=4621)

cahekp 02.02.2009 01:38

Ответ: The Maze
 
Почитал я эту тему от и до и... Захотелось сделать что-нибудь похожее на Wolfenstein3D. Странно, не правда ли? :)

Вот я вот все мучаюсь, каким же образом сделана эта игра:
http://get.mtscity.ru/free/id.22477/...e.210/game.jar
(Bunker3D)

Все так плавно, гладко... При этом вся проекция 3d мира растянута на весь экран, используются анимированные стены, полустены, анимированные спрайты... Блин, как же у них это так получилось?

В Мидлет Паскале нет аналогов drawRGB случаем? :)
* через некоторое время *
Хм, а если попробовать сделать библиотеку для MP, в которой будет находится метод, тело которого будет вызывать drawRGB?

Так, пойду попробую...

cahekp 03.02.2009 01:14

Ответ: The Maze
 
Вложений: 1
Фух! Только что написал библиотеку, которая работает с ARGB массивом, после чего дает перевести результат в простой Image.
Попробовал слегка переделать наш проект, подключив эту библиотеку...
Ура! Апплет стал работать быстрее раз в 10-20! Скорость стала более-менее порядочной! Больше не тормозит так, как раньше.
Появился шанс на светлое будущее... :)

Так, ребят, а кто-нибудь знает, как реализовать двери? Я вот все понять не могу... Кто сможет написать?

P.S. Данная версия подстроена под экран 176х220.
Если у вас не такой экран, тогда идите в мою библиотеку и изменяйте там параметры width и height (или просто в главной проге переменные w и h замените на 176 и 128 соответственно).

abcdef 03.02.2009 10:07

Ответ: The Maze
 
есть игра catacombs 3D написана перед wolfenshtein 3D, по задумкам интересней... можно подглядеть идеи.
___
анимированные стены это просто смена текстуры, проще всего и оптимальнее делать так:
а) на карте имеется 2 элемента со схожими изображениями проходить всю карту и менять друг на друга.
б) или же рисовать текстуру непосредственно в битовый массив.
___
дверь такой-же элемент стены, только он имеет 2а состояния и анимированный переход между ними

Serg153 03.02.2009 16:42

Ответ: The Maze
 
2cahekp - ммм.. запустил прогу на моторолке - картинка появилась - а при нажатии на любую клавишу - вылетает.. :-(

cahekp 03.02.2009 23:54

Ответ: The Maze
 
Вложений: 1
to Serg153:
Что за телефон? Размер экрана 176х220? Хм... Может, не хватает памяти?
А если попробовать закомментировать строку
" world:=argb_to_image(w,h); drawImage(world,0,0); "
в блоке MAIN LOOP и снова запустить?
Если все-равно не пойдет, то, значит, дело все-таки в памяти.
Если пойдет - дело в выводе изображения (хотя я сомневаюсь, что это так).

Сколько у тебя доступно динамической памяти (Heap) для приложений?

Попробуй выбросить из проекта какие-нибудь ресурсы на 150 кбайт.. Глядишь, пойдет! :)

to abcdef:
По поводу анимации: Ну, думаю, более оптимальный будет, конечно же, первый вариант. Либо мы один массив 64х64 перерисуем, либо кучу текстур точно с таким же размером 64х64...
По поводу двери: Ну, насчет того, что дверь - это такая стена, как и другие... Да еще и просто анимированная... Хм, ну не знаю...

А теперь пошли мои размышления... :)
Как я поглядел, есть две различные реализации дверей - это объемная (как, например, в Бункер3Д) и в виде спрайта, который имеет свою собственную ось вращения (Вольфенштейн3Д).
Я вот, например, совсем не представляю, как можно сделать объемную дверь и считаю, что это еще тот геморрой. Почему? Ну, во первых, надо создать объект, который имеет размер меньше обычных стен (дверь же будет выглядеть не в виде куба, правильно? :)). Это первая заноза: сделать на 2-мерной карте объекты, размеры которых будут меньше стандартных. Дальше - больше. Вот во время открытия двери что делать лучу? Вот он вылетает из нашего глаза и идет по клеткам с числом 0, пока не дойдет до какого-либо препятствия. Дошел он до клетки, скажем, 5. Это клетка, которая означает, что это - дверь. Да дверь то и не простая, а еще и в процессе анимации! И открыта наша дверь наполовину. Нет, пусть лучше будет чуть больше, чем в половину... ;) И что делать лучу? По логике, он каким-то макаром должен понять, именно в ЭТОЙ точке есть кусочек двери, или же тут ничего нет и нужно просто продолжать движение дальше? Для большей ясности смотрите аттач к посту. Это заноза номер два: проблема трассировкой лучей. Более того, а что делать спрайтам, которые находятся позади двери? Как им объяснить, что часть их находится позади двери и должна быть отображена, а часть - нет? Заноза три: проблемы со спрайтами. Хотя, наверно, последний пункт можно выбросить. Если мы сможем правильно заполнить массив ScreenDist, то, по ходу, проблем возникнуть не должно...

Я думаю, что гораздо легче будет создать дверь в виде спрайта. Это полезно, так как помимо дверей, можно будет точно также создать какие-нибудь решетки, стены со сквозными дырками... Да и просто спрайты, которые не будут постоянно поворачиваться в сторону игрока, а будут смотреть только строго туда, куда им указал смотреть разработчик. :)
Спрайтовую дверь будет легко всунуть в любое место, задать ей начальный поворот, двигать... С помощью спрайтов можно будет попробовать создать "битую" дверь, с небольшими сквозными отверстиями. Будет выглядеть круто. :)
Вот только как сделать так, чтобы спрайт имел свою собственную ось?!?? Вот, что меня больше всего мучает!!! :(
Как менять его вид, опираясь на угол зрения игрока? Не понимаю...
Кто сможет это объяснить (а еще лучше: реализовать)?

abcdef 04.02.2009 03:33

Ответ: The Maze
 
насчет дверей :) допустим младший байт на карте будет элемент, а остальные статус и тд. Т.о. у нас появляется место для записи положения. при столкновении луча с дверью находим место столкновения 0...63 и смотрим, если луч попадает в открытую часть - пропустить дальше. чтобы дверь рисовалась тоньше чем обычная стена лучу необходимо шагнуть немножко вглубь. да, и еще лучше разделить элемент карты на 4е элемента и для каждой стороны рисовать свою текстуру.
__
чтобы программа запускалась на motorola нужно освободить место для битового массива, удалив 8 картинок, в таком случае текстуры должны подгружаться по мере надобности

cahekp 04.02.2009 21:47

Ответ: The Maze
 
Хм, интересненько... )
Пойду эксперименты ставить.. )

cahekp 05.02.2009 23:53

Ответ: The Maze
 
Вложений: 1
Мда.. Весь день этой фигней промаялся и вот что сделал:
1. Алгоритм поиска квадратного корня для целых чисел был усовершенствован и теперь работает довольно быстро. :)
2. Карту игра считывает из файла 1.map. Файл имеет читабельный вид и представляет из себя набор символов, которых может быть меньше, чем 64*64 штук.
3. Изменил текстурки. Старые надоели. Пофиг, что новые не блещут качеством, зато они новые!.. :)
4. Еще немножко прооптимизировал игрульку.

НО! Я так до сих пор и не понял, КАК ЖЕ ВСЕ-ТАКИ ПУСТИТЬ ЛУЧ ЧУТЬ ДАЛЬШЕ, ЕСЛИ ОН СТОЛКНУЛСЯ С ДВЕРЬЮ! Точнее, понял, но как только я его начинаю пускать чуть дальше, то начинается ВСЯКАЯ НЕХОРОШАЯ КАЛЯ-БАЛЯ!!! Видимо, математик из меня никакой... :(
Блин, как же все-таки сделать?! Бесит уже! :crazy:

abcdef 06.02.2009 02:28

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

cahekp 06.02.2009 23:14

Ответ: The Maze
 
Хм... Ну что же, буду ждать твоей реализации... :)

А потом буду сравнивать со своей... Хех.

Serg153 07.02.2009 12:21

Ответ: The Maze
 
>>1. Алгоритм поиска квадратного корня для целых чисел был усовершенствован и теперь работает довольно быстро
...ммм - я так понимаю что квадратный корень нужен для определения растояния до пересечения с гориз или верт стеной -
а может отказаться от вычисления корня и использовать разницу квадратов?

abcdef 08.02.2009 00:13

Ответ: The Maze
 
Вложений: 1
переписал версию программы для работы со своей библиотекой RGB-массив. (все исходники упакованны в jar-файл)

для работы на motorola пришлось:
1. закомментировать строки вывода заднего фона
2. уменьшить высоту рисуемого экрана до 64 точек
3. сократить кол-во рисунков до 13 шт. (в дальнейшем прийдется отказаться от спрайтов ракурса)

добавлено:
1. открывающиеся двери по кнопке GA_GAMEA.
2. игрок стреляет огненными шарами, которые убивают солдат или ломают двери.
__
алгоритм работает в 2-3 раза быстрее моей предыдущей версии, но медленно на motorola v3i, необходимо оптимизировать работу с памятью, и лишними вычислениями... неплохо если кто-нить сделает интересную логику противников

Serg153 08.02.2009 06:32

Ответ: The Maze
 
>>неплохо если кто-нить сделает интересную логику противников
я попробую... но...
мне кажется, что пока - Стрелялку на телефоне хорошую незаделать...
чисто изза управления прицелом(игроком) - так как у мобилки нету мыши =)
может на сенсорных экранах чтонить и получится...
а тут - представь, выходит из двери солдат (видит тебя - открывает огонь - и сообразно своему АИ начинает перемещаться(укрываться) от твоих пуль... пока ты стрелочками донажимаешь его в прицел(центр экрана) он тебя раз 20 убьёт...
а если противник будет тупо стоять и время от времени постреливать - то тут уже тебе это быстро надоест...
---
я попробую реализовать 2 алгоритма Противников
- активный поиск(Пока "жизнь" > 10..20, бот будет "искать" игрока и при появлении его в поле видимости открывает огонь...< 10..20 жизни - убегать от игрока
- пассивный - стоит ждёт - пока или игрок не выстрелит рядом(или непокажется в поле зрения) - стреляет - при возможности вправо влево перемещается (рандмоно) - опять стреляет....

abcdef 08.02.2009 11:56

Ответ: The Maze
 
ты прав Serg153 - управление в мобильнике своеобразное...
___
рекомендую скачать досовскую игру catacombs 3d, там простые, но в тоже время хорошо продуманные противники. Для более-менее нормального AI также нужен алгоритм нахождения нахождения кратчайшего расстояния.
___
нужно заменить умножения/деления на логические сдвиги, буду рад любым предложениям по оптимизации в j2me в особенности для motorola.
___
корень квадратный нужен для нахождения дистанции между двумя точками на плоскости (из формулы: квадрат гипотезы равен сумме квадратов катетов)

Serg153 09.02.2009 11:05

Ответ: The Maze
 
>>...по оптимизации в j2me ...
>>..нахождения дистанции...
мммм.. а дистанция нужна для определения какую стену рисовать?
вертикальную или горизонтальную?
к примеру - до ВертСтены по х 3 по у=4, до гориз стены по х=5 у=4
1 -если просто использовать квадраты расстояний 3*3+4*4=25 5*5+4*4= 41
т.е. рисуем вертикальную стену так как она ближе(25<41) - можно и без корня квадратного обойтись
2 - попробовать вообще без Квадратов типа 3+4=7 5+4=9 снова рисуем верт стену т.к. 7<9...
~~~
попробовать оптимизировать кол-во интераций(глубину луча) -
исходно принимаем что макс длина лабиринта = 64 клетки
Но - при про прорисовке на такую длину стена будет в виде 1..2х пикселей...
тут конечно поэксперементировать - но ограничить максимальный перебор стен до 5-10-15... если стена дальше то отрисовать тёмно серой вертикальной полоской(типа в тени)...
и описать ограничение для дизайнера уровней, что максимально большая комната(видимый участок) не больше например 6 клеток, условно:
*******
*
*******
~~~
опять же расстояние до клеток, нужно для определения коэффициента масштаба выводимой стены - попробовать создать таблицу возможных растояний - с коэфициентами (расчитать и считывать из файла заранее или в програме инициализации игры)
например макс видимое поле 10 клеток - значит массив - вернее 2 массива будут размерностью(10+10=20) и [64+64]
то индекс в массиве будет расчитывать [x+y] - это расстояние в Больших клетках - [x1+y1] это координаты игрока в клетке....
и множитель выводимой стены будет равен m1[x+y]+m2[x1+y1]
типа такого?

abcdef 09.02.2009 11:45

Ответ: The Maze
 
Serg153 здесь немножко по другому (надоб разобраться в исходнике),
корень квадратный-вспомогательная функция для сортировки/отрисовки спрайтов,
луч из глаз всегда останавливается при достижении стены и ни когда не должены уходить дальше 64 клеток

cahekp 10.02.2009 20:18

Ответ: The Maze
 
to abcdef:
Класс! Респект тебе! ;)
Интересно получилось, только, вижу, ты так и не вдавил дверь... Не получается? :)
А я ведь не успокоюсь, пока дверь не вдавлю!
Все хожу, шаманю с бубном, брожу вокруг да около... А для чего нужны переменные u и v, а также u1 и v1? Можешь объяснить?

cahekp 03.03.2009 18:48

Ответ: The Maze
 
Вложений: 1
Фух, наконец-то! Десятки бессонных ночей наконец-то дали свои плоды!!
Доделал я все-таки эти двери! :cool:
Итак, что мы имеем:
1. Двери теперь вдавлены внутрь стен наполовину.
2. Двери могут быть полупрозрачными (со сквозными дырками там и т.д.).
3. Все-таки мой алгоритм нахождения квадратного корня для целых чисел почти в 2 раза быстрее твоего, abcdef! Сам на эмуляторе проверял. А потом и на телефоне. Вот. :cool:

Serg153, Что там с AI солдат? Ходют они у тебя уже или все еще нет?

ASMjavaC 09.03.2009 12:24

Ответ: The Maze
 
Вложений: 2
я так понял это все не 3д (не jsr184) а так сказать проекция 3д на 2д плоскость

не бейте но алгоритм текстур не идеален (см. ниже)
неая пилообразность.

jimon 09.03.2009 13:00

Ответ: The Maze
 
ASMjavaC
любое 3д это проекция 3д координат на 2д плоскость

impersonalis 09.03.2009 15:24

Ответ: The Maze
 
юзать сглаживание?

ASMjavaC 09.03.2009 15:55

Ответ: The Maze
 
jimon
да извеняюсь не та и не о том спросил...
меня интересует jsr184-почему его не используют (я так понял это помогает 3д какраз спректировать на 2д чтобы не замарачиваться)
а тут я смотрю делают "движки" и "отображения 3д-2д"

impersonalis вы про пилообоазность? не вдавался в подробности но помойму "немного неправильный" алгоритм текстур

cahekp 09.03.2009 17:03

Ответ: The Maze
 
to ASMjavaC:
>я так понял это все не 3д (не jsr184) а так сказать проекция 3д на 2д >плоскость
Ну да. Это все рэйкастинг.

>не бейте но алгоритм текстур не идеален (см. ниже)
>неая пилообразность.

Да, знаю. А сделать ничего не могу. Не понимаю я, в чем причина! :dontknow:

>меня интересует jsr184-почему его не используют
Насколько я знаю, MIDletPascal не позволяет использовать jsr184.
Да и зачем? Jsr184 тут нафиг не нужен и "true-3d" в играх этого типа никогда не используется. Да и по ходу, в данном случае рэйкастинг будет работать быстрее аналогичной игры, но построенной на jsr184. Вот. :cool:

to impersonalis:
> юзать сглаживание?
Не нужно. Здесь надо просто подкорректировать вывод текселей на экран.

ASMjavaC 09.03.2009 17:28

Ответ: The Maze
 
Да и зачем? Jsr184 тут нафиг не нужен и "true-3d" в играх этого типа никогда не используется.Да и зачем? Jsr184 тут нафиг не нужен и "true-3d" в играх этого типа никогда не используется.
Согласен.. даже игры переделаные на дос намного меньше весили и намного быстрее (хотя графика оставляла желать лучшего)
но для мобилы это актуально все понял.
(хм а смысл jsr184 в чом)

cahekp 09.03.2009 18:33

Ответ: The Maze
 
to ASMjavaC:
> (хм а смысл jsr184 в чом)
Во всем, кроме FPS игр. Я так думаю. :)
Jsr-184 пригодился бы, ну например, в создании гонок. Или космического симулятора. А можно еще и какой-нибудь квест в стиле Alone In The Dark забабахать! Ну и т.д.:)

cahekp 09.03.2009 18:36

Ответ: The Maze
 
ASMjavaC, impersonalis, jimon, поможете в написании этой проги? Людей очень не хватает! :)

abcdef 09.03.2009 19:29

Ответ: The Maze
 
Вложений: 1
хорошо сделал двери cahekp! вижу разобрался в алгоритме.
___
Выкладываю с изменениями алгоритма:
теперь карта - одномерный массив,
убрал некоторые лишние вычиления,
вернул разрешение к 176x132 (работает на motorola V3i и др.)
реализовал свое решение, отрисовки дверей.
____
Что нужно:
выявить медленные участки кода и оптимизировать их.
квадратный корень ищется 50 раз за игровой цикл (но все-таки это кандидат на оптимизацию... не использовал твой алгоритм нахождения кв.корня, потому что программа висла.), даже если полностью исключить подпрограмму отрисовки спрайтов, то прирост скорости ~60%.
____
p.s. занимаюсь этим проектом для отдыха после работы, народ будет предлогать свои решения буду поддерживать его...

cahekp 09.03.2009 21:46

Ответ: The Maze
 
to abcdef:
> не использовал твой алгоритм нахождения кв.корня, потому что программа висла.
Да, было такое дело. :) Добавил дополнительное условие и перестало виснуть. Совсем.

ASMjavaC 09.03.2009 22:08

Ответ: The Maze
 
поможете в написании этой проги
тут много "написано" всмысле измененных исходников..
я человек медленный и считаю что алгоритм arT необходимо как следует осмыслить потестить на ошибки.. впринципе тоесть необходимы еще движки.. чтобы в итоге сделать самый самый.. (думаю поняли), а так если чем могу помогу

ASMjavaC 09.03.2009 22:28

Ответ: The Maze
 
abcdef
сейчас заметил или было так, но прицел сбит - огонь пускается на 10 пикселов в лево\право

abcdef 10.03.2009 14:53

Ответ: The Maze
 
cahekp - проверил твой кв.корень с дополнительной проверкой цикла - вроде не виснет, переработанный алгоритм находится в выложенном архиве, дополни выход из цикла: ... until (m=n) or (n=m+1)
___
про "прицел" не знаю... а вот насчет полета шара - то здесь накладываются погрешности вычислении при полете, а кроме того игрок поворачивается за раз на 4 градуса

cahekp 11.03.2009 13:11

Ответ: The Maze
 
Вложений: 1
to ASMjavaC:
По поводу пилообразности... Текстуры кладутся правильно. Пилообразность - это погрешность в целочисленных вычислениях.
Она образуется из-за того, что во время текстуризации столбика шаг приращения не может принимать дробные значения. Из-за этого возникают вот такие вот "эффекты".
Так вот, чтобы не переводить шаг в вещественный тип (а вещественные числа очень медленные в вычислениях), мы пытаемся избавиться от этой погрешности, умножая шаг на 512, а во время определения цвета точки - деля его на 512.
Так вот, если шаг умножать не на 512, а, например, на 4096, то пилообразность практически полностью исчезает.
...
coof:=(63*4096) div hh;
...
setp(n, data[elem,TxLine+(yo div 4096)*64]);
...

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

ASMjavaC 12.03.2009 10:35

Ответ: The Maze
 
тут говорили о проблеме убийства "проворных" врагов
предлагаю управление (дополнительное по цифровой клаве):
1 - движение вперед с поворотом влево + огонь
2 - движение вперед + огонь
3 - движение вперед с поворотом вправо + огонь
4 - движение боком влево + огонь
5 - (наверно просто огонь стоя или поворот на 180 градусов)
6 - движение боком вправо + огонь
7 - движение назад с поворотом влево + огонь
8 - движение назад + огонь
9 - движение назад с поворотом вправо + огонь

еще остается * 0 # для них можно в будущем сменить оружие, включить фонарик, бросить гранату или еще чтонибудь другое

cahekp 12.03.2009 13:21

Ответ: The Maze
 
to ASMjavaC: На мобильнике нельзя нажимать более, чем одну клавишу. "Движение вперед с поворотом влево + огонь" выполнить не получится.

ASMjavaC 15.03.2009 14:28

Ответ: The Maze
 
cahekp
Цитата:

1 - движение вперед с поворотом влево + огонь
это означает что при нажатии на циферку 1 будет происходить движение вперед с поворотом влемо и притом еще и стрелять или опять не понятно?

KAK? TAK! 30.03.2009 11:20

Ответ: The Maze
 
тогда игра еще больше будет тормозить

abcdef 30.03.2009 13:51

Ответ: The Maze
 
это вообще ни как не скажется на скорости... просто непривычно как-то

KAK? TAK! 30.03.2009 17:13

Ответ: The Maze
 
ну незнаю производительность зашкаливать будет

WISHMASTER35 02.04.2009 19:20

Ответ: The Maze
 
Интересный проэкт. Но тормозит на моём к610й. Может его лучше было бы сделать на нормальной j2me?

KAK? TAK! 02.04.2009 19:31

Ответ: The Maze
 
не нужно просто не использовать бмп

WISHMASTER35 03.04.2009 00:14

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

Phantom 03.04.2009 04:32

Ответ: The Maze
 
KAK? TAK!, от формата изображений совершенно ничего не зависит. Разве что загрузка одних может быть медленнее, чем загрузка других на тысячные доли секунды, но когда изображения уже в памяти - разницы никакой.

KAK? TAK! 03.04.2009 13:05

Ответ: The Maze
 
все равно

scorey 05.04.2009 16:40

Ответ: The Maze
 
Вложений: 1
Я нашёл исходники всех фалов .class из игры Bunker3D на Java
Посмотрите!
вот архив
и сама игра

scorey 05.04.2009 16:45

Ответ: The Maze
 
Вложений: 1
-------

abcdef 11.04.2009 15:54

Ответ: The Maze
 
если это исходники... - то можно с уверенностью сказать, что все компилированные java-программы идут в исходных кодах :)

Romanzes 04.05.2009 20:23

Ответ: The Maze
 
IronWoodCutter (abcdef), ты вроде переделывал как-то мидлетпаскалевский математический класс, чтобы методы назывались по-нормальному. Вот сегодня я лазил по инету в поисках реализации квадратного корня в fixed-point, и наткнулся на вот это: http://home.comcast.net/~ohommes/MathFP/ . Я с удивлением обнаружил, что это полная копия F.class, но с понятными названиями методов! Очень полезная вещь.

abcdef 05.05.2009 10:47

Ответ: The Maze
 
да, это практически F.class, только в MidletPascal'e он немножко расширен, а в моей переделке немножко оптимизирован

DIMMON4IK 02.08.2009 17:58

К Cliffe Snake
--------------
А ты можеш к своёму варианту прикрутить карту в txt, двери и немцев? Стрельба необязательная.
ОЧЕНЬ НАДО:).
НА СПАСИБО НЕ ЖАДНЫЙ!!!

Cliffe Snake 06.08.2009 01:12

Ответ: The Maze
 
Карту в txt без проблем, а двери и немцев, хз.

DIMMON4IK 07.08.2009 14:02

Карту плиз!!!:)

abcdef 12.08.2009 11:46

Ответ: The Maze
 
Если кому интересно - нашел в "Советы по Delphi от Валентена Озерова 1-1000" алгоритм вычислений с произвольной величиной (можно адаптировать на MP в алгоритм с фиксированной точкой для больших величин), вот текст статьи:
____
Огромные числа
Данный модуль использует массив байт для предоставления БОЛЬШИХ чисел. Бинарно-хранимые числа заключены в массив, где первый элемент является Наименьшим Значимым Байтом (Least Significant Byte - LSB), последний - Наибольшим Значимым Байтом (Most Significant Byte - MSB), подобно всем Intel-целочисленным типам.
Арифметика здесь использует не 10- или 2-тиричную, а 256-тиричную систему исчисления, чтобы каждый байт представлял одну (1) цифру.

Числа HugeInttype - Подписанные Числа (Signed Numbers).

При компиляции с директивой R+, ADD и MUL могут в определенных обстоятельствах генерировать "Arithmetic Overflow Error" (RunError(215)) - ошибка арифметического переполнения. В таком случае пользуйтесь переменной "HugeIntCarry".

Переменная "HugeIntDiv0" используется для проверки деления на ноль.

Используйте {$DEFINE HugeInt_xx } или поле "Conditional defines" (символ условного компилирования) в "Compiler options" (опции компилятора) для задания размерности, где xx должно быть равно 64, 32 или 16, в противном случае HugeIntSize будет равен 8 байтам.
Код:

unit HugeInts;
interface

const
{$IFDEF HugeInt_64 }

HugeIntSize = 64;

{$ELSE}{$IFDEF HugeInt_32 }

HugeIntSize = 32;
{$ELSE}{$IFDEF HugeInt_16 }

HugeIntSize = 16;
{$ELSE}

HugeIntSize = 8;
{$ENDIF}{$ENDIF}{$ENDIF}

HugeIntMSB  = HugeIntSize-1;

type

HugeInt = array[0..HugeIntMSB] of Byte;

const

HugeIntCarry: Boolean = False;
HugeIntDiv0:  Boolean = False;


procedure HugeInt_Min(var a: HugeInt);                { a := -a }
procedure HugeInt_Inc(var a: HugeInt);                { a := a + 1 }
procedure HugeInt_Dec(var a: HugeInt);                { a := a - 1 }

procedure HugeInt_Add(a, b: HugeInt; var R: HugeInt);  { R := a + b }
procedure HugeInt_Sub(a, b: HugeInt; var R: HugeInt);  { R := a - b }
procedure HugeInt_Mul(a, b: HugeInt; var R: HugeInt);  { R := a * b }
procedure HugeInt_Div(a, b: HugeInt; var R: HugeInt);  { R := a div b }
procedure HugeInt_Mod(a, b: HugeInt; var R: HugeInt);  { R := a mod b }

function HugeInt_IsNeg(a: HugeInt): Boolean;
function HugeInt_Zero(a: HugeInt): Boolean;
function HugeInt_Odd(a: HugeInt): Boolean;

function HugeInt_Comp(a, b: HugeInt): Integer;          {-1:a< 0; 1:a>}
procedure HugeInt_Copy(Src: HugeInt; var Dest: HugeInt);{ Dest := Src }

procedure String2HugeInt(AString: string; var a: HugeInt);
procedure Integer2HugeInt(AInteger: Integer; var a: HugeInt);
procedure HugeInt2String(a: HugeInt; var S: string);


implementation

procedure HugeInt_Copy(Src: HugeInt; var Dest: HugeInt);
{ Dest := Src }
begin

Move(Src, Dest, SizeOf(HugeInt));
end;{ HugeInt_Copy }

function HugeInt_IsNeg(a: HugeInt): Boolean;
begin

HugeInt_IsNeg := a[HugeIntMSB] and $80 > 0;
end;{ HugeInt_IsNeg }

function HugeInt_Zero(a: HugeInt): Boolean;
var i: Integer;
begin

HugeInt_Zero := False;
for i := 0 to HugeIntMSB do
if a[i] <> 0 then Exit;
HugeInt_Zero := True;
end;{ HugeInt_Zero }

function HugeInt_Odd(a: HugeInt): Boolean;
begin

HugeInt_Odd := a[0] and 1 > 0;
end;{ HugeInt_Odd }

function HugeInt_HCD(a: HugeInt): Integer;
var i: Integer;
begin

i := HugeIntMSB;
while (i > 0) and (a[i] = 0) do Dec(i);
HugeInt_HCD := i;
end;{ HugeInt_HCD }

procedure HugeInt_SHL(var a: HugeInt; Digits: Integer);
{ Перемещение байтов переменной "Digits" в левую часть,

байты "Digits" будут 'ослабевать' в MSB-части.
LSB-часть заполняется нулями. }
var t: Integer;
b: HugeInt;
begin

if Digits > HugeIntMSB then
FillChar(a, SizeOf(HugeInt), 0)
else if Digits > 0 then
begin
Move(a[0], a[Digits], HugeIntSize-Digits);
FillChar(a[0], Digits, 0);
end;{ else if }
end;{ HugeInt_SHL }

procedure HugeInt_SHR(var a: HugeInt; Digits: Integer);
var t: Integer;
begin

if Digits > HugeIntMSB then
FillChar(a, SizeOf(HugeInt), 0)
else if Digits > 0 then
begin
Move(a[Digits], a[0], HugeIntSize-Digits);
FillChar(a[HugeIntSize-Digits], Digits, 0);
end;{ else if }
end;{ HugeInt_SHR }

procedure HugeInt_Inc(var a: HugeInt);
{ a := a + 1 }
var

i: Integer;
h: Word;
begin

i := 0; h := 1;
repeat
h := h + a[i];
a[i] := Lo(h);
h := Hi(h);
Inc(i);
until (i > HugeIntMSB) or (h = 0);
HugeIntCarry := h > 0;
{$IFOPT R+ }
if HugeIntCarry then RunError(215);
{$ENDIF}
end;{ HugeInt_Inc }

procedure HugeInt_Dec(var a: HugeInt);
{ a := a - 1 }
var Minus_1: HugeInt;
begin

{ самый простой способ }
FillChar(Minus_1, SizeOf(HugeInt), $FF); { -1 }
HugeInt_Add(a, Minus_1, a);
end;{ HugeInt_Dec }

procedure HugeInt_Min(var a: HugeInt);
{ a := -a }
var i: Integer;
begin

for i := 0 to HugeIntMSB do
a[i] := not a[i];
HugeInt_Inc(a);
end;{ HugeInt_Min }

function HugeInt_Comp(a, b: HugeInt): Integer;
{ a = b: ==0; a > b: ==1; a < b: ==-1 }
var

A_IsNeg, B_IsNeg: Boolean;
i:                Integer;
begin

A_IsNeg := HugeInt_IsNeg(a);
B_IsNeg := HugeInt_IsNeg(b);
if A_IsNeg xor B_IsNeg then
if A_IsNeg then HugeInt_Comp := -1
else HugeInt_Comp := 1
else
begin
if A_IsNeg then HugeInt_Min(a);
if B_IsNeg then HugeInt_Min(b);
i := HugeIntMSB;
while (i > 0) and (a[i] = b[i]) do Dec(i);
if A_IsNeg then { оба отрицательные! }
if a[i] > b[i] then HugeInt_Comp := -1
else if a[i] < b[i] then HugeInt_Comp := 1
else HugeInt_Comp := 0
else { оба положительные }
if a[i] > b[i] then HugeInt_Comp := 1
else if a[i] < b[i] then HugeInt_Comp := -1
else HugeInt_Comp := 0;
end;{ else }
end;{ HugeInt_Comp }

procedure HugeInt_Add(a, b: HugeInt; var R: HugeInt);
{ R := a + b }
var

i: Integer;
h: Word;
begin

h := 0;
for i := 0 to HugeIntMSB do
begin
h := h + a[i] + b[i];
R[i] := Lo(h);
h := Hi(h);
end;{ for }
HugeIntCarry := h > 0;
{$IFOPT R+ }
if HugeIntCarry then RunError(215);
{$ENDIF}
end;{ HugeInt_Add }

procedure HugeInt_Sub(a, b: HugeInt; var R: HugeInt);
{ R := a - b }
var

i: Integer;
h: Word;
begin

HugeInt_Min(b);
HugeInt_Add(a, b, R);
end;{ HugeInt_Sub }

procedure HugeInt_Mul(a, b: HugeInt; var R: HugeInt);
{ R := a * b }
var

i, j, k:          Integer;
A_end, B_end:    Integer;
A_IsNeg, B_IsNeg: Boolean;
h:                Word;
begin

A_IsNeg := HugeInt_IsNeg(a);
B_IsNeg := HugeInt_IsNeg(b);
if A_IsNeg then HugeInt_Min(a);
if B_IsNeg then HugeInt_Min(b);
A_End := HugeInt_HCD(a);
B_End := HugeInt_HCD(b);
FillChar(R, SizeOf(R), 0);
HugeIntCarry := False;
for i := 0 to A_end do
begin
h := 0;
for j:= 0 to B_end do
if (i + j) < HugeIntSize then
begin
h := h + R[i+j] + a[i] * b[j];
R[i+j] := Lo(h);
h := Hi(h);
end;{ if }
k := i + B_End + 1;
while (k < HugeIntSize) and (h > 0) do
begin
h := h + R[k];
R[k] := Lo(h);
h := Hi(h);
Inc(k);
end;{ while }
HugeIntCarry := h > 0;
{$IFOPT R+}
if HugeIntCarry then RunError(215);
{$ENDIF}
end;{ for }
{ если все хорошо... }
if A_IsNeg xor B_IsNeg then HugeInt_Min(R);
end;{ HugeInt_Mul }

procedure HugeInt_DivMod(var a: HugeInt; b: HugeInt; var R: HugeInt);
{ R := a div b  a := a mod b }
var

MaxShifts, s, q:  Integer;
d, e:            HugeInt;
A_IsNeg, B_IsNeg: Boolean;
begin

if HugeInt_Zero(b) then
begin
HugeIntDiv0 := True;
Exit;
end{ if }
else HugeIntDiv0 := False;
A_IsNeg := HugeInt_IsNeg(a);
B_IsNeg := HugeInt_IsNeg(b);
if A_IsNeg then HugeInt_Min(a);
if B_IsNeg then HugeInt_Min(b);
if HugeInt_Comp(a, b) < 0 then
{ a<b; нет необходимости деления }
FillChar(R, SizeOf(R), 0)
else
begin
FillChar(R, SizeOf(R), 0);
repeat
Move(b, d, SizeOf(HugeInt));
{ сначала вычисляем количество перемещений (сдвигов) }
MaxShifts := HugeInt_HCD(a) - HugeInt_HCD(b);
s := 0;
while (s <= MaxShifts) and (HugeInt_Comp(a, d) >= 0) do
begin
Inc(s);
HugeInt_SHL(d, 1);
end;{ while }
Dec(s);
{ Создаем новую копию b }
Move(b, d, SizeOf(HugeInt));
{ Перемещаем (сдвигаем) d }
HugeInt_ShL(d, S);
{ Для добавление используем e = -d, это быстрее чем вычитание d }
Move(d, e, SizeOf(HugeInt));
HugeInt_Min(e);
Q := 0;
{ пока a >= d вычисляем a := a+-d и приращиваем Q}
while HugeInt_Comp(a, d) >= 0 do
begin
HugeInt_Add(a, e, a);
Inc(Q);
end;{ while }
{ Упс!, слишком много вычитаний; коррекция }
if HugeInt_IsNeg(a) then
begin
HugeInt_Add(a, d, a);
Dec(Q);
end;{ if }
HugeInt_SHL(R, 1);
R[0] := Q;
until HugeInt_Comp(a, b) < 0;
if A_IsNeg xor B_IsNeg then HugeInt_Min(R);
end;{ else }
end;{ HugeInt_Div }

procedure HugeInt_DivMod100(var a: HugeInt; var R: Integer);
{ 256-тиричное деление - работает только с

положительными числами: R := a mod 100; a:= a div 100; }
var

Q: HugeInt;
S: Integer;
begin

R := 0; FillChar(Q, SizeOf(Q), 0);
S := HugeInt_HCD(a);
repeat
r := 256*R + a[S];
HugeInt_SHL(Q, 1);
Q[0] := R div 100;
R := R mod 100;
Dec(S);
until S < 0;
Move(Q, a, SizeOf(Q));
end;{ HugeInt_DivMod100 }

procedure HugeInt_Div(a, b: HugeInt; var R: HugeInt);
begin

HugeInt_DivMod(a, b, R);
end;{ HugeInt_Div }

procedure HugeInt_Mod(a, b: HugeInt; var R: HugeInt);
begin

HugeInt_DivMod(a, b, R);
Move(a, R, SizeOf(HugeInt));
end;{ HugeInt_Mod }

procedure HugeInt2String(a: HugeInt; var S: string);

function Str100(i: Integer): string;
begin
Str100 := Chr(i div 10 + Ord('0')) + Chr(i mod 10 + Ord('0'));
end;{ Str100 }
var

R:      Integer;
Is_Neg: Boolean;
begin

S := '';
Is_Neg := HugeInt_IsNeg(a);
if Is_Neg then HugeInt_Min(a);
repeat
HugeInt_DivMod100(a, R);
Insert(Str100(R), S, 1);
until HugeInt_Zero(a) or (Length(S) = 254);
while (Length(S) > 1) and (S[1] = '0') do Delete(S, 1, 1);
if Is_Neg then Insert('-', S, 1);
end;{ HugeInt2String }

procedure String_DivMod256(var S: string; var R: Integer);
{ 10(00)-тиричное деление - работает только с

положительными числами: R := S mod 256; S := S div 256 }
var Q: string;
begin

FillChar(Q, SizeOf(Q), 0);
R := 0;
while S <> '' do
begin
R := 10*R + Ord(S[1]) - Ord('0'); Delete(S, 1, 1);
Q := Q + Chr(R div 256 + Ord('0'));
R := R  mod 256;
end;{ while }
while (Q <> '') and (Q[1] = '0') do Delete(Q, 1, 1);
S := Q;
end;{ String_DivMod256 }

procedure String2HugeInt(AString: string; var a: HugeInt);
var

i, h:  Integer;
Is_Neg: Boolean;
begin

if AString = '' then AString := '0';
Is_Neg := AString[1] = '-';
if Is_Neg then Delete(Astring, 1, 1);
i := 0;
while (AString <> '') and (i <= HugeIntMSB) do
begin
String_DivMod256(AString, h);
a[i] := h;
Inc(i);
end;{ while }
if Is_Neg then HugeInt_Min(a);
end;{ String2HugeInt }

procedure Integer2HugeInt(AInteger: Integer; var a: HugeInt);
var Is_Neg: Boolean;
begin

Is_Neg := AInteger < 0;
if Is_Neg then AInteger := -AInteger;
FillChar(a, SizeOf(HugeInt), 0);
Move(AInteger, a, SizeOf(Integer));
if Is_Neg then HugeInt_Min(a);
end;{ Integer2HugeInt }

end.


DIMMON4IK 23.09.2009 18:17

Ответ: The Maze
 
Есть пару вопросов:
1.Как "подвинуть" спрайт напр. №2 на 1 по Х или Y?
2.Как сделать ещё один или два вида спрайтов (тоесть чтобы были не такие с виду)?

Очень надо!

abcdef 26.09.2009 19:32

Ответ: The Maze
 
летающие шары это двигающиеся спрайты...

я вроде полностью разжевал весь код для создания полноценной игры

Cliffe Snake 17.10.2009 15:40

Ответ: The Maze
 
Вложений: 1
Цитата:

Сообщение от DIMMON4IK (Сообщение 113312)
Карту плиз!!!:)

Вот с опозданием, но почти игра.. выкладываю как есть.
Реализовано:
Загрузка карты с файла, расстановка точек старта и перехода.
Незаметная для глаза смена карт, их подгрузку видно только если включить радар.
Сделал 2 карты из планировавшихся 5-ти. Так же хочу сделать редактор карт.
Формат карты:
1я строка: ШиринахВысота
Далее сама карта, пока только 0-9 (т.е. 10 текстур)
"S" - точки старта. "Е" - точки перехода/телепорта/выхода
после карты идут строки с описанием точек старта(откуда пришли на эту карту)
потом любая строка, после которой следуют описания точек перехода(при попадании на точку куда перейти).
в конце файла-карты должен быть хотябы 1 перевод строки (Капризы МП).
Перемещения методом телепорта в пределах одной карты ещё нет.
Чтобы включить радар введите имя "Radar".

cherepets 18.10.2009 23:30

Ответ: The Maze
 
убойно... исходник боюсь открывать...

WISHMASTER35 21.10.2009 19:32

Ответ: The Maze
 
красиво, но очень тормазит.

Sand 25.12.2009 17:11

Ответ: The Maze
 
парни если проект еще в стадии развития могу подкинуть ресурсы оружия! Если что ася 440448075

IvanNes 15.06.2010 05:56

Ответ: The Maze
 
Подскажите народ, как в этом двиге поставить спрайт оружия?(ну как на всех fps-шутерах) А то хочу попробовать Duke Nukem 3d mobile сделать....

psih1 15.06.2010 07:59

Ответ: The Maze
 
Он тормозит на телефонах жесть как врятле получится

cherepets 15.06.2010 09:05

Ответ: The Maze
 
ну, на моих не тормозит...

IvanNes 15.06.2010 09:58

Ответ: The Maze
 
Ну и так-то r3d для меня слишком сложен...
Возьмусь-ка я за maze3d....)

Igor 15.06.2010 12:24

Ответ: The Maze
 
Исходник на удивление маленький. Респект!

psih1 15.06.2010 13:29

Ответ: The Maze
 
Вложений: 1
Вот ресурсы оружия
Для начала хватит


Часовой пояс GMT +4, время: 06:24.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot