Воскресенье, 19.05.2024, 03:05
Personal dimanche13 site
Главная | Регистрация | Вход Приветствую Вас Гость | RSS
Категории каталога
Мои статьи [22]
BlitzMax [17]
раздел содержит статьи относящиеся к языку программирования BlitzMax
SDL [9]
раздел содержит статьи на тему SDL
Code::Blocks [3]
в этом разделе рассказывается как прикрутить движок к интегрированной среде разработки(IDE) Code::Blocks
Форма входа
Поиск
Друзья сайта
Главная » Статьи » BlitzMax

Лайф-бары в BlitzMax

Лайф-бары в BlitzMax

 
Содержание :
1 Введение
2 Ближе к делу
3 Type TBar
4 Function Create()
5 Method Draw()
6 Method Update()
7 Выведение


Введение

Привет, сегодня я хочу вам рассказать про бар. Да не про тот бар, где мы вчера бухали с друзьями. Это нечто иное, что используется во многих играх, с самых древних ZX времен и даже по сей день. Интернет-переводчик translate.ru слово «bar» – перевел как «брусок». Я бы перевел его, как полоска или шкала. Вам знакомы такие слова - ProgressBar, StatusBar, ScrollBar, LifeBar…? это некие шкалы, заполнение которых, зависит от некоторых событий или переменных. То есть визуально и динамически отображается какой-то процесс, некая замена скучным цифрам. Типичные примеры: шкала загрузки(ProgressBar), перед началом программы на экране пишется что-то типа Loading и шкала(Bar) заполняется по мере выполнения загрузки; LifeBar стратегии, где над юнитами располагаются полоски символизирующие кол-во жизни юнита. ScrollBar - тоже полоска, которая меняет свои размеры, например, в зависимости от кол-ва текста в окне. EnergyBar – в Worms- сила броска/удара. SkillBar – шкала умений персонажа в RPG. Да что там говорить, на моем стареньком мобильнике, уровень заряда батарей изображается как раз EnergyBar-ом. А увеличивая громкость телевизора мы можем наблюдать VolumeBar. Можно перечислять очень долго, так как существует множество разновидностей Bar-ов. Хочу заметить, что не все они имеют только горизонтальное расположение, бывают так же вертикальные и произвольной формы.



Ближе к делу

Я же хочу вам рассказать, как сделать горизонтальную шкалу на примере шкалы жизни, но эта информация применима также и ко всем остальным видам Bar-ов. Я использую язык BlitzMax, но вы можете использовать любой другой ЯП, для воспроизведения данного алгоритма. Сначала немного теории. Для отображения шкалы я воспользуюсь обычными функциями BMax-а: DrawRect(x,y,width,height). Эта функция рисует прямоугольник длинною width, и высотой height, начиная с координат x и y. Синим цветом, я изображу прямоугольник, который будет отображать максимальное кол-во жизни героя, и он будет рисоваться первым.
 
 
А красным цветом мы будем рисовать прямоугольник, который показывает сколько на данный момент жизни у нашего героя (реально).
 

Второй прямоугольник будет рисоваться начиная с тех же координат x и y, что и синий прямоугольник, то есть красный будет накладываться на синий. Но длина его(CurWidth) будет напрямую зависеть от здоровья юнита(!). Так если количество жизней максимально, то виден будет только красный прямоугольник, потому что он будет полностью закрывать собою синий. Если половина жизни, то красный закроет синий на половину. А если кол-во жизней 0, то мы увидим только синий прямоугольник, красный рисоваться не будет. Ну думаю, принцип понятен. Для начала, давайте введем, какой ширины(далее слово длина обозначает то же самое) и высоты будет наша шкала жизни:
Const WIDTHBAR:Int = 200           ‘ ширина шкалы
Const HEIGHTBAR:Int = 16           ‘ высота шкалы

Type TBar

Теперь сделаем класс(тип) TBar который будет:
  1. Создавать шкалу
  2. Изменять ее в зависимости от кол-ва жизни героя
  3. Отображать ее на экране
Названия функций, соответственно по пунктам:
  1. function Create()
  2. method Update()
  3. method Draw()
Но для начала опишем все свойства или поля(Field) нашего типа:
Field CurPts:Int

        Field MaxPts:Int
      
        Field x:Int
        Field y:Int
       
        Field Width:Int = WIDTHBAR
        Field Height:Int = HEIGHTBAR
 
        Field Percent:Int  
        Field CurWidth:Int

Пробежимся по всем переменным:
CurPts – текущее количество жизни(здоровья)
MaxPts – максимальное количество жизни(здоровья)
x и y – координаты для рисования шкалы на экране
Width и Height – габариты(размеры) нашей шкалы, мы определили их выше.
Percent – текущее значение жизни(в процентах)
CurWidth – текущее значение жизни(в пикселях) –длина красного прямоугольника


Function Create()

Вот функция создания нашей шкалы:

