【Java:的当てゲーム】カウントダウンの実装
前の記事 | 的当てゲーム制作Top | 次の記事 |
今回はカウントダウンの実装をしていきます。
カウントダウンの実装方法はいろんな方法が思いつくと思います。私は以下の方法などを思いつきました。
・フレームカウントベースの実装
・Timerクラスを使う
・CountDownLatchクラスを使う
・スレッドスリープ1000を指定する
今回はTimerクラスを利用した実装をすることにします。
これを選択した理由ですが、カウントごとに任意の処理が実行できるメリットがあるからです。ただカウントダウンを実装したいだけならCountDownLatchが優れものですが、今回はカウントごとに別の処理もはさみたいと思っているのでTimerを選択しました。
javaのTimerクラスはいくつか種類が存在するのですが、このサイトの別記事でも紹介したjava.util.Timerクラスを使用します。
・・・swingのtimerのほうが実装が簡単そうですがまぁいいでしょう。
今回使用するTimerクラスの使い方は以下の記事をご参照ください。
タイマーの実装はこんな感じで実装してみました。
//開始前カウント int prepareCountDown=3; //タイマー Timer timer = new Timer(); TimerTask task = new TimerTask() { @Override public void run() { if ( prepareCountDown > 0 ) { prepareCountDown--; if ( prepareCountDown == 0 ) { AppManager.startSE(); } else { AppManager.countSE(); } } else { timer.cancel(); } } };
3…2…1…STARTみたいな感じを想定しています。
AppManager.startSE()やAppManager.countSE()でカウントダウンの効果音を再生します。
さて、このタイマーの起動はコンストラクタでやってしまうことにしましょう。
//初期化コンストラクタ public GameMode() { //タイマーの起動 timer.scheduleAtFixedRate(task, 1000, 1000); }
続いて描画部分の修正です。
public void draw(Graphics g) { int width = AppManager.getW(); int height = AppManager.getH(); //アンチエイリアスの有効化 GraphicsUtil.setTextAntialiasing(g, true); //背景の描画 g.drawImage(AppManager.getBackImage(), 0, 0, null); g.setColor(Color.WHITE); g.setFont(countDownFont); if ( prepareCountDown == 0 ) { //START GraphicsUtil.drawCenteringString(g, "START", width / 2, height / 2); } else { //カウントダウンの描画 GraphicsUtil.drawCenteringString(g, ""+prepareCountDown, width / 2, height / 2); } //ステータスの描画 g.setColor(Color.BLACK); g.fillRect(0, 0, width, 50); g.setColor(Color.WHITE); g.setFont(statusFont); GraphicsUtil.drawCenteringString(g, "破壊数:"+breakNum, 400, 25); GraphicsUtil.drawCenteringString(g, "得点:"+score, 200, 25); GraphicsUtil.drawCenteringString(g, "コンボ:"+combo, 600, 25); }
drawCenteringStringというメソッドは文字列の真ん中が指定座標となるように描画するメソッドです。
さて、これでカウントダウン機能の実装は完了ですが、もう一工夫してみましょう。
カウントダウン終了後のSTARTという文字をアニメーションさせてみます。アニメーションはフェードアウトと拡大を適用させてみます。
使用するクラスはDrawLabel、ParallelAnimation、ScaleAnimation、FadeAnimationです。
まずDrawLabelクラスはTitleModeでも使用しましたが、文字を中央描画できるクラスです。その他にアニメーションクラスの適用先としても利用できます。
次にFadeAnimationですが、これは引数のアルファ値分だけ加算処理をします。
そして、ScaleAnimationは引数の倍率分だけ加算処理をします。
最後にParallelAnimationですが、複数のアニメーションクラスを同時実行できます。JavaFXのParallelTransitionと同じ感じですね。
まぁ複数の画像で同じようなアニメーションをさせることもできますが、こういうアニメーションはプログラムから制御したほうがより滑らかなアニメーションとなりますし、画像を複数利用しない分メモリの消費も抑えられます。
それでは、修正部分のソースだけ抜粋したプログラムと実行結果をご覧ください。
//STARTアニメーションラベル DrawLabel startLabel; ParallelAnimation startAnime; //windowにパネルが配置された後に呼び出される public void start() { //windowにパネルが配置された後ならGraphicsオブジェクトを取得できる startLabel = new DrawLabel(getGraphics(), "START", countDownFont, AppManager.getW()/2, AppManager.getH()/2); startAnime = new ParallelAnimation( new ScaleAnimation(startLabel, 0.02) , new FadeAnimation(startLabel, -0.03f) ); } public void draw(Graphics g) { int width = AppManager.getW(); int height = AppManager.getH(); //アンチエイリアスの有効化 GraphicsUtil.setTextAntialiasing(g, true); //背景の描画 g.drawImage(AppManager.getBackImage(), 0, 0, null); g.setColor(Color.WHITE); g.setFont(countDownFont); if ( prepareCountDown == 0 ) { //STARTアニメーション startAnime.update(); startLabel.draw(g); } else { //カウントダウンの描画 GraphicsUtil.drawCenteringString(g, ""+prepareCountDown, width / 2, height / 2); } //ステータスの描画 g.setColor(Color.BLACK); g.fillRect(0, 0, width, 50); g.setColor(Color.WHITE); g.setFont(statusFont); GraphicsUtil.drawCenteringString(g, "破壊数:"+breakNum, 400, 25); GraphicsUtil.drawCenteringString(g, "得点:"+score, 200, 25); GraphicsUtil.drawCenteringString(g, "コンボ:"+combo, 600, 25); }
良い感じになりました。
ディスカッション
コメント一覧
まだ、コメントがありません