LoginSignup
50
20

More than 1 year has passed since last update.

ノンプログラマーがSymbolブロックチェーンでゲームを作ってみた

Last updated at Posted at 2021-12-04

この記事は nem Advent Calendar 2021 5日目の記事です。

はじめに

プログラム経験ゼロでも、Symbolというブロックチェーンを利用すれば
Web環境とテキストメモだけ
で、ブロックチェーンゲームが作れます。

はじめてのプログラムはSymbolブロックチェーンから、
冬休みの学びに、是非お楽しみください。

自己紹介

日常生活でプログラムに一切触れない 仕事をしつつ

nembear(ねむぐま)

という名前で、暗号通貨Symbol界隈で開発以外の活動をしております。

そんな私でも、ほぼコピペでSymbolを利用した独自のブロックチェーンゲームを作ることが出来たので、皆さんにも紹介します。

本記事で作るブロックチェーンゲーム

ブロックチェーンを利用したスロットゲームを作ります。3つの数字が揃えば、「symbol:xym」というトークンが送信される仕組みです。このトークンの送信の部分にSymbolのブロックチェーンを利用します。この記事を読めば、このゲームだけでなくあなたのオリジナルブロックチェーンゲームをほぼコピペで作成することが出来るようになります。

※アドカレ用にnembearトークンがもらえるバージョンを作りました。とても簡単なゲームですので是非、遊んでください。
↓↓↓↓↓↓

必要な環境とスキル

【環境】
・インターネット接続環境
・Google Chromeブラウザ
・テキストメモ

【スキル】
・コピー&ペースト

開発までの流れ

1.SymbolWalletを手に入れる(約5分)

2.Symbol送金プログラムを書いて体験する(約20分)

3.ボタンを押すとSymbol送金されるWebアプリ作成(約10分)

4.スロットゲームにSymbol送金を組み合わせる(自由時間)

5.完成(自由時間)

※イメージ
1.スロットに利用するコインを保管する金庫を作ります。

2.コインの保管と金庫からコインを送信する仕組みを学びます。

3.2で学んだ仕組みを利用して、簡単なアプリを作ります。

4.上記までの学びを利用して、スロットゲームに組み込みます。

5.実際に遊んでみましょう!

Symbolブロックチェーンゲーム作成方法

1.SymbolWalletを手に入れる(約5分)

ここではスロットに利用するコインを保管する"金庫"を作ります。
その"金庫"となるものが「SymbolWallet」です。これは暗号資産Symbol:XYMを保管するために最もポピュラーでセキュリティの高いWalletとなります。
テキストと動画で同じ内容の作成方法を説明します。お好みに合わせて選択してください。

■テキストでの説明はこちらから
※ポイント:リンク先の「項目3-4」では必ず「TESTNET」を選択してください。

■動画での説明はこちらから
※ポイント:動画内のSymbolWalletはこちらからダウンロードしてください。
↓↓↓
https://github.com/symbol/desktop-wallet/releases


2.Symbol送金プログラムを書いて体験する(約20分)

ここでは、コインの保管と金庫からコインを送信する仕組み を学びます。
前項目で作成した「金庫:SymbolWallet」に、ゲーム内で利用するコインを保管します。そして保管したコインを送信するところまでを、プログラムで体験してもらいます。ここで言うコインとはSymbolのトークンである「XYM」です。(テスト用のXYMの為、購入する必要はありません。)

ここからSymbolブロックチェーンに触れることになりますが、すべてコピペで体験出来ます。リラックスしてお進みください。Symbolがいかに簡単で誰にでも使いやすいものであるかを感じてもらえますと幸いです。

※ポイント:本項目は @nem_takanobu さんの記事を参考に実施しております。以下のリンク記事を開いて動画をご覧ください。


3.ボタンを押すとSymbol送金されるWebアプリ作成(約10分)

