LoginSignup
7
2

More than 3 years have passed since last update.

#PowerApps GameDev#5 通信対戦を実装してみた

Last updated at Posted at 2019-05-16

PowerApps Game Tech No5

通信対戦の仕組み

1.ゲームルームの作成及び参加

image.png

① 1P側がゲームルームを作成すると、Azure上のSQL Serverに生成したroom idと1Pの情報、ターン情報としてPendingとしてInsertする

② 2P側はターン情報がPendingとなっているroom id一覧を取得する

③ 選択したroom idのレコードに2Pの情報及びターン情報を1PTurnとしてUpdateする

2.ゲームの進行

image.png

① 1秒間隔で、参加中のroom idのレコードを参照する

② ターン情報が1PTurnとなっている場合にのみ攻撃ボタンが有効化される

③ 攻撃ボタンを押すと、1Pのステータスと2Pのステータス情報をもとに、ダメージ値を計算し、2PのHPを減算しUpdateする

④ ターン情報が2PTurnとなっている場合にのみ攻撃ボタンが有効化される

⑤ 攻撃ボタンを押すと、1Pのステータスと2Pのステータス情報をもとに、ダメージ値を計算し、1PのHPを減算しUpdateする

作り方

Azure SQL Server

SQL Serverの作成方法は割愛します。
作り方はこちらのようなサイトをご覧くださいませ
日商エレクトロニクスさんのブログ

テーブル構造

image.png

DDL文

