Když jsem v roce 2011 popisoval Animace ve FireMonkey tak už tehdy jsem tvrdil, že je tam velký potenciál. Momentálně si trošku hraji s portování jedné svoji starší hry do FireMonkey a tak jsem se díval na jiné hry psané v opičce. A našel jsem Jweled, FMX verzi Bejeweled, které napsal Joaquin Monedero z Embarcadera pro CodeRage 8.
Pokud tuto hru neznáte, tak se jedná o klasické najdi tři sousední prvky tím, že zkoušíte vyměnit dva sousední prvky v matici obrázků. Graficky nic moc, ale je tam několik pěkných nápadů právě s animacemi. Vřele doporučuji pro inspiraci. Např.
procedure TfrmGame.CreateTextAnimation(i, j: Integer; Const aValue: string; aTextType: TTextType);
var
lText: TText;
lEffect: TGlowEffect;
lAni: TFloatAnimation;
begin
lText := TText.Create(nil);
lText.Parent := BoardLayout;
lText.Text := aValue;
lText.WordWrap := False;
lText.AutoSize := True;
lText.Position.X := i * fCellWidth;
lText.Position.Y := j * fCellHeight;
lText.HitTest := False;
lText.Font.Style := [TFontStyle.fsBold];
lText.BringToFront;
lEffect := TGlowEffect.Create(lText);
lEffect.Parent := lText;
lAni := TFloatAnimation.Create(lText);
lAni.Parent := lText;
lAni.PropertyName := 'Position.Y';
lAni.StartValue := lText.Position.Y;
lAni.StopValue := lAni.StartValue - fCellHeight;
lAni.OnFinish := DoTextFinish;
case aTextType of
ttScore:
begin
lText.Font.Size := 15;
lText.Color := TAlphaColorRec.White;
lEffect.GlowColor := TAlphaColorRec.Black;
lEffect.Softness := 0;
lAni.Duration := 2;
end;
ttMultiplier:
begin
lText.Font.Size := 30;
lText.Color := TAlphaColorRec.Magenta;
lEffect.GlowColor := TAlphaColorRec.Black;
lEffect.Softness := 0;
lAni.Duration := 4;
lText.BringToFront;
end;
end;
lAni.Start;
end;
procedure TfrmGame.DoTextFinish(Sender: TObject);
begin
if (Sender is TfmxObject) and Assigned(TFmxObject(Sender).Parent) and (TFmxObject(Sender).Parent is TText) then
begin
TFmxObject(Sender).Parent.DisposeOf;
end;
end;
Tento kód vytvoří komponentu text, nastaví mu TFloatAnimation animaci v ose y (lAni.PropertyName := 'Position.Y' - cítíte tam ten potenciál?), nastaví mu glow efekt. Takže text s pěkným efektem plynule odjede nahoru.
Zajímavý moment je přiřazení OnFinish kdy při dokončení animace se vše samo uvolní, takže se o to nemusíme starat a můžeme paralelně mít několik textů nezávisle na sobě. Doufám, že pro inspiraci to stačí.
Vlastní animace
U svého programu jsem řešil jak ve FireMonkey zaručit opakované kreslení s určitou frekvencí. Třeba uvedená hra používá přímo prvky z FMX, takže to neřeší (což je taky pěkné). Já jsem se ale rozhodl pro vlastní kreslení - via TPaintBox. Jen jsem potřeboval opakované automatické kreslení, protože jinak se kreslí když je třeba.
Viděl jsem několik variant: použití časovače nebo externí vlákno. Vím, že animace ve Firemonkey jsou řízeny z jednoho místa, a že se všechny vyvolávají pod 60Hz (konfigurovatelně). Napadlo mne vytvořit vlastního následníka, který jen vynutí překreslení hracího pole.
TSyncAnim = class(TAnimation)
protected
procedure ProcessAnimation; override;
public
PaintBox: TPaintBox;
end;
procedure TSyncAnim.ProcessAnimation;
begin
PaintBox.Repaint;
end;
a pak jen stačí ve FormCreate:
<code>
anym := TSyncAnim.Create(self);
anym.Parent := Self;
anym.PaintBox := PaintBox1;
anym.Loop := True;
anym.Enabled := True;
A máme automaticky volané OnPaint. Jen pro upřesnění - veškeré kreslení v TPaintBox (FMX) je prakticky provozováno grafickou kartou, zátěž je minimální.
Jen pro upřesnění: uvedený postup se dá kombinovat s prvním přístupem.