Автор Тема: RPG для Neo-Geo по мотивам Shaman King  (Прочитано 4270 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Томахомэ

  • Пользователь
  • Сообщений: 811
  • Пол: Мужской
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« : 27 Апрель 2018, 15:43:45 »
Среда разработки - SDK от Sebastian Mihai, с применением графической библиотеки DATlib v0.3.

Необычна данная RPG будет прежде всего тем, что в нём не будут использоваться вид сверху и изрядно недолюбливаемые мной chibi-пропорции спрайтов персонажей и прочей графики, игровое пространство будет наиболее близко к характерному для beat-em`up!'ов, плюс встречи с врагом будут не рандомными (как это обычно бывает с 8- и 16-битными RPG), а вызываемыми столкновением со спрайтом противника во время внебоевой прогулки по локации (похожим образом, с поправкой на трёхмерность, это реализовано в играх серии Xenosaga).

На данном этапе программа представляет собой пока что лишь модифицированный (в частности, код отображения спрайтов и фона, ранее разбросанный по разным функциям, теперь объединён в одну - она же теперь является главной в новой программе, плюс скроллинг фона управляется теперь не простым движением джойстика, а движением персонажа к краю экрана, плюс возможность персонажа перемещаться я ограничил соответствующим "полу" куском экрана, как в beat'em-up!'ах) пример работы библиотеки (собственно, этим и объясняется то, что графика в программе с Shaman King'ом вроде никак не связана), но, думаю, код её будет использован в качестве базы для внебоевой части геймплея.

Скачать программу можно здесь, (а для обеспечения возможности протестировать её на MAME кидайте XML-файл по ссылке, где уже заранее прописаны характеристики каждого ром-файла, в папку hash, затем создайте в директории MAME для ромов папку DATdemo и кидайте туда char.bin и fix.bin из папки out внутри директории непосредственно с исходниками плюс dev_p1.rom из этой же директории, а остальные нужные файлы берите из архива DATdemo.zip из папки DATdemo_rom) посмотреть видео геймплея - здесь. Скриншоты прикреплены ниже.

Надо подметить, кстати, что RPGшку свою я планирую делать по мотивам именно анимэ-сериала (по которому ещё с 2008 г. загорелся мечтой сделать RPG именно для Neo-Geo, о самом существовании которой узнал незадолго до этого) - хотя, может быть, и от оригинальной манги кое-какие элементы достанутся.
Для начала, раз уж упомянул причину отсутствия оригинальной графики, мне бы хотелось как-нибудь достать спрайт Haohmaru из первой части Samurai Shodown, чтобы с его поз и движений срисовать спрайт Йо, а также спрайт одного из противников в игре Burning Fight по имени Robert Baun (это который гангстер с револьвером) - на него в моей игре должен будет стать похож Рио (да и другие спрайты противников из Burning Fight могут понадобиться - для рядовых членов банды Рио, с которой героям поначалу придётся враждовать).

Оффлайн Томахомэ

  • Пользователь
  • Сообщений: 811
  • Пол: Мужской
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #1 : 04 Май 2018, 17:11:03 »
Заодно добавил также зачатки функции боевых сцен (для перехода на "арену боя" спрайты игрока и врага должны столкнуться друг с другом). Правда, есть одна проблема - всё никак не удаётся мне заставить персонажа во время атаки плавно подходить к врагу, а не "телепортироваться", как сейчас. Код, ответственный за ходы противника после игрока, будет добавлен позже.

Кстати, боево-ролевую систему, думаю, лучше всего было бы создать на основе результатов реверс-инжениринга кода Xenosaga Episode II (знать бы только, где приличный дизассемблер PS2 достать).

Оффлайн Томахомэ

  • Пользователь
  • Сообщений: 811
  • Пол: Мужской
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #2 : 06 Май 2018, 16:34:51 »
Добавил ходы противника с сопутствующей анимацией вражеских атак. Теперь прояснилась причина того, почему, несмотря на то, что в прошлых версиях я четко прописывал команду персонажу плавно подойти к врагу, затем воспроизвести анимацию удара и вернуться на прежнее место, команда эта не работала - что-то мешает программе плавно выполнять всю последовательность операций шаг за шагом (подход героя к врагу -> удар героя -> отход героя на прежнюю позицию -> переход очереди к противнику -> удар противника -> возвращение противника назад -> очередь игрока, и т. д.), и весь результат "выплёвывается" практически сразу, оттого и получается, что игрок с противником друг друга атакуют почти что одновременно.
Только вот что именно мешает, и как эту проблему решить?

Оффлайн Werton

  • Пользователь
  • Сообщений: 878
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #3 : 06 Май 2018, 17:14:36 »
Побуду кэпом :cool: , если это не баг в библиотеке, то наверняка косяк в твоем коде. Не думаю, что тут, еще кто-то, кроме тебя, занимается разработкой под Neo-Geo, а качать либу и разбираться сначала с ней, а потом с твоим кодом, уж точно никто не станет. Потому, если хочешь совета, то запость сюда кусок кода, лучше с комментариями (я так понимаю это Си), отвечающий именно за эту логику, кто-нибудь да подскажет, если косяк там.

Оффлайн Томахомэ

  • Пользователь
  • Сообщений: 811
  • Пол: Мужской
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #4 : 06 Май 2018, 18:04:52 »
(я так понимаю это Си)

Вы абсолютно правы.
Конкретно проблемы творятся вот с этим кодом:
if(turn==0) {
if(p1e&JOY_A)
{
aSpriteMove(&demoSpr,108,0);
/*for(i=0; i<108; i++)
{
aSpriteSetAnim(&demoSpr,1);
x++;
}*/
aSpriteSetAnim(&demoSpr,4);
damage=1;
enemy_hp-=damage;
turn=1;
fixPrintf1(1,26,3,3,"Enemy lost %d HP.", damage);
waitVBlank();
aSpriteMove(&demoSpr,-108,0);
}
if(p1e&JOY_B)
{
aSpriteMove(&demoSpr,108,0);
/*for(i=0; i<108; i++)
{
aSpriteSetAnim(&demoSpr,1);
x++;
}*/
aSpriteSetAnim(&demoSpr,5);
damage=2;
enemy_hp-=damage;
turn=1;
fixPrintf1(1,26,3,3,"Enemy lost %d HP.", damage);
waitVBlank();
aSpriteMove(&demoSpr,-108,0);
}
if(p1e&JOY_C)
{
aSpriteMove(&demoSpr,108,0);
/*for(i=0; i<108; i++)
{
aSpriteSetAnim(&demoSpr,1);
x++;
}*/
aSpriteSetAnim(&demoSpr,6);
damage=3;
enemy_hp-=damage;
turn=1;
fixPrintf1(1,26,3,3,"Enemy lost %d HP.", damage);
waitVBlank();
aSpriteMove(&demoSpr,-108,0);
}
}

if(turn==1) {
aSpriteMove(&Enemy,-108,0);
/*for(i=0; i<108; i++)
{
aSpriteSetAnim(&Enemy,2);
enemyX--;
}*/
aSpriteSetAnim(&Enemy,3);
damage=rand()%3;
char_hp-=damage;
turn=0;
fixPrintf1(1,26,3,3,"Player lost %d HP.", damage);
waitVBlank();
aSpriteMove(&Enemy,108,0);
}
Хранится он в функции battle файла main. На всякий случай добавлю ещё и мануал по библиотеке.

Оффлайн Werton

  • Пользователь
  • Сообщений: 878
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #5 : 07 Май 2018, 03:49:28 »
 Я думаю тебе стоило бы внимательнее почитать справку и разобрать с функциями библиотеки, которые используешь. Тем более, в справке все подробно разжевано(а справка то - просто шик! :wow: ). Читаем:

aSpriteMove
Updates position of an aSprite entity.

Syntax
void aSpriteMove(
aSprite* as,                           Pointer to aSprite handler
short shiftX,                          X axis offset
short shiftY )                         Y axis offset

Explanation
Change aSprite handler screen position.
New position is determined relatively to current position (new pos= current pos + shift).
Will not update the display position directly, use aSpriteAnimate / spritePoolDrawList afterward to
apply change
Note: When using sprite pools, you can freely increase or decrease the aSprite .posX and .posY
fields, without the need of this function.


aSpriteSetAnim
Sets animation for an aSprite entity.

Syntax
void aSpriteSetAnim(
aSprite* as,                            Pointer to aSprite handler
ushort anim )                          Animation ID

Explanation
Change current animation.
Animation IDs are defines issued by the animator tool, see documentation for syntax.
Will not push frame to display, use aSpriteAnimate / spritePoolDrawList afterward to apply changes.
If requesting change to the animation sequence ID that is already running, nothing will be done.

Что мы видим:
- что aSpriteMove, не является tweening функцией (плавного изменения координаты за определенное время, по определенной формуле), как ты ее пытаешься использовать, а по сути, это функция мгновенного сдвига координат спрайта. Хотя это было уже понятно и из ее аргументов, без чтения справки, т.к. там нету параметра типа времени задержки(duration), которое обязательно в твине. Сам посуди, как программа должна узнать за какое время ей сдвинуть спрайт твоего перса в нужную позицию, за секунду, за минуту, за час? Т.е. тебе надо самому написать такую функцию, либо временный костыль :lol:
- для применения изменений, после aSpriteMove нужно вызвать функцию aSpriteAnimate.
- для задания скрости анимации копай в строну структуры animStep и его члена duration (это не здесь написано).
- тоже для aSpriteSetAnim, для применения изменений и запуска анимации, после нужно вызвать функцию aSpriteAnimate.
- по коду. Код в блоке if(turn==1) выполнится сразу (в следуещем кадре) после кода в блоке if(turn==0), естественно для играющего это выглядит как одновременно. Добавляй задержки, на таймере или на счетчике кадров.
« Последнее редактирование: 07 Май 2018, 04:10:01 от Werton »

Оффлайн Томахомэ

  • Пользователь
  • Сообщений: 811
  • Пол: Мужской
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #6 : 07 Май 2018, 04:08:31 »
Я думаю тебе стоило бы внимательнее почитать справку и разобрать с функциями библиотеки, которые используешь. Тем более, в справке все подробно разжевано(а справка то - просто шик! :wow: ). Читаем:

aSpriteMove
Updates position of an aSprite entity.

Syntax
void aSpriteMove(
aSprite* as,                           Pointer to aSprite handler
short shiftX,                          X axis offset
short shiftY )                         Y axis offset

Explanation
Change aSprite handler screen position.
New position is determined relatively to current position (new pos= current pos + shift).
Will not update the display position directly, use aSpriteAnimate / spritePoolDrawList afterward to
apply change
Note: When using sprite pools, you can freely increase or decrease the aSprite .posX and .posY
fields, without the need of this function.

Что мы видим:
- что aSpriteMove, не является tweening функцией (плавного изменения координаты за определенное время, по определенной формуле), как ты ее пытаешься использовать, а по сути, это функция мгновенного сдвига координат спрайта. Хотя это было уже понятно и из ее аргументов, без чтения справки, т.к. там нету параметра типа времени задержки(duration), которое обязательно в твине. Сам посуди, как программа должна узнать за какое время ей сдвинуть спрайт твоего перса в нужную позицию, за секунду, за минуту, за час? Т.е. тебе надо самому написать такую функцию, либо временный костыль :lol:

Вообще-то изначально код был такой:

/*for(i=0; i<108; i++)
{
aSpriteSetAnim(&demoSpr,1);
x++;
}*/
А aSpriteAnimate(&demoSpr); и aSpriteSetPos(&demoSpr,x,y); расположены уже ниже, за пределами тех двух условий, которые я ранее показал.

Оффлайн Werton

  • Пользователь
  • Сообщений: 878
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #7 : 07 Май 2018, 04:15:01 »
Вообще-то изначально код был такой:

Код: [Выделить]
/*for(i=0; i<108; i++)
            {
               aSpriteSetAnim(&demoSpr,1);
               x++;
            }*/
это какое то страшное колдунство, 108 раз назначить анимацию спрайту. Это, например, чтобы понятнее было, как тебя 108 раз подряд попросить "иди сюда" :lol:

Добавлено позже:
Томахомэ, кажется тебе стоит разобраться с основами, как кодить игровый цикл. Рановато ты на neo-geo замахнулся.
« Последнее редактирование: 07 Май 2018, 04:22:58 от Werton »

Оффлайн Томахомэ

  • Пользователь
  • Сообщений: 811
  • Пол: Мужской
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #8 : 07 Май 2018, 07:54:58 »
это какое то страшное колдунство, 108 раз назначить анимацию спрайту. Это, например, чтобы понятнее было, как тебя 108 раз подряд попросить "иди сюда" :lol:

Добавлено позже:
Томахомэ, кажется тебе стоит разобраться с основами, как кодить игровый цикл. Рановато ты на neo-geo замахнулся.

aSpriteSetAnim теперь убрал за пределы цикла. Теперь надо бы назначить внутри цикла после команды x++ определённую задержку перед очередным выполнением. Тут как поступить?

Оффлайн Werton

  • Пользователь
  • Сообщений: 878
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #9 : 07 Май 2018, 09:07:49 »
цикл for там вообще не нужен, если уж совсем по тупому, то используй переменную вместо констант 108(твоя переменная x сейчас вообще ни к чему не привязана) в aSpriteMove, увеличивай\уменьшай эту переменную каждый цикл(игровой цикл\фрейм имеется в виду и он не должен останавливаться) на нужное приращение, пока не достигнет нужного значение.

Добавлено позже:
задержка делается через таймер или свой счетчик, при этом не надо останавливать игровой цикл.

Оффлайн Томахомэ

  • Пользователь
  • Сообщений: 811
  • Пол: Мужской
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #10 : 11 Май 2018, 06:21:44 »
Томахомэ, кажется тебе стоит разобраться с основами

Ну тогда хоть посоветуйте, что ли, где отыскать годное руководство именно по игровому применению C. А то ведь гукинское из серии "Для чайников", по которому, я, собсна, C и учил, тонкостей игроделия не затрагивало.

Оффлайн Томахомэ

  • Пользователь
  • Сообщений: 811
  • Пол: Мужской
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #11 : 13 Май 2018, 18:03:08 »
Наконец-таки дошёл своим умом до решения проблемы.

Как выглядят теперь бои, можно посмотреть в прикреплённом видео.

Неплохо бы теперь ещё научиться по прошествии определённого времени удалять с экрана только какие-то конкретные надписи, не тронув весь остальной fix layer, а также при анимации ударов выводить непосредственно бьющую часть спрайтов на передний относительно ударенного спрайта план.

Выход из функции битвы после победы или поражения, а также анимации получения ударов, будут добавлены позже.

Онлайн Mad

  • Пользователь
  • Сообщений: 8059
  • Пол: Мужской
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #12 : 13 Май 2018, 19:10:10 »
Томахомэ, а в чем твоя цель проекта? Ты хочешь просто сделать игру, хочешь научиться кодить именно для НеоГео или еще что? Если просто сделать игру - то путь ты выбрал очень не легкий, учитывая наличие готовых движков для ПК например.

Оффлайн Томахомэ

  • Пользователь
  • Сообщений: 811
  • Пол: Мужской
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #13 : 14 Май 2018, 04:35:23 »
Ты хочешь просто сделать игру, хочешь научиться кодить именно для НеоГео...

Скажем так - и то, и то.

Оффлайн Томахомэ

  • Пользователь
  • Сообщений: 811
  • Пол: Мужской
    • Просмотр профиля
Re: RPG для Neo-Geo по мотивам Shaman King
« Ответ #14 : 23 Май 2018, 17:02:54 »
Добавлены возможность проигрыша и анимации реакции на удары (как у врага, так и у игрока).





Оффлайн Томахомэ

  • Пользователь
  • Сообщений: 811
  • Пол: Мужской
    • Просмотр профиля
RPG для Neo-Geo по мотивам Shaman King
« Ответ #15 : 18 Ноябрь 2018, 04:58:40 »
За основу боево-ролевой системы Shaman King'а я решил взять аналогичную систему в Xenosaga Episode II (хотя её, в принципе, можно также взять и у 3-го эпизода). Но для этого, похоже, потребуется основательный реверс-энжинеринг игры. Начал я с того, что открыл через IDA Pro файл SLUS_208.92 (предполагаю, что такие файлы в играх для PS2 играют роль экзешников у писишных прог) с первого диска игры.

По ссылке - читаемый через IDA Pro файл с кодом, получившимся в результате дизассемблирования SLUS_208.92.
Кто-нибудь здесь сможет понять этот дизассемблированный код?