Recommended way to render a board game in 0.17

245 views
Skip to first unread message

Shump

unread,
Jun 9, 2016, 7:43:16 AM6/9/16
to Elm Discuss
Hi all!

Playing around with Elm for the first time since the release of 0.17. I'm trying to build a simple board game and I'm currently looking into a way to render the game.

I'm looking into the elm-graphics library since that seems more suitable for a game rather then doing it with html. But I have two problems with it:

1) What are the correct way of using Form and Element? in terms of a board game, should each tile be a Form, composed together with transforms and grouped to create a single element for the whole board, or, create a Element per tile and use functions such as flow to build up the board? Bonus points for anyone who can explain the technical details between the two approaches.

2) How can I register click events for individual tiles? Are there an easier way than using the elm-lang/mouse library which uses coordinates relative to the document?

Especially the second problem is of great concern to me. If there is no easier way other than using the mentioned mouse library, I think I will do the rendering with the html library, even though it doesn't seem like the right tool for the job.

Hope you can help clearing up these questions for me!

Thanks!

Janis Voigtländer

unread,
Jun 9, 2016, 8:53:02 AM6/9/16
to elm-d...@googlegroups.com

Ad 1), I think that creating one Element as a collage of many moved Forms is the better approach than creating many Elements and flowing them together. I don’t have a deep technical reason for that at hand, though.

Ad 2), you can get click coordinates relative to a single element (your game board) rather than relative to the whole document. Here is an example:

import Html exposing (..)
import Html.Events exposing (on)
import Html.App exposing (beginnerProgram)
import Collage exposing (collage, filled, circle)
import Color exposing (red)
import Element
import Json.Decode exposing (Decoder, (:=))

main =
    beginnerProgram
        { model = Nothing
        , view = view
        , update = \msg _ -> msg
        }

view model =
    div []
        [ Html.text (toString model)
        , div [ on "click" (Json.Decode.map Just offsetPosition) ]
            [ Element.toHtml (collage 100 100 [ filled red (circle 30) ]) ]
        ]

offsetPosition : Decoder ( Int, Int )
offsetPosition =
    Json.Decode.object2 (,)
        ("offsetX" := Json.Decode.int)
        ("offsetY" := Json.Decode.int)

Try it out and note how when you click on the canvas element, you get displayed coordinates relevant to just that canvas element, not relative to the whole document.


--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dave Compton

unread,
Jun 10, 2016, 6:25:17 PM6/10/16
to Elm Discuss
You might want to consider using SVG.

SVG gives you the ability to attach events for individual graphics components which you can arrange however you want.

SVG also gives you the option of creating a group of entities which you can display multiple times at different positions.  In your case, this might be useful if you have identical tiles that you are displaying.

Here is a modified version of the collage example that uses SVG to show three selectable circles:

import Html exposing (div)
import Html.App exposing (beginnerProgram)
import List exposing (map)
import Svg exposing (svg)
import Svg.Events exposing (onClick)
import Svg.Attributes exposing (width, height, r, cx, cy, fill)



main
=
    beginnerProgram
       
{ model = Nothing
       
, view = view
       
, update = \msg _ -> msg
       
}



svgCircle
(xCenter, yCenter) =
   
Svg.circle [ r "15"
               
, fill "red"
               
, cy (toString xCenter)
               
, cx (toString yCenter)
               
, onClick (Just (xCenter, yCenter) )
               
] []



view model
=
    div
[]
       
[ Html.text (toString model)

       
, div []
             
[ svg [ width "100" , height "100" ]
                   
(map svgCircle [ (30, 30) , (70, 30) , (50, 60) ])
             
]
       
]


Julian

unread,
Jun 10, 2016, 11:46:52 PM6/10/16
to elm-d...@googlegroups.com
Thank you both for the examples!

I'll try both approaches and see what suits best for me.

Thanks again for the answers!

--
You received this message because you are subscribed to a topic in the Google Groups "Elm Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elm-discuss/OBPKMzNCWlY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elm-discuss...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages