【PHP】RPGゲームを作る2(マップチップエディタ)

MySQL
map_chip編集画面

マップデータをDBで管理しようと思い、マップデータを作る管理者ページを作成しました。先ずはマップ用素材(mapchip)を作り、マップ編集画面でmapchipを選択するイメージです。
イベントはマップデータにテキストフィールド持たせておいて、後から考えようと思っています。

環境

 OS ubuntu22.04 
 Webサーバ apache2.4.52
(自身のIP 192.168.19.128、公開フォルダ /var/www/html/php/rpg)
 PHP 8.1.2-1ubuntu2.14
 DB MySQL Ver 8.0.34-ubuntu0.22.04.1

マップ用素材(mapchip)作成画面

まずは次のSQLでmapchip用のテーブルを作成します。

create table map_chip(chip_no int primary key,filename varchar(30),descript text);

 次は、次のPHPを作成して
   /var/www/html/php/rpg/
に配置し、パーミッションを705にしました。
 ファイル名 map_chip.php

<!DOCTYPE html>
<html>
<body>
<?php
$DEF_UPDATE = "update";
$DEF_INSERT = "insert";
// MySQL接続情報
$servername = "192.168.19.128"; // データベースのホスト名
$username = "********"; // データベースのユーザー名
$password = "********"; // データベースのパスワード
$dbname = "****"; // 使用するデータベース名
$do="";
$do_no="";
$do_filename="";
$do_do_descript="";
$map_chips="";
?>
<script type="text/javascript">
<!--
function updateForm(param){
	if(document.getElementById("filename_"+param).value =="") {
		alert("ファイル名を入力してください");
		exit;
	}
	document.getElementById("do").value="<?php echo $DEF_UPDATE ?>";
	document.getElementById("do_no").value=param;
document.getElementById("do_filename").value=document.getElementById("filename_"+param).value;
	document.getElementById("do_descript").value=document.getElementById("descript_"+param).value;
	document.update.submit();
}
function insertForm(param){
	if(document.getElementById("filename_"+param).value =="") {
		alert("ファイル名を入力してください");
		exit;
	}
	document.getElementById("do").value="<?php echo $DEF_INSERT ?>";
	document.getElementById("do_no").value=param;
	document.getElementById("do_filename").value=document.getElementById("filename_"+param).value;
	document.getElementById("do_descript").value=document.getElementById("descript_"+param).value;
	document.update.submit();
}
-->
</script>
<h1>MAP_CHIP編集画面</h1>
<?php
//db読込
// MySQLサーバーへの接続
$conn = new mysqli($servername, $username, $password, $dbname);
// 接続エラーの確認
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
//UPDATE INSERT
if ($_SERVER['REQUEST_METHOD'] === 'POST' 
	&& isset($_POST['do'])
	&& isset($_POST['do_no'])
	&& isset($_POST['do_filename'])
	&& isset($_POST['do_descript'])){
	$do = $_POST['do'];
	$do_no=$_POST['do_no'];
	$do_filename=$_POST['do_filename'];
	$do_descript=$_POST['do_descript'];

	if($do === $DEF_UPDATE){
		$stmt = $conn->prepare("UPDATE map_chip SET filename = ? , descript = ? WHERE chip_no = ?");
		$stmt->bind_param("ssi", $do_filename, $do_descript, $do_no);
		if ($stmt->execute()) {
		    echo "レコードが更新されました";
		} else {
		    echo "Error: " . $stmt->error;
		}
	} elseif($do === $DEF_INSERT){
		$stmt = $conn->prepare("INSERT INTO map_chip( chip_no , filename , descript ) VALUES (?,?,?)");
		$stmt->bind_param("iss", $do_no , $do_filename , $do_descript);
		if ($stmt->execute()) {
		    echo "レコードに追加されました";
		} else {
		    echo "Error: " . $stmt->error;
		}
	}
} 
// クエリの実行と結果の取得
$sql = "SELECT chip_no,filename,descript FROM map_chip";
$result = $conn->query($sql);
$count =0;
echo '<form action="" name="update" method="post">';
echo '<input type="hidden" name="do" id="do" value="">';
echo '<input type="hidden" name="do_no" id="do_no" value="">';
echo '<input type="hidden" name="do_filename" id="do_filename" value ="">';
echo '<input type="hidden" name="do_descript" id="do_descript" value ="">';
if ($result->num_rows > 0) {
    // 取得したデータの表示
    echo "<table border='1'><tr><td>No</td><td>ファイル名(./00.png 等)</td><td>説明(海、砂浜 等)</td></tr>";
    while($row = $result->fetch_assoc()) {
    	$count++;
        echo "<tr><td>";
        echo "<input type='text' value='" . $row["chip_no"] . "' size=3 readonly>";
        echo "</td><td>";
        echo "<input type='text' id='filename_".$count."' value='" . $row["filename"] . "'  size=15><img src='" . $row["filename"] . "' width='20px'>";
        echo "</td><td>";
        echo "<input type='text' id='descript_".$count."' value='" . $row["descript"] . "'  size=6>";
        echo "</td><td>";
        echo "<button type='button' onclick='updateForm(".$count.");' >UPDATE</button>";
        echo "</td></tr>";
    }
    //新規登録用
    $count++;
    echo "<tr><td>";
    echo "<input type='text' value='" . $count . "' size=3 readonly>";
    echo "</td><td>";
    echo "<input type='text' id='filename_".$count."' value='' size=15>";
    echo "</td><td>";
    echo "<input type='text' id='descript_".$count."'  value='' size=6>";
    echo "</td><td>";
    echo "<button type='button' onclick='insertForm(".$count.");' >INSERT</button>";
    echo "</td></tr>";
    echo "</table>";
} else {
    echo "0 results";
}
echo '</form>';
$conn->close();
echo '<A href="./map_edit.php">マップ編集画面へ</a><br>';
echo '<A href="./map_chip.php">reload</a><br>';
echo 'ファイル名の横に画像が表示されていれば、リンクは正常です。<br>';
echo '表示されない場合、リンク先に画像があるか、パーミッションに読込権限がついているか確認してください。';
?>
</body>
</html>

 次にマップ用の画像データを読み込ませる必要があるので、こちらの環境では、
/var/www/html/php/rpg/img/
フォルダを作成し、この中にマップ用IMGを置いています。
 こちらの環境では、「00.jpg」「01.jpg」といった感じの正方形の画像ファイルを用意しました。
 動画GIFを使うと動きがあるページになると思います。
 画像は、フリー素材のIllustAC様からドットイラストをダウンロードさせていただきました。
 縦横が20pxくらいのイメージですので、32×32ピクセルくらいのドットイラストを想定しています。
 imgフォルダのパーミッションを、705にすることと、この中に配置するIMGファイルのパーミッションを604にすることを忘れないようにしてください。
 動かすとこんな感じになります。

map_chip編集画面を起動させた様子。
適当な地図や人物を登録した様子です。

 マップの説明文は、TEXTフィールドですので長文も記載できますが、3文字くらいまでにしておいた方がいいと思います。(後からわかります)
 管理者用の画面なので、今のところ削除機能はついていません。