How do I make a collage (with more containers) more responsive in Elm?

I am writing a roguelike in Elm which has a 50x50 discrete grid (see share-elm.com snippet ). Rogue-like is a video game where objects (eg enemies, objects, walls, etc.) are represented by ASCII characters. So I must have hundreds of different ASCII characters aligned in a rectangular grid. Each character must be strictly inside the grid cell.

To create this grid, I place each character in a square container

(the size of 1/6 of a real game container). This means that I can have a maximum of 2500 containers per game. Elm creates items <div>

for containers even if I convert those containers to Form

and put them inside collage

. This makes my Firefox 39.0 very slow in performance.

How do I create a rectangular grid with well-aligned ASCII characters (and possibly some other graphic elements) inside my grid cells so that no matter how many elements I have at the same time, the collage is still fast and responsive? And what is the general idiomatic approach every time I write a program with a lot of containers and other elements inside the collage? Or maybe there is a completely different approach to creating fast rectangular grids in Elm?

+3


source to share


2 answers


One possibility (if you don't mind writing HTML instead of using collage

/ container

) should be used Html.Lazy

. You could, for example, wrap the rendering of each "line" of the display in lazy

and it will only redraw the lines that have changed (it should only be 1-2 per time / movement).



+1


source


What are you looking for here Graphics.Collage.text

. When you turn Element

into Form

, Elm will take a generic approach that anyone can place Element

like a Form

, but it didn't actually draw it to the canvas. (Yay, implementation details). If you instead navigate from Text

to Form

, then it is statically known to be text, so a faster method of drawing text to the canvas can be used. This is a simple change:

view : (Int, Int) -> Element
view (w,h) =
  let
    s = min w h -- collageSize
    forms = List.map (\(x,y) -> move (s,s) (x,y) playerForm)
               <| cartesian 0 (screenSize-1) 0 (screenSize-1)
    playerForm = "@"
               |> Text.fromString
               |> Text.height ((toFloat s) / screenSize)
               |> C.text
             --  |> E.centered
             --  |> E.container (s//screenSize) (s//screenSize) E.middle
             --  |> C.toForm
  in
    E.color Color.lightGray
       <| E.container w h E.middle
            <| E.color Color.white
                 <| C.collage s s forms

      



Instead of three lines in comments, it's easy C.text

. You can see the responsiveness in the updated share-elm snippet .
Please note that you can no longer select text! But if not, it should be much better.

+1


source







All Articles