CocosCreator版本:2.3.4

cocos没有List组件,所以要自己写。从cocos的example项目中找到assets/case/02_ui/05_listView的demo来改造。

自写一个虚拟列表,有垂直布局,水平布局,网格布局和Padding的List

Demo地址:https://files-cdn.cnblogs.com/files/gamedaybyday/cocos2.3.4_ListViewDemo_Grid.7z

cocos原来的LayOut做列表,有100个数据就有100个实例(左侧图)。

而虚拟列表则只有你看见的实例存在,当滑动时会循环使用。(右侧图)

List使用方法

使用方法就是在ScrollView上添加List组件即可。

List的item列表项直接放在content下,并赋值給List组件,item需要添加继承自ItemRender的对象,用于数据刷新。

代码中给List设置数据

//设置排行榜数据
let rankData = [];
 for(let i=0;i<100;i  ){
      rankData.push({rank:i, name:"名称"});
}
 
this.rankList.setData(rankData);

源码

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
 
import ItemRender from "./ItemRender"
 
const { ccclass, property } = cc._decorator;
 
/**列表排列方式 */
export enum ListType {
    /**水平排列 */
    Horizontal = 1,
    /**垂直排列 */
    Vertical = 2,
    /**网格排列 */
    Grid = 3
}
 
/**网格布局中的方向 */
export enum StartAxisType {
    /**水平排列 */
    Horizontal = 1,
    /**垂直排列 */
    Vertical = 2,
}
 
/**
 * 列表
 * 根据cocos_example的listView改动而来
 * @author chenkai 2020.7.8
 * @example
 *  1.创建cocos的ScrollView组件,添加List,设置List属性即可
 * 
 */
@ccclass
export default class List extends cc.Component {
 
    //==================== 属性面板 =========================
    /**列表选项 */
    @property({ type: cc.Node, tooltip: "列表项" })
    public itemRender: cc.Node = null;
 
    /**排列方式 */
    @property({ type: cc.Enum(ListType), tooltip: "排列方式" })
    public type: ListType = ListType.Vertical;
 
    /**网格布局中的方向 */
    @property({ type: cc.Enum(StartAxisType), tooltip: "网格布局中的方向", visible() { return this.type == ListType.Grid } })
    public startAxis: StartAxisType = StartAxisType.Horizontal;
 
    /**列表项之间X间隔 */
    @property({ type: cc.Integer, tooltip: "列表项X间隔", visible() { return (this.type == ListType.Horizontal || this.type == ListType.Grid) } })
    public spaceX: number = 0;
 
    /**列表项之间Y间隔 */
    @property({ type: cc.Integer, tooltip: "列表项Y间隔", visible() { return this.type == ListType.Vertical || this.type == ListType.Grid } })
    public spaceY: number = 0;
 
    /**上间距 */
    @property({ type: cc.Integer, tooltip: "上间距", visible() { return (this.type == ListType.Vertical || this.type == ListType.Grid) } })
    public padding_top: number = 0;
 
    /**下间距 */
    @property({ type: cc.Integer, tooltip: "下间距", visible() { return (this.type == ListType.Vertical || this.type == ListType.Grid) } })
    public padding_buttom: number = 0;
 
    /**左间距 */
    @property({ type: cc.Integer, tooltip: "左间距", visible() { return (this.type == ListType.Horizontal || this.type == ListType.Grid) } })
    public padding_left: number = 0;
 
 
 
    @property(cc.Integer)
    public _padding: number = 0;
 
    /**右间距 */
    @property({ type: cc.Integer, tooltip: "右间距", visible() { return (this.type == ListType.Horizontal || this.type == ListType.Grid) } })
    public padding_right: number = 0;
 
    //====================== 滚动容器 ===============================
    /**列表滚动容器 */
    public scrollView: cc.ScrollView = null;
    /**scrollView的内容容器 */
    private content: cc.Node = null;
 
