新手QML贪吃蛇 Qt Quick

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5



ApplicationWindow {
    id:window

    property int speech: 600
    property int movestate: 1//防止出现控制方向与行动方向相反的情况
    property var snakeBodylength: -1
    property var snakeBody: []//存储蛇身
    property var keydirection: 1//键盘控制方向
    property var n: 0//自定义一把锁


    minimumWidth:600
    minimumHeight: 460
    maximumWidth:600
    maximumHeight: 460
    visible: true
    title: qsTr("This snake is going to eat chickens")

    background: Rectangle
    {
        color:"#E0EEE0"
    }


    function creatObj(){
        snakeBodylength++;
        var obj = creat.createObject(window,{})//新对象的父对象window
        return obj
    }
    Component{//有了Component,就可以调用其createObject()方法来创建该组件的实例
        id:creat
        Rectangle{
            id:test
            height: 20
            width: 20
            color: "black"
        }
    }

    Rectangle{
        id:border
        x:20
        y:20
        width: 400
        height: 400
        border.color: "#6E8B3D"
        border.width: 1
    }
    Button {//暂停按钮
        id: stop
        x: 467
        y: 50
        width:100
        height: 50
        text: qsTr("stop")
        font.pixelSize: 16
        background:Rectangle{
            color:"#F0E68C"
            radius: 6
        }
        onClicked:{
          timer.running = false
        }
    }


    Button {//一键重新开始按钮
        id:start
        x: 467
        y: 150
        width:100
        height: 50
        text: qsTr("start")
        font.pixelSize: 16
        background:Rectangle{
            color:"#BFEFFF"
            radius: 6
        }
        onClicked:{
            keydirection = 1
            movestate = 1
            snake.x = 200
            snake.y = 200
            snake.focus = true
            score.text = 0
            for(snakeBodylength;snakeBodylength>=0;snakeBodylength--)
                 snakeBody.pop().destroy()
            timer.running = true
            newchicken()
            }

    }
    Rectangle{
        id:sn
        x:430
        y:310
        scale:1.2
        Image{
            source: 'tp/snake.png'
        }
    }
    Rectangle{
        id:ch1
        x:500
        y:17
        scale: 0.15
        Image{
            source: 'tp/chicken.png'
        }
    }
    Rectangle{
        id:ch2
        x:500
        y:117
        scale: 0.31
        Image{
            source: 'tp/chicken1.png'
        }
    }

    Text {
        id: scoretip
        x: 469
        y: 260
        width: 42
        height: 27
        text: qsTr("score:")
        font.pixelSize: 20
        color:"#EE9A00"
    }

    Text {//分数显示
        id: score
        x: 535
        y: 255
        width: 56
        height: 27
        text: qsTr("0")
        color:"#CD7054"
        font.pointSize: 20
    }

    Dialog{
        id:out_mesDialog
        title:"terrible new: You are out of bounds."
        x:100
        y:200
        width: 300
        height: 100
        background: Rectangle{
        border.color: "#ADD8E6"
        }
        Label{
            x:20
            y:0
            text:"grade:"
            font.pointSize: 20
        }
        Label{
            x:105
            y:0
            text:score.text
            font.pointSize: 20
        }
    }
    Dialog{
        id:self_mesDialog
        title:"terrible new: You bumped into yourself."
        x:100
        y:200
        background: Rectangle{
        border.color: "#ADD8E6"
        }
    }
    Dialog{
        id:win_mesDialog
        title:"good new: You win!!!!"
        x:100
        y:200
        background: Rectangle{
        border.color: "#ADD8E6"
        }
    }
    Rectangle{
        id:yanhua
        visible: false
        z:1//置位上
        AnimatedImage
        {
        id: animation
        source: 'tp/yanhua.gif'
        }
    }


    //chicken
    Rectangle{

        id:chicken
        width: 20
        height: 20
        radius: 20
        //initial position
        x:(Math.round(Math.random()*19)+1)*20//(1~20)*20即在20到400间取随机值
        y:(Math.round(Math.random()*19)+1)*20
        color: Qt.rgba(Math.random(),Math.random(),Math.random(),1)//rgba红黄蓝三色比例产生随机颜色,以及透明度

    }

    Rectangle {
        id:snake
             property var keydirection: 1//键盘控制方向
            // 初始化蛇
            x:200
            y:200
            z:2//置位上层
            width: 20
            height: 20
            color: "black"
            focus:true
            Keys.onPressed: {
                switch(event.key){
                case Qt.Key_Left:
                    keydirection = 1
                    if(!timer.running){
                        timer.running = true//如果暂停了按键继续游戏
                    }
                    break
                case Qt.Key_Right:
                    keydirection = 2
                    if(!timer.running){
                        timer.running = true
                    }
                    break
                case Qt.Key_Up:
                    keydirection = 3
                    if(!timer.running){
                        timer.running = true
                    }
                    break
                case Qt.Key_Down:
                    keydirection = 4
                    if(!timer.running){
                        timer.running = true
                    }
                    break
                  default:
                      keydirection = 0 //无意义按键
                      if(timer.running){
                          timer.running = false//按键错误时会暂停游戏
                      }
                }
                //event.accepted = true//应该被设置为 true 以免它被继续传递
            }

    }


    Timer{
         id:timer
         interval:speech
         repeat:true
         running:true//设置启动,true为启动
         onTriggered:{//触发,发出信号
            move()
//             console.log("snake.x="+snake.x)
//             console.log("snake.y="+snake.y)
//             console.log("keydirection="+snake.keydirection)
//             console.log("snakeBody[0].x="+snakeBody[0].x)
//             console.log("snakeBody[0].y="+snakeBody[0].y)
//复制用作调试代码
         }
     }

    function newchicken(){//刷新小鸡的函数
        for(var q=0;q<=snakeBodylength;q++){
        while((chicken.x===snakeBody[q].x&&chicken.y===snakeBody[q].y)//为了小鸡刷新的位置不在蛇身体的位置
              ||(chicken.x===snake.x&&chicken.y===snake.y)){
            chicken.x = (Math.round(Math.random()*19)+1)*20
            chicken.y = (Math.round(Math.random()*19)+1)*20
        }
        chicken.color = Qt.rgba(Math.random(),Math.random(),Math.random(),1)

//        此种方法考虑不完全,淘汰
//        chicken.x = (Math.round(Math.random()*19)+1)*20
//        chicken.y = (Math.round(Math.random()*19)+1)*20
//        for(var q=snakeBodylength;q>=0;q--){//为了小鸡刷新的位置不在蛇身体的位置
//            if(chicken.x!=snakeBody[q].x&&chicken.y!=snakeBody[q].y){
//                if(snake.x!=chicken.x&&snake.y!=chicken.y){
//                    chicken.color = Qt.rgba(Math.random(),Math.random(),Math.random(),1)
//                }
//            }
        }

    }

    function collid(item1,item2){//实现碰撞
        if((item1.x <= item2.x)&&(item1.x >= item2.x)){
           if((item1.y <= item2.y)&&(item1.y >= item2.y)){
               return true;//小鸡和蛇碰撞返回值为true
           }else
               return false;
        }else
            return false
    }

    function snakeBodyMove(){//蛇在未碰撞情况下蛇身体自由移动
        if (snakeBodylength>=0){
            for(var i=snakeBodylength;i>0;i--){

                snakeBody[i].x = snakeBody[i-1].x
                snakeBody[i].y = snakeBody[i-1].y
            }
            snakeBody[0].x = snake.x
            snakeBody[0].y = snake.y
        }
    }

    function eat(){


//出界,不适合于沿着边缘移动的情况
//        if((snake.x==20&&snake.keydirection==1)||(snake.x==400&&snake.keydirection==4)
//                ||(snake.y==20&&snake.keydirection==3)||(snake.y==400&&snake.keydirection==4)){
//            timer.running = false
//            out_mesDialog.open()
//        }
//出界,不美观会在出界后才提示
//        if(snake.x>420 || snake.y>420 ||snake.x<20 || snake.y<20){
//            timer.running = false
//            out_mesDialog.open()
//             }
        if(collid(snake,chicken)){//蛇吃到彩色小鸡时
            speech -= 20
            if(speech == 60){//检查是否提升速度,提升游戏等级--------------------------------------
                timer.running = false
                win_mesDialog.open()
                yanhua.visible = true
            }
            snakeBody.push(creatObj())//加入一个新身体
            snakeBody[snakeBodylength].x = snake.x
            snakeBody[snakeBodylength].y = snake.y
            newchicken()
            score.text++
            n++/*锁:蛇吃到彩色小鸡就变成1
                 制锁的原因:
                          1.在蛇吃到彩色小鸡的瞬间会有snakeBody[snakeBodylength]与蛇头坐标重合
                          2.蛇头由于操作不当撞到蛇身
                              两种情况均会触发自撞,为排除第一种影响因素*/

        }
        //自撞
        if(snakeBodylength>0){
            for(var t=1;t<=snakeBodylength;t++){

               if(snake.x===snakeBody[t].x&&snake.y===snakeBody[t].y)
               {
                   if(n==0){//此时锁为0,即未吃到彩色小鸡
                       timer.running = false
                       self_mesDialog.open()
                     }
                   else
                       n--
                }
            }
        }

    }

    function move(){//timer刷新时需要做的

//出界,不美观蛇头出界后显示
//        if(snake.x<=20&&snake.keydirection==1){
//            var m=snake.keydirection
//            m++
//            if(m==2){
//                timer.running = false
//                out_mesDialog.open()
//            }
//        }
        if(movestate == 1 && snake.keydirection == 2 ){
            snake.keydirection = movestate
         }
         if(movestate == 2 && snake.keydirection == 1 ){
             snake.keydirection = movestate
         }
         if(movestate == 3 && snake.keydirection == 4 ){
             snake.keydirection = movestate
         }
         if(movestate == 4 && snake.keydirection == 3 ){
             snake.keydirection = movestate
         }
         snakeBodyMove()//蛇在未碰撞情况下的自由移动
         if(snake.keydirection == 1){
             movestate = 1
             if(snake.x==20){
                 /*出界判断,优点:不会等到出界显示提示且适用于沿着边界行走的状况
                              缺点:蛇身仍然会向前一格,即snakeBody[0].x=snake.x;snakeBody[0].y=snake.y
                                  视觉上缺失了一格*/
                 timer.running = false
                 out_mesDialog.open()

             }
             else
                 snake.x -= 20
         }
         if(snake.keydirection == 2){
             movestate = 2
             if(snake.x==400){
                 timer.running = false
                 out_mesDialog.open()

             }
             else
                 snake.x += 20
         }
         if(snake.keydirection == 3){
             movestate = 3
             if(snake.y==20){
                 timer.running = false
                 out_mesDialog.open()

             }
             else
                snake.y -= 20
         }
         if(snake.keydirection == 4){
             movestate = 4
             if(snake.y==400){
                 timer.running = false
                 out_mesDialog.open()

             }
             else
                 snake.y += 20
         }
         eat();
         }
}

刚刚开始学习qml,尝试做了一个贪吃蛇(无C++交互),请多指教。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值