ここでは、項目2で学んだ仕組みを利用して、簡単なアプリを作ります。 先ほどはコンソール画面にコードを打ち込んで送金を体験しました。操作は簡単ではありましたが、毎回何度もあの操作を繰り返すのは大変ですよね?ですので、送信までの動作をボタン1つにまとめて、ボタンを押せばSymbolブロックチェーンを利用して送信される装置を作ってみましょう。

3-1.ボタンを押すと動作が発生するベースを作る

■準備するもの
→テキストエディタ(メモ帳でOK)

■手順
1.以下のコードをすべてテキストエディタにコピペし、保存する。
2.保存したテキストの名前を「test.html」に変更する。
3.「test.html」をダブルクリックする。

早速、以下のコードをテキストエディタにコピペしましょう。

test.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>nembear nemAdventCalendar2021</title>
</head>

<body>

    <p>button click</p>

    <input type="button" value="button" id="btn">

    <script>
        function butotnClick() {
            alert('Ok');
        }

        let button = document.getElementById('btn');
        button.addEventListener('click', butotnClick);
    </script>

</body>

</html>

時々質問で、↑のコードが良く分からない。という話を聞きますが、私も良く分かりません。私たちはエンジニアではないので、読める必要は無いのです。上記のサンプルも「html ボタン クリック」でWeb検索し、1番最初に上がってきた記事のサンプルを使ってます。深く考えるのはあとで、先ずは実践していきましょう。

次に、コピペしたテキストの名前を「test.html」として保存します。
1.png
「test.html」をダブルクリックしてください。
こんな画面が出てきたと思います。
2.png
「button」をクリックしてみましょう。
3.png
「Ok」のPOPが表示されました。おめでとうございます。これで、ボタンを押すと何かしら動作する(これなら「Ok」のPOPが出る)装置が完成しました。次の項目で、この装置にSymbolブロックチェーンの送金部分を投入してみましょう。

3-2.ボタンを押すとSymbol:XYMが送信されるアプリを作る

■準備するもの
→テキストエディタ(メモ帳でOK)

■手順
1.以下のコードをすべてテキストエディタにコピペし、保存する。
2.保存したテキストの名前を「test2.html」に変更する。
3.「test2.html」をダブルクリックする。

※ポイント:先ほど作った「test.html」の中身を確認すると、以下の部分がどうやら「Ok」POPが出るための呪文のようです。(試しに、この'Ok'を他の言葉に変えると、変えた内容のPOPが出ます。)

function butotnClick() {
            alert('Ok');
        }

つまり、ボタンを押すと、「 alert('Ok'); 」の処理が動くということです。だとしたらば、項目2で実施したSymbol送金のコードをすべてここに書き込めば、ボタン押すだけで送金出来るのではないでしょうか?

早速、以下のコードをテキストエディタにコピペしましょう。

※ポイント:項目2の動画で一緒に入力していたコードをそのまま利用してます。秘密鍵とアドレスだけ、あなたが作成したSymbolWalletのものを入力してください。

test2.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>nembear nemAdventCalendar2021</title>
</head>

