tips 0023 score drum roll - cwtickle/danoniplus GitHub Wiki
| < ステップゾーンや矢印全体を一時的に隠す | スコアドラムロールの作成 | カスタム画面の作成 > |
スコアドラムロールの作成
- カスタムJSを使って、スコア独自計算式&プレイ画面でのドラムロールを実装します。
- ここでは例として、izkdicさん(Type2)・FUJIさんサイト(Type3)での計算式の実装例を記載します。
タイトル画面
- 計算に必要な基礎情報をセットします。
- 作品によって計算式を変えるため、あらかじめカスタム譜面ヘッダーとして
scoreType
を定義し、「Type2」「Type3」のときに独自の計算が行われるようにします。
g_customJsObj.title.push(() => {
// 初項
g_headerObj.calcFirstTerm = 0;
// 公差
g_headerObj.calcDifference = 0;
// フリーズ基本点
g_headerObj.calcFreeze = 0;
// 得点率 (誤差フレーム数毎に定義)
g_headerObj.calcScoreRates = [100, 99, 95, 80, 60, 30];
// スコア除数(Type3用)
g_headerObj.cutRate = 0;
// 基準コンボ数(Type3用)
g_headerObj.cutCombo = 0;
// scoreTypeにより計算式を切り替える。デフォルトは"Type1"
if (g_rootObj.scoreType === undefined) {
g_rootObj.scoreType = `Type1`;
} else if (g_rootObj.scoreType === `Type3`) {
// Type3のときは判定強制変更(暫定)
g_judgObj.arrowJ = [1, 3, 5, 7, 7];
g_judgObj.frzJ = [1, 5, 7];
}
});
設定画面
- 設定画面でどの計算式かが判別できるように、Difficultyの真下にカスタムラベルを作成します。
- 計算式が独自(Type1以外)のとき、その計算タイプを表示するようにします。
g_customJsObj.option.push(() => {
if (g_rootObj.scoreType !== `Type1`) {
multiAppend(difficultySprite,
createDivCss2Label(`local_lblScType`, `Score: ${g_rootObj.scoreType}`, {
x: 13, y: 17, w: g_sWidth, h: g_limitObj.setLblHeight, siz: 12, align: C_ALIGN_LEFT,
})
);
}
});
ロード画面
- プレイ画面で必要となる設定の下準備を行います。
- ドラムロールの場合、実際のスコアとドラムロール上のスコアに差が生じるのでそれぞれ別変数を用意します。
- Type2の場合は、カスタム譜面ヘッダーとして「calc_data」を使用します。
|calc_data=2000,40,1500|
のように使い、「初項」「交差」「フリーズ基本点」を表します。
g_customJsObj.loading.push(() => {
// 実際のスコア
g_resultObj.realScore = 0;
// ドラムロール上のスコア
g_workObj.viewScore = 0;
// 実際のスコア - ドラムロール上のスコア
g_workObj.tempScore = 0;
// 桜点(Type3用)
g_workObj.sakuraScore = 0;
// スコア機構
if (g_rootObj.scoreType === `Type2`) {
let scoreIdHeader = ``;
if (g_stateObj.scoreId > 0) {
scoreIdHeader = Number(g_stateObj.scoreId) + 1;
}
// 譜面データより初項、公差、フリーズ基本点を取得
if (hasVal(g_rootObj.calc_data)) {
const calcs = g_rootObj[`calc` + scoreIdHeader + `_data`].split(`,`);
g_headerObj.calcFirstTerm = parseInt(calcs[0]);
g_headerObj.calcDifference = parseInt(calcs[1]);
g_headerObj.calcFreeze = parseInt(calcs[2]);
}
} else if (g_rootObj.scoreType === `Type3`) {
// 基準コンボ数は総ノート数÷10(小数以下切り捨て)
// 計算結果が1未満になった場合は1とする
g_headerObj.cutCombo = (g_fullArrows > 10) ? Math.floor(g_fullArrows / 10) : 1;
// スコア除数は総ノート数÷100
// 計算結果が1未満になった場合は1とする
g_headerObj.cutRate = (g_fullArrows > 100) ? g_fullArrows / 100 : 1.00;
}
});
プレイ画面
- 実際にドラムロールを表示する処理を実装します。
// プレイ初期時の動作
g_customJsObj.main.push(() => {
// スコアドラムロールのラベル作成
if (g_rootObj.scoreType === `Type2` || g_rootObj.scoreType === `Type3`) {
const judgeSprite = document.getElementById(`judgeSprite`);
multiAppend(judgeSprite,
createDivCss2Label(`local_lblScore`, `Score:`, {
x: g_sWidth * 3 / 4, y: g_headerObj.playingY + g_headerObj.playingHeight - 30, w: g_sWidth / 4 - 50, h: 30,
siz: 14, color: `#ffffff`, align: C_ALIGN_LEFT, fontFamily: C_LBL_BASICFONT,
}),
createDivCss2Label(`local_lblScoreRoll`, g_workObj.viewScore, {
x: g_sWidth / 2, y: g_headerObj.playingY + g_headerObj.playingHeight - 30, w: g_sWidth / 2 - 10, h: 30,
siz: 14, color: `#ffffff`, align: C_ALIGN_RIGHT, fontFamily: C_LBL_BASICFONT,
}),
);
// DisplayオプションでScoreが「OFF」のときは非表示にする
if (g_stateObj.d_score === C_FLG_OFF) {
local_lblScore.style.visibility = `hidden`;
local_lblScoreRoll.style.visibility = `hidden`;
}
}
});
// フレームごとに行う処理
g_customJsObj.mainEnterFrame.push(() => {
// スコアドラムロール処理
// 実スコアの乖離が大きいほど加算量を増やす
if (g_rootObj.scoreType === `Type2` || g_rootObj.scoreType === `Type3`) {
if (g_resultObj.realScore > g_workObj.viewScore) {
g_workObj.tempScore = g_resultObj.realScore - g_workObj.viewScore;
if (g_workObj.tempScore < 100) {
g_workObj.viewScore += 1;
} else if (g_workObj.tempScore < 1000) {
g_workObj.viewScore += 11;
} else if (g_workObj.tempScore < 10000) {
g_workObj.viewScore += 111;
} else if (g_workObj.tempScore < 100000) {
g_workObj.viewScore += 1111;
} else {
g_workObj.viewScore += 11111;
}
local_lblScoreRoll.innerHTML = g_workObj.viewScore;
}
}
});
/**
* スコア計算(回復判定)
*/
const calcArrowRcv = {
Type1: _ => { },
Type2: difFrame => {
const multi = (g_resultObj.combo > 100 ? 100 : g_resultObj.combo);
const absDifFrame = Math.abs(difFrame);
if (absDifFrame <= 5) {
g_resultObj.realScore += Math.floor((g_headerObj.calcFirstTerm +
g_headerObj.calcDifference * multi) * g_headerObj.calcScoreRates[absDifFrame] / 100);
}
},
Type3: (difFrame, rate = 0, plus = 0) => {
let coeff;
// FUJIさんソースはコンボ更新前にスコア計算を行うためその補正
const comboTotal = g_resultObj.combo + g_resultObj.fCombo - 1;
if (comboTotal > g_headerObj.cutCombo) {
coeff = 2 + (comboTotal - g_headerObj.cutCombo) / g_headerObj.cutCombo / 6;
} else {
coeff = 1 + comboTotal / g_headerObj.cutCombo;
}
// スコア更新
g_resultObj.realScore += Math.floor(coeff * rate * (100 + g_workObj.sakuraScore * 4 / g_headerObj.cutRate));
// 桜点更新
g_workObj.sakuraScore += plus;
},
};
/**
* スコア計算(ダメージ判定)
*/
const calcArrowDmg = {
Type1: _ => { },
Type2: _ => { },
Type3: sakuraDif => {
// 桜点更新、0未満になったら0にする
g_workObj.sakuraScore -= sakuraDif;
if (g_workObj.sakuraScore < 0) {
g_workObj.sakuraScore = 0;
}
},
};
/**
* 判定カスタム処理 (引数は共通で1つ保持)
* @param {number} difFrame タイミング誤差(フレーム数)
*/
// イイ
g_customJsObj.judgeIi.push((difFrame) => {
calcArrowRcv[g_rootObj.scoreType](difFrame, 1, 5);
});
// シャキン
g_customJsObj.judgeShakin.push((difFrame) => {
calcArrowRcv[g_rootObj.scoreType](difFrame, 0.8, 4);
});
// マターリ
g_customJsObj.judgeMatari.push((difFrame) => {
calcArrowRcv[g_rootObj.scoreType](difFrame);
});
// ショボーン
g_customJsObj.judgeShobon.push((difFrame) => {
calcArrowDmg[g_rootObj.scoreType](50);
});
// ウワァン
g_customJsObj.judgeUwan.push((difFrame) => {
calcArrowDmg[g_rootObj.scoreType](100);
});
// キター
g_customJsObj.judgeKita.push((difFrame) => {
if (g_rootObj.scoreType === `Type2`) {
g_resultObj.realScore += Math.floor(g_headerObj.calcFreeze);
} else if (g_rootObj.scoreType === `Type3`) {
calcArrowRcv.Type3(difFrame, 1, 5);
}
});
// イクナイ
g_customJsObj.judgeIknai.push((difFrame) => {
calcArrowDmg[g_rootObj.scoreType](100);
});
結果画面
- 計算式が独自のため、結果画面にスコアを上書きします。
g_customJsObj.result.push(() => {
// スコア計算
if (g_rootObj.scoreType === `Type2` || g_rootObj.scoreType === `Type3`) {
g_resultObj.score = g_resultObj.realScore;
lblScoreS.innerHTML = g_resultObj.score;
}
});
ページ作成者
- ティックル
| < ステップゾーンや矢印全体を一時的に隠す | スコアドラムロールの作成 | カスタム画面の作成 > |