前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >来玩玩打地鼠游戏,300行代码不到

来玩玩打地鼠游戏,300行代码不到

原创
作者头像
用户6167008
修改2019-09-26 17:52:10
1.8K0
修改2019-09-26 17:52:10
举报
文章被收录于专栏:javafx框架tornadofx

所用到的图片:

图1代码:

代码语言:txt
复制
import javafx.animation.KeyFrame
import javafx.animation.Timeline
import javafx.event.ActionEvent
import javafx.event.EventHandler
import javafx.geometry.Pos
import javafx.scene.effect.DropShadow
import javafx.scene.image.Image
import javafx.scene.image.ImageView
import javafx.scene.layout.*
import javafx.scene.layout.BorderPane.setAlignment
import javafx.scene.paint.Color
import javafx.scene.paint.Color.rgb
import javafx.scene.shape.Line
import javafx.scene.text.Font
import javafx.scene.text.FontPosture
import javafx.scene.text.FontWeight
import javafx.util.Duration
import tornadofx.*

class MyMoleApp : App(MyMole::class) {
    override fun stop() {
        find<StartGame>().replaceWith<MyMole>()
        super.stop()
    }
}

class MyMole : View("打地鼠") {
    override val root = borderpane {
        setPrefSize(1000.0, 768.0)
        val back = BackgroundImage(Image("whacAMole/mole.jpg", 1024.0, 768.0, false, true),
                BackgroundRepeat.REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT, BackgroundSize.DEFAULT)
        background = Background(back)
        top = label("Whac A Mole") {
            font = Font.font("Showcard Gothic", FontWeight.EXTRA_BOLD, FontPosture.REGULAR, 100.0)
            textFill = rgb(150, 46, 5)
            style = "-fx-text-border-color:rgb(138,95,69);"
            alignment = Pos.BASELINE_CENTER
        }
        setAlignment(top, Pos.CENTER)
        center = gridpane {
            vgap = 5.0
            hgap = 5.0
            alignment = Pos.CENTER

            button("Start") {
                background = null
                textFill = rgb(195, 46, 5)
                font = Font.font("Bauhaus 93", FontWeight.EXTRA_BOLD, FontPosture.ITALIC, 90.0)
                setOnMouseEntered {
                    effect = DropShadow()
                }
                setOnMouseExited {
                    effect = null
                }
                action {
                    replaceWith(StartGame::class)
                }
            }
        }
    }
}

class StartGame : View("打地鼠") {
    private var count = 0  // 打中地鼠数量
    private val tfCount = intProperty()  //显示打中地鼠数量
    private val msg = stringProperty()
    private var hammerView by singleAssign<ImageView>()
    private var ifHit = true //判断是否可以打地鼠,true时能击打
    private var pause = false
    val x1 = 256.0
    val y1 = 192.0
    val xx = 256.0
    val yy = 160.0 //第一个地洞位置及间隔
    //地鼠图像
    private val mouseList = (0..2).map {
        imageview("whacAMole/mouse$it.png") {
            fitWidth = 120.0
            fitHeight = 210.0
            x = x1 - 70
            y = y1 - 90
        }
    }

    override val root = pane {
        val pane1 = this
        setPrefSize(1024.0, 768.0)
        val eventHandler = EventHandler<ActionEvent> {
            //地鼠运动
            val lineList = (0..2).map { MouseAppear() }
            lineList.forEach { pane1.add(it) }

            var i = 0
            mouseList.forEach {
                //地鼠渐变
                it.fade(Duration.millis(4000.0 + i * 1000), 0) {
                    fromValue = 1.0
                    toValue = 0.1
                    cycleCount = 1
                }
                //地鼠运动
                it.follow(Duration.millis(400.0 + i * 200), lineList[i]) {
                    cycleCount = 2
                    isAutoReverse = true
                }

                i++
            }
            //置为能打
            ifHit=true
            // 锤子打下去、抬起来效果
            pane1.setOnMouseReleased { e1 ->
                hammerView.rotateProperty().animate(endValue = 0.0, duration = 0.1.seconds)
            }
            //打中地鼠记录次数 鼠标事件
            pane1.setOnMousePressed { e1 ->
                hammerView.rotateProperty().animate(endValue = -40.0, duration = 0.1.seconds)

                var i = 0
                lineList.forEach {
                    if (e1.x < it.endX + 80 && e1.x > it.endX - 80 && ifHit
                            && e1.y < it.startY + 110 && e1.y > it.endY - 110) {
                        count++

                        //文本框输出
                        tfCount.value = count
                        ifHit = false  //置为不能打
                    }
                    i++
                }
            }
        }

        //动画
        val animation = Timeline(KeyFrame(Duration.millis(1300.0), eventHandler)) //地鼠速度
        animation.cycleCount = 30  //地鼠钻出次数
        animation.play()
        //地洞图像
        imageview("whacAMole/mole.jpg") {
            fitWidth = 1024.0
            fitHeight = 768.0
        }
        hbox(20.0) {
            addStylesheet(MyStyle::class)
            alignment = Pos.BOTTOM_CENTER
            //重新开始按钮
            button("Quit") {
                background = null
                setOnMouseEntered {
                    effect = DropShadow()
                }
                setOnMouseExited {
                    effect = null
                }
                action {
                    animation.stop()
                    //animation1.stop();
                    count = 0
                    tfCount.value = 0
                    msg.value = ""
                    replaceWith(MyMole::class)
                }
            }
            //暂停按钮
            button("Pause/Continue") {
                background = null
                setOnMouseEntered {
                    effect = DropShadow()
                }
                setOnMouseExited {
                    effect = null
                }
                action {
                    if (!pause) {
                        animation.pause()
                        pause = true
                    } else {
                        animation.play()
                        pause = false
                    }
                }
            }
            textfield(tfCount) {
                setPrefSize(200.0, 40.0)
                style = "-fx-text-fill:rgb(195,46,5);"
                background = null
                font = Font.font("Bauhaus 93", FontWeight.EXTRA_BOLD, FontPosture.ITALIC, 80.0)
            }
        }
        text(msg) {
            fill = rgb(222, 87, 61)
            font = Font.font("Kristen ITC", FontWeight.BOLD, FontPosture.ITALIC, 45.0)
            x = 280.0
            y = 700.0
        }
        mouseList.forEach {
            add(it)
        }
        //锤子图像
        imageview("whacAMole/hammer.png") {
            hammerView = this
            fitWidth = 160.0
            fitHeight = 200.0
        }
        //事件源必须设在pane上,不能设在图片上,否则鼠标要放在图片上才能动
        setOnMouseMoved { e ->
            hammerView.x = e.x - 60
            hammerView.y = e.y - 80
        }
    }

