【发布时间】:2016-06-30 13:29:31
【问题描述】:
我最近使用seesaw 框架创建了一个小扫雷器UI,它基本上是一个漂亮的clojure 包装器。相关代码可以在here找到。
到目前为止,基本上一切正常,唯一的问题是当您选择专家级别的游戏时,用户体验非常糟糕。原因是每次单击单元格时都会重新绘制整个 ui,这需要很长时间(平均 850 毫秒)。
负责重绘的代码如下:
(defn- update-fields
[cell-states]
(doseq [[idx state] (map-indexed vector cell-states)
:let [field (select-field idx)]]
(config! field :icon (icons/cell-icons state))))
(defn- update-board
[snapshot face]
(do
(change-smiley face)
(update-fields (:cells snapshot))
(repaint! ui)))
图标处理的代码如下所示
(ns minesweeper.icons
(:require
[clojure.java.io :as io]
[clojure.string :as str]
[seesaw.icon :as icon]))
(def ^:private cell-icons-path "minesweeper/icons/cell")
(def ^:private face-icons-path "minesweeper/icons/face")
(defn- file-name
[file]
(str/replace-first
(.getName file) #"\.[^.]+$" ""))
(def ^:private init-icons
(memoize
(fn [res]
(let [parent (rest (file-seq (io/file (io/resource res))))]
(reduce
#(assoc %1 (keyword (file-name %2)) (icon/icon %2))
{}
parent)))))
(defn cell-icons
[id]
(let [icons (init-icons cell-icons-path)]
(get icons id)))
(defn face-icons
[id]
(let [icons (init-icons face-icons-path)]
(get icons id)))
所以我的问题是,如何更有效地解决这个问题?我考虑只更新受点击影响的单元格(由 JButton 表示),但如果自动清除会打开很多相邻的单元格,这也可能需要相当长的时间。
一般来说,使用带有按钮的 mig 布局来表示板子是合理的选择吗?
【问题讨论】:
-
据我所知,使用按钮的方法对于游戏开发来说并不常见。也许您应该尝试在 JPanel 的图形上绘制字段? stackoverflow.com/questions/6118737/…
-
听起来很合理,我只是想知道是否可以在某处配置一些缓冲以加快速度,或者图标处理是否错误。
-
您是否计算过 update-board 中这三个调用中的哪一个导致了延迟?如果重新绘制单个单元格“快速”,您可以重新组织代码以仅更新更改的单元格并在显示一个(或几个)单元格后重新绘制。然后,您可以玩弄以不同模式显示的单元格,例如螺旋,有序,对角线。
标签: swing user-interface clojure minesweeper seesaw