ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

爆款游戏开发零基础·第六季-常用编程框架和算法

2021-06-07 18:01:23  阅读:200  来源: 互联网

标签:GrideType cc 编程 爆款 DataGrid 算法 let grid 节点


第六季-常用编程框架和算法

01.MVC架构

是一种设计程序的思路/套路.

MVC的含义

  1. M-Model模型(数据)
    FlappyBird中小鸟的位置,当前激活的节点等等
  2. V-View视觉层
    展示出来的界面,通常是引擎进行处理
  3. C-Controller控制器(逻辑)
    写下的代码,小鸟碰到管子判断游戏结束

总结内涵:拿数据-根据逻辑-刷新界面

02.单例模式

单例(instance)的特点

  1. 单例类,全局只有一个对象,不可能产生多个
  2. 在代码任意位置容易获取这个对象

作用

防止一个全局使用的类频繁的实现与销毁
控制实例数目,节省系统资源

实现

/**单例类 */
export default class InstanceDemo {
    /**全局唯一的对象 */
    private static _instance: InstanceDemo = null; //private的变量名前一般加个_

    /**获取单例对象 */
    public static getInstance(): InstanceDemo{
        if (InstanceDemo._instance == null){
            InstanceDemo._instance = new InstanceDemo();
        }
        return InstanceDemo._instance;
    }

    /**防止创建第二个对象 */
    constructor(){
        if (InstanceDemo._instance != null) {
            throw Error("Already has InstanceDemo._instance");
        }
    }

    num: number = 0;

    trace(){
        this.num ++;
        console.log("trace",this.num);
    }
}

调用

import InstanceDemo from "./instanceDemo";

const {ccclass, property} = cc._decorator;

@ccclass
export default class HelloWorld extends cc.Component {

    start () {
        /**获取单例对象 */
        let instance = InstanceDemo.getInstance();
        /**调用单例方法 */
        instance.trace();

        //创建对象
        new InstanceDemo();
    }

    // update (dt) {}
}

结果

在这里插入图片描述

补充

实现单例模式,将构造函数私有化就好了

/**私有化构造函数*/
private constructor(){}

03.观察者模式-订阅发布模式

流程

  1. A订阅了开始游戏事件
  2. B抛出(发布)了开始游戏事件
  3. A响应事件

特点:A不管什么时候出发,只负责触发时接受,B不知道谁注册了事件,只负责触发.

实现

将WebStorm改为ES6:File→Setting→Languages&Framework→JavaScript→选择ES6
还要将typescriptconfig.json里的“ES5”改为“ES6”
在这里插入图片描述

EventCenter.ts 事件控制中心
EventHandler 记录事件信息

/**观察者模式 */
export default class EventCenter {
    //事件数据 存放事件名和注册该事件的注册信息们
    private static events: Map<string,Array<EventHandler>> = new Map<string,Array<EventHandler>>();

    /**注册事件
     * eventName: string 事件名
     * target: object 谁注册的事件 用于回调绑定
     * callBack: Function 回调
     */
    static registerEvent(eventName: string,target: object,callBack: Function): void {
        if (eventName == undefined || target == undefined || callBack == undefined) {
            throw Error("regsiter event error");
        }
        /**判断是否已经有该事件被注册过 */
        if (EventCenter.events[eventName] == undefined){
            EventCenter.events[eventName] = new Array<EventHandler>();
        }

        /**将此次注册事件的信息存入Map中 */
        let handler = new EventHandler(target,callBack);
        EventCenter.events[eventName].push(handler);
    }

    /**触发事件
     * eventName: string 事件名
     * param?: any 回调参数
     */
    static postEvent(eventName: string,param?: any): void {
        let handlers = EventCenter.events[eventName];
        if (handlers == undefined){
            return;
        }

        //遍历所有注册了该事件的eventHandler
        for (let i = 0; i < handlers.length; i++){
            let handler = handlers[i];
            if (handler){
                //调用事件回调
                //使用try-catch防止回调有报错但没有信息
                try {
                    //.call(绑定的this,参数) 调用方法
                    handler.function.call(handler.target,param);
                }catch (e){
                    console.log(e.message);
                    console.log(e.stack.toString()); //输出堆栈信息
                }
            }
        }
    }

