From fadbf188f2dbd5d712fa3ce3be9ccacc3be2e09d Mon Sep 17 00:00:00 2001 From: Bijan Date: Sun, 14 Jan 2018 21:42:40 -0500 Subject: [PATCH 1/4] Update app.js to use consistent js import syntax --- assets/js/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/app.js b/assets/js/app.js index d500c11..5ee11e6 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -21,7 +21,7 @@ import "phoenix_html" // import socket from "./socket" // Elm -const Elm = require("./elm.js"); +import Elm from "./elm"; const elmContainer = document.querySelector("#elm-container"); const platformer = document.querySelector("#platformer"); From 402ce16ff4ccbf0e554dc84d813a3c9fb3e4ef87 Mon Sep 17 00:00:00 2001 From: Bijan Date: Sun, 14 Jan 2018 21:43:31 -0500 Subject: [PATCH 2/4] Add images for character direction changes --- assets/static/images/character-left.gif | Bin 0 -> 1658 bytes assets/static/images/character-right.gif | Bin 0 -> 4098 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/static/images/character-left.gif create mode 100644 assets/static/images/character-right.gif diff --git a/assets/static/images/character-left.gif b/assets/static/images/character-left.gif new file mode 100644 index 0000000000000000000000000000000000000000..ce49afe9415b9363bdba585de16132274d05c1be GIT binary patch literal 1658 zcmV-=28H=YNk%v~VT}O10HOc@0002P2?-Toz5mRa|Ns900000000000A^8Le2ml2D zEC2ui0F3~=000C3Si0Q)Fv>}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhG{ za7Zi~kI1BQ$!t2G&?I0=ty-_ss13{Qdb3*8cTBd1Mdh>_aPF+%T8te}im+5QKk*4~U714UBq@4v>+O3Y3+Wn0b~3n}~d$lxL!wQKh0zsHIG+s7kJ{ zNU^I&w6aCFxI?In;M~){ zUE>4a*D+NIr#kmw&OR@9}a=@5RxO95ZXU@0nedJr!OL? zhY|}`naI)qB7lw>Gu==~(F#bASWYgqHWFgUDJnUpROzl|#)dFs=G#bfkPebFb-w)A zljRndIEe~P8nfonE(D@VB@lC})u~H|?)380%hj(Fzlycm^vc#Q_n?lI8g}j2vL-$5 z>B_}z)V6l7!sR)1F5N46@#e)^ly6eMf2#yWH&}0BDrfERsB2enW2%pH_Px@B^3@{12FS3w`PvY2$4(}1n2F0IxrY1(Kz$Np?K^6s^_OPbcrT6S-_#ckhyO(bSWUmahp&iCJ^goi#} ze|h)+aKK02bB573Aa?-1A)tQ*Lgw3bZ|$YVf=UGk5?Iu&@xyEwj&m7d-3`afd;@d{ z&WCJe$Q3mea${mQDBh)FZX@#NqGKM$7@T)C7FZ&VC+aw(WIZ|kBrPPry$FSr?fFD3ed885p2(z|Yw$hMnr!F2MAFs}a^d6K|=x(o542bW2) z!T__Irp6GT>oKt$7`x}T`^Jbdt@R4E>LD?&ys67pIa~9}7N}fk%Q#yL^TJD_Oo7kC zHfwOu4WGKRc|AWJ?Z#ABDfPE~Ts^UzRadR`)}9LTb!1(8J+?`*>vki=5q` z(v<_tP^p|Do%FAr>s*nn@_;@@>86upVd}oF&ic@<@A!G_U(8NBQmUWcyBE4U?K|$Z z4@r9P84v&Z?aSwmeDcK?ebeu3Kksn#S;5{s@Yav4yzSo`FJ<>%G7moXOA$`K)!|FO zO}6T<4=eA))4zT7@?UHJ`THZz!13~1mFU){ne5H$664FC0KcX^o;@Og0X(257-&BK zEdYS)TcF|~_dfSc;tB!?p$JDv!V;SBgeVN52190^0cz`mR!E@?XGlW5yxbVkrHH zM@y#Cj;?&ACs&}!PU3BXu~Z`~Pf$x)-m;gzG}@g;sY_TAvzW6~0Wig=N=NQ817uib z9AM}LXO=Mn(X?hVud>eVFDyGEAZqLKH<2dos#2 zixQMU9M$L;LK-xW_H&{nwaZ3RD$;Rs6QwL2i$wof&za&gqBixXLj#ISo~Epz1xNq@ EJBIu_p#T5? literal 0 HcmV?d00001 diff --git a/assets/static/images/character-right.gif b/assets/static/images/character-right.gif new file mode 100644 index 0000000000000000000000000000000000000000..cb8697350c6775f558300d8bea8d589dd9d83bc7 GIT binary patch literal 4098 zcmeIz_ct2~8wc7KXWmZesOWp z#mWkL+V*R|%%#BphXCY)U0>4#rJ-i1DJLTfWcb+{a>~TY@^iv|3H&+}01F+!z#^bs zmDdr>!XstVUxn)m`~9|VmUcD1CyMXB>ui5@eqWrhMx=mFO#vzC4vJ_)swo^ylXV!# z(y1*P&V;|-nkCg1kLIcdvkB_f5ytYhlcY5H@=7L(4f7RjDMrMpQj22aa%_F6Il=mN zpx|Q#Rf{mk32&7svvTVa47fd;{UKGY*(aAGk8P}+X=6HHyCPsAi|z#eHlfL(x^Led zdkYw=oF?tqVRBbVpO{`VHj)wXfeQQU!A4$@!PyfPnuObwvR&7-q@VW)rNCjOefIT3 zkGb}TK+cyRAA0um#(@_~1P}*n*xYrHY8#EbHQi=k9B8UIzsp!b_W;KULiGj~NzUIg z+FOPOcW2_re=MjxIXSBBCFg#k1{|K-*55J%B9G9|7egiNf{gDG%%22`_2-3LuQ*N) z))$1^hR$mCKtg|GX5kG92p|ZXh>P>tzghtrI6i;GFikd9=REthmLRr6vV<^2y{Z{+bz67J4mG+l#s8x$qWT9Z8?XeNt-Ou zL9ixA-)&e!|GckgOR&|M%*TD#7OKVSt8{4V7-Ne^#V*p)C31Ye0n-tpP7w_z?emxB za}LfFhI2JqO7<{&^hxw~xwMM*f&BbED{ox&l_de;vvU3O5z6;^WHffh%?-Ho4n~wX zXP~xH#8B=L{eLlaqos_t4%uQ{a|L6{x7}f}I+b3D6F}9u+Av{$-oLCg{8DPCnY7Pq zt?bf3-sTQ&?%q?gGUv{wuJyYL`Lf367`o%lHofe*=UT%@9qP!!gM4vuOu|AcuONIf znnz}8NpL-TM>85o_n8Ui$;n@05=Nh_M!nI;t;J~t?tR6X(-E6C=`xV5pi;EtHr`ss zW78*>da`DHOnpnyH$vA?Y4*vd-##blSuQqxYWLgeyh-ujN>KaeORhrI{g@yt<*Lk# zy?)eoTw{HUJ{RlquJw@Qkkj6?So!Yo#47DBZh3Ou60*DGCv@7-_$Y`}>3cYsaZV+- zGqjKT@B4-C#)IE)S7UT{4i@%K-lUzDUz6f(72XnOQS+1x2@&JKv207gndV2{v#LE~ z$i;VpoZ^vP)~41rC+hq%dtvnYgT+L6KNxb2D@65)2vB|lA;SCT-yFvH>t4*7SW-_o z>TKY8;YMnAN4%uPY$k6bwp%8a>aY0~GFzqID~I2W=3>g{uiZ#dU>u9SZbAmF-|1DP zcn0}|?J|Wjg-uaYGl~Zk*cOiW}gc>5~=Vz;@W! zOF6t9K%>Rdmk-1eY!Jhy>ZtTCj3^B1GVI3eku;RNcCTeqZzN(OYWRm3qD^PmGiM@_ zk>rRNZc@7Ok|#Epp6rYOIgff%%4FlRBp$^`Ho|7)KG2>^aGa%&+?c*EbtRner-bfU zq}3swFJ?paRJ+v?e}FS25wx{*#~Crn5!4|=SKWc})SAf$Q6^t_AY0=Zlw`bw*xUcIx()uP#OroRab17LNxPiHp!9eF0t?$ zFzb^tBKm5I8bjPHU5I89HKOIN@{-o1t?87{_2sVx-E2)?nK!R_mHO%F*d5W#%bC61 zEsshK_9-ge3St#tLD;kO>AFt-hSG>^82=*?%g^>^Wu7V+q@thYc!B~EZ<^y+sB79^ z^!a1-u)**u+nvQ`14$P*MRl=dZS@56D+YD&0|(jD|Fy0LAq-rav4YDc5IiQj1Z z=09Aza87LeRByG!wte#{11Hvg!Kh%4682|tP literal 0 HcmV?d00001 From 84059febeb46f743f61340dfcf71ec700456a2d2 Mon Sep 17 00:00:00 2001 From: Bijan Date: Sun, 14 Jan 2018 22:05:24 -0500 Subject: [PATCH 3/4] Sync Platformer content, display player names with scores --- assets/elm/Platformer.elm | 196 +++++++++++++++----------- assets/js/elm.js | 290 ++++++++++++++++++++------------------ 2 files changed, 260 insertions(+), 226 deletions(-) diff --git a/assets/elm/Platformer.elm b/assets/elm/Platformer.elm index 9a15e3e..9e68496 100644 --- a/assets/elm/Platformer.elm +++ b/assets/elm/Platformer.elm @@ -39,6 +39,11 @@ main = -- MODEL +type Direction + = Left + | Right + + type GameState = StartScreen | Playing @@ -46,6 +51,13 @@ type GameState | GameOver +type alias Gameplay = + { gameId : Int + , playerId : Int + , playerScore : Int + } + + type alias Player = { displayName : Maybe String , id : Int @@ -55,36 +67,38 @@ type alias Player = type alias Model = - { errors : String - , gameId : Int - , gameState : GameState + { characterDirection : Direction , characterPositionX : Int , characterPositionY : Int + , errors : String + , gameId : Int + , gameplays : List Gameplay + , gameState : GameState , itemPositionX : Int , itemPositionY : Int , itemsCollected : Int , phxSocket : Phoenix.Socket.Socket Msg , playersList : List Player , playerScore : Int - , playerScores : List Score , timeRemaining : Int } initialModel : Flags -> Model initialModel flags = - { errors = "" - , gameId = 1 - , gameState = StartScreen + { characterDirection = Right , characterPositionX = 50 , characterPositionY = 300 + , errors = "" + , gameId = 1 + , gameplays = [] + , gameState = StartScreen , itemPositionX = 150 , itemPositionY = 300 , itemsCollected = 0 , phxSocket = initialSocketJoin flags , playersList = [] , playerScore = 0 - , playerScores = [] , timeRemaining = 10 } @@ -100,7 +114,7 @@ initialSocket flags = in Phoenix.Socket.init prodSocketServer |> Phoenix.Socket.withDebug - |> Phoenix.Socket.on "shout" "score:platformer" SendScore + |> Phoenix.Socket.on "save_score" "score:platformer" SaveScore |> Phoenix.Socket.on "save_score" "score:platformer" ReceiveScoreChanges |> Phoenix.Socket.join initialChannel @@ -124,7 +138,12 @@ initialSocketCommand flags = init : Flags -> ( Model, Cmd Msg ) init flags = - ( initialModel flags, Cmd.map PhoenixMsg (initialSocketCommand flags) ) + ( initialModel flags + , Cmd.batch + [ fetchPlayersList + , Cmd.map PhoenixMsg (initialSocketCommand flags) + ] + ) @@ -153,16 +172,18 @@ decodePlayer = (Decode.field "username" Decode.string) -type alias Score = - { gameId : Int - , playerId : Int - , playerScore : Int +anonymousPlayer : Player +anonymousPlayer = + { displayName = Just "Anonymous User" + , id = 0 + , score = 0 + , username = "anonymous" } -scoreDecoder : Decode.Decoder Score +scoreDecoder : Decode.Decoder Gameplay scoreDecoder = - Decode.map3 Score + Decode.map3 Gameplay (Decode.field "game_id" Decode.int) (Decode.field "player_id" Decode.int) (Decode.field "player_score" Decode.int) @@ -182,9 +203,6 @@ type Msg | SaveScore Encode.Value | SaveScoreError Encode.Value | SaveScoreRequest - | SendScore Encode.Value - | SendScoreError Encode.Value - | SendScoreRequest | SetNewItemPositionX Int | TimeUpdate Time @@ -214,10 +232,11 @@ update msg model = 32 -> if model.gameState /= Playing then ( { model - | gameState = Playing + | characterDirection = Right , characterPositionX = 50 - , playerScore = 0 , itemsCollected = 0 + , gameState = Playing + , playerScore = 0 , timeRemaining = 10 } , Cmd.none @@ -227,13 +246,23 @@ update msg model = 37 -> if model.gameState == Playing then - ( { model | characterPositionX = model.characterPositionX - 15 }, Cmd.none ) + ( { model + | characterDirection = Left + , characterPositionX = model.characterPositionX - 15 + } + , Cmd.none + ) else ( model, Cmd.none ) 39 -> if model.gameState == Playing then - ( { model | characterPositionX = model.characterPositionX + 15 }, Cmd.none ) + ( { model + | characterDirection = Right + , characterPositionX = model.characterPositionX + 15 + } + , Cmd.none + ) else ( model, Cmd.none ) @@ -252,7 +281,7 @@ update msg model = ReceiveScoreChanges raw -> case Decode.decodeValue scoreDecoder raw of Ok scoreChange -> - ( { model | playerScores = scoreChange :: model.playerScores }, Cmd.none ) + ( { model | gameplays = scoreChange :: model.gameplays }, Cmd.none ) Err message -> ( { model | errors = message }, Cmd.none ) @@ -261,7 +290,7 @@ update msg model = ( model, Cmd.none ) SaveScoreError message -> - Debug.log "Error saveing score over socket." + Debug.log "Error saving score over socket." ( model, Cmd.none ) SaveScoreRequest -> @@ -282,31 +311,6 @@ update msg model = , Cmd.map PhoenixMsg phxCmd ) - SendScore value -> - ( model, Cmd.none ) - - SendScoreError message -> - Debug.log "Error sending score over socket." - ( model, Cmd.none ) - - SendScoreRequest -> - let - payload = - Encode.object [ ( "player_score", Encode.int model.playerScore ) ] - - phxPush = - Phoenix.Push.init "shout" "score:platformer" - |> Phoenix.Push.withPayload payload - |> Phoenix.Push.onOk SendScore - |> Phoenix.Push.onError SendScoreError - - ( phxSocket, phxCmd ) = - Phoenix.Socket.push phxPush model.phxSocket - in - ( { model | phxSocket = phxSocket } - , Cmd.map PhoenixMsg phxCmd - ) - SetNewItemPositionX newPositionX -> ( { model | itemPositionX = newPositionX }, Cmd.none ) @@ -363,20 +367,8 @@ view : Model -> Html Msg view model = div [] [ viewGame model - , viewSendScoreButton , viewSaveScoreButton - , viewPlayerScoresIndex model - ] - - -viewSendScoreButton : Html Msg -viewSendScoreButton = - div [] - [ button - [ onClick SendScoreRequest - , Html.Attributes.class "btn btn-primary" - ] - [ text "Send Score" ] + , viewGameplaysIndex model ] @@ -391,31 +383,56 @@ viewSaveScoreButton = ] -viewPlayerScoresIndex : Model -> Html Msg -viewPlayerScoresIndex model = - if List.isEmpty model.playerScores then +viewGameplaysIndex : Model -> Html Msg +viewGameplaysIndex model = + if List.isEmpty model.gameplays then div [] [] else div [ Html.Attributes.class "players-index" ] [ h1 [ Html.Attributes.class "players-section" ] [ text "Player Scores" ] - , viewPlayerScoresList model.playerScores + , viewGameplaysList model ] -viewPlayerScoresList : List Score -> Html Msg -viewPlayerScoresList scores = +viewGameplaysList : Model -> Html Msg +viewGameplaysList model = div [ Html.Attributes.class "players-list panel panel-info" ] - [ div [ Html.Attributes.class "panel-heading" ] [ text "Leaderboard" ] - , ul [ Html.Attributes.class "list-group" ] (List.map viewPlayerScoreItem scores) + [ div [ Html.Attributes.class "panel-heading" ] [ text "Scores" ] + , ul [ Html.Attributes.class "list-group" ] (List.map (viewGameplayItem model) model.gameplays) ] -viewPlayerScoreItem : Score -> Html Msg -viewPlayerScoreItem score = - li [ Html.Attributes.class "player-item list-group-item" ] - [ strong [] [ text (toString score.playerId) ] - , span [ Html.Attributes.class "badge" ] [ text (toString score.playerScore) ] - ] +viewGameplayItem : Model -> Gameplay -> Html Msg +viewGameplayItem model gameplay = + let + currentPlayer = + model.playersList + |> List.filter (\player -> player.id == gameplay.playerId) + |> List.head + |> Maybe.withDefault anonymousPlayer + + displayName = + Maybe.withDefault currentPlayer.username currentPlayer.displayName + in + li [ Html.Attributes.class "player-item list-group-item" ] + [ strong [] [ text displayName ] + , span [ Html.Attributes.class "badge" ] [ text (toString gameplay.playerScore) ] + ] + + +playersListItem : Player -> Html msg +playersListItem player = + let + displayName = + if player.displayName == Nothing then + player.username + else + Maybe.withDefault "" player.displayName + in + li [ Html.Attributes.class "player-item list-group-item" ] + [ strong [] [ text displayName ] + , span [ Html.Attributes.class "badge" ] [ text (toString player.score) ] + ] viewGame : Model -> Svg Msg @@ -527,14 +544,23 @@ viewGameGround = viewCharacter : Model -> Svg Msg viewCharacter model = - image - [ xlinkHref "/images/character.gif" - , x (toString model.characterPositionX) - , y (toString model.characterPositionY) - , width "50" - , height "50" - ] - [] + let + characterImage = + case model.characterDirection of + Left -> + "/images/character-left.gif" + + Right -> + "/images/character-right.gif" + in + image + [ xlinkHref characterImage + , x (toString model.characterPositionX) + , y (toString model.characterPositionY) + , width "50" + , height "50" + ] + [] viewItem : Model -> Svg Msg diff --git a/assets/js/elm.js b/assets/js/elm.js index a865de9..6195d49 100644 --- a/assets/js/elm.js +++ b/assets/js/elm.js @@ -16139,11 +16139,19 @@ var _user$project$Platformer$viewItem = function (model) { {ctor: '[]'}); }; var _user$project$Platformer$viewCharacter = function (model) { + var characterImage = function () { + var _p0 = model.characterDirection; + if (_p0.ctor === 'Left') { + return '/images/character-left.gif'; + } else { + return '/images/character-right.gif'; + } + }(); return A2( _elm_lang$svg$Svg$image, { ctor: '::', - _0: _elm_lang$svg$Svg_Attributes$xlinkHref('/images/character.gif'), + _0: _elm_lang$svg$Svg_Attributes$xlinkHref(characterImage), _1: { ctor: '::', _0: _elm_lang$svg$Svg_Attributes$x( @@ -16271,8 +16279,8 @@ var _user$project$Platformer$viewStartScreenText = A2( } }); var _user$project$Platformer$viewGameState = function (model) { - var _p0 = model.gameState; - switch (_p0.ctor) { + var _p1 = model.gameState; + switch (_p1.ctor) { case 'StartScreen': return { ctor: '::', @@ -16405,7 +16413,8 @@ var _user$project$Platformer$viewGame = function (model) { }, _user$project$Platformer$viewGameState(model)); }; -var _user$project$Platformer$viewPlayerScoreItem = function (score) { +var _user$project$Platformer$playersListItem = function (player) { + var displayName = _elm_lang$core$Native_Utils.eq(player.displayName, _elm_lang$core$Maybe$Nothing) ? player.username : A2(_elm_lang$core$Maybe$withDefault, '', player.displayName); return A2( _elm_lang$html$Html$li, { @@ -16420,8 +16429,7 @@ var _user$project$Platformer$viewPlayerScoreItem = function (score) { {ctor: '[]'}, { ctor: '::', - _0: _elm_lang$svg$Svg$text( - _elm_lang$core$Basics$toString(score.playerId)), + _0: _elm_lang$svg$Svg$text(displayName), _1: {ctor: '[]'} }), _1: { @@ -16436,14 +16444,75 @@ var _user$project$Platformer$viewPlayerScoreItem = function (score) { { ctor: '::', _0: _elm_lang$svg$Svg$text( - _elm_lang$core$Basics$toString(score.playerScore)), + _elm_lang$core$Basics$toString(player.score)), _1: {ctor: '[]'} }), _1: {ctor: '[]'} } }); }; -var _user$project$Platformer$viewPlayerScoresList = function (scores) { +var _user$project$Platformer$characterFoundItem = function (model) { + var approximateItemUpperBound = model.itemPositionX; + var approximateItemLowerBound = model.itemPositionX - 35; + var approximateItemRange = A2(_elm_lang$core$List$range, approximateItemLowerBound, approximateItemUpperBound); + return A2(_elm_lang$core$List$member, model.characterPositionX, approximateItemRange); +}; +var _user$project$Platformer$anonymousPlayer = { + displayName: _elm_lang$core$Maybe$Just('Anonymous User'), + id: 0, + score: 0, + username: 'anonymous' +}; +var _user$project$Platformer$viewGameplayItem = F2( + function (model, gameplay) { + var currentPlayer = A2( + _elm_lang$core$Maybe$withDefault, + _user$project$Platformer$anonymousPlayer, + _elm_lang$core$List$head( + A2( + _elm_lang$core$List$filter, + function (player) { + return _elm_lang$core$Native_Utils.eq(player.id, gameplay.playerId); + }, + model.playersList))); + var displayName = A2(_elm_lang$core$Maybe$withDefault, currentPlayer.username, currentPlayer.displayName); + return A2( + _elm_lang$html$Html$li, + { + ctor: '::', + _0: _elm_lang$html$Html_Attributes$class('player-item list-group-item'), + _1: {ctor: '[]'} + }, + { + ctor: '::', + _0: A2( + _elm_lang$html$Html$strong, + {ctor: '[]'}, + { + ctor: '::', + _0: _elm_lang$svg$Svg$text(displayName), + _1: {ctor: '[]'} + }), + _1: { + ctor: '::', + _0: A2( + _elm_lang$html$Html$span, + { + ctor: '::', + _0: _elm_lang$html$Html_Attributes$class('badge'), + _1: {ctor: '[]'} + }, + { + ctor: '::', + _0: _elm_lang$svg$Svg$text( + _elm_lang$core$Basics$toString(gameplay.playerScore)), + _1: {ctor: '[]'} + }), + _1: {ctor: '[]'} + } + }); + }); +var _user$project$Platformer$viewGameplaysList = function (model) { return A2( _elm_lang$html$Html$div, { @@ -16462,7 +16531,7 @@ var _user$project$Platformer$viewPlayerScoresList = function (scores) { }, { ctor: '::', - _0: _elm_lang$svg$Svg$text('Leaderboard'), + _0: _elm_lang$svg$Svg$text('Scores'), _1: {ctor: '[]'} }), _1: { @@ -16474,13 +16543,16 @@ var _user$project$Platformer$viewPlayerScoresList = function (scores) { _0: _elm_lang$html$Html_Attributes$class('list-group'), _1: {ctor: '[]'} }, - A2(_elm_lang$core$List$map, _user$project$Platformer$viewPlayerScoreItem, scores)), + A2( + _elm_lang$core$List$map, + _user$project$Platformer$viewGameplayItem(model), + model.gameplays)), _1: {ctor: '[]'} } }); }; -var _user$project$Platformer$viewPlayerScoresIndex = function (model) { - return _elm_lang$core$List$isEmpty(model.playerScores) ? A2( +var _user$project$Platformer$viewGameplaysIndex = function (model) { + return _elm_lang$core$List$isEmpty(model.gameplays) ? A2( _elm_lang$html$Html$div, {ctor: '[]'}, {ctor: '[]'}) : A2( @@ -16506,21 +16578,25 @@ var _user$project$Platformer$viewPlayerScoresIndex = function (model) { }), _1: { ctor: '::', - _0: _user$project$Platformer$viewPlayerScoresList(model.playerScores), + _0: _user$project$Platformer$viewGameplaysList(model), _1: {ctor: '[]'} } }); }; -var _user$project$Platformer$characterFoundItem = function (model) { - var approximateItemUpperBound = model.itemPositionX; - var approximateItemLowerBound = model.itemPositionX - 35; - var approximateItemRange = A2(_elm_lang$core$List$range, approximateItemLowerBound, approximateItemUpperBound); - return A2(_elm_lang$core$List$member, model.characterPositionX, approximateItemRange); -}; var _user$project$Platformer$initialChannel = _fbonetti$elm_phoenix_socket$Phoenix_Channel$init('score:platformer'); var _user$project$Platformer$Flags = function (a) { return {token: a}; }; +var _user$project$Platformer$Gameplay = F3( + function (a, b, c) { + return {gameId: a, playerId: b, playerScore: c}; + }); +var _user$project$Platformer$scoreDecoder = A4( + _elm_lang$core$Json_Decode$map3, + _user$project$Platformer$Gameplay, + A2(_elm_lang$core$Json_Decode$field, 'game_id', _elm_lang$core$Json_Decode$int), + A2(_elm_lang$core$Json_Decode$field, 'player_id', _elm_lang$core$Json_Decode$int), + A2(_elm_lang$core$Json_Decode$field, 'player_score', _elm_lang$core$Json_Decode$int)); var _user$project$Platformer$Player = F4( function (a, b, c, d) { return {displayName: a, id: b, score: c, username: d}; @@ -16554,7 +16630,9 @@ var _user$project$Platformer$Model = function (a) { return function (k) { return function (l) { return function (m) { - return {errors: a, gameId: b, gameState: c, characterPositionX: d, characterPositionY: e, itemPositionX: f, itemPositionY: g, itemsCollected: h, phxSocket: i, playersList: j, playerScore: k, playerScores: l, timeRemaining: m}; + return function (n) { + return {characterDirection: a, characterPositionX: b, characterPositionY: c, errors: d, gameId: e, gameplays: f, gameState: g, itemPositionX: h, itemPositionY: i, itemsCollected: j, phxSocket: k, playersList: l, playerScore: m, timeRemaining: n}; + }; }; }; }; @@ -16568,16 +16646,8 @@ var _user$project$Platformer$Model = function (a) { }; }; }; -var _user$project$Platformer$Score = F3( - function (a, b, c) { - return {gameId: a, playerId: b, playerScore: c}; - }); -var _user$project$Platformer$scoreDecoder = A4( - _elm_lang$core$Json_Decode$map3, - _user$project$Platformer$Score, - A2(_elm_lang$core$Json_Decode$field, 'game_id', _elm_lang$core$Json_Decode$int), - A2(_elm_lang$core$Json_Decode$field, 'player_id', _elm_lang$core$Json_Decode$int), - A2(_elm_lang$core$Json_Decode$field, 'player_score', _elm_lang$core$Json_Decode$int)); +var _user$project$Platformer$Right = {ctor: 'Right'}; +var _user$project$Platformer$Left = {ctor: 'Left'}; var _user$project$Platformer$GameOver = {ctor: 'GameOver'}; var _user$project$Platformer$Success = {ctor: 'Success'}; var _user$project$Platformer$Playing = {ctor: 'Playing'}; @@ -16588,36 +16658,6 @@ var _user$project$Platformer$TimeUpdate = function (a) { var _user$project$Platformer$SetNewItemPositionX = function (a) { return {ctor: 'SetNewItemPositionX', _0: a}; }; -var _user$project$Platformer$SendScoreRequest = {ctor: 'SendScoreRequest'}; -var _user$project$Platformer$viewSendScoreButton = A2( - _elm_lang$html$Html$div, - {ctor: '[]'}, - { - ctor: '::', - _0: A2( - _elm_lang$html$Html$button, - { - ctor: '::', - _0: _elm_lang$html$Html_Events$onClick(_user$project$Platformer$SendScoreRequest), - _1: { - ctor: '::', - _0: _elm_lang$html$Html_Attributes$class('btn btn-primary'), - _1: {ctor: '[]'} - } - }, - { - ctor: '::', - _0: _elm_lang$svg$Svg$text('Send Score'), - _1: {ctor: '[]'} - }), - _1: {ctor: '[]'} - }); -var _user$project$Platformer$SendScoreError = function (a) { - return {ctor: 'SendScoreError', _0: a}; -}; -var _user$project$Platformer$SendScore = function (a) { - return {ctor: 'SendScore', _0: a}; -}; var _user$project$Platformer$SaveScoreRequest = {ctor: 'SaveScoreRequest'}; var _user$project$Platformer$viewSaveScoreButton = A2( _elm_lang$html$Html$div, @@ -16651,15 +16691,11 @@ var _user$project$Platformer$view = function (model) { _0: _user$project$Platformer$viewGame(model), _1: { ctor: '::', - _0: _user$project$Platformer$viewSendScoreButton, + _0: _user$project$Platformer$viewSaveScoreButton, _1: { ctor: '::', - _0: _user$project$Platformer$viewSaveScoreButton, - _1: { - ctor: '::', - _0: _user$project$Platformer$viewPlayerScoresIndex(model), - _1: {ctor: '[]'} - } + _0: _user$project$Platformer$viewGameplaysIndex(model), + _1: {ctor: '[]'} } } }); @@ -16686,9 +16722,9 @@ var _user$project$Platformer$initialSocket = function (flags) { _user$project$Platformer$ReceiveScoreChanges, A4( _fbonetti$elm_phoenix_socket$Phoenix_Socket$on, - 'shout', + 'save_score', 'score:platformer', - _user$project$Platformer$SendScore, + _user$project$Platformer$SaveScore, _fbonetti$elm_phoenix_socket$Phoenix_Socket$withDebug( _fbonetti$elm_phoenix_socket$Phoenix_Socket$init(prodSocketServer))))); }; @@ -16698,18 +16734,19 @@ var _user$project$Platformer$initialSocketJoin = function (flags) { }; var _user$project$Platformer$initialModel = function (flags) { return { + characterDirection: _user$project$Platformer$Right, + characterPositionX: 50, + characterPositionY: 300, errors: '', gameId: 1, + gameplays: {ctor: '[]'}, gameState: _user$project$Platformer$StartScreen, - characterPositionX: 50, - characterPositionY: 300, itemPositionX: 150, itemPositionY: 300, itemsCollected: 0, phxSocket: _user$project$Platformer$initialSocketJoin(flags), playersList: {ctor: '[]'}, playerScore: 0, - playerScores: {ctor: '[]'}, timeRemaining: 10 }; }; @@ -16720,20 +16757,10 @@ var _user$project$Platformer$initialSocketCommand = function (flags) { var _user$project$Platformer$PhoenixMsg = function (a) { return {ctor: 'PhoenixMsg', _0: a}; }; -var _user$project$Platformer$init = function (flags) { - return { - ctor: '_Tuple2', - _0: _user$project$Platformer$initialModel(flags), - _1: A2( - _elm_lang$core$Platform_Cmd$map, - _user$project$Platformer$PhoenixMsg, - _user$project$Platformer$initialSocketCommand(flags)) - }; -}; var _user$project$Platformer$update = F2( function (msg, model) { - var _p1 = msg; - switch (_p1.ctor) { + var _p2 = msg; + switch (_p2.ctor) { case 'NoOp': return {ctor: '_Tuple2', _0: model, _1: _elm_lang$core$Platform_Cmd$none}; case 'CountdownTimer': @@ -16745,13 +16772,13 @@ var _user$project$Platformer$update = F2( _1: _elm_lang$core$Platform_Cmd$none } : {ctor: '_Tuple2', _0: model, _1: _elm_lang$core$Platform_Cmd$none}; case 'FetchPlayersList': - var _p2 = _p1._0; - if (_p2.ctor === 'Ok') { + var _p3 = _p2._0; + if (_p3.ctor === 'Ok') { return { ctor: '_Tuple2', _0: _elm_lang$core$Native_Utils.update( model, - {playersList: _p2._0}), + {playersList: _p3._0}), _1: _elm_lang$core$Platform_Cmd$none }; } else { @@ -16760,20 +16787,20 @@ var _user$project$Platformer$update = F2( _0: _elm_lang$core$Native_Utils.update( model, { - errors: _elm_lang$core$Basics$toString(_p2._0) + errors: _elm_lang$core$Basics$toString(_p3._0) }), _1: _elm_lang$core$Platform_Cmd$none }; } case 'KeyDown': - var _p3 = _p1._0; - switch (_p3) { + var _p4 = _p2._0; + switch (_p4) { case 32: return (!_elm_lang$core$Native_Utils.eq(model.gameState, _user$project$Platformer$Playing)) ? { ctor: '_Tuple2', _0: _elm_lang$core$Native_Utils.update( model, - {gameState: _user$project$Platformer$Playing, characterPositionX: 50, playerScore: 0, itemsCollected: 0, timeRemaining: 10}), + {characterDirection: _user$project$Platformer$Right, characterPositionX: 50, itemsCollected: 0, gameState: _user$project$Platformer$Playing, playerScore: 0, timeRemaining: 10}), _1: _elm_lang$core$Platform_Cmd$none } : {ctor: '_Tuple2', _0: model, _1: _elm_lang$core$Platform_Cmd$none}; case 37: @@ -16781,7 +16808,7 @@ var _user$project$Platformer$update = F2( ctor: '_Tuple2', _0: _elm_lang$core$Native_Utils.update( model, - {characterPositionX: model.characterPositionX - 15}), + {characterDirection: _user$project$Platformer$Left, characterPositionX: model.characterPositionX - 15}), _1: _elm_lang$core$Platform_Cmd$none } : {ctor: '_Tuple2', _0: model, _1: _elm_lang$core$Platform_Cmd$none}; case 39: @@ -16789,16 +16816,16 @@ var _user$project$Platformer$update = F2( ctor: '_Tuple2', _0: _elm_lang$core$Native_Utils.update( model, - {characterPositionX: model.characterPositionX + 15}), + {characterDirection: _user$project$Platformer$Right, characterPositionX: model.characterPositionX + 15}), _1: _elm_lang$core$Platform_Cmd$none } : {ctor: '_Tuple2', _0: model, _1: _elm_lang$core$Platform_Cmd$none}; default: return {ctor: '_Tuple2', _0: model, _1: _elm_lang$core$Platform_Cmd$none}; } case 'PhoenixMsg': - var _p4 = A2(_fbonetti$elm_phoenix_socket$Phoenix_Socket$update, _p1._0, model.phxSocket); - var phxSocket = _p4._0; - var phxCmd = _p4._1; + var _p5 = A2(_fbonetti$elm_phoenix_socket$Phoenix_Socket$update, _p2._0, model.phxSocket); + var phxSocket = _p5._0; + var phxCmd = _p5._1; return { ctor: '_Tuple2', _0: _elm_lang$core$Native_Utils.update( @@ -16807,14 +16834,14 @@ var _user$project$Platformer$update = F2( _1: A2(_elm_lang$core$Platform_Cmd$map, _user$project$Platformer$PhoenixMsg, phxCmd) }; case 'ReceiveScoreChanges': - var _p5 = A2(_elm_lang$core$Json_Decode$decodeValue, _user$project$Platformer$scoreDecoder, _p1._0); - if (_p5.ctor === 'Ok') { + var _p6 = A2(_elm_lang$core$Json_Decode$decodeValue, _user$project$Platformer$scoreDecoder, _p2._0); + if (_p6.ctor === 'Ok') { return { ctor: '_Tuple2', _0: _elm_lang$core$Native_Utils.update( model, { - playerScores: {ctor: '::', _0: _p5._0, _1: model.playerScores} + gameplays: {ctor: '::', _0: _p6._0, _1: model.gameplays} }), _1: _elm_lang$core$Platform_Cmd$none }; @@ -16823,7 +16850,7 @@ var _user$project$Platformer$update = F2( ctor: '_Tuple2', _0: _elm_lang$core$Native_Utils.update( model, - {errors: _p5._0}), + {errors: _p6._0}), _1: _elm_lang$core$Platform_Cmd$none }; } @@ -16832,7 +16859,7 @@ var _user$project$Platformer$update = F2( case 'SaveScoreError': return A2( _elm_lang$core$Debug$log, - 'Error saveing score over socket.', + 'Error saving score over socket.', {ctor: '_Tuple2', _0: model, _1: _elm_lang$core$Platform_Cmd$none}); case 'SaveScoreRequest': var payload = _elm_lang$core$Json_Encode$object( @@ -16855,44 +16882,6 @@ var _user$project$Platformer$update = F2( _fbonetti$elm_phoenix_socket$Phoenix_Push$withPayload, payload, A2(_fbonetti$elm_phoenix_socket$Phoenix_Push$init, 'save_score', 'score:platformer')))); - var _p6 = A2(_fbonetti$elm_phoenix_socket$Phoenix_Socket$push, phxPush, model.phxSocket); - var phxSocket = _p6._0; - var phxCmd = _p6._1; - return { - ctor: '_Tuple2', - _0: _elm_lang$core$Native_Utils.update( - model, - {phxSocket: phxSocket}), - _1: A2(_elm_lang$core$Platform_Cmd$map, _user$project$Platformer$PhoenixMsg, phxCmd) - }; - case 'SendScore': - return {ctor: '_Tuple2', _0: model, _1: _elm_lang$core$Platform_Cmd$none}; - case 'SendScoreError': - return A2( - _elm_lang$core$Debug$log, - 'Error sending score over socket.', - {ctor: '_Tuple2', _0: model, _1: _elm_lang$core$Platform_Cmd$none}); - case 'SendScoreRequest': - var payload = _elm_lang$core$Json_Encode$object( - { - ctor: '::', - _0: { - ctor: '_Tuple2', - _0: 'player_score', - _1: _elm_lang$core$Json_Encode$int(model.playerScore) - }, - _1: {ctor: '[]'} - }); - var phxPush = A2( - _fbonetti$elm_phoenix_socket$Phoenix_Push$onError, - _user$project$Platformer$SendScoreError, - A2( - _fbonetti$elm_phoenix_socket$Phoenix_Push$onOk, - _user$project$Platformer$SendScore, - A2( - _fbonetti$elm_phoenix_socket$Phoenix_Push$withPayload, - payload, - A2(_fbonetti$elm_phoenix_socket$Phoenix_Push$init, 'shout', 'score:platformer')))); var _p7 = A2(_fbonetti$elm_phoenix_socket$Phoenix_Socket$push, phxPush, model.phxSocket); var phxSocket = _p7._0; var phxCmd = _p7._1; @@ -16908,7 +16897,7 @@ var _user$project$Platformer$update = F2( ctor: '_Tuple2', _0: _elm_lang$core$Native_Utils.update( model, - {itemPositionX: _p1._0}), + {itemPositionX: _p2._0}), _1: _elm_lang$core$Platform_Cmd$none }; default: @@ -16946,6 +16935,25 @@ var _user$project$Platformer$fetchPlayersList = A2( _elm_lang$http$Http$send, _user$project$Platformer$FetchPlayersList, A2(_elm_lang$http$Http$get, '/api/players', _user$project$Platformer$decodePlayersList)); +var _user$project$Platformer$init = function (flags) { + return { + ctor: '_Tuple2', + _0: _user$project$Platformer$initialModel(flags), + _1: _elm_lang$core$Platform_Cmd$batch( + { + ctor: '::', + _0: _user$project$Platformer$fetchPlayersList, + _1: { + ctor: '::', + _0: A2( + _elm_lang$core$Platform_Cmd$map, + _user$project$Platformer$PhoenixMsg, + _user$project$Platformer$initialSocketCommand(flags)), + _1: {ctor: '[]'} + } + }) + }; +}; var _user$project$Platformer$CountdownTimer = function (a) { return {ctor: 'CountdownTimer', _0: a}; }; @@ -16987,7 +16995,7 @@ if (typeof _user$project$Main$main !== 'undefined') { } Elm['Platformer'] = Elm['Platformer'] || {}; if (typeof _user$project$Platformer$main !== 'undefined') { - _user$project$Platformer$main(Elm['Platformer'], 'Platformer', {"types":{"unions":{"Dict.LeafColor":{"args":[],"tags":{"LBBlack":[],"LBlack":[]}},"Platformer.Msg":{"args":[],"tags":{"SetNewItemPositionX":["Int"],"SendScoreRequest":[],"SaveScoreRequest":[],"CountdownTimer":["Time.Time"],"FetchPlayersList":["Result.Result Http.Error (List Platformer.Player)"],"SaveScore":["Json.Encode.Value"],"SendScore":["Json.Encode.Value"],"PhoenixMsg":["Phoenix.Socket.Msg Platformer.Msg"],"TimeUpdate":["Time.Time"],"SendScoreError":["Json.Encode.Value"],"KeyDown":["Keyboard.KeyCode"],"ReceiveScoreChanges":["Json.Encode.Value"],"NoOp":[],"SaveScoreError":["Json.Encode.Value"]}},"Json.Encode.Value":{"args":[],"tags":{"Value":[]}},"Dict.Dict":{"args":["k","v"],"tags":{"RBNode_elm_builtin":["Dict.NColor","k","v","Dict.Dict k v","Dict.Dict k v"],"RBEmpty_elm_builtin":["Dict.LeafColor"]}},"Maybe.Maybe":{"args":["a"],"tags":{"Just":["a"],"Nothing":[]}},"Dict.NColor":{"args":[],"tags":{"BBlack":[],"Red":[],"NBlack":[],"Black":[]}},"Http.Error":{"args":[],"tags":{"BadUrl":["String"],"NetworkError":[],"Timeout":[],"BadStatus":["Http.Response String"],"BadPayload":["String","Http.Response String"]}},"Result.Result":{"args":["error","value"],"tags":{"Ok":["value"],"Err":["error"]}},"Phoenix.Socket.Msg":{"args":["msg"],"tags":{"ChannelErrored":["String"],"ChannelClosed":["String"],"ExternalMsg":["msg"],"ChannelJoined":["String"],"Heartbeat":["Time.Time"],"NoOp":[],"ReceiveReply":["String","Int"]}}},"aliases":{"Http.Response":{"args":["body"],"type":"{ url : String , status : { code : Int, message : String } , headers : Dict.Dict String String , body : body }"},"Keyboard.KeyCode":{"args":[],"type":"Int"},"Platformer.Player":{"args":[],"type":"{ displayName : Maybe.Maybe String , id : Int , score : Int , username : String }"},"Time.Time":{"args":[],"type":"Float"}},"message":"Platformer.Msg"},"versions":{"elm":"0.18.0"}}); + _user$project$Platformer$main(Elm['Platformer'], 'Platformer', {"types":{"unions":{"Dict.LeafColor":{"args":[],"tags":{"LBBlack":[],"LBlack":[]}},"Platformer.Msg":{"args":[],"tags":{"SetNewItemPositionX":["Int"],"SaveScoreRequest":[],"CountdownTimer":["Time.Time"],"FetchPlayersList":["Result.Result Http.Error (List Platformer.Player)"],"SaveScore":["Json.Encode.Value"],"PhoenixMsg":["Phoenix.Socket.Msg Platformer.Msg"],"TimeUpdate":["Time.Time"],"KeyDown":["Keyboard.KeyCode"],"ReceiveScoreChanges":["Json.Encode.Value"],"NoOp":[],"SaveScoreError":["Json.Encode.Value"]}},"Json.Encode.Value":{"args":[],"tags":{"Value":[]}},"Dict.Dict":{"args":["k","v"],"tags":{"RBNode_elm_builtin":["Dict.NColor","k","v","Dict.Dict k v","Dict.Dict k v"],"RBEmpty_elm_builtin":["Dict.LeafColor"]}},"Maybe.Maybe":{"args":["a"],"tags":{"Just":["a"],"Nothing":[]}},"Dict.NColor":{"args":[],"tags":{"BBlack":[],"Red":[],"NBlack":[],"Black":[]}},"Http.Error":{"args":[],"tags":{"BadUrl":["String"],"NetworkError":[],"Timeout":[],"BadStatus":["Http.Response String"],"BadPayload":["String","Http.Response String"]}},"Result.Result":{"args":["error","value"],"tags":{"Ok":["value"],"Err":["error"]}},"Phoenix.Socket.Msg":{"args":["msg"],"tags":{"ChannelErrored":["String"],"ChannelClosed":["String"],"ExternalMsg":["msg"],"ChannelJoined":["String"],"Heartbeat":["Time.Time"],"NoOp":[],"ReceiveReply":["String","Int"]}}},"aliases":{"Http.Response":{"args":["body"],"type":"{ url : String , status : { code : Int, message : String } , headers : Dict.Dict String String , body : body }"},"Keyboard.KeyCode":{"args":[],"type":"Int"},"Platformer.Player":{"args":[],"type":"{ displayName : Maybe.Maybe String , id : Int , score : Int , username : String }"},"Time.Time":{"args":[],"type":"Float"}},"message":"Platformer.Msg"},"versions":{"elm":"0.18.0"}}); } if (typeof define === "function" && define['amd']) From ae8953a618b5c01f06c68a3d43f59b613d678777 Mon Sep 17 00:00:00 2001 From: Bijan Date: Sun, 14 Jan 2018 22:07:54 -0500 Subject: [PATCH 4/4] Link from home page to player show page --- assets/elm/Main.elm | 5 ++++- assets/js/elm.js | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/assets/elm/Main.elm b/assets/elm/Main.elm index 1993634..9ccac29 100644 --- a/assets/elm/Main.elm +++ b/assets/elm/Main.elm @@ -265,8 +265,11 @@ playersListItem player = player.username else Maybe.withDefault "" player.displayName + + playerLink = + "players/" ++ (toString player.id) in li [ class "player-item list-group-item" ] - [ strong [] [ text displayName ] + [ strong [] [ a [ href playerLink ] [ text displayName ] ] , span [ class "badge" ] [ text (toString player.score) ] ] diff --git a/assets/js/elm.js b/assets/js/elm.js index 6195d49..2ffe616 100644 --- a/assets/js/elm.js +++ b/assets/js/elm.js @@ -15476,6 +15476,10 @@ var _fbonetti$elm_phoenix_socket$Phoenix_Socket$listen = F2( }); var _user$project$Main$playersListItem = function (player) { + var playerLink = A2( + _elm_lang$core$Basics_ops['++'], + 'players/', + _elm_lang$core$Basics$toString(player.id)); var displayName = _elm_lang$core$Native_Utils.eq(player.displayName, _elm_lang$core$Maybe$Nothing) ? player.username : A2(_elm_lang$core$Maybe$withDefault, '', player.displayName); return A2( _elm_lang$html$Html$li, @@ -15491,7 +15495,18 @@ var _user$project$Main$playersListItem = function (player) { {ctor: '[]'}, { ctor: '::', - _0: _elm_lang$html$Html$text(displayName), + _0: A2( + _elm_lang$html$Html$a, + { + ctor: '::', + _0: _elm_lang$html$Html_Attributes$href(playerLink), + _1: {ctor: '[]'} + }, + { + ctor: '::', + _0: _elm_lang$html$Html$text(displayName), + _1: {ctor: '[]'} + }), _1: {ctor: '[]'} }), _1: {