JUCEアプリでアニメーションさせるチュートリアルです。
JUCEチュートリアル、「Graphics」の「Animating geometry」チュートリアルをやっていきます。
公式のチュートリアルページはこちらになります。
こんな人の役に立つかも
・JUCEプログラミングを勉強している人
・JUCEチュートリアル「Animating geometry」をやっている人
・JUCEアプリにアニメーションを導入したい人
AnimationAppComponentクラスについて
JUCEには、アニメーションを作成するための便利なクラスである「AnimationAppCopmonent」クラスが実装されています。このクラスは、音声処理をするときに継承すると便利な「AudioAppComponent」クラスやOpenGL描画をするときに継承すると便利な「OpenGLAppComponent」クラスと同じように、アニメーションを描画したいときに継承するとMainComponentクラスの実装で簡単にアニメーションを作成することができるようです。
「AnimatedAppComponent」クラスの次の関数を利用することで、アニメーション作成をより簡単に行うことができます。
1.setFramesPerSecond関数
2.update関数
3.getFrameCounter関数
4.getMillsecoundSinceLastUpdate関数
これらの関数がどのようにアニメーション作成に役立ってくるか、デモを実装しながら見ていきたいと思います。
デモアプリ実装の準備
AnimationAppComponentクラスを継承したMainComponentクラスをテンプレートで準備してくれる「Animated」テンプレートを使うと便利です。今回利用するアプリはアニメーションのチュートリアルなので、このテンプレートから始めることにします。
Audioアプリにアニメーションを導入したいときは、Audioテンプレートに今回のAnimationAppComponentを継承させていけばよいと思います。
Paint関数の実装
アニメーションさせる円を描画
まずは、アニメーションさせるための円をpaint関数で描きます。
void MainComponent::paint (juce::Graphics& g)
{
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
//以下のプログラムを追記します。
g.setColour(getLookAndFeel().findColour(juce::Slider::thumbColourId));//[1]
int radius = 150;//[2]
juce::Point<float> p(getWidth() / 2.0f + 1.0f * radius,
getHeight() / 2.0f + 1.0f * radius); // [3]
g.fillEllipse(p.x, p.y, 30.0f, 30.0f);//[4]
}
[1]では、juce::sliderクラスのthumbColourIdに定義された色を指定してこれから描画する色を設定しています。
[2]では、radiusというint型の変数に150を格納します。
[3]で、juce::pointクラスのオブジェクトpを定義します。pointクラスはX,Yの座標をペアで指し示すようなクラスです。X座標をウィンドウ幅+150、Y座標をウィンドウ高さ+150とした座標を格納します。
[4]では、pに定義した座標に直径30の円を描画しています。
円をアニメーションさせる
円をアニメーションさせるために次のようにpaint関数に変更を加えます。
void MainComponent::paint (juce::Graphics& g)
{
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
g.setColour(getLookAndFeel().findColour(juce::Slider::thumbColourId));
int radius = 150;
//ここを変更しました。
juce::Point<float> p((float)getWidth() / 2.0f + 1.0f * (float)radius * std::sin((float)getFrameCounter() * 0.04f),
(float)getHeight() / 2.0f + 1.0f * (float)radius * std::cos((float)getFrameCounter() * 0.04f));
g.fillEllipse(p.x, p.y, 30.0f, 30.0f);
}
juce::pointクラスの座標に、X軸方向ではsin関数に「getFrameCounter」の数値を与えたものを足し、Y座標にはcos関数に「getFrameCounter」を与えたものを足しています。
フレームレート60だと、PCスペックのせいか、getFrameCounterの値をDBGで観測すると2づつ加算されていっており、飛び飛びなので、30FPSくらいの描画にしてみました。私のPCではこのくらいが描画速度の限界のようです。