Отрисовка шкалы

Отрисовка шкалы

Переписал. Отказался от обезличивания. Примеры оставил самые простые. Умных слов и сложных предложений старался избегать, но не всегда получалось. Сейчас всё выглядит так. Примеры кода прилагаются (собственно они один в один как в трактате).

Как сделать полоску здоровья, маны и пр.

 Спойлер Show Spoiler Hide Spoiler
 
Отрисовка шкалы.

Все мы видели в различных играх полоски здоровья, маны, выносливости и прочих ресурсов и показателей героя. Выглядят они примерно одинаково: шкала фиксированной ширины, которая по мере игры то заполняется, то опустошается. Собственно, на отношении заполненной части шкалы к её ширине и строятся все алгоритмы отрисовки шкалы.

На примере шкалы здоровья рассмотрим построение такой шкалы в QSP.

Если в школе вы изучали пропорции, будет намного легче вникнуть в суть.

Итак. На протяжении всей игры шкала здоровья имеет фиксированную ширину. Эта ширина соответствует максимальному уровню здоровья. Ширина заполненной части шкалы соответствует текущему значению здоровья. Оба эти значения хранятся в специальных переменных, которые мы конечно же знаем. В нашем примере это будут переменные:

Код:


health['all'] - текущий уровень здоровья
health['max'] - максимальный уровень здоровья

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

Мы рассмотрим несколько способов отрисовки шкалы.

Первый - отрисовка шкалы символами.

Допустим, ширина шкалы 20 символов, что соответствует максимальному уровню здоровья. Если текущий уровень здоровья равен максимальному, или же равен нулю, нам потребуется всего лишь повторить 20 раз один и тот же символ.

Код:


|||||||||||||||||||| - полная шкала
.................... - пустая шкала

Проще всего сделать это, используя цикл:

Код:


i = 0
:for
if i<20:
    $scale = $scale + '|'
    i = i + 1
    jump 'for'
end

Данный цикл создаст текстовую строку из двадцати символов вертикальной черты в переменной $scale. Но этого нам мало. У нас ведь есть промежуточные состояния. Когда герой имеет всего половину от максимального уровня здоровья, четверть, или даже двести тридцать семь четыреста сорок вторых. То есть нам нужно получить что-то вроде этого:

Код:


|||||||||||||||..... - заполнена на три четверти
||||||||||.......... - заполнена наполовину

Чтобы вычислить, до какого места следует рисовать палочки, а с какого начинать точки, мы и используем пропорцию.

Код:


20 символов соответствует health['max']
x  символов соответствует health['all']

Таким образом, чтобы узнать, сколько палочек нам следует нарисовать в нашей шкале, нам достаточно вычислить x. Согласно пропорции:

Код:


20/health['max'] = x / health['all']

x = (20 * health['all']) / health['max']

Теперь, когда мы знаем x (что соответствует ширине заполненной части шкалы), мы можем усовершенствовать наш цикл отрисовки шкалы. Пока i меньше x, добавляем в $scale палочку, потом точку.

Код:


x = (health['all'] * 20) / health['max']
i = 0
:for
if i<20:
    if i < x:
        $scale = $scale + '|'
    else
        $scale = $scale + '.'
    end
    i = i + 1
    jump 'for'
end

Чтобы вывести шкалу, придётся использовать *pl $scale или pl $scale. Я рекомендую оформить алгоритм в отдельной локации в виде функции и вызывать по мере необходимости. Тогда вы можете использовать один алгоритм для отрисовки всех шкал в игре: здоровье, мана, выносливость, сила и пр. и пр. Вот как выглядит данный алгоритм в виде функции:

Код:


! ----scale.symbols----
args[0] = args[0]    &    ! текущее значение параметра
args[1] = args[1]    &    ! максимальное значение параметра
if args[2] = 0: args[2] = 20    &    ! ширина шкалы в символах (по умолчанию 20 символов)
! вычисляем ширину заполненной части - в символах:
args['x'] = (args[0] * args[2]) / args[1]
! выполняем цикл:
args['i'] = 0
:for
if args['i']<args[2]:
    if args['i'] < args['x']:
        $args['scale'] = $args['scale'] + '|'
    else
        $args['scale'] = $args['scale'] + '.'
    end
    args['i'] = args['i'] + 1
    jump 'for'
end
$result = $args['scale']

Такая функция позволяет быстро и легко вывести шкалу в любом месте игры, для любого параметра, и любой ширины:

Код:


*PL    $func('scale.symbols',health['all'],health['max'],30)    &    ! выведет в окно основного описания шкалу здоровья шириной 30 символов
PL    $func('scale.symbols',mana['all'],mana['max'])    &    ! выведет в окно дополнительного описания шкалу маны шириной 20 символов (по умолчанию)

