cocos实现一个中秋月饼消除类小游戏

in javascript前端游戏cocos with 0 comment

资源加载

首先我们可以把需要加载的资源放到一个数组里,这里也包含媒体资源

const source = [
    './assets/textures/btn_eat.png',
    './assets/textures/btn_threw.png',
    './assets/textures/moon_cake_1.png',
    './assets/textures/moon_cake_0.png',
    './assets/textures/bg.png',
    './assets/textures/icon_music.png',
    './assets/textures/icon_star.png',

    './assets/audios/game.mp3'
]

通过加载器将资源加载进去

cc.loader.load(source, function (result, count, loadedCount) {
    // 资源加载过程中回调函数
    // ......
}, function () {
    // 资源加载完成回调函数

});

场景布置

给背景换一个想要的颜色

const colorBackground = new cc.LayerColor(cc.color(67, 36, 99))
this.addChild(colorBackground)

摆上背景图

const bg = cc.Sprite.create('./assets/textures/bg.png')
// 这只背景图的位置到正中央
bg.setPosition(cc.visibleRect.center)
this.addChild(bg)

添加音乐控制按钮

const size = cc.winSize
const musicPhoto = cc.Sprite.create('./assets/textures/icon_music.png')
musicPhoto.setPosition(size.width / 1.1, size.height / 2 + size.width * .7)
musicPhoto.setContentSize(71, 71)
this.addChild(musicPhoto)

我们先来手捏一个月饼

const ratio = 0.9

const MoonCake = cc.Sprite.extend({
    moonCakeTypes: [0, 1], // 这里两种月饼类型我们用 `0` 和 `1` 表示
    moonCakeZIndexs: [19, 18, 17,16,15,14,13,12,11,10],
    moonCakeScales: [
        1,
        1 * ratio,
        1 * ratio * ratio,
        1 * ratio * ratio * ratio,
        1 * ratio * ratio * ratio * .9,
        1 * ratio * ratio * ratio * ratio,
        1 * ratio * ratio * ratio * ratio * .99,
    ],
    ctor: function () {
        let type = arguments[0]
        let texture
        if (this.moonCakeTypes.includes(type)) {
            texture = './assets/textures/moon_cake_'+type+'.png'
        } else {
            throw new Error('月饼类型错误! 你传入的月饼类型是: ' + type)
        }

        this._super(texture)
        this.x = cc.winSize.width / 2
        this.type = type
    },

    setZIndex: function (zIndex) {
        let moonCakesPositions = [
            327.5,
            327.5 + 119*1,
            327.5 + 119*2,
            327.5 + 119*3,
            327.5 + 119*4,
            327.5 + 119*5,
            327.5 + 119*6
        ]

        if (this.__zIndex == null) {
            this.__zIndex = zIndex
            this.y = moonCakesPositions[zIndex]
            this.setScale(this.moonCakeScales[zIndex])
            this.setLocalZOrder(this.moonCakeZIndexs[zIndex])
        } else if (zIndex !== this.__zIndex) {
            this.setLocalZOrder(this.moonCakeZIndexs[zIndex])
            let actionMove = cc.moveTo(.3, {x: cc.winSize.width / 2, y: moonCakesPositions[zIndex]})
            var actionScale = cc.scaleTo(.3, this.moonCakeScales[zIndex])
            var moonCakeAction = cc.spawn(actionMove, actionScale)
            this.stopAllActions()
            this.runAction(moonCakeAction)
        }
    }
})

创建月饼

function createMoonCake() {
    const moonCakes = []

    // 这里我们创建7个月饼
    for (let i = 0; i < 7; i++) {
        let moonCakeInstance = new MoonCake(Math.random()*10 > 5 ? 1 : 0)
        moonCakeInstance.setZIndex(i)
        moonCakes.push(moonCakeInstance)
        this.addChild(moonCakeInstance)
    }
}

当月饼被吃掉,我们要把最前的月饼移除掉,让排在后面的月饼站到前面来

