doom2d.org

Главная база плоских морпехов
It is currently 24 Mar 2025, 03:20

All times are UTC + 3 hours




Post new topic Reply to topic  [ 35 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: 13 Feb 2016, 18:06 
Offline
Приколист
User avatar

Joined: 17 Oct 2009, 19:57
Posts: 4102
Location: Киров
Немного странным выглядит, что с некоторых высот игрок не может свернуть в бок, пролетая дальше вниз. А стоит поднять такую дыру выше или ниже, и заворот возможен. Вот пример таких прыжков:
Attachment:
JUMP_BUG.wad [554 Bytes]
Downloaded 383 times

В средней дыре завернуть не выходит.
P.S. Подпрыгивать перед падением не надо.

_________________
Давай, картечью демонов
Размажем по стене.
Давай, берсерком выпустим
Весь ливер сатане!

Сделайте нормальный огнемёт! :evil:


Top
 Profile  
 
PostPosted: 13 Feb 2016, 19:20 
Offline
Site Admin
User avatar

Joined: 17 Oct 2009, 23:43
Posts: 7835
Location: \\HULK
Да, действительно. Интересно, почему такое происходит.
Если делать это с прыжка, кстати, можно попасть и в среднюю.

_________________
И неважно, что нет морей на Марсе, каждый морпех носит море в сердце.


Top
 Profile  
 
PostPosted: 13 Feb 2016, 20:23 
Offline
Приколист
User avatar

Joined: 17 Oct 2009, 19:54
Posts: 876
Location: Ульяновск
Просто в один момент времени думер упирается в потолок, а в следующий - в пол.

Image

_________________
Точность превыше всего.


Top
 Profile  
 
PostPosted: 01 Oct 2017, 23:22 
Offline
Приколист
User avatar

Joined: 24 Jan 2012, 15:18
Posts: 1440
Location: Москва
Это можно исправить, увеличив FPS игры.

Но я предпочёл бы закрыть как Won't Fix (просто думер не успевает зацепиться за панель).

_________________
by Stas'M


Top
 Profile  
 
PostPosted: 02 Oct 2017, 07:11 
Offline
Принципиально неуничтожаем
User avatar

Joined: 18 Oct 2009, 04:01
Posts: 7206
Location: Владивосток
> FPS
UPS тогда уж.

_________________
Чёрный Думер, Чёрный Думер
С монстрами сражается.
Чёрный Думер, Чёрный Думер
Рокетланчер плавится.


Top
 Profile  
 
PostPosted: 02 Oct 2017, 08:09 
Offline
Приколист
User avatar

Joined: 24 Jan 2012, 15:18
Posts: 1440
Location: Москва
Да, оно самое.

_________________
by Stas'M


Top
 Profile  
 
PostPosted: 02 Oct 2017, 14:41 
Offline
Site Admin
User avatar

Joined: 17 Oct 2009, 23:43
Posts: 7835
Location: \\HULK
Вонтфикс, наверно. Можно использовать в некоторых хитрозадых триксмапах.

_________________
И неважно, что нет морей на Марсе, каждый морпех носит море в сердце.


Top
 Profile  
 
PostPosted: 24 Feb 2024, 08:50 
Offline
Принципиально неуничтожаем
User avatar

Joined: 18 Oct 2009, 04:01
Posts: 7206
Location: Владивосток
Это кстати ровно того же рода особенность, что и способность думера проходить над узкими проёмами определённого размера в полу, если не останавливаться.
Так что точно wontfix. Почему-то лишь сейчас дошло.

_________________
Чёрный Думер, Чёрный Думер
С монстрами сражается.
Чёрный Думер, Чёрный Думер
Рокетланчер плавится.


Top
 Profile  
 
PostPosted: 24 Feb 2024, 09:33 
Offline
Приколист

Joined: 04 Feb 2010, 14:42
Posts: 988
Я когда-то сталкивался с похожей особенностью в своих играх.
Не обязательно подымать UPS, надо просто просчитывать промежуточное движение объектов.
Что-то типа for i := 1 to abs(vely) do move(velx, sign(vely)); вместо y := y + vely; x := x + velx;
Правда не уверен насколько это применяемо к физонию д2д/дф и насколько сломается его совместимость с оригиналом.


Top
 Profile  
 
PostPosted: 25 Feb 2024, 03:39 
Offline
Принципиально неуничтожаем
User avatar

Joined: 18 Oct 2009, 04:01
Posts: 7206
Location: Владивосток
DeaDDooMER wrote:
Не обязательно подымать UPS, надо просто просчитывать промежуточное движение объектов.
Что-то типа for i := 1 to abs(vely) do move(velx, sign(vely)); вместо y := y + vely; x := x + velx;
Это же буквально continuous collision detection, разве нет? Надо Кетмара спросить.
И да, даже в таком случае шаг цикла должен быть больше 1, мне кажется. Иначе летать в шахте на doom2d.wad:MAP08 будет слишком легко, например.

DeaDDooMER wrote:
Правда не уверен насколько это применяемо к физонию д2д/дф и насколько сломается его совместимость с оригиналом.
Сломаться не должна, потому что ну а где бы? Думер разве что проваливаться в узкие щели начнёт, это да. Но можно делать такое лишь для вертикальной скорости.
Зато вот работать будет по идее интереснее, хотя и требовательнее к скорости станет. Можно из этого реквест соорудить так-то, разве что в "Наркомании".

_________________
Чёрный Думер, Чёрный Думер
С монстрами сражается.
Чёрный Думер, Чёрный Думер
Рокетланчер плавится.


Top
 Profile  
 
PostPosted: 25 Feb 2024, 09:43 
Offline
Принципиально неуничтожаем
User avatar

Joined: 18 Oct 2009, 04:01
Posts: 7206
Location: Владивосток
Комментарий от Кетмара к моему предположению про CCD:

ketmar» эм... и?
blackdoomer» так это оно или не оно?
ketmar» там давно есть tracebox, хоть и черезжопный
ketmar» ну да, ccd. только физоний поменяется
blackdoomer» вот я тебя и прошу прояснить и заодно дать совет, как описанный в теме косяк поправить %-)
blackdoomer» только лучше не здесь, а на форуме же
ketmar» никак
blackdoomer» тогда проясни это деддумеру там, будь ласка
ketmar» он последним предложением всё сказал
ketmar» нельзя ничего чинить, надо сидеть и молиться. на совместимость и оригинальный физоний
ketmar» ничего не поделаешь
ketmar» там, кстати, и дак нечто похожее
blackdoomer» ну так дорогой, когда я тебе кидаю ссылко на форум, я хочу, чтобы это ты не мне сказал, а всем %-)
blackdoomer» я не хочу за тебя чревовещать
ketmar» если б я хотел сам -- я бы написал сам. мне лениво, у меня болит голова, жопа, хвост. пиши от себя как умный
ketmar» впрочем, там вам "пролетая над гнездом кукушки" никакой ццд не поможет
ketmar» я прочитал таки тему, лол
ketmar» поняш всё правильно сказал
ketmar» дельта движения же. хоть обмажься весь ццд -- на одном кадре думер ещё не, а на другом уже всё. а между этим неважно, насколько всё плавно, потому что опрос кнопочек покадровый
blackdoomer» так ведь думер УЖЕ в сторону идёт, просто упирается же, разве нет?
ketmar» ну и поняш показал решение. а ццд тут не при чём: ццд точно так же сразу упрётся в стену
ketmar» я давно предлагал сделать coyote time, которое и это решает
blackdoomer» можно я этот кусок переписки туда запощу?
ketmar» можно репостить всё, что я пишу, если я явно не запрещал %-)