Второй способ - отрисовка шкалы в виде таблицы.

Способ основан на умении QSP рисовать разноцветные таблицы по разметке html.

Дело в том, что в этом случае нам не важна ширина шкалы. Ширина заполненной и незаполненной части вычисляется в процентном отношении. Иными словами:

Код:


health['max'] соответствует 100% ширины таблицы
health['all'] соответствует x

Заполненную часть шкалы будет представлять первая ячейка таблицы, раскрашенная в один цвет, незаполненную - вторая, раскрашенная в другой цвет. Но тут стоит учитывать один нюанс: нельзя делать ячейку шириной в 0%. Т.е. если шкала опустошена, или заполнена по-максимуму, достаточно одной ячейки. Всё это вылилось в весьма простенький код, который я привожу сразу для отдельной функции:

Код:


! -----scale.table------
args[0] = args[0]    &    ! текущее значение параметра
args[1] = args[1]    &    ! максимальное значение параметра
if args[2] = 0: args[2] = 350    &    ! ширина шкалы (таблицы) в пикселях. По умолчанию 350 px
if $args[3] = "": $args[3]="FF0000"    &    ! цвет заполненной части шкалы в формате RRGGBB. По умолчанию - красный
! сначала "создаём" соответствующую таблицу
$args['table']='<TABLE width=<<args[2]>> border=0 cellspacing=0 cellpadding=0><TR>'
! вычисляем ширину в процентах заполненной части
args['x'] = (args[0] * 100) / args[1]
! вычисляем ширину в процентах незаполненной части
args['empty'] = 100 - args['x']
! Если ширина заполненной части больше нуля процентов, добавляем в таблицу ячейку с указанным цветом (красный по-умолчанию)
if args['x']>0:
    $args['table']+="<TD width=<<args['x']>>% bgcolor=#"+$args[3]+">&nbsp;</TD>"
end
! Если ширина незаполненной части шкалы больше нуля процентов, добавляем в таблицу ячейку с другим цветом (серый).
if args['empty']>0:
    $args['table']+="<TD width=<<args['empty']>>% bgcolor=#888888>&nbsp;</TD>"
end
! "закрываем" таблицу
$args['table']+='</TR></TABLE>'
! результат
$result = $args['table']

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

Собственно, это два основных способа отрисовки шкал в QSP. Примеры приведены в прилагаемом файле, с результатом их работы можно ознакомиться.

Примечание №1 к первому способу: для отрисовки шкал символами используйте моноширинные шрифты, например Courier.

Примечание №2 к первому способу: В условии сравнения i и x используется знак "строго меньше", потому что цикл считается с нуля. Если бы i изначально была равна единице, в условии цикла i сравнивалась бы не с числом 20, а 21. Тогда в условии сравнения i и x можно было бы использовать знак "меньше либо равно".

