-
Notifications
You must be signed in to change notification settings - Fork 0
5.リザルト機能を追加する
Suzuki-Takumi0505 edited this page Jun 8, 2022
·
11 revisions
ゲーム終了後に表示させるリザルト画面を作成します。
まず、以下を行なってください。
以下のコードを削除してください。
- live/game_editor_live.ex
def handle_event("toggle_" <> event, params, socket)
when event == "select_mode" do
socket =
update(socket, :editor, fn editor ->
GameEditor.update(editor, event, params)
end)
if connected?(socket) and socket.assigns.editor.mode in [:training, :game] do
:timer.send_interval(1000, "timer")
end
{:noreply, socket}
end
:timer.send_intrval/2 をマウント時に呼び出すようにします。
- live/game_editor_live.ex
def mount(_params, _session, socket) do
socket =
socket
|> assign(:editor, GameEditor.construct())
|> assign(:page_title, "タイピングゲーム")
|> assign(:template, "main.html")
if connected?(socket) do
:timer.send_interval(1000, "timer")
end
{:ok, socket}
end
リザルト画面を作成するために以下を実装してください。
- Typing.Editor.GameEditor構造体のfailure_count(ゲーム内でミスした回数)をfailure_countsに変更してください。
- Typing.Editor.GameEditor構造体に以下の表のキーを追加してください。
- Typing.Editor.GameEditor構造体のgame_statsuに3(ゲームクリア)のフラグを追加します。
- Typing.Editor.GameEditor構造体のmodeに:result(リザルト)のフラグを追加します。
- リザルト画面では、ゲーム全体の時間(練習モードの場合)、クリアした回数、ゲーム全体のミスした回数、入力した内容(お題、結果、入力にかかった時間、ミスした回数)を表示させてください。
キー | 値の型 | |
---|---|---|
failure_count | integer | お題でミスした回数 |
input_time | integer | お題を入力するのにかかった時間 |
results | リスト | お題、実行結果、ミスした回数、入力にかかった時間をマップにしてリストで保存する |
Typing.Editor.GameEditor構造体にキーを追加します。
- editor/game_editor.ex
defstruct input_char: "",
display_char: "",
char_count: 0,
now_char_count: 0,
failure_counts: 0,
game_status: 0,
char_list: [],
clear_count: 0,
result: nil,
mode: :select,
timer: 0,
input_time: 0,
failure_count: 0,
results: []
main.html.heex テンプレートの case に :result を追加します。
- templates/game_editor/main.html.heex
<%=
case @editor.mode do
:select -> render "select.html", editor: @editor
mode when mode in [:training, :game] -> render "game.html", editor: @editor
:result -> render "result.html", editor: @editor
end
%>
game.html.heex にゲームが終了したらリザルト画面に移行するボタンを追加します。
ゲーム全体のミスした回数も変更します。
- templats/game_editor/game.html.heex
<h2>
<%= if @editor.game_status == 1 do %>
<span style="color: blue;"><%= @editor.input_char %></span><%= trem_display_char(@editor) %>
<% else %>
<%= @editor.display_char %>
<% end %>
</h2>
<p>クリアした回数:<%= @editor.clear_count %> 回</p>
<p>ミスした回数:<%= @editor.failure_counts %> 回</p>
<h2>実行結果</h2>
<h2><%= if @editor.result, do: inspect(@editor.result), else: "" %></h2>
<%= if @editor.game_status == 2 do %>
<h1>Enterを押してください</h1>
<% end %>
<h2><%= get_timer_title(@editor) %></h2>
<h2><%= @editor.timer %></h2>
<%= if @editor.game_status == 3 do %>
<button phx-click="toggle_select_mode" phx-value-mode="result">
結果を表示
</button>
<% end %>
<div
phx-window-blur="page-inacive"
phx-window-focus="page-active"
phx-window-keyup="toggle_input_key">
</div>
editorのselect_modeを変更します。
mode を select にした時に全ての値を最初の状態にします。
- editor/game_editor.ex
def update(%__MODULE__{} = editor, "select_mode", %{"mode" => "game"}) do
%{editor | mode: :game, timer: 60, game_status: 1}
end
# trainigを割り当てる
def update(%__MODULE__{} = editor, "select_mode", %{"mode" => mode})
when mode in ["training", "result"] do
timer =
if mode == "result", do: editor.timer, else: 0
%{editor | mode: String.to_atom(mode), timer: 0, game_status: 1}
end
# game, training どちらでもない場合は select を割り当てる
def update(%__MODULE__{} = editor, "select_mode", _params) do
char_list =
[
"Enum.map([1, 2, 3], fn a -> a * 2 end)",
"Enum.shuffle([1, 2, 3])",
"Enum.map([1, 2, 3])"
]
%{
editor
| mode: :select,
failure_counts: 0,
failure_count: 0,
game_status: 0,
clear_count: 0,
timer: 0,
results: [],
char_list: char_list,
display_char: hd(char_list),
char_count: String.length(hd(char_list)),
input_char: "",
now_char_count: 0,
input_time: 0
}
end
リザルト画面を追加します。
- templates/game_editor/result.html.heex
<h2>結果</h2>
<%= if @editor.timer > 0 do %>
<h3>経過時間</h3>
<h3><%= @editor.timer %></h3>
<% end %>
<h3>クリアした回数</h3>
<h3><%= @editor.clear_count %> 回</h3>
<h3>ミスした回数</h3>
<h3><%= @editor.failure_counts %> 回</h3>
<h3>入力した内容</h3>
<%= for result <- @editor.results do %>
<h3>お題:<%= result.display_char %></h3>
<h3>結果:<%= inspect(result.result) %></h3>
<h3>入力にかかった時間:<%= result.time %> 秒</h3>
<h3>ミスした回数:<%= result.failure_count %> 回</h3>
<hr>
<% end %>
<button phx-click="toggle_select_mode" phx-value-mode="">
選択画面に戻る
</button>
ゲームモード時にタイマーが0になった場合に、game_statusを3にするように記述を追加します。
- editor/game_editor.ex
def update(%__MODULE__{} = editor, "timer")
when editor.mode == :game and editor.game_status == 1 and editor.timer <= 0 do
%{
editor
| display_char: "終了",
game_status: 3,
result: nil,
failure_count: 0
}
end
練習モードとゲームモードでinput_timeを+1づつしていくので追加してきます。
- editor/game_editor.ex
def update(%__MODULE__{} = editor, "timer")
when editor.mode == :game and editor.game_status == 1 do
%{editor | timer: editor.timer - 1, input_time: editor.input_time + 1}
end
def update(%__MODULE__{} = editor, "timer")
when editor.mode == :training and editor.game_status == 1 do
%{editor | timer: editor.timer + 1, input_time: editor.input_time + 1}
end
練習モード時のゲーム終了の際にgame_statsuを3にします。
- editor/game_editor.ex
defp next_char(editor, key) do
char_list = List.delete(editor.char_list, editor.display_char)
char_list =
if length(char_list) == 0 and editor.mode == :game do
list =
[
"Enum.map([1, 2, 3])",
"Enum.map([1, 2, 3], fn a -> a * 2 end)",
"Enum.shuffile([1, 2, 3])"
]
Enum.shuffle(list)
else
char_list
end
timer =
if editor.mode == :game, do: editor.timer + 2, else: editor.timer
case length(char_list) do
0 ->
%{
editor
| char_list: char_list,
display_char: "クリア",
input_char: editor.input_char <> key,
game_status: 3,
result: nil
}
_num ->
display_char = hd(char_list)
%{
editor
| char_list: char_list,
display_char: display_char,
input_char: "",
char_count: String.length(display_char),
now_char_count: 0,
game_status: 1,
result: nil,
timer: timer,
input_time: 0
}
end
end
お題を入力し終わった際にお題の関数を実行します。 その時にresultsにもお題、実行結果、入力にかかった時間、ミスした回数を追加していきます。
- editor/game_editor.ex
defp display_result(editor, key) do
result =
case Execution.execution(editor.display_char) do
{r, _} -> r
error -> error
end
results =
%{
display_char: editor.display_char,
time: editor.input_time,
result: result,
failure_count: editor.failure_count
}
%{
editor
| result: result,
game_status: 2,
input_char: editor.input_char <> key,
clear_count: editor.clear_count + 1,
results: List.insert_at(editor.results, -1, results)
}
end