<body>
    <!-- 設定値の定義とライブラリのインポート&ライブラリのインスタンス生成 -->
    <script src="https://xembook.github.io/nem2-browserify/symbol-sdk-1.0.1.js"></script>
    <script language="JavaScript">

        NODE = 'https://sym-test-09.opening-line.jp:3001';
        GENERATION_HASH = '7FCCD304802016BEBBCD342A332F91FF1F3BB5E902988B352697BE245F48E836';
        EPOCH_ADJUSTMENT = 1637848847;
        nem = require("/node_modules/symbol-sdk");

    </script>

    <p>button click</p>

    <input type="button" value="button" id="btn">

    <script>
        function butotnClick() {
            // アカウントの登録(自分のWalletの秘密鍵を入れてください)
            alice = nem.Account.createFromPrivateKey('あなた自身のSymbolWalletの秘密鍵を入力', nem.NetworkType.TEST_NET);
            console.log(alice);

            // トランザクション作成(自分のWalletのアドレスを入れてください)
            tx = nem.TransferTransaction.create(
                nem.Deadline.create(EPOCH_ADJUSTMENT),
                nem.Address.createFromRawAddress("あなたのSymbolアドレスを入力"),
                [new nem.Mosaic(new nem.MosaicId('3A8416DB2D53B6C8'), nem.UInt64.fromUint(1000000))],
                nem.PlainMessage.create('nemAdventCalendar2021'),
                nem.NetworkType.TEST_NET,
                nem.UInt64.fromUint(100000)
            );

            console.log(tx);
            // 署名
            signedTx = alice.sign(tx, GENERATION_HASH);

            console.log(signedTx);

            // 署名したトランザクションをネットワークにアナウンス
            new nem.TransactionHttp(NODE)
                .announce(signedTx)
                .subscribe((x) => console.log(x), (err) => console.error(err));

            alert('Ok');
        }

        let button = document.getElementById('btn');
        button.addEventListener('click', butotnClick);
    </script>

</body>

</html>

次に、コピペしたテキストの名前を「test2.html」として保存し、ダブルクリックして表示させてください。
2.png

「test.html」と同様の表示内容です。ですが、ボタンを押した後の処理が大きく異なります。あなたのWalletを開いたままで、ボタンを押してください。

4.png

「チャキン」という音と共に、あなたのWalletに1XYMが送金されていると思います。おめでとうございます。これであなたは、この世のどんなコードにも、Symbolブロックチェーンを繋げることが出来ました。これは嘘ではありません。”javascript”フリーコード等で検索して出てきた世界中のコードに、Symbolブロックチェーンを繋げることが出来るのです。では、次の章でそれを実践してみましょう。

※送信されていない場合は以下の確認をしてください。
1.すべてコピー&ペーストしているか?
2.秘密鍵とアドレスを正しく記入しているか?
3.Web上で開いている「test2.html」が更新されているか?(F5を押す)

4.スロットゲームにSymbol送金を組み合わせる

では早速、3章の最後に言った、”javascript”フリーコード等で検索して出てきた世界中のコードに、Symbolブロックチェーンを繋げることが出来るを証明したいと思います。今回はスロットゲームなので、「javascript スロットゲーム」で検索して出てきたサンプルコードを利用します。

早速出てきた「programmercollege」さんのサンプルコードを利用します。

以下のコードをコピペし、「slot1.html」という名前で保存、起動してください。

slot1.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>slot nemAdventCalendar2021</title>
</head>

<body>
    <h1>slot nemAdventCalendar2021</h1>

    <script language="JavaScript">

        var time1;
        var time2;
        var time3;

        // START
        function slot() {
            start1();
            start2();
            start3();
        }

        //各ランダム値を表示
        function start1() {
            document.getElementById("dat1").value = Math.floor(Math.random() * 2);
            time1 = setTimeout(start1, 10);
        }
        function start2() {
            document.getElementById("dat2").value = Math.floor(Math.random() * 2);
            time2 = setTimeout(start2, 10);
        }
        function start3() {
            document.getElementById("dat3").value = Math.floor(Math.random() * 2);
            time3 = setTimeout(start3, 10);
        }

        // STOP
        function stop1() {
            clearTimeout(time1);
        }
        function stop2() {
            clearTimeout(time2);
        }
        function stop3() {
            clearTimeout(time3);
            const textbox = document.getElementById("dat1");
            const inputValue1 = textbox.value;
            console.log(inputValue1);
            const textbox2 = document.getElementById("dat2");
            const inputValue2 = textbox2.value;
            console.log(inputValue2);
            const textbox3 = document.getElementById("dat3");
            const inputValue3 = textbox3.value;
            console.log(inputValue3);
            if (inputValue1 === inputValue2 && inputValue3 === inputValue1) {
                alert('Win');
            }
            else {
                alert('Lose');
            }
        }

    </script>

    <style>
        table,
        tr,
        td {
            border-style: none;
        }
    </style>

    <div style="background-color : rgb(214, 82, 82); padding : 20px;">
        <table>
            <tr>
                <td colspan="3">
                    <input type="button" value="START" onClick="slot()" style="width:100%;">
                </td>
            </tr>
            <tr>
                <td>
                    <input type="text" id="dat1" value="0" style="text-align:center;font-size:30px">
                </td>
                <td>
                    <input type="text" id="dat2" value="0" style="text-align:center;font-size:30px">
                </td>
                <td>
                    <input type="text" id="dat3" value="0" style="text-align:center;font-size:30px">
                </td>
            </tr>
            <tr>
                <td>
                    <input type="button" value="STOP" onClick="stop1()" style="width:100%;">
                </td>
                <td>
                    <input type="button" value="STOP" onClick="stop2()" style="width:100%;">
                </td>
                <td>
                    <input type="button" value="STOP" onClick="stop3()" style="width:100%;">
                </td>
            </tr>
        </table>
    </div>
    </script>
