Work on #38 - Cards show when players play. Still not quite happy with the effect.
This commit is contained in:
@@ -27,3 +27,4 @@ type Action
|
||||
| RemoveErrorPanel Int
|
||||
| NextRound
|
||||
| SetInitialState InitialState
|
||||
| AnimatePlayedCards (List Int)
|
||||
|
||||
@@ -33,7 +33,7 @@ update action global data = case action of
|
||||
(model global data, (API.newGame data.lobby.id data.secret) |> Task.map (StartGame << Result) |> API.toEffect)
|
||||
|
||||
StartGame (Result lobbyAndHand) ->
|
||||
(Playing.model global (PlayingData lobbyAndHand.lobby lobbyAndHand.hand data.secret [] Nothing), Effects.none)
|
||||
(Playing.model global (PlayingData lobbyAndHand.lobby lobbyAndHand.hand data.secret [] Nothing []), Effects.none)
|
||||
|
||||
Notification lobby ->
|
||||
case lobby.round of
|
||||
@@ -45,7 +45,7 @@ update action global data = case action of
|
||||
|
||||
JoinLobby lobbyId secret (Result lobbyAndHand) ->
|
||||
case lobbyAndHand.lobby.round of
|
||||
Just _ -> (Playing.model global (PlayingData lobbyAndHand.lobby lobbyAndHand.hand secret [] Nothing), Effects.none)
|
||||
Just _ -> (Playing.model global (PlayingData lobbyAndHand.lobby lobbyAndHand.hand secret [] Nothing []), Effects.none)
|
||||
Nothing -> (model global { data | lobby = lobbyAndHand.lobby }, Effects.none)
|
||||
|
||||
other ->
|
||||
|
||||
@@ -5,6 +5,7 @@ import Effects
|
||||
import Html exposing (Html)
|
||||
import StartApp
|
||||
import Json.Decode exposing (decodeString)
|
||||
import Random
|
||||
|
||||
import MassiveDecks.Models.State exposing (Model, State(..), LobbyIdAndSecret, Error, Global, InitialState)
|
||||
import MassiveDecks.Actions.Action exposing (Action(..), APICall(..))
|
||||
@@ -72,7 +73,7 @@ main = game.html
|
||||
|
||||
start : InitialState -> (Model, Effects.Effects Action)
|
||||
start initialState =
|
||||
(Start.model (Global [] initialState) (Start.initialData (Maybe.withDefault "" initialState.gameCode)),
|
||||
(Start.model (Global [] initialState (Random.initialSeed initialState.seed)) (Start.initialData (Maybe.withDefault "" initialState.gameCode)),
|
||||
case initialState.existingGame of
|
||||
Just existingGame ->
|
||||
if (Just existingGame.lobbyId == initialState.gameCode) then
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
module MassiveDecks.Models.State where
|
||||
|
||||
import Random
|
||||
import Html exposing (Attribute)
|
||||
|
||||
import MassiveDecks.Models.Card exposing (Hand)
|
||||
import MassiveDecks.Models.Game exposing (Config, Lobby, Round)
|
||||
import MassiveDecks.Models.Player exposing (Player, Secret)
|
||||
@@ -15,6 +18,7 @@ type alias Model =
|
||||
type alias Global =
|
||||
{ errors : List Error
|
||||
, initialState : InitialState
|
||||
, seed : Random.Seed
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +47,7 @@ type alias PlayingData =
|
||||
, secret : Secret
|
||||
, picked : List Int
|
||||
, lastFinishedRound : Maybe Round
|
||||
, shownPlayed : List Attribute
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +61,7 @@ type alias InitialState =
|
||||
{ url : String
|
||||
, gameCode : Maybe String
|
||||
, existingGame : Maybe LobbyIdAndSecret
|
||||
, seed : Int
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
module MassiveDecks.Playing where
|
||||
|
||||
import Time
|
||||
import Task
|
||||
import Effects
|
||||
import Html exposing (Html)
|
||||
import Html exposing (Html, Attribute)
|
||||
import Html.Attributes exposing (style)
|
||||
import Random exposing (Generator, Seed, list, bool, int)
|
||||
|
||||
import MassiveDecks.Models.Player exposing (Secret)
|
||||
import MassiveDecks.Models.Card as Card
|
||||
@@ -11,6 +14,7 @@ import MassiveDecks.Models.State exposing (State(..), Model, ConfigData, Playing
|
||||
import MassiveDecks.Actions.Action exposing (Action(..), APICall(..))
|
||||
import MassiveDecks.UI.Playing as UI
|
||||
import MassiveDecks.API as API
|
||||
import MassiveDecks.Util as Util
|
||||
|
||||
|
||||
update : Action -> Global -> PlayingData -> (Model, Effects.Effects Action)
|
||||
@@ -36,21 +40,29 @@ update action global data = case action of
|
||||
|
||||
Play (Result lobbyAndHand) ->
|
||||
let
|
||||
data = (updateLobby data lobbyAndHand.lobby)
|
||||
(data, effect, seed) = (updateLobby data lobbyAndHand.lobby global.seed)
|
||||
in
|
||||
(model global
|
||||
(model { global | seed = seed }
|
||||
{ data | hand = lobbyAndHand.hand
|
||||
, picked = []
|
||||
}, Effects.none)
|
||||
}, effect)
|
||||
|
||||
Notification lobby ->
|
||||
case lobby.round of
|
||||
Just _ -> (model global (updateLobby data lobby), Effects.none)
|
||||
Just _ ->
|
||||
let
|
||||
(data, effect, seed) = (updateLobby data lobby global.seed)
|
||||
in
|
||||
(model { global | seed = seed } data, effect)
|
||||
Nothing -> (configModel global (ConfigData lobby data.secret ""), Effects.none)
|
||||
|
||||
JoinLobby lobbyId secret (Result lobbyAndHand) ->
|
||||
case lobbyAndHand.lobby.round of
|
||||
Just _ -> (model global (updateLobby data lobbyAndHand.lobby), Effects.none)
|
||||
Just _ ->
|
||||
let
|
||||
(data, effect, seed) = (updateLobby data lobbyAndHand.lobby global.seed)
|
||||
in
|
||||
(model { global | seed = seed } data, effect)
|
||||
Nothing -> (configModel global (ConfigData lobbyAndHand.lobby data.secret ""), Effects.none)
|
||||
|
||||
Choose winner Request ->
|
||||
@@ -58,16 +70,22 @@ update action global data = case action of
|
||||
|
||||
Choose winner (Result lobbyAndHand) ->
|
||||
let
|
||||
data = (updateLobby data lobbyAndHand.lobby)
|
||||
(data, effect, seed) = (updateLobby data lobbyAndHand.lobby global.seed)
|
||||
in
|
||||
(model global
|
||||
(model { global | seed = seed }
|
||||
{ data | hand = lobbyAndHand.hand
|
||||
, picked = []
|
||||
}, Effects.none)
|
||||
}, effect)
|
||||
|
||||
NextRound ->
|
||||
(model global { data | lastFinishedRound = Nothing }, Effects.none)
|
||||
|
||||
AnimatePlayedCards toAnimate ->
|
||||
let
|
||||
(shownPlayed, seed) = updatePositioning toAnimate data.shownPlayed global.seed
|
||||
in
|
||||
(model { global | seed = seed } { data | shownPlayed = (Debug.log "shownPlayed" shownPlayed) }, Effects.none)
|
||||
|
||||
other ->
|
||||
(model global data,
|
||||
DisplayError ("Got an action (" ++ (toString other) ++ ") that can't be handled in the current state (Playing).")
|
||||
@@ -75,17 +93,62 @@ update action global data = case action of
|
||||
|> Effects.task)
|
||||
|
||||
|
||||
updateLobby : PlayingData -> Lobby -> PlayingData
|
||||
updateLobby data lobby =
|
||||
updateLobby : PlayingData -> Lobby -> Seed -> (PlayingData, Effects.Effects Action, Seed)
|
||||
updateLobby data lobby seed =
|
||||
let
|
||||
lastFinishedRound = if (Maybe.map .call data.lobby.round) == (Maybe.map .call lobby.round) then
|
||||
data.lastFinishedRound
|
||||
else
|
||||
data.lobby.round
|
||||
oldShownPlayed = data.shownPlayed
|
||||
oldShownPlayedLength = (List.length oldShownPlayed)
|
||||
(shownPlayed, effects, resultSeed) = case Maybe.map .responses data.lobby.round of
|
||||
Just (Card.Hidden amount) ->
|
||||
let
|
||||
(newShownPlayed, newSeed) =
|
||||
Random.generate (list (amount - oldShownPlayedLength) initialRandomPositioning) seed
|
||||
in
|
||||
(List.concat [ oldShownPlayed, newShownPlayed ]
|
||||
,(Task.sleep (Time.millisecond * 250)
|
||||
`Task.andThen`
|
||||
\_ -> (Task.succeed (AnimatePlayedCards (Util.range oldShownPlayedLength (List.length newShownPlayed)))))
|
||||
|> Effects.task
|
||||
,newSeed)
|
||||
_ -> ([], Effects.none, seed)
|
||||
in
|
||||
{ data | lobby = lobby
|
||||
, lastFinishedRound = lastFinishedRound
|
||||
}
|
||||
({ data | lobby = lobby
|
||||
, lastFinishedRound = lastFinishedRound
|
||||
, shownPlayed = shownPlayed
|
||||
}, effects, resultSeed)
|
||||
|
||||
|
||||
updatePositioning : List Int -> List Attribute -> Seed -> (List Attribute, Seed)
|
||||
updatePositioning toAnimate existing seed =
|
||||
let
|
||||
generator = (\index val -> if (List.member index toAnimate) then randomPositioning else Random.map (\_ -> val) bool)
|
||||
generators = List.indexedMap generator (Debug.log "existing" existing)
|
||||
in
|
||||
Random.generate (Util.inOrder generators) seed
|
||||
|
||||
|
||||
randomPositioning : Generator Attribute
|
||||
randomPositioning = Random.map4 positioning (int -75 75) (int 0 50) bool (int -5 5)
|
||||
|
||||
|
||||
initialRandomPositioning : Generator Attribute
|
||||
initialRandomPositioning = Random.map3 (\r h l -> positioning r h l -100) (int -75 75) (int 0 50) bool
|
||||
|
||||
|
||||
positioning : Int -> Int -> Bool -> Int -> Attribute
|
||||
positioning rotation horizontalPos left verticalPos =
|
||||
let
|
||||
horizontalDirection = if left then "left" else "right"
|
||||
in
|
||||
style
|
||||
[ ("transform", "rotate(" ++ (toString rotation) ++ "deg)")
|
||||
, (horizontalDirection, (toString horizontalPos) ++ "%")
|
||||
, ("top", (toString verticalPos) ++ "%")
|
||||
]
|
||||
|
||||
|
||||
model : Global -> PlayingData -> Model
|
||||
|
||||
@@ -45,7 +45,7 @@ update action global data = case action of
|
||||
|
||||
JoinLobby lobbyId secret (Result lobbyAndHand) ->
|
||||
case lobbyAndHand.lobby.round of
|
||||
Just _ -> (Playing.modelSub global lobbyId secret (PlayingData lobbyAndHand.lobby lobbyAndHand.hand secret [] Nothing), Effects.none)
|
||||
Just _ -> (Playing.modelSub global lobbyId secret (PlayingData lobbyAndHand.lobby lobbyAndHand.hand secret [] Nothing []), Effects.none)
|
||||
Nothing -> (Config.modelSub global lobbyId secret (Config.initialData lobbyAndHand.lobby secret), Effects.none)
|
||||
|
||||
other ->
|
||||
|
||||
@@ -41,11 +41,10 @@ roundContents address data round =
|
||||
picked = List.map snd pickedWithIndex
|
||||
isCzar = round.czar == data.secret.id
|
||||
pickedOrPlayed = case round.responses of
|
||||
Revealed responses -> playedView address isCzar responses
|
||||
Hidden others -> pickedView address pickedWithIndex (Card.slots round.call)
|
||||
Revealed responses -> [ playedView address isCzar responses ]
|
||||
Hidden _ -> pickedView address pickedWithIndex (Card.slots round.call) data.shownPlayed
|
||||
in
|
||||
[ playArea [ call round.call picked, pickedOrPlayed]
|
||||
, handView address data.picked isCzar hand ]
|
||||
[ playArea (List.concat [ [ call round.call picked ], pickedOrPlayed, [ handView address data.picked isCzar hand ] ]) ]
|
||||
|
||||
|
||||
winnerContentsAndHeader : Signal.Address Action -> Round -> List Player -> (List Html, List Html)
|
||||
@@ -113,6 +112,10 @@ response address picked isCzar responseId contents =
|
||||
div (List.concat [ classes, clickHandler ]) [ div [ class "response-text" ] [ text contents ] ]
|
||||
|
||||
|
||||
blankResponse : Attribute -> Html
|
||||
blankResponse positioning = div [ class "card mui-panel", positioning ] []
|
||||
|
||||
|
||||
handRender : Bool -> List Html -> Html
|
||||
handRender isCzar contents =
|
||||
let
|
||||
@@ -130,12 +133,14 @@ pickedResponse address (index, contents) =
|
||||
li [ onClick address (Withdraw index) ] [ div [ class "card response mui-panel" ] [ div [ class "response-text" ] [ text contents ] ] ]
|
||||
|
||||
|
||||
pickedView : Signal.Address Action -> List (Int, Response) -> Int -> Html
|
||||
pickedView address picked slots =
|
||||
pickedView : Signal.Address Action -> List (Int, Response) -> Int -> List Attribute -> List Html
|
||||
pickedView address picked slots shownPlayed =
|
||||
let
|
||||
pb = if (List.length picked < slots) then [] else [ playButton address ]
|
||||
in
|
||||
ol [ class "picked" ] (List.concat [ (List.map (pickedResponse address) picked), pb ])
|
||||
[ ol [ class "picked" ] (List.concat [ (List.map (pickedResponse address) picked), pb ])
|
||||
, div [ class "others-picked" ] (List.map blankResponse shownPlayed)
|
||||
]
|
||||
|
||||
|
||||
playButton : Signal.Address Action -> Html
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
module MassiveDecks.Util where
|
||||
|
||||
import Random exposing (Generator)
|
||||
|
||||
|
||||
interleave : List a -> List a -> List a
|
||||
interleave list1 list2 =
|
||||
@@ -21,10 +23,10 @@ remove list index =
|
||||
|
||||
|
||||
get : List a -> Int -> a
|
||||
get list index = case List.drop index list of
|
||||
get list index = case List.drop index list of
|
||||
[] -> Native.Error.raise <| "Attempted to take element " ++ toString index
|
||||
++ " of list " ++ toString list
|
||||
(item::_) -> item
|
||||
(item::_) -> item
|
||||
|
||||
|
||||
getAll : List a -> List Int -> List a
|
||||
@@ -35,3 +37,15 @@ getAll list indices =
|
||||
getAllWithIndex : List a -> List Int -> List (Int, a)
|
||||
getAllWithIndex list indices =
|
||||
getAll (List.indexedMap (,) list) indices
|
||||
|
||||
|
||||
range : Int -> Int -> List Int
|
||||
range first count = case count of
|
||||
0 -> []
|
||||
_ -> first :: range (first + 1) (count - 1)
|
||||
|
||||
|
||||
inOrder : List (Generator a) -> Generator (List a)
|
||||
inOrder generators = case generators of
|
||||
[] -> Random.map (\_ -> []) Random.bool
|
||||
head :: tail -> head `Random.andThen` (\value -> Random.map ((::) value) (inOrder tail))
|
||||
|
||||
@@ -23,6 +23,15 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
|
||||
.others-picked {
|
||||
.card {
|
||||
position: absolute;
|
||||
z-index: -10;
|
||||
transition: transform 3s, left 3s, right 3s, top 3s ease-out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.call {
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
var initialState = {
|
||||
url: "@url",
|
||||
gameCode: gameCode == "" ? null : gameCode,
|
||||
existingGame: existingGame
|
||||
existingGame: existingGame,
|
||||
seed: new Date().getTime()
|
||||
};
|
||||
|
||||
var game = Elm.fullscreen(Elm.MassiveDecks.Main, { notifications: "", initialState: initialState });
|
||||
|
||||
Reference in New Issue
Block a user