概要
こんリリス!BCGゲーム「クリプトスペルズ」にドはまりしているmaepuです。
(この挨拶はクリプトスペルズ公式キャラのリリスちゃんの挨拶を真似してみました)
挨拶はさておき、表題の件をお話しします。
BCGゲーム「クリプトスペルズ」とは、デジタルトレーディングカードゲームで、**レアカードがNFT(Non-Fungible Token)**になっています。
ブロックチェーンやNFTの説明をすると長くなるので、ここでは割愛します。
クリプトスペルズが気になるという方はクリプトスペルズ公式をご参照ください。
さて、クリプトスペルズには採掘というガチャがあります。
はっきり言うとクリプトスペルズのガチャは無課金プレイをしているとまったく当たりません。ガチャの排出率アップの方法はありますが、かなり労力と課金が必要になってきます。
なので、少しでもレアカードを当てた気分を味わいたいと思いで、自分だけのガチャを作りました。(中毒者...)
作るにあたり、個人のお遊び程度なので、環境構築してプロジェクト管理や一般公開など考えないで作ることを考えました。
そこで、私の知っているお手軽プロトタピングサービス「enebular」を使って作る事にしました。
※こちらの記事はQiitaアドベントカレンダーに投稿しています。遅れてしまい申し訳ありません。
本記事の対象者
- enebularに興味があるor知っているor使ったことある方
- Node-REDに興味があるor知っているor使ったことある方
作ったもの
シンプルに「ガチャを引く」ボタンを押すと、ランダムにカードを決めて画像を表示します。
素人ながら思い付きでクリスペガチャを作ってみました。技術足りないのでお粗末ですが、気分転換に遊べてます!リリースされているカードは連番だと思いましたが、歯抜けになっているようです。それはハズレとして猪表示します🐗#クリスペ pic.twitter.com/zede4RESzc
— まえぷー (@kmaepu) December 13, 2021
せっかくなので、通常のガチャでは排出されないレジェンドカード(世界に19枚しかないカード)も当てられるようにしてみました!なかなか出ませんが。
技術的なところ
クリプトスペルズにはAPIが用意されています。
URL:https://cryptospells.gitbook.io/cryptospells/other/api
この中にカード情報を取得するAPIがあり、カードの画像が公開されてるURLを取得できます。これを利用して、ガチャに表示する画像をにしています。
システム構成はシンプルで、次の図のようにNode-REDのフローからクリプトスペルズAPIにリクエストし、画像のURLを取得します。UIはNode-REDのダッシュボードを利用しブラウザで表示しています。
Node-REDのフロー
今回、enebularに用意されているNode-REDを利用し、サーバー側の処理を構築しました。
Node-REDは「ノード」と呼ばれる処理ブロックをビジュアル的に接続してシステムを構築するツールです。詳しく知りたい方はNode-RED日本ユーザ会をご参照ください。
このフローでは、主に次の処理を行っています。
(1)ダッシュボードでUI表示
(2)UIのボタンが押されたら、クリプトスペルズAPIで画像URLを取得
(3)UIの画像を更新
中でも躓いたのが、(3)のUIの画像を更新でした。
次の図に示すダッシュボードのTemplateノードでUIを表示します。
使い方は、この中にHTMLを書くか入力データに「msg.template」を与えるかです。
今回は次の図のように前段にTemplateノードを用意しています。
この中で画像URLを動的に設定するHTMLコードを書いています。
Templateノードのコードは次の通りです。
<div>
<img src="{{payload.image_url}}" width="100%" height="100%">
</div>
画像URLを「mag.payload.image_url」で渡すと、HTML内の画像が動的に変更できます。
Templateノードより前段は、クリプトスペルズAPIで取得したjsonデータから、画像URLを抜き出しています。
以上のフローは次のjsonをNode-REDに読込んで確認できます。
[{"id":"1ac7b607.ebe26a","type":"tab","label":"フロー 1","disabled":false,"info":""},{"id":"52e65947.89c228","type":"ui_template","z":"1ac7b607.ebe26a","group":"8de655c7.20ffc8","name":"","order":0,"width":"6","height":"7","format":"<div>\n <img src=\"https://d3n9a7g7xguuos.cloudfront.net/uploads/card/image/500/3610.png\" width=\"50%\" height=\"50%\">\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":320,"y":340,"wires":[[]]},{"id":"f2fca.b46cb0368","type":"inject","z":"1ac7b607.ebe26a","name":"","topic":"","payload":"https://d3n9a7g7xguuos.cloudfront.net/uploads/card/image/500/3610.png","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":90,"y":60,"wires":[["d92a1923.64b0f8"]]},{"id":"1f7c92ed.8b027d","type":"http request","z":"1ac7b607.ebe26a","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"","tls":"","persist":false,"proxy":"","authType":"","x":450,"y":140,"wires":[["bcb334c0.c7e598"]]},{"id":"7e3a278d.daa248","type":"debug","z":"1ac7b607.ebe26a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload.image_url","targetType":"msg","x":630,"y":360,"wires":[]},{"id":"bcb334c0.c7e598","type":"json","z":"1ac7b607.ebe26a","name":"","property":"payload","action":"","pretty":false,"x":610,"y":140,"wires":[["3c2242bd.df463e"]]},{"id":"4510e11.d61a12","type":"ui_button","z":"1ac7b607.ebe26a","name":"","group":"8de655c7.20ffc8","order":1,"width":0,"height":0,"passthru":false,"label":"ガチャを引く!","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":120,"y":140,"wires":[["d92a1923.64b0f8"]]},{"id":"d92a1923.64b0f8","type":"function","z":"1ac7b607.ebe26a","name":"","func":"var min = 1 ;\nvar max = 3610 ;\n\nmsg.a = Math.floor( Math.random() * (max + 1 - min) ) + min ;\n\nmsg.url = \"https://cryptospells.jp/public_api/cards/\" + msg.a + \".json\"\n\nreturn msg;","outputs":1,"noerr":0,"x":310,"y":140,"wires":[["1f7c92ed.8b027d"]]},{"id":"3c2242bd.df463e","type":"switch","z":"1ac7b607.ebe26a","name":"","property":"payload.status","propertyType":"msg","rules":[{"t":"eq","v":"404","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":310,"y":220,"wires":[["1663b2ae.091d0d"],["cf8be37a.9dc33"]]},{"id":"1663b2ae.091d0d","type":"change","z":"1ac7b607.ebe26a","name":"はずれ","rules":[{"t":"set","p":"payload.image_url","pt":"msg","to":"https://d3n9a7g7xguuos.cloudfront.net/uploads/card/image/562/396.png","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":220,"wires":[["2dd06f1d.bf2f9","7e3a278d.daa248"]]},{"id":"2dd06f1d.bf2f9","type":"template","z":"1ac7b607.ebe26a","name":"","field":"template","fieldType":"msg","format":"html","syntax":"mustache","template":"<div>\n <img src=\"{{payload.image_url}}\" width=\"100%\" height=\"100%\">\n</div>","output":"str","x":660,"y":220,"wires":[["52e65947.89c228"]]},{"id":"cf8be37a.9dc33","type":"change","z":"1ac7b607.ebe26a","name":"日本語","rules":[{"t":"set","p":"payload.image_url","pt":"msg","to":"payload.image_url.ja","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":260,"wires":[["2dd06f1d.bf2f9","7e3a278d.daa248"]]},{"id":"da9bea27.9e9998","type":"debug","z":"1ac7b607.ebe26a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"template","targetType":"msg","x":600,"y":400,"wires":[]},{"id":"31ee41f5.b7d80e","type":"debug","z":"1ac7b607.ebe26a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":590,"y":440,"wires":[]},{"id":"8de655c7.20ffc8","type":"ui_group","z":"","name":"クリスペガチャ","tab":"4606de96.13ae5","order":1,"disp":true,"width":"6","collapse":false},{"id":"4606de96.13ae5","type":"ui_tab","z":"","name":"ホーム","icon":"dashboard","disabled":false,"hidden":false}]
感想
Twitterで#クリスペで呟いたところ、CryptoGames 代表取締役(クリプトスペルズの運営本)の小澤さんからいいねを頂けました!
師走の忙しい時期ですが、苦労して作ってよかったなと感じます。
今回のプロトタイピングでクリプトスペルズAPIの使い方が分かりました。
このノウハウを活かして「レジェンドカードの保有者」を調べるものが作りたいと思ってます。
なぜかというと、レジェンドカードは勝ち負けをひっくり返すほど強力なので、所有者に注意してプレイが必要だからです。
しかし、クリプトスペルズAPIを使用して実現するには全ユーザの所有カードを調べてレジェンドカードとユーザ情報だけ抽出する手間があります。
これをNode-REDで自動化できたらなと考えています。
気になる方はQiitaで私のアカウントをフォローしていただけると、記事公開の通知があると思うので宜しくお願いします!