Function Create:TBar(sx:Int , sy:Int, pts:Int = 0, mxpts:Int = 100)
                Local TB:TBar = New TBar
                        TB.x = sx
                        TB.y = sy
                        TB.CurPts = pts
                        TB.MaxPts = mxpts
                ListAddLast(BarList , TB)
                Return TB
End Function
Она принимает 4 параметра. sx и sy - координаты на экране, pts - кол-во жизни(по умолчанию-0) и также максимальное кол-во жизни mxpts (по умолчанию-100). Параметры по умолчанию очень облегчают работу и являются не обязательными к указанию, но имейте ввиду, что при создании функции, они должны находиться СТРОГО ПОСЛЕ параметров, которые объявлять обязательно. Итак, входные параметры функции инициализируют поля созданного объекта TB и затем, вновь созданный объект добавляется в список BarList, где будут храниться все созданные lifebar-ы. Наконец, вернем созданный и заполненный объект командой Return, авось пригодится позже))).


Method Draw()

Теперь рассмотрим функцию Draw(), которая будет рисовать шкалу на экране. 
 Method Draw() 
                SetColor(0 , 0 , 255)
                DrawRect(x , y , Width , Height)
                SetColor(255 , 0 , 0)
                DrawRect(x , y , CurWidth , Height)
 
                SetColor(255 , 255 , 255)
                DrawText(Percent + "%" , x + (Width / 2) - 10 , y + 2 )
                DrawText(CurPts + "/" + MaxPts + " pts", x + Width + 10 , y + 2)
 End Method

В общем-то и здесь нет ничего хитрого. Сначала устанавливается синий цвет и рисуется прямоугольник (первый) нашей полоски жизни, начиная с позиции x,y с шириной и высотой ранее нами установленными. Дальше устанавливается красный цвет, и начиная с тех же координат (x и y) рисуется уже другой(второй) прямоугольник, такой же высотой, что и первый. Но длина этого прямоугольника (CurWidth) будет зависеть от текущего количества жизни (CurPts). (Я это уже говорил, но как говорят «повторенье-мать ученья»). Как раз этот параметр нам и надо рассчитать. Но об этом чуть ниже. Затем устанавливается белый цвет, и приблизительно посередине шкалы, пишется сколько процентов здоровья, относительно максимального, сейчас имеет юнит (этот параметр мы тоже рассчитаем позже). Чуть правее Bar-а пишутся через дробь текущее здоровье и максимальное (CurPts/MaxPts), это как в РПГ. Всё, отрисовка завершена!


Method Update()

Теперь самая важная часть, необходимо вычислить какой длины должен быть красный прямоугольник, а это напрямую зависит от текущего состояния здоровья юнита (CurPts). То есть рассчитать CurWidth через CurPts. А затем еще рассчитать, сколько это будет в процентах (Percent) от максимального количества жизни. Давайте начнем с процентов.

Ух, как же я не любил проценты в школе! Мало того, что на математике их проходили, так еще и на химии. Но начав с ними разбираться уже после окончания учебы тогда, когда это было нужно мне, я понял что это не просто… а очень просто. Итак, чтобы узнать сколько это будет в процентах, всего лишь надо: текущее количество чего-либо поделить на максимальное его количество и домножить на сто. В нашем случае вот так:

Percent  = (CurPts / MaxPts) * 100

Ок, рассчитали. Вставим эту формулу в наш метод Update().

Теперь надо рассчитать длину нашего красного прямоугольника (CurWidth) , который символизирует текущее количество жизни.

Кто сказал, что это сигарета? А в глаз! Нет, это не сигарета, и не “косяк” какой-нибудь межгалактический, это наш с вами lifebar. На рисунке я обозначил все ключевые точки.
 
Итак мы хотим, чтобы максимальная длина(Width) отображала макимальное кол-во очков(MaxPts), а (CurWidth) отображала текущее кол-во очков(CurPts). То есть математически: Width = MaxPts, а CurWidth = CurPts. Из этого очевидно, что CurWidth должна так относиться к Width, как CurPts относится к MaxPts. Напомню: отношение – это частное двух чисел выраженных в одной и той же единице измерения. А вот математическая запись этой пропорции:
 
 
 Из 4 параметров, 3 нам известны (CurPts, MaxPts и Width) нам осталось найти один. Проделав нехитрые перестановки, мы видим, что CurWidth рассчитывается так:

CurWidth = (Width * CurPts) / MaxPts

Занесем и эту формулу в метод Update().

Отлично. Все необходимые функции и методы у нас есть. Конечно, не мешало бы добавить еще парочку методов, типа SetXY(x,y), SetPts(pts) и других, но тут я ,думаю вы справитесь и без меня. Поздравляю, теперь можно использовать TBar в вашем проекте! Но я бы хотел еще немного задержать ваше внимание. Я решил добавить парочку методов, а заодно и протестить созданные функции. Лишний тест никогда не повредит, уж поверьте. Предлагаю ввести два тестовых метода: первый будет увеличивать текущую жизнь(CurPts) на единицу, а второй будет на единицу её уменьшать.
 Method AddPts()
                If(CurPts < MaxPts)
                        CurPts :+ 1
                EndIf
 End Method    

 Method SubPts()
                If(CurPts > 0)
                        CurPts :- 1
                EndIf
 End Method

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