_________________
Чёрный Думер, Чёрный Думер
С монстрами сражается.
Чёрный Думер, Чёрный Думер
Рокетланчер плавится.


Top
 Profile  
 
PostPosted: 25 Feb 2024, 14:02 
Offline
Приколист
User avatar

Joined: 17 Oct 2009, 19:57
Posts: 4102
Location: Киров
Самое интересное, что у нас и так сейчас не работают эти пролёты как в классике. Так что не вижу смысла за неё так держаться в этом случае.

_________________
Давай, картечью демонов
Размажем по стене.
Давай, берсерком выпустим
Весь ливер сатане!

Сделайте нормальный огнемёт! :evil:


Top
 Profile  
 
PostPosted: 25 Feb 2024, 17:14 
Offline
Принципиально неуничтожаем
User avatar

Joined: 18 Oct 2009, 04:01
Posts: 7206
Location: Владивосток
Перенёс тему в наркоманские реквесты.

ar888 wrote:
Самое интересное, что у нас и так сейчас не работают эти пролёты как в классике. Так что не вижу смысла за неё так держаться в этом случае.
А в классике как?

_________________
Чёрный Думер, Чёрный Думер
С монстрами сражается.
Чёрный Думер, Чёрный Думер
Рокетланчер плавится.


Top
 Profile  
 