    /**移除注册事件
     * eventName: string 事件名
     * target: object 谁注册的事件 用于回调绑定
     * callBack: Function 注册事件回调
     */
    static removeEvent(eventName: string,target: object,callBack: Function): void {
        if (eventName == undefined || target == undefined || callBack == undefined) {
            throw Error("destory event failed");
        }
        let handlers = EventCenter.events[eventName];
        if (handlers){
            for (let i = 0; i < handlers.length; i++){
                let handler = handlers[i];
                if (handler && target == handler.target && callBack == handler.function){
                    //有两种移除方法 "= undefined"性能要好 "splice"要省内存空间
                    handlers[i] = undefined;
                    // handlers.splice(i,1);
                    break;
                }
            }
        }
    }

}

/**注册信息类 */
class EventHandler {
    /**记录谁注册了事件 */
    target: object;
    /**记录事件触发时调用的方法 */
    function: Function;

    constructor(target: object,func: Function){
        this.target = target;
        this.function = func;
    }
}

Panel.ts 用来注册事件

import EventCenter from "./EventCenter";

/**用来注册事件 检验观察者模式 */
const {ccclass, property} = cc._decorator;

@ccclass
export default class Panel extends cc.Component {

    @property(cc.Label)
    label: cc.Label = null;

    onl oad () {
        EventCenter.registerEvent("gameStart",this,this.onGameStart);
        //5s后移除事件注册
        this.scheduleOnce(function() {
            this.onDestroy();
        }.bind(this),5)
    }

    /**注册事件回调 */
    onGameStart(str: string){
        console.log("event callBack");
        this.label.string = str;
    }

    onDestroy(){
        //移除gameStart事件
        console.log("remove event gameStart");
        EventCenter.removeEvent("gameStart",this,this.onGameStart);
    }
}

触发事件

EventCenter.postEvent("gameStart","game is start!");

结果

在这里插入图片描述
点击按钮

在这里插入图片描述
输出
在这里插入图片描述

注意:target节点destory后,一定要记得注销其注册的事件。否则callBack会出错

04.工厂模式

特点和作用

操作的对象本身只实现功能方法,具体的操作由工厂实现
这样不会暴露对象及创建逻辑

实现

/**工厂模式 */

//c: {new ():T} 告诉ide这个T类型的c是可以被实例化的
export function createAttack<T extends IActor>(c: {new (): T},life: number): T {
    let object = new c();
    object.attack();
    object.life = life;
    return object;
}

export function createDie<T extends IActor>(c: {new (): T}): T {
    let object = new c();
    object.die();
    return object;
}

/**角色接口 */
interface IActor {
    attack: Function;
    die: Function;
    life: number;
}

/**盗贼 */
export class Thief implements IActor {
    life: number;
    attack() {
        console.log("thief attack");
    }
    die() {
        console.log("thief is die");
    }
}

/**战士 */
export class Warrior implements IActor {
    life: number;
    attack() {
        console.log("warrior attack");
    }
    die() {
        console.log("warrior is die");
    }
}

调用

	createAttack<Thief>(Thief,10);
    createDie<Warrior>(Warrior);

05.代理模式

代理 (额外的控制器)

  1. 单一原则,不给一个类太多功能.
    自己的功能留在类里面,将一些逻辑控制放到外面.
    高内聚,低耦合.
  2. 不方便访问一个类的时候,给个代理
    例如:明星和经纪人的关系;
    快递中发货人-快递-收货人;
    cc.loader.load(…)内部非常复杂,但对于调用的人来说并不关 心内部逻辑.

06.递归寻路

题目

需要从①走到②,要怎么走(可以斜着走,褐色是不能走的)
在这里插入图片描述

步骤

  1. 把起点当作当前节点
  2. 重复以下步骤
    a. 把当前节点加入openList,标记Open
    b.查找可以走的下一步节点
    c.把下一步可以走的节点排序
    d.把下一步可以走的离终点最近的点,当做当前的寻路节点
    e.把走过的节点标记为Close
  3. 直到查找到目标节点

实战

先制作格子 NodeGrid.ts

import FindPath from "./FindPath";

