tag:crieit.net,2005:https://crieit.net/users/hikaru_firecamp/feed hikaru🐧の投稿 - Crieit Crieitでユーザーhikaru🐧による最近の投稿 2020-12-02T14:27:24+09:00 https://crieit.net/users/hikaru_firecamp/feed tag:crieit.net,2005:PublicArticle/16249 2020-12-02T07:00:10+09:00 2020-12-02T14:27:24+09:00 https://crieit.net/posts/Qiita-5fc6bcea9e658 [供養] Qiita の記事に投げ銭サービスを仕込むハックでやらかした話 <p>人生はじめての Advent Calendar に挑戦です!今年は<strong>挑戦を恐れず色々やってきました</strong>が、その中で「あー、やっちった~」的なものを1つご紹介して私の中で供養しようかと思います。</p> <p>※ なお、<strong>具体的なやり方は記載しません</strong>が、やり方を想像できる方もいらっしゃると思います。<strong>真似なさらないようにお願いします</strong>🙇‍</p> <h2 id="序章"><a href="#%E5%BA%8F%E7%AB%A0">序章</a></h2> <p><code>ブログを収益化できる投げ銭サービス</code>というものが世の中にはあって、それを使って「何か面白いことできないかな~」と純粋な気持ちで考えていました。「自分のブログには既に広告を貼ってるし、あー Qiita か・・・」</p> <p>(この時の私は『Qiita で投げ銭するのは多分グレーだろうな~あとで利用規約確認するとして、とりあえず技術的に実現できるのか試してみよう』などと思っていました)</p> <p><strong>一旦それぞれの仕様をまとめてみます</strong></p> <ul> <li>投げ銭サービスは iframe タグと script タグを実行できれば使える<br /> (自分のブログに iframe, script タグを張り付けることを想定している)</li> <li>Qiita には CodePen を埋め込める</li> </ul> <p>この2つの情報があったので、もはや試さずにはいられませんでした。ええ、<strong>Qiita 上で投げ銭のボタンを表示することに成功</strong>してしまいました👺</p> <h2 id="やらかし (〃´∪`〃)ゞ"><a href="#%E3%82%84%E3%82%89%E3%81%8B%E3%81%97+%28%E3%80%83%C2%B4%E2%88%AA%EF%BD%80%E3%80%83%29%E3%82%9E">やらかし (〃´∪`〃)ゞ</a></h2> <p>『Qiita 投げ銭』というタイトルで具体的な方法を記載したうえで Qiita に投稿しました。<br /> その数分後に1通のメールが届くことになります。内容は Qiita でコメントされたと。コメントの内容は・・・</p> <blockquote> <p>Qiitaの利用規約違反になりませんか?</p> </blockquote> <p>と。(この時コメントくださった方。本当にありがとうございました)<br /> <strong>記事を一旦削除</strong>した上で利用規約を再度確認してみました。以下に該当部分を抜粋します。</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/terms">https://qiita.com/terms</a></p> <blockquote> <p>第三章:禁止事項・本ユーザー資格の停止について<br /> 第10条(禁止事項)<br /> 3. 登録ユーザーは、本サービスを利用するに際し、以下のような本サービス利用上不適切な行為を行ってはなりません。<br /> (4)客観的には<strong>事実上、広告・宣伝や商用を目的とした</strong>勧誘と認められる行為(検索サイト最適化又はアフィリエイトを目的とする投稿行為を含むがこれに限らない)。ただし、当社が本サービス上で別途定める場合はその限りではありません。</p> </blockquote> <p>なるほどよくわからん。『事実上…商用を目的とした…』に当たりそうなような当たらなそうな・・・</p> <h2 id="運営さんに問い合わせ"><a href="#%E9%81%8B%E5%96%B6%E3%81%95%E3%82%93%E3%81%AB%E5%95%8F%E3%81%84%E5%90%88%E3%82%8F%E3%81%9B">運営さんに問い合わせ</a></h2> <p>わかないことは聴くのが一番早いので、<strong>Qiita 運営に問合せ</strong>てみました。<br /> 以下送った内容です。</p> <blockquote> <p><strong>Qiita の記事内に CodePen を利用して投げ銭サービスを組み込むことは規約違反でしょうか?</strong></p> <p>規約を確認する限り判断できかねるため Qiita 運営の判断を仰ぎたいと思いました。</p> <p>参考までに以下の URL で実際の動作を確認できるように「限定公開中」にしております。問題があればすぐに削除いたします。<br /> https://qiita.com/alclimb/private/********</p> <p>(以下、対象規約部分を抜粋)<br /> 第三章:禁止事項・本ユーザー資格の停止について<br /> 第10条(禁止事項)<br /> 3. 登録ユーザーは、本サービスを利用するに際し、以下のような本サービス利用上不適切な行為を行ってはなりません。<br /> (4)客観的には事実上、広告・宣伝や商用を目的とした勧誘と認められる行為(検索サイト最適化又はアフィリエイトを目的とする投稿行為を含むがこれに限らない)。ただし、当社が本サービス上で別途定める場合はその限りではありません。</p> <p>--<br /> 以上です。お手数ですがよろしくお願いいたします。</p> </blockquote> <p>夕方 18:40 頃に問い合わせして、40 分後の 19:20 頃には <strong>Qiita サポートから回答が来てました</strong>。(はやっ)<br /> <strong>回答の一部のみ引用</strong>すると、</p> <blockquote> <p>今後状況が変わる可能性も0ではありませんが、少なくとも現時点では利用規約違反となります。</p> </blockquote> <p>とのことでした。はい<strong>利用規約違反</strong>でした。申し訳ございませんでしたー<br /> 今後状況が変わる可能性も0ではないとの事なので今後に期待したいです。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <ul> <li>Qiita で投げ銭は技術的に可能だけど利用規約的に NG</li> <li>Qiita サポートは回答が早くユーザーとしては嬉しかった。個人開発としても見習いたい部分</li> <li>失敗は何らかの形で供養するとセルフ反省会にもなるのでおススメ</li> </ul> <p>きっと来年もいっぱい失敗します。でも『とにかくやる!』で精進していきたいと思います✨</p> <hr /> <p>明日の Advent Calendar 3日目は <a href="https://crieit.net/users/frabbit_mbp">みにに</a> さんです!よろしくお願いします</p> hikaru🐧 tag:crieit.net,2005:PublicArticle/15975 2020-06-23T09:37:52+09:00 2020-06-23T09:43:27+09:00 https://crieit.net/posts/game1week 【1週間】Web ゲームを爆速で開発するために実践したこと🐧個人開発向け <p>(内心)<br /> 作ったゲームを沢山の人に触ってもらってリアクションが欲しいなぁ~<br /> そうだ、記事投稿して宣伝しよう!</p> <p>といった<strong>下心で書いた記事です</strong>。すみませんでした 遊んでください😆</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Web Game 処女作🎉シンプルでストレス発散になるゲームが爆誕!敵さんを吹っ飛ばして 1,000 G 以上を目指してみてね😆<a target="_blank" rel="nofollow noopener" href="https://t.co/h8w574aGGQ">https://t.co/h8w574aGGQ</a>★アドバイス急募★『こうしたらもっと面白くなる』など、ご意見ご感想を頂けると嬉しいっす(〃´∪`〃)ゞ<a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/%E4%BB%8A%E6%97%A5%E3%81%AE%E7%A9%8D%E3%81%BF%E4%B8%8A%E3%81%92?src=hash&ref_src=twsrc%5Etfw">#今日の積み上げ</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/100DaysOfCode?src=hash&ref_src=twsrc%5Etfw">#100DaysOfCode</a> DAY 21 <a target="_blank" rel="nofollow noopener" href="https://t.co/HJvFj87zTf">pic.twitter.com/HJvFj87zTf</a></p>— hikaru🐧#100DaysOfCode! (@hikaru_firecamp) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hikaru_firecamp/status/1273289660186292224?ref_src=twsrc%5Etfw">June 17, 2020</a></blockquote> <blockquote> <p>ペンギンがサメさんを倒すゲーム<br /> 敵さんを吹っ飛ばして 1,000 G 以上を目指してみてね😆<br /> <a target="_blank" rel="nofollow noopener" href="https://games.westa.io/">https://games.westa.io/</a></p> </blockquote> <h2 id="0⃣ 結論 / 爆速で開発するために実践したこと"><a href="#0%E2%83%A3+%E7%B5%90%E8%AB%96+%2F+%E7%88%86%E9%80%9F%E3%81%A7%E9%96%8B%E7%99%BA%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AB%E5%AE%9F%E8%B7%B5%E3%81%97%E3%81%9F%E3%81%93%E3%81%A8">0⃣ 結論 / 爆速で開発するために実践したこと</a></h2> <ul> <li>1週間のカウントダウンタイマーを設置する</li> <li>適当な企画書を作って全体を把握しならが作業する</li> <li>新しいことは1個までに制限して知っているものを使う</li> <li>こだわりたい部分を絞り他を捨てる覚悟を持つ</li> </ul> <h2 id="1️⃣ この記事の対象読者"><a href="#1%EF%B8%8F%E2%83%A3+%E3%81%93%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%AE%E5%AF%BE%E8%B1%A1%E8%AA%AD%E8%80%85">1️⃣ この記事の対象読者</a></h2> <p>この記事では<strong>1週間で Web ゲームを作る為に何を考え何をしたのか</strong>を書きました。<br /> 以下に当てはまる人達に参考になれば嬉しいです。</p> <ul> <li>好きなことへのこだわりが強く<strong>いつまでも作品が完成しない</strong>人</li> <li>いつも<strong>ダラダラ期限を伸ばしてしまう</strong>人</li> <li>このゲームがどんなライブラリ使っているか知りたい人</li> <li>奇特な人</li> </ul> <h2 id="2️⃣ なぜ1週間なの?"><a href="#2%EF%B8%8F%E2%83%A3+%E3%81%AA%E3%81%9C%EF%BC%91%E9%80%B1%E9%96%93%E3%81%AA%E3%81%AE%EF%BC%9F">2️⃣ なぜ1週間なの?</a></h2> <p>個人開発の一番の敵って<strong>いかにモチベーションを保つか</strong>だと思いませんか?</p> <p>私の場合1ヶ月もたてば他に興味あることが出てきてしまうのでモチベーションが移ってしまいます。<br /> でも、<strong>1週間なら全力で頑張れるちょうどよい長さ</strong>かな~と考えました。</p> <p>(それと、1週間ならクオリティ低くても言い訳になるかな と)</p> <h2 id="3⃣ 1週間という短い期間で終わらせるために意識したこと"><a href="#3%E2%83%A3+%EF%BC%91%E9%80%B1%E9%96%93%E3%81%A8%E3%81%84%E3%81%86%E7%9F%AD%E3%81%84%E6%9C%9F%E9%96%93%E3%81%A7%E7%B5%82%E3%82%8F%E3%82%89%E3%81%9B%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AB%E6%84%8F%E8%AD%98%E3%81%97%E3%81%9F%E3%81%93%E3%81%A8">3⃣ 1週間という短い期間で終わらせるために意識したこと</a></h2> <h3 id="(1) 1週間のカウントダウンタイマーを設置する"><a href="#%281%29+%EF%BC%91%E9%80%B1%E9%96%93%E3%81%AE%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%83%80%E3%82%A6%E3%83%B3%E3%82%BF%E3%82%A4%E3%83%9E%E3%83%BC%E3%82%92%E8%A8%AD%E7%BD%AE%E3%81%99%E3%82%8B">(1) 1週間のカウントダウンタイマーを設置する</a></h3> <p>いつもズルズル伸ばしてしまう癖があるので <strong>Twitter で公開日を宣言</strong>しました。<br /> そして公開日までの<strong>カウントダウンタイマーを常に目に入る位置に設置</strong>しておきました。</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">次に出す Web アプリのリリース日を 6/17 12:00 頃に決めました🎉メリハリ付けるために中途半端でもこのタイミングで出します写真はちょうどいいカウントダウンタイマーが無かったので作ってみました▪コードはこちら<a target="_blank" rel="nofollow noopener" href="https://t.co/HiGjiROP4R">https://t.co/HiGjiROP4R</a>(8,9行目を編集すれば自分用に使えるよ!) <a target="_blank" rel="nofollow noopener" href="https://t.co/HnjXxktDLb">pic.twitter.com/HnjXxktDLb</a></p>— hikaru🐧#100DaysOfCode! (@hikaru_firecamp) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hikaru_firecamp/status/1269807592533979138?ref_src=twsrc%5Etfw">June 8, 2020</a></blockquote> <p>このカウントダウンタイマー、<strong>すっごく効果があった</strong>ように思います。度々目に入るので<strong>程よい緊張感と無機質な圧力</strong>をくれます。<br /> さらにシレっと<strong>周囲の人たちに公開日を宣言</strong>できるのでかなりお勧めです。</p> <blockquote> <p>⚠ 補足 ⚠<br /> さも予定を守ったように言ってますが結局半日ほど遅く公開してしまいました<br /> ほ ん と す み ま せ ん で し た 😗</p> </blockquote> <h3 id="(2) 適当な企画書を作って全体を把握しならが作業する"><a href="#%282%29+%E9%81%A9%E5%BD%93%E3%81%AA%E4%BC%81%E7%94%BB%E6%9B%B8%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E5%85%A8%E4%BD%93%E3%82%92%E6%8A%8A%E6%8F%A1%E3%81%97%E3%81%AA%E3%82%89%E3%81%8C%E4%BD%9C%E6%A5%AD%E3%81%99%E3%82%8B">(2) 適当な企画書を作って全体を把握しならが作業する</a></h3> <p>企画書などが無い状態でコーディングすると目に付いた場所から手を付けてしまいがちで<strong>視野が局所的になりやすく作業の優先度決めが難しく</strong>なります。</p> <p>簡単なものでも<strong>全体像を把握できるもの</strong>があると、次にどの部分を実装するか考えるときに『最低でもここを実装しないとだから優先度高めで』みたいな<strong>スケジュール管理が容易</strong>になります。</p> <p>今回は以下の様な簡易仕様書をあらかじめ書いておりました。</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これから作るミニゲームの簡易仕様書!よくあるクリックゲームですが、ちゃんと作りきれるか不安😇1週間がんばります〜(あ、奇しくも一人 web1week みたいになってる)全然関係ないけど最近 iPad でお絵描きの練習始めました!スマブラやったことあればピンとくるはず😎 <a target="_blank" rel="nofollow noopener" href="https://t.co/oVo5xAUeBe">pic.twitter.com/oVo5xAUeBe</a></p>— hikaru🐧#100DaysOfCode! (@hikaru_firecamp) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hikaru_firecamp/status/1270280818116583425?ref_src=twsrc%5Etfw">June 9, 2020</a></blockquote> <p>これのおかげで実装段階での仕様変更が減り、<strong>一直線にゴールに向かって実装できるので結構大切</strong>なものだと思います。</p> <h3 id="(3) 新しいことは1個までに制限して知っているものを使う"><a href="#%283%29+%E6%96%B0%E3%81%97%E3%81%84%E3%81%93%E3%81%A8%E3%81%AF%EF%BC%91%E5%80%8B%E3%81%BE%E3%81%A7%E3%81%AB%E5%88%B6%E9%99%90%E3%81%97%E3%81%A6%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%82%82%E3%81%AE%E3%82%92%E4%BD%BF%E3%81%86">(3) 新しいことは1個までに制限して知っているものを使う</a></h3> <p>初めて使う道具が多いと勉強することが増えたり些細なことにはまったりして時間を消費しがちなので、<strong>使い慣れた開発環境</strong>と<strong>使った事のあるライブラリ</strong>を中心に選定しました。</p> <h4 id="使い慣れたもの"><a href="#%E4%BD%BF%E3%81%84%E6%85%A3%E3%82%8C%E3%81%9F%E3%82%82%E3%81%AE">使い慣れたもの</a></h4> <ul> <li><strong>VS-Code</strong> ... 開発環境</li> <li><strong>TypeScript</strong> ... 開発言語</li> <li><strong>UIKit</strong> ... UI コンポーネント</li> </ul> <h4 id="以前から実験レベルで遊んでいたもの"><a href="#%E4%BB%A5%E5%89%8D%E3%81%8B%E3%82%89%E5%AE%9F%E9%A8%93%E3%83%AC%E3%83%99%E3%83%AB%E3%81%A7%E9%81%8A%E3%82%93%E3%81%A7%E3%81%84%E3%81%9F%E3%82%82%E3%81%AE">以前から実験レベルで遊んでいたもの</a></h4> <ul> <li><strong>Three.js</strong> ... 3D 描画エンジン</li> <li><strong>Cannon.js</strong> ... 3D 物理エンジン</li> </ul> <h4 id="初めて使うもの"><a href="#%E5%88%9D%E3%82%81%E3%81%A6%E4%BD%BF%E3%81%86%E3%82%82%E3%81%AE">初めて使うもの</a></h4> <ul> <li><strong>Audio API</strong> ... BGM や効果音の再生</li> </ul> <p>今回は遊べる Web ゲームを<strong>短期間で作ることが目的</strong>だったので冒険をしない制約を設けましたが、完成度が低くても<strong>未知なる技術を沢山学びたいならどんどん新しい技術を使ってみたらよい</strong>と思います。</p> <p><strong>目的次第でやり方を臨機応変にする</strong>ことが大事なのかなと😎</p> <h3 id="(4) こだわりたい部分を絞り他を捨てる覚悟を持つ"><a href="#%284%29+%E3%81%93%E3%81%A0%E3%82%8F%E3%82%8A%E3%81%9F%E3%81%84%E9%83%A8%E5%88%86%E3%82%92%E7%B5%9E%E3%82%8A%E4%BB%96%E3%82%92%E6%8D%A8%E3%81%A6%E3%82%8B%E8%A6%9A%E6%82%9F%E3%82%92%E6%8C%81%E3%81%A4">(4) こだわりたい部分を絞り他を捨てる覚悟を持つ</a></h3> <p>こだわりが強いと味のあるイイものができるけど、その代わり<strong>完成が遅くなる</strong>傾向にあると思います。</p> <p>今回は『ローポリキャラ達が<strong>物理演算で予想外の挙動</strong>をする』部分だけこだわりましたが、操作 UI の見た目などはブラウザ標準のプログレスバーを使っていたりと<strong>大部分はかなり適当</strong>です。</p> <p>個人的にはゲームの中に<strong>ブラウザの DOM を混ぜることに違和感</strong>とアレルギーを感じるのですが『<strong>こだわる部分を絞って他は適当</strong>』と大胆に割り切っちゃいました。<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67192/ef433b3e-8d54-62b9-94b9-83f98f528ade.png" alt="image.png" /></p> <p>他にも、ペンギン/サメ/コイン/木 の当たり判定はすべて立方体(正六面体)で手抜きをしましたが、これは予想に反して『<strong>サメさんやコインが地面に刺さってる</strong>』ように見えたり『木々があらぶってる』感じになったり<strong>ヘンテコな世界観の演出</strong>に一役買ったように思います。<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67192/a1a1764b-8e99-17a7-de03-a410ae195d96.png" alt="2020-06-18_00h32_18.png" /></p> <h2 id="4⃣ おまけ: 実装 Tips"><a href="#4%E2%83%A3+%E3%81%8A%E3%81%BE%E3%81%91%3A+%E5%AE%9F%E8%A3%85+Tips">4⃣ おまけ: 実装 Tips</a></h2> <p>唐突なおまけの実装 Tips です。</p> <h3 id="(1) Cannon.js / サメさんの Z 位置(奥行)を固定"><a href="#%281%29+Cannon.js+%2F+%E3%82%B5%E3%83%A1%E3%81%95%E3%82%93%E3%81%AE+Z+%E4%BD%8D%E7%BD%AE%28%E5%A5%A5%E8%A1%8C%29%E3%82%92%E5%9B%BA%E5%AE%9A">(1) Cannon.js / サメさんの Z 位置(奥行)を固定</a></h3> <p>Cannon.js は 3 次元物理演算なので XYZ 軸分の動きがあるのですが、サメさん(敵)に関しては奥行方向に動かれると攻撃を当てられなくなるので Z 軸を固定しています。</p> <pre><code class="ts">// CannonJs: サメさんの物理演算用の剛体を生成 const sharkBody = new CANNON.Body({ <省略> }); // ThreeJs: アニメーションループを開始 renderer.setAnimationLoop(() => { // CannonJs: 1フレーム分の物理演算を実行 world.step(<省略>); // ★★ サメさんのZ位置を固定する ★★ sharkBody.position.set( sharkBody.position.x, sharkBody.position.y, 0); // Z軸を0に変更 }); </code></pre> <h3 id="(2) Cannon.js / 摩擦設定・反発設定"><a href="#%282%29+Cannon.js+%2F+%E6%91%A9%E6%93%A6%E8%A8%AD%E5%AE%9A%E3%83%BB%E5%8F%8D%E7%99%BA%E8%A8%AD%E5%AE%9A">(2) Cannon.js / 摩擦設定・反発設定</a></h3> <p>初期値だとほとんど滑ることは無く、滑らせた方が面白そうだったので摩擦と反発の設定をいじっています。</p> <p>モデルごとに摩擦係数や反発係数を設定できれば直感的だったのですが、Cannon.js では『モデル1とモデル2に対しての摩擦・反発を設定』といった具合に設定が必要でした。</p> <pre><code class="ts">// // 物理演算ワールドを初期化 // const world = new CANNON.World(); world.gravity.set(0, -9.82, 0); // m/s² const floorBodyMaterial = new CANNON.Material(`FloorModel`); const penguinBodyMaterial = new CANNON.Material(`PenguinModel`); const sharkBodyMaterial = new CANNON.Material(`SharkModel`); // 摩擦反発設定: 床とペンギン world.addContactMaterial(new CANNON.ContactMaterial( floorBodyMaterial, penguinBodyMaterial, { friction: 0.01, // 摩擦設定 (ペンギンが床を滑るように) restitution: 0.8, // 反発設定 } )); // 摩擦反発設定: 床とサメ world.addContactMaterial(new CANNON.ContactMaterial( floorBodyMaterial, sharkBodyMaterial, { friction: 0.05, // 摩擦設定 restitution: 0.3, // 反発設定 contactEquationStiffness: 1e8, contactEquationRelaxation: 3, } )); // 摩擦反発設定: ペンギンとサメ world.addContactMaterial(new CANNON.ContactMaterial( penguinBodyMaterial, sharkBodyMaterial, { friction: 0.01, // 摩擦設定 restitution: 2.0, // 反発設定 (攻撃を受けたサメが吹っ飛びやすいように) } )); </code></pre> <h3 id="(3) Three.js / 同じモデルは使いまわして効率化"><a href="#%283%29+Three.js+%2F+%E5%90%8C%E3%81%98%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AF%E4%BD%BF%E3%81%84%E3%81%BE%E3%82%8F%E3%81%97%E3%81%A6%E5%8A%B9%E7%8E%87%E5%8C%96">(3) Three.js / 同じモデルは使いまわして効率化</a></h3> <p>今回ゲーム内では<strong>同じモデルが大量に出現</strong>します。その際に<strong>毎回モデルをロードしていると実行効率が悪い</strong>ので、モデル管理クラスが必要になります。</p> <p>こういった目的の管理クラス系にはシングルトン実装が最適かと思いますが、TypeScript では <strong><code>module</code> を使うと簡単にシングルトン実装が可能</strong>です。</p> <pre><code class="ts">/** モデル名の型定義 */ export type ModelName = `PENGUIN` | `SHARK` | `TREE` | `COIN`; /** * ゲーム内のモデルを管理するモジュール *  シングルトン実装 *  モデルをあらかじめロードして、ロード済みのモデルを使いまわすことで効率化 */ export module ModelManager { /** ロード済みのモデルを保持 */ const modelMap = new Map<ModelName, THREE.Object3D>(); /** 各種モデルをロードする */ export async function load() { await loadModel(`PENGUIN`, `models/PenguinJumping.glb`); await loadModel(`SHARK`, `models/Shark.glb`); await loadModel(`TREE`, `models/Tree.glb`); await loadModel(`COIN`, `models/Coin.glb`); } /** モデルを複製して取得する */ export function getModel(modelName: ModelName) { return modelMap.get(modelName)!.clone(); } /** ロード済みモデルを開放する */ export function dispose() { // ThreeJs: ロードしたモデルをすべて解放 modelMap.forEach((obj3D, key) => { GameUtils.disposeObject3D(obj3D); }); } async function loadModel(modelName: ModelName, path: string) { // ThreeJs: モデル読み込み const obj3D = await GameUtils.loadGltfModel(path); // リストに追加 modelMap.set(modelName, obj3D); } } </code></pre> <p>使い方</p> <pre><code class="ts">// あらかじめすべてのモデルをロードする await ModelManager.load(); // ペンギンモデルを取得する (内部的にはロード済みのモデルを複製しているので効率的) const penguin1 = ModelManager.getModel(`PENGUIN`); const penguin2 = ModelManager.getModel(`PENGUIN`); const penguin3 = ModelManager.getModel(`PENGUIN`); </code></pre> <h2 id="最後に"><a href="#%E6%9C%80%E5%BE%8C%E3%81%AB">最後に</a></h2> <p>ゲーム開発中に Twitter でいいねやコメントなどでリアクションをくれた方、開発中のゲームを試してヒントをくれた友人方、本当にありがとうございました。<br /> 大変励みになりモチベーションになりました、重ねてお礼申し上げます😆</p> <p>あと、ここまで読んでまだプレイしていない人!!<br /> ↓ やってからリアクションをクレクレ厨😗</p> <blockquote> <p>ペンギンがサメさんを倒すゲーム<br /> 敵さんを吹っ飛ばして 1,000 G 以上を目指してみてね😆<br /> <a target="_blank" rel="nofollow noopener" href="https://games.westa.io/">https://games.westa.io/</a></p> </blockquote> <hr /> <p>P.S. crieit.net で初カノニカル投稿してみました🎉これ書く側としてはイイ仕組みですね</p> hikaru🐧