let currentMoonCake = this.moonCakes.shift()

this.moonCakes.forEach(function (moonCakeInstance, i) {
    moonCakeInstance.setZIndex(i)
})

currentMoonCake.removeFromParent(true)

我们让背景音乐自动播放

// 这里设置的是自动播放
cc.audioEngine.playMusic('./assets/audios/game.mp3', true)

也可以让播放中的音乐暂停播放

cc.audioEngine.pauseMusic()

当然,还可以让暂停的音乐恢复播放

cc.audioEngine.resumeMusic()

处理音乐的播放和暂停

function toggleBackgroundMusic(boolean) {
    let self = this
    let musicPhoto = this.musicPhoto

    if (boolean) {
        return play()
    }

    if (boolean === false) {
        return stop()
    }

    if (musicPhoto.isPlaying) {
        stop()
    } else {
        play()
    }

    function play() {
        musicPhoto.runAction(self.musicActionRotate());
        if (!this.notFirst) {
            this.notFirst = true
            cc.audioEngine.playMusic('./assets/audios/game.mp3', true);
        } else {
            cc.audioEngine.resumeMusic();
        }
    }

    function stop() {
        musicPhoto.isPlaying = false
        musicPhoto.stopAllActions()
        cc.audioEngine.pauseMusic()
    }
}

给音乐按钮添加交互事件

const self = this
this.addTap(musicPhoto, function () {
    self.toggleBackgroundMusic()
})

给场景中的元素添加事件

我们把事件封装到 addTap 函数里

function addTap(target, callbackFun) {
    cc.eventManager.addListener({
        event: cc.EventListener.TOUCH_ONE_BY_ONE,
        onTouchBegan: function (touch, event) {
            const touchLocation = touch.getLocation()
            const targetConvertLocation = {
                x: target.x - touchLocation.x,
                y: target.y - touchLocation.y
            }

            const targetSize = target.getContentSize()
            const rect = cc.rect(-target.width / 2, -target.height / 2, target.width, target.height)
            return cc.rectContainsPoint(rect, targetConvertLocation)
        },
        onTouchEnded: function () {
            typeof callbackFun === 'function' && callbackFun()
        }
    }, target)
}

分数

const size = cc.winSize
// 默认0分,这里我们选用 微软雅黑字体,字体大小是36
const scoreLabel = cc.LabelTTF.create('0分', 'MicrosoftYaHei', 36)
scoreLabel.setPosition(size.width * 0.2, size.height / 2 + this.bg.height / 2 - scoreLabel.getContentSize().height - 20)
this.addChild(scoreLabel)

给分数旁边摆上星星

const tagStar = cc.Sprite.create('./assets/textures/icon_star.png')
// 我们把星星放到分数的左边
tagStar.setPosition(scoreLabel.x - tagStar.getContentSize().width * 1.7, scoreLabel.y + 15)
this.addChild(tagStar)

加入倒计时

加入倒计时的显示文字

this.countTime = 60 * 1000
const timeLabel = cc.LabelTTF.create('60s', 'MicrosoftYaHei', 40)
// 设置倒计时文字颜色为白色
timeLabel.setColor(cc.color(255, 255, 255))
timeLabel.countTime = this.countTime / 1000
this.addChild(timeLabel)

倒计时执行内容

function countDownAction(t) {
    timeLabel.counttime -= t
    if (timeLabel.countTime <= 0) {
        timeLabel.countTime = 0

        // 倒计时结束,我们让游戏结束
        this.gameOver()
    }

    timeLabel.string = timeLabel.countTime.toFixed(2) + 's'
}

我们让倒计时每隔 0.03秒执行一次

this.schedule(countDownAction, .03)

游戏结束

游戏结束了,我们来做一些处理

function gameOver() {
    cc.eventManager.setEnabled(false)
    this.toggleBackgroundMusic(false)
    this.unscheduleAllCallbacks()
}
Responses