Отрисовка шкал в классическом QSP
Лирическое отступление
Внимание!!! Эта статья не актуальна для qSpider и других плееров, поддерживающих HTML, поскольку в HTML-разметке вы можете воспользоваться уже готовым элементом <progress>.
Пример использования (HTML-код):
<progress value="275" max="420">275/420</progress>
QSP-код:
health = 275
max_health = 420
*pl '<progress value="<<health>>" max="<<max_health>>"<<health>>/<<max_health>></progress>'
Вид прогресс-бара по умолчанию (в разных браузерах отображается по-разному):
Описанные в данной статье приёмы отрисовки шкал можно использовать в любых версиях классического плеера. Однако, стоит учитывать, что данная статья написана для плееров версии 5.8.0.
Начало статьи
Все мы видели в различных играх полоски здоровья, маны, выносливости и прочих ресурсов и показателей героя. Выглядят они примерно одинаково: шкала фиксированной ширины, которая по мере игры то заполняется, то опустошается. Собственно, на отношении заполненной части шкалы к её ширине и строятся все алгоритмы отрисовки шкалы.
На примере шкалы здоровья рассмотрим построение такой шкалы в QSP.
Если в школе вы изучали пропорции, будет намного легче вникнуть в суть.
Итак. На протяжении всей игры шкала здоровья имеет фиксированную ширину. Эта ширина соответствует максимальному уровню здоровья. Ширина заполненной части шкалы соответсвует текущему значению здоровья. Оба эти значения хранятся в специальных переменных, которые мы конечно же знаем. В нашем примере это будут переменные:
health['тек'] - текущий уровень здоровья
health['макс'] - максимальный уровень здоровья
Следует отметить, что численно ширина шкалы может не совпадать со значением максимального уровня здоровья. Так же и заполненная часть - с текущим уровнем здоровья. Эх, если бы всё было так просто, нам бы не пришлось ничего считать.
Мы рассмотрим несколько способов отрисовки шкалы.
Отрисовка шкалы символами
Допустим, ширина шкалы 20 символов, что соответствует максимальному уровню здоровья. Если текущий уровень здоровья равен максимальному, или же равен нулю, нам потребуется всего лишь повторить 20 раз один и тот же символ.
|||||||||||||||||||| - полная шкала
.................... - пустая шкала
Проще всего сделать это, используя цикл:
loop local i = 0 while i < 20 step i += 1:
$scale += '|'
end
Данный цикл создаст текстовую строку из двадцати символов вертикальной черты в переменной $scale. Но этого нам мало. У нас ведь есть промежуточные состояния. Когда герой имеет всего половину от максимального уровня здоровья, четверть, или даже двести тридцать семь четыреста сорок вторых. То есть нам нужно получить что-то вроде этого:
|||||||||||||||..... - заполнена на три четверти
||||||||||.......... - заполнена наполовину
Чтобы вычислить, до какого места следует рисовать палочки, а с какого начинать точки, мы и используем пропорцию.
20 символов соответствует health['макс']
x символов соответствует health['тек']
Таким образом, чтобы узнать, сколько палочек нам следует нарисовать в нашей шкале, нам достаточно вычислить x. Согласно пропорции:
20 / health['макс'] = x / health['тек']
⇓
x = (20 * health['тек']) / health['макс']
Теперь, когда мы знаем x (что соответствует ширине заполненной части шкалы), мы можем усовершенствовать наш цикл отрисовки шкалы. Пока i меньше x, добавляем в $scale палочку, потом - точку.
x = (health['тек'] * 20) / health['макс']
loop local i = 0 while i < 20 step i += 1:
if i < x:
$scale += '|'
else
$scale += '.'
end
end
Чтобы вывести шкалу, придётся использовать *pl $scale или pl $scale. Я рекомендую оформить алгоритм в отдельной локации в виде функции и вызывать по мере необходимости. Тогда вы можете использовать один алгоритм для отрисовки всех шкал в игре: здоровье, мана, выносливость, сила и пр. и пр. Вот как выглядит данный алгоритм в виде функции:
! ----scale.symbols----
local current = args[0] & ! текущее значение параметра
local maximal = args[1] & ! максимальное значение параметра
local width = iif (args[2] = 0, 20, args[2]) & ! ширина шкалы в символах (по умолчанию 20 символов)
! вычисляем ширину заполненной части - в символах:
local x = (current * width) / maximal
! выполняем цикл:
$result = ''
loop local i = 0 while i < width step i += 1::
if i < x:
$result += '|'
else
$result += '.'
end
end
Такая функция позволяет быстро и легко вывести шкалу в любом месте игры, для любого параметра, и любой ширины:
! выведет в окно основного описания шкалу здоровья шириной 30 символов:
*pl @scale.symbols(health['тек'], health['макс'], 30)
! выведет в окно доп. описания шкалу маны шириной 20 символов (по умолчанию):
pl @scale.symbols(mana['all'], mana['max'])
Отрисовка шкалы в виде таблицы
Способ основан на умении QSP рисовать разноцветные таблицы по разметке html.
Дело в том, что в этом случае нам не важна ширина шкалы. Ширина заполненной и незаполненной части вычисляется в процентном отношении. Иными словами:
health['макс'] соответствует 100% ширины таблицы
health['тек'] соответствует x
Заполненную часть шкалы будет представлять первая ячейка таблицы, раскрашенная в один цвет, незаполненную - вторая, раскрашенная в другой цвет. Но тут стоит учитывать один нюанс: нельзя делать ячейку шириной в 0%. Т.е. если шкала опустошена, или заполнена по-максимуму, достаточно одной ячейки. Всё это вылилось в весьма простенький код, который я привожу сразу для отдельной функции:
! -----scale.table------
local current = args[0] & ! текущее значение параметра
local maximal = args[1] & ! максимальное значение параметра
local width = iif (args[2] = 0, 350, args[2]) & ! ширина шкалы (таблицы) в пикселях. По умолчанию 350 px
local color = iif ($args[3] = '', 'FF0000', $args[3]) & ! цвет заполненной части шкалы в формате RRGGBB. По умолчанию - красный
! объявляем другие локальные переменные:
local $table, x, empty
! сначала "создаём" соответствующую таблицу
$table = '<table width=<<width>> border=0 cellspacing=0 cellpadding=0><tr>'
! вычисляем ширину в процентах заполненной части
x = (current * 100) / maximal
! вычисляем ширину в процентах незаполненной части
empty = 100 - x
! Если ширина заполненной части больше нуля процентов, добавляем в таблицу ячейку с указанным цветом (красный по-умолчанию)
if x > 0:
$table += '<td width="<<width>>%" bgcolor="#<<width>>"> </td>'
end
! Если ширина незаполненной части шкалы больше нуля процентов, добавляем в таблицу ячейку с другим цветом (серый).
if empty > 0:
$table += '<td width="<<empty>>%" bgcolor="#888888"> </td>'
end
! "закрываем" таблицу
$table += '</tr></table>'
! результат
$result = $table
У этого кода может быть ряд модификаций. Например, можно вставить в ячейку таблицы рисунок шириной один пиксель и растягивать его по ширине на всю ячейку. Можно прописывать внутри ячеек значения параметра, и прочее.
Заключение, примечания, скриншоты
Заключение и примечания
Собственно, это два основных способа отрисовки шкал в QSP. Примеры приведены в прилагаемом файле, с результатом их работы можно ознакомиться.
Примечание №1 к первому способу: для отрисовки шкал символами используйте моноширинные шрифты, например Courier.
Примечание №2 к первому способу: В условии сравнения i и x используется знак "строго меньше", потому что цикл считается с нуля. Если бы i изначально была равна единице, в условии цикла i сравнивалась бы не с числом 20, а 21. Тогда в условии сравнения i и x можно было бы использовать знак "меньше либо равно".
Примечание ко второму способу: в ячейки таблицы нужно поместить хоть что-нибудь. Это может быть полностью прозрачный рисунок шириной 1 пиксель, или символ пробела. В нашем примере - это символ неразрывного пробела.