SHIROのIchigoJam日記

マイコン「IchigoJam」(イチゴジャム)の電子工作とプログラミングをメインに

100mダッシュ・ネット対戦

IchigoJam+MixJuice(Wi-fiボード)で100mダッシュゲームのプログラムを作って、ネット対戦するプログラミング教室用Webサイトの作り方です。
f:id:shiro0922:20210515183627p:plain
★注意★ 簡単なプログラムなのでセキュリティを一切考えていません。教室を行う時だけサイトを設置して、終わったら削除や移動をするようにしてください。置きっぱなしにすると、悪意のある人にアクセスされてデータベースを破壊されたり乗っ取られたりする危険性があります。

上記の乗っ取りなどを防ぐために、教室内にサーバーPCとWi-fiルーターを置いて、ローカルネット環境で動かすことをお勧めします。

準備

■Webサーバー

PHPMySQLが動くWebサーバーを用意します。
新規に作るならXAMPPなどを利用すると良いでしょう。

MySQLのデータベース、テーブル

phpMyAdminなどを使って、タイムを記録するデータベース(例「100m」)を新規に作ります。
その中に「usertime」テーブルを作成して、「userid」列(text型)にユーザー名、「time」列(int11型)に仮のタイムを入れておきます。
f:id:shiro0922:20210515181130p:plain

■ページの設置

www.example.jp/dir/(サイトのアドレス)内に、以下のWebページファイルを設置します。

db_login.php

ログイン情報を入れるファイルです。
dbnameはデータベース名、usernameはデータベースにアクセスするユーザー名、passwordはそのユーザーのパスワードを記述します。

<?php
$db_host='localhost';
$db_database='dbname';
$db_username='username';
$db_password='password';
?>
index.php

タイムの一覧表を表示するファイルです。10秒ごとに表示が自動更新されます。
※7/11修正:タイム表示をIchigoJamと同様に切り捨て計算に修正。
※7/25修正:順位の数字を表示。

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>100mダッシュ対決</title>
<link rel="stylesheet" href="styles.css" type="text/css" />
<meta http-equiv="refresh" content="10; URL=">
</head>

<body>
<h1>100mダッシュ対決</h1>

<?php

// ログイン情報のインクルード
include('db_login.php');

// データベースサーバーへ接続
$connection = mysqli_connect($db_host, $db_username, $db_password, $db_database);
if (!$connection) {
	die ("DB接続エラー<br />". mysql_error());
}

// === usertimeテーブルから一覧表 ===

// 一覧表クエリを作成
$query = "SELECT * FROM usertime ORDER BY time";

// クエリを実行
$result = mysqli_query($connection, $query);
if (!$result) {
	die ("DBクエリエラー<br />". mysql_error());
}

// 結果から一覧表を表示
echo "<table>\r\n";
echo "<tr><th>No.</th><th>ID</th><th>Time</th></tr>\r\n";

$n = 0;

foreach ($result as $row) {
	$n = $n + 1;
	$t = floor($row['time'] / 60);
	$s = floor(($row['time'] - $t*60) / 6);
	echo "<tr><td>$n</td><td>" . $row['userid'] . "</td><td>" . $t . "." . $s . "</td></tr>\r\n";
}

echo "</table>\r\n";

// === 終了処理 ===

// データベース接続を閉じる
mysqli_close($connection);

?>

</body>
</html>
styles.css

一覧表ページの見栄えを設定するスタイルシートです。お好みで改造してください。

html {
background-color: #FFFFFF;
font-family: sans-serif;
}

body {
margin: 20px auto 10px auto;
width: 920px;
text-align: center;
font-size: middle;
line-height: 1.3em;
color: #000000;
}

h1 {
height: 40px;
margin: 0px;
padding-left: 10px;
font-size: 18pt;
line-height: 40px;
color: #000000;
}

table {
margin: 10px auto 10px auto;
border-style: solid;
border: 2px solid #8888ff;
}

th {
text-align: center;
font-size: 14pt;
padding: 2px;
border: 1px solid #8888ff;
}

td {
font-size: 14pt;
padding: 2px;
border: 1px solid #8888ff;
}
100.php

タイムのデータを書き込むファイルです。
「receive.log」にアクセスログが出力されます。もしデータベース接続エラーなどが出た場合は、このログを参照してください。
※7/20更新:新記録が出た時だけテーブルのデータを更新するように修正

<?php

// ログイン情報のインクルード
include('db_login.php');

// データ受信

