Масштабирование всей игры без мыла и дрожания (финальная версия)

GameMaker

Пост относится только к GM8.1. У Студии есть такая же проблема, решается ли она — не читал, но какое-то обсуждение на официальном форуме было. Да скорее всего решается, просто функции другие и надо пересоздавать сёрфейс если он вдруг пропал (вечная беда главная фишка Студии).

Техника, которую я описываю в этом посте, собирает в себе опыт Йеовского копания в этом вопросе в 2011 году, ответ (2013) и дополненный ответ (2014) от некоего юзера Blue на gamedev.stackexchange.com, который на самом деле основывается на бородатом ответе на форумах Гейм Мейкера времён 2008-2010 (уже не удаётся найти через поисковик), и мой собственный, отработанный на Castle of no Escape и окончательно отфильтрованный при попытке встроить это «безмыльное» масштабирование в Princess Remedy in a World of Hurt.

Суть проблемы: при использовании встроенного масштабирования в GM8.1, на многих системах получаем мыло, тогда как нужны чёткие квадратные (или хотя бы неразмытые) пикселы.

Решение проблемы:

    1. Создать комнату инициализации, такого же размера как первая комната в игре, и поместить её в самое начало, до фактической первой комнаты игры.
    2. Создать объект, который сделать Persistent (постоянным) и поместить его в комнату инициализации. В объект прописать код с требуемыми размерами окна (тут для примера 320x240 это исходный):

      Create:

      screen_w=320
      screen_h=240
      screen_scale=2

      screen = surface_create(screen_w,screen_h);
      if screen = -1 instance_destroy();

      r=room_first
      while room_exists( r ) && (r!=-1)
      {
          room_set_view(r, 0, true, 0, 0, screen_w, screen_h, 0, 0, screen_w*screen_scale, screen_h*screen_scale, screen_w div 2, screen_h div 2, -1, -1, noone)
          room_set_view_enabled(r, true)
          r=room_next( r )
      }
      room_goto_next()

      Begin Step:
      surface_reset_target();

      draw_clear(0);
      draw_set_blend_mode_ext(bm_one, bm_zero);
      draw_surface_stretched(screen,0,0,screen_w*screen_scale,screen_h*screen_scale);
      draw_set_blend_mode(bm_normal);
      screen_refresh();

      End Step:
      surface_set_target(screen);
      Room Start:
      view_wview[0]=screen_w
      view_hview[0]=screen_h
      view_wport[0]=screen_w*screen_scale
      view_wport[0]=screen_h*screen_scale
      view_visible[0]=1

      window_set_region_size(screen_w*screen_scale, screen_h*screen_scale, 1)
      window_set_region_scale(1, 1)

У того юзера Blue не хватает кода, который устанавливает в комнатах параметры Views, для того чтобы не приходилось ставить их все вручную через IDE в редакторе комнат. У Йео этот код есть, но предлагается вручную копипастить строку для того чтобы писать туда названия всех комнат. В моём же коде этот обход делается автоматически. Не сработает он разве что для игр где комнаты подгружаются динамически, но для таких надо просто сделать цикл от 0 до пары тыщ if room_exists(i) room_set_вот_это_вот_всё.

Мне всё никак не удавалось прикрутить это масштабирование к Castle of no Escape 2 в последнее время (хотя в ConE1 оно всегда было), но затея Козинаки по переводу Принцессы Ремеди создала намного больше движухи вокруг этой техники, чем мне было достаточно, чтобы её отладить. Баг был в том, что у меня (и у всех моих предшественников, естественно) не хватало room_set_view_enabled(r,true) в обходе комнат с автоматической установкой видов.

В общем - всем свои плюсы.

Похожие статьи

13 комментариев
Xitilon
Обалдеть, типографская система Коленки поменяла ( r ) на ®, во дела. 
pevzi
Так ведь <pre> же есть. Правда, оно всё ещё неудобно в использовании.
Xitilon
Ай, некогда красоты наводить, разработка стоит. Но ты прав, я даже забыл об этом, так спешил.
Martiy
Полезная хрень! Респект =))
Xitilon
Юзаешь ГМ?
Martiy
Моя игра "Безумное сопротивление" на GameMaker 8.1 =))
Xitilon
Неплохо!
Palets

Чето непонятно.

Begin Step:

surface_reset_target();

draw_clear(0);

draw_set_blend_mode_ext(bm_one, bm_zero);

draw_surface_stretched(screen,0,0,screen_w*screen_scale,screen_h*screen_scale);

draw_set_blend_mode(bm_normal);

screen_refresh();

Всю жизнь думал, что draw-функции не работают вне draw-эвента (только если ты не рисуешь внутри сурфейса).

И про бленд моды тоже не понял, зачем это.

В этом смысле студия удобнее тем, что там есть возможность отдельно рисовать в application_surface, и отдельно — в экран, что позволяет сначала нарисовать всё в реальном размере, а потом замасштабировать/закрутить/заблендить/зашейдерить всё, как тебе надо, и уже в таком виде пихнуть на монитор.

Xitilon

Таки работают. Бренд мод устанавливается на всякий случай, потому что непонятно в какой игре мы добавили эти действия, и не факт что там не менялся этот бленд мод до того. В 99% игр его никто не трогает, это да.

Про application_surface не знаю, как перейду на Студию — погляжу.

kostak
Когда перейдёшь то?)
Xitilon
После Castle of no Escape 2, который мы с командой закончим где-то к лету.
Xitilon

* где-то к зиме.

Вот как раз этот пост о масштабировании без мыла-то мне и пригодится сейчас. Спасибо деду за победу.

Xitilon
М-да. Этот пост — хрень какая-то, в итоге что-то нашаманил уже на месте, и запахало. Надо всё переделать будет потом, и выложить конкретный исходник для Студии. Впрочем, код автоматической установки видов в комнатах реально пригодился.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.