最近は細々した対応が多くて「早く次のステップに進めよ!」と思っている方も多いでしょう。
ご意見ごもっともですが、残っている対応が意外にも追加しなければいけない処理が多く苦戦しているのが実情だったりします。そして、そのおかげか試行回数が多くなり見過ごしていた不具合や修正不備がポロポロ出てきています。
今回はそんなテスト中に気づいてしまった「バーアニメーション」の不具合を直していきます。
animateによる不具合について
まずはコチラを御覧ください。
おわかり頂けただろうか・・・
はい、HPバーの挙動がおかしいですね。
そうです、減っていくと思いきや途中で増えるという謎の帳尻合わせ現象が発生しています。
最初はイージングやデュレーションの問題かと思い、animateメソッドのプロパティを変更しながら様子を見ていましたが、解消されることはありませんでした。
開始地点0%問題
プログラミングでの基本は不具合の原因を突き止めることです。エラーが出ていればそれを辿っていくだけなのですが、今回はエラーが出ていないため、ある程度目星をつけて当たっていく必要があります。
そして、実際のcssの変動値を確認することでその問題が判明しました。
そうです、HPのアニメーションが開始されると、widthが0%にリセットされています。これは、開始位置が0%、終了位置が残りHPの割合となっているからです。
理想:現在のHP → 計算結果のHP
現実:現在のHP → HP0→ 計算結果のHP
もしHPが満タン(100%)で計算結果が70%の場合、animateメソッドが起動することでHPが0%になります。そこでcssの動きとしてHPバーが減っていくのですが、animateメソッドによりwidthを70%にするという動きも介入するため、平行的に処理が行われているのでしょう。(予想)
対応方法
とにかく、開始位置の0%をどうにかしなければ、よりスムーズなHPバーの演出はできません。ですが、animateメソッドでは開始位置を設定する方法がありません。
開始位置がセットできるとなれば、まず最初に上がったのがcssのkeyframesです。しかし、jQueryの標準機能ではkeyframesはセット出来ませんし、毎回値も異なります。なので、これを動的にセットする方法がないかを探しました。
そこでたどり着いたのが「jQuery.Keyframes」というライブラリです。今回は、こちらのライブラリを使ってanimateでは対応できなかったHPバーの演出を再度作成します。
jQuery.Keyframesとは
その名の通り、jQueryでcss3のkeyframesを動的にセットできるライブラリです。Javascriptもcssもそこまで得意ではありませんが、keyframesで行うことはwidthを減らすだけなので、これがセットできるとなれば解決したも同様です。
実際のマニュアルに沿って、アニメーションを置き換えていきましょう。
キーフレームの設定
このライブラリの仕組みとしては、まずキーフレームを作成し、そこから要素に対して用意されたキーフレームのアニメーションを割り当てるといったものです。
なので、まずはHPバー用のキーフレームを作成します。
メッセージ用JS(/Public/Assets/js/Battle/message.js)
// コードの先頭(グローバル)でjquery.keyframeを有効可
var supportedFlag = $.keyframe.isSupported();
// doAnimateHpBar関数内
$.keyframe.define({
name: target + 'hpbar-animation',
from: {
width: hpbar.width()
},
to: {
width: width + '%'
}
});
キーフレーム名については、相手ポケモンとの重複を回避するためにも、接頭語にtargetを付与しました。あとはfrom(開始位置)に現在のHPバーの長さ、to(終了位置)に算出結果をセットするだけです。
これでキーフレームが用意できたので、次に要素に対してアニメーションを割り当て、実行します。animateメソッドを以下のplayKeyFrameメソッドに置き換えましょう。
hpbar.playKeyframe({
name: target + 'hpbar-animation',
duration: '1000ms',
timingFunction: 'ease',
delay: '0s',
iterationCount: 1, // 繰り返し回数
direction: 'normal',
fillMode: 'forwards',
complete: function(){
// 処理完了(css変更のズレがあるため0.5秒後にresolveを返却)
if(target === 'friend'){
// HPバーの色チェック
hpbar.removeClass('bg-success bg-warning bg-danger');
if(width <= 20){
hpbar.addClass('bg-danger');
}else if(width <= 50){
hpbar.addClass('bg-warning');
}else{
hpbar.addClass('bg-success');
}
}
setTimeout(function() {
resolve();
}, 500);
}
});
cssのanimationに必要なパラメーターを割り当て、completeにはanimateと同様のコールバック関数を宣言しています。
これで実際の動きを見てみましょう。
スムーズに動いてくれるようになりましたね。これでHPバーのアニメーション不具合修正は完了です。
レベルアップ処理
レベルアップバーについても同様にキーフレームを使って処理をしました。ですが、レベルアップ後の処理にだけ1つ追加の記述が必要です。
// ==============================================
// レベルアップ処理 =============================
//
/**
* 経験値バーのアニメーションを実行
* @param json
* @return Promise
**/
var doAnimateLevelUp = function(param){
return new Promise ((resolve, reject) => {
var expbar = $("#expbar");
expbar.pauseKeyframe();
expbar.hide();
expbar.css('width', 0);
レベルアップ時、widthを0にしてリセットしていますが、そのまま0にしてもkeyframeが残っているためアニメーションが発火してしまいます。
それを防ぐためにも、経験値バーを非表示にする際、一緒にpauseKeyframeメソッドでアニメーションをストップさせておきましょう。
こうしておけば、レベルアップ時に経験値バーがリセットされ、残量計算でも正常に0スタートで始めることができます。
まとめ
いかがだったでしょうか。
今回のPHPポケモンでは「バーアニメーションの不具合修正」を行いました。
1人開発では、仕様書などを作らなくても自分で把握できていればなんとなくシステムは作れますが、その分テストがおろそかになりがちです。これは、工数や作業負担はもちろん、「些細なミスに気づかない」ということが起こるからです。
現在プログラミング学習に取り組んでいる方や、SEへの転職を目指している人は、ぜひ参考にしてみてくださいね。