    private fun MouseAppear(): Line {
        val ran = (Math.random() * 10.0 * 0.9).toInt()
        var x0 = x1
        var y0 = y1
        when (ran) {
            0 -> {
                x0 = x1
                y0 = y1
            }
            1 -> {
                x0 = x1 + xx - 20
                y0 = y1
            }
            2 -> {
                x0 = x1 + xx * 2 - 20
                y0 = y1
            }
            3 -> {
                x0 = x1 - 50
                y0 = y1 + yy - 15
            }
            4 -> {
                x0 = x1 + xx - 20
                y0 = y1 + yy
            }
            5 -> {
                x0 = x1 + xx * 2 - 20
                y0 = y1 + yy
            }
            6 -> {
                x0 = x1 - 60
                y0 = y1 + yy * 2 - 10
            }
            7 -> {
                x0 = x1 + xx - 20
                y0 = y1 + yy * 2
            }
            8 -> {
                x0 = x1 + xx * 2
                y0 = y1 + yy * 2
            }
        }
        val line = Line(x0, y0 + 30, x0, y0 - 50)
        line.stroke = Color.TRANSPARENT
        return line
    }
}

class MyStyle : Stylesheet() {
    init {
        button {
            textFill = rgb(195, 46, 150)
            prefWidth = 400.px
            prefHeight = 80.px
            font = Font.font("Showcard Gothic", FontWeight.EXTRA_BOLD, FontPosture.ITALIC, 30.0)
        }
    }
}

图2代码:

代码语言:txt
复制
import javafx.animation.KeyFrame
import javafx.animation.Timeline
import javafx.event.ActionEvent
import javafx.event.EventHandler
import javafx.geometry.Pos
import javafx.scene.effect.DropShadow
import javafx.scene.image.ImageView
import javafx.scene.paint.Color
import javafx.scene.shape.Line
import javafx.scene.text.Font
import javafx.scene.text.FontPosture
import javafx.scene.text.FontWeight
import javafx.util.Duration
import tornadofx.*
class MyMoleApp1 : App(StartGame1::class)
class StartGame1 : View("打地鼠") {
    private var count = 0  // 打中地鼠数量
    private val tfCount = intProperty()  //显示打中地鼠数量
    private val msg = stringProperty()
    private var hammerView by singleAssign<ImageView>()
    private var ifHit = true //判断是否可以打地鼠,true时能击打
    private var pause = false
    val x1 = 256.0
    val y1 = 192.0
    val xx = 256.0
    val yy = 160.0 //第一个地洞位置及间隔
    //地鼠图像
    private val mouseList = (0..2).map {
        imageview("whacAMole/mouse$it.png") {
            fitWidth = 120.0
            fitHeight = 110.0
            x = x1 - 70
            y = y1 -30
        }
    }

