使用CocosCreator2.x完成一个左右跳小游戏

本文主要是使用Cocos2.x版本完成一个左右跳跃的小游戏demo。游戏的核心玩法比较简单即是通过点击左右方向控制人物左右向上的跳跃。这里实现主要逻辑

  • 玩法如下
    请添加图片描述

1:场景/节点制作
  • 在demo中主要是一个背景节点以及一个放置所有地板节点的父节点,当人物往上跳跃的时候就让所有地板节点的父节点往下方移动并且朝着点击方向的反方向移动地板宽度的一半,即可在场景中表现出是人物在往上跳跃的现象。
  • 人物是通过不同的部位进行拼接得到的一个预制体。其中有jump和walk动画。在这里插入图片描述
2:事件注册
  • 由于游戏的玩法需要使用到触摸事件以及判断是点击在设备的左侧还是右侧,那么我们需要在代码中先添加触摸事件。
// Learn cc.Class:
//  - https://docs.cocos.com/creator/manual/en/scripting/class.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
let isTouchEnabled = true
cc.Class({
    extends: cc.Component,
    properties: { 
    },
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
        this.initTouchEnabled();
    },
    initTouchEnabled() {
        this.node.on("touchstart", this.touchStart, this, false);
        this.node.on("touchend", this.touchEnd, this, false);
    },
    touchStart(event) {
        if (!isTouchEnabled) return
        let touchPos = event.getLocation()
        if (touchPos.x < cc.winSize.width / 2) {
            this.player.scaleX = -1 * Math.abs(this.player.scaleX)
            this.blockMoveDown(false);
        } else {
            this.player.scaleX = Math.abs(this.player.scaleX)
            this.blockMoveDown(true);
        }
        isTouchEnabled = false
        this.player.getComponent(cc.Animation).play("jump")
    },
    touchEnd() {
		cc.log("touchEnd--");
    },
    start () {
    },
    // update (dt) {},
});

3:地块的生成与放置
  • 地块的生成是每次会生成一些地块的位置数据放到一个数组里面,当场上的地块少于某个数量时,就会将数组内的地块位置赋值给对象池(对象池[cocos文档])中拿出来的地块。然后清空数组,再次生成一些地块的位置数据放到该数组内,重复下去。
// Learn cc.Class:
//  - https://docs.cocos.com/creator/manual/en/scripting/class.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
const ladderNum = [2, 6];//the block nun of Min and Max 
let wallArr = [];//wall Array(set zIndex) 
let totalWallArr = []
let position = [];//wall's position
let totalPosition = []
let objectCount = 10;//max length of Arrays
let checkTime = 120
let isTouchEnabled = true
let playerPos = cc.v2(0, -400);
cc.Class({
    extends: cc.Component,
    properties: {
    },
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
 		this.getWallPosition()
 		this.createItem(position)
    },
    getWallPosition(isFirst = true) {
        //first put one!another put later。
        let x = playerPos.x
        let y = playerPos.y
        let width = 0
        let height = 0
        for (let i = 0; i < objectCount; i) {
            let num = getRandom(ladderNum[0], ladderNum[1])
            i + num < objectCount ? i += num : i = objectCount
            if (!isFirst) {
                let lasted = null
                if (position.length > 0) {
                    lasted = position[position.length - 1];
                } else {
                    lasted = totalPosition[totalPosition.length - 1]
                }
                x = lasted.x
                y = lasted.y
                width = lasted.width
                height = lasted.height
            }
            let dstNum = getRandom(0, 3, false);//dstNum is design to change the rotate of blocks
            for (let j = 0; j < num; j++) {
                let obj = {}
                if (isFirst) {
                    let node = this.getWall()
                    width = node.getContentSize().width
                    height = node.getContentSize().height
                    
                    node.setPosition(x, y)
                    this.wallNode.addChild(node)
                    isFirst = false
                    totalPosition.push({ "x": x, "y": y, "width": width, "height": height })
                    totalWallArr.push(node)
                } else {
                    if (dstNum <= 2.5) {
                        dstNum <= 1.25 ? x += width / 2 : x -= width / 2;
                        y += height / 2
                        obj = { "x": x, "y": y, "width": width, "height": height }
                        // cc.log(obj)
                        position.push(obj)
                    } else {
                        this.getBoxPosition(x, y, width, height);
                        break
                    }
                }
            }
        }
    },
    getBoxPosition(x, y, w, h) {
        let r = getRandom(3, 6)
        let l = getRandom(3, 6)
        for (let i = 0; i <= r; i++) {
            for (let j = 0; j <= l; j++) {
                if (i == 0 && j == 0) continue//delete frist block
                if (j == 0 || j == l || i == 0 || i == r) {
                    let dx = x + (i - j) * w / 2
                    let dy = y + (i + j) * h / 2
                    let pos = { "x": dx, "y": dy, "width": w, "height": h }
                    position.push(pos);
                }
            }
        }
        // cc.log(position)
    },
    createItem(posArr) {
        let index = true;
        for (let pos of posArr) {
            // let node = cc.instantiate(this.wallPre);
            let node = this.getWall();
            node.setPosition(pos.x, pos.y + 500)
            this.wallNode.addChild(node)
            if (index) {
                index = false;
                node.zIndex = totalWallArr[totalWallArr.length - 1].zIndex - 1
            } else {
                node.zIndex = wallArr[wallArr.length - 1].zIndex - 1
            }
            cc.tween(node)
                .by(0.1, { scale: 0.1, angle: 10 })
                .by(0.1, { scale: -0.1, angle: -10 })
                .by(0.3, { position: cc.v2(0, -500) })
                .start();
            wallArr.push(node)
        }
        totalPosition = totalPosition.concat(posArr);
        // position = []
        posArr = []
        totalWallArr = totalWallArr.concat(wallArr);
        wallArr = []
        return posArr
    },
    start () {
    },
    // update (dt) {},
});

