zoukankan      html  css  js  c++  java
  • Laya连线小游戏

    Laya连线小游戏

    游戏规则

    1. 通过连接不同颜色的方块来实现连一连
    2. 连线不可重复,就是一条线不能和另外一条线撞一起
    3. 最后所有连线要占据整个空间

    游戏资源

     

    创建Item

     线条可以分为上左下右,通过显示和隐藏达到画线的效果。

     譬如item1到item2,通过判断两者posX,posY,item1调用方法showLine(3)显示line3,item2调用方法showLine(1)显示line1。

    Item.ts。

    import { ui } from "../ui/layaMaxUI";
    export class Item extends ui.view.ItemUI{
        public colorType:number = 1;//定义线条颜色
        public type:number = 0;//类型
        public posX:number = 1;//位置x
        public posY:number = 1;//位置y
        public isLinkList:boolean = false;//是否已经连过了
        /* 创建item */
        public static createItem():Item{
            let item:Item = new Item();
            item.line1.visible = false;
            item.line2.visible = false;
            item.line3.visible = false;
            item.line4.visible = false;
            return item;
        }
        /* 设置线条颜色 */
        public setLineColor(value:number):void{
            this.isLinkList = true;
            this.colorType = value;
            for(let i:number = 1; i <= 4; i++){
                this["line" + i].skin = "res/ui/icon/line_line" + value + ".png";
            }
        }
        /* 设置icon */
        public setIcon(value:number):void{
            this.type = value;
            if(value > 0){
                this.icon.skin = "res/ui/icon/line_icon" + value + ".png";
            }else{
                this.icon.skin = "";
            }
        }
        /* 显示上或下或左或右线条 */
        public showLine(value:number):void{
            switch(value){
                case 1:
                    this.line1.visible = true;break;
                case 2:
                    this.line2.visible = true;break;
                case 3:
                    this.line3.visible = true;break;
                case 4:
                    this.line4.visible = true;break;
                default:
                    this.line1.visible = false;
                    this.line2.visible = false;
                    this.line3.visible = false;
                    this.line4.visible = false;
                    this.isLinkList = false;
                    break;
            }
        }
    
    }

    游戏界面创建

    创建GameView.ts,类GameView继承自该界面

    import { LinkList } from "../script/LinkList";
    import { ui } from "../ui/layaMaxUI";
    import { Item } from "./Item";
    export class GameView extends ui.dialog.GameUI {
        private row:number = 5;//行数
        private column:number = 5;//列数
        private itemArr:Array<Item> = [];//存放item的数组
        private dataArr:Array<number> = [1,0,0,0,3,0,0,2,0,0,1,0,0,3,0,4,0,0,4,2,5,0,0,0,5];
        private ITEM_WIDTH:number = 120;//定义item宽
        private ITEM_HEIGHT:number = 120;//定义item高
        private canDraw:boolean = false;//是否能画线
        private tempPoint:Laya.Point = new Laya.Point();
        private list1:LinkList = new LinkList();//链表1
        private list2:LinkList = new LinkList();//链表2
        private list3:LinkList = new LinkList();//链表3
        private list4:LinkList = new LinkList();//链表4
        private list5:LinkList = new LinkList();//链表5
        private currentList:LinkList;
        constructor() {
            super();
            this.init();
        }
    
        private init():void{
            this.addEvent();
            this.initDrawLinePanel();
        }
    
        private addEvent():void{
            Laya.stage.on(Laya.Event.RESIZE,this,this.onResize);
            this.panelNode.on(Laya.Event.MOUSE_DOWN,this,this.onMouseDown);
            this.panelNode.on(Laya.Event.MOUSE_MOVE,this,this.onMouseMove);
            this.panelNode.on(Laya.Event.MOUSE_OUT,this,this.onMouseOut);
            this.panelNode.on(Laya.Event.MOUSE_UP,this,this.onMouseOut);
        }
        /* 初始化画线面板 */
        private initDrawLinePanel():void{
            let item:Item;
            for(let i:number = 0; i < this.row; i++){
                for(let j:number = 0; j < this.column; j++){
                    item = Item.createItem();
                    item.pos(j *  this.ITEM_WIDTH,i  * this.ITEM_HEIGHT);
                    item.posX = j;
                    item.posY = i;
                    item.setIcon(this.dataArr.shift());
                    this.panelNode.addChild(item);
                    this.itemArr.push(item);
                }
            }
            let panelWidth:number = this.ITEM_WIDTH * this.column;
            let panelHeight:number = this.ITEM_HEIGHT * this.row;
            this.panelNode.size(panelWidth,panelHeight);
            this.panelNode.x = -0.5 * panelWidth;
            this.panelNode.y = -0.5 * panelHeight;
        }
        /* 鼠标按下 */
        private onMouseDown():void{
            //全局坐标转为panelNode局部坐标
            this.tempPoint.setTo(Laya.MouseManager.instance.mouseX,Laya.MouseManager.instance.mouseY);
            let point:Laya.Point = this.panelNode.globalToLocal((this.tempPoint));
            let posX:number = Math.floor(point.x / this.ITEM_WIDTH);
            let posY:number = Math.floor(point.y / this.ITEM_HEIGHT);
            let index:number = posY * this.column + posX;
            let item:Item = this.itemArr[index];//拿到对应的item
            if(item.type > 0){//点击到有颜色的item
                this.canDraw = true;
                this.currentList = this["list" + item.type];
                this.currentList.clear();
                this.currentList.append(item);
            }else{//点击到没有颜色的item
                if(item.isLinkList){//连过了
                    this.currentList = this["list" + item.colorType];
                    let tail:Item = this.currentList.getTail().item;
                    if(item == item){//判断该item是否属于链表尾节点
                        this.canDraw = true;
                    }
                }
            }
        }
        /* 鼠标滑动 */
        private onMouseMove():void{
            if(!this.canDraw) return;
            //全局坐标转为panelNode局部坐标
            this.tempPoint.setTo(Laya.MouseManager.instance.mouseX,Laya.MouseManager.instance.mouseY);
            let point:Laya.Point = this.panelNode.globalToLocal((this.tempPoint));
            let posX:number = Math.floor(point.x / this.ITEM_WIDTH);
            let posY:number = Math.floor(point.y / this.ITEM_HEIGHT);
            let index:number = posY * this.column + posX;
            let item:Item = this.itemArr[index];//拿到对应的item
            let tail:Item = this.currentList.getTail().item;//链表尾
            if((posX == tail.posX && Math.abs(posY - tail.posY) == 1) || (posY == tail.posY && Math.abs(posX - tail.posX) == 1)){//必须与链表尾相邻(上下左右)
                if(item.type <= 0 || item.type == tail.colorType){//滑动到没有颜色的节点或者是颜色一样
                    let position:number = this.currentList.positionOf(item);
                    if(position < 0){
                        if(item.isLinkList){//已经在其它链表里了
                            let list:LinkList = this["list" + item.colorType]
                            list.slice(list.positionOf(item) - 1);
                        }
                        this.currentList.append(item);//添加到链表
                        this.isGetVictory();//是否通关
                        if(item.type > 0){
                            this.canDraw = false;
                        }
                    }else{
                        this.currentList.slice(position);//切割链表
                    }
                }else{
                    this.canDraw = false;
                }
            }else{
                if(item != this.currentList.getTail().item){//此时滑动到的点不是链表尾,才不能画线(在当前的点滑来滑去还是能画线)
                    this.canDraw = false;
                }
            }
        }
        /* 鼠标松开 */
        private onMouseOut():void{
            this.canDraw = false;
        }
        /* 是否通过 */
        private isGetVictory():boolean{
            let count:number = 0
            for(let i:number = 1; i <= 5;i ++){//遍历所有链表,判断链表长度是否等于面板上的方格总数
                count += this["list" + i].size()
            }
            if(count == this.row * this.column){
                return true;
            }
            return false;
        }
    
        private onResize():void{
            this.height = Laya.stage.height;
            this.width = Laya.stage.width;
        }
    }

    通过行数5,列数5创建item,添加到panelNode节点上,初始化画线面板。

    /* 初始化画线面板 */
        private initDrawLinePanel():void{
            let item:Item;
            for(let i:number = 0; i < this.row; i++){
                for(let j:number = 0; j < this.column; j++){
                    item = Item.createItem();
                    item.pos(j *  this.ITEM_WIDTH,i  * this.ITEM_HEIGHT);
                    item.posX = j;
                    item.posY = i;
                    item.setIcon(this.dataArr.shift());
                    this.panelNode.addChild(item);
                    this.itemArr.push(item);
                }
            }
            let panelWidth:number = this.ITEM_WIDTH * this.column;
            let panelHeight:number = this.ITEM_HEIGHT * this.row;
            this.panelNode.size(panelWidth,panelHeight);
            this.panelNode.x = -0.5 * panelWidth;
            this.panelNode.y = -0.5 * panelHeight;
        }

    通过鼠标位置,计算出posX,posY,拿到对应的item

    鼠标全局位置转为panelNode局部位置,计算出posX,posY,再从itemArr拿到对应的item

     this.tempPoint.setTo(Laya.MouseManager.instance.mouseX,Laya.MouseManager.instance.mouseY);
     let point:Laya.Point = this.panelNode.globalToLocal((this.tempPoint));
     let posX:number = Math.floor(point.x / this.ITEM_WIDTH);
     let posY:number = Math.floor(point.y / this.ITEM_HEIGHT);
     let index:number = posY * this.column + posX;
     let item:Item = this.itemArr[index];

    鼠标按下

    鼠标点击时,有俩种情况,才可以画线

    第一种情况,点击到颜色方块

     第二种情况,不是点击到 颜色方块,但是点击到连线的末端,这时可以继续连线

    /* 鼠标按下 */
    private onMouseDown():void{
        //全局坐标转为panelNode局部坐标
        this.tempPoint.setTo(Laya.MouseManager.instance.mouseX,Laya.MouseManager.instance.mouseY);
        let point:Laya.Point = this.panelNode.globalToLocal((this.tempPoint));
        let posX:number = Math.floor(point.x / this.ITEM_WIDTH);
        let posY:number = Math.floor(point.y / this.ITEM_HEIGHT);
        let index:number = posY * this.column + posX;
        let item:Item = this.itemArr[index];//拿到对应的item
        if(item.type > 0){//点击到有颜色的item
            this.canDraw = true;
            this.currentList = this["list" + item.type];
            this.currentList.clear();
            this.currentList.append(item);
        }else{//点击到没有颜色的item
            if(item.isLinkList){//连过了
                this.currentList = this["list" + item.colorType];
                let tail:Item = this.currentList.getTail().item;
                if(item == item){//判断该item是否属于链表尾节点
                    this.canDraw = true;
                }
            }
        }
    }

    鼠标滑动,连线

     连线时,只有跟该线线尾相邻才可以连接

     滑到不同颜色节点时断开连接

     如果滑动到的已经连接过了,就切割该链表

     如果滑动到的节点已经被其它节点连接过了,就切割连接过的链表

    /* 鼠标滑动 */
    private onMouseMove():void{
        if(!this.canDraw) return;
        //全局坐标转为panelNode局部坐标
        this.tempPoint.setTo(Laya.MouseManager.instance.mouseX,Laya.MouseManager.instance.mouseY);
        let point:Laya.Point = this.panelNode.globalToLocal((this.tempPoint));
        let posX:number = Math.floor(point.x / this.ITEM_WIDTH);
        let posY:number = Math.floor(point.y / this.ITEM_HEIGHT);
        let index:number = posY * this.column + posX;
        let item:Item = this.itemArr[index];//拿到对应的item
        let tail:Item = this.currentList.getTail().item;//链表尾
        if((posX == tail.posX && Math.abs(posY - tail.posY) == 1) || (posY == tail.posY && Math.abs(posX - tail.posX) == 1)){//必须与链表尾相邻(上下左右)
            if(item.type <= 0 || item.type == tail.colorType){//滑动到没有颜色的节点或者是颜色一样
                let position:number = this.currentList.positionOf(item);
                if(position < 0){
                    if(item.isLinkList){//已经在其它链表里了
                        let list:LinkList = this["list" + item.colorType]
                        list.slice(list.positionOf(item) - 1);
                    }
                    this.currentList.append(item);//添加到链表
                    this.isGetVictory();//是否通关
                    if(item.type > 0){
                        this.canDraw = false;
                    }
                }else{
                    this.currentList.slice(position);//切割链表
                }
            }else{
                this.canDraw = false;
            }
        }else{
            if(item != this.currentList.getTail().item){//此时滑动到的点不是链表尾,才不能画线(在当前的点滑来滑去还是能画线)
                this.canDraw = false;
            }
        }
    }

    判断是否连接完成

     只需要遍历所有链表,判断链表长度是否等于面板上的方格总数

    /* 是否通过 */
    private isGetVictory():boolean{
        let count:number = 0
        for(let i:number = 1; i <= 5;i ++){//遍历所有链表,判断链表长度是否等于面板上的方格总数
            count += this["list" + i].size()
        }
        if(count == this.row * this.column){
            return true;
        }
        return false;
    }

    item链表

    LinkList.ts

    import { Item } from "../view/Item";
    export class Node{
        public item:Item;//节点数据
        public next:Node = null;//指向下一个节点 
        constructor(item:Item){
            this.item = item;
        }
    }
    export class LinkList{
        private head:Node = null;//链表头
        private tail:Node = null;//链表尾
        private length:number = 0;//链表长度
        /* 向链表添加新节点 */
        public append(item:Item):void{
            let node:Node = new Node(item);
            if(this.length <= 0){//如果当前链表为空,则将head,tail指向node
                item.setLineColor(item.type);
                this.head = node;
                this.tail = node;
            }else{//否则在链表尾添加新元素
                item.setLineColor(this.head.item.colorType);
                let prevItem:Item = this.tail.item;
                this.tail.next = node;
                this.tail = node;
                this.setLine(prevItem,this.tail.item);
            }
            this.length++;//链表长度+1
        }
        
        /* 截取链表,包含position */
        public slice(position:number):boolean{
            if(position < 1 || position > this.length){
                return false;
            }
            console.log(position);
            let currentNode:Node = this.head;
            let currentPosition:number = 1;
            let sliceNode:Node;
            let prevNode:Node;
            while(currentNode){
                if(currentPosition == position - 1){
                    prevNode = currentNode;
                }
                else if(currentPosition == position){
                    this.length = position;
                    sliceNode = currentNode;
                    currentNode.item.showLine(0);
                    currentNode.item.isLinkList = true;
                }else if(currentPosition > position){
                    currentNode.item.showLine(0);
                }
                currentNode = currentNode.next;
                currentPosition++;
            }
            sliceNode.next = null;
            if(prevNode){
                this.setLine(prevNode.item,sliceNode.item);
            }
            this.tail = sliceNode;
            
        }
        /* 设置线条 */
        private setLine(item1:Item,item2:Item):void{
            let prevX:number = item1.posX;
            let prevY:number = item1.posY;
            let nextX:number = item2.posX;
            let nextY:number = item2.posY;
            if(prevX == nextX){
                if(prevY > nextY){
                    item1.showLine(1);
                    item2.showLine(3);
                }else{
                    item1.showLine(3);
                    item2.showLine(1);
                }
            }
            if(prevY == nextY){
                if(prevX > nextX){
                    item1.showLine(4);
                    item2.showLine(2);
                }else{
                    item1.showLine(2);
                    item2.showLine(4);
                }
            }
        }
    
         /* 查找某个元素所在的节点位置 */
         public positionOf(item:Item):number{
            let currentNode:Node = this.head;
            let currentPosition:number = 1;
            while(currentNode){
                if(currentNode.item == item){
                    return currentPosition;
                }
                currentPosition++;
                currentNode = currentNode.next;
            }
            return -1;
        }
        /*  返回某位置的节点*/
        public getNodeAt(position:number):Node{
            if(position < 1 || position > this.length){//越界
                return null;
            }
            let currentNode:Node = this.head;
            let currentPositon:number = 1;
            while(currentPositon < position){//遍历链表,找到节点
                currentNode = currentNode.next;
                currentPositon++;
            }
            return currentNode;
        }
        /* 链表是否为空 */
        public isEmpty():boolean{
            return this.length == 0;
        }
        /*  返回链表长度 */
        public size():number{
            return this.length;
        }
        /* 返回链表头 */
        public getHead():Node{
            return this.head;
        }
        /* 返回链表尾 */
        public getTail():Node{
            return this.tail;
        }
        /* 清空链表 */
        public clear():void{
            let currentNode:Node = this.head;
            while(currentNode){
                currentNode.item.showLine(0);
                currentNode = currentNode.next;
            }
            this.head = null;
            this.tail = null;
            this.length = 0;
        }
    }

    设置线条

    通过比较链表前后节点的item,显示对应的线条

    /* 设置线条 */
        private setLine(item1:Item,item2:Item):void{
            let prevX:number = item1.posX;
            let prevY:number = item1.posY;
            let nextX:number = item2.posX;
            let nextY:number = item2.posY;
            if(prevX == nextX){
                if(prevY > nextY){
                    item1.showLine(1);
                    item2.showLine(3);
                }else{
                    item1.showLine(3);
                    item2.showLine(1);
                }
            }
            if(prevY == nextY){
                if(prevX > nextX){
                    item1.showLine(4);
                    item2.showLine(2);
                }else{
                    item1.showLine(2);
                    item2.showLine(4);
                }
            }
        }

    item链表添加节点

    需要设置一下当前节点跟上一个节点的线条

    /* 向链表添加新节点 */
    public append(item:Item):void{
        let node:Node = new Node(item);
        if(this.length <= 0){//如果当前链表为空,则将head,tail指向node
            item.setLineColor(item.type);
            this.head = node;
            this.tail = node;
        }else{//否则在链表尾添加新元素
            item.setLineColor(this.head.item.colorType);
            let prevItem:Item = this.tail.item;
            this.tail.next = node;
            this.tail = node;
            this.setLine(prevItem,this.tail.item);
        }
        this.length++;//链表长度+1
    }

    item链表截取节点

     

    /* 截取链表,包含position */
    public slice(position:number):boolean{
        if(position < 1 || position > this.length){
            return false;
        }
        console.log(position);
        let currentNode:Node = this.head;
        let currentPosition:number = 1;
        let sliceNode:Node;
        let prevNode:Node;
        while(currentNode){
            if(currentPosition == position - 1){
                prevNode = currentNode;
            }
            else if(currentPosition == position){
                this.length = position;
                sliceNode = currentNode;
                currentNode.item.showLine(0);
                currentNode.item.isLinkList = true;
            }else if(currentPosition > position){
                currentNode.item.showLine(0);
            }
            currentNode = currentNode.next;
            currentPosition++;
        }
        sliceNode.next = null;
        if(prevNode){
            this.setLine(prevNode.item,sliceNode.item);
        }
        this.tail = sliceNode;
        
    }

    清空item链表

    将链表清空,item线条全部隐藏

    /* 清空链表 */
    public clear():void{
        let currentNode:Node = this.head;
        while(currentNode){
            currentNode.item.showLine(0);
            currentNode = currentNode.next;
        }
        this.head = null;
        this.tail = null;
        this.length = 0;
    }

     

  • 相关阅读:
    103、服务器出现大量close_wait的连接的原因是什么?有什么解决方法?
    102、常见的HTTP状态码有哪些?
    rpm包管理、yum源及创建本地仓库(同步华为源)
    文件管理之:输出与重定向echo
    高级权限--acl, mask,文件属性权限;su切换用户,sudo提权
    基本权限;权限对⽂件or⽬录的意义;特殊权限;文件权限之umask
    权限管理--用户介绍;用户与组相关文件;用户管理命令之用户创建、查看、删除、修改
    文件管理之:打包、压缩
    字符处理命令-sort排序,uniq去重,cut剪切文件,tr删除或替换结果集,wc统计
    上传与下载wget、curl、r z、s z
  • 原文地址:https://www.cnblogs.com/kootimloe/p/14221527.html
Copyright © 2011-2022 走看看