PostPosted: 26 Feb 2024, 02:59 
Offline
Приколист

Joined: 04 Feb 2010, 14:42
Posts: 988
Чёрный Думер wrote:
А в классике как?
Из чего помню, на MAP03 сложнее запрыгнуть в проём в третьей секции уровня.


Top
 Profile  
 
PostPosted: 01 Nov 2024, 21:15 
Offline
Принципиально неуничтожаем
User avatar

Joined: 18 Oct 2009, 04:01
Posts: 7206
Location: Владивосток
DeaDDooMER wrote:
Не обязательно подымать UPS, надо просто просчитывать промежуточное движение объектов.
Что-то типа for i := 1 to abs(vely) do move(velx, sign(vely)); вместо y := y + vely; x := x + velx;
Выяснилось, что у нас это уже давно есть, да только вот сделано криво:
https://repo.or.cz/d2df-sdl.git/blob/6ab87ab2:/src/game/g_phys.pas#l372
Code:
for i := 1 to dx do if not movex() then break;
for i := 1 to dy do if not movey() then break;

Косяк здесь в том, что сначала объект перемещается сугубо по оси X, а затем так же целиком по оси Y. И вместо диагонального движения (точнее, векторного) мы получаем дифференцированное.

Однако если попробовать сходу починить наивным способом, то он не особо помогает:

Code:
MinAxis := Min(dx, dy);

// main motion
for i := 1 to MinAxis do
begin
  movey();  // vertical movement is less common, so it goes first
  movex();
end;

// remaining movement
// only one of both lines will be executed at a time, so their order doesn't matter
for i := 1 to dy-MinAxis do if not movey() then break;
for i := 1 to dx-MinAxis do if not movex() then break;


Как и вот такой вариант:

Code:
MinAxis := Min(dx, dy);
xgo := True;
ygo := True;

// main motion
for i := 1 to MinAxis do
begin
  // vertical movement is less common, so it goes first
  if ygo then ygo := movey() else if not xgo then break;
  if xgo then xgo := movex() else if not ygo then break;
end;

// remaining movement
// only one of both next lines will be executed at a time, so their order here doesn't matter
for i := 1 to dy-MinAxis do if not ygo then break else ygo := movey();
for i := 1 to dx-MinAxis do if not xgo then break else xgo := movex();


А вот это - работает и позволяет игроку залетать в любые проёмы вне зависимости от скорости. Причём как в вертикальные, так и в горизонтальные.
Code:
h := Abs(dx);
v := Abs(dy);  // TODO: why it's always 1 for an idle player?

// main motion
repeat
  // h/v will not go negative here, as we already operate on a minimal quantity
  MinAxis := Min(h, v);
  for i := 1 to MinAxis do
  begin
    xfree := movex();
    yfree := movey();

    // leave early if no movement were made and thus we became static
    if not xfree and not yfree then
      Exit(state);

    // Ord() is used to avoid explicit conditionals which are expensive because we're in a loop
    h -= Ord(xfree);
    v -= Ord(yfree);
  end;
