爱大客 - 2016年12月
type: channel
link: https://www.idarc.cn/index.php/2016/12/
description: Every piece of all creatures in this freezing world, are racing for freedom.
items: javascript的lint工具那么多,还是eslint比较好用啊.
items: websocket使用chrome客户端REPL和node.js服务端REPL
items: 将Electron的APP打包为UWP的appx包
items: js如何判断一个对象没有任何自己的属性(为空)?
items: 在chrome console和node.js的REPL中使用严格模式
items: java的交互式命令环境(REPL)
items: cocos creator 音频部分控制
items: 微软拥抱开源?!
items: 关于this和箭头函数
items: cocos creator学习浅谈

javascript的lint工具那么多,还是eslint比较好用啊.
type: item
date: 2016-12-30T15:29:28+08:00
description: 有jslint, javascriptlint(jsl), 还有eslint. 貌似eslint是最受欢迎的. 安装eslintnpm i -g eslint 运行:eslint *.js 在js目录下放一个.eslintrc.json文件, 可以对需要lint的规则做设置.下面是我复制cocos creator的配置,并做了一点修改, 忽略了末尾分号检测.{ "extends": "eslint:recommended", "rules": { "comma-dangle": 0, "no-console": 0, "no-constant-condition": 0, "semi": 0, "no-unused-vars": 1 }, "env": { "browser": true, "node": true, "es6": true, "mocha": true }, "plugins": [ ], "globals": { "cc": false, "CC_EDITOR": false, "CC_DEV": false, "CC_JSB": false, "_ccsg": false } }

websocket使用chrome客户端REPL和node.js服务端REPL
type: item
date: 2016-12-29T18:44:50+08:00
description: 在REPL中比较容易调试和发现问题, 所以这儿介绍REPL的玩法.node.js服务端需要安装模块. npm install ws 进入node, 开启服务,等待客户端连接. 为了便于以后向客户端发送消息, 把连接后的ws对象赋值给全局变量thiswsnode > var thisws var Wss = require('./ws').Server var wss = new Wss({port: 3888}) wss.on('connection', function(ws){ thisws = ws console.log('connected.') ws.on('message', function(message){ console.log("msg: ",message) }) }) chrome 打开console,进行连接和监听服务器消息s = new WebSocket('ws://localhost:3888') s.onmessage = function(e){console.log(e.data)} 好啦!, 在chrome中send消息可以在node那边收到, 在node中send消息也可以在chrome中收到了 先从chrome中sends.send('我是chrome') // 在node中将看到这条消息. 再从node中sendthisws.send('我是node服务器') //在chrome中将看到这条消息. 当然,除了chrome自带的WebSocket客户端, 在node中ws也提供客户端, 另外,socket.io也是另一种websocket客户端和服务器的提供者. 总结 浏览器客户端监听和发送 onclose = function(e){} onmessage = function(e){} onopen = function(){} onerror = function(){} send(string) close() node ws服务端监听和发送wss.on('connection',function(ws){}) wss.on('error', function(err){}) wss.on('header',function(array){}) wss.on('listening',function(){}) ws.on('message',function(message_string,flags){}) ws.on('close',function(code, reason){}) ws.on('error',function(err){}) ws.on('open',function(){}) ws.onclose = function(e){} ws.onerror = function(e){} ws.onmessage = function(e){} ws.onopen = function(e){} ws.readyState ws.send(message_string, function(error){}) ws.close(code, reason) // 所有客户端列表 wss.clients wss.close(function(){}) 参考文章: WebSocket and Socket.IO node ws API