/**寻路地图格子 */
const {ccclass, property} = cc._decorator;
/**格子 显示层 */
@ccclass
export default class NodeGrid extends cc.Component {
    dataGrid: DataGrid = null;
    findPathController: FindPath;

    onl oad () {
        this.node.on(cc.Node.EventType.TOUCH_END,this.onBtnGrid,this);
    }

    /**点击格子 确定起点终点 生成路线 */
    onBtnGrid(){
        this.findPathController.onTouch(this);
    }

    /**刷新格子颜色 */
    updateGridColor(){
        if (this.dataGrid.type == GrideType.Normal){
            this.node.color = new cc.Color().fromHEX("#fffff9");
        } else if (this.dataGrid.type == GrideType.Wall){
            this.node.color = new cc.Color().fromHEX("#151513");
        } else if (this.dataGrid.type == GrideType.Road){
            this.node.color = new cc.Color().fromHEX("#41ff0b");
        } else {
            this.node.color = new cc.Color().fromHEX("#fff42d");
        } 
    }
}

/**格子数据 数据层 */
export class DataGrid {
    type: GrideType;
    //坐标
    x: number;
    y: number;
    /**是否为当前节点 */
    inOpenList: boolean = false;
    /**路径节点标记 */
    inCloseList: boolean = false;
}

/**格子类型枚举 */
export enum GrideType {
    Normal, //普通
    Wall, //墙
    Start, //起点,当前节点
    End, //终点
    Road, //路线
}

在场景下创建一个40x40的格子,并挂载NodeGrid.ts
在这里插入图片描述

制作地图

/**随机生成8x8地图 */
    generateMap () {
        for (let x = 0;x < 8;x ++){
            this.dataGrids[x] = [];
            this.nodeGrids[x] = [];
            for (let y = 0;y < 8;y ++){
                let rand = Math.random();
                let grideType: GrideType = GrideType.Normal;
                if (rand < 0.2) { //1/5的概率生成墙
                    grideType = GrideType.Wall;
                }
                //数据层
                let grid: DataGrid = new DataGrid();
                grid.x = x;
                grid.y = y;
                grid.type = grideType;
                this.dataGrids[x][y] = grid;

                //视图层
                let gridNode: NodeGrid = cc.instantiate(this.nodeGridPrefab).getComponent(NodeGrid);
                gridNode.node.position = cc.v3(50 * (x - 4),50 * (y - 4),0);
                this.nodeGrids[x][y] = gridNode;
                gridNode.dataGrid = grid;
                gridNode.findPathController = this;
                gridNode.updateGridColor();
                gridNode.node.parent = this.node;
            }
        }
    }

寻路(完整代码 FindPath.ts)

import NodeGrid, { DataGrid, GrideType } from "./NodeGrid";