Примечание №3 к первому способу: этот способ позволяет отрисовывать шкалу в том числе и картинками. Используйте вместо символов картинки шириной 1-2 пикселя (вставляются html-тегом <img src="...">.

Примечание ко второму способу: в ячейки таблицы нужно поместить хоть что-нибудь. Это может быть полностью прозрачный рисунок шириной 1 пиксель, или символ пробела. В нашем примере - это символ неразрывного пробела.

Примеры шкал

Изменено: aleksversus
04.Апр.14 01:23:19
Aleks Versus
воздвигатель башни
useravatar
Онлайн
1617 Сообщений
Информация о пользователе в сообщениях
Администратор отключил публичную отправку сообщений

Re: Отрисовка шкалы

Выделил в отдельную тему.

Непонятно, зачем называть "get.scale" если можно просто "scale".

Такой код

Код:

'<font face="Courier" color=#00ff00>|</font>'

для отрисовки одного символа - чересчур. На полоску одинаковых символов достаточно будет и одного тега "font".

Если используется и рассматривается только цикл, то рассуждения про альтернативные способы - лишнее.

Nex
useravatar
Offline
4277 Сообщений
Информация о пользователе в сообщениях
Администратор отключил публичную отправку сообщений

Re: Отрисовка шкалы

Переписал код слегка:

 Спойлер Show Spoiler Hide Spoiler
 

Код:

! --- get.scale --- 

! args[0]  - текущее значение параметра
! args[1]  - максимальное значение параметра
! $args[2] - цвет шкалы, не обязательно (по умолчанию '#888888')
! args[3]  - ширина шкалы в символах, не обязательно (по умолчанию 20)
! $args[4] - символы, не обязательно (по умолчанию '|.')

!проверка параметров
if args[1] = 0: args[1] = 1
if NO STRCOMP($args[2],'^#[0-9a-fA-F]{6}$'): $args[2] = '#888888'
if args[3] <= 0: args[3] = 20
if LEN($args[4]) != 2: $args[4] = '|.'
$args['|'] = MID($args[4],1,1)
$args['.'] = MID($args[4],2,1)

!рисуем шкалу
args['x'] = (args[0] * args[3]) / args[1]
args['i'] = 0
:for
if args['i'] < args[3]:
    if args['i'] < args['x']:
        $result += $args['|']
    else
        $result += $args['.']
    end
    args['i'] += 1
    jump 'for'
end

!выставляем шрифт
$result = '<font face="Courier" color=' + $args[2] + '>' +  _
          $result +  _
          '</font>'
! --- get.scale ---

Пример вызова:

Код:


$func('get.scale',mana['now'],mana['max'],$mana['scaleColor'],mana['scaleLength'])

newsash
useravatar
Offline
465 Сообщений
Информация о пользователе в сообщениях
Администратор отключил публичную отправку сообщений

Re: Отрисовка шкалы

Соберусь, добью. Хочу всё-таки подробнее и про шкалу с изображениями, и способ без цикла сделать.

Aleks Versus
воздвигатель башни
useravatar
Онлайн
1617 Сообщений
Информация о пользователе в сообщениях
Администратор отключил публичную отправку сообщений

Re: Отрисовка шкалы

newsash,
у него там в оригинале двумя цветами одна полоска раскрашивается. "Пустая" и "полная" части полосы различаются цветом.

Nex
useravatar
Offline
4277 Сообщений
Информация о пользователе в сообщениях
Администратор отключил публичную отправку сообщений

Re: Отрисовка шкалы

Nex написал(а):

у него там в оригинале двумя цветами одна полоска раскрашивается. "Пустая" и "полная" части полосы различаются цветом.

Можно ещё отдельный параметр (необязательный) добавить для цвета "пустой" полоски и по умолчанию сделать его совпадающим с цветом "полной" части.
А вообще я лишь предложил альтернативный вариант кода, а захочет Aleks Versus его использовать или нет - это уже ему решать. smile

newsash
useravatar
Offline
465 Сообщений
Информация о пользователе в сообщениях
Администратор отключил публичную отправку сообщений

Re: Отрисовка шкалы

В Зоне+ - графическая шкала.

Код:

!usage : gs 'showFillbar',[name,max,filled,filledCol,emptyCol]


!вообще-то это делается с помощью progressbar или, в случае его отсутствия div или canvas,
!но пришлось поизвращаться с таблицами из-за кривости местного хтмля

*nl '<table width="100%" cellspacing="0" cellpadding="0" ALIGN=CENTER><tr>'
    *p '<td width="20"><font color="#<<$args[3]>>"><<$args[0]>></font></td>'
    !*p '<td><<$args[0]>></td>'
    filledWidth=args[2]*100/args[1]
    emptyWidth=100-filledWidth
    if filledWidth>0:
        *p '<td bgcolor="#<<$args[3]>>" width="<<filledWidth>>%"><<args[2]>></td>'
    end
    if emptyWidth>0:
        *p '<td bgcolor="#<<$args[4]>>" width="<<emptyWidth>>%">'
        if args[5]:*p args[1]-args[2]
        *p '</td>'
    end
*p '</tr></table>'

KOLANICH
useravatar
Offline
92 Сообщений
Информация о пользователе в сообщениях
Администратор отключил публичную отправку сообщений

Re: Отрисовка шкалы

О! Прекрасный способ, KOLANICH. До чего просто. Можно и картинку воткнуть: растягивать по ширине даже классический плеер умеет.

Aleks Versus
воздвигатель башни
useravatar
Онлайн
1617 Сообщений
Информация о пользователе в сообщениях
Администратор отключил публичную отправку сообщений

Re: Отрисовка шкалы

Парни вы конечно молодцы, но например мне и простые "100%" здоровья не мешают, думаю многим также.

KliM
Лидер
useravatar
Offline
107 Сообщений
Информация о пользователе в сообщениях
Администратор отключил публичную отправку сообщений

Re: Отрисовка шкалы

KlimKlim написал(а):

Парни вы конечно молодцы, но например мне и простые "100%" здоровья не мешают, думаю многим также.

Это вопрос видения автора - кто-то пишет текстом, кто-то рисует шкалу, кто-то изгаляется над шрифтом в зависимости от здоровья.

newsash
useravatar
Offline
465 Сообщений
Информация о пользователе в сообщениях
Администратор отключил публичную отправку сообщений

Информация

Статистика форума:
 
Всего тем:
1005
Всего опросов:
14
Всего сообщений:
16790883
Всего сообщений сегодня:
2
Пользователи форума:
 
Всего пользователей:
2570
Последним зарегистрировался:
Jebcek