1. 程式人生 > >egret 簡單的一筆畫算法,在wing中可以直接跑(以後玩這類遊戲就有個作弊器了)

egret 簡單的一筆畫算法,在wing中可以直接跑(以後玩這類遊戲就有個作弊器了)

com ast font 必須 ech upd length reat ini

/**
* 在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中可以直接跑(以後玩這類遊戲就有個作弊器了)