/**递归寻路 */
const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {
    /**格子节点 */
    @property(cc.Node)
    nodeGridPrefab: cc.Node = null;

    dataGrids: DataGrid[][] = [];
    nodeGrids: NodeGrid[][] = [];

    /**记录起点 */
    startGrid: DataGrid = null;
    /**记录终点 */
    endGrid: DataGrid = null;

    onl oad () {
        this.generateMap();
    }

    /**随机生成8x8地图 */
    generateMap () {
        for (let x = 0;x < 8;x ++){
            this.dataGrids[x] = [];
            this.nodeGrids[x] = [];
            for (let y = 0;y < 8;y ++){
                let rand = Math.random();
                let grideType: GrideType = GrideType.Normal;
                if (rand < 0.2) { //1/5的概率生成墙
                    grideType = GrideType.Wall;
                }
                //数据层
                let grid: DataGrid = new DataGrid();
                grid.x = x;
                grid.y = y;
                grid.type = grideType;
                this.dataGrids[x][y] = grid;

                //视图层
                let gridNode: NodeGrid = cc.instantiate(this.nodeGridPrefab).getComponent(NodeGrid);
                gridNode.node.position = cc.v3(50 * (x - 4),50 * (y - 4),0);
                this.nodeGrids[x][y] = gridNode;
                gridNode.dataGrid = grid;
                gridNode.findPathController = this;
                gridNode.updateGridColor();
                gridNode.node.parent = this.node;
            }
        }
    }

    /**点击格子 */
    onTouch(nodeGrid: NodeGrid){
        if (!this.startGrid) { //设置起点
            this.startGrid = nodeGrid.dataGrid;
            this.startGrid.type = GrideType.Start;
            nodeGrid.updateGridColor();
        }else if (!this.endGrid) { //设置终点
            this.endGrid = nodeGrid.dataGrid;
            this.endGrid.type = GrideType.End;
            nodeGrid.updateGridColor();

            //寻路
            this.startFindPath();
        }
    }

    openPath: DataGrid[] = [];

    /**寻路 */
    startFindPath(){
        if (this.find(this.startGrid)) {
            for (let i = 0; i < this.openPath.length; i++) {
                let path = this.openPath[i];
                path.type = GrideType.Road;
                this.nodeGrids[path.x][path.y].updateGridColor();
            }
        }else {
            console.log("无法走到终点");
        }
    }

    find(base: DataGrid) {
        this.openPath.push(base);
        base.inOpenList = true;
        if (base == this.endGrid){ //寻路结束
            return true;
        }
        let round = this.getRoundGrid(base);
        for (let i = 0;i < round.length;i ++) {
            let nextBaseGride = round[i];
            if (this.find(nextBaseGride)) {
                return true;
            }
        }

        base.inCloseList = true;
        this.openPath.splice(this.openPath.length - 1,1);
        return false;
    }

    /**获取当前节点周围可走的节点 */
    getRoundGrid(grid: DataGrid): DataGrid[] {
        let arr: DataGrid[] = [];
        //周围的格子
        this.addToRoundIfNeed(arr,this.getGrid(grid.x,grid.y + 1));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x - 1,grid.y));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x,grid.y - 1));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x + 1,grid.y));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x - 1,grid.y - 1));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x + 1,grid.y + 1));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x + 1,grid.y - 1));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x - 1,grid.y + 1));

        //会将数组里元素两两进行比较,自定义方法里返回-1就不交换位置 返回1交换位置
        arr.sort(this.compareGrids.bind(this));

        return arr;
    }

    /**将格子放到数组里 */
    addToRoundIfNeed(arr: DataGrid[],roundGrid: DataGrid) {
        //当前节点和路径节点都不计入
        if (!roundGrid || roundGrid.type == GrideType.Wall || roundGrid.inCloseList || roundGrid.inOpenList){
            return;
        }
        if (roundGrid) {
            arr.push(roundGrid);
        }
    }

    /**根据坐标获取格子数据 */
    getGrid(x: number,y: number): DataGrid {
        //边界判断
        if (x < 0 || x >= 8 || y < 0 || y >=8){
            return null;
        }
        return this.dataGrids[x][y];
    }

    /**格子比较和终点的距离
     * 距离小的放在前面
     */
    compareGrids(grid0: DataGrid,grid1: DataGrid): number{
        let grid0Dis = this.getDistance(grid0);
        let grid1Dis = this.getDistance(grid1);
        if (grid0Dis > grid1Dis) {
            return 1;
        }else{
            return -1;
        }
    }

    /**获取节点到终点距离 */
    getDistance(grid: DataGrid){
        return Math.abs(grid.x - this.endGrid.x) + Math.abs(grid.y - this.endGrid.y);
    }

    /**点击重新开始*/
    onBtnRestart(){
        for (let x = 0;x < this.dataGrids.length;x ++){
            for (let y = 0;y < this.dataGrids[x].length;y ++){
                let dataGrid = this.dataGrids[x][y];
                dataGrid.inOpenList = false;
                dataGrid.inCloseList = false;
                if (dataGrid.type != GrideType.Wall){
                    dataGrid.type = GrideType.Normal;
                }
                this.nodeGrids[x][y].updateGridColor();
            }
        }
        this.startGrid = null;
        this.endGrid = null;
        this.openPath = [];
    }

}

运行结果

在这里插入图片描述

不足

当前算法只是寻找下一步的最优解,并不是全局的最优解,有时并不是最优路径。

07.A星寻路

可以看下大神写的A星寻路算法原理

步骤

  1. 把起点当做当前节点
  2. 重复以下步骤
    a.把当前节点加入openList,标记Open
    b.查找可以走的下一步节点
    c.把下一步可以走的节点的父节点,设置为当前节点
    d.把下一步可以走的节点加入到openList,排序
    e.把openList中的第一个节点,当做当前节点
    f.把走过的节点标记为Close
  3. 直到查找到目标节点

