Flutter3.0+Firebaseを使ってiOS/Android/Webで操作できるオンラインゲームの基礎部分アプリを作ってみた!

はじめに

はじめまして。
株式会社アドグローブ ソリューション事業部アプリエンジニアの佐藤です。
会社では要件定義から設計、アプリ開発、テストまでその時々に応じて幅広く担当しています。

さて!
2022年5月にFlutter3.0.0がリリースされました!! docs.flutter.dev 今回の3.0.0から、今まで以上にさまざまなプラットフォームに対応できるようになりました。

対応プラットフォーム

・iOS
・Android
・Web
・Windows
・macOS
・Linux
・Embedded

上記のようにプラットフォームが増えたことを活用して、
今回は私の手元にあるiOS/Android/Web環境で操作できるオンラインゲームの基礎部分のアプリを作ってみました。

ゴール

Flutter+Firebaseを使って、iOS/Androidのアプリ化!
Webはブラウザから操作を行い、オンラインゲームの基礎部分っぽいものを作る。

完成品はこちら

www.youtube.com 満足いく動きとなりました!😚
最近よく見かける、バーチャルオフィス/イベントの下地のようなものができました。
(動画では、見やすさ重視でシミュレータで実施しましたがもちろん外のネットワークからも動きます)
では、さっそく中身のコア機能についてご紹介していきたいと思います。

環境

flutter doctor
[✓] Flutter (Channel stable, 3.0.0, on macOS 12.3 21E230 darwin-x64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 13.3.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.1)

ライブラリ

dependencies:
  #FireBaseCoreとFireStoreのバージョン。
  firebase_core: ^1.17.1
  cloud_firestore: ^3.1.17

コア機能紹介

今回はコア機能のみ紹介します。
「FlutterとFireBaseを使えば、簡単にできるよ!」ということが伝われば嬉しいです。

下記流れで作成しています。

  1. ログインボタン押下時にFirebaseFireStoreにユーザー追加
  2. ユーザー追加完了コールバックにて、現在マップに居るユーザー一覧取得し、描画する
  3. 自身が動いたらFirebaseFireStoreに都度データを更新する
  4. FireBaseFireStoreから変更データを都度受け取る


準備

データを扱いやすいようにユーザークラスを作成し、メンバー変数として持たせてます。

// firebaseのインポートも忘れずに!
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class User{
  String id = "";
  String name = "";
  double x = 0.0;
  double y = 0.0;
}

class _GamePageState extends State<GamePage> {
  var myUser = User();
  List<User> users = [];
1.ログインボタン押下時にFirebaseFireStoreにユーザー追加
class _GamePageState extends State<GamePage> {
  // FirebaseFirestoreのコレクションをuserで初期化します。
  CollectionReference usersCollection = FirebaseFirestore.instance.collection('users');

  var myUser = User();

  @override
  void initState() {
    super.initState();
    addMyUser();
  }

  // 初回
  addMyUser() async {
    // ユーザーコレクションに、任意のIDで追加します。
    usersCollection.add({
      'name': widget.name,
      'x': 0.0,
      'y': 0.0,
      'date' : DateTime.now()
    }).then((value) {
      // 成功コールバックmyUserは
      myUser.id = value.id;
      myUser.name = widget.name;
      myUser.x = 0.0;
      myUser.y = 0.0;
    }).catchError((error) {
      print(error);
    });
  }
2.ユーザー追加完了コールバックにて、現在マップに居るユーザー一覧取得し、描画する
  oneshotGetUserCollection(){
    // ユーザーコレクションからすべてのデータを取る。
    usersCollection.get().then((element) {

      // ドキュメントを配列で受け取るため、for分で回す。
      for (var i = 0; i < element.docs.length; i++) {
        var doc = element.docs[i];

        // 自身以外をメンバー変数に保持。
        if (doc.id == myUser.id) {
          continue;
        }
        var other = User();
        other.id = doc.id;
        other.x = double.parse(doc.get("x").toString());
        other.y = double.parse(doc.get("y").toString());
        other.name = doc.get("name");
        users.add(other);
      }
    });
  }
3.自身が動いたらFirebaseFireStoreに都度データを更新する

自身が動いたらFireStoreにupdate処理を掛けます。

 updateLocation(double x , double y){
    // ユーザーコレクションの自身のIDを更新。
    usersCollection.doc(myUser.id).update({
        'x': x,
        'y': y,
        'date' : FieldValue.serverTimestamp()
    });
  }
4.FireBaseFireStoreから変更データを都度受け取る

snapshotsを使えば、都度変更通知を受け取ることができます。

 setCollectionListen() async {
    // ユーザーコレクションから変更通知を受け取る。
    usersCollection.snapshots().listen((event) {

      // 配列分回す。
      for (var i = 0; i < event.docChanges.length; i++) {

        var change = event.docChanges[i];
        switch(change.type) {
          // 追加
          case DocumentChangeType.added:
       ~~~
            break;

        // 変更
          case DocumentChangeType.modified:
       ~~~
            break;

        // 削除
          case DocumentChangeType.removed:
       ~~~
            break;
        }
      }
    });
  }

まとめ

いかがでしたでしょうか?
Flutter+Firebaseを使えば、このように簡単なオンラインゲーム形式のアプリを作成することができます。
機会があれば、次回はmacOSやWindowsアプリなどの開発にもチャレンジしてみたいと思います!

こちらの記事でFlutterやアプリ開発に少しでも興味を持っていただければ幸いです。
最後までお読みいただきありがとうございました。