-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #27 from su-its/feat/game-screen/template
Feat/game screen/template (ゲーム画面途中まで)
- Loading branch information
Showing
23 changed files
with
956 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# ProgressBar コンポーネント説明 | ||
|
||
Team1 用.適宜加筆していってください. | ||
|
||
## 場所 | ||
|
||
typing/typing-app/src/components/atoms/ProgressBar.tsx | ||
|
||
## 使い方 | ||
|
||
```[jsx] | ||
<ProgressBar maxWidth={250} value={100} /> | ||
``` | ||
|
||
### props | ||
|
||
- maxWidth: number:100%時の横幅[px]. | ||
- value: number:進捗.0-maxValue をとる. | ||
- maxValue: number:100%の進捗. | ||
- height: number:高さ[px] | ||
|
||
### 例 | ||
|
||
progress を変更することで ProgressBar が伸び縮みする. | ||
|
||
```[jsx] | ||
const [progress, setProgress] = useState(0); | ||
const handleProgressChange = () => setProgress(progress+1); | ||
return ( | ||
<ProgressBar maxWidth={250} height={20} maxValue={100} value={progress} /> | ||
); | ||
``` | ||
|
||
### Style | ||
|
||
css ファイルは不使用. | ||
div タグ内で CSS-in-JS のみ使用. | ||
背景色・高さはここで指定. | ||
変更する場合は,他で使用されている場所に影響がでるので注意. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# WPM 表示の対数表示 | ||
|
||
## 動機 | ||
|
||
瞬間 WPM を表示すると現状のゲージを飛び出すことがかなり多い. | ||
|
||
## 対数表示 | ||
|
||
### 現状(線形表示) | ||
|
||
- ゲージ幅:330px | ||
- 現状の値域:謎(ラベルの数値がおかしい) | ||
- 実際には 0〜500 で仮実装 | ||
|
||
### 変更後 | ||
|
||
- ゲージ幅:330px(同じ) | ||
- 値域:0〜1000 | ||
- それを超えたら天井処理 | ||
- 式 | ||
|
||
``` | ||
value = (1000 / 3) * Math.log10((999 / 1000) * wpm + 1); | ||
``` | ||
|
||
- value: ProgressBar に渡す パラメータ | ||
- ProgressBar に渡す maxValue は 1000 とする. | ||
|
||
### 効果 | ||
|
||
頻出しそうな 0〜240WPM でゲージの 約 8 割を専有できる. | ||
![](./img/game-page/wpmLogFunc.webp) | ||
|
||
## UI 更新 | ||
|
||
以下の値に合わせてゲージのラベルを更新する必要がある. | ||
| WPM | ゲージ上での値 | | ||
| ---- | ---- | | ||
| 0 | 0 | | ||
| 50 | 569 | | ||
| 100 | 668 | | ||
| 150 | 726.2 | | ||
| 200 | 767.6 | | ||
| 250 | 799.7 | | ||
| 300 | 826 | | ||
| 350 | 848.3 | | ||
| 400 | 867.6 | | ||
| 450 | 884.6 | | ||
| 500 | 899.8 | | ||
| 550 | 913.6 | | ||
| 600 | 926.1 | | ||
| 650 | 937.7 | | ||
| 700 | 948.4 | | ||
| 750 | 958.4 | | ||
| 800 | 967.7 | | ||
| 850 | 976.5 | | ||
| 900 | 984.8 | | ||
| 950 | 992.6 | | ||
| 1000 | 1000 | | ||
|
||
Excel 用計算式 | ||
|
||
``` | ||
=(1000 / 3) _LOG10((999 / 1000) _ A1 + 1) | ||
``` | ||
|
||
## その他 | ||
|
||
### 対数化に使った関数の導出 | ||
|
||
#### 記号定義 | ||
|
||
$\log$の底は 10 とする(常用対数). | ||
$w \in [0, 1000]$:WPM の値 | ||
$v\in [0, 1000]$:ProgressBar 上での値 | ||
$v=f(w)$として | ||
|
||
- $v$が$\log w$に比例する | ||
- $[0, 1000] \rightarrow [0, 1000]$ | ||
|
||
の 2 つを満たす$f$を作る. | ||
|
||
$\log 0 : undefined$ なので$f(1000)$を先に考える. | ||
仮に | ||
$g(x) := a\log (x)$ ($a$: 任意定数, ただし$a\neq 0$) | ||
とすると, | ||
$g(1000) = 1000$から | ||
$g(1000)=a\log 1000 = 3a$ | ||
$\therefore a = \frac{1000}{3}$ | ||
つぎに$f(0)$について考える. | ||
ここで, $x:=h(w)$とし,$f(x)=g(h(w))$とすれば, | ||
$h(0) = 1, h(1000)=1000$を満たすとき | ||
$f(0) = 0, f(1000)=1000$を満たす. | ||
$w\in[0,1000]$を線形変換して$x\in[1,1000]$にすることを考えると | ||
$x=h(w)=\frac{999}{1000}x+1$ | ||
$\therefore f(w) = \frac{1000}{3}\log (\frac{999}{1000}x+1)$ | ||
|
||
### 採用しなかった対処 | ||
|
||
現状のゲージを飛び出すときは,飛び出さないように(max 関数使うなりして)天井処理. | ||
|
||
#### 採用しなかった理由 | ||
|
||
現状のゲージを飛び出す頻度が高すぎる and 切り捨てられる値域が広い. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
# GamePage 向け説明などなど | ||
|
||
Team1 用.適宜加筆していってください. | ||
|
||
## 用語 | ||
|
||
- Page:[url]/game で表示されるページ. | ||
- SubPage:Page 内の画面遷移で使う.それぞれ 1 つの画面. | ||
- GamePre:ゲーム開始前の画面のこと. | ||
- GameTyping:実際にタイピングする画面のこと. | ||
- GameResult:ゲーム終了後の結果表示画面のこと. | ||
|
||
## 前提 | ||
|
||
Game は以下のように画面遷移する. | ||
GamePre → GameTyping → GameResult | ||
|
||
## ディレクトリ | ||
|
||
### Page | ||
|
||
src/app/compontents/pages/ | ||
|
||
- Game.tsx | ||
|
||
### SubPage | ||
|
||
src/app/compontents/templates/ | ||
|
||
- GamePre.tsx | ||
- GameTyping.tsx | ||
- GameResult.tsx | ||
|
||
## 実装 | ||
|
||
### 画面遷移 | ||
|
||
![画面遷移図](./img/game-page/screen-transition.png) | ||
|
||
暫定的に `GamePre` → `GameTyping` → `GameResult` をループ.`GameResult` の後は変更のはず. | ||
Game.tsx 内で`subPageList`配列に 3 つの `SubPage` コンポーネントを格納しておき,インデックスを変更することで画面を遷移させる. | ||
`SubPage` 内では`nextPage`関数を受け取り,それを実行することで次のページのインデックスに変更されるようにしておく. | ||
`GameResult` の `nextPage` は要変更. | ||
|
||
### 各役割について | ||
|
||
それぞれの分担について,編集する可能性のあるファイルとやることを簡単に書いた.どちらも軽く考えただけ.編集する可能性のあるファイルは足りないかもしれないし余分かもしれないし,やることは他に良い or 理解しやすいやり方があるならそのようにすれば OK.以下のリストはあくまでも目安. | ||
|
||
#### 1 ゲーム開始ボタン | ||
|
||
##### 編集する可能性のあるファイル | ||
|
||
- GamePre.tsx | ||
|
||
##### やること | ||
|
||
- ボタンのスタイリングなど | ||
|
||
#### 2 開始ボタンを押したら、文章をランダムに選択 | ||
|
||
##### 編集する可能性のあるファイル | ||
|
||
- GamePre.tsx | ||
- GameTyping.tsx | ||
|
||
##### やること | ||
|
||
- まだはっきりしてない?のでとりあえず 0 ~ n の乱数を生成してダミーの fetch リクエストを送る. | ||
- GamePre.tsx ではすでに開始ボタンをクリックした時のイベントを設定しているが,props として受け取っている`nextPage`関数を呼び出す関数を作り,その中で文章選択のプログラムを書く. | ||
|
||
#### 3 カウントダウンの開始 | ||
|
||
##### 編集する可能性のあるファイル | ||
|
||
- GamePre.tsx | ||
- GameTyping.tsx | ||
- ProgressBar.tsx | ||
|
||
##### やること | ||
|
||
- `useEffect`を使いそう.タイマーアプリの実装とかが参考になるはず. | ||
- カウントダウン開始は[2]に実装してもらうので,最初はボタンを押したら開始とかで開発. | ||
- ProgressBar に残り時間と最大時間を渡す. | ||
|
||
#### 4 入力のマッチング | ||
|
||
##### 編集する可能性のあるファイル | ||
|
||
- GameTyping.tsx | ||
|
||
##### やること | ||
|
||
- キー入力はライブラリを使えば楽…? | ||
- 入力したキーの正誤のカウント. | ||
|
||
#### 5 カウントダウンが 0 になったタイミングで、データを送信 | ||
|
||
##### 編集する可能性のあるファイル | ||
|
||
- GameTyping.tsx | ||
|
||
##### やること | ||
|
||
- POST リクエストでスコアデータを送信.データ形式等はまた後で. | ||
|
||
#### 6 入力テキストの管理 | ||
|
||
##### 編集する可能性のあるファイル | ||
|
||
##### やること | ||
|
||
#### 7 リザルトの表示 | ||
|
||
##### 編集する可能性のあるファイル | ||
|
||
- GameResult.tsx | ||
|
||
##### やること | ||
|
||
- 結果を良い感じに表示. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<mxfile host="65bd71144e"> | ||
<diagram id="MP6PQ0_d54WQjaptJSu5" name="ページ1"> | ||
<mxGraphModel dx="432" dy="1955" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0"> | ||
<root> | ||
<mxCell id="0"/> | ||
<mxCell id="1" parent="0"/> | ||
<mxCell id="13" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;" edge="1" parent="1" source="2" target="6"> | ||
<mxGeometry relative="1" as="geometry"/> | ||
</mxCell> | ||
<mxCell id="14" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;" edge="1" parent="1" source="2" target="7"> | ||
<mxGeometry relative="1" as="geometry"/> | ||
</mxCell> | ||
<mxCell id="2" value="Game" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
<mxGeometry x="280" y="-560" width="60" height="30" as="geometry"/> | ||
</mxCell> | ||
<mxCell id="3" value="GamePre" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
<mxGeometry x="400" y="-640" width="80" height="30" as="geometry"/> | ||
</mxCell> | ||
<mxCell id="6" value="GameTyping" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
<mxGeometry x="400" y="-560" width="80" height="30" as="geometry"/> | ||
</mxCell> | ||
<mxCell id="7" value="GameResult" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
<mxGeometry x="400" y="-480" width="80" height="30" as="geometry"/> | ||
</mxCell> | ||
<mxCell id="8" value="" style="endArrow=classic;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="3" target="6"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="440" y="-600" as="sourcePoint"/> | ||
<mxPoint x="350" y="-580" as="targetPoint"/> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="9" value="" style="endArrow=classic;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="439.76" y="-530" as="sourcePoint"/> | ||
<mxPoint x="439.76" y="-480" as="targetPoint"/> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="11" value="" style="endArrow=classic;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="7" target="3"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="360" y="-480" as="sourcePoint"/> | ||
<mxPoint x="410" y="-530" as="targetPoint"/> | ||
<Array as="points"> | ||
<mxPoint x="440" y="-430"/> | ||
<mxPoint x="500" y="-430"/> | ||
<mxPoint x="500" y="-660"/> | ||
<mxPoint x="440" y="-660"/> | ||
</Array> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="12" value="" style="endArrow=classic;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;" edge="1" parent="1" source="2" target="3"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="340" y="-490" as="sourcePoint"/> | ||
<mxPoint x="390" y="-540" as="targetPoint"/> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="15" value="呼び出し" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=8;" vertex="1" parent="1"> | ||
<mxGeometry x="320" y="-580" width="40" height="20" as="geometry"/> | ||
</mxCell> | ||
</root> | ||
</mxGraphModel> | ||
</diagram> | ||
</mxfile> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
It is April 2002, and I am visiting Tokuro Takei’s comfortably sunlit Japanese/Western-style home in Hamamatsu, Japan for the first time. His wife meets me at the door with a deep bow, which I return with one of my own before handing over a gift-wrapped box of rice crackers and offering a stock Japanese apology for imposing myself like this. Mrs. Takei receives my gift with another bow and, as etiquette dictates, politely refuses to acknowledge my need to apologize. I remove my shoes in the ground-level foyer and step up on to the raised floor of the house in my stocking feet. Mrs. Takei offers me the customary house slippers a visitor to a Japanese house will typically wear. I decline the offer on the valid grounds that my feet are too big for the slippers, and we share a quick if bashful laugh over this footwear conundrum while she shows me to the living room sofa. | ||
When not in motion plying me with green tea and cookies while we wait for her husband to come to the living room, Mrs. Takei stands a few steps behind the sofa and just out of my field of vision. I can sense her nervousness, and am not sure if her taciturnity stems from fear and shyness or from her assuming that a language barrier will make any attempts at meaningful conversation a mutually embarrassing exercise in frustration. Accordingly, neither of us says anything. I sit on the Takeis’ sofa looking at naval citations on the wall and plastic models of Zero fighters lined up on the bookshelves while Mrs. Takei maintains her vigil safely out of sight. | ||
The cultural dynamic of silence at work here – which I have encountered thousands of times during my Japanese sojourn – is not particularly uncomfortable for me (although it may be for Takei-san, uninitiated as she is to visits from international men of mystery). Over the years, I have lost my quintessentially American fear of conversational lulls longer than a few seconds, so this particular silence does not faze me. Nevertheless, I am beginning to feel a tad guilty over Takei-san’s obvious discomfort, so I decide to try to put my hostess at ease with a little demonstration of Japanese language ability. Etiquette gives me an in here – it will not be untoward for me to apologize once again for my rude intrusion (under the rules of Japanese etiquette you can never truly apologize too much for anything). The tit-for-tat torrent of stock platitudes my apology will trigger can be found virtually word for word in any basic Japanese conversation textbook, but then again, sometimes clichés can be reassuring, and I suppose this has as good a chance of breaking some ice as anything else. (459 words) | ||
|
||
出典:Sheftall, M.G. (2005[2023]). Blossoms in the Wind: Human Legacies of the Kamikaze (pp113-114). New York: Dutton Books. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
As the night falls and silence covers everything, in my dream I become an adventurer. I crossed far-off mountains, explored unknown forests and interacted with various creatures I met along the way. Sometimes making friendships, sometimes overcoming ordeals, I am breath taken by the fantastic landscapes that I can only see in my dreams. Although the destinations are always changing, the experience of travelling enriches my mind and adds a new colour to my days in the real world. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
In 2050, our lives have changed in ways we cannot even imagine. At home, AI assists with daily tasks and transport is supported by fully automated vehicles. At work, virtual reality has replaced meeting rooms, enabling real-time collaboration even in remote locations. At the heart of all this technology, however, is the human spirit of connection. The technologies of the future exist to enhance humanity and enrich our lives. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Throughout the year, the change of seasons always brings fresh surprises. The arrival of spring melts away the cold of winter and brings flowers into bloom. Summer gives energy to activities in the sunshine, and autumn signals the end of the year through the carpet of fallen leaves. And when winter arrives, the serenity of snow envelops everything. Each season has its own unique beauty and rhythm of life. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Brewing a cup of tea in the afternoon is a special moment to get away from the busyness of everyday life and calm down. As the hot tea is poured into the cup, the warm steam fills the air and the subtle aroma soothes the soul. Through this quiet time, you face yourself and temporarily escape from the hustle and bustle of everyday life. Tea time is not just a rest, but a ritual for self-renewal. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,9 @@ | ||
import GamePage from "@/components/pages/Game"; | ||
import fs from "fs"; | ||
import path from "path"; | ||
|
||
export default function Typing() { | ||
return <GamePage />; | ||
const textsDirectory = path.join(process.cwd(), "public/texts"); | ||
const filenames = fs.readdirSync(textsDirectory).filter((filename) => filename.endsWith(".txt")); | ||
return <GamePage filenames={filenames} />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from "react"; | ||
|
||
interface ProgressBarProps { | ||
maxWidth: number; | ||
height: number; | ||
maxValue: number; | ||
value: number; | ||
} | ||
|
||
const ProgressBar: React.FC<ProgressBarProps> = ({ maxWidth, value, maxValue, height }) => { | ||
const rate = value / maxValue; | ||
const actualWidth = maxWidth * rate + "px"; | ||
const actualHeight = height + "px"; | ||
return ( | ||
<div | ||
style={{ background: "#2196f3", height: actualHeight, width: actualWidth, transition: "width 0.2s ease-in-out" }} | ||
/> | ||
); | ||
}; | ||
|
||
export default ProgressBar; |
Oops, something went wrong.