首页 » 技术分享 » cocos creator 做一个涂鸦跳跃

cocos creator 做一个涂鸦跳跃

 

cocos creator 做一个涂鸦跳跃

问题1:如何实现主角跟随

问题2:如何实现向上跳动时,所有跳板都能穿透,向下掉落时,所有跳板都能弹起

问题3:如果实现不同跳板有不同的弹跳高度

问题4:如何实现背景滚动

问题5:添加怪物

问题6:添加子弹

 

实现主角跟随

cocos 有一个摄像机的概念,在摄像机里面的东西,就能看到,在这之外 的就看不到,所以,只需要把摄像机一直跟着主角,就能实现主角跟随的效果了

代码其实就一点点:

cc.Class {
    extends: cc.Component

    properties: {
        player: cc.Node
    }
    lateUpdate: (dt) ->
        targetPos = this.player.convertToWorldSpaceAR(cc.Vec2.ZERO)
        pos = this.node.parent.convertToNodeSpaceAR(targetPos)
        this.node.position = cc.v2(this.node.position.x, pos.y)
        return
}

 

因为主角在游戏过程中,一直在移动,所以要先获取主角的世界坐标

之后为了让摄像机和跟随主角,需要把摄像机的坐标设置成主角的坐标

主角的世界坐标算出来后,再把它换算成摄像机的模型坐标,这样就可以直接 setposition了

跳跃过程弹板状态

尝试过程很复杂,尝试过上升过程设置所有弹板为sensor,发现无效,尝试过隐藏collider,也无效,最后把rigidbody隐藏就好了

于是,有了下面的步骤:

1、根据角色当前位置和上一次位置的正负,判断角色是在上升还是在下落

_getPlayerDir: ->
        @_lastPlayerY ?= 0
        playerPos = this.player.convertToWorldSpaceAR(cc.Vec2.ZERO)
        dir = "up"
        if playerPos.y > @_lastPlayerY
            dir = "up"
        else
            dir = "down"
        @_lastPlayerY = playerPos.y
        return dir

2、上升时隐藏所有弹板的rigidBody

3、下降时显示所有弹板的rigidBody

_changeRigidBodyActive: (dt) ->
        return unless @_isTimeOk()
        playerDir = @_getPlayerDir()
        for platform, index in @_platformList
            rigidBody = platform.getComponent(cc.RigidBody)
            rigidBody.active = playerDir is "down"
        return

 

实现不同跳板有不同的弹跳高度

先生成三个预制体,每个预制体挂同一个脚本文件

然后在脚本属性里,设置不同的参数即可

cc.Class {
    extends: cc.Component

    properties: {
        impulse: cc.v2(0, 3000)
    }

    onLoad: ->
        this.node.getComponent(cc.PhysicsBoxCollider).name = "impulse_platform"
        @_createAction() if Math.random() > 0.8
        
    _createAction: ->
        ac1 = cc.moveBy(1, 200, 0)
        ac2 = cc.moveBy(1, -200, 0)
        this.node.runAction(cc.repeatForever(cc.sequence(ac1, ac2)))

    onBeginContact: (contact, selfCollider, otherCollider) ->
        manifold = contact.getWorldManifold()
        return if manifold.normal.y isnt 1
        body = otherCollider.body
        body.linearVelocity = cc.v2()
        body.applyLinearImpulse(this.impulse, body.getWorldCenter(), true)
        return
}

实现背景滚动

游戏中摄像机是跟随角色移动的,所以很多书上讲的那种背景移动,即循环减一个数,减到小于一定值后,再重置回去的方法,就无效了。因为这种方法是要保证摄像机不动的情况下才有用的。所以,得想另一种方法来满足这个背景滚动

 

之前做过一个动态scrollview的插件,其实这个就和背景滚动的原理是一样的。当角色往上移动时,如果最高的背景到当前位置的距离小于一定值,则把最低位置的背景移动到最高背景的上方,当角色往下降落时,如果最低位置的背景与当前位置的距离小于一定值时,则把最高位置的背景移动下最低背影的下方。

 

步骤为:

1、将所有layer放在一个数组中,这个游戏中用到了4个

2、在update中调用

3、对layer按y坐标按从小到大排序

4、如果要比较最远距离的,则取数组中最大索引值对应的layer,反之取0

cc.Class {
    extends: cc.Component

    properties: {
        player: cc.Node
        bgLayerTable: [cc.Node]
    }

    onLoad: ->
        @speed = 5

    _fillUpLayer: ->
        playerPos = @player.convertToWorldSpaceAR(cc.Vec2.ZERO)
        maxY = @bgLayerTable[@bgLayerTable.length - 1].getBoundingBox().yMax
        if maxY - playerPos.y < cc.winSize.height
            @bgLayerTable[0].setPosition(cc.v2(0, maxY + cc.winSize.height / 2))
        return

    _fillDownLayer: ->
        playerPos = @player.convertToWorldSpaceAR(cc.Vec2.ZERO)
        minY = @bgLayerTable[0].getBoundingBox().yMin
        if playerPos.y - minY < cc.winSize.height
            pos = cc.v2(0, minY - cc.winSize.height / 2)
            @bgLayerTable[@bgLayerTable.length - 1].setPosition(pos)
        return

    _updateBackgroundLayer: (dt) ->
        @_orderLayerTable()
        @_fillUpLayer()
        @_fillDownLayer()
        
    _orderLayerTable: ->
        this.bgLayerTable.sort( (a, b) -> a.y - b.y)

    update: (dt) ->
        @_updateBackgroundLayer(dt)
}

添加怪物

1、创建预制体

2、写一个脚本

cc.Class {
    extends: cc.Component

    properties: {
        
    }
    onLoad: ->
        this.node.getComponent(cc.PhysicsBoxCollider).name = "monster"
        @_createAction()

    _createAction: ->
        ac1 = cc.moveBy(1, 200, 0)
        ac2 = cc.moveBy(1, -200, 0)
        this.node.runAction(cc.repeatForever(cc.sequence(ac1, ac2)))

    update: (dt) ->
        # do your update here

    onBeginContact: (contact, selfCollider, otherCollider) ->
        if otherCollider.name is "player"
            cc.director.emit("game_over")
        return
}

添加子弹

_createBullet: ->
        bullet = cc.instantiate(this.bulletPrefab)
        this.platformRootNode.addChild(bullet)
        bullet.setPosition(this.player.x, this.player.y + this.player.height * 1.5)
        body = bullet.getComponent(cc.RigidBody)
        body.linearVelocity = cc.v2()
        speedY = this.player.getComponent(cc.RigidBody).linearVelocity.y / 3
        body.applyLinearImpulse(cc.v2(10, Math.max(speedY, 200)), body.getWorldCenter(), true)
        @_bulletList.push bullet

 

转载自原文链接, 如需删除请联系管理员。

原文链接:cocos creator 做一个涂鸦跳跃,转载请注明来源!

0