游戏开发小玩法(连剧名)

实现的效果

        编辑器版本:cocoscreator3.8.x

游戏的功能

简单描述下功能,就是一张含有多个电视剧名字的地图,需要按照电视剧的顺序连起来,多字,少字或者顺序错误都属于失败

所需要的资源

带上所有字的一张地图,还有一张纯白色的方格图,通过代码去控制颜色,初始颜色为浅棕色

思路


        首先通过手指移动的位置,算出此时的位置在window中的行和列的值,定义左上角为(0,0),那么整张图的行列即可表示为下图形式,然后将能连接的正确的行和列拼接起来,比如左上角的 墨雨云间  ,这四个字分别对应的横纵坐标为[(1,1),(1,0),(0,0),(0,1)],那么它的正确的数组类型 为(11100001),依次将所有的答案拼接出来用于检查是否结果正确,放在answerArr中
        在移动的时候记录按顺序记录所移动过的行和列,放进moveArr数组中,最后在松手的时候将记录的moveArr中的所有元素拼接起来,如果在answerArr中,即选择正确

整体思路:

  1. 创建文字底部的box,用于展示颜色(默认颜色、当前选中的颜色、错误时的红色)

  2. 背景的一大张图片所在的物体为window,对window进行节点的监听,并在监听中处理逻辑

  3. 在抬起手指那一刻,检查是否是选中正确的字体

代码

  • 创建box。

        window上面有layout组件,box_white是一个纯白色的格子,大小和每个字所占的大小一样

如图:

//图片中所有的剧名连成正确的线以后,相对于window中的行列组成的数组
allAnswerArr = [
     "11100001", "021222", "0313142425", "2717070616150504",
     "2120304041515060", "3132", "4243535262", "617170",
     "5444343323", "6364747372","75656676", "5556",
     "263637", "3545464757", "6777"]
errorColor = "#E64D32FF";
startColor = "EEE8DDFF";
colorArr = ["#D7F2DCFF", "#FFDCFAFF", "#D6F0F9FF", 
    "#DFD2E4FF", "#FAD8D2FF", "#FFE7ABFF", "#D5DBE8FF"]