    //======================== 列表项 ===========================
    /**列表项数据 */
    private itemDataList: Array<any> = [];
    /**应创建的实例数量 */
    private spawnCount: number = 0;
    /**存放列表项实例的数组 */
    private itemList: Array<cc.Node> = [];
    /**item的高度 */
    private itemHeight: number = 0;
    /**item的宽度 */
    private itemWidth: number = 0;
    /**存放不再使用中的列表项 */
    private itemPool: Array<cc.Node> = [];
 
    //======================= 计算参数 ==========================
    /**距离scrollView中心点的距离,超过这个距离的item会被重置,一般设置为 scrollVIew.height/2   item.heigt/2   space,因为这个距离item正好超出scrollView显示范围 */
    private halfScrollView: number = 0;
    /**上一次content的X值,用于和现在content的X值比较,得出是向左还是向右滚动 */
    private lastContentPosX: number = 0;
    /**上一次content的Y值,用于和现在content的Y值比较,得出是向上还是向下滚动 */
    private lastContentPosY: number = 0;
    /**网格行数 */
    private gridRow: number = 0;
    /**网格列数 */
    private gridCol: number = 0;
    /**刷新时间,单位s */
    private updateTimer: number = 0;
    /**刷新间隔,单位s */
    private updateInterval: number = 0.1;
    /**是否滚动容器 */
    private bScrolling: boolean = false;
    /**刷新的函数 */
    private updateFun: Function = function () { };
 
    onLoad() {
        this.itemHeight = this.itemRender.height;
        this.itemWidth = this.itemRender.width;
        this.scrollView = this.node.getComponent(cc.ScrollView);
        this.content = this.scrollView.content;
        this.content.anchorX = 0;
        this.content.anchorY = 1;
        this.content.removeAllChildren();
        this.scrollView.node.on("scrolling", this.onScrolling, this);
    }
 
    /**
     * 列表数据 (列表数据复制使用,如果列表数据改变,则需要重新设置一遍数据)
     * @param itemDataList item数据列表
     */
    public setData(itemDataList: Array<any>) {
        this.itemDataList = itemDataList.slice();
        this.updateContent();
    }
 
    /**计算列表的各项参数 */
    private countListParam() {
        let dataLen = this.itemDataList.length;
        if (this.type == ListType.Vertical) {
            this.scrollView.horizontal = false;
            this.scrollView.vertical = true;
            this.content.width = this.content.parent.width;
            this.content.height = dataLen * this.itemHeight   (dataLen - 1) * this.spaceY   this.padding_top   this.padding_buttom;
            this.spawnCount = Math.round(this.scrollView.node.height / (this.itemHeight   this.spaceY))   2; //计算创建的item实例数量,比当前scrollView容器能放下的item数量再加上2个
            this.halfScrollView = this.scrollView.node.height / 2   this.itemHeight / 2   this.spaceY; //计算bufferZone,item的显示范围
            this.updateFun = this.updateV;
        } else if (this.type == ListType.Horizontal) {
            this.scrollView.horizontal = true;
            this.scrollView.vertical = false;
            this.content.width = dataLen * this.itemWidth   (dataLen - 1) * this.spaceX   this.padding_left   this.padding_right;
            this.content.height = this.content.parent.height;
            this.spawnCount = Math.round(this.scrollView.node.width / (this.itemWidth   this.spaceX))   2;
            this.halfScrollView = this.scrollView.node.width / 2   this.itemWidth / 2   this.spaceX;
            this.updateFun = this.udpateH;
        } else if (this.type == ListType.Grid) {
            if (this.startAxis == StartAxisType.Vertical) {
                this.scrollView.horizontal = false;
                this.scrollView.vertical = true;
                this.content.width = this.content.parent.width;
                //如果left和right间隔过大,导致放不下一个item,则left和right都设置为0,相当于不生效
                if (this.padding_left   this.padding_right   this.itemWidth   this.spaceX > this.content.width) {
                    this.padding_left = 0;
                    this.padding_right = 0;
                    console.error("padding_left或padding_right过大");
                }
 
                this.gridCol = Math.floor((this.content.width - this.padding_left - this.padding_right) / (this.itemWidth   this.spaceX));
                this.gridRow = Math.ceil(dataLen / this.gridCol);
                this.content.height = this.gridRow * this.itemHeight   (this.gridRow - 1) * this.spaceY   this.padding_top   this.padding_buttom;
                this.spawnCount = Math.round(this.scrollView.node.height / (this.itemHeight   this.spaceY)) * this.gridCol   this.gridCol * 2;
                this.halfScrollView = this.scrollView.node.height / 2   this.itemHeight / 2   this.spaceY;
                this.updateFun = this.updateGrid_V;
            } else if (this.startAxis == StartAxisType.Horizontal) {
                this.scrollView.horizontal = true;
                this.scrollView.vertical = false;
                //计算高间隔
                this.content.height = this.content.parent.height;
                //如果left和right间隔过大,导致放不下一个item,则left和right都设置为0,相当于不生效
                if (this.padding_top   this.padding_buttom   this.itemHeight   this.spaceY > this.content.height) {
                    this.padding_top = 0;
                    this.padding_buttom = 0;
                    console.error("padding_top或padding_buttom过大");
                }
 
                this.gridRow = Math.floor((this.content.height - this.padding_top - this.padding_buttom) / (this.itemHeight   this.spaceY));
                this.gridCol = Math.ceil(dataLen / this.gridRow);
                this.content.width = this.gridCol * this.itemWidth   (this.gridCol - 1) * this.spaceX   this.padding_left   this.padding_right;
                this.spawnCount = Math.round(this.scrollView.node.width / (this.itemWidth   this.spaceX)) * this.gridRow   this.gridRow * 2;
                this.halfScrollView = this.scrollView.node.width / 2   this.itemWidth / 2   this.spaceX;
                this.updateFun = this.updateGrid_H;
            }
        }
    }
 
