新增Time/String/Array/Keyboard/Random/Object/Texture辅助类
This commit is contained in:
@@ -29,7 +29,6 @@ class AStarPathfinder {
|
||||
}
|
||||
|
||||
graph.getNeighbors(current.data).forEach(next => {
|
||||
console.log(next);
|
||||
let newCost = costSoFar.get(current.data) + graph.cost(current.data, next);
|
||||
if (!this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)){
|
||||
costSoFar.set(next, newCost);
|
||||
|
||||
20
source/src/ECS/Utils/ObjectUtils.ts
Normal file
20
source/src/ECS/Utils/ObjectUtils.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
class ObjectUtils {
|
||||
/**
|
||||
* 对象深度拷贝
|
||||
* @param p any 源对象
|
||||
* @param c any 目标对象, 不传则返回新对象, 传则合并属性, 相同名字的属性则会覆盖
|
||||
*/
|
||||
public static clone<T>(p: any, c: T = null): T {
|
||||
var c = c || <T>{};
|
||||
for (let i in p) {
|
||||
if (typeof p[i] === 'object') {
|
||||
c[i] = p[i] instanceof Array ? [] : {};
|
||||
this.clone(p[i], c[i]);
|
||||
}
|
||||
else {
|
||||
c[i] = p[i];
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
238
source/src/ECS/Utils/StringUtils.ts
Normal file
238
source/src/ECS/Utils/StringUtils.ts
Normal file
@@ -0,0 +1,238 @@
|
||||
class StringUtils {
|
||||
/**
|
||||
* 匹配中文字符
|
||||
* @param str 需要匹配的字符串
|
||||
* @return
|
||||
*/
|
||||
public static matchChineseWord(str: string): string[] {
|
||||
//中文字符的unicode值[\u4E00-\u9FA5]
|
||||
let patternA: RegExp = /[\u4E00-\u9FA5]+/gim;
|
||||
return str.match(patternA);
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除字符串左端的空白字符
|
||||
* @param target 目标字符串
|
||||
* @return
|
||||
*/
|
||||
public static lTrim(target: string): string {
|
||||
let startIndex: number = 0;
|
||||
while (this.isWhiteSpace(target.charAt(startIndex))) {
|
||||
startIndex++;
|
||||
}
|
||||
return target.slice(startIndex, target.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除字符串右端的空白字符
|
||||
* @param target 目标字符串
|
||||
* @return
|
||||
*/
|
||||
public static rTrim(target: string): string {
|
||||
let endIndex: number = target.length - 1;
|
||||
while (this.isWhiteSpace(target.charAt(endIndex))) {
|
||||
endIndex--;
|
||||
}
|
||||
return target.slice(0, endIndex + 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回一个去除2段空白字符的字符串
|
||||
* @param target
|
||||
* @return 返回一个去除2段空白字符的字符串
|
||||
*/
|
||||
public static trim(target: string): string {
|
||||
if (target == null) {
|
||||
return null;
|
||||
}
|
||||
return this.rTrim(this.lTrim(target));
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回该字符是否为空白字符
|
||||
* @param str
|
||||
* @return 返回该字符是否为空白字符
|
||||
*/
|
||||
public static isWhiteSpace(str: string): boolean {
|
||||
if (str == " " || str == "\t" || str == "\r" || str == "\n")
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回执行替换后的字符串
|
||||
* @param mainStr 待查找字符串
|
||||
* @param targetStr 目标字符串
|
||||
* @param replaceStr 替换字符串
|
||||
* @param caseMark 是否忽略大小写
|
||||
* @return 返回执行替换后的字符串
|
||||
*/
|
||||
public static replaceMatch(mainStr: string, targetStr: string,
|
||||
replaceStr: string, caseMark: boolean = false): string {
|
||||
let len: number = mainStr.length;
|
||||
let tempStr: string = "";
|
||||
let isMatch: boolean = false;
|
||||
let tempTarget: string = caseMark == true ? targetStr.toLowerCase() : targetStr;
|
||||
for (let i: number = 0; i < len; i++) {
|
||||
isMatch = false;
|
||||
if (mainStr.charAt(i) == tempTarget.charAt(0)) {
|
||||
if (mainStr.substr(i, tempTarget.length) == tempTarget) {
|
||||
isMatch = true;
|
||||
}
|
||||
}
|
||||
if (isMatch) {
|
||||
tempStr += replaceStr;
|
||||
i = i + tempTarget.length - 1;
|
||||
}
|
||||
else {
|
||||
tempStr += mainStr.charAt(i);
|
||||
}
|
||||
}
|
||||
return tempStr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 特殊符号字符串
|
||||
*/
|
||||
private static specialSigns: string[] = [
|
||||
'&', '&',
|
||||
'<', '<',
|
||||
'>', '>',
|
||||
'"', '"',
|
||||
"'", ''',
|
||||
'®', '®',
|
||||
'©', '©',
|
||||
'™', '™',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 用html实体换掉字符窜中的特殊字符
|
||||
* @param str 需要替换的字符串
|
||||
* @param reversion 是否翻转替换:将转义符号替换为正常的符号
|
||||
* @return 换掉特殊字符后的字符串
|
||||
*/
|
||||
public static htmlSpecialChars(str: string, reversion: boolean = false): string {
|
||||
let len: number = this.specialSigns.length;
|
||||
for (let i: number = 0; i < len; i += 2) {
|
||||
let from: string;
|
||||
let to: string;
|
||||
from = this.specialSigns[i];
|
||||
to = this.specialSigns[i + 1];
|
||||
if (reversion) {
|
||||
let temp: string = from;
|
||||
from = to;
|
||||
to = temp;
|
||||
}
|
||||
str = this.replaceMatch(str, from, to);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 给数字字符前面添 "0"
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* trace( StringFormat.zfill('1') );
|
||||
* // 01
|
||||
*
|
||||
* trace( StringFormat.zfill('16', 5) );
|
||||
* // 00016
|
||||
*
|
||||
* trace( StringFormat.zfill('-3', 3) );
|
||||
* // -03
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @param str 要进行处理的字符串
|
||||
* @param width 处理后字符串的长度,
|
||||
* 如果str.length >= width,将不做任何处理直接返回原始的str。
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
public static zfill(str: string, width: number = 2): string {
|
||||
if (!str) {
|
||||
return str;
|
||||
}
|
||||
width = Math.floor(width);
|
||||
let slen: number = str.length;
|
||||
if (slen >= width) {
|
||||
return str;
|
||||
}
|
||||
|
||||
let negative: boolean = false;
|
||||
if (str.substr(0, 1) == '-') {
|
||||
negative = true;
|
||||
str = str.substr(1);
|
||||
}
|
||||
|
||||
let len: number = width - slen;
|
||||
for (let i: number = 0; i < len; i++) {
|
||||
str = '0' + str;
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
str = '-' + str;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 翻转字符串
|
||||
* @param str 字符串
|
||||
* @return 翻转后的字符串
|
||||
*/
|
||||
public static reverse(str: string): string {
|
||||
if (str.length > 1)
|
||||
return this.reverse(str.substring(1)) + str.substring(0, 1);
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 截断某段字符串
|
||||
* @param str 目标字符串
|
||||
* @param start 需要截断的起始索引
|
||||
* @param len 截断长度
|
||||
* @param order 顺序,true从字符串头部开始计算,false从字符串尾巴开始结算。
|
||||
* @return 截断后的字符串
|
||||
*/
|
||||
public static cutOff(str: string, start: number,
|
||||
len: number, order: boolean = true): string {
|
||||
start = Math.floor(start);
|
||||
len = Math.floor(len);
|
||||
let length: number = str.length;
|
||||
if (start > length) start = length;
|
||||
let s: number = start;
|
||||
let e: number = start + len;
|
||||
let newStr: string;
|
||||
if (order) {
|
||||
newStr = str.substring(0, s) + str.substr(e, length);
|
||||
}
|
||||
else {
|
||||
s = length - 1 - start - len;
|
||||
e = s + len;
|
||||
newStr = str.substring(0, s + 1) + str.substr(e + 1, length);
|
||||
}
|
||||
return newStr;
|
||||
}
|
||||
|
||||
/**{0} 字符替换 */
|
||||
public static strReplace(str: string, rStr: string[]): string {
|
||||
let i: number = 0, len: number = rStr.length;
|
||||
for (; i < len; i++) {
|
||||
if (rStr[i] == null || rStr[i] == "") {
|
||||
rStr[i] = "无";
|
||||
}
|
||||
str = str.replace("{" + i + "}", rStr[i]);
|
||||
}
|
||||
return str
|
||||
}
|
||||
}
|
||||
154
source/src/ECS/Utils/TextureUtils.ts
Normal file
154
source/src/ECS/Utils/TextureUtils.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* 纹理帮助类
|
||||
*/
|
||||
class TextureUtils {
|
||||
public static sharedCanvas: HTMLCanvasElement;
|
||||
public static sharedContext: CanvasRenderingContext2D;
|
||||
|
||||
public static convertImageToCanvas(texture: egret.Texture, rect?: egret.Rectangle): HTMLCanvasElement{
|
||||
if (!this.sharedCanvas){
|
||||
this.sharedCanvas = egret.sys.createCanvas();
|
||||
this.sharedContext = this.sharedCanvas.getContext("2d");
|
||||
}
|
||||
|
||||
let w = texture.$getTextureWidth();
|
||||
let h = texture.$getTextureHeight();
|
||||
if (!rect){
|
||||
rect = egret.$TempRectangle;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.width = w;
|
||||
rect.height = h;
|
||||
}
|
||||
|
||||
rect.x = Math.min(rect.x, w - 1);
|
||||
rect.y = Math.min(rect.y, h - 1);
|
||||
rect.width = Math.min(rect.width, w - rect.x);
|
||||
rect.height = Math.min(rect.height, h - rect.y);
|
||||
|
||||
let iWidth = Math.floor(rect.width);
|
||||
let iHeight = Math.floor(rect.height);
|
||||
let surface = this.sharedCanvas;
|
||||
surface["style"]["width"] = iWidth + "px";
|
||||
surface["style"]["height"] = iHeight + "px";
|
||||
this.sharedCanvas.width = iWidth;
|
||||
this.sharedCanvas.height = iHeight;
|
||||
|
||||
if (egret.Capabilities.renderMode == "webgl") {
|
||||
let renderTexture: egret.RenderTexture;
|
||||
//webgl下非RenderTexture纹理先画到RenderTexture
|
||||
if (!(<egret.RenderTexture>texture).$renderBuffer) {
|
||||
if (egret.sys.systemRenderer["renderClear"]) {
|
||||
egret.sys.systemRenderer["renderClear"]();
|
||||
}
|
||||
renderTexture = new egret.RenderTexture();
|
||||
renderTexture.drawToTexture(new egret.Bitmap(texture));
|
||||
}
|
||||
else {
|
||||
renderTexture = <egret.RenderTexture>texture;
|
||||
}
|
||||
//从RenderTexture中读取像素数据,填入canvas
|
||||
let pixels = renderTexture.$renderBuffer.getPixels(rect.x, rect.y, iWidth, iHeight);
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
for (let i = 0; i < pixels.length; i += 4) {
|
||||
this.sharedContext.fillStyle =
|
||||
'rgba(' + pixels[i]
|
||||
+ ',' + pixels[i + 1]
|
||||
+ ',' + pixels[i + 2]
|
||||
+ ',' + (pixels[i + 3] / 255) + ')';
|
||||
this.sharedContext.fillRect(x, y, 1, 1);
|
||||
x++;
|
||||
if (x == iWidth) {
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(<egret.RenderTexture>texture).$renderBuffer) {
|
||||
renderTexture.dispose();
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
else {
|
||||
let bitmapData = texture;
|
||||
let offsetX: number = Math.round(bitmapData.$offsetX);
|
||||
let offsetY: number = Math.round(bitmapData.$offsetY);
|
||||
let bitmapWidth: number = bitmapData.$bitmapWidth;
|
||||
let bitmapHeight: number = bitmapData.$bitmapHeight;
|
||||
let $TextureScaleFactor = SceneManager.stage.textureScaleFactor;
|
||||
this.sharedContext.drawImage(bitmapData.$bitmapData.source, bitmapData.$bitmapX + rect.x / $TextureScaleFactor, bitmapData.$bitmapY + rect.y / $TextureScaleFactor,
|
||||
bitmapWidth * rect.width / w, bitmapHeight * rect.height / h, offsetX, offsetY, rect.width, rect.height);
|
||||
return surface;
|
||||
}
|
||||
}
|
||||
|
||||
public static toDataURL(type: string, texture: egret.Texture, rect?: egret.Rectangle, encoderOptions?): string {
|
||||
try {
|
||||
let surface = this.convertImageToCanvas(texture, rect);
|
||||
let result = surface.toDataURL(type, encoderOptions);
|
||||
return result;
|
||||
}
|
||||
catch (e) {
|
||||
egret.$error(1033);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 有些杀毒软件认为 saveToFile 可能是一个病毒文件
|
||||
* @param type
|
||||
* @param texture
|
||||
* @param filePath
|
||||
* @param rect
|
||||
* @param encoderOptions
|
||||
*/
|
||||
public static eliFoTevas(type: string, texture: egret.Texture, filePath: string, rect?: egret.Rectangle, encoderOptions?): void {
|
||||
let surface = this.convertImageToCanvas(texture, rect);
|
||||
let result = (surface as any).toTempFilePathSync({
|
||||
fileType: type.indexOf("png") >= 0 ? "png" : "jpg"
|
||||
});
|
||||
|
||||
wx.getFileSystemManager().saveFile({
|
||||
tempFilePath: result,
|
||||
filePath: `${wx.env.USER_DATA_PATH}/${filePath}`,
|
||||
success: function (res) {
|
||||
//todo
|
||||
}
|
||||
})
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static getPixel32(texture: egret.Texture, x: number, y: number): number[] {
|
||||
egret.$warn(1041, "getPixel32", "getPixels");
|
||||
return texture.getPixels(x, y);
|
||||
}
|
||||
|
||||
public static getPixels(texture: egret.Texture, x: number, y: number, width: number = 1, height: number = 1): number[] {
|
||||
//webgl环境下不需要转换成canvas获取像素信息
|
||||
if (egret.Capabilities.renderMode == "webgl") {
|
||||
let renderTexture: egret.RenderTexture;
|
||||
//webgl下非RenderTexture纹理先画到RenderTexture
|
||||
if (!(<egret.RenderTexture>texture).$renderBuffer) {
|
||||
renderTexture = new egret.RenderTexture();
|
||||
renderTexture.drawToTexture(new egret.Bitmap(texture));
|
||||
}
|
||||
else {
|
||||
renderTexture = <egret.RenderTexture>texture;
|
||||
}
|
||||
//从RenderTexture中读取像素数据
|
||||
let pixels = renderTexture.$renderBuffer.getPixels(x, y, width, height);
|
||||
return pixels;
|
||||
}
|
||||
try {
|
||||
let surface = this.convertImageToCanvas(texture);
|
||||
let result = this.sharedContext.getImageData(x, y, width, height).data;
|
||||
return <number[]><any>result;
|
||||
}
|
||||
catch (e) {
|
||||
egret.$error(1039);
|
||||
}
|
||||
}
|
||||
}
|
||||
209
source/src/ECS/Utils/TimeUtils.ts
Normal file
209
source/src/ECS/Utils/TimeUtils.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
class TimeUtils {
|
||||
/**
|
||||
* 计算月份ID
|
||||
* @param d 指定计算日期
|
||||
* @returns 月ID
|
||||
*/
|
||||
public static monthId(d: Date = null): number {
|
||||
d = d ? d : new Date();
|
||||
let y = d.getFullYear();
|
||||
let m = d.getMonth() + 1;
|
||||
let g = m < 10 ? "0" : "";
|
||||
return parseInt(y + g + m);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算日期ID
|
||||
* @param d 指定计算日期
|
||||
* @returns 日期ID
|
||||
*/
|
||||
public static dateId(t: Date = null): number {
|
||||
t = t ? t : new Date();
|
||||
let m: number = t.getMonth() + 1;
|
||||
let a = m < 10 ? "0" : "";
|
||||
let d: number = t.getDate();
|
||||
let b = d < 10 ? "0" : "";
|
||||
return parseInt(t.getFullYear() + a + m + b + d);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算周ID
|
||||
* @param d 指定计算日期
|
||||
* @returns 周ID
|
||||
*/
|
||||
public static weekId(d: Date = null, first: boolean = true): number {
|
||||
d = d ? d : new Date();
|
||||
let c: Date = new Date();
|
||||
c.setTime(d.getTime());
|
||||
c.setDate(1); c.setMonth(0);//当年第一天
|
||||
|
||||
let year: number = c.getFullYear();
|
||||
let firstDay: number = c.getDay();
|
||||
if (firstDay == 0) {
|
||||
firstDay = 7;
|
||||
}
|
||||
let max: boolean = false;
|
||||
if (firstDay <= 4) {
|
||||
max = firstDay > 1;
|
||||
c.setDate(c.getDate() - (firstDay - 1));
|
||||
} else {
|
||||
c.setDate(c.getDate() + 7 - firstDay + 1);
|
||||
}
|
||||
let num: number = this.diffDay(d, c, false);
|
||||
if (num < 0) {
|
||||
c.setDate(1); c.setMonth(0);//当年第一天
|
||||
c.setDate(c.getDate() - 1);
|
||||
return this.weekId(c, false);
|
||||
}
|
||||
let week: number = num / 7;
|
||||
let weekIdx: number = Math.floor(week) + 1;
|
||||
if (weekIdx == 53) {
|
||||
c.setTime(d.getTime());
|
||||
c.setDate(c.getDate() - 1);
|
||||
let endDay: number = c.getDay();
|
||||
if (endDay == 0) {
|
||||
endDay = 7;
|
||||
}
|
||||
if (first && (!max || endDay < 4)) {
|
||||
c.setFullYear(c.getFullYear() + 1);
|
||||
c.setDate(1); c.setMonth(0);//当年第一天
|
||||
return this.weekId(c, false);
|
||||
}
|
||||
}
|
||||
let g: string = weekIdx > 9 ? "" : "0";
|
||||
let s: string = year + "00" + g + weekIdx;//加上00防止和月份ID冲突
|
||||
return parseInt(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算俩日期时间差,如果a比b小,返回负数
|
||||
*/
|
||||
public static diffDay(a: Date, b: Date, fixOne: boolean = false): number {
|
||||
let x = (a.getTime() - b.getTime()) / 86400000;
|
||||
return fixOne ? Math.ceil(x) : Math.floor(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本周一 凌晨时间
|
||||
*/
|
||||
public static getFirstDayOfWeek(d?: Date): Date {
|
||||
d = d ? d : new Date();
|
||||
let day = d.getDay() || 7;
|
||||
return new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1 - day, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当日凌晨时间
|
||||
*/
|
||||
public static getFirstOfDay(d?: Date): Date {
|
||||
d = d ? d : new Date();
|
||||
d.setHours(0, 0, 0, 0);
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取次日凌晨时间
|
||||
*/
|
||||
public static getNextFirstOfDay(d?: Date): Date {
|
||||
return new Date(this.getFirstOfDay(d).getTime() + 86400000);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns 2018-12-12
|
||||
*/
|
||||
public static formatDate(date: Date): string {
|
||||
let y = date.getFullYear();
|
||||
let m: any = date.getMonth() + 1;
|
||||
m = m < 10 ? '0' + m : m;
|
||||
let d: any = date.getDate();
|
||||
d = d < 10 ? ('0' + d) : d;
|
||||
return y + '-' + m + '-' + d;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns 2018-12-12 12:12:12
|
||||
*/
|
||||
public static formatDateTime(date: Date): string {
|
||||
let y = date.getFullYear();
|
||||
let m: any = date.getMonth() + 1;
|
||||
m = m < 10 ? ('0' + m) : m;
|
||||
let d: any = date.getDate();
|
||||
d = d < 10 ? ('0' + d) : d;
|
||||
let h = date.getHours();
|
||||
let i: any = date.getMinutes();
|
||||
i = i < 10 ? ('0' + i) : i;
|
||||
let s: any = date.getSeconds();
|
||||
s = s < 10 ? ('0' + s) : s;
|
||||
return y + '-' + m + '-' + d + ' ' + h + ':' + i + ":" + s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns s 2018-12-12 或者 2018-12-12 12:12:12
|
||||
*/
|
||||
public static parseDate(s: string): Date {
|
||||
let t = Date.parse(s);
|
||||
if (!isNaN(t)) {
|
||||
return new Date(Date.parse(s.replace(/-/g, "/")));
|
||||
} else {
|
||||
return new Date();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 秒数转换为时间形式。
|
||||
* @param time 秒数
|
||||
* @param partition 分隔符
|
||||
* @param showHour 是否显示小时
|
||||
* @return 返回一个以分隔符分割的时, 分, 秒
|
||||
*
|
||||
* 比如: time = 4351; secondToTime(time)返回字符串01:12:31;
|
||||
*/
|
||||
public static secondToTime(time: number = 0, partition: string = ":", showHour: boolean = true): string {
|
||||
let hours: number = Math.floor(time / 3600);
|
||||
let minutes: number = Math.floor(time % 3600 / 60);
|
||||
let seconds: number = Math.floor(time % 3600 % 60);
|
||||
|
||||
let h: string = hours.toString();
|
||||
let m: string = minutes.toString();
|
||||
let s: string = seconds.toString();
|
||||
|
||||
if (hours < 10) h = "0" + h;
|
||||
if (minutes < 10) m = "0" + m;
|
||||
if (seconds < 10) s = "0" + s;
|
||||
|
||||
let timeStr: string;
|
||||
if (showHour)
|
||||
timeStr = h + partition + m + partition + s;
|
||||
else
|
||||
timeStr = m + partition + s;
|
||||
|
||||
return timeStr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 时间形式转换为毫秒数。
|
||||
* @param time 以指定分隔符分割的时间字符串
|
||||
* @param partition 分隔符
|
||||
* @return 毫秒数显示的字符串
|
||||
* @throws Error Exception
|
||||
*
|
||||
* 用法1 trace(MillisecondTransform.timeToMillisecond("00:60:00"))
|
||||
* 输出 3600000
|
||||
*
|
||||
*
|
||||
* 用法2 trace(MillisecondTransform.timeToMillisecond("00.60.00","."))
|
||||
* 输出 3600000
|
||||
*/
|
||||
public static timeToMillisecond(time: string, partition: string = ":"): string {
|
||||
let _ary: any[] = time.split(partition);
|
||||
let timeNum: number = 0;
|
||||
let len: number = _ary.length;
|
||||
for (let i: number = 0; i < len; i++) {
|
||||
let n: number = <number>_ary[i];
|
||||
timeNum += n * Math.pow(60, (len - 1 - i));
|
||||
}
|
||||
timeNum *= 1000;
|
||||
return timeNum.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,27 @@
|
||||
class GraphicsCapabilities {
|
||||
public supportsTextureFilterAnisotropic: boolean;
|
||||
public supportsNonPowerOfTwo: boolean;
|
||||
public supportsDepth24: boolean;
|
||||
public supportsPackedDepthStencil: boolean;
|
||||
public supportsDepthNonLinear: boolean;
|
||||
public supportsTextureMaxLevel: boolean;
|
||||
public supportsS3tc: boolean;
|
||||
public supportsDxt1: boolean;
|
||||
public supportsPvrtc: boolean;
|
||||
public supportsAtitc: boolean;
|
||||
public supportsFramebufferObjectARB: boolean;
|
||||
class GraphicsCapabilities extends egret.Capabilities {
|
||||
|
||||
public initialize(device: GraphicsDevice){
|
||||
this.platformInitialize(device);
|
||||
}
|
||||
|
||||
private platformInitialize(device: GraphicsDevice){
|
||||
let gl: WebGLRenderingContext = new egret.sys.RenderBuffer().context.getInstance();
|
||||
this.supportsNonPowerOfTwo = false;
|
||||
this.supportsTextureFilterAnisotropic = gl.getExtension("EXT_texture_filter_anisotropic") != null;
|
||||
this.supportsDepth24 = true;
|
||||
this.supportsPackedDepthStencil = true;
|
||||
this.supportsDepthNonLinear = false;
|
||||
this.supportsTextureMaxLevel = true;
|
||||
this.supportsS3tc = gl.getExtension("WEBGL_compressed_texture_s3tc") != null ||
|
||||
gl.getExtension("WEBGL_compressed_texture_s3tc_srgb") != null;
|
||||
this.supportsDxt1 = this.supportsS3tc;
|
||||
this.supportsPvrtc = false;
|
||||
this.supportsAtitc = gl.getExtension("WEBGL_compressed_texture_astc") != null;
|
||||
this.supportsFramebufferObjectARB = false;
|
||||
let capabilities = this;
|
||||
capabilities["isMobile"] = true;
|
||||
|
||||
let systemInfo = wx.getSystemInfoSync();
|
||||
let systemStr = systemInfo.system.toLowerCase();
|
||||
if (systemStr.indexOf("ios") > -1){
|
||||
capabilities["os"] = "iOS";
|
||||
} else if(systemStr.indexOf("android") > -1){
|
||||
capabilities["os"] = "Android";
|
||||
}
|
||||
|
||||
let language = systemInfo.language;
|
||||
if (language.indexOf('zh') > -1){
|
||||
language = "zh-CN";
|
||||
} else {
|
||||
language = "en-US";
|
||||
}
|
||||
capabilities["language"] = language;
|
||||
}
|
||||
}
|
||||
241
source/src/Utils/ArrayUtils.ts
Normal file
241
source/src/Utils/ArrayUtils.ts
Normal file
@@ -0,0 +1,241 @@
|
||||
class ArrayUtils {
|
||||
/**
|
||||
* 执行冒泡排序
|
||||
* @param ary
|
||||
* 算法参考 -- http://www.hiahia.org/datastructure/paixu/paixu8.3.1.1-1.htm
|
||||
*/
|
||||
public static bubbleSort(ary: number[]): void {
|
||||
let isExchange: Boolean = false;
|
||||
for (let i: number = 0; i < ary.length; i++) {
|
||||
isExchange = false;
|
||||
for (let j: number = ary.length - 1; j > i; j--) {
|
||||
if (ary[j] < ary[j - 1]) {
|
||||
let temp: number = ary[j];
|
||||
ary[j] = ary[j - 1];
|
||||
ary[j - 1] = temp;
|
||||
isExchange = true;
|
||||
}
|
||||
}
|
||||
if (!isExchange)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行插入排序
|
||||
* @param ary
|
||||
*/
|
||||
public static insertionSort(ary: number[]): void {
|
||||
let len: number = ary.length;
|
||||
for (let i: number = 1; i < len; i++) {
|
||||
let val: number = ary[i];
|
||||
for (var j: number = i; j > 0 && ary[j - 1] > val; j--) {
|
||||
ary[j] = ary[j - 1];
|
||||
}
|
||||
ary[j] = val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行二分搜索
|
||||
* @param ary 搜索的数组(必须排序过)
|
||||
* @param value 需要搜索的值
|
||||
* @return 返回匹配结果的数组索引
|
||||
*/
|
||||
public static binarySearch(ary: number[], value: number): number {
|
||||
let startIndex: number = 0;
|
||||
let endIndex: number = ary.length;
|
||||
let sub: number = (startIndex + endIndex) >> 1;
|
||||
while (startIndex < endIndex) {
|
||||
if (value <= ary[sub]) endIndex = sub;
|
||||
else if (value >= ary[sub]) startIndex = sub + 1;
|
||||
sub = (startIndex + endIndex) >> 1;
|
||||
}
|
||||
if (ary[startIndex] == value) return startIndex;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回匹配项的索引
|
||||
* @param ary
|
||||
* @param num
|
||||
* @return 返回匹配项的索引
|
||||
*/
|
||||
public static findElementIndex(ary: any[], num: any): any {
|
||||
let len: number = ary.length;
|
||||
for (let i: number = 0; i < len; ++i) {
|
||||
if (ary[i] == num)
|
||||
return i;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回数组中最大值的索引
|
||||
* @param ary
|
||||
* @return 返回数组中最大值的索引
|
||||
*/
|
||||
public static getMaxElementIndex(ary: number[]): number {
|
||||
let matchIndex: number = 0;
|
||||
let len: number = ary.length;
|
||||
for (let j: number = 1; j < len; j++) {
|
||||
if (ary[j] > ary[matchIndex])
|
||||
matchIndex = j;
|
||||
}
|
||||
return matchIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回数组中最小值的索引
|
||||
* @param ary
|
||||
* @return 返回数组中最小值的索引
|
||||
*/
|
||||
public static getMinElementIndex(ary: number[]): number {
|
||||
let matchIndex: number = 0;
|
||||
let len: number = ary.length;
|
||||
for (let j: number = 1; j < len; j++) {
|
||||
if (ary[j] < ary[matchIndex])
|
||||
matchIndex = j;
|
||||
}
|
||||
return matchIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回一个"唯一性"数组
|
||||
* @param ary 需要唯一性的数组
|
||||
* @return 唯一性的数组
|
||||
* 比如: [1, 2, 2, 3, 4]
|
||||
* 返回: [1, 2, 3, 4]
|
||||
*/
|
||||
public static getUniqueAry(ary: number[]): number[] {
|
||||
let uAry: number[] = [];
|
||||
let newAry: number[] = [];
|
||||
let count = ary.length;
|
||||
for (let i: number = 0; i < count; ++i) {
|
||||
let value: number = ary[i];
|
||||
if (uAry.indexOf(value) == -1) uAry.push(value);
|
||||
}
|
||||
|
||||
count = uAry.length;
|
||||
for (let i: number = count - 1; i >= 0; --i) {
|
||||
newAry.unshift(uAry[i]);
|
||||
}
|
||||
return newAry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回2个数组中不同的部分
|
||||
* 比如数组A = [1, 2, 3, 4, 6]
|
||||
* 数组B = [0, 2, 1, 3, 4]
|
||||
* 返回[6, 0]
|
||||
* @param aryA
|
||||
* @param aryB
|
||||
* @return
|
||||
*/
|
||||
public static getDifferAry(aryA: number[], aryB: number[]): number[] {
|
||||
aryA = this.getUniqueAry(aryA);
|
||||
aryB = this.getUniqueAry(aryB);
|
||||
let ary: number[] = aryA.concat(aryB);
|
||||
let uObj: Object = new Object();
|
||||
let newAry: number[] = [];
|
||||
let count: number = ary.length;
|
||||
for (let j: number = 0; j < count; ++j) {
|
||||
if (!uObj[ary[j]]) {
|
||||
uObj[ary[j]] = new Object();
|
||||
uObj[ary[j]].count = 0;
|
||||
uObj[ary[j]].key = ary[j];
|
||||
uObj[ary[j]].count++;
|
||||
}
|
||||
else {
|
||||
if (uObj[ary[j]] instanceof Object) {
|
||||
uObj[ary[j]].count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let i in uObj) {
|
||||
if (uObj[i].count != 2) {
|
||||
newAry.unshift(uObj[i].key);
|
||||
}
|
||||
}
|
||||
return newAry;
|
||||
}
|
||||
|
||||
/**
|
||||
* 交换数组元素
|
||||
* @param array 目标数组
|
||||
* @param index1 交换后的索引
|
||||
* @param index2 交换前的索引
|
||||
*/
|
||||
public static swap(array: any[], index1: number, index2: number): void {
|
||||
let temp: any = array[index1];
|
||||
array[index1] = array[index2];
|
||||
array[index2] = temp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 清除列表
|
||||
* @param ary 列表
|
||||
*/
|
||||
public static clearList(ary: any[]): void {
|
||||
if (!ary) return;
|
||||
let length: number = ary.length;
|
||||
for (let i: number = length - 1; i >= 0; i -= 1) {
|
||||
ary.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 克隆一个数组
|
||||
* @param ary 需要克隆的数组
|
||||
* @return 克隆的数组
|
||||
*/
|
||||
public static cloneList(ary: any[]): any[] {
|
||||
if (!ary) return null;
|
||||
return ary.slice(0, ary.length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断2个数组是否相同
|
||||
* @param ary1 数组1
|
||||
* @param ary2 数组2
|
||||
* @return 是否相同
|
||||
*/
|
||||
public static equals(ary1: number[], ary2: number[]): Boolean {
|
||||
if (ary1 == ary2) return true;
|
||||
let length: number = ary1.length;
|
||||
if (length != ary2.length) return false;
|
||||
while (length--) {
|
||||
if (ary1[length] != ary2[length])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据索引插入元素,索引和索引后的元素都向后移动一位
|
||||
* @param index 插入索引
|
||||
* @param value 插入的元素
|
||||
* @return 插入的元素 未插入则返回空
|
||||
*/
|
||||
public static insert(ary: any[], index: number, value: any): any {
|
||||
if (!ary) return null;
|
||||
let length: number = ary.length;
|
||||
if (index > length) index = length;
|
||||
if (index < 0) index = 0;
|
||||
if (index == length) ary.push(value); //插入最后
|
||||
else if (index == 0) ary.unshift(value); //插入头
|
||||
else {
|
||||
for (let i: number = length - 1; i >= index; i -= 1) {
|
||||
ary[i + 1] = ary[i];
|
||||
}
|
||||
ary[index] = value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
declare class fui {}
|
||||
|
||||
class ContentManager {
|
||||
protected loadedAssets: Map<string, any> = new Map<string, any>();
|
||||
|
||||
@@ -29,7 +27,7 @@ class ContentManager {
|
||||
reject(err);
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
|
||||
239
source/src/Utils/KeyboardUtils.ts
Normal file
239
source/src/Utils/KeyboardUtils.ts
Normal file
@@ -0,0 +1,239 @@
|
||||
class KeyboardUtils {
|
||||
/**
|
||||
* 键盘事件类型
|
||||
*/
|
||||
public static TYPE_KEY_DOWN: number = 0;
|
||||
public static TYPE_KEY_UP: number = 1;
|
||||
|
||||
//存放按下注册数据的字典
|
||||
private static keyDownDict: Object;
|
||||
//存放按起注册数据的字典
|
||||
private static keyUpDict: Object;
|
||||
|
||||
/**
|
||||
* 键值字符串枚举
|
||||
*/
|
||||
public static A: string = "A";
|
||||
public static B: string = "B";
|
||||
public static C: string = "C";
|
||||
public static D: string = "D";
|
||||
public static E: string = "E";
|
||||
public static F: string = "F";
|
||||
public static G: string = "G";
|
||||
public static H: string = "H";
|
||||
public static I: string = "I";
|
||||
public static J: string = "J";
|
||||
public static K: string = "K";
|
||||
public static L: string = "L";
|
||||
public static M: string = "M";
|
||||
public static N: string = "N";
|
||||
public static O: string = "O";
|
||||
public static P: string = "P";
|
||||
public static Q: string = "Q";
|
||||
public static R: string = "R";
|
||||
public static S: string = "S";
|
||||
public static T: string = "T";
|
||||
public static U: string = "U";
|
||||
public static V: string = "V";
|
||||
public static W: string = "W";
|
||||
public static X: string = "X";
|
||||
public static Y: string = "Y";
|
||||
public static Z: string = "Z";
|
||||
|
||||
public static ESC: string = "Esc";
|
||||
public static F1: string = "F1";
|
||||
public static F2: string = "F2";
|
||||
public static F3: string = "F3";
|
||||
public static F4: string = "F4";
|
||||
public static F5: string = "F5";
|
||||
public static F6: string = "F6";
|
||||
public static F7: string = "F7";
|
||||
public static F8: string = "F8";
|
||||
public static F9: string = "F9";
|
||||
public static F10: string = "F10";
|
||||
public static F11: string = "F11";
|
||||
public static F12: string = "F12";
|
||||
|
||||
public static NUM_1: string = "1";
|
||||
public static NUM_2: string = "2";
|
||||
public static NUM_3: string = "3";
|
||||
public static NUM_4: string = "4";
|
||||
public static NUM_5: string = "5";
|
||||
public static NUM_6: string = "6";
|
||||
public static NUM_7: string = "7";
|
||||
public static NUM_8: string = "8";
|
||||
public static NUM_9: string = "9";
|
||||
public static NUM_0: string = "0";
|
||||
|
||||
public static TAB: string = "Tab";
|
||||
public static CTRL: string = "Ctrl";
|
||||
public static ALT: string = "Alt";
|
||||
public static SHIFT: string = "Shift";
|
||||
public static CAPS_LOCK: string = "Caps Lock";
|
||||
public static ENTER: string = "Enter";
|
||||
public static SPACE: string = "Space";
|
||||
public static BACK_SPACE: string = "Back Space";
|
||||
|
||||
public static INSERT: string = "Insert";
|
||||
public static DELETE: string = "Page Down";
|
||||
public static HOME: string = "Home";
|
||||
public static END: string = "Page Down";
|
||||
public static PAGE_UP: string = "Page Up";
|
||||
public static PAGE_DOWN: string = "Page Down";
|
||||
|
||||
public static LEFT: string = "Left";
|
||||
public static RIGHT: string = "Right";
|
||||
public static UP: string = "Up";
|
||||
public static DOWN: string = "Down";
|
||||
|
||||
public static PAUSE_BREAK: string = "Pause Break";
|
||||
public static NUM_LOCK: string = "Num Lock";
|
||||
public static SCROLL_LOCK: string = "Scroll Lock";
|
||||
|
||||
public static WINDOWS: string = "Windows";
|
||||
|
||||
|
||||
public static init(): void {
|
||||
this.keyDownDict = {};
|
||||
this.keyUpDict = {};
|
||||
document.addEventListener("keydown", this.onKeyDonwHander);
|
||||
document.addEventListener("keyup", this.onKeyUpHander);
|
||||
}
|
||||
|
||||
private static onKeyDonwHander(event: KeyboardEvent): void {
|
||||
if (!this.keyDownDict) return;
|
||||
var key: string = this.keyCodeToString(event.keyCode);
|
||||
var o: Object = this.keyDownDict[key];
|
||||
if (o) {
|
||||
var fun: Function = o["fun"];
|
||||
var thisObj: any = o["thisObj"];
|
||||
var args: any = o["args"];
|
||||
fun.apply(thisObj, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static onKeyUpHander(event: KeyboardEvent): void {
|
||||
if (!this.keyUpDict) return;
|
||||
var key: string = this.keyCodeToString(event.keyCode);
|
||||
var o: Object = this.keyUpDict[key];
|
||||
if (o) {
|
||||
var fun: Function = o["fun"];
|
||||
var thisObj: any = o["thisObj"];
|
||||
var args: any = o["args"];
|
||||
fun.apply(thisObj, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 注册按键
|
||||
* @param key 键值
|
||||
* @param fun 回调方法
|
||||
* @param type 按键类型 TYPE_KEY_DOWN、TYPE_KEY_UP
|
||||
*/
|
||||
public static registerKey(key: string, fun: Function, thisObj: any, type: number = 0, ...args): void {
|
||||
var keyDict: Object = type ? this.keyUpDict : this.keyDownDict;
|
||||
keyDict[key] = { "fun": fun, args: args, "thisObj": thisObj };
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销按键
|
||||
* @param key 键值
|
||||
* @param type 注销的类型
|
||||
*/
|
||||
public static unregisterKey(key: string, type: number = 0): void {
|
||||
var keyDict: Object = type ? this.keyUpDict : this.keyDownDict;
|
||||
delete keyDict[key];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据keyCode或charCode获取相应的字符串代号
|
||||
* @param keyCode
|
||||
* @return 键盘所指字符串代号
|
||||
*/
|
||||
private static keyCodeToString(keyCode: number): string {
|
||||
switch (keyCode) {
|
||||
case 8:
|
||||
return this.BACK_SPACE;
|
||||
case 9:
|
||||
return this.TAB;
|
||||
case 13:
|
||||
return this.ENTER;
|
||||
case 16:
|
||||
return this.SHIFT;
|
||||
case 17:
|
||||
return this.CTRL;
|
||||
case 19:
|
||||
return this.PAUSE_BREAK;
|
||||
case 20:
|
||||
return this.CAPS_LOCK;
|
||||
case 27:
|
||||
return this.ESC;
|
||||
case 32:
|
||||
return this.SPACE;
|
||||
case 33:
|
||||
return this.PAGE_UP;
|
||||
case 34:
|
||||
return this.PAGE_DOWN;
|
||||
case 35:
|
||||
return this.END;
|
||||
case 36:
|
||||
return this.HOME;
|
||||
case 37:
|
||||
return this.LEFT;
|
||||
case 38:
|
||||
return this.UP;
|
||||
case 39:
|
||||
return this.RIGHT;
|
||||
case 40:
|
||||
return this.DOWN;
|
||||
case 45:
|
||||
return this.INSERT;
|
||||
case 46:
|
||||
return this.DELETE;
|
||||
case 91:
|
||||
return this.WINDOWS;
|
||||
case 112:
|
||||
return this.F1;
|
||||
case 113:
|
||||
return this.F2;
|
||||
case 114:
|
||||
return this.F3;
|
||||
case 115:
|
||||
return this.F4;
|
||||
case 116:
|
||||
return this.F5;
|
||||
case 117:
|
||||
return this.F6;
|
||||
case 118:
|
||||
return this.F7;
|
||||
case 119:
|
||||
return this.F8;
|
||||
case 120:
|
||||
return this.F9;
|
||||
case 122:
|
||||
return this.F11;
|
||||
case 123:
|
||||
return this.F12;
|
||||
case 144:
|
||||
return this.NUM_LOCK;
|
||||
case 145:
|
||||
return this.SCROLL_LOCK;
|
||||
default:
|
||||
return String.fromCharCode(keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 销毁方法
|
||||
*/
|
||||
public static destroy(): void {
|
||||
this.keyDownDict = null;
|
||||
this.keyUpDict = null;
|
||||
document.removeEventListener("keydown", this.onKeyDonwHander);
|
||||
document.removeEventListener("keyup", this.onKeyUpHander);
|
||||
}
|
||||
}
|
||||
134
source/src/Utils/RandomUtils.ts
Normal file
134
source/src/Utils/RandomUtils.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
class RandomUtils {
|
||||
/**
|
||||
* 在 start 与 stop之间取一个随机整数,可以用step指定间隔, 但不包括较大的端点(start与stop较大的一个)
|
||||
* 如
|
||||
* this.randrange(1, 10, 3)
|
||||
* 则返回的可能是 1 或 4 或 7 , 注意 这里面不会返回10,因为是10是大端点
|
||||
*
|
||||
* @param start
|
||||
* @param stop
|
||||
* @param step
|
||||
* @return 假设 start < stop, [start, stop) 区间内的随机整数
|
||||
*
|
||||
*/
|
||||
public static randrange(start: number, stop: number, step: number = 1): number {
|
||||
if (step == 0)
|
||||
throw new Error('step 不能为 0');
|
||||
|
||||
let width: number = stop - start;
|
||||
if (width == 0)
|
||||
throw new Error('没有可用的范围(' + start + ',' + stop + ')');
|
||||
if (width < 0)
|
||||
width = start - stop;
|
||||
|
||||
let n: number = Math.floor((width + step - 1) / step);
|
||||
return Math.floor(this.random() * n) * step + Math.min(start, stop);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回a 到 b直间的随机整数,包括 a 和 b
|
||||
* @param a
|
||||
* @param b
|
||||
* @return [a, b] 直接的随机整数
|
||||
*
|
||||
*/
|
||||
public static randint(a: number, b: number): number {
|
||||
a = Math.floor(a);
|
||||
b = Math.floor(b);
|
||||
if (a > b)
|
||||
a++;
|
||||
else
|
||||
b++;
|
||||
return this.randrange(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回 a - b之间的随机数,不包括 Math.max(a, b)
|
||||
* @param a
|
||||
* @param b
|
||||
* @return 假设 a < b, [a, b)
|
||||
*/
|
||||
public static randnum(a: number, b: number): number {
|
||||
return this.random() * (b - a) + a;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打乱数组
|
||||
* @param array
|
||||
* @return
|
||||
*/
|
||||
public static shuffle(array: any[]): any[] {
|
||||
array.sort(this._randomCompare);
|
||||
return array;
|
||||
}
|
||||
|
||||
private static _randomCompare(a: Object, b: Object): number {
|
||||
return (this.random() > .5) ? 1 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从序列中随机取一个元素
|
||||
* @param sequence 可以是 数组、 vector,等只要是有length属性,并且可以用数字索引获取元素的对象,
|
||||
* 另外,字符串也是允许的。
|
||||
* @return 序列中的某一个元素
|
||||
*
|
||||
*/
|
||||
public static choice(sequence: any): any {
|
||||
if (!sequence.hasOwnProperty("length"))
|
||||
throw new Error('无法对此对象执行此操作');
|
||||
let index: number = Math.floor(this.random() * sequence.length);
|
||||
if (sequence instanceof String)
|
||||
return String(sequence).charAt(index);
|
||||
else
|
||||
return sequence[index];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对列表中的元素进行随机采æ ?
|
||||
* <pre>
|
||||
* this.sample([1, 2, 3, 4, 5], 3) // Choose 3 elements
|
||||
* [4, 1, 5]
|
||||
* </pre>
|
||||
* @param sequence
|
||||
* @param num
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
public static sample(sequence: any[], num: number): any[] {
|
||||
let len: number = sequence.length;
|
||||
if (num <= 0 || len < num)
|
||||
throw new Error("采样数量不够");
|
||||
|
||||
let selected: any[] = [];
|
||||
let indices: any[] = [];
|
||||
for (let i: number = 0; i < num; i++) {
|
||||
let index: number = Math.floor(this.random() * len);
|
||||
while (indices.indexOf(index) >= 0)
|
||||
index = Math.floor(this.random() * len);
|
||||
|
||||
selected.push(sequence[index]);
|
||||
indices.push(index);
|
||||
}
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回 0.0 - 1.0 之间的随机数,等同于 Math.random()
|
||||
* @return Math.random()
|
||||
*
|
||||
*/
|
||||
public static random(): number {
|
||||
return Math.random();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算概率
|
||||
* @param chance 概率
|
||||
* @return
|
||||
*/
|
||||
public static boolean(chance: number = .5): boolean {
|
||||
return (this.random() < chance) ? true : false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user