javafx框架tornadofx实战-益智游戏-找出指定的内容1

时间:2022-07-23
本文章向大家介绍javafx框架tornadofx实战-益智游戏-找出指定的内容1,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

布局与上一个案例舒尔特基本相似,来体验一下吧,代码也在同小异,直接上代码:

重要的事情说3遍: 动手敲代码!!!动手敲代码!!!动手敲代码!!!

class MainAPP : App(MainView::class)

class MainView : View("把指定的图片全都给我找出来") {
    private val c by inject<MainController>()
    lateinit var r: GridPane
    private val suerte = mutableListOf<String>()
    private val nproperty = intProperty(2)//行列数
    private val startTime = longProperty(0)//开始时间
    private val endTime = longProperty(0)//结束时间
    private val resultSize = intProperty()
    private val correctSize = intProperty()
    private val timeUsed = stringProperty(format(0))//使用时间
    private val aniTimer = AniTimer()
    private val isRun = booleanProperty(false)//标记aniTimer是否处于运行状态
    private val _fontSize = intProperty(32)
    private val originalContent = stringProperty("佩奇/${Random.nextInt(6)}.png")
    private val titles = observableListOf<String>()
    private val categories = observableListOf<String>()

    private val _title = stringProperty()
    private val titleMap = mutableMapOf<String, List<String>>()

    private val dirName = stringProperty("佩奇")

    init {
        loadJsonFile(File("./content.json").toPath())
    }

    /**
     * 加载项目根目录下的content.json文件,获取到的数据用于填充左侧的combobox和listview
     */
    fun loadJsonFile(path: Path) {
        categories.clear()
        loadJsonArray(path).forEach {
            val obj = it.asJsonObject()
            val titlee = obj.getString("title").trim()
            categories.add(titlee)
            titleMap[titlee] = obj.getString("content").split(",").map { category ->
                category.trim()
            }
        }
    }
top = vbox {
    hbox(10) {
        paddingAll = 10.0
        alignment = Pos.CENTER
        button("加载文件") {
            action {
                _chooseFile()
            }
        }
        combobox(_fontSize, (12..72 step 4).toList()) {
            _fontSize.onChange {
                refreshGrid()
            }
        }
        button("刷新") {
            action {
                refreshGrid()
            }
        }
        separator(Orientation.VERTICAL)
        button("导出") {
            action {
                (1..c.outNums.value).map { i ->
                    refreshGrid()
                    val img = r.snapshot(SnapshotParameters(), null)
                    ImageIO.write(SwingFXUtils.fromFXImage(img, null), "png", File(c.outPath.value + "./schulteGrid$i.png"))
                }

                information("恭喜!成功导出 ${c.outNums.value} 张舒尔特方格。")
            }
        }
        separator(Orientation.VERTICAL)
        togglegroup {
            selectedToggleProperty().onChange {
                val n = (it as RadioButton).text.toInt()
                nproperty.set(n)
                if (n > 1)
                    refreshGrid()
            }

            (2..8).forEach {
                radiobutton(it.toString()) {
                    if (it == 2) isSelected = true
                }
            }
        }
        separator(Orientation.VERTICAL)
        label(stringBinding(resultSize, correctSize) { "${correctSize.value}/${resultSize.value}" })
        separator(Orientation.VERTICAL)
        label(stringBinding(timeUsed) { "使用时间:$value" })
    }
}
 // 刷新网格,点击单选按钮、更换listview中的选项、选择不同的单选按钮时会调用此函数,来更新gridview中的数据
    private fun refreshGrid() {
        timeUsed.set(format(0))
        isRun.set(false)
        aniTimer.stop()

        r.clear()
        suerte.clear()
        resultSize.set(0)
        val n = nproperty.value
        val n2 = n * n

        c.dirFiles(File("./图片/${dirName.value}"))?.let { pics ->
            (1..n2).map {
                suerte.add(pics.random())
            }
        }
        originalContent.set(suerte.random())
        correctSize.set(suerte.filter { it == originalContent.value }.size)

        suerte.shuffle()    //将list中的元素打乱顺序
        val iter = suerte.iterator()
        val cellSize = r.prefHeight / n   //每个按钮大小

        try {
            (0 until n).map { i ->
                (0 until n).map { j ->
                    r.add(button {
                        val imgPath = iter.next()
                        graphic = imageview(File(imgPath).toURI().toURL().toExternalForm()).apply {
                            fitHeight = cellSize - 2
                            fitWidth = cellSize - 2
                            isCache = true
                        }
                        setPrefSize(cellSize, cellSize)
                        isWrapText = true

                        action {
                            if (imgPath == originalContent.value) {
                                resultSize.set(resultSize.value + 1)
                            }
                            if (resultSize < 2) {//当第一次点击时,开始计时
                                isRun.set(true)
                                startTime.set(System.currentTimeMillis())
                            }

                            if (isRun.value) {
                                aniTimer.start()
                            } else {
                                aniTimer.stop()
                            }

                            style {
                                backgroundColor += c("#99CC00")
                            }
                            if (correctSize.value == resultSize.value) {
                                isRun.set(false)
                                aniTimer.stop()
                                information("恭喜!成功完成本局")
                            }

                        }
                        style {
                            borderColor += box(c("red"))
                            borderWidth += box(1.px)
                        }
                    }, i, j)
                }
            }
        } catch (e: Exception) {
            return
        }
    }

    inner class AniTimer : AnimationTimer() {
        override fun handle(now: Long) {
            runLater {
                endTime.set(System.currentTimeMillis())
                val totalTime = endTime.value - startTime.value //总消耗时间
                timeUsed.set(format(totalTime))
            }
        }
    }
}