实现

DataGrid添加一个字段

/**父节点 用于A星寻路 */
fatherGrid: DataGrid = null;

FindPathAX.ts完整代码

/**A星寻路 */
import NodeGrid, { DataGrid, GrideType } from "./NodeGrid";

const {ccclass, property} = cc._decorator;

@ccclass
export default class FindPathAX extends cc.Component {
    /**格子节点 */
    @property(cc.Node)
    nodeGridPrefab: cc.Node = null;

    dataGrids: DataGrid[][] = [];
    nodeGrids: NodeGrid[][] = [];

    /**记录起点 */
    startGrid: DataGrid = null;
    /**记录终点 */
    endGrid: DataGrid = null;

    onl oad () {
        this.generateMap();
    }

    /**随机生成8x8地图 */
    generateMap () {
        for (let x = 0;x < 8;x ++){
            this.dataGrids[x] = [];
            this.nodeGrids[x] = [];
            for (let y = 0;y < 8;y ++){
                let rand = Math.random();
                let grideType: GrideType = GrideType.Normal;
                if (rand < 0.2) { //1/5的概率生成墙
                    grideType = GrideType.Wall;
                }
                //数据层
                let grid: DataGrid = new DataGrid();
                grid.x = x;
                grid.y = y;
                grid.type = grideType;
                this.dataGrids[x][y] = grid;

                //视图层
                let gridNode: NodeGrid = cc.instantiate(this.nodeGridPrefab).getComponent(NodeGrid);
                gridNode.node.position = cc.v3(50 * (x - 4),50 * (y - 4),0);
                this.nodeGrids[x][y] = gridNode;
                gridNode.dataGrid = grid;
                gridNode.findPathController = this;
                gridNode.updateGridColor();
                gridNode.node.parent = this.node;
            }
        }
    }

    /**点击格子 */
    onTouch(nodeGrid: NodeGrid){
        if (!this.startGrid) { //设置起点
            this.startGrid = nodeGrid.dataGrid;
            this.startGrid.type = GrideType.Start;
            nodeGrid.updateGridColor();
        }else if (!this.endGrid) { //设置终点
            this.endGrid = nodeGrid.dataGrid;
            this.endGrid.type = GrideType.End;
            nodeGrid.updateGridColor();

            //寻路
            this.startFindPathAStar();
        }
    }

    /**待考虑的节点列表 */
    openPath: DataGrid[] = [];

    /**A星寻路 */
    startFindPathAStar(){
        this.openPath.push(this.startGrid);
        this.startGrid.inOpenList = true;

        while (this.openPath.length > 0) {
            let current = this.openPath.shift(); //shift--取出数组中首个元素

            if (current == this.endGrid) {
                break;
            }
            let round = this.getRoundGrid(current);

            for (let i = 0;i < round.length;i ++) {
                let r = round[i];
                r.fatherGrid = current;
                r.inOpenList = true;
            }

            this.openPath = this.openPath.concat(round); //拼接数组
            this.openPath.sort(this.compareGridsAStar.bind(this));

            current.inCloseList = true;
        }

        if (this.endGrid.fatherGrid) {
            let pathGrid = this.endGrid;

            while (pathGrid) {
                pathGrid.type == GrideType.Road;
                this.nodeGrids[pathGrid.x][pathGrid.y].updateGridColor();
                pathGrid = pathGrid.fatherGrid;
            }
        }else {
            console.log("没有路径可走");
        }
    }