if (isset($_GET['time'])) {

	$strParas = $_GET['time'];
	
	$strPara = explode(",", $strParas);
	$strID = $strPara[0];
	$strTime = $strPara[1];
	
	// ログファイルの相対パス
	$strDataFilePath = 'receive.log';

	// ログファイルを追記モードでオープン
	$fp = fopen($strDataFilePath, "a");

	// 日付、時刻を取得
	date_default_timezone_set('Asia/Tokyo');
	$dt = new DateTime();
	$strDateTime = $dt->format('Y-m-d H:i:s');
	$strDate = $dt->format('Y-m-d');
	$ms = substr(microtime(), 2, 2);
	$strDateTime = $strDateTime . "." . $ms;

	// 受信した値をログファイルに書き込み
	fwrite($fp, $strDateTime . ',ID=' . $strID . ',Time=' . $strTime . "\r\n");

	// データベースサーバーへ接続
	$connection = mysqli_connect($db_host, $db_username, $db_password, $db_database);
	if (!$connection) {
		fwrite($fp, "DB接続エラー\r\n");
		die ("DB接続エラー<br />". mysql_error());
	}

	// === usertimeテーブルからデータ読み込み ===

	// データ読み込みクエリを作成
	$query = "SELECT time FROM usertime WHERE userid = '$strID'";

	// クエリを実行
	$result = mysqli_query($connection, $query);
	if (!$result) {
		fwrite($fp, "データ読み込みエラー\r\n");
		die ("データ読み込みエラー<br />". mysql_error());
	}

	$row = mysqli_fetch_assoc($result);
	$strTblTime = $row['time'];

	// === 新記録だったらusertimeテーブルを更新 ===

	if ($strTime < $strTblTime) {

		// データ変更クエリを作成
		$query = "UPDATE usertime SET time = '$strTime' WHERE userid = '$strID'";

		// クエリを実行
		$result = mysqli_query($connection, $query);
		if (!$result) {
			fwrite($fp, "データ更新エラー\r\n");
			die ("データ更新エラー<br />". mysql_error());
		}

	}

	// === 終了処理 ===

	// データベース接続を閉じる
	mysqli_close($connection);

	// ログファイルポインタをクローズ
	fclose($fp);

}

?>
reset.php

このファイルにアクセスすると、テーブルの全タイムデータを3600(60秒)にリセットします。

<?php

// ログイン情報のインクルード
include('db_login.php');

// データ受信
echo '<h1>100m Dash データリセット</h1>';
echo "\n";

// データベースサーバーへ接続
$connection = mysqli_connect($db_host, $db_username, $db_password, $db_database);
if (!$connection) {
	die ("DB接続エラー<br />". mysql_error());
}

// === usertimeテーブルを更新 ===

// データ変更クエリを作成
$query = "UPDATE usertime SET time = 3600";

// クエリを実行
$result = mysqli_query($connection, $query);
if (!$result) {
	die ("データ更新エラー<br />". mysql_error());
}

// === 終了処理 ===

// データベース接続を閉じる
mysqli_close($connection);

?>

■ページの動作テスト

PCのブラウザで「www.example.jp/dir/index.php」を開くと、一覧表ページが表示されます。
タイムは秒数(テーブルの数値を60で割った値)で表示されます。
f:id:shiro0922:20210515182237p:plain
ブラウザの別ウインドウで、書き換えページへ以下のようにアクセスすると、タイムが書き換えられます。

www.example.jp/dir/100.php?time=UEDA01,678

「UEDA01」はusertimeテーブルのユーザー名(userid)に対応させます。
2番目の数字はタイムです。(TICK値なので60で1秒)
タイムを書き換えた後、一覧表ページでタイムが更新されることを確認してください。

教室での使い方

(1)IchigoJam+MixJuiceを動かして、Wi-fiアクセスポイントに接続します。

?”MJ APC ssid password”

ssidWi-fiアクセスポイントのSSID、passwordはパスワードです。ちゃんと接続するまで1分ほど待ってください。
(一度接続するとその設定が記憶され、次回は入力しなくても自動接続されます)

(2)100mダッシュのプログラムを作り、最後にMixJuiceコマンドでタイムを送信する行を追加します。プログラムを実行して100m走ると、タイムが送信されます。

f:id:shiro0922:20210515183104p:plain

5 CLT
10 ?CHR$(251);
15 FOR R=1 TO 100
17 IF !BTN(32) CONT
18 IF BTN(32) CONT
20 ?CHR$(8,46,251);
30 NEXT
40 T=TICK()
50 ?:?T/60;".";T%60/6
60 ?"MJ GET www.example.jp/dir/100.php?time=UEDA01,";T

60行の「UEDA01」はusertimeテーブルのユーザー名(userid)に対応します。
それぞれのIchigoJamで別のIDにしてください。

(3)PCのブラウザで一覧表ページ「www.example.jp/dir/index.php」を開くと、タイムが一覧で表示されます。タイムが速い順でソート表示され、10秒ごとに自動更新されます。

f:id:shiro0922:20210515183627p:plain
ユーザーIDを区別して、usertimeテーブルに設定しておけば、遠隔地の教室同士でもネット対戦できます。

IchigoSodaで使うsakura.io LTEモジュールが近々製造終了ということで、MixJuiceを使った通常のWi-fiネット接続で100mダッシュ対決ができないかと思って、作ってみました。