将Electron的APP打包为UWP的appx包
type: item
date: 2016-12-26T18:49:58+08:00
description: 开始以前,准备好visual studio 2015, 现在社区版是免费的.这玩意儿很大, 需要装个半天的.先安装由微软推出的Electron打包为uwp工具 (真的是微软推出啊! 微软现在竟然这么拥抱开源...)npm install -g electron-windows-store 然后进入管理员权限的powershell运行:Set-ExecutionPolicy -ExecutionPolicy RemoteSigned OK, 接下来就打包了, 举我自己的app的例子:electron-windows-store --input-directory C:\r\vueproj\nhproj\nhpe --output-directory C:\r\vueproj\nhproj\nhpe_uwp --flatten true --package-version 1.0.0.0 --package-name nhpe 哦, 真的好长, 幸好里面的参数还可以简写:electron-windows-store -i C:\r\vueproj\nhproj\nhpe -o C:\r\vueproj\nhproj\nhpe_uwp -f true -p 1.0.0.0 -n nhpe 需要注意的是, --package-name一项, 名称必须是app运行文件的名称. 比如, 我已经把electron.exe修改为nhpe.exe了,这儿就一定要填写nphe 然后回车后要提示:? Did you download and install the Desktop App Converter? It is *not* required to run this tool. No 这一步不是必须的, 回答no即可. 如果yes的话, 你需要去这儿安装Desktop App Converter,不过还是懒得麻烦了. 回车后提示:? You need to install a development certificate in order to run your app. Would you like us to create one? Yes 这一步必须yes, 否则虽然可以打包成功,然而打好的包由于没有签名而不能运行. 继续回车:? Please enter your publisher identity: CN=idarc ? Please enter the location of your Windows Kit's bin folder: C:\Program Files (x86)\Windows Kits\10\bin\x64 publisher identity这一步必须填写为 CN=xxxx 的格式,否则后面会报错的... Windows Kit这一步, 如果visual studio 装的OK的话, 直接回车就可以了. 接下来会弹窗让你输入密码. 不用输入密码, 点击"none"即可. 等待一会儿, 如果没有错误的话, 就会在指定的目录下看到nhpe.appx, 双击运行安装即可. 安装完了再运行, 哦, 这货和直接运行electron.exe改名的nhpe.exe为毛没有任何外观上的区别? 微软说区别是可以获取在在其他xbox等上运行的能力,然而我并没有xbox...

js如何判断一个对象没有任何自己的属性(为空)?
type: item
date: 2016-12-26T11:43:21+08:00
description: 参考原文 假如有两个空对象, 判断他们是否相等, 结果一定是false:var a = {} var b = {} a == b // false 因为跟c语言类似, 这儿判断的是地址而不是内容. 那么怎么知道a是空呢? 有三个方法. 这儿先假设有一个对象objvar obj = {}方法1Object.keys(obj).length === 0方法2Object.getOwnPropertyNames(obj).length === 0方法3, 自己判断// Speed up calls to hasOwnProperty var hasOwnProperty = Object.prototype.hasOwnProperty; function isEmpty(obj) { // null and undefined are "empty" if (obj == null) return true; // Assume if it has a length property with a non-zero value // that that property is correct. if (obj.length > 0) return false; if (obj.length === 0) return true; // If it isn't an object at this point // it is empty, but it can't be anything *but* empty // Is it empty? Depends on your application. if (typeof obj !== "object") return true; // Otherwise, does it have any properties of its own? // Note that this doesn't handle // toString and valueOf enumeration bugs in IE < 9 for (var key in obj) { if (hasOwnProperty.call(obj, key)) return false; } return true; } // test it isEmpty(""), // true isEmpty(33), // true (arguably could be a TypeError) isEmpty([]), // true isEmpty({}), // true isEmpty({length: 0, custom_property: []}), // true isEmpty("Hello"), // false isEmpty([1,2,3]), // false isEmpty({test: 1}), // false isEmpty({length: 3, custom_property: [1,2,3]}) // false