    /**获取当前节点周围可走的节点 */
    getRoundGrid(grid: DataGrid): DataGrid[] {
        let arr: DataGrid[] = [];
        //周围的格子
        this.addToRoundIfNeed(arr,this.getGrid(grid.x,grid.y + 1));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x - 1,grid.y));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x,grid.y - 1));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x + 1,grid.y));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x - 1,grid.y - 1));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x + 1,grid.y + 1));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x + 1,grid.y - 1));
        this.addToRoundIfNeed(arr,this.getGrid(grid.x - 1,grid.y + 1));

        //会将数组里元素两两进行比较,自定义方法里返回-1就不交换位置 返回1交换位置
        arr.sort(this.compareGridsAStar.bind(this));

        return arr;
    }

    /**将格子放到数组里 */
    addToRoundIfNeed(arr: DataGrid[],roundGrid: DataGrid) {
        //当前节点和路径节点都不计入
        if (!roundGrid || roundGrid.type == GrideType.Wall || roundGrid.inCloseList || roundGrid.inOpenList){
            return;
        }
        if (roundGrid) {
            arr.push(roundGrid);
        }
    }

    /**根据坐标获取格子数据 */
    getGrid(x: number,y: number): DataGrid {
        //边界判断
        if (x < 0 || x >= 8 || y < 0 || y >=8){
            return null;
        }
        return this.dataGrids[x][y];
    }

    /**格子排序 优化
     * 距离小的放在前面
     */
     compareGridsAStar(grid0: DataGrid,grid1: DataGrid): number{
        let grid0Dis = this.getDistanceAStar(grid0,this.startGrid,this.endGrid);
        let grid1Dis = this.getDistanceAStar(grid1,this.startGrid,this.endGrid);
        if (grid0Dis > grid1Dis) {
            return 1;
        }else{
            return -1;
        }
    }

    /**获取综合距离 优化
     * grid 当前节点
     * start 起始节点
     * end 目标节点
    */
    getDistanceAStar(grid: DataGrid,start: DataGrid,end: DataGrid) {
        let endDis = Math.abs(grid.x - end.x) + Math.abs(grid.y - end.y);
        let startDis = Math.abs(grid.x - start.x) + Math.abs(grid.y - start.y);
        return endDis + startDis;
    }

    /**点击重新开始*/
    onBtnRestart(){
        for (let x = 0;x < this.dataGrids.length;x ++){
            for (let y = 0;y < this.dataGrids[x].length;y ++){
                let dataGrid = this.dataGrids[x][y];
                dataGrid.inOpenList = false;
                dataGrid.inCloseList = false;
                if (dataGrid.type != GrideType.Wall){
                    dataGrid.type = GrideType.Normal;
                }
                this.nodeGrids[x][y].updateGridColor();
            }
        }
        this.startGrid = null;
        this.endGrid = null;
        this.openPath = [];
    }

}


08.对象池模式

意义

用于解决当需要创建大量相同对象的时候,避免重复创建,节能.

流程图

在这里插入图片描述

直接创建对象

/**对象池模式 */
const {ccclass, property} = cc._decorator;

@ccclass
export default class PoolDemo extends cc.Component {

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

    onl oad () {

    }

    shoot() {
        let node = cc.instantiate(this.nodeIcon);
        //创建完节点还要从父节点上移出,太费事了
        node.runAction(cc.sequence(cc.moveBy(1,0,300),cc.removeSelf()));
        node.parent = this.node;
    }

    update() {
        this.shoot();
    }
}

会不断创建节点,并将节点从父节点移出,耗费性能,内存.

使用对象池

/**对象池模式 */
const {ccclass, property} = cc._decorator;

@ccclass
export default class PoolDemo extends cc.Component {

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

    /**对象池 */
    pool: cc.Node[] = [];

    onl oad () {

    }

    shoot() {
        let node = this.getNode();
        //创建完节点还要从父节点上移出,太费事了
        node.runAction(cc.sequence(cc.moveBy(1,0,300),cc.removeSelf(),cc.callFunc(function () {
            node.position = cc.Vec2.ZERO; //节点位置重置
            //用完后将节点放回对象池
            this.pool.push(node);
        }.bind(this))));
        node.parent = this.node;
    }

    /**获取节点
     * 如果对象池里有节点的话就取出来用
     * 没有的话就实例化一个
     */
    getNode(): cc.Node {
        if (this.pool.length > 0) {
            return this.pool.shift();
        }else {
            console.log("创建了一个节点");
            return cc.instantiate(this.nodeIcon);
        }
    }

    update() {
        this.shoot();
    }
}

运行效果

只需创建了62个节点
在这里插入图片描述

标签:GrideType,cc,编程,爆款,DataGrid,算法,let,grid,节点
来源: https://blog.csdn.net/qq_39685400/article/details/117234606

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有