    /**
     * 创建列表
     * @param startIndex 起始显示的数据索引 0表示第一项
     * @param offset     scrollView偏移量
     */
    private createList(startIndex: number, offset: cc.Vec2) {
        //当需要显示的数据长度 > 虚拟列表长度, 删除最末尾几个数据时,列表需要重置位置到scrollView最底端
        if (this.itemDataList.length > this.spawnCount && (startIndex   this.spawnCount - 1) >= this.itemDataList.length) {
            startIndex = this.itemDataList.length - this.spawnCount;
            offset = this.scrollView.getMaxScrollOffset();
 
            //当需要显示的数据长度 <= 虚拟列表长度, 隐藏多余的虚拟列表项
        } else if (this.itemDataList.length <= this.spawnCount) {
            startIndex = 0;
        }
 
        for (let i = 0; i < this.spawnCount; i  ) {
            let item: cc.Node;
            //需要显示的数据索引在数据范围内,则item实例显示出来
            if (i   startIndex < this.itemDataList.length) {
                if (this.itemList[i] == null) {
                    item = this.getItem();
                    this.itemList.push(item);
                    item.parent = this.content;
                } else {
                    item = this.itemList[i];
                }
                //需要显示的数据索引超过了数据范围,则item实例隐藏起来
            } else {
                //item实例数量 > 需要显示的数据量
                if (this.itemList.length > (this.itemDataList.length - startIndex)) {
                    item = this.itemList.pop();
                    item.removeFromParent();
                    this.itemPool.push(item);
                }
                continue;
            }
 
            let itemRender: ItemRender = item.getComponent(ItemRender);
            itemRender.itemIndex = i   startIndex;
            itemRender.data = this.itemDataList[i   startIndex];
            itemRender.dataChanged();
 
            if (this.type == ListType.Vertical) {
                //因为content的锚点X是0,所以item的x值是content.with/2表示居中,锚点Y是1,所以item的y值从content顶部向下是0到负无穷。所以item.y= -item.height/2时,是在content的顶部。
                item.setPosition(this.content.width / 2, -item.height * (0.5   i   startIndex) - this.spaceY * (i   startIndex) - this.padding_top);
            } else if (this.type == ListType.Horizontal) {
                item.setPosition(item.width * (0.5   i   startIndex)   this.spaceX * (i   startIndex)   this.padding_left, -this.content.height / 2);
            } else if (this.type == ListType.Grid) {
                if (this.startAxis == StartAxisType.Vertical) {
                    var row = Math.floor((i   startIndex) / this.gridCol);
                    var col = (i   startIndex) % this.gridCol;
                    item.setPosition(item.width * (0.5   col)   this.spaceX * col   this.padding_left, -item.height * (0.5   row) - this.spaceY * row - this.padding_top);
                    item.opacity = 255;
                } else if (this.startAxis == StartAxisType.Horizontal) {
                    var row = (i   startIndex) % this.gridRow;
                    var col = Math.floor((i   startIndex) / this.gridRow);
                    item.setPosition(item.width * (0.5   col)   this.spaceX * col   this.padding_left, -item.height * (0.5   row) - this.spaceY * row - this.padding_top);
                    item.opacity = 255;
                }
            }
        }
 
        this.scrollView.scrollToOffset(offset);
    }
 