在chrome console和node.js的REPL中使用严格模式
type: item
date: 2016-12-26T11:14:09+08:00
description: 在chrome中你只能这么做了:(function() { 'use strict'; var foo = 123;//works fine bar = 345;//ReferenceError: bar is not defined }()); 上面这种模式被称之为IIFE(Immediately Invoked Function Expression)即刻执行的函数表达式. 在node中, 你当然也可以用上这种方式, 不过还有一种方式, 在启动node的时候使用--use-strict参数node --use_strict

java的交互式命令环境(REPL)
type: item
date: 2016-12-24T14:01:41+08:00
description: java8及其以前是不支持交互式命令环境REPL的. Java9 将引入一个JShell来支持. 但目前Java9还没有推出, 怎么办呢? 有一个github的项目, 支持java的REPL 使用前, 需要安装JDK(不是JRE), 以及gradle. 下面是命令行中的安装方法git clone https://github.com/albertlatacz/java-repl.git cd java-repl gradle shadowJar cd build/libs java -jar javarepl-dev.jar 需要注意的是,gradle这一步需要执行数分钟, 我的电脑上是8分多钟. java运行这一步, 需要是类似于jdk1.8.0_111/bin/java这样的目录

cocos creator 音频部分控制
type: item
date: 2016-12-21T16:17:59+08:00
description: 由于当前cocos creator音频部分的文档还没有, 这儿简单介绍一下音频部分. 普通的音频的组件是cc.AudioSource, 可以附加在一个node节点上, 同时只能播放一个音频, 添加组件后, 需要将音频拖放到Clip一栏里面(属性为audio-clip). 组件可以进行的操作包括播放/暂停/停止/继续audioSource.play() audioSource.pause() audioSource.stop() audioSource.resume() 可以获取播放进度和总长度audioSource.getCurrentTime() //单位为秒的浮点数 audioSource.getDuration() //同样是单位为秒的浮点数 从属性浏览器中可以发现还有如下属性: clip volume mute loop playOnLoad preload 使用音频引擎 引擎是一个cc下的对象cc.audioEngine来操作的.引擎并不需要去操作一个node对象, 而是直接操作一个资源管理器里面的源文件.所以在定义cc.Class的时候与audioSource不同. 以url的方式定义, 音乐文件(很可能)需要放在resources目录中.// 在操作audioSource的AudioSourceControl.js文件中, 定义属性为cc.AudioSource类型. 然后, 从资源管理器中拖动一个音乐文件到audiosource节点的clip上. 再从层级管理器中拖动audiosource节点到另一个节点的AudioSourceControl.js属性的audioSource上 cc.Class({ properties: { audioSource: { type: cc.AudioSource, default: null }, // 省略其他代码 }) // 在操作audioEngine的AudioEngineControl.js文件中, 定义**url**为cc.AudioClip类型. 然后, 从资源管理器中拖动一个音乐文件到使用此AudioEngineControl.js的节点的audio属性上. // 从示例代码中来看, 这个文件是放在resources目录中的,也就是说, 需要动态加载的. cc.Class({ properties: { audio: { url: cc.AudioClip, default: null }, // 省略其他代码 }) 使用引擎播放, 每次会产生一个audio id, 记住这个id, 用来在后面对该播放中的音乐进行操作.// 播放,暂停,继续, 停止 var id = cc.audioEngine.play(this.audio, false, 1); //参数分别为filepath, loop, volume. filepath示例为res/raw-assets/resources/audio/music_logo.mp3, 如果是拖进来的就不用管这个了. cc.audioEngine.pause(id) cc.audioEngine.resume(id) cc.audioEngine.stop(id) 对所有的播放中音乐统一操作: cc.audioEngine.stopAll(); cc.audioEngine.pauseAll(); cc.audioEngine.resumeAll(); 获取各种状态cc.audioEngine.getCurrentTime(id) // 秒数, 有对应set方法 cc.audioEngine.getDuration(id) // 秒数 cc.audioEngine.getStatus(id) // 返回值-1: 停止状态, 1: 播放状态, 2: 暂停状态. cc.audioEngine.getVolume(id) // 有对应set方法 下面放出cocos creator的示例代码, 先是AudioSourceControl cc.Class({ extends: cc.Component, properties: { audioSource: { type: cc.AudioSource, default: null }, label: { type: cc.Label, default: null } }, // use this for initialization onLoad: function () { // cc.audioEngine.setMaxWebAudioSize(1024*10); }, update: function () { if (!this.label) { return; } va…

微软拥抱开源?!
type: item
date: 2016-12-20T14:27:50+08:00
description: 微软目前的开源项目: 代码编辑器Visual Studio Code, 基于github的开源项目electron Edge浏览器的JS引擎Chakra, 甚至被允许用于node.js, 以替换V8. ANGLE, OpenGL ES到DirectX的翻译器 HoloJS, 微软增强现实眼镜Hololens的开发库 WinJS, 是的, 你可以用WinJS+HTML+JavaScript开发win10的UWP软件, 哦, 不过这和electron有什么区别?

关于this和箭头函数
type: item
date: 2016-12-14T14:18:37+08:00
description: 箭头函数里使用的this不是它自己的this, 是上层环境的this. 默认情况下, 是window.

cocos creator学习浅谈
type: item
date: 2016-12-13T18:55:18+08:00
description: cocos creator集electron, node.js, vue.js, 浏览器对象, canvas, webGL于一身, 哦看起来还是很强大的.结构/assets 根目录下面主要编辑的文件都在这儿 /library, /temp 可以认为都是临时文件, 貌似为了加速编辑器某些处理产生的, 和assets里的资源是匹配关系, 如果匹配出了问题, 这些都删掉, creator会自动再次生成. /local 编辑器布局, 一般情况下并没有什么用, 貌似删了也没有关系 /settings 构建发布等相关配置, 蛮重要的,要保留. package.json 也规定了一些重要的信息, 要保留.运行后还会生成很多.meta文件, 是一个资源文件对应一个.meta, 里面主要是资源文件的uuid和其他一些信息.assets资源所以, 主要的编辑工作都是在assets里面. 再说说assets, 文件可以包括: .fire 场景文件, 规定了场景中各个内容, 也就是creator中层级管理器里面显示的那些东东. 其实是一个json文件. .js 脚本文件, 当然了, 是JavaScript, 这个后面专门说一下资源文件: 图片 包括.png, jpg等, 这个不消说, 是在场景中添加到精灵里面的; 粒子 以.plist结尾. plist和json文件作用相同, 只不过是xml形式的. 粒子文件的粒子图片可以是独立图片, 也可以是内嵌在plist中的base64数据.独立图片的话, 需要和plist放在一个目录中. cocos支持的粒子文件在windows上可以用Particle Editor编辑. 字体 可以使用ttf字体或者是位图字体.fnt, windows下使用BMFont制作, MAC下使用glyph designer制作. windows下的制作方法查看这儿动画 动画目前就我所知, 有三种形式: 通过creator编辑的动画, 以.anim结尾, 实际上也是json文件. 这个应该和项目是紧密耦合的, 因为在文件里面规定了frame帧引用的资源是uuid形式的, 而uuid是在项目中生成的. spine骨骼动画 是使用spine软件制作的骨骼动画, 收费才能使用, 恩, 因此我也不知道这个文件是什么样子的. DragonBones骨骼动画 是使用DragonBones软件制作的骨骼动画, 常被称为龙骨动画, 免费开源, 但似乎以前cocos不支持, 现在貌似也支持的吧太好, 我下载了一个动画加入, 发现骨头缺了一块...不厚道地揣测, 也许是因为龙骨软件的开发商是Egret, 也就是另一个游戏引擎白鹭的开发方, 白鹭引擎貌似现在发展的也不错, 在知乎上还能看到两个引擎的拥护者对喷, 是由于这种竞争关系导致的支持不好吗? 龙骨动画包括三个文件, xxx_ske.json, xxx_tex.json, _tex.png. 在creator中, 将xxx_ske.json拖进层级管理器, 再把_tex.png拖到Dragon Atlas Asset中即可. 音乐等其他文件, 目前暂未涉及. js脚本与nodejs和浏览器js异同js脚本很大程度上结合了node.js和浏览器环境, 然而又有所不同.目前发现与nodejs一致的有: 可以使用node.js的require加载自定义在assets中的任何js模块. js中定义的所有变量var ,function 都只能在本js文件中引用. 要让require的方式暴露本模块中的变量, 同nodejs一样,需要通过module.exports的方式. 可以使用ES2015语法, 如let, const, 箭头函数等 不一致的有: 不能使用node.js自带的模块, 如fs, path等. 与浏览器环境一致的有: 包含一个全局变量window, 向window.xxx赋值,可以在任一js中访问. window其实本来是BOM(浏览器对象模型)的一部分, 然而可以在这儿使用. 据说还可以使用npm install安装第三方纯js库使用, 尚未试过. 另外根据帮助文档, cocos creator的项目中也有一个类似于electron的index.html文件, 目前暂未开放出来提前修改.js脚本运行方式 事实上, 在assets目录中的js脚本, 会在游戏一开始加载的时候全部运行一遍, 运行的顺序似乎并没有什么规律. 如果要控制运行顺序参考这儿 所以, 在js正文中所书写的内容都会被运行. 通过require('js文件名')可以直接引用任意目录下的js 文件, 所以js文件就算在不同的目录下也不能同名. js脚本与其他资源文件的关联 所有的资源是以节点树的方式组织, 有点类似于DOM树, …