cocos creator 2.1+ 中使用材质和自定义shader

版本说明

  • cocos creator 1.x shader 没有经过包装,可以直接定义shader,替换 sprite 原来的 shader,可以参考之前博客
  • cocos creator 2.x 引入了材质系统,使用 shader 必须通过材质,这里介绍下如何使用自定义 shader;
  • 2.1.2 版本编辑器中开放了实验版材质和shader,如图:
    在这里插入图片描述

流程

  1. 如上图,新建一个shader,即Effect,然后再新建一个材质 Material;
  2. 选中新建的材质,将材质的effect设为刚刚新建的 shader,如图:在这里插入图片描述
  3. 使用文本编辑器打开刚刚新建的 shader,可以看到有三大部分内容:
%{
......
}%

%%  vs  {
......
}

%% fs {
......
}

其中 vs 对应的就是顶点着色器,fs 对应片段着色器,定义shader时,修改这两部分内容即可。

  1. 最后,就是修改 sprite 的材质,提供一个工具,如下:
let MaterialUtils = {
    customCache: {}, // 保存自定义材质,避免重复加载
    MAT: {
        // build in
        DEFAULT: {
            custom: false,
            name: "2d-sprite",
        },
        GRAY: {
            custom: false,
            name: "2d-gray-sprite"
        },
		// custom
        TIME: {
            custom: true,
            name: "MaterialTime",
        },
        OVERLAY: {
            custom: true,
            name: "MaterialOverlay",
        },
    },
};

MaterialUtils.getMaterial = function(sp, matCfg, cb) {
    if (matCfg.custom) {
        let url = "material/" + matCfg.name;
        if (this.customCache[url]) {
            cb(false, this.customCache[url]);
            return;
        }

        cc.loader.loadRes(url, cc.Material, (err, asset) => {
            if (err) {
                cc.error(err);
                cb(err, null);
            }
            this.customCache[url] = asset;
            cb(false, asset);
        });
    } else {
        let mat = cc.Material.getInstantiatedBuiltinMaterial(matCfg.name, sp);
        cb(false, mat);
    }
};

MaterialUtils.useMaterial = function(sp, matCfg, cb) {
    MaterialUtils.getMaterial(sp, matCfg, (err, mat)=>{
        if (err) 
            return;
        mat.setProperty('texture', sp.spriteFrame.getTexture());
        sp.setMaterial(0, mat);
        sp.markForRender(true);
        cb(err, mat);
    });
};

module.exports = MaterialUtils;

可以看到,把自定义材质和系统内建材质分开处理的,因为内建材质默认就已经加载了,不需要我们另外去加载。使用非常简单,如:

const MaterialUtils = require("MaterialUtils");

cc.Class({
    extends: cc.Component,

    properties: {
        spCocoa: cc.Sprite,
    },

	onLoad() {
		MaterialUtils.useMaterial(this.spCocoa, MaterialUtils.MAT.OVERLAY, (err, mat) => {
	            if (err) {
                	return;
            	}
            	this.mat = mat;
        	});
		};
	});

最终效果如图:

在这里插入图片描述

以下是一个使用 Cocos Creator 3.7 和 TypeScript 实现的简单涂鸦跳跃游戏的代码示例: ```typescript const { ccclass, property } = cc._decorator; @ccclass export default class DoodleJump extends cc.Component { @property(cc.Node) player: cc.Node = null; @property(cc.Node) platformPrefab: cc.Node = null; @property(cc.Integer) jumpHeight: number = 300; @property(cc.Integer) jumpDuration: number = 0.5; @property(cc.Integer) maxJumpCount: number = 2; // 最大跳跃次数 private jumpCount: number = 0; // 当前跳跃次数 onLoad() { cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this); cc.director.getCollisionManager().enabled = true; } onDestroy() { cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this); } onKeyDown(event: cc.Event.EventKeyboard) { if (event.keyCode === cc.macro.KEY.space) { this.jump(); } } jump() { if (this.jumpCount < this.maxJumpCount) { this.jumpCount++; const jumpAction = cc.jumpBy(this.jumpDuration, cc.v2(0, 0), this.jumpHeight, 1); const callback = cc.callFunc(() => { this.jumpCount--; }); const sequence = cc.sequence(jumpAction, callback); this.player.runAction(sequence); } } spawnPlatform() { // 在场景生成平台节点 const platformNode = cc.instantiate(this.platformPrefab); // 设置平台的位置 // ... // 添加平台节点到场景 this.node.addChild(platformNode); } // 碰撞回调 onCollisionEnter(other: cc.Collider, self: cc.Collider) { if (other.node.group === 'platform') { const platform = other.node.getComponent(Platform); if (platform) { platform.bounce(); } } } } ``` 在上述代码示例,我们使用 TypeScript 编写了一个名为 `DoodleJump` 的组件,它是涂鸦跳跃游戏的主要逻辑控制器。该组件包括了玩家角色、平台预制资源以及一些相关的属性和方法。 在 `jump()` 方法,我们使用 `cc.jumpBy` 创建一个跳跃动作,并通过回调函数来处理跳跃次数的计数。按下空格键时,会调用 `jump()` 方法触发角色跳跃。 在 `spawnPlatform()` 方法,你可以根据自己的需求生成平台节点,并设置其位置信息。 在 `onCollisionEnter()` 碰撞回调,我们检测与平台的碰撞,并调用平台组件的 `bounce()` 方法来实现弹起效果。 请注意,以上代码示例仅为参考,具体的实现方式可能会因你的游戏逻辑和组件设置而有所不同。你可以根据自己的需求和项目结构进行相应的调整和扩展。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值