|
07.12.2008, 16:42
|
#46
|
Троллота
Регистрация: 09.07.2007
Сообщений: 1,829
Написано 554 полезных сообщений (для 1,772 пользователей)
|
Ответ: The Maze
Товарищи, а где можно популярно и доходчиво почитать про ray-casting? Все никак не могу с ним разобраться
|
(Offline)
|
|
07.12.2008, 18:15
|
#47
|
Разработчик
Регистрация: 06.04.2008
Сообщений: 541
Написано 196 полезных сообщений (для 638 пользователей)
|
Ответ: The Maze
Вот, если кто хочет, покурите исходники оригинального Wolfenstein 3D. Сам я в них разобраться не могу, потому что пока не знаю C++. А я пока займусь переносом двига от abcdef на java. Все-таки я считаю, что нужно юзать png картинки, а не bmp.
|
(Offline)
|
|
07.12.2008, 19:28
|
#48
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: The Maze
Romanzes - в принципе без разницы в каком формате картинки. Помнится что jar-файл поворота картинки был даже больше, чем версия на паскале. Это все из-за файла Gordon.png - он плохо сжимался. А bmp из-за малой палитры лучше упаковывался. Все-таки лучше оставить bmp, потому что с ним легче работать и после загрузки картинок (безразлично в каком формате) остаются только массивы пикселов.
___
Cliffe Snake - текстурирование пола и потолка в 2 раза понизит скорость программы, но есть способ зарисовки удаленным задним фоном зданий/гор/неба, (когда-то придумывал, но он будет работать только c drawRG ,состоит в том что: в массив экрана вводим другой массив со смешением позиции: остаток от деления угола зрения на ширину экрана, таким образом получаем плавную прокрутку заднего фона.. смотрится довольно эффективно,..
___
Посмотрел "в закромах" нашел алгоритм, который когда-то делал для расчетов и рисования спрайтов. Выкладываю чтоб не изобретали велосипед. Возможно где-нибудь будет неточности, переписывал не проверяя..
___
function intSqrt(v : integer) : integer;
{Вычисление квадратного корня}
var
result, tmp : integer;
low, high : integer;
i : integer;
begin
if (v > 1) then
begin
low := v;
high := 0;
result := 0;
for i := 0 to 15 do
begin
result := result+result;
high := (high shl 2) or ((low shr 30) and $03);
low := low shl 2;
tmp := result+result+1;
if (high >= tmp) then
begin
inc(result);
high := high-tmp;
end;
end;
if (v-(result*result) >= (result - 1)) then inc(result);
intSqrt := result;
end
else intSqrt := abs(v);
end;
procedure sprites;
const
scalNum = 7000; {масштабный коофициент для спрайтов}
var
sp : tSprite;
dx,dy,rx,ry : integer;
i,j,scale,r,ycent, xcent : integer;
var {- Рисование линии заданной высоты: с y1 до y2 -}
yyy,y1,y2,offs,coof,yo,imgOffs,color : Integer;
begin
ycent := screenHeight shr 1;
xcent := screenWidth shr 1;
for i := 0 to MaxSprites-1 do
begin
{Найдем расстояние до спрайта}
dx := sprite[i].x - px;
dy := sprite[i].y - py;
sprite[i].dist :=intSqrt(dx*dx+dy*dy); {Определение расстояния между двумя точками}
{Расчет луча для центра спрайта}
rx := trunc(dx*costab[angle] + dy*sintab[angle]); {Поворачиваем dx,dy на}
ry := trunc(dy*costab[angle] - dx*sintab[angle]); {угол зрения игрока}
if (rx < 0) then sprite[i].ray :=-1000 {спрайт вне зоны видимости}
else
begin {Расчет луча для центра спрайта}
if (rx > 0) then ray := xcent + trunc((xcent*ry)/(rx*tan30))
else ray := xcent + trunc((xcent*ry)/tan30);
{найдем положение спрайта относительно нас}
if (abs(dx) >= abs(dy)) then
begin
if dx > 0 then
begin
if dy > 0 then Racurs := 0
else Racurs := 7;
end else
begin
if dy > 0 then Racurs := 3
else Racurs := 4;
end;
end
else
begin
if dx > 0 then
begin
if dy > 0 then Racurs := 1
else Racurs := 6;
end else
begin
if dy > 0 then Racurs := 2
else Racurs := 5;
end;
end;
end;
end;
{Сортировка спрайтов по удаленности}
for i := 0 to MaxSprites-1-1 do
for j := i+1 to MaxSprites-1 do
if sprite[i].dist < sprite[j].dist then
begin
sp := sprite[i]; sprite[i] := sprite[j]; sprite[j] := sp;
end;
{логика работы и вывод спрайтов на экран}
for i :=0 to MaxSprites-1 do
begin
{logic}
анимация-высчитываем номер картинки: imgOffs := номер_картинки*64*64
где (64*64 - размер одной картинки)
.....
{logic-end}
{outToScreen}
{Вывод спрайтов на экран если они попадают в зону видимости}
scale := scalNum div (sprite[i].dist+1); {масштаб изображения}
r := sprite[i].ray - (scale shr 1); {по обе стороны от середины}
for j := 1 to scale do
begin
if (r>=0) and (r<=screenWidth-1) then {если попадаем в экран и}
if (scale>screenDist[r]) then {если ближе чем стена, то вывести}
begin
{---------------------- Текстурирование линии ----------------------}
offs := imgOffs + ((j shl 6) div scale);
y1 := (screenHeight-scale) shr 1;
y2 := y1+scale;
if y2 > screenHeight-1 then y2 := screenHeight-1;
coof := (63*256) div scale;
yo := 0;
for yyy := y1 to y2 do
begin
if yyy >= 0 then
begin
color := data[offs+((yo shr 8) shl 6)];
if color <> 0 then begin setColor(...); plot(r,yyy); end;
end;
inc(yo, coof);
end;
{-------------------------------------------------------------------}
end;
inc(r); {следующий луч}
end;
{outToScreen-end}
end;
end;
|
(Offline)
|
|
08.12.2008, 15:48
|
#49
|
Нуждающийся
Регистрация: 22.09.2008
Сообщений: 74
Написано 8 полезных сообщений (для 12 пользователей)
|
Ответ: The Maze
Вот подкрутил радарчик, исправил текстуры, добавил небо. Полный список изменений смотрите в ReadMe.txt
|
(Offline)
|
|
08.12.2008, 21:25
|
#50
|
Разработчик
Регистрация: 06.04.2008
Сообщений: 541
Написано 196 полезных сообщений (для 638 пользователей)
|
Ответ: The Maze
Сообщение от Tadeus
Товарищи, а где можно популярно и доходчиво почитать про ray-casting? Все никак не могу с ним разобраться
|
Только что нашел туториал по рэй-кастингу на английском языке: http://www.permadi.com/tutorial/raycast/. Сейчас буду разбираться.
|
(Offline)
|
|
09.12.2008, 00:59
|
#51
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: The Maze
Cliffe Snake - да,да задний фон примерно так как ты сделал.. но немножко упростил, выглядит так:
drawimage(sky,-((angle+angle) mod 360),0);
drawImage(floor,0,h2);
raycast;
картинка sky высотой в пол-экрана (64). и длинной 360+ширина_экрана, где кусочек 360..360+ширина_экрана совпадает с изображением в позиции 0..ширина_экрана.
___
Оч. неудобно что MIDletPascal не хочет делать длинные массивы, правильная идея сделать двухмерный но думаю на java быстрее будет делать одномерным..
___
переделал программку с учетом предложений Cliffe Snake
___
давайте для оптимальности будем делать так:
1. вычисления real заменять Lib_mathmp.class.
2. картинки желательно в bmp-формате, и при необходимости png, другие форматы лучше не использовать т.к. не все телефоны их будут поддерживать.
3. карты записывать в текстовом виде, где кубик стены записывается числом, здесь же будем описывать спрайты.
|
(Offline)
|
|
09.12.2008, 04:43
|
#52
|
Нуждающийся
Регистрация: 22.09.2008
Сообщений: 74
Написано 8 полезных сообщений (для 12 пользователей)
|
Ответ: The Maze
Сообщение от abcdef
Cliffe Snake - да,да задний фон примерно так как ты сделал.. но немножко упростил, выглядит так:
drawimage(sky,-((angle+angle) mod 360),0);
drawImage(floor,0,h2);
raycast;
картинка sky высотой в пол-экрана (64). и длинной 360+ширина_экрана, где кусочек 360..360+ширина_экрана совпадает с изображением в позиции 0..ширина_экрана.
|
При такой реализации на экране 240x320 изображение смазывается.
Мой способ отображения "неба" более универсален, так как не зависит от размера экрана. :p
|
(Offline)
|
|
09.12.2008, 09:33
|
#53
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: The Maze
длина картинки заднего фона расчитывается так: угол обзора 60 градусов, равны ширине экрана, значит всего этих экранов будет 6 плюс добавочный, получается длина_картинки = ширина_экрана*7.
запускал на motorola V3i повисло, пришлось уменьшить data [0..6,0..4096] of integer;
|
(Offline)
|
|
09.12.2008, 17:54
|
#54
|
Нуждающийся
Регистрация: 22.09.2008
Сообщений: 74
Написано 8 полезных сообщений (для 12 пользователей)
|
Ответ: The Maze
Сообщение от abcdef
длина картинки заднего фона расчитывается так: угол обзора 60 градусов, равны ширине экрана, значит всего этих экранов будет 6 плюс добавочный, получается длина_картинки = ширина_экрана*7.
|
По моим вычислениям выходит, что 360 градусов равны 1080 пикселям
(то есть 1 градус = 3 пикселям)
//.... drawimage(nebo,angle*(-3),0); drawimage(nebo,angle*(-3)+360,0); drawimage(nebo,angle*(-3)+720,0); drawimage(nebo,angle*(-3)+1080,0); raycast; //....
Dlina текстуры неба=90*n // где n=[1..12]
Кол-во повторений drawimage со двигом на Dlina = 1080/Dlina+1
Проверенно, 100% работает не зависимо от экрана.
Сообщение от abcdef
запускал на motorola V3i повисло, пришлось уменьшить data [0..6,0..4096] of integer;
|
Да... надо будет подсчитать сколько хипа хавает одна текстура..
|
(Offline)
|
|
10.12.2008, 00:36
|
#55
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: The Maze
Cliffe Snake - спорим об одном и том же, хотя по идее можно обойтись и картинкой шириной с экран.. нужно как можно более минимизировать кол-во вызовов графических функций.
Текстуры лучше представить одним файлом, на подобии вертикальной киноленты, т.о. будем экономить на каждом файле более 1кб из счет заголовка и палитры, кроме того большой файл упаковывается лучше, чем несколько маленьких. кол-во текстур нужно сократить и подгружать их по ходу игры, например при входе в комнату, но это уже в конце, когда все будет готово..
___
Интересно как справиться с программой средствами MIDletPascal, а иначе переписал бы за час на java..
Ранее выложил всю необходимую математику спрайтов, кто-нить уже сделал живых человечков? логику можно сделать такой: если догнал - уменьшаются жизни, а еще довольно неплохо смотриться метание огненными шарами (как в DOOM), шар - тот-же спрайт (направление движения (dx,dy) как у игрока в момент создания), который деинициализиреутся когда столкнется с каким-либо предметом.
Массив со спрайтами наполовину пуст, для генерации всевозможных дополнительных спрайтов. отработавшие спрайты либо превращаются в статические либо помечаются как пустые и свободные..
___
p.s. выкладываю редактор спрайтов/текстур для MSDOS-Wolfenshtein3D скопировать в папку с программой и запускать, есть возможность сохранения изображений в формате gif.
|
(Offline)
|
|
10.12.2008, 07:25
|
#56
|
Разработчик
Регистрация: 24.11.2008
Адрес: UA
Сообщений: 504
Написано 110 полезных сообщений (для 225 пользователей)
|
Ответ: The Maze
Вижу, я немного не в тему пишу, еще про maze. Но пдскажите, пожалуйста, как в maze3d сделать так чтоб когда поварачиваешся влево/вправо не поварачивалась и карта (при этом меняются координаты х, у, что очень мешает узнаванию местонахождения на карте). Если не трудно выложите пример в зипе или хотябы просто листинг. Заранее благодарен...
__________________
Уважай собеседника, а лучше подари ему +
|
(Offline)
|
|
10.12.2008, 09:10
|
#57
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: The Maze
поворот карты, своего рода оптимизация, иначе б в основном алгоритме нужно было рассматривать 4е случая. Получить координаты можно если запомнинать поворот относительно начального, а затем временные_х_у поворачивать обратно
|
(Offline)
|
|
12.12.2008, 07:10
|
#58
|
Разработчик
Регистрация: 24.11.2008
Адрес: UA
Сообщений: 504
Написано 110 полезных сообщений (для 225 пользователей)
|
Ответ: The Maze
Я в мидлетпаскале относительно не долго, и теоретически знаю как это делается, а на деле чет не выходит. Можно пример?
__________________
Уважай собеседника, а лучше подари ему +
|
(Offline)
|
|
12.12.2008, 21:22
|
#59
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: The Maze
Добавил алгоритм спрайтов, нужно оптимизировать и добавить логику, тогда будет хорошая игрушка. Подобных программ на MP не видел.. Кто возьмется делать логику? у кого есть интересные идеи?
__
p.s. ArtikZ - MIDletPascal это не лучший пособ для первого языка программирования, много ситуаций компиляции и проверки синтаксиса программы не поддается здравому смыслу, например при разработке спрайтов, если они были в записях record, то неправильно считался один из параметров. и если в массивах, то нельзя использовать последний элемент,
алгоритм поворота направо t:=x;x:=y;y:=29-t; налево t:=y;y:=x;x:=29-t; смотри какой угол и поворачивай в цикле обратно..
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо abcdef за это полезное сообщение:
|
|
14.12.2008, 10:21
|
#60
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: The Maze
несколько замечаний по использованию вычислений в fixed-point real: числа с фиксированной точкой можно напрямую умножать или делить (если real в делимом, но не наоборот) на integer, а также складывать или вычитать два real-числа обычным сложением или вычитанием, во всех остальных случаях вычисления проводить только через библиотеку, а integer приводить к типу real через fIntToReal
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 14:47.
|