From c5fcf5324f3b482019506f8bf04cfdbbcaeb72f1 Mon Sep 17 00:00:00 2001 From: EasterPeanut Date: Tue, 23 Apr 2019 13:36:45 +0200 Subject: [PATCH 1/3] Add animated GIFs for a claw move for bears The classes clawing up, right, down, left can be set to display the corresponding claw move for a bear, whenever a bear is clawing. --- .../assets/css/game/game.css | 33 ++++++++++++++++-- .../assets/static/images/bear/down-claw.gif | Bin 0 -> 2246 bytes .../assets/static/images/bear/left-claw.gif | Bin 0 -> 2138 bytes .../assets/static/images/bear/right-claw.gif | Bin 0 -> 2148 bytes .../assets/static/images/bear/up-claw.gif | Bin 0 -> 1904 bytes .../bear_necessities_web/views/playfield.ex | 14 ++++---- 6 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 apps/bear_necessities_web/assets/static/images/bear/down-claw.gif create mode 100644 apps/bear_necessities_web/assets/static/images/bear/left-claw.gif create mode 100644 apps/bear_necessities_web/assets/static/images/bear/right-claw.gif create mode 100644 apps/bear_necessities_web/assets/static/images/bear/up-claw.gif diff --git a/apps/bear_necessities_web/assets/css/game/game.css b/apps/bear_necessities_web/assets/css/game/game.css index 4778a56..6815a22 100644 --- a/apps/bear_necessities_web/assets/css/game/game.css +++ b/apps/bear_necessities_web/assets/css/game/game.css @@ -34,22 +34,27 @@ height: 100%; flex: 1; } + .tile.grass-1 { background-color: #44d873; background-image: url("/images/terain/grass-1.gif"); } + .tile.grass-2 { background-color: #44d873; background-image: url("/images/terain/grass-2.gif"); } + .tile.grass-3 { background-color: #44d873; background-image: url("/images/terain/grass-3.gif"); } + .tile.grass-4 { background-color: #44d873; background-image: url("/images/terain/grass-4.gif"); } + .tile.nothing { background-color: gray; background-image: url("/images/terain/nothing.gif"); @@ -75,8 +80,8 @@ Items that are displayed inside tiles (bears, trees, etc) } /* Bear (player and opponents) */ -.bear.self { -} +.bear.self {} + .bear.opponent { filter: grayscale(60%); } @@ -84,31 +89,55 @@ Items that are displayed inside tiles (bears, trees, etc) .bear.dead { background-image: url("/images/bear/dead.gif"); } + .bear.up { background-image: url("/images/bear/up.gif"); } + .bear.left { background-image: url("/images/bear/left.gif"); } + .bear.right { background-image: url("/images/bear/right.gif"); } + .bear.down { background-image: url("/images/bear/down.gif"); } + .bear.up.idle { background-image: url("/images/bear/up-idle.gif"); } + .bear.left.idle { background-image: url("/images/bear/left-idle.gif"); } + .bear.right.idle { background-image: url("/images/bear/right-idle.gif"); } + .bear.down.idle { background-image: url("/images/bear/down-idle.gif"); } +.bear.clawing.up { + background-image: url("/images/bear/up-claw.gif"); +} + +.bear.clawing.left { + background-image: url("/images/bear/left-claw.gif"); +} + +.bear.clawing.right { + background-image: url("/images/bear/right-claw.gif"); +} + +.bear.clawing.down { + background-image: url("/images/bear/down-claw.gif"); +} + .tree { background-image: url("/images/trees/tree-1.gif"); } diff --git a/apps/bear_necessities_web/assets/static/images/bear/down-claw.gif b/apps/bear_necessities_web/assets/static/images/bear/down-claw.gif new file mode 100644 index 0000000000000000000000000000000000000000..13e413d511865908fc783d9f17b30c95c26e240b GIT binary patch literal 2246 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 literal 0 HcmV?d00001 diff --git a/apps/bear_necessities_web/assets/static/images/bear/up-claw.gif b/apps/bear_necessities_web/assets/static/images/bear/up-claw.gif new file mode 100644 index 0000000000000000000000000000000000000000..f92b8ff1b26e7ccaa78b7744bc7b7c7ab667a26b GIT binary patch literal 1904 zcmZ?wbh9u|RA5kGC}&_${Lk&@8WQa67~pE8XTZ$J02KPk!pQ}sb$}SCNP(dV#9&~E z3=2xLH0%$vc9s$S|Np=Flsx7o9J}uPGdShhEYO%`>c(+bjn^e}TJwtuu7%rNRu#Ei z-1$}ZJj3mYhI4&bRYa3D=6x(N`ZU4&N>SJ*$MrjU51M5Bt&5wSc&TUWx#t<4n|Pac zo88`SB6rv7!c*HV2i?CqOS2c{**mhb8#fnP#OZc6F?441W=xtc)H$nrN;>@8b)CT!Tbci;X42M-;V=0tdim4S&tj6njAhq^d+ zNh>v;TzQP+V31YE|9cyBV*?x16!Vsr3bn4@wBhQ?PgZwj*SBqv)-ahZQMb4Msk&uV z(uo(IOj0v)wykb|xOvvTTeBNmwpN`r6VRL%^X<$$LrW=LeLe;=zHV)g4;A71@o@|l zJPir{39Jnw>^(hw?d5G!>@&n>Os;R6H)pE!oId4_`Ae5h5hlsmQ#f`>;dHhaTf&ww zjrHA*cN9Z67$*x@yIcsE@% zOIIvg)(`Xm&)W6Mt9g(-zy=I=QM}>a&9O@W=mAb(xL>jag}Wv=+=CF|t_2ErA?K&; zzrK_$ywCgHS*_aZYUf6oBROW5dsmrM?hR=A&`=tg9L~+*uup4YTK~fXVeJnijy`;# z_k9gdNp+Ndf?7^vPP|;aT2oa=O>caE33roNb@j~ZiJepDO_yHKue@mKGLdN_NbV+_ zUV5mWUOqAw6#QTG^ytF_#}W%!g^H^|Nv5Q!B_5b!nyWf%`VuA-^E69Umom?u)HHwE z4CO@=lou~sEibWzR`XO>$JNI%v~+f}*S5v>_Dt#(>z%?pv8#D<*Q}aJ zla*)BTr|I%W|?#GAD#L4&L`Mt&evxu7Bsq<6E@+HgUpP5@lSb5dLxssA7nfby0G7W z{j3t(vclJFJ-^*&x<1qqvc4?zCyj3nnTH zFI>881p`TGq@QD#49?66E>jX1tc%O-Lr*xonAoy_-#|q$YKougVzJnJGrA_6Jl5Oj z;<7x`Chpw6Z8yx0U2S2{SuVP6Wx?Xm(+?Fow>K743)N%;-Q85fRl}armeRvLvA1sm z!{q7HtE;Nnt7h_abn=;q?e%wIl+7hayy}X2`UebJ?f_Uzc-J*G9h50 zUdpD(WUq!s3xmqN-hwY~^&VZ*d^oJst!;PaBvGked5PST_0>D{--X7>rLopB)RnWx zYZ}CLa`kt0$4{KfE>>GRqn)R2!kme7q!;!p3oTqGJdZSYcS4dkG47s?lvIMjNk!lQ zB&q0kem#~HE*RcwXSa9PmyO+vw_LW>e{kSI^nST?*6NlP_5@9X_?nuw>W+?HuAXXk ccCl$SGg>Ft_Dz{2yr556Xz|iTD>xaf0iR;_v;Y7A literal 0 HcmV?d00001 diff --git a/apps/bear_necessities_web/lib/bear_necessities_web/views/playfield.ex b/apps/bear_necessities_web/lib/bear_necessities_web/views/playfield.ex index 53f2fdd..bcf398d 100644 --- a/apps/bear_necessities_web/lib/bear_necessities_web/views/playfield.ex +++ b/apps/bear_necessities_web/lib/bear_necessities_web/views/playfield.ex @@ -10,17 +10,18 @@ defmodule BearNecessitiesWeb.Playfield do def item_class(item, player_id) do case item do - %Bear{id: id, direction: direction, moving: moving, dead: nil} when id == player_id -> + %Bear{id: id, direction: direction, moving: moving, clawing: clawing, dead: nil} = bear + when id == player_id -> ["bear", "self", direction] - |> bear_idle_class(moving) + |> bear_idle_class(moving, clawing) |> Enum.join(" ") %Bear{id: id, direction: direction, dead: _} when id == player_id -> "bear dead" - %Bear{direction: direction, moving: moving, dead: nil} -> + %Bear{direction: direction, moving: moving, clawing: clawing, dead: nil} -> ["bear", "opponent", direction] - |> bear_idle_class(moving) + |> bear_idle_class(moving, clawing) |> Enum.join(" ") %Bear{direction: direction, dead: _dead} -> @@ -37,6 +38,7 @@ defmodule BearNecessitiesWeb.Playfield do end end - defp bear_idle_class(classes, false), do: ["idle" | classes] - defp bear_idle_class(classes, _), do: classes + defp bear_idle_class(classes, false, false), do: ["idle" | classes] + defp bear_idle_class(classes, _, true), do: ["clawing" | classes] + defp bear_idle_class(classes, _, _), do: classes end From 59776fdcdad08d396296524e28f28f84b0046ab2 Mon Sep 17 00:00:00 2001 From: EasterPeanut Date: Tue, 23 Apr 2019 14:06:42 +0200 Subject: [PATCH 2/3] Update clawing of bears when a player claws Whenever a player claws, a timer of 1000ms is set and every 50ms it will decrease with 50ms until it becomes 0. During this time the bear's 'claw' will be true and it will be nil when it reaches 0. This is needed to temporarily set a 'clawing' class on bears in the game. --- .../lib/bear_necessities_web/live/game.ex | 10 ++-- apps/game/lib/bear.ex | 3 +- apps/game/lib/{game.ex => game_server.ex} | 10 ++-- apps/game/lib/player.ex | 50 +++++++++++++++---- 4 files changed, 56 insertions(+), 17 deletions(-) rename apps/game/lib/{game.ex => game_server.ex} (97%) diff --git a/apps/bear_necessities_web/lib/bear_necessities_web/live/game.ex b/apps/bear_necessities_web/lib/bear_necessities_web/live/game.ex index 6d8d35a..fe1d204 100644 --- a/apps/bear_necessities_web/lib/bear_necessities_web/live/game.ex +++ b/apps/bear_necessities_web/lib/bear_necessities_web/live/game.ex @@ -88,12 +88,16 @@ defmodule BearNecessitiesWeb.Game do def handle_event("key_up", key, %{id: id} = socket) when key in @arrow_keys do - Bear.stop(id) + Bear.stop(id) {:noreply, socket} end def handle_event("key_up", " ", %{id: id} = socket) do - Player.claw(id) + socket = + socket + |> assign(:bear, Player.claw(id)) + |> assign(:viewport, ViewPort.get_viewport(id)) + {:noreply, socket} end @@ -162,7 +166,7 @@ defmodule BearNecessitiesWeb.Game do def set_updates(false), do: nil def set_updates(true) do - {:ok, {:interval, ref}} = :timer.send_interval(50, self(), :update) + {:ok, ref} = :timer.send_interval(50, self(), :update) ref end diff --git a/apps/game/lib/bear.ex b/apps/game/lib/bear.ex index 4ff7468..a9ef1c4 100644 --- a/apps/game/lib/bear.ex +++ b/apps/game/lib/bear.ex @@ -7,7 +7,8 @@ defmodule Bear do display_name: nil, started: false, direction: :down, - moving: false + moving: false, + clawing: false def create_bear(%{height: height, width: width}, id, display_name, started) do pos_x = Enum.random(0..height) diff --git a/apps/game/lib/game.ex b/apps/game/lib/game_server.ex similarity index 97% rename from apps/game/lib/game.ex rename to apps/game/lib/game_server.ex index 1a43bee..f2870df 100644 --- a/apps/game/lib/game.ex +++ b/apps/game/lib/game_server.ex @@ -112,7 +112,7 @@ defmodule Game do @impl true def handle_call({:stop, id}, _pid, %{bears: bears} = state) do bear = get_bear_from_list(id, bears) - bear = %{bear | moving: false} + bear = %{bear | moving: false, clawing: false} state = update_state_with(state, bear) {:reply, bear, state} @@ -124,6 +124,8 @@ defmodule Game do _pid, state ) do + bear = %{bear | clawing: true} + {bear, state} = case target(direction, x, y, state) do %Tree{honey: tree_honey} = tree when tree_honey > 0 -> @@ -153,13 +155,13 @@ defmodule Game do {new_bear, new_state} %Tree{honey: 0} -> - {bear, state} + {bear, update_state_with(state, bear)} %Bear{honey: 0} -> - {bear, state} + {bear, update_state_with(state, bear)} _ -> - {bear, state} + {bear, update_state_with(state, bear)} end {:reply, bear, state} diff --git a/apps/game/lib/player.ex b/apps/game/lib/player.ex index 36b7f72..09f18f6 100644 --- a/apps/game/lib/player.ex +++ b/apps/game/lib/player.ex @@ -2,19 +2,22 @@ defmodule Player do use GenServer require Logger - defstruct [:display_name, :score, :bear] + @claw_time_ms 1000 + + @enforce_keys [:id] + defstruct [:id, :claw, :timer_pid] def start_link(default) when is_list(default) do GenServer.start_link(__MODULE__, default, name: __MODULE__) end @impl true - def init([]) do - {:ok, []} + def init(id: id) do + {:ok, %Player{id: id}} end @impl true - def handle_call({:action, user_input, id}, _pid, _) do + def handle_call({:action, user_input, id}, _pid, state) do bear = case user_input do :up_arrow -> @@ -30,14 +33,43 @@ defmodule Player do Bear.move(id, :right) end - {:reply, bear, []} + {:reply, bear, state} end - @imp true - def handle_call({:claw, id}, _pid, _) do + @impl true + def handle_call({:claw, id}, _pid, state) do bear = Bear.claw(id) + {:ok, timer_pid} = :timer.send_interval(50, self(), :update_claw) + state = %{state | claw: @claw_time_ms, timer_pid: timer_pid} + + {:reply, bear, state} + end + + @impl true + def handle_info(:update_claw, %{claw: nil} = state) do + {:noreply, state} + end + + @impl true + def handle_info(:update_claw, %{claw: claw_time} = state) when claw_time > 0 do + state = %{state | claw: claw_time - 50} + + {:noreply, state} + end + + @impl true + def handle_info(:update_claw, %{id: id, claw: claw_time, timer_pid: timer_pid} = state) + when claw_time < 1 do + :timer.cancel(timer_pid) + state = %{state | claw: nil, timer_pid: nil} + Bear.stop(id) + + {:noreply, state} + end - {:reply, bear, []} + @impl true + def handle_info(:update_claw, state) do + {:noreply, state} end def move(player_id, way) do @@ -49,7 +81,7 @@ defmodule Player do end def start(display_name, id) do - Player.start_link([]) + Player.start_link(id: id) Game.create_bear(display_name: display_name, id: id, started: true) end end From 8290229b34692bc56d06292cb6240a12563573fe Mon Sep 17 00:00:00 2001 From: EasterPeanut Date: Tue, 23 Apr 2019 14:33:17 +0200 Subject: [PATCH 3/3] Add divs to load GIFs in the lobby Adding GIFs for clawing up, right, down, left, to be preloaded in the lobby. --- .../templates/playfield/template.html.leex | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/bear_necessities_web/lib/bear_necessities_web/templates/playfield/template.html.leex b/apps/bear_necessities_web/lib/bear_necessities_web/templates/playfield/template.html.leex index a546c39..b061842 100644 --- a/apps/bear_necessities_web/lib/bear_necessities_web/templates/playfield/template.html.leex +++ b/apps/bear_necessities_web/lib/bear_necessities_web/templates/playfield/template.html.leex @@ -67,6 +67,10 @@
+
+
+
+
<% end %>