IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> cocos 贝塞尔曲线编辑器 -> 正文阅读

[游戏开发]cocos 贝塞尔曲线编辑器

贝塞尔曲线的定义我就不详细说了,网上很多资料都有介绍可以用递归方法求曲线点也可以用迭代法求解,这里使用迭代法求点,总的来说就是第一个控制点到第二个控制点的细分点和第二个到第三个控制点连成的线,其他的更高阶的以此类推,知道迭代到点的集合的长度为1,

这里采用左键单击画布就会生成一个控制点,根据控制点进行步进生成点进而绘制出来:


const {ccclass, property,requireComponent} = cc._decorator;

export interface Vector2 {
    x: number,
    y: number
}

@ccclass
@requireComponent(cc.Graphics)
export default class BezierTest extends cc.Component {

    @property(cc.Prefab)
    dotPrefab: cc.Prefab = null;

    @property(cc.Prefab)
    settingPrefab: cc.Prefab = null;

    @property(cc.Graphics)
    pen: cc.Graphics = null;

    @property(cc.Node)
    box: cc.Node = null;

    @property({
        type: cc.Integer,
        tooltip: '步进长度,帧率,控制t'
    })
    stepFrame: number = 60;

    /** 控制点数组 */
    private _controllPoints: Vector2[] = [];

    /** 生成的目标点信息 即贝塞尔曲线的信息 */
    private _targetPoints: Vector2[] = [];

    private _controllNodes: cc.Node[] = [];

    onLoad () {

    }

    protected onEnable(): void {
        this.node.on(cc.Node.EventType.TOUCH_END,this.tapEnd,this);
        cc.director.on('repaint',this.repaint,this);
        cc.director.on('exportData',this.exportData,this);
        cc.director.on('clear',this.clearAllData,this);
    }   
    
    protected onDisable(): void {
        this.node.off(cc.Node.EventType.TOUCH_END,this.tapEnd,this);
        cc.director.off('repaint',this.repaint,this);
        cc.director.off('exportData',this.exportData,this);
        cc.director.off('clear',this.clearAllData,this);
        
    }

    exportData(): void {
        console.log('export');
        if(this._targetPoints.length > 0) {
            this._targetPoints = this._targetPoints.map(item => ({
                x: item.x,
                y: item.y,
                rotate: 0
            }))

            let len = this._targetPoints.length;
            for(let i = 0; i < len - 1; i++) {
                let cur = this._targetPoints[i];
                let next = this._targetPoints[i + 1];

                let offsetY = next.y - cur.y;
                let offsetX = next.x - cur.x;
                let tanRes = offsetY / offsetX;

                let r = Math.atan(tanRes);
                let angle = 180 * r / Math.PI;
                // 设置经过该点的角度值
                cur['rotate'] = angle;

            }

            this._targetPoints[len - 1]['rotate'] = this._targetPoints[len - 2]['rotate'];
            console.log('targetPoint is ',this._targetPoints);

            const blob = new Blob([JSON.stringify(this._targetPoints)],{type: 'application/json'});
            const a = document.createElement('a');
            a.href = window.webkitURL.createObjectURL(blob);
            a.download = '';
            a.click();
        }
    }

    clearAllData(): void {
        this.pen.clear();
        this._controllNodes.length = 0;
        this._controllPoints.length = 0;
    }

    /** 重新绘制 */
    repaint(): void {
        this._controllPoints = [];
        this._controllNodes.forEach(item => {
            this._controllPoints.push(item.position);
        });

        this.checkControllPoints();
    }

    tapEnd(event: cc.Event.EventTouch) {
        // 生成点
        const localPos = this.node.convertToNodeSpaceAR(event.getLocation());
        if(event.target == this.node) {
            const dotNode = cc.instantiate(this.dotPrefab);
            this.node.addChild(dotNode);
            dotNode.setPosition(localPos);
            this._controllPoints.push(localPos);
            this._controllNodes.push(dotNode);
        }

        this.checkControllPoints();
    }

    checkControllPoints() {
        /** 清空路径点 */
        this._targetPoints = [];

        if(this._controllPoints.length > 1) {
            // 绘制
            for(let i = 0; i <= this.stepFrame; i++) {
                this.changeT(i / this.stepFrame);
            }

            console.log('targetpoints is',this._targetPoints);
            
            this.pen.clear();
            this.drawControllPoints();
            if(this._targetPoints.length > 1) {
                this.pen.strokeColor = cc.color().fromHEX('#ff0000');
                this._targetPoints.forEach((item,index) => {
                    if(!index) {
                        this.pen.moveTo(item.x,item.y);
                    } else {
                        this.pen.lineTo(item.x,item.y);
                    }
                });
                this.pen.stroke();
            }
        }
    }

    drawControllPoints(): void {
        this.pen.strokeColor = cc.color().fromHEX('#dcdcdc');
        this._controllPoints.forEach((item,index) => {
            if(!index) {
                this.pen.moveTo(item.x,item.y);
            } else {
                this.pen.lineTo(item.x,item.y);
            }
        });

        this.pen.stroke();
    }

    /** 改变时间参数t 关键代码 */
    changeT(ratio: number): void {
        console.log('ratio is ',ratio);

        let tempPosArr: Vector2[] = [];
        for(let i = 0,len = this._controllPoints.length; i < len - 1; i++) {
            let deltaX = this._controllPoints[i + 1].x - this._controllPoints[i].x;
            let deltaY = this._controllPoints[i + 1].y - this._controllPoints[i].y;

            let x = this._controllPoints[i].x + deltaX * ratio;
            let y = this._controllPoints[i].y + deltaY * ratio;

            let targetPoint = {x,y};
            tempPosArr.push(targetPoint);
        }
        console.log('tempPosArr is ',tempPosArr);

        // 一直迭代直到tempPosArr的长度为1
        while(tempPosArr.length > 1) {
            let posArrLen = tempPosArr.length;
            for(let i = 0, len = tempPosArr.length; i < len - 1; i++) {
                let deltaX = tempPosArr[i + 1].x - tempPosArr[i].x;
                let deltaY = tempPosArr[i + 1].y - tempPosArr[i].y;

                let x = tempPosArr[i].x + deltaX * ratio;
                let y = tempPosArr[i].y + deltaY * ratio;

                let tp = {x,y};

                tempPosArr.push(tp);
            }
            tempPosArr.splice(0,posArrLen);
        }

        if(tempPosArr.length === 1) {
            this._targetPoints.push(tempPosArr[0]);
        }
    }

    async play() {
        this.box.active = true;
        for(let item of this._targetPoints) {
            this.box.setPosition(cc.v2(item.x,item.y));
            this.box.angle = item['rotate'];

            await new Promise((resolve) => {
                setTimeout(resolve,100);
            })
        }
    }

    settingsEvent() {
        const settingNode = cc.instantiate(this.settingPrefab);
        this.node.addChild(settingNode);
    }

    start () {

    }

    // update (dt) {}
}

导出数据的时候需要计算每个点需要旋转的角度值,这里做的比较粗略,因为曲线上的点比较密集,就粗略计算两个点之间的坐标差值求正切得到角度值,导出的时候需要用到blob对象来创建下载链接

const blob = new Blob([JSON.stringify(this._targetPoints)],{type: 'application/json'});

const a = document.createElement('a');

a.href = window.webkitURL.createObjectURL(blob);

a.download = '';

a.click();

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-02-24 15:38:55  更:2022-02-24 15:39:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 16:48:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码