4:人物下方的地块检测与下移重新放入对象池
  • 在本示例中人物下方的地块是通过一个简单的相对的节点的y坐标来判断的。小于人物的y坐标-某个值时,将该地块节点下移且移动到屏幕外时将该节点重新放入对象池。
// Learn cc.Class:
//  - https://docs.cocos.com/creator/manual/en/scripting/class.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
cc.Class({
    extends: cc.Component,
    properties: { 
    },
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
    	
    },
    blockMoveDown(isRight = false) {
        let node = totalWallArr[totalWallArr.length - 1];
        let delX = 0;
        isRight ? delX = - node.width / 2 : delX = node.width / 2
        cc.tween(this.wallNode)
            .by(0.2, { position: cc.v2(delX, -node.height / 2 - 20) })
            .by(0.15, { position: cc.v2(0, 20) })
            .call(() => {
                if(!this.checkPlayerPos(isRight, node)){
                    this.playerFall()
                    return
                }
                // this.player.getComponent(cc.Animation).play("walk")
                isTouchEnabled = true
                this.checkBlock();
            })
            .start()
    },
    playerFall(){
        cc.tween(this.player)
            .by(0.2, { position: cc.v2(0, 50) })
            .by(0,2)
            .by(2, { position: cc.v2(0, -cc.winSize.height) })
            .call(() => {
                this.gameOver()
            })
            .start()
    },
    checkPlayerPos(isRight, wall) {
        isRight ? playerPos.x += wall.width / 2 : playerPos.x += -wall.width / 2
        playerPos.y += wall.height / 2
        for (let pos of totalPosition) {
            if(Math.abs(pos.x-playerPos.x)<1&&Math.abs(pos.y-playerPos.y)<1){
                // cc.log(Math.abs(pos.x-playerPos.x),Math.abs(pos.y-playerPos.y))
                return true
            }
        }
        return false
    },
    checkBlock() {
        let count = 0
        for (let node of totalWallArr) {
            let worldPos = localConvertWorldPointAR(node)
            let dstPos = worldConvertLocalPoint(this.player, worldPos)
            // cc.log(dstPos);
            if (count >= 2) return
            if (dstPos.y < -120) {
                count++
                totalPosition = removeObjFromArray(node, totalPosition)
                totalWallArr = removeObjFromArray(node, totalWallArr)
                cc.tween(node)
                    .by(0.1, { scale: 0.1, angle: -10 })
                    .by(0.1, { scale: -0.1, angle: 20 })
                    .by(0.1, { scale: 0.1, angle: -20 })
                    .by(0.1, { scale: -0.1, angle: 10 })
                    .by(1, { position: cc.v2(0, -cc.winSize.height / 2) })
                    .call(() => {
                        if (totalWallArr.length < 8) {
                            this.getWallPosition(false)
                            setTimeout(() => {
                                position = this.createItem(position);
                            }, 0.5);
                        }

                        this.putWall(node);
                    })
                    .start();
            } else {
            }
        }
    },
    start () {
    },
    // update (dt) {},
});


完结完结,overover!
一般,真心没意思

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小蟹 !

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值