【cocos creator】2.4.x实现简单3d功能,点击选中,旋转,材质修改,透明材质

demo下载:(待审核)
https://download.csdn.net/download/K86338236/89527924


const { ccclass, property } = cc._decorator;

const enum box_color {
    NORMAL = 0,
    DASHED_LINE = 1,//虚线
    TRANSLUCENT = 2,//半透明
}

@ccclass
export default class main extends cc.Component {
    @property(cc.Node)
    boxNode: cc.Node = null;
    @property(cc.Node)
    layerNode: cc.Node = null;

    /**层的父节点 */
    @property(cc.Node)
    layerRootNode: cc.Node = null;

    /**点击检测射线 */
    @property(cc.Node)
    touchNode: cc.Node = null;

    /**普通的颜色 */
    @property([cc.Material])
    changeMat: cc.Material[] = [];
    /**普通颜色第二层,半透明用 */
    @property([cc.Material])
    changeMat2: cc.Material[] = [];
    /**选择状态的颜色 */
    @property([cc.Material])
    changeMatChoose: cc.Material[] = [];
    @property([cc.Material])
    changeMatChoose2: cc.Material[] = [];

    /**向左旋转45 */
    @property(cc.Button)
    leftBtn: cc.Button = null;

    /**向右旋转45 */
    @property(cc.Button)
    rightBtn: cc.Button = null;

    /**分离、合起 */
    @property(cc.Button)
    divideBtn: cc.Button = null;

    /**已经修改颜色uid物体 */
    changeUids: string[] = [];

    /**当前分离状态,是否分离 */
    curDivideState: boolean = false;

    /**当前角度 */
    curAngle: number = 0;

    /**是否动作中 */
    isPlay: boolean = false;


    /**当前角度 */
    choose_type: number = 0;

    // onLoad () {}

    start() {
        this.setAngle(-15)
        cc.director.getPhysics3DManager().enabled = true;
        this.touchNode.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        let boxArr = ["1,1|1,2|1,3|2,1|2,2|3,1", "1,1|1,2|2,1", "1,1"]
        let minX = 999
        let maxX = -999
        let minZ = 999
        let maxZ = -999
        for (let i = 0; i < boxArr.length; i++) {
            const element1 = boxArr[i];
            const element = element1.split("|")
            for (let j = 0; j < element.length; j++) {
                const element2 = element[j];
                let pos = element2.split(",")
                let x = (Number(pos[0]) - 1) || 0
                let z = (Number(pos[1]) - 1) || 0
                if (x < minX) minX = x
                if (x > maxX) maxX = x
                if (z < minZ) minZ = z
                if (z > maxZ) maxZ = z
            }
        }
        let maxData = { minX, maxX, minZ, maxZ }
        this.creatLayer(boxArr, maxData)
        this.onShowType(null, 0)
    }

    creatLayer(boxArr = [], maxData) {
        this.layerRootNode.children.forEach((value) => { value.active = false })
        for (let i = 0; i < boxArr.length; i++) {
            const element = boxArr[i];
            let layer = this.layerRootNode.children[i] || cc.instantiate(this.layerNode)
            layer.parent = this.layerRootNode;
            layer.name = "layer" + (i + 1)
            this.creatBox(element, layer, maxData);
            layer.y = i - (boxArr.length - 1) / 2;
            // layer.y = i 
            layer.active = true
        }
    }

    creatBox(boxString = "", parent: cc.Node, maxData) {
        const { minX, maxX, minZ, maxZ } = maxData
        parent.children.forEach((value) => { value.active = false })
        let boxArr = boxString.split("|")
        for (let i = 0; i < boxArr.length; i++) {
            const element = boxArr[i];
            let pos = element.split(",")
            let box = parent.children[i] || cc.instantiate(this.boxNode)
            box.parent = parent;
            box.name = `box${pos[0]}_${pos[i]}`
            let x = ((Number(pos[0]) - 1) || 0) - (maxX - minX) / 2
            let z = ((Number(pos[1]) - 1) || 0) - (maxZ - minZ) / 2
            box.setPosition(x, 0, z)
            box.active = true
        }
    }

    setAngle(angle) {
        this.curAngle = angle
        let quat: cc.Quat = new cc.Quat();
        let oldVe: cc.Vec3 = new cc.Vec3();
        let oldQuat: cc.Quat = new cc.Quat();
        this.layerRootNode.getRotation(oldQuat);
        oldQuat.toEuler(oldVe);
        this.layerRootNode.setRotation(cc.Quat.fromEuler(quat, oldVe.x, angle, oldVe.z));
    }

    /**检测射线 */
    onTouchStart(event) {
        let touchLoc = event.touch.getLocation();
        let ray = this.node.getChildByName("3D Camera").getComponent(cc.Camera).getRay(touchLoc);
        let maxDistance = 1050;
        let rayColliderGroupName = "3d";
        const result = cc.director.getPhysics3DManager().raycastClosest(ray, rayColliderGroupName, maxDistance, false);
        if (result) {
            let box = result.collider.node
            const uuid = box.uuid;
            let index = this.changeUids.indexOf(uuid)
            let isChoose = index >= 0
            if (isChoose) {
                this.changeUids.splice(index, 1)
                this.setMaterial(box, false)
                return;
            }
            this.setMaterial(box, true)
            this.changeUids.push(uuid)
        }
    }