    override val root = stackpane {
        setPrefSize(1024.0, 768.0)
        imageview("whacAMole/mole.jpg") {
            fitWidth = 1024.0
            fitHeight = 768.0
        }
        pane {
            val pane1 = this
            setPrefSize(1024.0, 768.0)
            val eventHandler = EventHandler<ActionEvent> {
                //地鼠运动
                val lineList = (0..2).map { MouseAppear() }
                lineList.forEach { pane1.add(it) }

                var i = 0
                mouseList.forEach {
                    //地鼠渐变
                    it.fade(Duration.millis(4000.0 + i * 1000), 0) {
                        fromValue = 1.0
                        toValue = 0.1
                        cycleCount = 1
                    }
                    //地鼠运动
                    it.follow(Duration.millis(400.0 + i * 200), lineList[i]) {
                        cycleCount = 2
                        isAutoReverse = true
                    }

                    i++
                }
                //置为能打
                ifHit = true
                // 锤子打下去、抬起来效果
                pane1.setOnMouseReleased { e1 ->
                    hammerView.rotateProperty().animate(endValue = 0.0, duration = 0.1.seconds)
                }
                //打中地鼠记录次数 鼠标事件
                pane1.setOnMousePressed { e1 ->
                    hammerView.rotateProperty().animate(endValue = -40.0, duration = 0.1.seconds)

                    var i = 0
                    lineList.forEach {
                        if (e1.x < it.endX + 80 && e1.x > it.endX - 80 && ifHit
                                && e1.y < it.startY + 110 && e1.y > it.endY - 110) {
                            count++

                            //文本框输出
                            tfCount.value = count
                            ifHit = false  //置为不能打
                        }
                        i++
                    }
                }
            }

            //动画
            val animation = Timeline(KeyFrame(Duration.millis(1300.0), eventHandler)) //地鼠速度
            animation.cycleCount = 30  //地鼠钻出次数
            animation.play()
            //地洞图像
            mouseList.forEach {
                add(it)
            }

            imageview("whacAMole/mask.png")
            //锤子图像
            imageview("whacAMole/hammer.png") {
                hammerView = this
                fitWidth = 160.0
                fitHeight = 200.0
            }
            //事件源必须设在pane上,不能设在图片上,否则鼠标要放在图片上才能动
            setOnMouseMoved { e ->
                hammerView.x = e.x - 60
                hammerView.y = e.y - 80
            }
            hbox(20.0) {
                addStylesheet(MyStyle::class)
                alignment = Pos.BOTTOM_CENTER
                //重新开始按钮
                button("Quit") {
                    background = null
                    setOnMouseEntered {
                        effect = DropShadow()
                    }
                    setOnMouseExited {
                        effect = null
                    }
                    action {
                        animation.stop()
                        //animation1.stop();
                        count = 0
                        tfCount.value = 0
                        msg.value = ""
                        replaceWith(MyMole::class)
                    }
                }
                //暂停按钮
                button("Pause/Continue") {
                    background = null
                    setOnMouseEntered {
                        effect = DropShadow()
                    }
                    setOnMouseExited {
                        effect = null
                    }
                    action {
                        if (!pause) {
                            animation.pause()
                            pause = true
                        } else {
                            animation.play()
                            pause = false
                        }
                    }
                }
                textfield(tfCount) {
                    setPrefSize(200.0, 40.0)
                    style = "-fx-text-fill:rgb(195,46,5);"
                    background = null
                    font = Font.font("Bauhaus 93", FontWeight.EXTRA_BOLD, FontPosture.ITALIC, 80.0)
                }
            }
            text(msg) {
                fill = Color.rgb(222, 87, 61)
                font = Font.font("Kristen ITC", FontWeight.BOLD, FontPosture.ITALIC, 45.0)
                x = 280.0
                y = 700.0
            }


        }
    }

    private fun MouseAppear(): Line {
        val ran = (Math.random() * 10.0 * 0.9).toInt()
        var x0 = x1
        var y0 = y1
        val offset=150
        when (ran) {
            0 -> {
                x0 = x1
                y0 = y1+offset
            }
            1 -> {
                x0 = x1 + xx - 20
                y0 = y1+offset
            }
            2 -> {
                x0 = x1 + xx * 2 - 20
                y0 = y1+offset
            }
            3 -> {
                x0 = x1 - 50
                y0 = y1 + yy - 15+offset
            }
            4 -> {
                x0 = x1 + xx - 20
                y0 = y1 + yy+offset
            }
            5 -> {
                x0 = x1 + xx * 2 - 20
                y0 = y1 + yy+offset
            }
            6 -> {
                x0 = x1 - 60
                y0 = y1 + yy * 2 - 10+offset
            }
            7 -> {
                x0 = x1 + xx - 20
                y0 = y1 + yy * 2+offset
            }
            8 -> {
                x0 = x1 + xx * 2
                y0 = y1 + yy * 2+offset
            }
        }
        val line = Line(x0, y0 + 30, x0, y0 - 50)
        line.stroke = Color.TRANSPARENT
        return line
    }
}

class MyStyle1 : Stylesheet() {
    init {
        Companion.button {
            textFill = Color.rgb(195, 46, 150)
            prefWidth = 400.px
            prefHeight = 80.px
            font = Font.font("Showcard Gothic", FontWeight.EXTRA_BOLD, FontPosture.ITALIC, 30.0)
        }
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档