300行代码不到的tornadofx拼图游戏

1package com.cyy.game.pingtu 2 3import javafx.application.Application 4import javafx.beans.property.SimpleObjectProperty 5import javafx.event.EventHandler 6import javafx.geometry.Pos 7import javafx.geometry.Rectangle2D 8import javafx.scene.control.Alert 9import javafx.scene.control.RadioButton 10import javafx.scene.image.Image 11import javafx.scene.image.ImageView 12import javafx.scene.input.MouseEvent 13import javafx.scene.layout.GridPane 14import javafx.scene.layout.VBox 15import javafx.stage.FileChooser 16import tornadofx.* 17import java.io.File 18import java.util.* 19import kotlin.math.sqrt 20 21fun main(args: Array<String>) = Application.launch(PingTuApp::class.java, *args) 22 23class PingTuApp : App(PingTuView::class) 24 25class PingTuView : View("拼图") { 26 var N = intProperty(4) 27 var n = random(N.value - 1) //自定义的函数,产生逆序数为偶数的不重复数组 28 var m = findnum(n) //找出那个不在随机数组里面的数字 29 var imageViews = (1..N.value).map { ImageView() }.toTypedArray() 30 // 大图片路径 31 val imgPath = stringProperty("pingtu/1.png") 32 // 空图片路径 33 val imgBlankPath = "pingtu/2.png" 34 lateinit var rbox: VBox 35 lateinit var gridPane: GridPane 36 lateinit var bigImageView: ImageView 37 lateinit var smallImageView: ImageView 38 val bigImage = SimpleObjectProperty<Image>() 39 val smallImage = SimpleObjectProperty<Image>() 40 // 大图片宽度 41 val imageSize = 300.0 42 // 每个小方格宽度 43 var smallSize = imageSize / sqrt(N.value.toDouble()) 44 45 override val root = borderpane { 46 paddingAll = 10 47 prefHeight = 700.0 48 prefWidth = 1000.0 49 primaryStage.isResizable = false 50 top = hbox(10) { 51 alignment=Pos.CENTER 52 button("选择图片") { 53 action { 54 val imgType = listOf("*.jpg", "*.png", "*.bmp", "*.gif") 55 val efset = arrayOf(FileChooser.ExtensionFilter("$imgType", imgType)) 56 val imgFile = chooseFile("选择图片", efset, FileChooserMode.Single) { 57 // p初始目录为当前项目目录 58 initialDirectory = File(File("").canonicalPath) 59 } 60 if (imgFile.isNotEmpty()) { 61 val imgPath = imgFile.first().toString().replace("\\", "/") 62 bigImage.value = Image(File(imgPath).inputStream()) 63 imageViews=initImageViews1(N.value, imgPath) 64 initView(N.value, imgPath, smallSize,imageViews) 65 } 66 } 67 } 68 69 togglegroup { 70 listOf(4,9, 16, 25).map { v -> 71 radiobutton(v.toString(), this, v) { if (v === 4) isSelected = true } 72 } 73 selectedToggleProperty().addListener { _, _, _ -> 74 N.value = (selectedToggle as RadioButton).text.toInt() 75 smallSize = imageSize / sqrt(N.value.toDouble()) 76 } 77 } 78 79 button("重置") { 80 action { 81 bigImage.value = Image(imgPath.value) 82 83 imageViews =initImageViews(N.value,imgPath.value) 84 initView(N.value, imgPath.value, smallSize,imageViews) 85 } 86 } 87 paddingAll = 10 88 } 89 center = gridpane { 90 alignment=Pos.CENTER 91 92 gridPane = this 93 isGridLinesVisible = true 94 } 95 right = vbox(20) { 96 alignment=Pos.CENTER 97 98 rbox = this 99 //显示空格子的图片 100 imageview(smallImage) { 101 smallImageView = this 102 } 103 //完整的大图 104 imageview(bigImage) { 105 bigImageView = this 106 fitHeight = imageSize 107 fitWidth = imageSize 108 } 109 } 110 } 111 112 inner class Myevent : EventHandler<MouseEvent> { //点击事件的实现 113 override fun handle(arg0: MouseEvent) { 114 val img = arg0.source as ImageView 115 val sx = img.layoutX 116 val sy = img.layoutY 117 val dispx = sx - imageViews[m].layoutX 118 val dispy = sy - imageViews[m].layoutY 119 if (dispx == -smallSize && dispy == 0.0) { //点击的空格左边的格子 120 swapimg(img, imageViews[m]) //交换imageView 121 if (issucc(imageViews)) { //判断是否拼成功 122 val alert = Alert(Alert.AlertType.WARNING, "成功!") 123 alert.show() 124 } 125 } else if (dispx == 0.0 && dispy == -smallSize) { //上面的格子 126 swapimg(img, imageViews[m]) 127 if (issucc(imageViews)) { 128 val alert = Alert(Alert.AlertType.WARNING, "成功!") 129 alert.show() 130 } 131 } else if (dispx == smallSize && dispy == 0.0) { //右边的格子 132 swapimg(img, imageViews[m]) 133 if (issucc(imageViews)) { 134 val alert = Alert(Alert.AlertType.WARNING, "成功!") 135 alert.show() 136 } 137 } else if (dispx == 0.0 && dispy == smallSize) { //下面的格子 138 swapimg(img, imageViews[m]) 139 if (issucc(imageViews)) { 140 val alert = Alert(Alert.AlertType.WARNING, "成功!") 141 alert.show() 142 } 143 } 144 } 145 146 fun swapimg(i1: ImageView, i2: ImageView) { //交换两个imageView的实现 147 val row1 = GridPane.getRowIndex(i1) 148 val colu1 = GridPane.getColumnIndex(i1) 149 val row2 = GridPane.getRowIndex(i2) 150 val colu2 = GridPane.getColumnIndex(i2) 151 152 GridPane.setRowIndex(i1, row2) 153 GridPane.setColumnIndex(i1, colu2) 154 GridPane.setRowIndex(i2, row1) 155 GridPane.setColumnIndex(i2, colu1) 156 } 157 } 158 159 init { 160 imageViews =initImageViews(N.value,imgPath.value) 161 initView(N.value, imgPath.value, smallSize,imageViews) 162 } 163 164 // nn : 9,16,25 165 fun initView(nn: Int, imgPath: String, smallSize: Double,imageViews:Array<ImageView>) { 166 n = random(nn) //自定义的函数,产生逆序数为偶数的不重复数组 167 m = findnum(n) //找出那个不在随机数组里面的数字 168 gridPane.clear() 169 // nn1 =3,4,5 170 val nn1 = sqrt(nn.toDouble()).toInt() 171 var i = 0 172 var k = 0 173 while (i <= nn1 - 1) { 174 var j = 0 175 while (j <= nn1 - 1) { 176 //切割图片 177 imageViews[k].viewport = Rectangle2D(smallSize * j, smallSize * i, smallSize, smallSize) 178 ++j 179 ++k 180 } 181 ++i 182 } 183 184 // nn1-1=2,3,4 185 var t = 0 186 (0 until nn1).forEach { r -> 187 (0 until nn1).forEach { c -> 188 if (t < nn - 1) { 189 gridPane.add(imageViews[n[t]], c, r) 190 } 191 ++t 192 } 193 } 194 195 smallImage.value = imageViews[m].image 196 smallImageView.viewport = imageViews[m].viewport 197 198 imageViews[m].image = Image(imgBlankPath) //2.png为一个透明图,放在空格子中 199 gridPane.add(imageViews[m], nn1 - 1, nn1 - 1) 200 } 201 202 //读取类路径下的图片 203 fun initImageViews(nn: Int, imgPath: String):Array<ImageView>{ 204 return (1..nn).map { 205 imageview(imgPath) { 206 onMouseClicked = Myevent() 207 } 208 }.toTypedArray() 209 } 210 //读取电脑文件系统中图片文件的路径 211 fun initImageViews1(nn: Int, imgPath: String):Array<ImageView>{ 212 return (1..nn).map { 213 imageview(Image(File(imgPath).inputStream())) { 214 onMouseClicked = Myevent() 215 } 216 }.toTypedArray() 217 } 218 219 //判断是否拼成功 220 fun issucc(imageViews: Array<ImageView>): Boolean { 221 val t = imageViews.size 222 imageViews.indices.forEach { i -> 223 if (i != sqrt(t.toDouble()).toInt() * GridPane.getRowIndex(imageViews[i]) + GridPane.getColumnIndex(imageViews[i])) { 224 return false 225 } 226 } 227 return true 228 } 229 230 fun findnum(n: IntArray): Int { 231 (n.indices).forEach { j -> 232 if (j in n) { 233 } else { 234 return j 235 } 236 } 237 238 return -1 239 } 240 241 //生成nn个不重复的逆序数为偶数的数字 242 fun random(nn: Int): IntArray { 243 var ran = IntArray(nn) 244 while (!iso(ran)) { 245 ran = random_num(nn) 246 } 247 return ran 248 } 249 250 //生成nn个不重复数 251 fun random_num(nn: Int): IntArray { 252 val r = IntArray(nn) 253 val random = Random() 254 var i = 0 255 while (i < nn - 1) { 256 r[i] = random.nextInt(nn) 257 for (j in 0 until i) { 258 while (r[i] == r[j]) { 259 i-- 260 break 261 } 262 } 263 ++i 264 } 265 return r 266 } 267 268 //判断逆序数是否为偶数 269 fun iso(num: IntArray): Boolean { 270 var sum = 0 271 val t = num.size 272 for (i in 0..t - 2) { 273 for (j in i..t - 1) { 274 if (num[i] > num[j]) { 275 sum++ 276 } 277 } 278 } 279 return sum % 2 == 0 && sum != 0 280 } 281}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

300行代码不到的tornadofx拼图游戏 - HelloWorld