    /**
     * 
     * @param event 
     * @param index  0.普通 1.虚线 2.半透明
     */
    onShowType(event, index = 0) {
        index = Number(index) || 0
        this.choose_type = index;
        for (let i = 0; i < this.layerRootNode.children.length; i++) {
            const element = this.layerRootNode.children[i];
            for (let j = 0; j < element.children.length; j++) {
                const box = element.children[j];
                const uuid = box.uuid;
                const showChoose = this.changeUids.indexOf(uuid) >= 0
                this.setMaterial(box, showChoose)
            }
        }
    }

    /**
     * 
     * @param box 需要改变材质的节点 
     * @param index  是否是选择
     */
    setMaterial(box, showChoose = false) {
        let showArr = showChoose ? this.changeMatChoose : this.changeMat
        let showArr2 = showChoose ? this.changeMatChoose2 : this.changeMat2
        const ren = box.getComponent(cc.MeshRenderer);
        ren.setMaterial(0, showArr[this.choose_type]);
        const ren2 = box.getComponentInChildren(cc.MeshRenderer);
        if (ren2 && showArr2[this.choose_type]) {
            ren2.setMaterial(0, showArr2[this.choose_type]);
            ren2.node.active = true
        }
        else if (!showArr2[this.choose_type]) {
            ren2.node.active = false
        }
    }

    /**向左旋转 */
    onLeftRotate() {
        this.roatateFun(true);
    }

    /**向右旋转 */
    onRightRotate() {
        this.roatateFun(false);
    }

    /**分离 合并 */
    onDivide(event, t = 0.2) {
        if (this.isPlay) return;
        this.isPlay = true;
        let lb = this.divideBtn.node.getComponentInChildren(cc.Label);
        for (let i = 0; i < this.layerRootNode.childrenCount; i++) {
            const node = this.layerRootNode.children[i];
            let y = node.y;
            if (!this.curDivideState) y *= 2;// 分离
            else y /= 2;// 合并
            node.stopAllActions()
            cc.tween(node).to(t, { y: y }, { easing: 'sineOut' }).call(() => {
                this.curDivideState = !this.curDivideState;
                this.isPlay = false;
                if (this.curDivideState) lb.string = "合";
                else lb.string = "分";
            }).start();
        }

    }

    /**旋转 */
    roatateFun(left: boolean, angel = 9) {

        if (this.isPlay) return;
        this.isPlay = true;

        let count = 10;
        let func = () => {
            count--;
            if (left) this.curAngle -= angel;
            else this.curAngle += angel;

            let quat: cc.Quat = new cc.Quat();
            let oldVe: cc.Vec3 = new cc.Vec3();
            let oldQuat: cc.Quat = new cc.Quat();
            this.layerRootNode.getRotation(oldQuat);
            oldQuat.toEuler(oldVe);
            this.layerRootNode.setRotation(cc.Quat.fromEuler(quat, oldVe.x, this.curAngle, oldVe.z));
            if (count <= 0) {
                this.isPlay = false;
                this.unschedule(func);
            }
        }
        this.schedule(func, 0.01, count);
    }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以为您提供一个基于 cocoscreator 2.4.x 的发光 shader。以下是代码: ``` CCEffect %{ techniques: - name: glow passes: - vert: ccShader_PositionTextureColor_vert frag: glow_frag } %} CCProgram glow { CCShader_PositionTextureColor_vert, highp vec4 blurSize; void main() { mat4 mvp; CC_USE_MVP(mvp); gl_Position = mvp * vec4(a_position, 1); v_fragmentColor = a_color; v_texCoord = a_texCoord; } CCShader_Header { uniform highp vec4 blurSize; varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; const highp float glowPow = 2.0; const highp float glowStrength = 0.5; } CCShader glow_frag { highp vec4 blurSize; highp float blurRadius = 2.0; void main() { highp vec4 sum = vec4(0.0); highp vec2 texcoord = v_texCoord.xy; highp vec2 blur = blurSize.xy; highp float strength = blurSize.z; highp float glow = blurSize.w; highp float samples = 8.0; highp vec4 col = texture2D(CC_Texture0, texcoord); for (highp float i = 0.0; i < samples; i++) { highp float angle = i / samples * 3.14159265 * 2.0; highp vec2 blurDirection = vec2(sin(angle), cos(angle)); highp vec4 blurCol = texture2D(CC_Texture0, texcoord + blurDirection * blurRadius * blur); sum += blurCol; } highp vec4 glowCol = sum / samples; glowCol = (glowCol - col) * glow * glowPow + col; gl_FragColor = mix(col, glowCol, strength) * v_fragmentColor; } } } ``` 您可以将此代码添加到您的 cocoscreator 2.4.x 项目中,然后将此 shader 应用于需要发光效果的 sprite 上。希望这可以帮到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

烧仙草奶茶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值