createBox() {
        for (let i = 0; i < 8; i++) {
            for (let j = 0; j < 8; j++) {
                let box = instantiate(this.box_white);
                box.name = `box_${i}${j}`
                box.getComponent(Sprite).color = new Color(this.startColor);
                box.setParent(this.window);

            }
        }
    }
  • 对window进行监听,此处是处理一些逻辑的重点

        主要是通过当前鼠标所在的UI位置,即用此方法(getUILocation)得到手指的UI,然后通过坐标转换,将UIPos转换为window坐标系中的位置,再根据坐标系的位置,就可以知道当前手指处在window的哪一行以及哪一列,我定义window的左上角位置为起始点(0,0),就是说  左上角 那个云字的坐标为(0,0),依次 间 字就是(0,1),依次类推,然后将移动的坐标转换为行和列,放入一个数组中moveArr,这个数组用来存放手指所移动过的点以及路径(如果改点不存在数组中,则加入数组,如果已经存在于数组中,那么要找到当前点在数组中的index,并且删除这个index后面所有的元素


this.window.on(Node.EventType.TOUCH_START, this.onWindowStart, this);
this.window.on(Node.EventType.TOUCH_MOVE, this.onWindowMove, this);
this.window.on(Node.EventType.TOUCH_END, this.onWindowEnd, this);
this.window.on(Node.EventType.TOUCH_CANCEL, this.onWindowEnd, this);

onWindowStart(e: EventTouch) {
        this.moveArr = [];
        let startUIPos = e.getUIStartLocation();
        let pos = this.window.getComponent(UITransform).convertToNodeSpaceAR(v3(startUIPos.x, startUIPos.y, 0));
        let row_col = this.getRowAndColByPos(pos);
        let row = row_col.row;
        let col = row_col.col;
        let value = `${row}${col}`
        if (this.rightRowCol.indexOf(value) != -1) {
            this.isCanClick = false;
            return;
        }
        if (this.moveArr.indexOf(value) == -1) {
            AudioManager.inst.playShotByLevel(this.levelId,"26_click");
            this.changeColor(row, col);
            this.moveArr.push(value);
            this.isCanClick = true;
        }
    }
//手指移动时所处理的逻辑
 onWindowMove(e: EventTouch) {
         //isCanClick表示是否已经连过线,如果是则return;
        if (!this.isCanClick) {
            return;
        }
        let moveUIPos = e.getUILocation();
        let pos = this.window.getComponent(UITransform).convertToNodeSpaceAR(v3(moveUIPos.x, moveUIPos.y, 0));
        let row_col = this.getRowAndColByPos(pos);
        let row = row_col.row;
        let col = row_col.col;
        let value = `${row}${col}`
        let lastValue = this.moveArr[this.moveArr.length - 1];
        //排除边界值的影响
        if (Number(row) < 0 || Number(col) < 0 || Number(row) > 7 || Number(col) > 7) {
            return;
        }
        //如果选中已经确定为正确的格子,则不进行任何操作
        if (this.rightRowCol.indexOf(value) != -1) {
            return;
        }
        let del = Math.abs(Number(lastValue[0] - Number(row))) + Math.abs(Number(lastValue[1] - Number(col)))
        //相邻一个长度的格子才会被计算在内
        let index = this.moveArr.indexOf(value);
        if (index == -1) {
            if (del == 1) {
                this.changeColor(row, col);
                this.moveArr.push(value);
                AudioManager.inst.playShotByLevel(this.levelId,"26_click");
            }
            // console.log("push.moveArr", this.moveArr);
        } else if (index != -1) {
            //将要删除的格子的颜色变为正常色值
            for (let i = index + 1; i < this.moveArr.length; i++) {
                this.changeStartColor(this.moveArr[i]);
            }
            this.moveArr.splice(index + 1, this.moveArr.length - index);
            // console.log("splice.moveArr", this.moveArr);
        }
    }
    //松开手指时所执行的方法
    onWindowEnd(e: EventTouch) {
        if (!this.isCanClick) {
            return;
        }
        //检查选中的格子以及顺序是否正确
        let result = "";
        for (let i = 0; i < this.moveArr.length; i++) {
            result += this.moveArr[i];
        }
        // console.log("result", result);
        let index = this.allAnswerArr.indexOf(result);
        // console.log("index", index);
        if (index != -1) {
            //正确答案
            AudioManager.inst.playShotByLevel(this.levelId,"26_right");
            //将所有正确的已经用过的rowcol存入数组
            for (let i = 0; i < this.moveArr.length; i++) {
                this.rightRowCol.push(this.moveArr[i]);
            }
            this.nowStep++;
            this.allAnswerArr.splice(index, 1);
            let value = GameMgr.inst.tipsIdArray[0][index]
            this.deleteTipsId(Number(value));
            if (GameMgr.inst.tipsIdArray[0].length == 0) {
                this.showWinPanel(0.1);
            }
        } else {
            //错误答案
            AudioManager.inst.playShotByLevel(this.levelId,"26_error");
            for (let i = 0; i < this.moveArr.length; i++) {
                let value = this.moveArr[i];
                this.changeErrorColor(value);
                this.scheduleOnce(() => {
                    let node = this.window.getChildByName(`box_${value}`);
                    //如果节点是红色,则返回正常值,防止一秒内再次点击box影响颜色变化
                    let targetColor = color(this.errorColor)
                    let nowColor = node.getComponent(Sprite).color;
                    if (nowColor.equals(targetColor)) {
                        this.changeStartColor(value)
                    }
                }, 1)
            }
        }
    }
    //通过手指在window的pos,获得当前所处的行和列
    getRowAndColByPos(pos: Vec3) {
        let row = Math.floor(-(pos.y - this.windowSize / 2) / (this.spacingY + this.size));
        let col = Math.floor((pos.x + this.windowSize / 2) / (this.spacingX + this.size));
        return { row, col };
    }
  • 还有几个改变字体下面box的颜色的方法
changeStartColor(value) {
        const name = `box_${value}`
        let node = this.window.getChildByName(name);
        if (node) {
            node.getComponent(Sprite).color = color(this.startColor);
        }
    }
    changeErrorColor(value) {
        const name = `box_${value}`
        let node = this.window.getChildByName(name);
        if (node) {
            node.getComponent(Sprite).color = color(this.errorColor);
        }
    }
    changeColor(row: number, col: number) {
        const name = `box_${row}${col}`
        let node = this.window.getChildByName(name);
        if (node) {
            let index = this.nowStep % 7;
            node.getComponent(Sprite).color = color(this.colorArr[index]);
        }
    }

整个游戏的功能代码就以上这么多,其实功能不复杂,主要涉及坐标的转换以及相对应的二维数组行列,如果能正确处理,功能写起来也比较快

附:整个游戏节点树比较简单

bg_label就是那种写满了整个字体的图片,window为node节点,添加layout组件,需要比bg_label稍微大一点点,因为会有横纵间隔,

如果需要代码的话可以私信我,将游戏demo发过去参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值