    /**获取一个列表项 */
    private getItem() {
        if (this.itemPool.length == 0) {
            return cc.instantiate(this.itemRender);
        } else {
            return this.itemPool.pop();
        }
    }
 
    update(dt) {
        if (this.bScrolling == false) {
            return;
        }
        this.updateTimer  = dt;
        if (this.updateTimer < this.updateInterval) {
            return;
        }
        this.updateTimer = 0;
        this.bScrolling = false;
        this.updateFun();
    }
 
    onScrolling() {
        this.bScrolling = true;
    }
 
    /**垂直排列 */
    private updateV() {
        let items = this.itemList;
        let item;
        let bufferZone = this.halfScrollView;
        let isUp = this.scrollView.content.y > this.lastContentPosY;
        let offset = (this.itemHeight   this.spaceY) * items.length;
        for (let i = 0; i < items.length; i  ) {
            item = items[i];
            let viewPos = this.getPositionInView(item);
            if (isUp) {
                //item上滑时,超出了scrollView上边界,将item移动到下方复用,item移动到下方的位置必须不超过content的下边界
                if (viewPos.y > bufferZone && item.y - offset - this.padding_buttom > -this.content.height) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex   items.length;
                    itemRender.itemIndex = itemIndex;
                    itemRender.data = this.itemDataList[itemIndex];
                    itemRender.dataChanged();
                    item.y = item.y - offset;
                }
            } else {
                //item下滑时,超出了scrollView下边界,将item移动到上方复用,item移动到上方的位置必须不超过content的上边界
                if (viewPos.y < -bufferZone && item.y   offset   this.padding_top < 0) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex - items.length;
                    itemRender.itemIndex = itemIndex;
                    itemRender.data = this.itemDataList[itemIndex];
                    itemRender.dataChanged();
                    item.y = item.y   offset;
                }
            }
        }
        this.lastContentPosY = this.scrollView.content.y;
    }
 
    /**水平排列 */
    private udpateH() {
        let items = this.itemList;
        let item;
        let bufferZone = this.halfScrollView;
        let isRight = this.scrollView.content.x > this.lastContentPosX;
        let offset = (this.itemWidth   this.spaceX) * items.length;
        for (let i = 0; i < items.length; i  ) {
            item = items[i];
            let viewPos = this.getPositionInView(item);
            if (isRight) {
                //item右滑时,超出了scrollView右边界,将item移动到左方复用,item移动到左方的位置必须不超过content的左边界
                if (viewPos.x > bufferZone && item.x - offset - this.padding_left > 0) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex - items.length;
                    itemRender.itemIndex = itemIndex;
                    itemRender.data = this.itemDataList[itemIndex];
                    itemRender.dataChanged();
                    item.x = item.x - offset;
                }
            } else {
                //item左滑时,超出了scrollView左边界,将item移动到右方复用,item移动到右方的位置必须不超过content的右边界
                if (viewPos.x < -bufferZone && item.x   offset   this.padding_right < this.content.width) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex   items.length;
                    itemRender.itemIndex = itemIndex;
                    itemRender.data = this.itemDataList[itemIndex];
                    itemRender.dataChanged();
                    item.x = item.x   offset;
                }
            }
        }
        this.lastContentPosX = this.scrollView.content.x;
    }
 
    /**网格垂直排列 */
    private updateGrid_V() {
        let items = this.itemList;
        let item: cc.Node;
        let bufferZone = this.halfScrollView;
        let isUp = this.scrollView.content.y > this.lastContentPosY;
        let offset = (this.itemHeight   this.spaceY) * (this.spawnCount / this.gridCol);
        for (let i = 0; i < items.length; i  ) {
            item = items[i];
            let viewPos = this.getPositionInView(item);
            if (isUp) {
                //item上滑时,超出了scrollView上边界,将item移动到下方复用,item移动到下方的位置必须不超过content的下边界
                if (viewPos.y > bufferZone && item.y - offset - this.padding_buttom > -this.content.height) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex   (this.spawnCount / this.gridCol) * this.gridCol;
                    if (this.itemDataList[itemIndex] != null) {
                        item.y = item.y - offset;
                        itemRender.itemIndex = itemIndex;
                        itemRender.data = this.itemDataList[itemIndex];
                        itemRender.dataChanged();
                        item.opacity = 255;
                    } else {
                        item.y = item.y - offset;
                        itemRender.itemIndex = itemIndex;
                        item.opacity = 0;
                    }
                }
            } else {//item下滑时,超出了scrollView下边界,将item移动到上方复用,item移动到上方的位置必须不超过content的上边界
                if (viewPos.y < -bufferZone && item.y   offset   this.padding_top < 0) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex - (this.spawnCount / this.gridCol) * this.gridCol;
                    if (this.itemDataList[itemIndex] != null) {
                        item.y = item.y   offset;
                        itemRender.itemIndex = itemIndex;
                        itemRender.data = this.itemDataList[itemIndex];
                        itemRender.dataChanged();
                        item.opacity = 255;
                    } else {
                        item.y = item.y   offset;
                        itemRender.itemIndex = itemIndex;
                        item.opacity = 0;
                    }
                }
            }
        }
        this.lastContentPosY = this.scrollView.content.y;
    }
 
    /**网格水平排列 */
    private updateGrid_H() {
        let items = this.itemList;
        let item;
        let bufferZone = this.halfScrollView;
        let isRight = this.scrollView.content.x > this.lastContentPosX;
        let offset = (this.itemWidth   this.spaceX) * (this.spawnCount / this.gridRow);
        for (let i = 0; i < items.length; i  ) {
            item = items[i];
            let viewPos = this.getPositionInView(item);
            if (isRight) {
                //item右滑时,超出了scrollView右边界,将item移动到左方复用,item移动到左方的位置必须不超过content的左边界
                if (viewPos.x > bufferZone && item.x - offset - this.padding_left > 0) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex - (this.spawnCount / this.gridRow) * this.gridRow;
                    if (this.itemDataList[itemIndex] != null) {
                        item.x = item.x - offset;
                        itemRender.itemIndex = itemIndex;
                        itemRender.data = this.itemDataList[itemIndex];
                        itemRender.dataChanged();
                        item.opacity = 255;
                    } else {
                        item.x = item.x - offset;
                        itemRender.itemIndex = itemIndex;
                        item.opacity = 0;
                    }
                }
            } else {
                //item左滑时,超出了scrollView左边界,将item移动到右方复用,item移动到右方的位置必须不超过content的右边界
                if (viewPos.x < -bufferZone && item.x   offset   this.padding_right < this.content.width) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex   (this.spawnCount / this.gridRow) * this.gridRow;
                    if (this.itemDataList[itemIndex] != null) {
                        item.x = item.x   offset;
                        itemRender.itemIndex = itemIndex;
                        itemRender.data = this.itemDataList[itemIndex];
                        itemRender.dataChanged();
                        item.opacity = 255;
                    } else {
                        item.x = item.x   offset;
                        itemRender.itemIndex = itemIndex;
                        item.opacity = 0;
                    }
                }
            }
        }
        this.lastContentPosX = this.scrollView.content.x;
    }
 
    /**获取item在scrollView的局部坐标 */
    private getPositionInView(item) {
        let worldPos = item.parent.convertToWorldSpaceAR(item.position);
        let viewPos = this.scrollView.node.convertToNodeSpaceAR(worldPos);
        return viewPos;
    }
 
    /**获取列表数据 */
    public getListData() {
        return this.itemDataList;
    }
 
    /**
     * 增加一项数据到列表的末尾
     * @param data 数据
     */
    public addItem(data: any) {
        this.itemDataList.push(data);
        this.updateContent();
    }
 
    /**
     * 增加一项数据到列表指定位置
     * @param index   位置,0表示第1项
     * @param data  数据
     */
    public addItemAt(index: number, data: any) {
        if (this.itemDataList[index] != null || this.itemDataList.length == index) {
            this.itemDataList.splice(index, 1, data);
            this.updateContent();
        }
    }
 
    /**
     * 删除一项数据
     * @param index 删除项的位置 ,0表示第1项
     */
    public deleteItem(index: number) {
        if (this.itemDataList[index] != null) {
            this.itemDataList.splice(index, 1);
            this.updateContent();
        }
    }
 
    /**
     * 改变一项数据
     * @param index   位置,0表示第1项
     * @param data  替换的数据
     */
    public changeItem(index: number, data: any) {
        if (this.itemDataList[index] != null) {
            this.itemDataList[index] = data;
            this.updateContent();
        }
    }
 
    /**获取第一个Item的位置 */
    private updateContent() {
        //显示列表实例为0个
        if (this.itemList.length == 0) {
            this.countListParam();
            this.createList(0, new cc.Vec2(0, 0));
            //显示列表的实例不为0个,则需要重新排列item实例数组
        } else {
            if (this.type == ListType.Vertical) {
                this.itemList.sort((a: any, b: any) => {
                    return b.y - a.y;
                });
            } else if (this.type == ListType.Horizontal) {
                this.itemList.sort((a: any, b: any) => {
                    return a.x - b.x;
                });
            } else if (this.type == ListType.Grid) {
                if (this.startAxis == StartAxisType.Vertical) {
                    this.itemList.sort((a: any, b: any) => {
                        return a.x - b.x;
                    });
                    this.itemList.sort((a: any, b: any) => {
                        return b.y - a.y;
                    });
                } else if (this.startAxis == StartAxisType.Horizontal) {
                    this.itemList.sort((a: any, b: any) => {
                        return b.y - a.y;
                    });
                    this.itemList.sort((a: any, b: any) => {
                        return a.x - b.x;
                    });
                }
            }
 
            this.countListParam();
 
            //获取第一个item实例需要显示的数据索引
            var startIndex = this.itemList[0].getComponent(ItemRender).itemIndex;
 
            if (this.type == ListType.Grid && this.startAxis == StartAxisType.Vertical) {
                startIndex  = (startIndex   this.spawnCount) % this.gridCol;
            } else if (this.type == ListType.Grid && this.startAxis == StartAxisType.Horizontal) {
                startIndex  = (startIndex   this.spawnCount) % this.gridRow;
            }
 
            //getScrollOffset()和scrollToOffset()的x值是相反的
            var offset: cc.Vec2 = this.scrollView.getScrollOffset();
            offset.x = - offset.x;
 
            this.createList(startIndex, offset);
        }
    }
 
    /**销毁 */
    public onDestroy() {
        //清理列表项
        let len = this.itemList.length;
        for (let i = 0; i < len; i  ) {
            if (cc.isValid(this.itemList[i], true)) {
                this.itemList[i].destroy();
            }
        }
        this.itemList.length = 0;
        //清理对象池
        len = this.itemPool.length;
        for (let i = 0; i < len; i  ) {
            if (cc.isValid(this.itemPool[i], true)) {
                this.itemPool[i].destroy();
            }
        }
        this.itemPool.length = 0;
        //清理列表数据
        this.itemDataList.length = 0;
    }
}