PowerApps_NetBattle_Test_tbl.sql
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[PowerApps_NetBattle_Test_tbl](
    [room_id] [char](50) NOT NULL,
    [1PMAXHP] [int] NOT NULL,
    [1PCurrentHP] [int] NOT NULL,
    [1PPwr] [int] NOT NULL,
    [1PDfs] [int] NOT NULL,
    [1PSpd] [int] NOT NULL,
    [1PLcy] [int] NOT NULL,
    [1PMAXMP] [int] NOT NULL,
    [1PCurrentMP] [int] NOT NULL,
    [2PMAXHP] [int] NULL,
    [2PCurrentHP] [int] NULL,
    [2PPwr] [int] NULL,
    [2PDfs] [int] NULL,
    [2PSpd] [int] NULL,
    [2PLcy] [int] NULL,
    [2PMAXMP] [int] NULL,
    [2PCurrentMP] [int] NULL,
    [Turn] [char](10) NULL,
 CONSTRAINT [PK_PowerApps_NetBattle_Test_tbl] PRIMARY KEY CLUSTERED 
(
    [room_id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

PowerApps

0.App

アプリ起動時に実行される処理を定義します。

OnStart
//global_valiable
Set(Dist_Point,20);

//1P_global_valiable
Set(Pre_1p_Max_HP,20);
Set(Pre_1p_Current_HP,Pre_1p_Max_HP);
Set(Pre_1p_Pwr,1);
Set(Pre_1p_Dfs,1);
Set(Pre_1p_Spd,1);
Set(Pre_1p_Lcy,1);
Set(Pre_1p_Max_MP,3);
Set(Pre_1p_Current_MP,3);
Set(Pre_1p_Dist_Point,Dist_Point);
Set(Pre_Room_ID,GUID());

//2P_global_valiable
Set(Pre_2p_Max_HP,Pre_1p_Max_HP);
Set(Pre_2p_Current_HP,Pre_2p_Max_HP);
Set(Pre_2p_Pwr,0);
Set(Pre_2p_Dfs,0);
Set(Pre_2p_Spd,0);
Set(Pre_2p_Lcy,0);
Set(Pre_2p_Max_MP,Pre_1p_Max_MP);
Set(Pre_2p_Current_MP,Pre_2p_Max_MP);
Set(Pre_2p_Dist_Point,Dist_Point);

1.SelectScreen

ここではボタンを二つ作成します。
image.png

新しく部屋を作成するボタン

ボタンを押すと以下の処理が実行されるように宣言します。

OnSelect
Navigate(CreateRoom,ScreenTransition.Fade)

部屋に参加するボタン

ボタンを押すと以下の処理が実行されるように宣言します。

OnSelect
Navigate(JoinRoom,ScreenTransition.Fade)

2.CreateRoom

こんな画面になります。
image.png

各パラメータを操作する部分はこちらの記事を参考に作成してください。
PowerAppsでバトルゲームを作ろう!(その1:パラメータ設定画面)

画面遷移ボタン

ボタンを押すと以下の処理が実行されるように宣言します。

OnSelect
Patch(
    '[dbo].[PowerApps_NetBattle_Test_tbl]',
    Defaults('[dbo].[PowerApps_NetBattle_Test_tbl]'),
    {
        room_id: Pre_Room_ID,
        '1PMAXHP': Pre_1p_Max_HP,
        '1PMAXMP': Pre_1p_Max_MP,
        '1PCurrentHP': Pre_1p_Max_HP,
        '1PCurrentMP': Pre_1p_Max_MP,
        '1PPwr': Pre_1p_Pwr,
        '1PDfs': Pre_1p_Dfs,
        '1PSpd': Pre_1p_Spd,
        '1PLcy': Pre_1p_Lcy,
        Turn: "Pendding"
    }
);
Set(
    CurrentRoomID,
    Pre_Room_ID
);
Navigate(
    BattleView,
    ScreenTransition.Fade
)

3.JoinRoom

こんな画面になります。
image.png

参加する部屋の選択制御

部屋を選択するドロップダウンボックスはこのように宣言します。

Items
Filter('[dbo].[PowerApps_NetBattle_Test_tbl]',Turn="Pendding").room_id

画面遷移ボタン

ボタンを押すと以下の処理が実行されるように宣言します。

OnSelect
Set(
    CurrentRoomID,
    Dropdown1.SelectedText.Value
);
Patch(
    '[dbo].[PowerApps_NetBattle_Test_tbl]',
    First(
        Filter(
            '[dbo].[PowerApps_NetBattle_Test_tbl]',
            room_id = Dropdown1.SelectedText.Value
        )
    ),
    {
        '2PMAXHP': Pre_2p_Max_HP,
        '2PMAXMP': Pre_2p_Max_MP,
        '2PCurrentHP': Pre_2p_Max_HP,
        '2PCurrentMP': Pre_2p_Max_MP,
        '2PPwr': Pre_2p_Pwr,
        '2PDfs': Pre_2p_Dfs,
        '2PSpd': Pre_2p_Spd,
        '2PLcy': Pre_2p_Lcy,
        Turn: "1PTurn"
    }
);
Navigate(
    BattleView,
    ScreenTransition.Fade
)

4. BattleView

こんな画面になります
image.png

ステータス表示部

HP部分はこんな風になっています。

Text
Concatenate(
    "HP:",
    Text(
        First(
            Filter(
                '[dbo].[PowerApps_NetBattle_Test_tbl]',
                room_id = CurrentRoomID
            )
        ).'1PCurrentHP'
    ),
    "/",
    Text(
        First(
            Filter(
                '[dbo].[PowerApps_NetBattle_Test_tbl]',
                room_id = CurrentRoomID
            )
        ).'1PMAXHP'
    )
)

攻撃ボタン

攻撃ボタン(1PTurnと2PTurn)は、ボタン操作を制御するプロパティ(DisplayMode)と押したときに処理が実行されるプロパティ(OnSelect)を設定しています。
今回の処理は検証のために複雑なダメージ計算式などは除外、簡略化しています。

DisplayMode
If(
    First(
        Filter(
            '[dbo].[PowerApps_NetBattle_Test_tbl]',
            room_id = CurrentRoomID
        )
    ).Turn = "1PTurn",
    DisplayMode.Edit,
    Disabled
)
OnSelect(1PTurn)
Set(
    Pre_2p_Current_HP,
    First(
        Filter(
            '[dbo].[PowerApps_NetBattle_Test_tbl]',
            room_id = CurrentRoomID
        )
    ).'2PCurrentHP' - 1
);
Patch(
    '[dbo].[PowerApps_NetBattle_Test_tbl]',
    First(
        Filter(
            '[dbo].[PowerApps_NetBattle_Test_tbl]',
            room_id = CurrentRoomID
        )
    ),
    {
        '2PCurrentHP': Pre_2p_Current_HP,
        Turn: "2PTurn"
    }
)
OnSelect(2PTurn)
Set(
    Pre_1p_Current_HP,
    First(
        Filter(
            '[dbo].[PowerApps_NetBattle_Test_tbl]',
            room_id = CurrentRoomID
        )
    ).'1PCurrentHP' - 1
);
Patch(
    '[dbo].[PowerApps_NetBattle_Test_tbl]',
    First(
        Filter(
            '[dbo].[PowerApps_NetBattle_Test_tbl]',
            room_id = CurrentRoomID
        )
    ),
    {
        '1PCurrentHP': Pre_1p_Current_HP,
        Turn: "1PTurn"
    }
)

SQL Serverの情報取得タイマー

現在のレコードの内容を取得するタイマーです。
1秒毎に繰り返す設定をしています。
タイマーがスタートしたときに以下の処理が実行されるように宣言します。

OnTimerStart
Refresh('[dbo].[PowerApps_NetBattle_Test_tbl]')

データソースについて

今回異なるテナントでも通信対戦ができるようにとデータソースとしてSQL Serverを使用しました。一番格安なBasicプランでも、サクサク動作するようです。
使用者が増えたりした場合は順次Standardなどに切り替えればよろしいかと思います。

まとめ

やってる内容については実はあまり大したことをしていません。
仕組みも理解できれば案外単純なのか!とおもったり・・・。
実際はトランザクション処理などいろいろ大変だとは思いますが。使い方が個人利用レベルであればこの程度でも十分でしょう。
これをもとにバーコードバトラーを改造しようかなと考えています。

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2