1. はじめに
みなさんこんにちは、たべと申します。
2024年度の筑波大学のenPiTという授業でおよそ1年間チーム開発をしていました。
今年度から2年生が受講できるようになったのですが、2年生はcoins1・mast2・klis3からそれぞれ3名ずつくらいでした。初の2年生受講生として参加させていただいたenPiTを振り返っていきます。
かなり長くなってしまったのでここだけは読んで欲しいというところを残しておきます。
2. 開発したプロダクトについて
プロダクト名: Who?Name!
*このプロダクトは未完成です。今後も開発続けていく予定です。
これは、プレイヤーがカードとして登場する、人間版ナンジャモンジャです。
アイスブレイクとして、初対面の人の顔と名前を覚えることを目的としています。
3. チームについて
- チーム名: 脱・薄情者
- 由来: 名前を覚えられない薄情者を脱したい
割とみんな「チーム薄情者です」と名乗っていることが多く、本来「脱」の部分が重要なのでは…?と思っていました。最終成果発表会ではしっかりと「脱・薄情者です」と名乗ったら、コメントに「脱」がちらほら書き込まれていました。 - メンバー: 6人→7人
-
芦沢さん : 情報理工学位プログラム・M1
進行役や議事録を取ったり、常にチームをまとめてくれていた
-
伊勢さん : 情報理工学位プログラム・M1
enPiT3回目のプロ、チーム専属メンターと言っても過言ではない
-
とまとさん : 情報理工学位プログラム・M1
お菓子担当大臣、いろいろなアイデアを出してくれていた
-
やーさん : 情報理工学位プログラム・M1
現状確認のプロ、これってこういうことですよね?と確認を入れてくれていた
-
モリくん : coins・B2
状況整理のプロ、やーさんのストップに呼応して状況整理をしてくれていた
-
そらき : klis・B2
秋から加入、発表が上手い、enPiTで一緒にがんばった数少ないklis同期、戦友
-
たべ : klis・B2
PO4やってました。例え話などで話をまとめるのが上手いと言ってもらえることが多くて嬉しかったです。
-
芦沢さん : 情報理工学位プログラム・M1
ScM5はスプリントごとに変えていました。
このチームはボリューム層の3年生が1人もいない面白いチームでした。あと、たぶん人数が過去最多です。楽しく和気藹々としたチームで雰囲気がすごい良かったです。トップクラスで仲良しな自信あります!
最終成果発表会では「薄情者だった人間のテンションとは思えない」「なかよしそうでよい」「おしゃべりで話がすぐ逸れる→本当に薄情者だったのか?」「ファッション薄情者!?」「さてはビジネス薄情者か」などと面白いコメントをたくさんいただきました。
その反面、雑談や話の脱線、議論が長すぎて手を動かす時間がない、チーム内での認識の齟齬といった課題に悩まされていました。これらの課題を解決するために、以下のような取り組みをしていました。
-
議題の提示
特に夏合宿では話し合いが多かったので議題といつまでに決めるかを最初に決定して、タイマーと議題を机の上に置いてから話し合いを始めていました。Miroのタイマーもよく使っていました。 -
雑談ベル
議論が飛躍したり、話が逸れたり、雑談が終わらなかったりといったことを防ぐために、「これは雑談だ!」と思ったら「チーン!!!」と叫んで雑談を終わらせるようにしました。これも夏合宿期間で大活躍でした。 -
役割分担
人数が多いが故に何もしていない人がいることもありましたが、人数が多いからこそできたことでもあると思います。Sprint 3以降は開発班2つとルール班に分かれて作業することが多かったです。
また、レビュー開始30分前からレビュー準備をするレビュー係を2人割り振り、開発を進めながら、質の良いフィードバックをもらえるように工夫していました。 -
合意
「今、何の話をしているか」「どこがどのように変更されたか」「方針がどうなったか」といったことで、よく認識の齟齬が起きていました。これも人数が多いが故の課題であったと思います。
特に、夏合宿期間の話し合いでは、今何の話をしているかわからない人がいたり、考え方の違いから意見がうまく伝わらないといったことが頻発していました。
ざっくり、芦沢さんとやーさん、伊勢さんとたべ、とまとさん、モリくんといった感じで方向性が分散していて、似た考え方の人同士では伝わっているけど…といったことが多かった印象です。芦沢さんとやーさんが「今何の話だっけ?」と確認する機会をよく作ってくれていました。
また、開発が進んでからは決定事項チャンネルを作り、重要な決定事項はテキストベースで残すようにしました。Sprint 3以降は実装方針や変更点などを共有するために、毎回プランニング時にTeamAMFを確認するようにしました。
4. enPiTの1年間について
春学期
自己学習期間
4-7月は自己学習期間でした。正直何を勉強すれば良いのかわからず困っていました。
仲の良い先輩に「Webアプリ作る授業取るんですけど、何やっておくと良いですか!!!」と聞いて、まずHTMLとCSS、次にJavaScriptを勧めてもらったので、その2つをやりました。
HTMLとCSS
『スラスラわかるHTML&CSSのきほん』という本で勉強しました。4月から5月の頭くらいでやり切りました。
JavaScript
『確かな力が身につくJavaScript「超」入門』という本で勉強しました。HTMLとCSSが終わってすぐに本を購入したのですが、サークル関係で忙しく、手をつけたのは宿祭が終わってからだった気がします。その後、雙峰祭準備で忙しくなり始めて、夏合宿が始まる直前までやっていたと思います。
事前準備
8月に入って、Discordで事前準備の連絡がありました。おおまかに3つの準備と夏合宿についてのアナウンスがありました。
身近な「困りごと」をメモしておく
以下は、アナウンスの内容です。
授業開始までに、自身の身近な「困りごと」をメモしておいてください。enPiTでは、各自の困りごとを持ち寄り、共感する人同士が集まってチームを組みます。解決方法や作りたいものはチーム結成後に演習を通して考えるのでまだ考えないでください。
(Discordより)
意外と「困りごと」が思いつかず、むしろ困っていました。
事前確認教材
アジャイルに関するオンデマンド教材
産技大enPiTのオンデマンドコンテンツとその動画中で説明されているスクラムガイドについて目を通しておくように促されました。
当時は聞きなれない言葉がたくさん出てきてあまりよくわかりませんでしたが、enPiTを通してアジャイルに関する考え方がなんとなくわかるようになって良かったです。今はアジャイルとは、「より良い」を生み出すためのプロセスという理解をしています。
Git/Github事前準備
夏合宿初日Git/Github演習の資料が公開され、確認と準備をしました。以下の5つのうち必須のものは必ず夏合宿までに済ませておくようにとのことでした。
- 【必須】Gitのインストール
- 【必須】VSCode, Git Graph拡張のインストール
- 【必須】GitHubのサインアップ
- 【必須】Git GraphでGitHubにアップロード
- Gitの言葉入門
Git/Githubが何もわからない状態で資料を読みながら事前準備に取り掛かりました。出てくる画面が英語なので不安になりながら準備していましたが、環境構築は一通りできました。Gitの言葉入門は目を通したもののよくわかりませんでした。
情報収集フォームへの回答
授業実施に関係するアカウント情報(Google, Discord, Github)、および物品貸出以降の事前調査等のためのフォームに回答しました。
夏合宿
9/18(水)-20(金), 24(火)-27(金)の計7日間、10:00-18:00でした。
外部講師を招いての講義で楽しかったです。
各日程の内容は以下のとおりです。
9/18:ガイダンス、Git/Github演習他
9/19:チーム決め、デザイン思考/UXD演習(講義、課題の観察&分析)
9/20:デザイン思考/UXD演習(課題の観察&分析)
9/24:アジャイル研修(講義、チーム演習)
9/25-27:チーム開発
(Discordより)
前半
前半Day1: 9/18
チームビルディング練習
近くに座っている4人でチームを組んで活動しました。授業に来たときklisの同期で固まって座っていたので、klis2年生3人と情報理工学位プログラムの院生の先輩1人のチームでした。余談ですが、この先輩と出身高校が同じだと判明して嬉しかったです。
これは実際に開発を行うチームとは別で、アイスブレイクとアジャイルの考え方に慣れるためのグループワークといった感じでした。
Git/Github演習
環境構築は済んでいたので、「Gitとは何か、使い方について」「バージョン管理とは」「用語について」などといった座学をして、実際にリポジトリを作ってみてローカルに持ってくるところまでやりました。
これも演習だけでは理解しきれなかったのですが、開発していくうちにGitが使えるようになりました。
毎年恒例のクイズ大会
Gitやアジャイルに関するクイズ大会がありました。設問が正解させる気なさそうで面白かったです。文字数などで必死に資料を探して「リーン思考」を当てられて満足しました。
SprintAMFとTeamAMF
その日の良かったところと改善点を付箋に書き出して、チームで重要だと思ったものを残しておくというふりかえりをしました。
前半Day2: 9/19
デザイン思考概要
デザイン思考とは何かという座学と9/18に組んだチームでインタビュー練習をしました。私は、本当にユーザーが欲しているものは何かということを重視している考え方という理解をしました。インタビュー練習は「1日の過ごし方」というテーマでやったのですが、みんな大学生らしい生活リズムで面白かったです。
チーム決め
「困りごと」を持ち寄ってチーム決めをしました。「困りごと」を思いつくだけ紙に書いて公開して、シールを貼って共感するものに投票して、多かった「困りごと」はブースを立てて人を募るという方法でチームを作りました。
3年生がボリューム層の授業なので就活に関わる「困りごと」や一人暮らしに関わる「困りごと」や多く、2年生で宅通6をしている私にはあまり共感できるものがなくて困ってうろうろしていたところを「人の名前が覚えられない」というブースを立てていた伊勢さんに拾ってもらいました。
デザイン思考演習
「人の名前が覚えられない」 というテーマのもとで、PECOフレームワークを使ってRQ7をたくさん書き出して、優先順位づけをしました。本来は、POV8を作る作業もあったのですが、時間が足りず仮で決定して翌日に持ち越すことにしました。翌日のインタビューのために他のチームの人に協力依頼のメッセージをDiscordに流したりしました。
RQ
PECOフレームワークの4つの観点からRQを立てました。
POV
以下のようなタテマエメソッドを用いてPOVを作りました。
仮で決定したPOVは以下のものでした。
- 一度自己紹介されたにも関わらず名前を忘れてしまった人は、
- 何かしらのものを見て人の名前を思い出している。
- なぜなら、初対面で無いのに人の名前を聞くのは気まずいからだ。
- とはいえ、毎回その何かしらのものがあるとは限らない。
- つまり、誰でも持っているものでその場で確認することができれば良いのではないか?
このときから、チームの雰囲気はすごい良かったのですが、みんながよく話すがために手を動かす時間が足りなくなり、進捗が生まれないという課題が片鱗を見せていました。
前半Day3:9/20
Day2の続きです。
進捗が芳しくなかったため、午前中にテーマの深掘りとRQなどの再考をして、POVを作り直したり、インタビューの内容を決めてインタビューを行い、HMWQを考える作業をしました。
議題をその都度紙に書いて掲示したり、雑談ベルを導入しました。雑談ベルとは、話が脱線したと気づいたら「チーン!」と叫んで雑談を止めるための仕組みです。
テーマを「名前が覚えられない」から「一度名前を聞いたにも関わらず、その名前を忘れてしまった時に、再度聞き直すのが気まずい」に絞りました。
その結果、チームで選んだPOVは以下のものになりました。
- 名前がわからない時に濁している人は、
- 本人に聞き返さずに名前を確認する手段を必要としている。
- なぜなら、人に名前を聞き返すのは失礼だと感じているからだ。
- とはいえ、人に聞き返されることを不快に思う人は少ないと思う。
- つまり、大学生なら名前を忘れても聞き返せば良いことを広めれば良いのではないか?
その後、インタビューの内容を話し合い、インタビューとアンケートを実施しました。ご協力いただいた方はありがとうございました。
チームメンバーが多いので2人1組になって、インタビュアーとメモ係を分担していました。
ユーザーリサーチではそれが本当にあっているかを確かめるのが重要ということを念頭においていました。
HMWQ
HMWQとは我々はどうすれば〜できそうか?という問いで、講義ではPOVとともに空港の例を挙げて説明されていました。
- 名前を聞き返しても怒る人はほぼいないので、意識的に名前を聞き返しやすくする。
- 名前を聞き返す行為すらなくなるように、いつでも名前を確認できる環境を用意する。
- 名前を忘れることを会話のチャンスにする、レクリエーションにする。
- そもそも一回で忘れないようにするには?
など様々なアイデアが出ましたが最終的に、以下のものに決定しました。
最高に名前を聞き返しやすくするには?
その後、全体のワークショップで開発するプロダクトのポスターを考えました。
名前を組み合わせて面白い画像を出力するプロダクトと、アバターを作成して人の顔と名前を覚えるプロダクトの案が出ましたが、意見が割れて1つに絞りきれず、このままレビューでどちらが良いか聞いた記憶があります。
レトロスペクティブツアー
各チームのところをまわり、レトロスペクティブの結果であるTeamAMFを全体で共有するツアーです。チームごとに全く違っていて興味深かったです。自分のチームの抱えるチーム運営の課題をどう解決しているのか、何か工夫をしているかなどと質問して、自分のチームに持ち帰ることができて良かったです。
今後、レビュー→レトロスペクティブツアーという流れはどのスプリントでも行っていました。
前半の打ち上げとして、塚田農場で夜ごはん食べました。
楽しかったです。
9/21-23
お休み!!!と言いつつ9/21はTHKという放送サークルで感謝の会という大学のイベントのスタッフをしていました。立食パーティーに参加できるのでお得です。
9/22と9/23は教習所に行っていました。私のお休み…どこ…
後半
いよいよ開発が始まります。
後半Day1: 9/24
この日から「U_name」というプロダクト作りが始まりました。
アジャイル開発概要
アジャイル開発についての座学とワークショップがありました。事前学習でわからなかった部分が少しわかるようになりました。
ワークショップでは、再度「困りごと」とそれを解決する「アイデア」を出し、優先度や実現性を考えました。さらに、その「アイデア」を細部化して誰のどんな課題を解決するのかという「解決案」を考えました。
PBL
さらに、プロダクトバックログ(PBL)を考えました。PBLは利用者にとって価値のある単位でプロダクトが実現したいものをリストにしたものです。PBLの中の付箋はプロダクトバックログアイテム(PBI)と言い、1-2時間程度で実現できる、開発者の作業項目でもなく、機能単位でもない、ユーザーから評価可能な機能性の単位であることが求められていました。
この日はTHKのイベスタで秋季入学式の仕込みをしてから授業に参加しました。昼休みと授業終わりもイベスタに参加して、業務が終わり次第夜ごはんの百香亭に向かいました。忙し〜
後半Day2: 9/25
EVP
エレベーターピッチ(EVP)を作成しました。EVPとはエレベーターが目的階に着く間ぐらいの短い時間でも伝えられる、短くまとまったビジネスの売り文句のことです。
相変わらず時間内で決めきれず、一旦仮で提出したものです。
その後、議論を重ねてこのようになりました。
スプリントバックログ
毎回スプリントゴールを達成するために、タスクを細分化してスプリントプランニングをします。
各タスクをスプリントバックログアイテムといいます。
Hello World
実質、環境構築のことです。スプリントバックログに沿って、デプロイ方法を決めたり、言語を決めながら進めました。このチームで最も知識がなかったのが私だったので、私が環境構築してみることになったのですが、チームのみんなが私の理解度に合わせて進めてくれました。
このときに初めてデプロイが「システムをサーバーに上げて実際に動かせるようにすること」と知りました。
この日も同じくTHKで業務してから授業に参加。夜ごはんは楽蔵でした。
後半Day3: 9/26
プロダクトバックログリファインメント
PBLの見直しをしました。ユーザーストーリーが定まっていなかったのでEVPから見直すことにしました。
EVPの中の「たべちゃん」は私です。ペルソナを具体的に決めようとなった結果、私向けのプロダクトになりました。
リファインメントに時間を取られ、達成できそうなスプリントゴールとして「固定の3人の名前を確認できる」を設定し、固定で名前を表示して、実際の画面表示に近いものを作成し、レビューに持って行きました。
この日の夜ごはんは駅前のビストロポリッツァというイタリアンバルでした。
後半Day4: 9/27
プロダクトのペルソナになったことから、POに任命されました。同時に芦沢さんがScMに。
「自分の近くにいる人がわかる」をゴールに開発を進めました。Bluetoothを使って端末情報を取得しようという方針になりました。このときは、コーディングにはノータッチでした。
この日のデモで、使用想定として寸劇をやりました。ちょっと恥ずかしかったです。
FunDoneLearn
夏合宿のふりかえりとして楽しかったこと、やったこと、学んだことを書き出しました。
ここで『FunDoneLearnのうた』というものがあるそうなので紹介しておきます。
夏合宿最終日ということで、夜はさん吉で打ち上げやりました。Tsuquidというスプラトゥーンサークルの飲み会とかぶってしまったのでそちらに顔を出してから参加しました。着いたときに好きなひらがなの話題で盛り上がっていて面白かったです。二次会はbetteiでしたが、終電の関係ですぐにお暇しました。もう少し居たかったな…
秋学期
秋学期は水曜3・4限、金曜5・6限で授業だったのですが、水曜4限がklis2年次必修の専門英語と被っていたので、毎週3B棟から7A棟までおよそ3kmを15分の休み時間で移動していました。流石に間に合うか不安だったので3限を5分ほど早く抜けさせてもらっていましたが、それでもギリギリでした。
これもあって、秋学期はチームメンバーが揃わなかったです。
10/9: ガイダンス・プロダクト方針検討
ここで、そらきが脱・薄情者に加入!!!
この日は以下の4つを再考しました。
- ロングレビュー1までのゴール
- チーム内のロール(PO:プロダクトオーナー、ScM:スクラムマスター、他)
- エレベーターピッチ
- プロダクトバックログ(PBL)
Bluetoothの関係でネイティブ移行の話があがりましたが、klis2年組が居なかったため、次回へ持ち越しに。
10/11-27: Sprint 1
「自分の近くにいる人がわかる」をゴールに開発を進めました。
iOSに向けのネイティブ移行はFlutterとReactNativeがあがりましたが、今までReactを使っていたため、ReactNativeに決まりました。
新たにリポジトリを作り直し、環境構築とデプロイに時間がかかり、デモできるようなプロダクトがなく、困っていました。
Sprint 1-4で、他のチームのiOSアプリはExpo Goを使ってデプロイしているとわかり少し希望が見えました。
10/30: ロングレビュー 1
デプロイしたプロダクトがないままロングレビューを迎えました。
取り急ぎ作ったUIのモック画像を使いましたが、レビューで聞きたいこととやっていたことがずれていてあまり実りはありませんでした。
メンターさんからいただいたフィードバックがすごく刺さりました。
レビューで聞きたいことは「このプロダクトを使うかどうか(体験に価値があるかどうかだと思ってます)」なのに、今回は「こういう体験や機能があると想像したうえで、どう思うか」を聞いていたという印象です
見せてもらったプロダクトも7枚のUIモック画像もあくまで想像上のもので、本質的な体験(名前がわからない人が近くにいるとき、名前が確認できるという体験)は提供してないです
プロダクトがなくても人力でその体験は提供できます(例えばメンバーが横について、名前を知らない人に近づいたら名前を見せてあげるとか)
それで十分このプロダクト(ソリューション)の価値の検証はできるかと思います
そこで価値があると判断したらソリューションを実装し、そのうえでBluetoothが必要になったら実装するという順番でいいのかなと思います
この検証をしないと、仮に価値がないと判断したとき皆さんが頑張ってた環境構築やBluetooth機能が必要なくなってしまいます
『プロダクトがなくても「このプロダクトを使うかどうか」は検証できる』という助言をいただき、ここからチームのレビューに対しての姿勢が変わったと思います。
11/1: ゲスト講義 1
不調で参加できず、悔しかったです。資料とMiroの確認をして、次のスプリントの初めに何をしたか教えてもらいました。
「プロダクトが提供できるのは、機会、体験、経験だけ」という観点から、プロダクトについて見直しをしていたようです。
11/6-22: Sprint 2
Bluetoothを使った端末情報の取得が難航し、このスプリントも「自分の近くにいる人がわかる」をゴールに開発を進めました。
このスプリントでレビュー開始30分前になったらレビュー準備をするレビュー係ができました。ほとんどの開発を2班に分けて進めていたので、各班から1人ずつレビュー係を出して、進捗のすり合わせなど情報共有や、レビューで聞きたいことをまとめ、実機がないうちはアナログで価値提供するために、実機ができてからは他のテームに根回するなどしてスムーズにレビューが始められるように準備をしていました。
Sprint 2-3でBluetoothが使えなさそうだと判明し、再度方針転換しました。
そのため、Sprint 2-4ではソリューションやEVPから見直しました。
ソリューションを「名前を忘れないようにする」と方針を変え、かつて出ていたリアルパーソンナンジャモンジャの案を採用することになりました。このときのレビューは、再度価値検証を行い、「ナンジャモンジャで名前を覚えることはできるのか」ということに焦点を当てていました。
ここから「Who?Name!」の開発が始まります。
Sptint 2-5で、Gitのリポジトリを作り直し、ReactでHello Worldをして、サンプル画像を出せるようにしてデモをしていました。ここまで来ると手慣れたもので、比較的スムーズにHello Worldできました。
11/25: ロングレビュー 2
ここでも、レビューで価値検証することを意識していました。使用想定を考え、その上で使いたいか、名前を覚えるのに効果はありそうかということに着目していました。フィードバックをMiroに書き出し、優先順位をつけたり、改善案を出していました。
12/4-18: Sprint 3
名付けのハードルが高かったため、ゴールが「簡単に名付けができる」になりました。そして、ScMは伊勢さんに。
ここから、プランニング時にTeamAMFを確認するという付箋が貼られるようになりました。
ロングレビューをやる度にレビューへの意識が高まっていったような気がします。
開発班とルール班に分かれて作業していました。水曜4限の関係で私はルール担当が多かったです。
本家ナンジャモンジャのルールを参考にルールの文章を考えたり、名付けのハードルを下げるためのヒントを考えたりしました。スプリントの後半になると、「楽しくゲームができる」を目標に、機能性とわかりやすくゲームを進められることを両立できるように、アイデア出しから実装まで携わりました。
Sprint 3-5ではカードをめくるSEの実装を担当しました。
Game.tsx
// カードをめくるSE
const playSound = () => {
const audio = new Audio('/sounds/card-flip.mp3');
audio.play().catch((error) => {
console.error('効果音の再生に失敗しました:', error);
});
};
{/* --- Nextボタン --- */}
{entries.length > 0 && (
<div className={styles.card}>
<button
onClick={() => {
setCount(Math.floor(Math.random() * entries.length)); // カウント設定
playSound(); // 効果音を再生
}}
className="p-4 text-white font-bold bg-blue-400 rounded-xl shadow-lg m-2"
>
Next
</button>
{/* --- ヒントボタン --- */}
<button onClick={()=>setIsOpenHint(true)} className="my-4 p-4 text-white font-bold bg-blue-400 rounded-xl shadow-lg">名付けのヒント</button>
</div>
)}
ここに来て、ようやく自分で実装してみたいと言ってコーディングしたのですが、もう少し積極的に開発に関わっても良かったかなという気持ちもあります。
12/20: ゲスト講義 2
プレゼンの仕方の講義でした。すごく良かったです。
そのときのメモが残っていたので重要そうな部分だけ下に残しておきます。
認知→信頼→利益と主張・根拠・裏付け
わかりやすさが正義、わかったつもりにさせるのが重要
データのような数字で安心、一体感や共有のような感覚で安心、広がりや収束のような傾向で安心する人の3パターンに分かれることが多い→スライドで数字なら、トークで傾向のように補う
五感のうち三つを刺激する
「3」を意識して聞き手の行動変容を起こそうといった趣旨でした。一度に理解できるものは3つまでみたいな話もあったような気がします。
プレゼン資料の作り方も扱っていて、最終成果発表会の資料作りのときに講義資料を読み返しながら資料作成しました。
12/25: ロングレビュー3
12/26-1/5: 冬休み
たくさん遊びました。ゲームしたり、ライブに行ったり、遊びに行ったりと充実してました。
1/8-16: Sprint 4
ロングレビュー3でもらったフィードバックをMiroにリストアップして優先順位をつけたり、改善案を出したりしてからスプリントを開始しました。このスプリントは毎回もらったフィードバックを書き出して整理していました。
Sprint3からあった付箋がバージョンアップしていました。
このスプリントは主にバグの修正と流れを止めずにゲームができるということを目標にしていました。
コンフリクトが起きたり、ビルドエラーが出たり色々大変でした。残業も多かったです。
ゲームの公平性とカードをめくったかどうかわかりやすくするために、カウントダウンの機能を実装しました。
Countdown.tsx
import { useEffect } from 'react';
export default function CountdownTimer({ timeLeft, setTimeLeft, isRunning }: { timeLeft: number, setTimeLeft : React.Dispatch<React.SetStateAction<number>>, isRunning: boolean }){
useEffect(() => {
let timer: NodeJS.Timeout;
if (isRunning && timeLeft > 0) {
timer = setTimeout(() => {
setTimeLeft(timeLeft - 1);
}, 1000);
}
return () => clearTimeout(timer);
}, [isRunning, timeLeft, setTimeLeft]);
const formatTime = (time: number) => {
return time;
};
const getDisplayContent = () => {
if (isRunning) {
return <p className="font-bold">次の画像まで<span className="font-bold text-4xl text-blue-500">{formatTime(timeLeft)}</span></p>; // trueの場合
} else {
return <p className="font-bold">Nextを押すと3秒後に画像が切り替わるよ</p> // falseの場合
}
};
return (
<div className="h-9">
{getDisplayContent()}
</div>
);
};
Game.tsx
import Image from "next/image"
import { useState, useEffect } from "react";
import CountdownTimer from "./Countdown";
type entries = {
id: number;
name: string;
imgURL: string[];
}
export default function Game({ setSceneController, entries }: { setSceneController : React.Dispatch<React.SetStateAction<string>>, entries: entries[] }){
const [audio, setAudio] = useState<HTMLAudioElement>();
useEffect(() => {
if (typeof Audio !== 'undefined') {
setAudio(new Audio('/sounds/countdown.mp3'));
}
}, []);
// const audio = new Audio('/sounds/countdown.mp3');
const playSound = () => {
audio?.play().catch((error) =>{
console.error('効果音の再生に失敗しました:',error);
});
};
function getRandomEntry(obj: entries[] ): {name: string, img: string} {
const randomIndex = Math.floor(Math.random() * obj?.length);
const randomImg = obj?.[randomIndex].imgURL[Math.floor(Math.random() * obj?.[randomIndex].imgURL.length)]
return {name: obj?.[randomIndex].name, img: randomImg};
}
const [randomEntry, setRandomEntry] = useState<{name: string, img: string}>(getRandomEntry(entries))
// CountdownTimer用
const [timeLeft, setTimeLeft] = useState(0);
const [isRunning, setIsRunning] = useState(false);
const startCountdown = async() => {
console.log("開始");
playSound(); // サウンド再生を呼び出す
setTimeLeft(3); // 3秒のカウントダウン
setIsRunning(true);
await new Promise(resolve => setTimeout(resolve, 4000));
setIsRunning(false); // カウントダウン停止
console.log("3秒後に実行");
}
audio?.addEventListener('ended', () => {
// ここに音声再生後に実行したいコードを書きます
console.log('音声再生が終了しました');
// 他の処理を追加
setRandomEntry(getRandomEntry(entries)); // エントリーを更新
}, { once: true });
return(
<>
<button
onClick={() => setSceneController('Home')}
className="p-4 text-white font-bold bg-blue-400 rounded-xl shadow-lg m-2"
>
ゲームをやめる
</button>
<div>
{/* --- 表示 --- */}
<div className="p-4">
<Image
src={randomEntry.img}
alt={randomEntry.name}
width={300}
height={300}
layout='responsive'
className='max-h-72'
/>
<p className="text-4xl text-amber-300 font-bold">{randomEntry.name}</p>
</div>
<CountdownTimer timeLeft={timeLeft} setTimeLeft={setTimeLeft} isRunning={isRunning} ></CountdownTimer>
<div>
初めて出た人の場合:この人の<b>あだ名</b>をつけよう!
</div>
<br></br>
<div>
再度出てきた場合:名付けた<b>あだ名</b>を素早く叫ぼう!
</div>
<br></br>
{/* --- Nextボタン --- */}
<div className="flex flex-col">
<button
onClick={startCountdown}
className={`p-4 font-bold rounded-xl shadow-lg m-2 ${
isRunning ? "bg-gray-300 text-gray-500 cursor-not-allowed" : "bg-blue-400 text-white"
}`}
disabled={isRunning} // カウントダウン中は無効化
>
Next
</button>
</div>
</div>
</>
)
}
Sprint 4-4から最終成果発表会に向けて資料作成をしました。
ゲスト講義2を参考に資料作りと発表内容を考えました。
1/20: アジャイルリーダーシップ研修
任意参加ですが、せっかくなので参加しました。
英語がわからなくても通訳してくれるのでとてもありがたかったですが、英語できるようになりたいなぁと思いました。
内容はアジャイルとは、リーダーシップとはという趣旨で、アジャイルとアジリティ、アダプティブといった語の意味から実際のビジネスの例を挙げて説明していただけたのでとてもわかりやすかったです。言葉の定義は難しいから、状況に応じて解釈されているという話が印象に残っています。
1/24: 最終成果発表会
直前まで資料を作ったり、CM動画を作ったりと忙しかったです。発表資料を作るためにふりかえりをしていたので授業ふりかえりのときとかは少し楽でした。
実は、2時間くらいで動画編集しました。
他のチームのデモがすごく楽しかったです。特に、琉大のチームは夏合宿以来どんなプロダクトを作っているのか知る機会がなかったので面白かったです。
口頭発表を一通り終えて、ブースを立ててデモをした後は、チームで振り返りをしました。
ここでもFunDoneLearnをやりました。
その後、ドキドキの表彰タイム…!
方針転換をして時間がなかったのもあり、UIまで手が回らず、他のチームの整ったUIを見て(もちろん、どのチームのプロダクトも完成度が高かったです)、賞は厳しいかな〜と思っていたのですが…
優秀賞をいただけました!!!
すごい嬉しかったです。えっ!!!って叫んでました。
余談ですが、授業が終わった後は、ビストロ椿々で打ち上げをしました。学類の先輩に履修相談したり、同郷の人が多くて地元トークで盛り上がったりしました。チーズ豆腐がめちゃくちゃ美味しかったです。二次会はbetteiでした。このときもギリ19歳だったのでお酒は飲めませんでしたが楽しかったです。
1/29: 授業ふりかえり
AMFの最終リファクタリングをしました。緑がざっくりとわけた項目、薄い緑が良かったところ、赤が改善点、エメラルドグリーンが改善案です。
実は、脱・薄情者のTeamAMFにずっと外部講師のkyonさんがいました。
その後、授業全体へのフィードバックをしました。夏合宿のようにアイデアを出した後、ブースに分かれて話しました。私は残業のところにいたのですが、必修と被って居なかった分の補填は残業なのか…?と思いつつ、どうにかならないのかなぁと思いました。ちなみに私は、残業は合意が取れているのであればしても良い派です。
5. 学んだこと
-
合意の重要さ
3. チームについてでも触れましたが、このチームは本当によく認識の齟齬が起きていて、合意を取ることの難しさを実感しました。今何の話をしているかわかっていない人がいたり、考え方の違いから意見がうまく伝わらないということがよく起こっていました。合意が取れていないと方針が定まらないし、そもそも何について議論しているかわかっていないということもあったので、他の人が何についてどのように考えているか細かく確認を取るということが大事だと思いました。
アジャイルリーダーシップ研修でも合意に関するメモを残していました。メモにあるように、「合意」はアジャイルの根幹を成す重要な要素であると私は思います。しかし、「合意を取る」ことを目的にしたり、強要したりしてはならず、あくまで「合意を取る」ことは全員で同じ方向を向くための手段であるということを忘れてはいけないと思いました。
- そもそもアジャイルとは何か
色々定義があるが良い時、悪い時さまざま
その定義を適用することに全員が合意していることが重要→Frame of reference
その時々に応じて合意が取れていて全員が同じ方向を向いている状態- リーダーシップとは
責任を取ること
チームのメンバーの合意を取れるようにする力- お互いに相手に期待することを明確にして合意する
当然だと思っている思い込みにリーダーは対処していかなければならない
みんなわかっているということは期待であり、私はこう思うという約束をしなければならない
-
わからないことはすぐに聞く
どうしても知識不足や経験不足でわからないことが多かったので「わからないです!教えてください!」と言う勇気が大切だと思いました。今回先輩が多かったこともあって、わからないと言うとみんな快く教えてくれたのですごくありがたかったです。また、技術面では早めにメンターさんを頼るのも大事だと思いました。もちろん頼ってばかりで意思決定を丸投げするのは良くないですが、選択肢を広げるという意味ではすごく重要だと思います。意見を聞いて、それを実際に行動に移すかどうかの判断は自分で判断することが大切です。これも自分で納得してから意見を取り入れるという点で、自分自身との合意と言えるのではないかと思います。併せて、わからないことをわからないと言いやすい環境づくりも大事だと思いました。 -
ユーザー目線の価値
私は、「アジャイルはより良いを生み出すためのプロセスである」という解釈をしたのですが、誰にとっての「より良い」なのかということを常に考えることが重要だと思いました。プロダクトを実際に使うのはユーザーなので、ユーザーにとって「より良い」となるような価値を提供することが大切です。(開発者がユーザーであることもありますが、)開発者が作りたいものよりも、ユーザーにとって本当に価値のあるものは何かということを考え続けることが大切だと思います。これも、ユーザーが本当に欲しているものを開発するという点で、ユーザーとの合意と言えるのではないかと思います。 -
自己主張
自分の意見をしっかりと話すということは合意を取るために大事なことだと思います。お互いに自分の考えをしっかり伝えないと合意は取れません。私は「私はこう思う」と明確な意見を出すことが苦手で、「特に明確な意見がない」ということが多々あります。なので、自分で意見を生み出すのではなく、「誰かの意見に対してどう思うか」という形で議論に参加していました。さらに、私は頭の中でじっくり考えてから話す傾向にあるので最初のうちは話の流れに乗れないこともありましたが、だんだん思ったことをすぐに口に出せるようになりました。これもチームの雰囲気が良かったからだと思います。わからないことを早めに聞くにも繋がりますが、意見を言いやすい環境作りも大切だと思います。 -
立ち戻る勇気
このチームでは、2度の方針転換がありました。1度目は元々進捗がほぼなかったので失うものが少なかったのですが、2度目はソリューションごと変えたのでかなり勇気が要りました。2度目に関しては、Bluetoothが行き詰まった時点でもっと早く方針転換をしても良かったのかなという反省もあります。
また、デイリースクラムにおいては、合意の重要さでも書きましたが、「今何について話しているのか、何をしているのか」というように一旦立ち戻ってみて、全員の理解をそろえるということが大切だと思いました。
6. 終わりに
とても長くなってしまいましたが、ここまで読んでいただき本当にありがとうございます。
2年生のうちに貴重な経験をさせていただいて、多くのことを学びました。
ここで学んだことは、開発だけでなく日常生活にも活かせると思います。
今後、脱・薄情者としては、3/23のアジャイルPBL祭り2025に参加予定です。
お時間ある方は来ていただけたら大変嬉しいです。
私自身としては、来年度COJTのソフトウェアコースに参加することが決まっているので受講はできませんが、メンターとしてenPiTに関われたら良いなぁと思っています。
最後に、脱・薄情者のみなさん、本当にありがとうございました!楽しかったです!!!
-
情報メディア創生学類(College of Media Arts, Science and Technology)の略称、メ創とも ↩
-
知識情報・図書館学類(College of Knowledge and Library Science)の略称、知識や図書館、図情などとも ↩
-
プロダクトオーナー
製品開発における方向性を決め、プロダクトの価値を最大限化させる責任者 ↩ -
スクラムマスター
スクラムの進行役 ↩ -
一人暮らしをしている人が大半を占める筑波大学において、自宅から通学している人は「宅通」と呼ばれている ↩
-
リサーチクエスチョン(Research Question)
研究を定義し、研究を通してどのような答えを探すのか、方向性を定めるもの ↩ -
この講義ではユーザーの共感を得ることを目的とした観点(Point Of View) ↩