获胜画面我们做一个 modal 好了
如果 游戏状态不是进行中 与 开启modal 的话
就显示 game_over_modal
component
进行中的时候状态是 :start
host 赢是 :host_win
guest 赢是 :guest_win
我们可以用 @current_player
与 "_win"
组合起来看看是不是等於状态来判断目前玩家是否获胜
@game.status == :"#{@current_player}_win"
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)}/>
<%= if (@game.status != :start) && @modal_on do %>
<.game_over_modal win={@game.status == :"#{@current_player}_win"}/>
<% end %>
</div>
"""
end
再来用 tailwind 做一个盖版 modal
除了显示输赢之外
还要有一个可以关掉 modal 的按钮
可以用 phx-click 来实作
def game_over_modal(assigns) do
~H"""
<div phx-capture-click="close_model" class="fixed w-full h-screen flex bg-black bg-opacity-20 justify-center items-center">
<div class="flex flex-col p-4 bg-gray-50 shadow-lg text-center border w-60 h-70 rounded-xl">
<div class="flex">
# 关闭 modal 按钮
<button phx-click="close_model" class="-mt-6">
<div class="bg-red-300 w-4 h-4 rounded-xl transform skew-x-12 -rotate-6 translate-y-6"></div>
<h2 class="block transform text-xl">x</h2>
</button>
</div>
# 依照输赢显示讯息
<%= if @win do %>
<div class="bg-yellow-300 w-12 h-8 rounded-xl transform skew-x-12 -rotate-12 translate-x-12 translate-y-12"></div>
<h2 class="transform text-3xl font-serif mb-4">You Win</h2>
<% else %>
<div class="bg-gray-300 w-8 h-8 rounded-xl transform skew-x-12 -rotate-12 translate-x-12 translate-y-12"></div>
<h2 class="transform text-3xl font-serif mb-4">You Lose</h2>
<% end %>
<div class="flex flex-col mt-8 justify-center">
<%= link to: "/" do %>
<div class="bg-green-300 w-24 h-6 rounded-xl transform -skew-x-12 rotate-6 translate-y-8 translate-x-16"></div>
<h2 class="block transform text-xl font-serif">Back to Start Menu</h2>
<% end %>
</div>
</div>
</div>
"""
end
加上 handle_event :close_modal
def handle_event("close_model", _params, socket) do
{:noreply, assign(socket, :modal_on, false)}
end
别忘了要在 mount 最後加上我们用的 :modal_on
def mount(
# 略
id: id,
game: maybe_fold_last(game, current_player, opponent),
current_player: current_player,
opponent: opponent,
modal_on: true
})}
end
赶快试试看
虽然我们的规模就算不关也不会塞爆
但没用的时候还是关掉一下好了
在这次我觉得用 超过时间就关闭 的做法就行了
回到 lib/card/game.ex
这次的做法是,
启动游戏的时候顺便设定 1 小时後会发 GenServer.cast :times_up
handle_cast :times_up
里面再去呼叫 GenServer.stop
启动时定时
def init(game) do
Process.send_after(self(), :stop_timer, 60 * 60 * 1000)
{:ok, start_turn_timer(game)}
end
自我毁灭按钮
def handle_info(:stop_timer, _game) do
GenServer.stop(self())
end
GenServer stop 的时候会呼叫 terminate callback
我们可以在这边把要关掉的 id 从 games 表格里面拿掉
def terminate(_reason, game) do
:ets.delete(:games, game.id)
:ok
end
这样子就行了,游戏开始後一小时,那个游戏就会坏掉。
>>: 29.5 如果我要装 javascript 套件勒?
#odoo #开源系统 #数位赋能 #E化自主 前言 在我们对於odoo社区版重要应用模组功能有简单...
利用Day 13的collection public function getData(){ ret...
假设我们取得受害主机的 shell (cmd.exe 或 powershell)可以根据自己的需求取...
Abstract 无论何种时候,每种系统的开发元件势必都有先後启动顺序,如何有效管控每项元件的启动流...
台湾地图拼图 教学原文参考:台湾地图拼图 这篇文章延伸「形状配对拼图」的范例,在 Scratch 3...