until MinAxis = 0;

// Remaining movement. At this point either 'h' or 'v' must be zero.
// Therefore, only one of both these loops will be executed, so their order doesn't matter.
// But horizontal movement is more common, so it goes first to avoid the excessive check for 'v'.
for i := 1 to h do if not movex() then Exit(state);
for i := 1 to v do if not movey() then Exit(state);

В чём суть. Вызовы movex() можно считать синонимами проверок, залетаем ли мы в вертикальное отверстие. То же самое верно и относительно movey() для горизонтальных, но это мы пока опустим. Отсюда следует, что чисто умозрительно пролёт может происходить в следующих обстоятельствах:

  • если горизонтальное движение оказалось небольшим и потому исчерпалось в основном цикле (main motion) сильно раньше того, как иссякло вертикальное;
  • если вертикальное движение оказалось по модулю намного больше горизонтального и потому долго крутило доводящий цикл (remaining movement), где нет movex().

Мой код учитывает оба этих случая. Но тут уже я сам не уверен в правильности содеянного, потому что некоторые карты вроде бы полагались на данную особенность физики для трюков. Ар, Джа и прочие неравнодушные - опишите, как должно быть. В теме сейчас этого нет.

Кстати, в этой же функции ещё есть вполне конкретный баг: шаг по оси применяется к объекту сразу же, поэтому следующая за этим проверка по противоположной оси осуществляется уже в новых координатах. При нынешнем дифференцированном движении это незаметно, но иначе физика начинает зависеть от того, какая из осей для проверки выбирается первой.
Я это исправил, но не уверен, что оно так не было и в оригинале. DeaDDooMER, можешь глянуть, пожалуйста? Ты лучше нас всех знаком с тамошним кодом.
Кроме того, если исправлять эту проблему для наклонных поверхностей, то игрок начинает намертво застревать вот здесь на Anthill:
Attachment:
screenshot-2024-11-02-02-55-20.png
screenshot-2024-11-02-02-55-20.png [ 74.28 KiB | Viewed 11090 times ]

Поэтому для них пока впилил хак, оставляющий старое поведение. Хотя не знаю, может так наоборот правильно стало бы. Надо смотреть точно размер проёма на карте.

Ар - посмотри, пожалуйста, и потестируй. Как вертикальные проёмы, так и горизонтальные. А также наклонные поверхности.
Заодно прилагаю новую проверочную карту на основе твоей, где сделал побольше вертикальных проёмов.
Оффтоп:

Джа - теперь наклонные поверхности можно попробовать отладить. Я вроде въехал, как они работают.



Attachments:
df_2024-11-01_jumpbug.exe [8.99 MiB]
Downloaded 112 times
JUMP_BUG_moar.wad [759 Bytes]
Downloaded 103 times

_________________
Чёрный Думер, Чёрный Думер
С монстрами сражается.
Чёрный Думер, Чёрный Думер
Рокетланчер плавится.
Top
 Profile  
 
PostPosted: 01 Nov 2024, 23:42 
Offline
Приколист

Joined: 04 Feb 2010, 14:42
Posts: 988
Чёрный Думер wrote:
Exit
стоит потом переписать без exit. бряки фу кака.
Чёрный Думер wrote:
DeaDDooMER, можешь глянуть, пожалуйста? Ты лучше нас всех знаком с тамошним кодом.
Ты преувеличиваешь моё познание и понимаение кода %)
Взаимодействие игрока с миром смотреть в PL_act(), а движение в Z_moveobj().


Top
 Profile  
 
PostPosted: 02 Nov 2024, 05:12 
Offline
Принципиально неуничтожаем
User avatar

