Как сделать коллаж (с большим количеством контейнеров) более отзывчивым в Elm?

Я пишу roguelike в Elm, где есть дискретная сетка 50x50 (см. Фрагмент share-elm.com). Roguelike - это видеоигра, в которой объекты (например, враги, предметы, стены и т. Д.) Представлены символами ASCII. Поэтому я должен иметь возможность иметь сотни различных символов ASCII, выровненных по прямоугольной сетке. Каждый персонаж должен находиться строго внутри своей ячейки сетки.

Чтобы создать эту сетку, я поместил каждого персонажа в квадрат container(1/50 размера фактического игрового контейнера). Это означает, что я могу иметь максимум 2500 контейнеров в игре. Вяз создает <div> элементы для контейнеров, даже если я преобразую эти контейнеры в Form и положить их в collage, Это делает мой Firefox 39.0 очень медленным по производительности.

Как создать прямоугольную сетку с хорошо выровненными символами ASCII (и, возможно, некоторыми другими графическими элементами) внутри ее ячеек сетки, чтобы коллаж все равно оставался быстрым и отзывчивым, независимо от того, сколько элементов у меня есть одновременно? И каков общий идиоматический подход каждый раз, когда я пишу программу с множеством контейнеров и других элементов внутри коллажа? Или, может быть, есть совершенно другой подход к созданию быстрых прямоугольных сеток в Elm?

2 ответа

То, что вы ищете здесь Graphics.Collage.text, Когда вы включаете Element в Form Вяза будут придерживаться общего подхода, который может поставить любой Element как Form, но на самом деле это не рисует его на холсте. (Yay, детали реализации). Если вместо этого вы идете прямо из Text в Form Статически известно, что это текст, поэтому можно использовать более быстрый метод рисования текста на холсте. Это простое изменение:

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

Вместо трех строк в комментариях, это просто C.text, Вы можете увидеть отзывчивость в обновленном фрагменте общего ресурса.
Обратите внимание, что вы больше не можете выделять текст! Но в остальном все должно быть намного лучше.

Одна возможность (если вы не против написания HTML вместо использования collage / container) будет использовать Html.Lazy модуль. Вы можете, например, обернуть рендеринг каждой "строки" дисплея в lazy и это только переопределяет измененные строки (которые должны быть только 1-2 за шаг / перемещение).

Другие вопросы по тегам