标签:cal draw enable addchild obs extc com erro net
 /**
     * 在Main中创建游戏场景
     * Create a game scene
     */
    private createGameScene() {
        MtwGame.Instance.init(this.stage);
    }
//===========================场景类============================
class MtwGame {
 public constructor() {
    }
    private static _instance: MtwGame;
    public static get Instance(): MtwGame {
        if (this._instance == null || this._instance == undefined) {
            this._instance = new MtwGame();
        }
        return this._instance;
    }
    public stage: egret.Stage;
    // X ↓; Y →
    public mapTitle: Array<Array<number>>;
    //障碍
    public mapObstacle: Array<Array<number>> = [
[1, 3], [2, 3], [3, 3], [4, 3], [5, 3], [6, 3],
        [2, 5], [3, 5], [4, 5], [5, 5], [6, 5],
    ];
    public path: Array<Array<number>>;
    public width: number = 20;
    public strokeWid: number = 3;
    public color1: number = 0x00000;//线和阻挡的颜色
    public color2: number = 0xe60b0b;//路径的颜色
    // public color3: number = 0x00000;
    public showTxt2: eui.Label;
    pathRect = [];//用于存储路径方块,便于管理
    map: MapClass;
    point = {};//用于存储阻挡点方块,便于管理
    //初始化舞台
    public init(stage: egret.Stage): void {
        this.stage = stage;
        this.initMap(8, 8);//输入地图的长宽(格子个数)
        this.initmenu();
        this.initBlock();
    }
    /**点击添加或删除阻挡点*/
    protected addObstacle(evt: egret.TouchEvent): void {
        let x = Math.floor(Math.floor(evt.localY) / (this.strokeWid + this.width));
        let y = Math.floor(Math.floor(evt.localX) / (this.strokeWid + this.width));
        let name = x + "_" + y;
        if (this.point[name]) {
            this.stage.removeChild(this.point[name]);
            delete this.point[name];
            this.map.update(x, y, false);
        } else {
            let xx = this.strokeWid * (y + 1) + this.width * y;
            let yy = this.strokeWid * (x + 1) + this.width * x;
            this.setRect(xx, yy, this.color1, 0.8, name);
            this.map.update(x, y, true);
        }
    }
    /**初始化菜单*/
    protected initmenu(): void {
        let shp: egret.Shape = new egret.Shape();
        shp.graphics.beginFill(0xffffff, 1);
        shp.graphics.drawRect(0, 0, this.stage.stageWidth, this.stage.stageHeight);
        shp.graphics.endFill();
        this.stage.addChild(shp);
        let shp1: eui.Rect = new eui.Rect();
        shp1.fillAlpha = 0.2;
        shp1.width = shp1.height = this.stage.stageWidth;
        this.stage.addChild(shp1);
        shp1.addEventListener(egret.TouchEvent.TOUCH_END, this.addObstacle, this);
        this.showTxt2 = new eui.Label();
        this.stage.addChild(this.showTxt2);
        this.showTxt2.text = "重新生成路径";
        this.showTxt2.size = 32;
        this.showTxt2.textAlign = "center";
        this.showTxt2.fontFamily = "SimHei";
        this.showTxt2.textColor = 0xf3c382;
        this.showTxt2.strokeColor = 0x0;
        this.showTxt2.stroke = 1;
        this.showTxt2.width = Math.floor(this.stage.stageWidth / 3 * 2);
        this.showTxt2.x = this.stage.stageWidth - this.showTxt2.width >> 1;
        this.showTxt2.y = 680;
        this.showTxt2.addEventListener(egret.TouchEvent.TOUCH_END, this.touchHandler, this);
    }
    /**重新寻路*/
    protected touchHandler(evt: egret.TouchEvent): void {
        if (this.tt > 0)
            clearInterval(this.tt);
        this.findPath();
    }
    /**开始寻路*/
    protected findPath(): void {
        let returns = this.map.getPath();//输入起点和终点(2,2),(5,5)
        this.path = returns;
        //显示路径
        this.initPath();
    }
    /**渲染地图*/
    protected initBlock(): void {
        //横
        for (let i = 0; i < this.mapTitle.length + 1; i++) {
            let y = i * (this.width + this.strokeWid);
            this.setLine(0, y, this.stage.stageWidth, y);
        }
        //竖
        for (let i = 0; i < this.mapTitle[0].length + 1; i++) {
            let x = i * (this.width + this.strokeWid);
            let height = this.width * this.mapTitle[0].length + this.strokeWid * (this.mapTitle[0].length + 1);
            this.setLine(x, 0, x, height);
        }
        //阻挡点
        for (let i = 0; i < this.mapTitle.length; i++) {
            for (let j = 0; j < this.mapTitle[i].length; j++) {
                if (this.mapTitle[i][j] == 1) {
                    this.setRect(this.strokeWid * (j + 1) + this.width * j, this.strokeWid * (i + 1) + this.width * i, this.color1, 0.8, i + "_" + j);
                }
            }
        }
    }
    tt;
    /**
    * 将路径显示在地图上
    */
    protected initPath(): void {
        if (this.pathRect.length > 0) {
            for (let i = 0; i < this.pathRect.length; i++) {
                this.stage.removeChild(this.pathRect[i]);
            }
            this.pathRect = [];
        }
        if (this.path && this.path.length > 0) {
            let i = 0;
            this.tt = setInterval(() => {
                if (!this.path[i]) {
                    clearInterval(this.tt);
                    return;
                }
                let x = this.strokeWid * (this.path[i][1] + 1) + this.width * this.path[i][1];
                let y = this.strokeWid * (this.path[i][0] + 1) + this.width * this.path[i][0];
                this.setRect(x, y, this.color2, 0.3, this.path[i][0] + "_" + this.path[i][1], true);
                i++;
            }, 50);
        }
    }
    /**
     * 初始化地图
     * */
    protected initMap(w: number, h: number): void {
        if (w < 2 || h < 2) console.error("地图格子长宽数不对");
        this.mapTitle = [];
        for (let i = 0; i < h; i++) {
            this.mapTitle.push([]);
            for (let j = 0; j < w; j++) {
                if (i == 0 || j == 0 || i == h - 1 || j == w - 1) {
                    this.mapTitle[i][j] = 1;
                } else {
                    this.mapTitle[i][j] = 0;
                }
            }
        }
        this.width = (this.stage.stageWidth - (this.mapTitle[0].length + 1) * this.strokeWid) / this.mapTitle[0].length;
        this.map = new MapClass(this.mapTitle);
        this.initObstacle();
        for (let i in this.mapObstacle) {
            this.map.update(this.mapObstacle[i][0], this.mapObstacle[i][1], true)
        }
    }
    /**
     * 将障碍显示在地图上
     * */
    protected initObstacle(): void {
        for (let i = 0; i < this.mapObstacle.length; i++) {
            if (this.mapObstacle[i][0] < this.mapTitle.length - 1 && this.mapObstacle[i][0] > 0
                && this.mapObstacle[i][1] < this.mapTitle[0].length - 1 && this.mapObstacle[i][1] > 0)
                this.mapTitle[this.mapObstacle[i][0]][this.mapObstacle[i][1]] = 1;
        }
    }
    //划线
    public setLine(x: number, y: number, x1: number, y1: number): egret.Shape {
        var shp: egret.Shape = new egret.Shape();
        shp.touchEnabled = false;
        shp.graphics.lineStyle(this.strokeWid, this.color1);
        shp.graphics.moveTo(x, y);
        shp.graphics.lineTo(x1, y1);
        shp.graphics.endFill();
        this.stage.addChild(shp);
        return shp;
    }
    //划块
    protected setRect(x: number, y: number, col: number, alpha: number = 1, name: string, bool: boolean = false): egret.Shape {
        var shp: egret.Shape = new egret.Shape();
        shp.touchEnabled = false;
        shp.graphics.beginFill(col, alpha);
        shp.graphics.drawRect(x, y, this.width, this.width);
        shp.graphics.endFill();
        this.stage.addChild(shp);
        if (bool) {
            this.pathRect.push(shp);//记录路径
        } else {
            this.point[name] = shp;//记录阻挡点
        }
        return shp;
    }
}
//================================================寻路的类(核心代码)===============================================
class MapClass {
    public closeArr: { [pos: string]: number };//已经用过的格子
    public openArr: { [pos: string]: Array<number> };//可以走的格子
    public Arr: { [pos: string]: number };//所有的格子
    public pathArr: Array<Array<number>>;//当前的只能连1路奇点
openObj;//记录所有用过的格子的信息,用于最后找到终点后的寻路
    public constructor(mapArr: Array<Array<number>>) {
        this.Arr = {};
        for (let i = 0; i < mapArr.length; i++) {
            for (let j = 0; j < mapArr.length; j++) {
                this.Arr[i + "_" + j] = mapArr[i][j];
            }
        }
    }
    count: number;//迭代次数
    allCount: number;
    /**
     * 获得最短路径;
     * x1,y1是起点;x2,y2是终点
     */
    public getPath(): any {
        this.closeArr = {};
        this.openArr = {};
        this.count = 0;
        this.pathArr = [];
        for (let key in this.Arr) {
            if (this.Arr[key] == 0)
                this.openArr[key] = [Number(key.split("_")[0]), Number(key.split("_")[1])]
        }
        this.allCount = Object.keys(this.openArr).length;
        if(this.returnOneStrockes())
            return this.pathArr;
        else{
           console.log("不能一笔画完"); 
        }
    }
    public jiArr: Array<Array<number>>;//当前的只能连1路奇点
    public ouArr: Array<Array<number>>;//记录偶点
    /**
     * 判断this.openArr里面的奇点的情况
     * 返回能否一步走完
     */
    public returnOneStrockes(): boolean {
        if (Object.keys(this.openArr).length == 1) {
            for(let key in this.openArr){
                this.pathArr.push([this.openArr[key][0],this.openArr[key][1]]);
            }
            return true;
        }
        this.count++;
        if (this.count > this.allCount)//每个格子都走一遍时,表示不能一笔画
            return false
        this.jiArr = [];
        this.ouArr = [];
        for (let key in this.openArr) {
            let four = this.getfour(this.openArr[key][0], this.openArr[key][1]);
            if (four.length % 2 == 1) {//记录奇点
                if (four.length == 1) {
                    this.jiArr.push([this.openArr[key][0], this.openArr[key][1]])
                }
            }
            if (four.length % 2 == 0) {//记录偶点
                this.ouArr.push([this.openArr[key][0], this.openArr[key][1]])
            }
            if (four.length == 0 && Object.keys(this.openArr).length > 1) //1.还有多个点时,就存在无路的点
                return false;
            if (this.jiArr.length > 2)//2.一路的奇点最多存在两个
                return false
        }
        if (this.jiArr.length % 2 != 0 && this.jiArr.length != 1)//3.偶数个奇点时//奇数个奇点时,必须存在一个一路的奇点
            return false;
        if (Object.keys(this.openArr).length > 0 && this.jiArr.length > 0) {//存在奇点
            let xy: Array<number> = [this.jiArr[0][0], this.jiArr[0][1]];
            if (this.pathArr.length != 0) {//刚开始寻路时,以第一个奇点为起点
                let lastP: Array<number> = [this.pathArr[this.pathArr.length - 1][0], this.pathArr[this.pathArr.length - 1][1]];
                let four = this.getfour(lastP[0], lastP[1]);
                if (four.length == 1) {
                    xy = four[0];
                } else {
                    let ouXy: Array<number> = [];
                    let jiStr: Array<string> = this.toStringArr(this.jiArr);
                    let ouStr: Array<string> = this.toStringArr(this.ouArr);
                    for (let i in four) {
                        let fours:string = four[i].join("#");
                        if (jiStr.indexOf(fours) > -1) {
                            xy = [four[i][0], four[i][1]];
                        }
                        if (ouStr.indexOf(fours) > -1 && ouXy == []) {
                            ouXy = [four[i][0], four[i][1]];
                        }
                    }
                    if (!xy) xy = ouXy;
                }
            }
            this.pathArr.push([xy[0], xy[1]]);
            delete this.openArr[xy[0] + "_" + xy[1]];
            this.closeArr[xy[0] + "_" + xy[1]] = 1;
            return this.returnOneStrockes();
        } else {//全为偶点
            let xy: Array<number> = [this.ouArr[0][0], this.ouArr[0][1]];
            if (this.pathArr.length != 0) {//刚开始寻路时,以第一个偶点为起点
                let lastP: Array<number> = [this.pathArr[this.pathArr.length - 1][0], this.pathArr[this.pathArr.length - 1][1]];
                xy = this.getfour(lastP[0], lastP[1])[0];
            }
            this.pathArr.push([xy[0], xy[1]]);
            delete this.openArr[xy[0] + "_" + xy[1]];
            this.closeArr[xy[0] + "_" + xy[1]] = 1;
            return this.returnOneStrockes();
        }
    }
    public toStringArr(arr:Array<Array<number>>):Array<string>{
        let strArr:Array<string> = [];
        for(let i in arr){
            strArr.push(arr[i].join("#"))
        }
        return strArr;
    }
    //获得四个方向的格子[x,y,]
    public getfour(x1: number, y1: number): Array<Array<number>> {
        let siGe: Array<Array<number>> = [];
        let str1: string = x1 + 1 + "_" + y1;
        let str2: string = x1 - 1 + "_" + y1;
        let str3: string = x1 + "_" + (y1 + 1);
        let str4: string = x1 + "_" + (y1 - 1);
        if (this.Arr[str1] == 0 && !this.closeArr[str1])
            siGe.push([x1 + 1, y1]);
        if (this.Arr[str2] == 0 && !this.closeArr[str2])
            siGe.push([x1 - 1, y1]);
        if (this.Arr[str3] == 0 && !this.closeArr[str3])
            siGe.push([x1, y1 + 1]);
        if (this.Arr[str4] == 0 && !this.closeArr[str4])
            siGe.push([x1, y1 - 1]);
        return siGe;
    }
    /**更新地图的阻挡物 */
    public update(x1: number, y1: number, bool: boolean): void {
        this.Arr[x1 + "_" + y1] = bool ? 1 : 0;
    }
    public dispose(): void {
        this.closeArr = null;
        this.openArr = null;
        this.Arr = null;
        this.openObj = null;
    }
}

egret 简单的一笔画算法,在wing中可以直接跑(以后玩这类游戏就有个作弊器了)
标签:cal draw enable addchild obs extc com erro net
原文地址:https://www.cnblogs.com/jiajunjie/p/9565316.html