以上就是如何在CocosCreator中做一个List的详细内容,更多关于CocosCreator List的资料请关注Devmax其它相关文章!

如何在CocosCreator中做一个List的更多相关文章

  1. ios – 如何使用blender和PowerVR SDK为cocos3d创建一个简单的3d球体

    我是cocos3d的新手.我想创建一个简单的项目–旋转的3d球体.我用搅拌机设计了一个3d球体.所以我想要帮助创建collada文件和pod文件.使用blender和PowerVRSDK创建这个简单的3d对象时应该注意什么.谢谢解决方法如何在搅拌机中制作简单的球体,然后使用JeffLamarche的Blender-to-iOSscript将其导出?这甚至不需要Cocos或PowerVR,但这是一个良好的开端.由于您可以在iOS中轻松地将Cocos与非Cocos类集成,因此可能会有所帮助.你可以更进一步,利

  2. Swift 字符串替换/过滤/切割/拼接

    替换为/结果过滤过滤掉单个字符/结果过滤掉开头和结尾的空白结果切割对字符串使用/作为分隔符来切割,不允许空字符串使用split函数结果是一个数组对字符串使用/作为分隔符来切割,允许空字符串结果拼接结果

  3. Swift开发教程--字符串的操作

    替换把?替换为/结果

  4. swift 网络搜索热词排行

    1.使用www.showapi.com上的接口,需要注册添加一个App,这样才能获取appid和secret密钥,调用前需要订购套餐(选免费的就可以了);2.外部库Podfile文件内容,SnapKit这里暂时不需要用到:3.桥接头文件参考:http://www.jb51.cc/article/p-pcleyxep-te.html4.AppTransportSecurityhasblockedac

  5. 如何在Swift中打乱数组?

    如何随机化或混洗Swift中的数组中的元素?例如,如果我的数组包括52张扑克牌,我想洗牌,以便洗牌。这个答案详细说明了如何在Swift的各种版本中添加Fisher-Yatesshuffle。Swift3版本是最宽松的,但是它们至少可以用于数组。每个Swift版本的命名和行为与该版本的mutating和nonmutating排序方法相匹配。

  6. unit-testing – 如何在Swift中对NSFetchedResultsController进行单元测试

    我有一个Swift应用程序,它使用NSFetchedResultsController从持久存储中获取List对象:它的工作方式与预期的一样,我将List对象描述打印到控制台.我想为我的应用程序编写一些单元测试,所以我创建了扩展XCTestCase的类.代码编译没有问题,测试运行,但不幸的是我无法在该上下文中获取List对象.我在控制台中获得的所有内容都是List对象的数量和致命错误:线路上升:我

  7. swift – 检查自定义对象数组是否包含特定的自定义对象

    说我有一个非常简单的Person类我希望将一个这样的人的集合存储在一个属性中,该属性是一个Person类的数组,类型为Person也许我实现如下问题:我如何检查people.list是否包含实例alex,好吗?

  8. swift – 使用反射来设置对象属性,而不使用setValue forKey

    在Swift中,不可能使用.setValue(…)>可空类型字段,如Int?>具有枚举类型的属性>一个可空对象的数组,如[MyObject?]这有一个解决方法,也就是通过覆盖对象本身中的UnVersionKey方法的setValue.因为我正在写一个基于反射的通用对象映射器.请参阅EVReflection我想尽量减少这种手动映射.是否有其他方式自动设置这些属性?

  9. Swift Sliceable上的递归

    事实证明,有一个通用的解决方案.您需要添加这些通用要求:对于发布的问题,这给出了:这是任何切片上有用的通用缩减:我不能相信这一点,Apple开发论坛上的解决方案是posted.令人遗憾的是,通用要求如此涉及到这样一个基本操作–它几乎不直观!

  10. uitableview – 使用Swift的“使用未解析的标识符”

    我正在重写我在Swift中的一个应用程序,它显示SouthKohala的实时天气数据.爱Swift到目前为止!

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部