Добавим в Update() парочку строк:
 
 If (KeyDown(KEY_RIGHT))
     AddPts()
 End If
 
 If (KeyDown(KEY_LEFT))
     SubPts()
 EndIf
Нетрудно догадаться, что делает и этот код. Если нажать кнопку «вправо», то CurPts (текущее кол-во здоровья) будет увеличиваться, а если кнопку «влево», то уменьшаться. Теперь наконец-таки создадим 3 lifebar-а:

TBar.Create(200 , 150 )
TBar.Create(200 , 200 , 25)            
TBar.Create(200 , 250 , 50 , 300)

Заметьте, что благодаря параметрам «по-умолчанию», функция создания стала очень гибкой. Можно использовать как все 4 параметра, так и 3, а то и всего лишь 2.

Теперь напишем главный цикл нашей тестовой программы.

Global ScrWidth : Int  = 640
Global ScrHeight : Int = 480
 
Graphics(ScrWidth, ScrHeight)
 
Repeat
         Cls
 
                For Local TB:TBar = EachIn BarList
                        TB.Update()
                        TB.Draw()      
                Next        
 
                DrawText("KEY LEFT  - sub points, KEY RIGHT - add points" , 150 , 450)
 
         Flip
Until (KeyDown(KEY_ESCAPE) Or AppTerminate())
 
End

Здесь все стандартно, для приложения BMax. Устанавливаем графический режим, крутим список Lifebar-ов, апдейтим и рисуем их. Напоминаем, какие кнопки надо жать, в этой «ну ооочень сложной» программе))). Повторять это всё, пока не нажат ESC или крестик окна.

У кого не получилось, вот весь исходник программы “tutor_bar.bmx”. Давайте эксперементируйте, а я пошел в бар, меня уже друзья заждались ;)
SuperStrict
Global ScrWidth : Int  = 640
Global ScrHeight : Int = 480
 
Global BarList:TList = CreateList()
 
Const WIDTHBAR:Int = 200
Const HEIGHTBAR:Int = 16
 
Type TBar
 
        Field CurPts:Int
        Field MaxPts:Int
       
        Field x:Int
        Field y:Int
       
        Field Width:Int = WIDTHBAR
        Field Height:Int = HEIGHTBAR
 
        Field Percent:Int
        Field CurWidth:Int
               
        Function Create:TBar(sx:Int , sy:Int, pts:Int = 0, mxpts:Int = 100)
                Local TB:TBar = New TBar
                        TB.x = sx
                        TB.y = sy
                        TB.CurPts = pts
                        TB.MaxPts = mxpts
                ListAddLast(BarList , TB)
                Return TB
        End Function
       
        Method Update()
                If (KeyDown(KEY_RIGHT))
                        AddPts()
                End If
 
                If (KeyDown(KEY_LEFT))
                        SubPts()
                EndIf
               
                CurWidth = (Width * CurPts) / MaxPts
                Percent = Float(CurPts) / MaxPts * 100
 
        End Method
       
        Method AddPts()
                If(CurPts < MaxPts)
                        CurPts :+ 1
                EndIf
        End Method    
 
        Method SubPts()
                If(CurPts > 0)
                        CurPts :- 1
                EndIf
        End Method    
       
        Method Draw()
 
                SetColor(0 , 0 , 255)
                DrawRect(x , y , Width , Height)
                SetColor(255 , 0 , 0)
                DrawRect(x , y , CurWidth , Height)
 
                SetColor(255 , 255 , 255)
                DrawText(Percent + "%" , x + (Width / 2) - 10 , y + 2 )
                DrawText(CurPts + "/" + MaxPts + " pts", x + Width + 10 , y + 2)
 
        End Method
      
End Type
 
TBar.Create(200 , 150 )
TBar.Create(200 , 200 , 25)            
TBar.Create(200 , 250 , 50 , 200)           
 
Graphics(ScrWidth, ScrHeight)
 
Repeat
         Cls
 
                For Local TB:TBar = EachIn BarList
                        TB.Update()
                        TB.Draw()      
                Next        
 
                DrawText("KEY LEFT  - sub points, KEY RIGHT - add points" , 150 , 450)
 
         Flip
Until (KeyDown(KEY_ESCAPE) Or AppTerminate())
 
End
 

Выведение

Об опечатках, багах и других пишите в комменты. Спасибо, за внимание ;)


Источник: http://blitzetc.blitzmax.ru/index.php/Лайф-бары_в_BlitzMax
Категория: BlitzMax | Добавил: dimanche (24.05.2008) | Автор: Dmitriy
Просмотров: 1223 | Комментарии: 1 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Имя *:
Email *:
Код *:
Copyright MyCorp © 2024