| Разработка и ромхакинг > Ромхакинг и программирование |
| SGDK |
| << < (34/40) > >> |
| nonamezerox:
--- Цитата: rep-stosw от 01 Ноябрь 2021, 04:49:50 ---щё на счёт коллизий не совсем понятно. Можно ли сделать коллизию с точностью до пиксела? --- Конец цитаты --- Эммм, градиус, ты логику от представления не можешь отделить? Коллизии это привязанные к спрайтам и окружению Box-Box и существуют в вообще отдельном программном слое от графики. Сооотвественно, как ты эти самые хитбоксы сделаешь такая точность и будет. |
| ALKOSHA:
--- Цитата ---Сооотвественно, как ты эти самые хитбоксы сделаешь такая точность и будет. --- Конец цитаты --- На сеге есть игры и с per-pixel колижном. Worms, sub-terrania, pugsy и прочее. Но эти игры с акцентом на физику. Другой вопрос, зочем ему это нужно, если он делает кальку с контры, судя по всему. Там просто надо позу спрайта поменять при проверке краёв платформы. То есть по-тайловой проверки более чем достаточно. |
| lupus:
Вставлю свои 5 копеек: я при “переносе” Silent Hill: Play Novel с GBA на SMD активно использовал вышеупомянутый Retro Graphics Toolkit и его алгоритмы дизеринга, после чего ещё маленько в фотошопе поправлял. Оптимизировать от души пришлось, т.к. палитра ограничена и самой графики немало, а её надо было как-то в 4 метра уместить, вместе с непожатым звуком. |
| rep-stosw:
--- Цитата: nonamezerox от 01 Ноябрь 2021, 14:11:15 ---Коллизии это привязанные к спрайтам и окружению Box-Box и существуют в вообще отдельном программном слое от графики. Сооотвественно, как ты эти самые хитбоксы сделаешь такая точность и будет. --- Конец цитаты --- Чувачок, представленный на картинке с таким боксом упадёт вниз. Не удержится. Для платформера желалась пиксельная точность. На учёт гравитации. Чтобы ноги в воздухе не висели и чтоб не падал, когда перекрытие хотя бы на 1 пиксел. В случае с сегой надо определить какие тайлы пересекаются и потом ещё проверить на локальное пересечение внутри тайлов. Насколько это будет ресурсоёмко? Как вообще в нормальных сеговских платформерах это делается? Чем обыгрывается? Добавлено позже: --- Цитата: lupus от 01 Ноябрь 2021, 16:40:14 ---Оптимизировать от души пришлось --- Конец цитаты --- Я уже наигрался от души! :lol: Понял, что лучше перерисовать под требования сеги. Только вот беда - не художник я. Добавлено позже: --- Цитата: ALKOSHA от 01 Ноябрь 2021, 05:31:24 ---проверка коллизий откуда-то из примеров взята, или же свой велосипед? --- Конец цитаты --- Пока взял отсюда: https://under-prog.ru/sgdk-%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-%d0%bf%d0%bb%d0%b0%d1%82%d1%84%d0%be%d1%80%d0%bc%d0%b5%d1%80%d0%b0-%d0%b4%d0%bb%d1%8f-sega-genesis/ Автор этого сайта здесь недавно был. |
| ALKOSHA:
--- Цитата ---Как вообще в нормальных сеговских платформерах это делается? --- Конец цитаты --- Как правило - по-тайлово. Даже в сонике на наклонных плоскостях в таблички загнаны интерполированные значения оффсета. Шоба чувачок не падал - делаешь шире колижн-бокс. Шоба нога не свисала в воздухе - меняешь кадры анимации... Та блин, ты ни разу не становился на край в том же сонике, флинке, ультра-коре и тд? Тут чисто вопрос арт-исполнения, а не каких-то заумных алгоритмов. |
| Werton:
--- Цитата: rep-stosw от 01 Ноябрь 2021, 04:49:50 ---Как это сделать средствами SGDK ? Пока приходят в голову 2 идеи: 1) Распилить атлас на отдельныве анимации и задать им разное время. 2) Сделать самостоятельно процедуры анимации - с нужными задержками и переходами между фреймами в одном большом атласе. --- Конец цитаты --- Ну в целом да, для одной задержки на отдельную анимацию сойдет и первый, для покадровой задержки 2ой. |
| Ti_:
--- Цитата: rep-stosw от 01 Ноябрь 2021, 04:49:50 ---Исходный фрагмент атласа (RGB 8:8:8): --- Конец цитаты --- |
| rep-stosw:
--- Цитата: Ti_ от 01 Ноябрь 2021, 20:34:08 --- --- Конец цитаты --- Глянул оба варианта на реальной сеге + ТВ. Да, стало лучше: более выделены груди, немного стали различимы детали лица. Для сравнения: |
| Ti_:
--- Цитата: rep-stosw от 02 Ноябрь 2021, 05:30:58 ---Да, стало лучше: более выделены груди, немного стали различимы детали лица. --- Конец цитаты --- scolor_gen.exe in.png 16 out.png 0.1 3 3 но есть нюанс - там каждый раз разные результаты выдаёт, поэтому все спрайты надо разом конвертить. несколько раз прогнать и выбрать лучший вариант. как-то так. Ссылки тут: http://gendev.spritesmind.net/forum/viewtopic.php?p=20105#p2010 |
| rep-stosw:
--- Цитата: Ti_ от 02 Ноябрь 2021, 19:34:49 ---scolor_gen.exe in.png 16 out.png 0.1 3 3 но есть нюанс - там каждый раз разные результаты выдаёт, поэтому все спрайты надо разом конвертить. несколько раз прогнать и выбрать лучший вариант. как-то так. Ссылки тут: http://gendev.spritesmind.net/forum/viewtopic.php?p=20105#p2010 --- Конец цитаты --- Интересная программа, спасибо! :) Да и вся ветка того форума интересная. Несколько раз прогнать - это как? Результат загонять в качестве исходного? Было бы неплохо понять смысл параметров: уровень дизеринга, размер фильтра и режим GEN. Почему-то генерит пустой белый прямоугольник, когда размер фильтра =1. |
| Ti_:
--- Цитата: rep-stosw от 03 Ноябрь 2021, 04:50:03 ---Несколько раз прогнать - это как? Результат загонять в качестве исходного? Было бы неплохо понять смысл параметров: уровень дизеринга, размер фильтра и режим GEN. --- Конец цитаты --- нет, исходный один: scolor_gen.exe in.png 16 out1.png 0.1 3 3 scolor_gen.exe in.png 16 out2.png 0.1 3 3 scolor_gen.exe in.png 16 out3.png 0.1 3 3gen - от названия sega genesis. то есть адаптация под её палитру. дизеринг это просто его величина, чем больше, тем сильнее. 0 не ставится. по фильтру не знаю. |
| rep-stosw:
--- Цитата: Ti_ от 03 Ноябрь 2021, 08:40:54 ---нет, исходный один: --- Конец цитаты --- Глянул сорец этой программы. Да, там действительно random() используется. Поэтому результат каждый раз разный. Интересно, зачем так сделано? --- Начал изобретать свой велосипед с коллизиями, так как примеры из интернета меня не впечатлили: либо всё в общем и ни о чём, либо неприменимо к СЕГе. Итак, мне понадобились точные коллизии спрайта с тайловой плоскостью. Весь гемор в том, что маска таловой плоскостью задана массивом клеток кратных 8. Эта же плоскость должна плавно скролиться по двум осям, ну и спрайт естественно тоже. Мало определить индексы i,j массива клеток, ещё нужно пиксельные смещения взаимно учесть : движение спрайта и скролы плоскости. Ну и конечно, ограничение приращения координат спрайта, если шаг приращения больше дистанции до стены (когда спрайт близко к стене) чтобы не впечатывался в стену. Скажу, что был мощный брэйн-фак, но мне удалось родить рабочий код: сделал 4 коллизии спрайта с тайлами плоскости. Код: --- Код: ---#define STEP 3 /* шаг приращения координат спрайта */ //Координаты спрайта s16 RegionX=0; s16 RegionY=0; //Скроллы: s16 ScrollX=0; s16 ScrollY=0; bool CollisionU(s16 rx,s16 ry) { rx+=ScrollX; ry+=ScrollY; s16 i=rx>>3; s16 j=ry>>3; if(LevelMask[j][i ])return TRUE; if(rx&7)if(LevelMask[j][i+1])return TRUE; return FALSE; } bool CollisionD(s16 rx,s16 ry) { rx+=ScrollX; ry+=ScrollY -1; s16 i= rx>>3; s16 j=(ry>>3)+1; if(LevelMask[j][i ])return TRUE; if(rx&7)if(LevelMask[j][i+1])return TRUE; return FALSE; } bool CollisionL(s16 rx,s16 ry) { rx+=ScrollX; ry+=ScrollY; s16 i=rx>>3; s16 j=ry>>3; if(LevelMask[j ][i])return TRUE; if(ry&7)if(LevelMask[j+1][i])return TRUE; return FALSE; } bool CollisionR(s16 rx,s16 ry) { rx+=ScrollX -1; ry+=ScrollY; s16 i=(rx>>3)+1; s16 j= ry>>3; if(LevelMask[j ][i])return TRUE; if(ry&7)if(LevelMask[j+1][i])return TRUE; return FALSE; } void Joystick(void) { u16 J=JOY_readJoypad(JOY_1); if(J&BUTTON_UP ) { for(s16 s=STEP;s>0;s--)if(!CollisionU(RegionX,RegionY-s)) { RegionY-=s; break; } } else if(J&BUTTON_DOWN ) { for(s16 s=STEP;s>0;s--)if(!CollisionD(RegionX,RegionY+s)) { RegionY+=s; break; } } if(J&BUTTON_LEFT ) { for(s16 s=STEP;s>0;s--)if(!CollisionL(RegionX-s,RegionY)) { RegionX-=s; break; } } else if(J&BUTTON_RIGHT) { for(s16 s=STEP;s>0;s--)if(!CollisionR(RegionX+s,RegionY)) { RegionX+=s; break; } } static u8 t=0; if(!t) { if(J&BUTTON_A)ScrollX--; if(J&BUTTON_B)ScrollX++; if(J&BUTTON_X)ScrollY--; if(J&BUTTON_Y)ScrollY++; } t++; if(t==8)t=0; } #define LEVEL_W 40 #define LEVEL_H 28 const u8 LevelMask[LEVEL_H][LEVEL_W] = { //маска тайлов: 0 - свободно, 1 - cтена { 0, 0, 1,1,1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, .... --- Конец кода --- Скроллы двигаются кнопками: A,B,X,Y. Спрайт двигается: Up,Down,Left,Right Протестировал - всё чётко. Спрайт при тесном контакте со стенами не осциллирует. |
| rep-stosw:
Прикрутил прыжок и гравитацию. Пока без ускорения. Кстати, какая механика более правильная? : 1) В прыжке отжатие влево-вправо приводит к остановке перемещения игрока по горизонтали 2) В прыжке отжатие влево-вправо НЕ приводит к остановке перемещения игрока по горизонтали На видео, сделан способ (1). И как побороть этот треш? При этом все ресурсы вроде как собираются... |
| rep-stosw:
--- Цитата: rep-stosw от 05 Ноябрь 2021, 05:16:53 ---И как побороть этот треш? При этом все ресурсы вроде как собираются... --- Конец цитаты --- Пофиксил этот придурошный баг: https://allthe.codes/mirror/sgdk/commit/13b13e37d98e5e876befbc55120cee2cb418cff2 Прикрепил пофикшенный Jar (класть в bin). sizebnd(fixed).zip (2.5 КБ - загружено 26 раз.) P.S. Чё-то я не понял... Релиз 1.65 у Стефа без фикса: https://allthe.codes/mirror/sgdk/src/tag/v1.65/tools/sizebnd/src/sgdk/sizebnd/Launcher.java |
| Werton:
--- Цитата: rep-stosw от 05 Ноябрь 2021, 09:12:53 ---P.S. Чё-то я не понял... Релиз 1.65 у Стефа без фикса: --- Конец цитаты --- Потому что фикс закомичен после релиза 1.65, ваш КО. |
| rep-stosw:
Приделал ускорение при прыжке и падении. Скорость линейно убывает при прыжке: V-=A И линейно возрастает при падении: V+=A Максимальная скорость S Максимальная высота прыжка H Необходимо было один раз просчитать ускорение (насколько увеличивать/уменьшать скорость). Реккурентная формула: S + S-A + S-2A + ... +S-nA = H Граничное условие сверху: S-nA = V = 1 (минимальная скорость) Граничное условие снизу: V= S (максимальная скорость) Решая, получил: A = (S-1)(S+1)/(2H-S-1) Загоняем в код, получим: --- Код: ---#define JUMP_H 32 /* максимальная высота прыжка */ #define JUMP_S 5.0F /* начальная скорость прыжка/конечная скорость падения */ //#define JUMP_A FIX16((JUMP_S*JUMP_S)/((2.0F*JUMP_H)-JUMP_S)) /* ускорение прыжка/падения (скорость уменьшается до 0) */ #define JUMP_A FIX16(((JUMP_S-1.0F)*(JUMP_S+1.0F))/((2.0F*JUMP_H)-JUMP_S-1.0F)) /* ускорение прыжка/падения (скорость уменьшается до 1) */ f32 js=FIX16(JUMP_S); //скорость прыжка/падения с учётом ускорения u8 BF=1; //разрешено нажатие кнопки "B" u8 JF=0; //прыжок запрещён s16 Ground; //уровень земли void MoveControl(void) { u16 J=JOY_readJoypad(JOY_1); if(BF==1)if(J&BUTTON_B) //если разрешено нажатие кноки "B" и нажата кнопка "B" { BF=0; //запретить следующие нажатия кнопки "B" JF=1; //разрешаем прыжок (движение вверх) Ground=RegionY; //запоминаем уровень земли // js=FIX16(JUMP_S); //начальная скорость прыжка/падения } // if(BF==0)if(!(J&BUTTON_B))BF=1; //если запрещено нажатие кнопки "B" и если кнопка "B" отжата, то разрешаем следующее нажатие кнопки "B" (запрет TURBO-нажатия) if(JF==0) //если прыжок запрещён, то движение вниз (гравитация) { for(s16 s=fix16ToInt(js);s>0;s--)if(!CollisionD(RegionX,RegionY+s)) //если нет коллизии вниз... { RegionY+=s; //...то движемся вниз break; } else BF=1; //...в противном случае разрешаем нажатие кнопки "B" (убрать, если используется запрет TURBO-нажатия) js+=JUMP_A; //увеличиваем скорость if(js>FIX16(JUMP_S))js=FIX16(JUMP_S); //ограничение } else //если прыжок разрешён, то движение вверх { for(s16 s=fix16ToInt(js);s>0;s--)if(!CollisionU(RegionX,RegionY-s)) //если нет коллизии вверх... { RegionY-=s; //...то движемся вверх if(RegionY<=Ground-JUMP_H)JF=0; //если высота превысила длину прыжка, то запрещаем прыжок break; } else JF=0; //...в противном случае запрещаем прыжок js-=JUMP_A; //уменьшаем скорость if(js<FIX16(1.0F))js=FIX16(1.0F); //ограничение } --- Конец кода --- Все скорости - [пиксели/c], расстояния - [пиксели] Вот весь автомат прыжка без движка! :lol: |
| rep-stosw:
Есть ли способ в SGDK обращаться к отдельным спрайтам из спрайтового атласа? К примеру, у меня есть один большой спрайтовый атлас со сгруппированными спрайтами (выровнены на фрейм) каждый спрайт M x N тайлов. Необходимо выборочно дёргать произвольный спрайт и отображать его со своими: палитрой, координатами, атрибутами отзеркаливания. Стандартную функцию анимации использовать не хочу по причинам, изложенным ранее здесь в форуме. Как в этом случае описать ресурс в res-файле и какими функциями выводить спрайты-устанавливать параметры? Хочу создать свою анимацию - со своими последовательностями цепочек спрайтов и со своими атрибутами. Через железо сеги я и сам могу это сделать. Интересует как это сделать ИМЕННО средствами SGDK через отрисов спрайта и установку атласа спрайтов. |
| Werton:
Все что можно описано в справке и в rescomp.txt, никаких секретных техник там нет. Добавлено позже: --- Цитата: rep-stosw от 06 Ноябрь 2021, 15:53:50 ---Есть ли способ в SGDK обращаться к отдельным спрайтам из спрайтового атласа? --- Конец цитаты --- стандартные SPR_setAnim (Sprite *sprite, s16 anim) SPR_setFrame (Sprite *sprite, s16 frame) --- Цитата: rep-stosw от 06 Ноябрь 2021, 15:53:50 ---Необходимо выборочно дёргать произвольный спрайт и отображать его со своими: палитрой, координатами, атрибутами отзеркаливания. --- Конец цитаты --- SPR_addSprite (const SpriteDefinition *spriteDef, s16 x, s16 y, u16 attribut) используй макрос TILE_ATTR(pal, prio, flipV, flipH) как параметр attribut Добавлено позже: --- Цитата: rep-stosw от 06 Ноябрь 2021, 15:53:50 ---Стандартную функцию анимации использовать не хочу по причинам, изложенным ранее здесь в форуме. --- Конец цитаты --- Не используй, отключи автопроигрывание анимации и переключай фреймы вручную Добавлено позже: --- Цитата: rep-stosw от 06 Ноябрь 2021, 15:53:50 ---Как в этом случае описать ресурс в res-файле --- Конец цитаты --- SPRITE name img_file width heigth [compression [time [collision [opt [iteration]]]]] установи параметр time в 0, чтобы отключить автопроигрывание анимации --- Цитата: rep-stosw от 06 Ноябрь 2021, 15:53:50 ---и какими функциями выводить спрайты-устанавливать параметры? --- Конец цитаты --- стандартными |
| rep-stosw:
Werton, спасибо! Забыл отключить авто-анимацию, из-за этого мои анимации артефачили. Можно ли заставить rescompiler выкидывать повторяющиеся тайлы в атласах спрайтов? Спрайты-то он выкидывает. Ещё хотелось бы оптимизации на уровне тайлов. Ещё на счёт палитры вопрос. Я сохраняю PNG как 16-цветный. Но иногда цвет прозрачности в СЕГЕ не совпадает с прозрачностью в PNG. Из-за этого изображение выводится с одним потеряным цветом и без прозрачности. Что я делаю не так и как следует конвертить? Использую IrfanView или GIMP. |
| Werton:
--- Цитата: rep-stosw от 06 Ноябрь 2021, 17:12:11 ---Ещё на счёт палитры вопрос. Я сохраняю PNG как 16-цветный. Но иногда цвет прозрачности в СЕГЕ не совпадает с прозрачностью в PNG. Из-за этого изображение выводится с одним потеряным цветом и без прозрачности. Что я делаю не так и как следует конвертить? --- Конец цитаты --- Альфа канал png тут не применим, нужно конвертить в png с индексированной палитрой. Первый цвет палитры и будет считаться прозрачным (либо же можно задать индекс прозрачного цвета вручную через VDP_setBackgroundColor (u8 value), но нужно знать индекс цвета). Для работы с индексированной палитрой я юзаю Graphics Gale, Aseprite, Pro Motion NG. |
| Навигация |
| Главная страница сообщений |
| Следующая страница |
| Предыдущая страница |