</body>

</html>

早速立ち上げてみましょう。
こんな感じで、startを押すと数字が変化し(便宜上0,1だけにしてます)、すべて揃えば「Win」揃わなかったら「Lose」のPOPが出力されます。
5.png

3章で学んだことを思い出してください。前回は「Ok」のPOPが表示されるきっかけで送金コマンドを登録してましたよね?ということは、今回も「Win」POPが表示されるきっかけの箇所にSymbol送金コマンドを張り付けるだけではないでしょうか。イメージではもう完成してませんか?Symbolって簡単すぎますよね。

それでは、ここからは是非、ご自身で書いてみてほしいですが、どうしてもうまくいかない場合は以下のサンプルコードをご利用ください。

※ポイント:秘密鍵とアドレスだけ、あなたが作成したSymbolWalletのものを入力してください。

slot2.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>slot nemAdventCalendar2021</title>
</head>

<body>
    <h1>slot nemAdventCalendar2021</h1>

    <!-- 設定値の定義とライブラリのインポート&ライブラリのインスタンス生成 -->
    <script src="https://xembook.github.io/nem2-browserify/symbol-sdk-1.0.1.js"></script>
    <script language="JavaScript">

        NODE = 'https://sym-test-09.opening-line.jp:3001';
        GENERATION_HASH = '7FCCD304802016BEBBCD342A332F91FF1F3BB5E902988B352697BE245F48E836';
        EPOCH_ADJUSTMENT = 1637848847;
        nem = require("/node_modules/symbol-sdk");

        var time1;
        var time2;
        var time3;

        // START
        function slot() {
            start1();
            start2();
            start3();
        }

        //各ランダム値を表示
        function start1() {
            document.getElementById("dat1").value = Math.floor(Math.random() * 2);
            time1 = setTimeout(start1, 10);
        }
        function start2() {
            document.getElementById("dat2").value = Math.floor(Math.random() * 2);
            time2 = setTimeout(start2, 10);
        }
        function start3() {
            document.getElementById("dat3").value = Math.floor(Math.random() * 2);
            time3 = setTimeout(start3, 10);
        }

        // STOP
        function stop1() {
            clearTimeout(time1);
        }

        function stop2() {
            clearTimeout(time2);
        }
        function stop3() {
            clearTimeout(time3);
            const textbox = document.getElementById("dat1");
            const inputValue1 = textbox.value;
            console.log(inputValue1);
            const textbox2 = document.getElementById("dat2");
            const inputValue2 = textbox2.value;
            console.log(inputValue2);
            const textbox3 = document.getElementById("dat3");
            const inputValue3 = textbox3.value;
            console.log(inputValue3);
            if (inputValue1 === inputValue2 && inputValue3 === inputValue1) {

                // アカウントの登録(自分のWalletの秘密鍵を入れてください)
                alice = nem.Account.createFromPrivateKey('自分のWalletの秘密鍵を入れてください', nem.NetworkType.TEST_NET);
                console.log(alice);

                // トランザクション作成(自分のWalletのアドレスを入れてください)
                tx = nem.TransferTransaction.create(
                    nem.Deadline.create(EPOCH_ADJUSTMENT),
                    nem.Address.createFromRawAddress("自分のWalletのアドレスを入れてください"),
                    [new nem.Mosaic(new nem.MosaicId('3A8416DB2D53B6C8'), nem.UInt64.fromUint(1000000))],
                    nem.PlainMessage.create('nemAdventCalendar2021'),
                    nem.NetworkType.TEST_NET,
                    nem.UInt64.fromUint(100000)
                );

                console.log(tx);

                // 署名
                signedTx = alice.sign(tx, GENERATION_HASH);

                console.log(signedTx);

                // 署名したトランザクションをネットワークにアナウンス
                new nem.TransactionHttp(NODE)
                    .announce(signedTx)
                    .subscribe((x) => console.log(x), (err) => console.error(err));

                alert('Win');

            }
            else {

                alert('Lose');

            }
        }

    </script>

    <style>
        table,
        tr,
        td {
            border-style: none;
        }
    </style>

    <div style="background-color : rgb(214, 82, 82); padding : 20px;">
        <table>
            <tr>
                <td colspan="3">
                    <input type="button" value="START" onClick="slot()" style="width:100%;">
                </td>
            </tr>
            <tr>
                <td>
                    <input type="text" id="dat1" value="0" style="text-align:center;font-size:30px">
                </td>
                <td>
                    <input type="text" id="dat2" value="0" style="text-align:center;font-size:30px">
                </td>
                <td>
                    <input type="text" id="dat3" value="0" style="text-align:center;font-size:30px">
                </td>
            </tr>
            <tr>
                <td>
                    <input type="button" value="STOP" onClick="stop1()" style="width:100%;">
                </td>
                <td>
                    <input type="button" value="STOP" onClick="stop2()" style="width:100%;">
                </td>
                <td>
                    <input type="button" value="STOP" onClick="stop3()" style="width:100%;">
                </td>
            </tr>
        </table>
    </div>
    </script>
