Как сделать коллаж (с большим количеством контейнеров) более отзывчивым в 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 за шаг / перемещение).