- 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++交互),请多指教。