【FFRK】ダークモード実装進捗(2024.08時点)
こんにちは、tosumaです。
今回はFFRKのファンサイトついての記事です。普段利用頂いている方やFFRKプレイヤーの方、その他プログラムやシステムについてご興味のある方に見て頂けますと幸いです。
6月にダークモードについて書かさせ貰いました。
こんな感じの完成イメージです。(以下)
トップページ。(↑通常、↓ダーク)
ダンジョン一覧ページ。(↑通常、↓ダーク)
ランキングページ。(↑通常、↓ダーク)
リクエストフォーム。(↑通常、↓ダーク)
で、肝心の8月の現在の進捗ですね。
ほとんど6月から進んでません!!
いや、基本的な大枠は6月時点で既にできているのと、残作業についても頭の中での構築は割と進んでるんです、モノが出来ていないだけで....。
(それが進捗0や)
言い訳としては、7月はノマガチャランキングの準備があって(結局お蔵入りですが苦笑)、8月はコロナ感染&必殺技の所持数が10から15に変更などもあって、ぜんぜん追っつきませんでした。
(あと、ランキングの表現案が思いつかず......)
で、今回の必殺技保持数の変更だったり、ちょこちょこメンテしてるんですが、日々の30分程度の作業時間ではダブルメンテ(ダークモード側と現行側)が現実的ではないと判断しました。
で、何が言いたいかと言うと、ダブルメンテしなくてもいい仕組みから考え直すので、、、再度0からやり直すことにしました。
ということでダークモード実装はだいぶ先になりそうです。
それでは皆さん、引き続き良きレコパライフを!
お読み頂き有難うございました。
※よければもう1本 関連記事をお読み頂けると幸いです
Javascriptで作るオリンピックのルーレットぽい物
こんにちは、tosumaです。
今回はJavascriptのお話です。
先日、ジョーク動画で例のルーレットぽい物を作りました。
#FFRK #レコパミーム
— 白ご飯🍚 (@Tay_Tosuma) 2024年8月8日
カウントダウン装備召喚で神引きした際にご自由にお使いください。 pic.twitter.com/LC6bfQVrNb
ライブラリにはenchant.jsを使っています。
enchant.jsはオープンソースのHTML5向けゲームエンジンです。
公式サイトも閉鎖してGitの更新もなので実質終了したライブラリですね。
と言いつつ個人的には使いやすくて使い続けています。
Wikiはコチラ。
enchant.js - Wikipedia
今回は上記の軽く、かつ、ざっくりとソースの紹介をします。
だいたい20~30分くらいで作ったものですね。
(このブログのためにインデントつけたりは後付け)
以下が実際に動くものです。
これを動画キャプチャしてトリミングして出来上がりです。
しばらくは置いておきます。(しばらくしたら消します)
https://taytsm.com/roulette/
2|index.html
index.htmlはこんな感じです。
bodyだけ整えてiframeでgame.htmlを読み込んでます。
index.html、game.html、jsで定義した領域の幅と高さは合わせておくのがポイントですかね。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="ja"> <head> <meta charset="utf-8"> <title>ルーレット</title> <style type="text/css"> body { background-color: #1e90ff; color: #000000; } .center { width: 700px; height: 780px; margin-right: auto; margin-left: auto; } </style> </head> <body> <div class="center"> <iframe src="game.html" width="700" height="780" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" > </iframe> </div> </body> </html>
3|game.html
game.htmlはこんな感じです。
こちらがメインの処理になります、普段は「<script>~</script>」の部分は別ファイルにして、そこの中だけ差し替えています。
enchant.jsの仕組みを使うためjsフォルダのenchant.min.jsを参照してます。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="ja"> <head> <meta charset="utf-8"> <script src="js/enchant.min.js"></script> <script> enchant(); enchant.ENV.USE_TOUCH_TO_START_SCENE = false; window.onload = function () { //画面サイズ const game = new Game(700, 780); game.fps = 50; //ロード後 呼出 game.onload = function () { //----------------------------------------------------- // シーン //----------------------------------------------------- //メインシーン const mainScene = new Scene(); game.pushScene(mainScene); mainScene.backgroundColor = "#1e90ff"; //----------------------------------------------------- // 共通変数 //----------------------------------------------------- var counter_main = 0; //メインカウンター var counter_sub = 0; //サブカウンター var speed = 1; //回転速度 var y_position = 200; //開始位置 var soubi = new Array(); //装備配列 //----------------------------------------------------- // タイトル //----------------------------------------------------- //タイトル1 const titleText_01 = new Label(); titleText_01.font = "bold 40px Meiryo"; titleText_01.color = '#fff'; titleText_01.width = 700; titleText_01.moveTo(100, 310); mainScene.addChild(titleText_01); titleText_01.text = 'JUST BEFORE THE 10th'; //タイトル2 const titleText_02 = new Label(); titleText_02.font = "bold 40px Meiryo"; titleText_02.color = '#fff'; titleText_02.width = 700; titleText_02.moveTo(10,370); mainScene.addChild(titleText_02); titleText_02.text = 'ANNIVERSARY OF ITS RELEASE'; //タイトル3 const titleText_03 = new Label(); titleText_03.font = "bold 40px Meiryo"; titleText_03.color = '#fff'; titleText_03.width = 700; titleText_03.moveTo(65,430); mainScene.addChild(titleText_03); titleText_03.text = 'COUNTDOWN RELIC DRAW'; //----------------------------------------------------- // 装備 //----------------------------------------------------- //閃技(★7) soubi[0] = new Label(); soubi[0].font = "bold 50px Meiryo"; soubi[0].color = '#fff'; soubi[0].width = 700; soubi[0].moveTo(220,y_position); soubi[0].opacity = 0.0; mainScene.addChild(soubi[0]); soubi[0].text = '閃技(★7)'; y_position = y_position + 70; //究極神技 soubi[1] = new Label(); soubi[1].font = "bold 50px Meiryo"; soubi[1].color = '#00ffff'; soubi[1].width = 700; soubi[1].moveTo(235,y_position); soubi[1].opacity = 0.0; mainScene.addChild(soubi[1]); soubi[1].text = '究極神技'; y_position = y_position + 70; //クリスタル神技 soubi[2] = new Label(); soubi[2].font = "bold 50px Meiryo"; soubi[2].color = '#fff'; soubi[2].width = 700; soubi[2].moveTo(160,y_position); soubi[2].opacity = 0.0; mainScene.addChild(soubi[2]); soubi[2].text = 'クリスタル神技'; y_position = y_position + 70; //アクセル神技 soubi[3] = new Label(); soubi[3].font = "bold 50px Meiryo"; soubi[3].color = '#00ffff'; soubi[3].width = 700; soubi[3].moveTo(190,y_position); soubi[3].opacity = 0.0; mainScene.addChild(soubi[3]); soubi[3].text = 'アクセル神技'; y_position = y_position + 70; //オーバーフロー神技 soubi[4] = new Label(); soubi[4].font = "bold 50px Meiryo"; soubi[4].color = '#fff'; soubi[4].width = 700; soubi[4].moveTo(120,y_position); soubi[4].opacity = 0.0; mainScene.addChild(soubi[4]); soubi[4].text = 'オーバーフロー神技'; y_position = y_position + 70; //シンクロ奥義 soubi[5] = new Label(); soubi[5].font = "bold 50px Meiryo"; soubi[5].color = '#00ffff'; soubi[5].width = 700; soubi[5].moveTo(190,y_position); soubi[5].opacity = 0.0; mainScene.addChild(soubi[5]); soubi[5].text = 'シンクロ奥義'; y_position = y_position + 70; //真奥義 soubi[6] = new Label(); soubi[6].font = "bold 50px Meiryo"; soubi[6].color = '#fff'; soubi[6].width = 700; soubi[6].moveTo(260,y_position); soubi[6].opacity = 0.0; mainScene.addChild(soubi[6]); soubi[6].text = '真奥義'; y_position = y_position + 70; //デュアル覚醒奥義 soubi[7] = new Label(); soubi[7].font = "bold 50px Meiryo"; soubi[7].color = '#00ffff'; soubi[7].width = 700; soubi[7].moveTo(135,y_position); soubi[7].opacity = 0.0; mainScene.addChild(soubi[7]); soubi[7].text = 'デュアル覚醒奥義'; //透明のオブジェクト(上) var coverSquare_1_s = new Sprite(700,200); var coverSquare_1 = new Surface(700,200); coverSquare_1.context.beginPath(); coverSquare_1.context.fillStyle = 'rgba(30,144,255,1.0)'; coverSquare_1.context.fillRect(0,0,700,200); coverSquare_1_s.image = coverSquare_1; coverSquare_1_s.moveTo(0,0); coverSquare_1_s.opacity = 1.0; mainScene.addChild(coverSquare_1_s); //透明のオブジェクト(下) var coverSquare_2_s = new Sprite(700,200); var coverSquare_2 = new Surface(700,200); coverSquare_2.context.beginPath(); coverSquare_2.context.fillStyle = 'rgba(30,144,255,1.0)'; coverSquare_2.context.fillRect(0,0,700,200); coverSquare_2_s.image = coverSquare_2; coverSquare_2_s.moveTo(0,585); coverSquare_2_s.opacity = 1.0; mainScene.addChild(coverSquare_2_s); //ここからメイン処理 mainScene.onenterframe = function () { //カウンターをインクリメント counter_main += 1; //タイトルを非表示 if ( counter_main > 50 && counter_main < 150 ) { if ( titleText_01.opacity > 0.01 ) { titleText_01.opacity -= 0.01; titleText_02.opacity -= 0.01; titleText_03.opacity -= 0.01; } else { titleText_01.opacity = 0.0; titleText_02.opacity = 0.0; titleText_03.opacity = 0.0; } } //ルーレットの要素を表示 if ( counter_main >= 150 && counter_main < 250 ) { for (let i = 0; i <= 7; i++) { if ( soubi[0].opacity < 0.99 ) { soubi[i].opacity += 0.01; } else { soubi[i].opacity = 1.0; } } } //ルーレット回転(上方向) if ( counter_main >= 250 && counter_main < 290 ) { for (let i = 0; i <= 7; i++) { soubi[i].y -= 1; } } //ルーレット回転(下方向)徐々に速度アップ if ( counter_main >= 290 && counter_main < 390 ) { counter_sub += 1; for (let i = 0; i <= 7; i++) { soubi[i].y += speed; if ( soubi[i].y >= 760 ) { soubi[i].y = 200; } } if ( counter_sub >= 10 && speed < 10 ) { speed += 1; counter_sub = 0; } } //ルーレット回転(下方向) if ( counter_main >= 390 && counter_main < 700 ) { for (let i = 0; i <= 7; i++) { soubi[i].y += 10; if ( soubi[i].y >= 760 ) { if ( i==7 ) { soubi[i].y = soubi[0].y - 70; } else { soubi[i].y = soubi[i+1].y - 70; } } } } //ルーレット回転(下方向)徐々に速度ダウン if ( counter_main >= 700 && counter_main < 910 ) { counter_sub += 1; for (let i = 0; i <= 7; i++) { soubi[i].y += speed; if ( soubi[i].y >= 760 ) { if ( i==7 ) { soubi[i].y = soubi[0].y - 70; } else { soubi[i].y = soubi[i+1].y - 70; } } } if ( counter_sub >= 10 && speed > 1 ) { speed -= 1; counter_sub = 0; } } //ルーレットの文字を拡大 if ( counter_main >= 910 && counter_main < 955 ) { soubi[4].x += 1.2; soubi[4].y -= 0.2; soubi[4].scaleX += 0.01; soubi[4].scaleY += 0.01; } }; }; game.start(); }; </script> </head> </html>
こんな感じですね。
まず前提として「mainScene.onenterframe = function () {~}」の部分が延々とループされ処理が動く感じです。
あとはcounter_main を順にカウント増やしていってカウントに応じた処理を細々してる感じ。
ほんとはもっとスマートな実装方法があるとは思いますがちょっとしたものは凝らずに作るのも悪くは無いです。
コピペしてポンポンと処理増やせますしね。笑
必殺技の部分なんかはClassにしておくとホントは便利ですね。
一回だけポストするだけの即席プログラムなので平打ちで適当に作ってますが。笑
今回は細かい解説ではなく、こんな感じで作ってるよ!!ってのが少しでも伝わればいいかなと思った記事でした。
それでは皆さんも良いテクニカルライフを!!
加害者になりました。
こんにちは、tosumaです。
少し前に、車で事故を起こしました。私が加害者です。
立駐から車道へ出る際の出会い頭事故でした。相手は小さい子供でした。
1|事故
普段からよく利用する駐車場で、いつも通り出庫しようとゲートバーをあげて、
左右確認しながらトロトロと歩道へ。
別に特別意識してるわけではないですが自然の流れで歩道の手前で一旦停車、
左右に歩行者などが居ない事を確認してまたトロトロと進みました。
駐車場への通過部分なので歩道部分は若干傾斜になっているのでアクセルは踏まず
いつもクリープで進みます、ここでも左右を交互に確認しつつ進んでいました。
駐車場から車体が3/4ほど出たところで「トンッ」という小さい音が補助席の横から聞こえてきました。
補助席側を見ても何も見えず、「石でも踏んだかな?」と止まって思っていると
男性が慌てて駆けつけてきました。
時間的には音が聞こえて数秒くらいです。
頭で「まさか」と思ったのと同時に胸から込み上げてくるざわざわ感がどっと押し上げてきて、慌てて車から降りて補助席側に向かうと小さい子供と自転車が倒れていました。
2|事故直後
まずは子供の状態を確認しました。
特に泣いているわけでもなく、痛がってる様子も無し、見たところ外傷もなし、こけているので足がやや赤くなっているようには見えました。
この状況には強く驚いていました、当然ですね。大人でも困惑します。
続いて、男性(その子の父)に深くお詫びして、私から警察にすぐに連絡する事と判断して必要なら救急車を呼んで頂きたい旨をお伝えしました。
男性は特に怒って感情的になる事も無く、お子さんの心配と事故に困惑している様子でした。
少しして女性(その子の母)も合流し、お子さんの状態を確認されていました。
正直、もうこの時点で私自身は精神的にギリギリで、とにかく私がすべき事だけをしなければという感覚で動いていました。
車と自転車、そして小さい子供との事故というのは言葉だと言い表せない心への圧がありました。
それに、相手はウチの子とほぼ同じ年ごろの子です。
相手のお子さんが見た感じ元気にしていたというのが唯一心を維持する要素でした。
「早く帰りたいー」とか言っていました。
3|事故後(警察到着)
警察に通報し、待つ事5分ほどで最寄りの交番より警察の方が到着。
現場を確認、双方に状況の確認を取り、さらに15分ほど待ち交通課の方々が到着。
改めて更に詳しい現場確認、双方に聞き取りが行われました。
交通課の方より「なぜ事故が起こったと思いますか?」と問われました。
左右の確認もして、速度面も注意していて、これ以上何を......?と一瞬脳を過ったものの
今回接触した際にまったく相手が見えなかったので死角部分へのチェックと予測が甘かったと答えました。
子供は7歳で、乗っていた自転車はその子にしてはかなり小さい印象でした、おそらく幼稚園の頃に買ってもらってそのまま乗っていたのだろうと感じました。
私はミニバンに乗っていたので自転車に乗った子供の頭の高さはタイヤくらいの高さなので、運転席からは見えませんでした。
交通課の方からは「でも事故は起きてるので、そうは言っても左右の確認してないんちゃいます?」と。
特に何も言い返す気力も無く、必要も感じなかったので言われるままに受け入れていました。
各応対中、私の妻も急いで現場まで来てくれ、相手の家族へ深く謝罪してくれていました。
相手の女性からは妻へ「ウチの子が申し訳ない」「ケガもしてないし病院も行くつもりもない」「自転車も特に問題無さそう」と話があったようで私の精神状態と相手家族の雰囲気と警察の方々の話の温度差に若干困惑していました。
相手と連絡先を交換して、その場は解散となりました。事故発生から凡そ1時間くらいでした。
4|事故後(解散後)
妻からは「ちゃんと注意して運転してたから相手にケガ一つなかったんだよ」といった感じでたくさんフォローしてもらいましたが、さすがに気持ちの立て直しがすぐには出来ずでした。
家に帰って子供の顔を見るとより心にくるものがありました。
相手にケガも無いし、金銭的なトラブルなども生じなかったので、出来る限り普通にしていようと普段通りに生活していましたがしばらくは車に乗るのや、子供に自転車を乗せるのが怖くてしょうがなかったです。
その数日後に家族でコロナになってしまい、一瞬それどころではなくなったのですが、
回復後に相手へ連絡入れました。繋がりませんでした。
5|最終的に
日をあけて再度連絡入れました。繋がりませんでした。
一旦留守電を入れて、様子見する事にしました。警察へも次のアクションがわからなかったので連絡してみると担当の警察の方が夏休みらしく繋がりませんでした。
しばらく日が経ち、担当の警察の方とも連絡が取れ。
話を聞くと相手の方より物損で処理で進めて頂いたとの事でした。
つまり罰則的なものは無しですね。
なので、相手の認識としては車が子供にぶつかったのではなく
子供の方から車にぶつかった、という事でしょうか。
6|今回の事故をふまえて
なんにせよ、やっと胸につかえていたものが少し取れた気がしました。
結果的には大した事故ではないのかもしれませんが、
車から降りて子供が倒れていた画が脳裏にこびりついていて
小さかろうが、大きかろうが、事故は事故だと改めて感じました。
よく事故を起こしたら「絶対自分からは謝るな」とか聞きますが
初めて事故を起こして正直そんな立ち回りする気持ちにはなれませんでした。
ただただ「相手の子大丈夫だろうか」「申し訳ない」の2つしか頭になかったです。
もし子供の方からぶつかったのだとしても。
車に乗らないってのは生きていく中で避けようがないため、
今後も気を付けて車には乗りたいと強く思いました。
皆さんもどうか車の運転はご注意くださいませ。
お読み頂き有難うございました。
※よければもう1本 関連記事をお読み頂けると幸いです