/*** 观察者方法** @export* @param {*} obj* @param {Function} callback* @param {*} pointer* @return {*}  {ProxyConstructor}*/
export function observer(obj: any,callback: Function,pointer: any
): ProxyConstructor {return new Proxy<ProxyConstructor>(obj, {set(target, property, value, reciever): boolean {if (target[property] !== value) callback.call(pointer, value);Reflect.set(target, property, value, reciever);return true;},});
}
/*** 加载远程url资源方法** @export* @param {string} path* @return {*}  {Promise<any>}*/
export function loadRemote(path: string): Promise<any> {return new Promise<any>((resolve, reject) => {cc.assetManager.loadRemote(path, (error, asset) => {if (error) reject(error);resolve(asset);});});
}
/*** 加载本地resources资源方法** @export* @param {string} path* @return {*}  {Promise<any>}*/
export function loadRes(path: string): Promise<any> {return new Promise<any>((resolve, reject) => {cc.resources.load(path, (error, asset) => {if (error) reject(error);resolve(asset);});});
}
/*** 延时执行方法** @export* @param {number} time* @return {*}  {Promise<boolean>}*/
export function delay(time: number): Promise<boolean> {return new Promise<boolean>((resolve, reject) => {setTimeout(() => {resolve(true);}, time);});
}
/*** 生成随机数方法* @param Min 最小数* @param Max 最大数* @returns min ≤ r ≤ max*/
export function randomNumBoth(Min: number, Max: number): number {let Range: number = Max - Min;let Rand: number = Math.random();let num: number = Min + Math.round(Rand * Range); //四舍五入return num;
}
/*** 多选一方法* @param arr 数组* @returns 数组中任意的一个元素*/
export function manyToOne(arr: Array<any>): any {let key = Math.floor(Math.random() * arr.length);let val = arr[key];// return [key, val];return val;
}
/*** 深拷贝** @param {*} obj* @return {*}*/
export function deepClone(obj: any): any {// 判断是否是对象,不是对象,返回结果(返回值类型)// obj == null判断了null和undefined两种情况  null==undefinedif (typeof obj !== "object" || obj == null) {return obj;}// 初始化结果数据,如果是数组赋值为[],否则为{}let result = Array.isArray(obj) ? [] : {};for (let key in obj) {// 判断是否是自己的属性方法,而不是原型属性方法// 如果是递归复制if (obj.hasOwnProperty(key)) {result[key] = deepClone(obj[key]);}}return result;
}
/*** 一天剩余时间(毫秒)* @returns 剩余时间*/
export const timeRemainingToday = (): number => {const today = new Date();const tomorrowNow = new Date(today);tomorrowNow.setDate(today.getDate() + 1);const tomorrow = new Date(tomorrowNow.getFullYear(),tomorrowNow.getMonth(),tomorrowNow.getDate());return tomorrow.getTime() - today.getTime();
};
/*** 编码方法*/
export const encode = (data) =>window.btoa(encodeURIComponent(JSON.stringify(data)));
/*** 解码方法*/
export const decode = (data) =>JSON.parse(decodeURIComponent(window.atob(data)));
/*** 获取网址的值* @param 网址* @returns 值*/
export function getQueryVariable(variable: string): string {const query = window.location.search.substring(1);const vars = query.split("&");for (let i = 0; i < vars.length; i++) {const pair = vars[i].split("=");if (pair[0] == variable) {return pair[1];}}return "";
}
/*** storage*/
export const storage = {//存储set(key, value) {localStorage.setItem(key, encode(value));},//取出数据get(key) {let data = localStorage.getItem(key);if (data != null && data != "") {data = decode(data);return data;} else {return null;}},// 删除数据remove(key) {localStorage.removeItem(key);},
};
/*** 判断是否是手机的方法* @returns 是否手机*/
export function isMobile() {return !!navigator.userAgent.match(/(iPhone|iPod|Android|ios|iOS|iPad|Backerry|WebOS|Symbian|Windows Phone|Phone)/i);
}
/*** 通过img获取base64格式图片* @param img* @returns*/
export function getBase64Image(img) {let canvas = document.createElement("canvas");canvas.width = img.width;canvas.height = img.height;let ctx = canvas.getContext("2d");ctx.drawImage(img, 0, 0, img.width, img.height);let ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();let dataURL = canvas.toDataURL("image/" + ext);return dataURL;
}
/*** 通过src获取base64格式图片* @param src* @returns*/
export function getBase64ImageByUrl(src) {return new Promise<string>((resolve, reject) => {let image = new Image();image.crossOrigin = "";image.src = src;image.onload = function () {let base64 = getBase64Image(image);resolve(base64);};});
}
/*** 下载图片方法* @param imgsrc 图片路径* @param name 图片名称*/
export function downloadIamge(imgsrc, name) {//下载图片地址和图片名let image = new Image();// 解决跨域 Canvas 污染问题image.setAttribute("crossOrigin", "anonymous");image.onload = function () {let canvas = document.createElement("canvas");canvas.width = image.width;canvas.height = image.height;let context = canvas.getContext("2d");context.drawImage(image, 0, 0, image.width, image.height);let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据let a = document.createElement("a"); // 生成一个a元素let event = new MouseEvent("click"); // 创建一个单击事件a.download = name || "photo"; // 设置图片名称a.href = url; // 将生成的URL设置为a.href属性a.dispatchEvent(event); // 触发a的单击事件};image.src = imgsrc;
}
/*** cocos截图方法* @param node 节点*/
export function screenshot(node: cc.Node) {return new Promise<string>((resolve, reject) => {let nodeCamera = new cc.Node();nodeCamera.parent = cc.find("Canvas");let camera = nodeCamera.addComponent(cc.Camera);let position = node.getPosition();let width = node.width * node.scaleX;let height = node.height * node.scaleY;// 当 alignWithScreen 为 true 的时候,摄像机会自动将视窗大小调整为整个屏幕的大小。如果想要完全自由地控制摄像机,则需要将 alignWithScreen 设置为 false。(v2.2.1 新增)camera.alignWithScreen = false;// 设置摄像机的投影模式是正交(true)还是透视(false)模式camera.ortho = true;// 摄像机在正交投影模式下的视窗大小。该属性在 alignWithScreen 设置为 false 时生效。camera.orthoSize = height / 2;let texture = new cc.RenderTexture();// 如果截图内容中不包含 Mask 组件,可以不用传递第三个参数texture.initWithSize(width,height,cc.game["_renderContext"].STENCIL_INDEX8);// 如果设置了 targetTexture,那么摄像机渲染的内容不会输出到屏幕上,而是会渲染到 targetTexture 上。camera.targetTexture = texture;node.setPosition(cc.Vec2.ZERO);// 渲染一次摄像机,即更新一次内容到 RenderTexture 中camera.render(node);node.setPosition(position);// 从 render texture 读取像素数据,数据类型为 RGBA 格式的 Uint8Array 数组。// 默认每次调用此函数会生成一个大小为 (长 x 高 x 4) 的 Uint8Array。let data = texture.readPixels();// 创建画布let canvas = document.createElement("canvas");canvas.width = width;canvas.height = height;let ctx = canvas.getContext("2d");// write the render data// 1 像素 = 32 bit(RGBA),1 byte = 8 bit,所以 1 像素 = 4 byte// 每行 width 像素,即 width * 4 字节let rowBytes = width * 4;for (let row = 0; row < height; row++) {// RenderTexture 得到的纹理是上下翻转的let srow = height - 1 - row;let imageData = ctx.createImageData(width, 1);let start = srow * width * 4;for (let i = 0; i < rowBytes; i++) {imageData.data[i] = data[start + i];}ctx.putImageData(imageData, 0, row);}let dataURL = canvas.toDataURL("image/jpeg");nodeCamera.destroy();resolve(dataURL);});
}
/*** cocos截图返回精灵方法* @param node 节点*/
export function screenshotSpriteFrame(node: cc.Node) {return new Promise<cc.SpriteFrame>(async (resolve, reject) => {const dataURL = await screenshot(node);let img = document.createElement("img");img.src = dataURL;let texture2D = new cc.Texture2D();texture2D.initWithElement(img);let spriteFrame = new cc.SpriteFrame();spriteFrame.setTexture(texture2D);resolve(spriteFrame);});
}
/*** cocos渲染节点截图方法* @param node 节点*/
export function renderNode(nodeCapture: cc.Node) {return new Promise<string>((resolve, reject) => {let nodeCamera = new cc.Node();nodeCamera.parent = cc.find("Canvas");let camera = nodeCamera.addComponent(cc.Camera);let position = nodeCapture.getPosition();let width = nodeCapture.width * nodeCapture.scaleX;let height = nodeCapture.height * nodeCapture.scaleY;// 当 alignWithScreen 为 true 的时候,摄像机会自动将视窗大小调整为整个屏幕的大小。如果想要完全自由地控制摄像机,则需要将 alignWithScreen 设置为 false。(v2.2.1 新增)camera.alignWithScreen = false;// 设置摄像机的投影模式是正交(true)还是透视(false)模式camera.ortho = true;// 摄像机在正交投影模式下的视窗大小。该属性在 alignWithScreen 设置为 false 时生效。camera.orthoSize = height / 2;let texture = new cc.RenderTexture();// 如果截图内容中不包含 Mask 组件,可以不用传递第三个参数texture.initWithSize(width,height,cc.RenderTexture.DepthStencilFormat.RB_FMT_S8);// 如果设置了 targetTexture,那么摄像机渲染的内容不会输出到屏幕上,而是会渲染到 targetTexture 上。camera.targetTexture = texture;// 创建画布let canvas = document.createElement("canvas");canvas.width = width;canvas.height = height;let ctx = canvas.getContext("2d");nodeCapture.setPosition(cc.Vec2.ZERO);// 渲染一次摄像机,即更新一次内容到 RenderTexture 中camera.render(nodeCapture);nodeCapture.setPosition(position);// 从 render texture 读取像素数据,数据类型为 RGBA 格式的 Uint8Array 数组。// 默认每次调用此函数会生成一个大小为 (长 x 高 x 4) 的 Uint8Array。let data = texture.readPixels();// write the render data// PNG 中 1 像素 = 32 bit(RGBA),1 byte = 8 bit,所以 1 像素 = 4 byte// 每行 width 像素,即 width * 4 字节let rowBytes = width * 4;for (let row = 0; row < height; row++) {// RenderTexture 得到的纹理是上下翻转的let srow = height - 1 - row;let imageData = ctx.createImageData(width, 1);let start = srow * width * 4;for (let i = 0; i < rowBytes; i++) {imageData.data[i] = data[start + i];}ctx.putImageData(imageData, 0, row);}let dataURL = canvas.toDataURL("image/png");let img = document.createElement("img");img.src = dataURL;nodeCamera.destroy();let texture2D = new cc.Texture2D();texture2D.initWithElement(img);let spriteFrame = new cc.SpriteFrame();spriteFrame.setTexture(texture2D);let node = new cc.Node();let sprite = node.addComponent(cc.Sprite);sprite.spriteFrame = spriteFrame;resolve(dataURL);});
}
/*** cocos creater 截屏方法* 分享数据页* orthoSize 视窗大小,用于调整截图避免出现黑边或者白边* @returns 图片*/
export function screenNode(nd: cc.Node,orthoSize: number = 750,w: number = 750,h: number = 1464
) {let node = nd;let camera = node?.getComponent(cc.Camera);if (!camera) {camera = node.addComponent(cc.Camera);}// 设置你想要的截图内容的 cullingMask// camera.cullingMask = 0xffffffff;// 新建一个 RenderTexture,并且设置 camera 的 targetTexture 为新建的 RenderTexture,这样 camera 的内容将会渲染到新建的 RenderTexture 中。let texture = new cc.RenderTexture();//区域截图关闭这个camera.alignWithScreen = false;// let gl = cc.game._renderContext; //gl.STENCIL_INDEX8//尺寸固定750*1624texture.initWithSize(w, h, cc.RenderTexture.DepthStencilFormat.RB_FMT_S8); //(node.width,node.height,cc.RenderTexture.DepthStencilFormat.RB_FMT_S8);  //(cc.visibleRect.width, cc.visibleRect.height);camera.targetTexture = texture;//设置合适的比例,避免出现黑边或者白边camera.orthoSize = orthoSize * node.anchorX * 0.975; //node.width* node.scaleX * 1.07;//截头像的比例 0.5 //截数据页的比例1.07// camera.backgroundColor = cc.Color.TRANSPARENT;// 渲染一次摄像机,即更新一次内容到 RenderTexture 中camera.render();// 这样我们就能从 RenderTexture 中获取到数据了let data = texture.readPixels();// 接下来就可以对这些数据进行操作了let canvas = document.createElement("canvas");let ctx = canvas.getContext("2d");canvas.width = texture.width;canvas.height = texture.height;let width = texture.width;let height = texture.height;let rowBytes = width * 4;for (let row = 0; row < height; row++) {let srow = height - 1 - row;let imageData = ctx.createImageData(width, 1);let start = srow * width * 4;for (let i = 0; i < rowBytes; i++) {imageData.data[i] = data[start + i];}ctx.putImageData(imageData, 0, row);}let dataURL = canvas.toDataURL("image/jpeg");// let img = document.createElement("img");// img.src = dataURL;return dataURL;
}
/*** cocos截取图片方法* @param node 节点*/
export function captureNode(nodeCapture: cc.Node) {return new Promise<cc.SpriteFrame>((resolve, reject) => {let nodeCamera = new cc.Node();nodeCamera.parent = cc.find("Canvas");let camera = nodeCamera.addComponent(cc.Camera);let width = nodeCapture.width;let height = nodeCapture.height;let texture = new cc.RenderTexture();texture.initWithSize(cc.visibleRect.width,cc.visibleRect.height,cc.RenderTexture.DepthStencilFormat.RB_FMT_S8);camera.targetTexture = texture;let canvas = document.createElement("canvas");canvas.width = width;canvas.height = height;let ctx = canvas.getContext("2d");camera.render();// 指定需要读取的区域的像素let size = nodeCapture.getContentSize();let pixels = new Uint8Array(size.width * size.height * 4);let x = texture.width / 2 - nodeCapture.width / 2;let y = texture.height / 2 - nodeCapture.height / 2;let w = nodeCapture.width;let h = nodeCapture.height;let data = texture.readPixels(pixels, x, y, w, h);// write the render datalet rowBytes = width * 4;for (let row = 0; row < height; row++) {let srow = height - 1 - row;let imageData = ctx.createImageData(width, 1);let start = srow * width * 4;for (let i = 0; i < rowBytes; i++) {imageData.data[i] = data[start + i];}ctx.putImageData(imageData, 0, row);}let dataURL = canvas.toDataURL("image/png");let img = document.createElement("img");img.src = dataURL;let texture2D = new cc.Texture2D();texture2D.initWithElement(img);let spriteFrame = new cc.SpriteFrame();spriteFrame.setTexture(texture2D);let node = new cc.Node();let sprite = node.addComponent(cc.Sprite);sprite.spriteFrame = spriteFrame;// return node;resolve(spriteFrame);});
}/*** 截圆形头像图* @param avatar 头像* @param frame 头像框*/
export function captureAvatar(avatar,frame) {return new Promise<string>((resolve, reject) => {let canvas = document.createElement("canvas");//?头像尺寸待定let w = 600;let h = 600;canvas.width = w;canvas.height = h;let ctx = canvas.getContext("2d");ctx.rect(0, 0, canvas.width, canvas.height);ctx.fillStyle = "rgba(255, 255, 255, 0)";ctx.fill();// return;let img = document.createElement("img");img.src = frame;let bgImage = document.createElement("img");bgImage.src = avatar;bgImage.crossOrigin = "Anonymous";bgImage.onload = function () {let circle = {x: w / 2,y: h / 2,r: w / 2,};ctx.clearRect(0, 0, w, h);ctx.save();ctx.beginPath();ctx.arc(circle.x, circle.y, circle.r, 0, Math.PI * 2, false);ctx.clip();ctx.drawImage(bgImage, 0, 0, 600, 600);ctx.drawImage(img, 0, 0, 600, 600);let base64 = canvas.toDataURL("image/png");// let img2 = document.createElement("img");// img2.src = base64;resolve(base64);};});}/*** 清除对象中的空属性* @param obj 对象* @returns 对象*/
export function clearEmpty(obj: any) {const clearFun = () => {for (const key in obj) {if (["[object Object]"].includes(Object.prototype.toString.call(obj[key])) &&Object.keys(obj[key]).length > 0) {clearEmpty(obj[key]);} else {if (["", null, undefined].includes(obj[key]) ||(["[object Object]"].includes(Object.prototype.toString.call(obj[key])) &&Object.keys(obj[key]).length === 0)) {delete obj[key];}}}return obj;};// 第一次清理空属性clearFun();// 第二次清理空对象return clearFun();
}/*** 判断是否是当天函数* @param timeStamp 时间戳* @returns */
export function isToday(timeStamp){if(!timeStamp) return false;return !!(new Date(Number(timeStamp)).toDateString() === new Date().toDateString());
}
/*** 返回当前场景中的canvas节点* @returns */
export function getCanvas() {return <any>director.getScene().getChildByName("Canvas");
}
/*** base64解密*/
export function decode(input) {// private method for UTF-8 decoding  const _utf8_decode = function (utftext) {let string = "";let i = 0;let c = 0;let c1 = 0;let c2 = 0;while (i < utftext.length) {    c = utftext.charCodeAt(i);if (c < 128) {string += String.fromCharCode(c);i++;} else if ((c > 191) && (c < 224)) {c1 = utftext.charCodeAt(i + 1);string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));i += 2;} else {c1 = utftext.charCodeAt(i + 1);c2 = utftext.charCodeAt(i + 2);string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));i += 3;}}return string;}let _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";let output = "";let chr1, chr2, chr3;let enc1, enc2, enc3, enc4;let i = 0;input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");while (i < input.length) {enc1 = _keyStr.indexOf(input.charAt(i++));enc2 = _keyStr.indexOf(input.charAt(i++));enc3 = _keyStr.indexOf(input.charAt(i++));enc4 = _keyStr.indexOf(input.charAt(i++));chr1 = (enc1 << 2) | (enc2 >> 4);chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);chr3 = ((enc3 & 3) << 6) | enc4;output = output + String.fromCharCode(chr1);if (enc3 != 64) {output = output + String.fromCharCode(chr2);}if (enc4 != 64) {output = output + String.fromCharCode(chr3);}}output = _utf8_decode(output);return output;
}
/*** 是否是对象函数* @param {对象} obj*/
export function isObj(obj) {// @ts-ignorereturn ["[object Object]"].includes(Object.prototype.toString.call(obj));}
/*** 更新属性函数(深度搜索算法)* @param {目标属性} targetParams* @param {更新属性} params*/
export function updateProps(targetParams, params) {if (!targetParams ?? !isObj(targetParams)) targetParams = {};if (!isObj(params)) return params;Object.keys(params).forEach((key) => {if (isObj(params[key])) {targetParams[key] = targetParams?.[key] ?? {};updateProps(targetParams[key], params[key]);} else {if (targetParams[key] !== params[key]) {targetParams[key] = params[key];}}});return targetParams;}

cocos creater 游戏开发工具方法相关推荐

  1. Cocos Creator游戏开发教程 学习笔记

    学完提问几个问题吧: position的锚点位置数值原点在哪里? 因为position是相对坐标,所以原点是父节点的锚点 .所以Canvas下面的直属节点原点就是世界坐标系的原点Canvas的锚点. ...

  2. Unity3D ——强大的跨平台3D游戏开发工具教程

    http://unity3d.9ria.com/?p=22 众所周知,Unity3D是一个能够实现轻松创作的多平台的游戏开发工具,是一个全面整合的专业游戏引擎.在现有的版本中,其强大的游戏制作功能已经 ...

  3. 高端游戏开发工具:Unity Pro 2019 Mac版

    Unity Pro 2019 for Mac是专业的游戏开发工具,unity pro 2019 mac版具备最先进的游戏引擎之一,新版本提供了模块化组件系统.着色器可视化编程工具.可视乎开发环境.渲染 ...

  4. Action Game Maker 游戏开发工具介绍

    游戏开发者的论坛(66rpg):http://bbs.66rpg.com/forum-agm-1.html 在上面的论坛看一款游戏开发工具,使开发比较便利,主要能开发2d游戏(RPG,ARPG,RTG ...

  5. 2022 年顶级游戏开发工具

    2,000 亿美元. 这样一个可以追溯到 20 世纪 50 年代的产业现今产值已逾 2,000 亿美元,据估计,间接收入可达 1,000 亿美元.新冠疫情对于蓬勃发展中的游戏业确有益处,因为新老玩家都 ...

  6. 【Cocos Creator游戏开发教程】仿微信趣味画赛车小游戏(三)代码实现

    [Cocos Creator游戏开发教程]仿微信趣味画赛车小游戏(一)前言,界面UI [Cocos Creator游戏开发教程]仿微信趣味画赛车小游戏(二)物理刚体关节 项目地址已放到 github ...

  7. Android 游戏开发工具大升级

    不同的硬件厂商为 Android 用户带来了不同尺寸和体验的设备,因此,我们也一直努力地帮助开发者们将游戏呈现到尽多的 Android 设备并使得开发过程更加高效轻松.本文将向您介绍众多新的 Andr ...

  8. 【转】部分游戏开发工具

    2019独角兽企业重金招聘Python工程师标准>>> GPL许可证        GPL通用性公开许可证(General Public License,简称GPL).在字典中的含义 ...

  9. 部分游戏开发工具(转载)

      GPL许可证 GPL通用性公开许可证(General Public License,简称GPL).在字典中的含义是非洲大羚羊,我们可以常常看到非常个性化的羊头,想必很多人已经非常熟悉.象征 GNU ...

最新文章

  1. 3550配置DHCP
  2. Android SystemProperties系统属性分析
  3. cve-2018-1273 Spring Expression Language 漏洞分析
  4. Uipath 学习栏目基础教学:1Uipath设计器介绍
  5. VS与Matlab混合编译 - mexw64 (C++版)
  6. docker 常用命令(1)
  7. 1024到了,默默给自己点个赞!
  8. stringbuffer字符串反转操作
  9. @Autowired的使用--Spring规范解释,推荐对构造函数进行注释
  10. 认证协议RADIUS篇
  11. MATLAB胸部CT图像中肺部提取,轮廓跟踪技术勾画出肺部轮廓
  12. SQLI-LABS——Page-2 Advanced Injections Less21~Less37
  13. 用CSS 实现水波扩散的特效
  14. 台式电脑怎么添加计算机硬盘,台式机如何添加硬盘|台式机添加硬盘的方法
  15. [体感游戏]关于体感游戏的一些思考(七) --- “我是泰山,你是简?”
  16. RS422管脚定义说明
  17. 一千度近视眼学计算机,【震惊了】你见过近视8百,1千,3千,5千度?你见过9000度吗?...
  18. carsim设置坡度的模块
  19. 华为ensp交换机vlan划分三种接入模式详解-----网络通信原理
  20. 金蝶BOS,服务端执行SQL语句参考

热门文章

  1. python 床前明月光_Python之利用Whoosh搭建轻量级搜索
  2. 谷歌浏览器怎么将迅雷设置为默认下载方式 谷歌浏览器设置迅雷为默认下载的教程
  3. php输出今年春节倒计时,2019年春节倒计时
  4. 棋盘类游戏中的栅格地形渲染
  5. scrapy-中国气象局·天气预报
  6. oracle sun小机处理器,浅析IBM、HP和Sun新一代小型机竞争格局
  7. 黑客新手基础扫盲贴(上) 黑客基地 黑客传说 黑客帝国 指间的黑客 黑客网站
  8. Oracle 分页查询 rownum 和 offset
  9. Nwafu-OJ-1428 Problem Y C语言实习题五——3.数据倒置
  10. 百度云盘搜索引擎【升级版】