CocosCreator2.x 开发笔记
一. 组件相关
1. Canvas 组件
1.1 画布透明
场景描述
设置画布透明。
解决方法
开启宏,并且设置Camera的alpha为0。
cc.macro.ENABLE_TRANSPARENT_CANVAS = true;
2. Label 组件
2.1 截屏时字体有黑边
场景描述
海报生成类H5,截屏时 label 字体有黑边。
解决方法
把Label组件的 Src Blend Factior 设为 预乘处理 ONE
参考链接
2.0.0 b7 字体有黑边
2.2 动态改变字体颜色
this.labelTip.node.color = new cc.Color(62, 62, 62);
2.3 动态获取文字高度
Label 组件 overflow 设置为 resize_height 属性之后,动态获取文字高度,以便初始化 ScrollView 的 content高度。
this.labelResult.string = 'xxx';
(<any>this.labelResult)._forceUpdateRenderData();
console.log(this.labelResult.node.height);
2.4 通过脚本添加 Label
// 游戏加分动效
let labelScore = new cc.Node();
labelScore.color = new cc.Color(255, 199, 112);
labelScore.addComponent(cc.Label);
labelScore.getComponent(cc.Label).fontSize = 48;
labelScore.getComponent(cc.Label).string = '+' + score;
labelScore.name = 'score';
labelScore.parent = scoreLayer;
labelScore.setPosition(0, 0);
3. Widget (对齐挂件)
3.1 使用方法
通过 Widget (对齐挂件) 组件使元素固定在相当于屏幕的某个位置,注意target属性设置要为canvas。
4. BlockInputEvents 防止事件穿透
4.1 使用方法
在上层UI背景添加 BlockInputEvents 组件 防止事件穿透。
5. ScrollView 组件
5.1 滚动到顶部
scrollView.getComponent(cc.ScrollView).scrollToTop(0);
5.2 规定时间内滚动指定百分比位置上
scrollView.scrollToPercentHorizontal(0.22);
scrollView.scrollToPercentHorizontal(0.22, 0.1);
scrollView.scrollToPercentVertical(0.5, 0.1);
6. WebView 组件
6.1 url改变后的适配问题
WebView改变url后,iPhone底部出现导航栏,尺寸改变,出现顶部显示不全的适配问题。
// 改变 webview url
WebView.url = 'http://xxx';
// 监听屏幕尺寸改变,重新做顶部适配
window.addEventListener('resize', () => {
let adaptHeight = 1514 - 750 * window.innerHeight / window.innerWidth;
this.pageGroup.y = - adaptHeight / 2;
});
7. Sprite 组件
7.1 图片置灰
将彩色图片以黑白图片切换显示。
7.1.1 置灰显示
Sprite 的 Materials 属性默认为 builtin-2d-sprite.mtl,内置灰色Material为 builtin-2d-gray-sprite.mtl,把其拖到Sprite 插槽即可把图片置灰。
7.1.2 代码控制
// 图片节点
@property(cc.Sprite)
card: cc.Sprite = null;
// 材质数组:0=builtin-2d-sprite.mtl;1=builtin-2d-gray-sprite.mtl;
@property([cc.Material])
cardMatArray: cc.Material[] = [];
// 根据代码逻辑,为图片设置材质
if (gray == true) {
this.card.setMaterial(0, this.cardMatArray[1]);
} else {
this.card.setMaterial(0, this.cardMatArray[0]);
}
参考链接
CocosCreator 图片置灰(Material/按钮/图片/Spine)
二. 常用方法
1. 加载微信头像
场景描述
H5生成海报,加载用户微信头像及昵称。
解决方法
使用cc.assetManager.loadRemote加载远程贴图资源。
let headimgurl = 'https://thirdwx.qlogo.cn/xxx';
cc.assetManager.loadRemote<cc.Texture2D>(headimgurl, {ext: '.png'}, (err, texture: cc.Texture2D) => {
// Use texture to create sprite frame
let sf = new cc.SpriteFrame(texture);
this.itemHead.spriteFrame = sf;
});
2. 开发环境判断
if (CC_DEBUG) {
console.log('debug');
} else {
console.log('release');
}
3. 游戏全局变量
通过 window[‘game’] 设置游戏的全局变量,注意在 onLoad() 里赋值
@property // 关卡数据
levelInfo = [];
onLoad() {
window['gameData'] = this;
this.init();
}
init() {
this.levelInfo = [];
}
4. 从父节点中删除该节点
node.removeFromParent();
5. 转化局部坐标系、获取包围盒、判断某个区域是否包含指定坐标点
let p_start = this.nodeParent.convertToNodeSpaceAR(e.getLocation()); // convertToNodeSpace 将一个点转换到节点 (局部) 坐标系,并加上锚点的坐标。
let rect_block = children[i].getBoundingBox(); // getBoundingBox 返回父节坐标系下的轴向对齐的包围盒。
if(rect_block.contains(p_start)){} // contains 当前矩形是否包含指定坐标点。
6. 克隆clone节点
let node = cc.instantiate(this.target);
node.parent = scene;
node.setPosition(0, 0);
7. 获取屏幕尺寸
// 返回视图的设计分辨率(开发分辨率),如:750*1514
cc.view.getDesignResolutionSize().width
cc.view.getDesignResolutionSize().height
// 返回可见区域尺寸,如:750*1334
cc.view.getVisibleSize().width
cc.view.getVisibleSize().height
8. 打开网址
cc.sys.openURL('http://www');
9. 上传base64数据到oss
屏幕截图后,将base64数据上传至oss,并返回图片链接。
需引用sdk
<script src="http://gosspublic.alicdn.com/aliyun-oss-sdk-4.4.4.min.js"></script>
/**
* 截图函数
*/
screenShot() {
...
const dataURL = canvas.toDataURL("image/jpeg", 1.0);
this.uploadToOss(dataURL);
}
/**
* base64转blob
*/
toBlob(urlData, fileType) {
let bytes = window.atob(urlData);
let n = bytes.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bytes.charCodeAt(n);
}
return new Blob([u8arr], { type: fileType });
}
/**
* 上传base64到oss
* urlData: 图像数据 (data:image/png;base64,iVBOR...yssDuN70DiAAAAABJRU5ErkJggg==)
*/
uploadToOss(urlData) {
const self = this;
// 图像数据
const base64 = urlData.split(',').pop();
const fileType = urlData.split(';').shift().split(':').pop();
// base64转blob
const blob = this.toBlob(base64, fileType);
// blob转arrayBuffer
const reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onload = function (event) {
// 配置OSS
const client = new OSS.Wrapper({
region: '<Your region>',
accessKeyId: '<Your AccessKeyId>',
accessKeySecret: '<Your AccessKeySecret>',
bucket: 'Your bucket name'
});
// 路径
const dirname = 'xxx/upload/'
// 文件名
const objectKey = `${new Date().getTime()}.${fileType.split('/').pop()}`;
// arrayBuffer转Buffer
const buffer = new OSS.Buffer(event.target.result);
// 上传
client.put(dirname + objectKey, buffer).then(function (result) {
// console.log(result);
self.uploadImg = `http://xxx/upload/${objectKey}`;
}).catch(function (err) {
console.log(err);
});
}
}
参考链接
三. 使用技巧
1. 自定义loading样式
场景描述
H5加载页面,不使用cocos默认样式,改为白色页面显示加载百分比。
解决方法
使用自定义发布模版,新建build-templates/web-mobile目录,新建index.html、main.js文件。
index.html添加代码,
<style>
html, body {
-ms-touch-action: none;
touch-action: none;
background: #fff;
padding: 0;
border: 0;
margin: 0;
height: 100%;
}
.landscape-tip {
display: none;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #000;
z-index: 1000;
}
.landtip {
position: fixed;
left: 50%;
top: 50%;
margin: -146px 0 0 -146px;
width: 292px;
height: 370px;
background: url(http://xxx/land-tip.png) no-repeat center center;
-webkit-transform: scale(.5, .5);
transform: scale(.5, .5);
}
#splash {
background: #fff;
}
#precent {
position: absolute;
left: 50%;
top: 50%;
color: #000;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.progress-bar {
display: none;
}
</style>
...
<!-- 横屏提示 -->
<div class="landscape-tip" id="landscape">
<div class="landtip"></div>
</div>
...
<script>
var landscape = document.getElementById('landscape');
function orientationChange() {
switch (window.orientation) {
case 0:
landscape.style.display = 'none';
break;
case -90:
landscape.style.display = 'block';
break;
case 90:
landscape.style.display = 'block';
break;
}
}
window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", orientationChange, false);
</script>
main.js添加代码,
function setLoadingDisplay () {
// ...
var percent = 100 * finish / total;
if (progressBar && percent < 100) {
progressBar.style.width = percent.toFixed(2) + '%';
document.getElementById('precent').innerHTML = 'Loading...' + percent.toFixed(0) + '%';
}
// ...
}
2. 字体制作的公共字符集
场景
制作字体文件,如:加载文字、游戏提示语、游戏结果等字符集合。
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:,;'"(!?)+-*/=%
3. 获取地址参数函数
// 获取地址参数, 参数可以是中文也可以是英文
getUrlParam(key) {
let url = window.location.search;
let reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
let result = url.substr(1).match(reg);
return result ? decodeURIComponent(result[2]) : null;
}
4. 上下滑动事件
let startPosY = 0;
this.eventLayer.node.on(cc.Node.EventType.TOUCH_START, function (e) {
startPosY = e.getLocationY();
}, this);
this.eventLayer.node.on(cc.Node.EventType.TOUCH_END, function (e) {
if(e.getLocationY() - startPosY > 15) {
cc.log('上滑');
}else if(e.getLocationY() - startPosY < -15){
cc.log('下滑');
}
}, this);
5. 随机函数
// 随机数函数,num:随机数数量,from-to:随机数取值范围
createRandom(num, from, to) {
let array = [];
for (let i = from; i <= to; i++) array.push(i);
array.sort(() => {
return 0.5 - Math.random();
});
array.length = num;
return array;
}
6. 像素间隔Bug
场景描述
本来间隔应该是1个像素,但会有规律地出现2个像素间隔的情况。
// 添加以下代码
let size = cc.view.getVisibleSizeInPixel();
cc.view.setDesignResolutionSize(size.width, size.height, cc.ResolutionPolicy.FIXED_WIDTH);
7. 远程打包
场景描述
v2.4版本项目需要首页和资源代码分离部署。
解决方法
修改index.html、main.js文件。
main.js修改代码,
var remote_url = "https://xxx/assets/";
window.boot = function () {
...
function cb (err) {
if (err) return console.error(err.message, err.stack);
count++;
if (count === bundleRoot.length + 1) {
cc.assetManager.loadBundle(remote_url + MAIN, function (err) {
if (!err) cc.game.run(option, onStart);
});
}
}
...
for (var i = 0; i < bundleRoot.length; i++) {
cc.assetManager.loadBundle(remote_url + bundleRoot[i], cb);
}
};
if (window.jsb) {
var isRuntime = (typeof loadRuntime === 'function');
if (isRuntime) {
require('https://xxx/src/settings.js');
...
}
else {
require('https://xxx/src/settings.js');
...
}
...
}
index.html修改代码,
<head>
<link rel="stylesheet" type="text/css" href="https://xxx/style-mobile.css"/>
<link rel="icon" href="https://xxx/favicon.ico"/>
</head>
<body>
...
<script src="https://xxx/src/settings.js" charset="utf-8"></script>
<script src="https://xxx/main.js" charset="utf-8"></script>
<script type="text/javascript">
(function () {
...
loadScript(debug ? 'cocos2d-js.js' : 'https://xxx/cocos2d-js-min.js', function () {
if (CC_PHYSICS_BUILTIN || CC_PHYSICS_CANNON) {
loadScript(debug ? 'physics.js' : 'physics-min.js', window.boot);
}
else {
window.boot();
}
});
})();
</script>
</body>
参考链接
Cocos Creator 打包WebMobile,实现资源代码分离,部署 cdn
8. 接口请求超时处理
// 接口请求
apiPost() {
...
let params = 'xxx';
let xhr = new XMLHttpRequest();
xhr.open('POST', 'xxx');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(params);
let timeState = false; // 是否超时
let timer = setTimeout(() => {
timeState = true;
xhr.abort(); // 请求中止
// 隐藏加载提示
...
}, 20000);
xhr.timeout = 20000; // 20秒超时时间
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400)) {
let response = eval('(' + xhr.responseText + ')');
...
// 程序部分
...
if (timeState) return; // 请求已经超时,忽略中止请求
clearTimeout(timer); // 取消等待的超时
}
};
}
参考链接
cocos creator 网络http请求超时处理
9. CNZZ事件统计
// cnzz统计
_czc.push(['_trackEvent', '按钮点击', '开始游戏按钮']);
10. 创建一个连续数字的数组
/**
* 生成一个从 start 到 end 的连续数组
* @param start
* @param end
*/
generateArray (start: number, end: number) {
return Array.from(new Array(end + 1).keys()).slice(start);
}