iT邦幫忙

2021 iThome 鐵人賽

DAY 25
0
Modern Web

連線網頁卡牌遊戲(Elixir, Phoenix, Liveview)系列 第 25

25 把卡片擺一擺

來把卡擺上去吧
我們先來做卡的外型
放在 lib/card_web/component.ex 裡面

def card(assigns) do
  ~H"""
  <div class="border border-gray-200 rounded-lg p-0.5 w-14 h-22 m-1 shadow">
    <div class="border-2 border-blue-500 rounded-md flex justify-center items-center w-full h-full">
      <div class="text-xl font-bold text-blue-500">
        <%= card_name(@name) %>
      </div>
    </div>
  </div>
  """
end

defp card_name(:reverse), do: "Rev"
defp card_name(name), do: name

"reverse" 太長了,我們遇到它的時候用 card_name/1 改成 "Rev"

接著是桌面上的區域,中間是牌桌放出過的牌,
上面是對手出的,下面是玩家出的,可能要先判斷目前在網頁上的玩家是 host 或 guest

還好我們弄 router 的時候就想到把它放在 live_action 裡面了

於是我們修改一下 lib/card_web/live/game_live/game.ex
從socket 的 assigns 裡面拿出 live_action 當作 current_player 來用

  def mount(
        %{"id" => id} = _params,
        _session,
        %{assigns: %{live_action: current_player}} = socket
      ) do
    # [:host, :guest] 減掉其中一個,對手就一定是另一個了
    [opponent] = [:host, :guest] -- [current_player]
    if connected?(socket), do: Card.Game.subscribe(id)

    pid = Card.Dealer.find_or_create_game(id)
    game = Game.status(pid)

    {:ok,
     assign(socket, %{
       pid: pid,
       id: id,
       game: game,
       current_player: current_player,
       opponent: opponent
     })}
  end

好了之後就可以來放雙方的 desk 了

  def render(assigns) do
    ~H"""
    <div class="flex flex-col items-center h-screen">
      <.logo />
      <%= inspect @game %>
      <.desk player={Map.get(@game, @opponent)}/>
      <.desk player={Map.get(@game, @current_player)}/>
    </div>
    """
  end

  def desk(assigns) do
    ~H"""
    <div class="flex w-full justify-center items-center h-32 border">
      <%= for card <- @player.desk do %>
        <.card name={card}/>
      <% end %>
    </div>
    """
  end

在desk component 裡面把所有的卡用 card component 印出來
在放到 render 裡面 依照排序上面是對手,下面是自己出的牌

接著最下面就是手牌,也是把等等給進去玩家手牌印出來就行

  def hand(assigns) do
    ~H"""
    <div class="flex w-full justify-center">
      <%= for card <- @player.hand do %>
        <.card name={card}/>
      <% end %>
    </div>
    """
  end

也把手牌放進去,手牌放自己的就好了,不用放對手的

  def render(assigns) do
    ~H"""
    <div class="flex flex-col items-center h-screen">
      <.logo />
      <%= inspect @game %>
      <.desk player={Map.get(@game, @opponent)}/>
      <.desk player={Map.get(@game, @current_player)}/>
      <.hand player={Map.get(@game, @current_player)}/>
    </div>
    """
  end

來跑跑看

我記得那時候好像是設計只會看到當下回合的卡片,
沒關係 我們明天先把關鍵的出牌做好,再來調整畫面

https://ppt.cc/fggZzx@.gif


上一篇
24 讓畫面跟遊戲聯動
下一篇
26 可以按按鈕出牌才算出牌
系列文
連線網頁卡牌遊戲(Elixir, Phoenix, Liveview)32

尚未有邦友留言

立即登入留言