Joined: 18 Oct 2009, 04:01
Posts: 7206
Location: Владивосток
DeaDDooMER wrote:
стоит потом переписать без exit. бряки фу кака.
У меня там ещё и Goto будет. А как бы ты переписал? Просто я вот наоборот считаю, что не стоит пытаться вытанцовывать парадигму на языке, не соответствующему ей в полной мере. Потому что язык в конечном счёте оказывается всегда сильнее. Особенно если сам код был перенесён с другого языка (в нашем случае - Си).

DeaDDooMER wrote:
Ты преувеличиваешь моё познание и понимаение кода %)
Это не отменяет моего утверждения, что исходники 1.35 более-менее глубоко исследовали только falcon, Rembo, ketmar и ты. Сам понимаешь, кого из этой цепочки мне сподручнее попросить.

DeaDDooMER wrote:
Взаимодействие игрока с миром смотреть в PL_act(), а движение в Z_moveobj().
Угу, спасибо. Похоже, что это действительно косяк, и оригинал так не делает. Потому что p->x=x; p->y=y; (это 1.35, но в 1.30 и 1.40 то же самое, я посмотрел).
По этой причине осмелился закоммитить: https://repo.or.cz/d2df-sdl.git/commitdiff/866d84306232261c7be9e5a3ea47222562abe9d4
На всякий случай повторю: это исправление не для описанного в первом сообщении изъяна, а лишь связанного с ним.

_________________
Чёрный Думер, Чёрный Думер
С монстрами сражается.
Чёрный Думер, Чёрный Думер
Рокетланчер плавится.


Top
 Profile  
 
PostPosted: 02 Nov 2024, 15:26 
Offline
Приколист

Joined: 04 Feb 2010, 14:42
Posts: 988
Чёрный Думер wrote:
А как бы ты переписал?
Примерно так.
Code:
h := Abs(dx);
v := Abs(dy);
while (h > 0) and (v > 0) do
begin
  if movex() then Dec(h) else h := 0;
  if movey() then Dec(v) else v := 0;
end;
while (h > 0) and movex() do Dec(h);
while (v > 0) and movey() do Dec(v);

Чёрный Думер wrote:
Просто я вот наоборот считаю, что не стоит пытаться вытанцовывать парадигму на языке, не соответствующему ей в полной мере.
for надо воспринимать как цикл с фиксированным счётом. То что в него можно вставить бряк не значит что это хорошая идея, потому что это нарушает инвариант i = MaxAxis+1 после цикла. В данном случае этот инвариант тут вообще не нужен ни для чего и цикл можно объеденить с внешним.

Алсо, надо попробовать двигаться по алгоритму Брезенхэма, а после упирания в стенку - по отдельным осям как сейчас.
А ещё лучше делать через трассировку в гриде, что бы не попуксельно прыгать, а сразу по тайлам.


Top
 Profile  
 
PostPosted: 03 Nov 2024, 11:03 
Offline
Принципиально неуничтожаем
User avatar

Joined: 18 Oct 2009, 04:01
Posts: 7206
Location: Владивосток
DeaDDooMER wrote:
Примерно так.
У этого кода по-прежнему есть описанная здесь проблема с проёмами. Именно потому, что ты зануляешь одну из компонент в качестве флага.

DeaDDooMER wrote:
for надо воспринимать как цикл с фиксированным счётом.
Верно. Именно поэтому во FreePascal запрещено напрямую изменять индексную переменную в теле цикла, а изменение границы цикла внутри него не влияет на количество итераций.
https://wiki.freepascal.org/index.php?title=For&oldid=160198#immutable_requirement
https://www.freepascal.org/docs-html/3.2.2/ref/refsu58.html
Quote:
Free Pascal always calculates the upper bound exactly once before initializing the counter variable with the initial value.
It is not allowed to change (i. e. assign a value to) the value of a loop variable inside the loop.
А вообще жаль, что нет элементарной конструкции repeat N, как в GML.

