Сделать простой хелсбар очень просто - все что нужно это один спрайт для фона и еще один спрайт для отображения текущего значения. После этого можно задать спрайту, отображающему текущее значение, горизонтальное масштабирование по формуле: текущее значение / максимальное значение.
Сделаем маленький пример для тестирования хелсбара. Сначала отрисуем фон, затем добавим наш будущий хелсбар и кнопку, которая будет задавать хелсбару случайное значение. Для кнопки я использовал PushButton из пакета minimalcomps но вы можете навесить событие клика прямо на stage.
Также, для того чтобы лучше протестировать наш хелсбар, добавим слушатель события ENTER_FRAME в котором будем увеличивать значение хелсбара, если оно меньше максимального значения, и будем обновлять отрисовку хелсбара с новым значением.
Код Example.as:
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.*;
import com.bit101.components.*;
[SWF(width="660", height="260", backgroundColor="0xeeeeee", frameRate="30")]
public class Example extends Sprite {
private const WIDTH:int = 660;
private const HEIGHT:int = 260;
private var bar:Bar;
private var healthLabel:Label;
private var damageButton:PushButton;
public function Example() {
var matrix:Matrix = new Matrix();
matrix.createGradientBox(660, 660, 0, 0, -200);
graphics.beginGradientFill(GradientType.RADIAL, [0xe0e0e0, 0xd0d0d0], [1, 1], [0, 255], matrix);
graphics.drawRect(0, 0, WIDTH, HEIGHT);
graphics.endFill();
bar = new Bar();
bar.x = 330 - bar.width / 2;
bar.y = 130 - bar.height / 2;
bar.maximum = 100;
bar.value = 100;
stage.addChild(bar);
healthLabel = new Label(stage, 330, 40, "Health: "+bar.value);
healthLabel.move(330 - healthLabel.width / 2, 40);
damageButton = new PushButton(stage, 285, 200, "Damage", damage);
damageButton.setSize(90, 20);
stage.addEventListener(Event.ENTER_FRAME, update);
}
private function damage(event:MouseEvent):void {
bar.value = int(Math.random() * 50);
}
private function update(event:Event):void {
if (bar.value < bar.maximum) {
bar.value++;
healthLabel.text = "Health: "+bar.value;
}
}
}
}
Теперь можно сделать сам хелсбар. Хелсбар будет наследовать от Sprite и у него будет два Shape для отрисовки нужной нам графики: bg для фона и bar для отображения текущего значения. Также у него будут геттеры/сеттеры для максимального и текущего значения, и приватный метод update, который будет задавать горизонтальное масштабирование для bar.
Код Bar.as:
package {
import flash.display.*;
import flash.geom.*;
public class Bar extends Sprite {
private const WIDTH:int = 300;
private const HEIGHT:int = 8;
private var bg:Shape;
private var bar:Shape;
private var _value:Number = 0;
private var _max:Number = 1;
public function Bar() {
bg = new Shape();
bg.graphics.beginFill(0x222222);
bg.graphics.drawRect(0, 0, WIDTH, HEIGHT);
bg.graphics.endFill();
addChild(bg);
bar = new Shape();
bar.graphics.beginFill(0xff0060);
bar.graphics.drawRect(0, 0, WIDTH, HEIGHT);
bar.graphics.endFill();
addChild(bar);
}
private function update():void {
bar.scaleX = _value / _max;
}
public function set maximum(m:Number):void {
_max = m;
_value = Math.min(_value, _max);
update();
}
public function get maximum():Number {
return _max;
}
public function set value(v:Number):void {
_value = Math.min(v, _max);
update();
}
public function get value():Number {
return _value;
}
}
}
Тестируем:
Работает очень хорошо. Но что, если мы захотим хелсбар с закругленными углами или с текстурой? Добавим нашему хелсбару градиент и закругленные уголки:
Смотрится не очень красиво. Чтобы это исправить мы добавим в хелсбар еще один Shape с именем cover, который будет маской для bar. Теперь, для отображения текущего значения, мы будет задавать горизонтальное масштабирование для cover, а не для bar.
Новый код Bar.as:
package {
import flash.display.*;
import flash.geom.*;
public class Bar extends Sprite {
private const WIDTH:int = 300;
private const HEIGHT:int = 30;
private const CORNER:int = 30;
private var bg:Shape;
private var bar:Shape;
private var cover:Shape;
private var _value:Number = 0;
private var _max:Number = 1;
public function Bar() {
bg = new Shape();
bg.graphics.beginFill(0x333333);
bg.graphics.drawRoundRect(0, 0, WIDTH, HEIGHT, CORNER);
bg.graphics.endFill();
addChild(bg);
var matrix:Matrix = new Matrix();
matrix.createGradientBox(WIDTH / 2, HEIGHT);
bar = new Shape();
bar.graphics.beginGradientFill(GradientType.LINEAR, [0x4488ff, 0x00c8ff], [1, 1], [0, 255], matrix, SpreadMethod.REFLECT);
bar.graphics.drawRoundRect(0, 0, WIDTH, HEIGHT, CORNER);
bar.graphics.endFill();
addChild(bar);
cover = new Shape();
cover.graphics.beginFill(0xffffff);
cover.graphics.drawRect(0, 0, WIDTH, HEIGHT);
cover.graphics.endFill();
addChild(cover);
bar.mask = cover;
}
private function update():void {
cover.scaleX = _value / _max;
}
public function set maximum(m:Number):void {
_max = m;
_value = Math.min(_value, _max);
update();
}
public function get maximum():Number {
return _max;
}
public function set value(v:Number):void {
_value = Math.min(v, _max);
update();
}
public function get value():Number {
return _value;
}
}
}
Тестируем:
Смотрится намного лучше. Для bar и bg вместо Shape вы также можете использовать изображения, спрайты из библиотеки или анимированые MovieClip:
Ваш хелсбар может иметь нестандартную форму или может быть вертикальным, а не горизонтальным: