💨

kintoneで反応速度ゲームを作ってみた

2021/03/10に公開

はじめに

サイボウズが提供するクラウドサービス kintone は業務システムが作成できるプラットフォームです。本来は仕事で使うツールとして、

  • 案件管理
  • 顧客管理
  • 日報
  • タスク管理

等に使われるケースがほとんどですが、今回はそんな真面目な使い方ではなく、kintoneを ゲーム として使ってみた記事です。

不真面目 ネタ記事としてお楽しみください😏

作ったもの

  • プレイ動画

https://twitter.com/BB_File/status/1369249452238671876

  • イメージ写真

その名も KATANACTION!! カタナでアクションするゲームです⚔

使ったもの

  • カタナのおもちゃ × 2本
  • obniz(M5StickC版) × 2つ
  • obniz(ブロック倒す用) × 1つ
  • 磁気センサ × 2つ
  • 磁石 × 2つ
  • 発泡ブロック × 6つ
  • サーボモータ × 2つ

総額15,000円くらい。
カタナのおもちゃ はダイソーで売っていたものを分解して中にobnizを埋め込んでいます。
刀身に磁気センサを埋め込み、鞘側に磁石を付けています。

倒れる物体 は発泡ブロックを重ねていて、下の段にサーボモータを埋め込んでいます。
最初ソレノイドを使って押し上げる方法でやろうとしましたが、パワーが足りずモータで。

わりとちゃんと動く!
https://twitter.com/BB_File/status/1369249780715511811

システム構成図

kintoneのカスタマイズビュー(HTMLが自由に埋め込める場所)にVue.jsで作成したゲーム画面を埋め込んでいます。obnizを動かすJavaScriptプログラムはkintone上にアップロードしています。

ソースコード

全部載せると膨大になるので一部のみ抜粋します。

カタナ

磁気センサはボタンと同じ扱いなので、obnizのボタン操作のプログラムが使えます。

katana_sample.js
const katana1 = new Obniz.M5StickC('XXXX-XXXX'); // M5StickC用のメソッド
let count1 = 0;

katana1.onconnect = async function() {
  const sensor1 = katana1.wired('Button', {signal: 26, pull: '3v'});
  sensor1.onchange = async state => {
    if (!state) {
      count1++;
      // カウント数に応じてサーボモータを動かす処理を追記
    }
  };
};

鞘に磁石をつけることで「鞘を抜き差しすると磁気センサが反応してカウントアップ」されていきます。あとはカウント数に応じて処理を追記するだけです。

倒れる物体

obnizのサーボモータを操作するプログラムがそのまま使えます。

servo_sample.js
const block = new Obniz('XXXX-XXXX');

block.onconnect = async function() {
  servo1 = block.wired('ServoMotor', {gnd:0, vcc:1, signal:2});
  servo2 = block.wired('ServoMotor', {gnd:3, vcc:4, signal:5});
  servo1.angle(0);
  servo2.angle(0);

  // カタナの処理を組み合わせて servo?.angle(90)にする
};

カタナと倒れる物体のコードを合体

sample.js
const katana1 = new Obniz.M5StickC('XXXX-XXXX'); // Player1のカタナ用
const katana2 = new Obniz.M5StickC('XXXX-XXXX'); // Player2のカタナ用
const block = new Obniz('XXXX-XXXX'); // 倒れる物体用

let count1 = 0;
let count2 = 0;
let sensor1, sensor2, servo1, servo2;

// obnizのコネクション
katana1.onconnect = () => {
  sensor1 = katana1.wired('Button', {signal: 26, pull: '3v'});
};
katana2.onconnect = () => {
  sensor2 = katana2.wired('Button', {signal: 26, pull: '3v'});
};
block.onconnect = () => {
  servo1 = obniz.wired("ServoMotor", {gnd: 0, vcc: 1, signal: 2});
  servo2 = obniz.wired("ServoMotor", {gnd: 3, vcc: 4, signal: 5});
};

// カタナ1を抜き差ししたときのイベント
sensor1.onchange = async state => {
  if (!state) {
    count1++;
    if (count1 === 1) {
      // Player1が反応した

      if (count2 < 1) {
        // count1が1のときにcount2が1未満なら、Player1が先に動かしたことになる
        // => Player1の勝ち
        servo1.angle(90);
      }
    }
  }
};

// カタナ2を抜き差ししたときのイベント
sensor2.onchange = async state => {
  if (!state) {
    count2++;
    if (count2 === 1) {
      // Player2が反応した

      if (count1 < 1) {
        // count2が1のときにcount1が1未満なら、Player2が先に動かしたことになる
        // => Player2の勝ち
        servo2.angle(90);
      }
    }
  }
};

kintone側

kintone側はわりと無駄遣いをしていて、

  • ゲーム画面:ただのHTML画面として利用
  • ランキング画面:ただのHTML画面として利用(裏側でランキングデータをkintoneに格納)

といった感じで 「別にkintoneじゃなくても良くね?」 感満載ですw

ただ、kintoneをフロントにすることで、kintone JavaScript API が使えるのでkintone内のデータ操作はめちゃくちゃ楽です。
今回だと、サーボモータを servo?.angle(90) にした後、各Playerの反応速度をkintoneのDBへ格納するためにkintone JavaScript APIを使っています。

post_kintone_sample.js
const startTime = new Date().getTime();
let endTime1, endTime2;

// カタナ1を抜き差ししたときのイベント
sensor1.onchange = async state => {
  if (!state) {
    count1++;
    if (count1 === 1) {
      // Player1が反応した
      // スタートしてから反応までの時間
      endTime1 = (new Date().getTime() - startTime) / 1000;

      if (count2 < 1) {
        // count1が1のときにcount2が1未満なら、Player1が先に動かしたことになる
        // => Player1の勝ち
        servo1.angle(90);

        // kintoneへデータを登録する処理
        const postParams = {
          app: 'XXX',
          record: {
            winner: { value: 'Player1' },
            player1_time: { value: endTime1 },
            player2_time: { value: endTime2 },
          }
        };
        await kintone.api(kintone.api.url('/k/v1/record'), 'POST', postParams);
      }
    }
  }
};

おわりに

kintoneはビジネスツールですが、APIが搭載されたWeb DBなのでビジネス用途以外にもいろいろな使い方ができます。ぜひいろいろなものに使ってみてください!
無料の開発環境もありますよ〜

Discussion