DeaDDooMER wrote:
То что в него можно вставить бряк не значит что это хорошая идея, потому что это нарушает инвариант i = MaxAxis+1 после цикла.
А вот это уже неправда. Такого инварианта во FreePascal нет - и как раз именно потому, что в нём есть Break, Exit, Fail (sic!) и прочие конструкции, вышибающие порядок исполнения. Не говоря уже о том, что переменная счётчика может быть и глобальной. Смотрим документацию по предыдущей ссылке:
Quote:
The value of the loop variable is undefined after a loop has completed or if a loop is not executed at all. However, if the loop was terminated prematurely with an exception or a break or goto statement, the loop variable retains the value it had when the loop was exited.
Почти дословно то же самое написано и на вышеупомянутой странице в вики: https://wiki.freepascal.org/index.php?title=For&oldid=160198#Loop_Completion
И это не какое-то собственное новшество у FPC - ровно так же дела обстоят и в Delphi: https://docwiki.embarcadero.com/RADStud ... Statements
Quote:
After the for statement terminates (provided this was not forced by a Break or an Exit procedure), the value of counter is undefined.
Я же ведь недаром говорю, что не стоит писать на Pascal'е как на Oberon'е. При этом сугубо теоретически я согласен с твоим обоснованием, но это тот самый случай, когда язык побеждает парадигму. С этим ничего поделать нельзя, кроме как смириться.

DeaDDooMER wrote:
В данном случае этот инвариант тут вообще не нужен ни для чего и цикл можно объеденить с внешним.
Увы, нельзя - иначе игрок будет пролетать проёмы, см. выше. Другой вопрос, что нам может быть необходимо, чтобы он их пролетал. Поэтому я и попросил Ара и Джа подумать, как должно быть. Но с нынешним вариантом точно надо что-то делать, потому что он попросту непредсказуем ни для игрока, ни для картодела.
А свой код я привёл лишь в качестве наглядного примера, чтобы чётко граничные случаи физики понимать. Он не претендует на оптимальность, к тому же при замерах встроенным xprofiler оказывается несколько медленнее нынешнего и твоего. Хотя тут ещё надо убедиться, что профилировщик не привирает - порой значения в нём начинает зашкаливать, и я не понимаю, по какой причине.

Вообще, неплохо было бы посмотреть поведение в 1.30 и 1.40 для справки. Ар или Джа - это тоже к вам просьба.

DeaDDooMER wrote:
Алсо, надо попробовать двигаться по алгоритму Брезенхэма, а после упирания в стенку - по отдельным осям как сейчас.
Я не уверен, что это не повлияет на физику.

_________________
Чёрный Думер, Чёрный Думер
С монстрами сражается.
Чёрный Думер, Чёрный Думер
Рокетланчер плавится.


Top
 Profile  
 
PostPosted: 03 Nov 2024, 12:21 
Offline
Приколист
User avatar

Joined: 17 Oct 2009, 19:57
Posts: 4102
Location: Киров
Чёрный Думер wrote:
Вообще, неплохо было бы посмотреть поведение в 1.30 и 1.40 для справки. Ар или Джа - это тоже к вам просьба.
В оригинале с аэроконтролем туго обстоят дела. Тот же случай с пролётом дыры с зелёным ключом, на уровне с тюрьмой и соплемётом в оригинальной кампании. В дф этот ключ брался без проблем при тупом падении вниз с поворотом. Из-за этого в 1.666 и были внесены исправления в этом месте.
Поэтому ориентироваться на неповоротливую физику д2д явно не стоит. В дф она уже изначально делалась другой. И делать сейчас как в д2д – портить старые карты под дф.
Другое дело, что сейчас возникают вот такие неприятные вещи, как пример из первого поста: просто падая, игрок не может завернуть; а вот подпрыгнув и падая (то есть высота падения увеличится ~56px) – заворот вдруг становится возможен.
То есть такие вещи даже в голове не просчитываются у игрока. И это плохо.

_________________
Давай, картечью демонов
Размажем по стене.
Давай, берсерком выпустим
Весь ливер сатане!

Сделайте нормальный огнемёт! :evil:


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 35 posts ]  Go to page 1, 2  Next

All times are UTC + 3 hours


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
doom2d.org, since 2007