</body>

</html>

5.完成(遊んでみよう!)

アナタが作った、Symbolブロックチェーンゲーム。早速遊んでみましょう。数字が揃うと、XYMが送金されていることが分かります。

私が言っていた”javascript”フリーコード等で検索して出てきた世界中のコードに、Symbolブロックチェーンを繋げることが出来るが嘘でないことが証明されたのではないでしょうか??例えば、シューティングゲームがあって、敵を倒した時?10,000点を超えた時?レースゲームで勝利した時?想像するだけで何でも出来そうな気になりますし、実際に出来ます。あなたの想像力にSymbolはコストゼロで寄り添います。力を貸してくれます。どうぞ、来年はこの新たな武器を手にエンジョイしてください!

ハッカソン情報(開発イベント)

Symbol/NEMを世の中に広める活動をしているNPO法人NEMTUS内で「ハッカソン」が開催される予定です。誰でも参加出来て、ビギナーにも賞が出るという噂です。是非ここでの学びで挑戦してはいかがでしょうか?しかもテーマが「ゲーム」です!!

終わりに

いかがでしたでしょうか?ブロックチェーンがとても近い存在に感じられたのではないでしょうか?Symbolはそのように設計されてます。世界中の誰もが利用できるブロックチェーンです。ごく一部の人間だけが使えるものではありません。

あなたも今日からSymbolを利用する側になりました。ブロックチェーンでアプリケーションを作る側になりました。とても素晴らしいことです。ブロックチェーンは投資するだけのものではないことが理解できたと思います。

私はそんなSymbolで活動する方々へ、支援を続けております。
アナタの活躍に支援する日が来ることを楽しみにしております。

Symbolはいつでもあなたのそばに。

素敵な旅と幸運を。

50
20
1

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
50
20