RPGツクールMZランキングスクリプト

RPGツクールMZでスクリプトを使ってランキングを表示する方法なんですが、RPGツクールMZ本体とは別にWebサーバー等が必要となりますので、公開しようかどうしようか迷いましたが、知りたい人もいるかもしれませんので公開します…!
(諸々の知識があるとして話を進めます)

まず、スコアが出るタイプのゲームを作ります。
今回は10秒の間に何回タップ出来るかというゲームを例にします。

ゲーム本体になるイベントのイベントの1ページ目で10秒のタイマーを起動して

2ページ目、TouchInput.isTriggered()でタップされたかどうかを条件分岐し、タップされた数を変数に入れて「TextPicture」で表示します。

これでゲーム本体は完成です。

次にタップ回数(スコア)を送信するイベントを作ります。

選択肢の表示位置を変える方法はRPGツクールMZテキストファイルを読み込んで画面に表示するスクリプトをご覧ください。

条件分岐でランキング更新の場合、スコアを送信するかを問い、スクリプトを実行します。

function sendHighScore(username, score) {
fetch('スコア送信先URLファイル.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'username=' + encodeURIComponent(username) + '&score=' + encodeURIComponent(score)
})
.then(response => response.text())
.then(data => {
$gameVariables.setValue(変数ID,'スコアを送信しました');
})
.catch((error) => {
$gameVariables.setValue(変数ID,'エラーが発生しました');
});
}

let textbox = prompt("プレイヤーネームを入力して下さい");
if (textbox === '') {
let textbox = "noname";
$gameVariables.setValue(変数ID ,textbox)
sendHighScore($gameVariables.value(変数ID),$gameVariables.value(変数ID));

} else if (textbox === null) {
$gameVariables.setValue(変数ID,'キャンセルしました');

} else {
$gameVariables.setValue(変数ID ,textbox)
sendHighScore($gameVariables.value(変数ID),$gameVariables.value(変数ID));
}

スコア送信先URLファイル.php(下記PHPをサーバーにアップロードしてそのURLを記入)と変数IDをご自身のゲームに合わせて変更します。

拒否する言葉などがあればelse ifで設定します。
RPGツクールMZテキスト入力応答スクリプトを参考下さい)

最後にウエイトを入れて送信結果を表示すればスコア送信イベントは終了です。

次にランキングを表示するイベントを作ります。

fetch("スコアが保存されたファイル")
.then(response => response.json()) 
.then(data => {
// ランキングデータを変数に保存
$gameVariables.setValue(変数ID, data);
})

ファイルを読み込んで次のスクリプトへ行く前にウェイトをはさみます。

function displayHighScores() {
let highScores = $gameVariables.value(変数ID);
let sortedScores = [];

// highScoresオブジェクトを配列に変換
for (let [username, score] of Object.entries(highScores)) {
sortedScores.push({ username, score });

// ハイスコア比較用
$gameVariables.setValue(変数ID, score);
}

// スコアの降順でソート
sortedScores.sort((a, b) => b.score - a.score); 

let ranking = "ランキング\n";
sortedScores.forEach((entry, index) => {
ranking += `Rank ${index + 1}:${entry.username} スコア: ${entry.score}\n`;
});

let args = {text:ranking};
PluginManager.callCommand(this, "TextPicture", "set", args)
$gameScreen.showPicture(番号,"",原点,x座標,y座標,幅の拡大率,高さの拡大率,不透明度,合成方法)
}
displayHighScores();

複雑に見えますがRPGツクールMZテキストファイルを読み込んで画面に表示するスクリプトでやってる事と一緒です。

これでRPGツクールMZでの作業は終わりです。

後はWebサーバーにスコア送信用のPHPファイルをアップロードするだけです!

<?php
// セキュリティヘッダーの設定
header("Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self';");
header("X-XSS-Protection: 1; mode=block");
header("X-Frame-Options: DENY");
header("X-Content-Type-Options: nosniff");

// POSTリクエストのみを許可
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
http_response_code(405);
}

$username = isset($_POST['username']) ? $_POST['username'] : '';
$score = isset($_POST['score']) ? intval($_POST['score']) : 0;

// ファイルパス
$scoresFile = __DIR__ . '/ファイル名';

// ファイルの存在確認と書き込み権限チェック
if (!is_writable($scoresFile) && !is_writable(dirname($scoresFile))) {
http_response_code(500);
}

// 排他的ファイルロックを使用してファイルを読み込む
$fp = fopen($scoresFile, 'c+');
if (flock($fp, LOCK_EX)) {
$scores = file_get_contents($scoresFile);
$scores = $scores ? json_decode($scores, true) : [];

// 新しいスコアを追加または更新
if ($score > $scores[$username]) {
$scores[$username] = $score;

// スコアでソート
arsort($scores);

// 何位まで保存するか
$scores = array_slice($scores, 0, 5, true);

// ファイルに保存
file_put_contents($scoresFile, json_encode($scores));
flock($fp, LOCK_UN);
fclose($fp);

} else {
flock($fp, LOCK_UN);
fclose($fp);
}

} else {
fclose($fp);
http_response_code(500);
}
?>

自分の好きなファイル名.phpファイルを作ります。
(セキュリティの観点からファイル名は知られないようにして下さい)

次にスコアを保存するファイルを作ります。

JSONの形式でフォーマットされますがスコアを保存するファイルは.txtでも.jsonでも大丈夫です。

{"name1":50,"name2":40,"name3":30,"name4":20,"name5":10}


スコアを保存したファイルが無いとゲームが動かないのでとりあえずこちらを作ったスコア保存用のファイルに記入してください。

作った保存用のファイルは

// ファイルパス
の所の「ファイル名」の部分に作ったファイルのファイル名を記入します。

ファイル名を書いてサーバーにPHPをアップロードして、アップロードしたPHPのURLをRPGツクールMZのスクリプト内に記入して下さい。

これで簡単なランキングを表示させることが出来るゲームが作れるかと思います。

簡易的なものなので色々カスタムしてみて下さい♪

コメント