是時候把 inspect game 拿掉,換成好看的介面了,啊更正!相對好看的介面哈哈
主要有兩小區
東西都已經在 game 裡面了,所以我們直接用 live component
把他們用 tailwind 勾出來就行了
先把 原本暫時寫的 inspect game 改成呼叫 status component
def render(assigns) do
~H"""
<div class="flex flex-col items-center h-screen">
<.logo />
<.status game={@game} opponent={@opponent} current_player={@current_player}/>
<.desk player={Map.get(@game, @opponent)}/>
<.desk player={Map.get(@game, @current_player)}/>
<.hand player={Map.get(@game, @current_player)}/>
</div>
"""
end
接著定義 status component
def status(assigns) do
~H"""
<div class="flex flex-col items-center">
<.wins game={@game} opponent={@opponent} current_player={@current_player}/>
<.game_round round={@game.round}/>
</div>
"""
end
這個裡面包的分別是
wins
def wins(assigns) do
~H"""
<div class="flex h-6 items-center justify-between text-gray-600 m-4">
<div class="bg-blue-300 w-4 h-3 rounded-xl transform skew-x-12 -rotate-12 translate-x-8"></div>
<h2 class="transform mr-8 text-xl font-serif"> Wins:</h2>
<.player_wins player={"You"} wins={Map.get(@game, @current_player).wins}/>
<div class="ml-8"></div>
<.player_wins player={"Opponent"} wins={Map.get(@game, @opponent).wins}/>
</div>
"""
end
# wins 裡面有重複的地方再拉出來一次
def player_wins(assigns) do
~H"""
<h3 class="block"><%= @player %>:</h3>
<%= for x <- 0..(@wins), x > 0 do %>
<div class={"ml-4 bg-green-300 w-4 h-4 rounded-3xl transform -skew-x-3 rotate-12"}></div>
<% end %>
<%= for x <- 0..(2 - @wins), x > 0 do %>
<div class={"ml-4 bg-gray-300 w-4 h-4 rounded-3xl transform -skew-x-3 rotate-12"}></div>
<% end %>
"""
end
回合的部分
def game_round(assigns) do
~H"""
<div class="mt-2 text-gray-600 flex m-4">
<div class="bg-blue-300 w-9 h-2 rounded-xl transform -skew-x-12 rotate-6 translate-x-10 translate-y-4"></div>
<h2 class="transform mr-8 text-xl font-serif block">Round:</h2>
<div class="ml-2 text-lg"><%= @round %></div>
</div>
"""
end
這邊用game_round
是因為round
會撞到是內建的Kernel.round/1
方法
看起來可能沒有時間做成只顯示當下回合的卡
不過還是可以加上分隔線讓他看起來舒服一些
def desk(assigns) do
~H"""
<div class="flex w-full justify-center items-center h-32">
<%= for {card, i} <- Enum.with_index(@player.desk, 1) do %>
<%= if Enum.member?([4,7], i) do %>
<div class="w-1 h-20 bg-gray-200 mx-2 rounded"></div>
<% end %>
<.card name={card}/>
<% end %>
</div>
"""
end
使用了 Enum.with_index
後,我就可以得知目前正準備要顯示的卡是第幾張
在顯示第 4, 7 張卡的時候,在前面加一個小分隔
儘管規則已經盡量簡單了
還是需要有很多說明,因為篇幅的關西
我們就在第一個回合 畫面上只有手牌的時候
提醒一下玩家出牌好了
做一個notice元件
def notice(%{game: %{round: 1, turn: 1}} = assigns) do
~H"""
<div class="mt-4 h-4 text-gray-600">? Pick a card</div>
"""
end
def notice(assigns) do
~H"""
<div class="mt-4 h-4"></div>
"""
end
放在 hand 上面
def render(assigns) do
~H"""
<div class="flex flex-col items-center h-screen">
<.logo />
<.status game={@game} opponent={@opponent} current_player={@current_player}/>
<div class="border-t border-b m-4">
<.desk player={Map.get(@game, @opponent)}/>
<.desk player={Map.get(@game, @current_player)}/>
</div>
<.notice game={@game}/>
<.hand player={Map.get(@game, @current_player)}/>
</div>
"""
end
完成之後就變成這樣,算是相對好看的狀態了
超嚴重bug
在 card/game.ex 的 host_win_this_round?
方法
if reverse?(host_desk ++ guest_desk) do
host_win
else
!host_win
end
那個 ! 加錯地方了拉,難怪有的時候遊戲結果很奇怪
這樣才對
if reverse?(host_desk ++ guest_desk) do
!host_win
else
host_win
end