背景滑动效果实现
如果不转换场景,那玩家在单个屏幕上能够看到的游戏元素是有限的。但是跳转到另一个场景去显示其他元素的话需要一些时间,所以不是必要的话,建议不作跳转。那么为了让单个场景的游戏元素更加丰富,我们可以通过背景滑动操作,将之前处在"屏幕外边"的游戏元素显示出来。
运行效果如下:
Cocos Creator版本:2.2.2
后台回复"背景滑动",获取该项目完整文件:
创建节点
以下是笔者用于演示的几个节点:
- bg就是背景节点,我们在该教程中就是要移动这个节点。
- New Sprite节点是bg的子节点,只是用来在背景移动时作为一个参照物,好让大家知道背景是有被移动的。
- posLabel用于显示当前位置(坐标点)。
- restoreBtn用于还原节点位置,不管玩家当前处在什么坐标点,只要点击该按钮,就直接回到原点。
稍微调整下位置后,场景显示如下:
编写脚本
新建Slide.js脚本文件,在onLoad方法中加入以下代码:
// Slide.js
onLoad () {
// 坐标汇总
this.map = [[0,0]];
this.nowX = 0;
this.nowY = 0;
// 屏幕宽高
this.canvasWidth = cc.Canvas.instance.node.width;
this.canvasHeight = cc.Canvas.instance.node.height;
// 背景原始宽高
this.bgStartWidth = this.node.width;
this.bgStartHeight = this.node.height;
// 触摸监听
this.node.on('touchstart', this.onTouchStart, this);
this.node.on('touchend', this.onTouchEnd, this);
},
1. this.map数组用于存储到达过的所有坐标点。请想象一个直角坐标系,每次滑动,x或者y的大小都会增加或减小1。
2. this.nowX和this.nowY用于当前所在位置的x和y值。
3. 屏幕宽高和背景原始宽高后面会用到。
4. 既然是屏幕滑动,那就肯定要对触摸操作监听了。
onTouchStart方法编写如下:
// Slide.js
onTouchStart (event) {
// 获取手指初始坐标
this.startPos = this.node.convertToNodeSpaceAR(event.getLocation());
},
我们只需要记录下手指刚触摸时的坐标,注意要将世界坐标转为节点坐标。
重点是onTouchEnd方法:
更新:如果有两根手指放上去的话,不进行滑动,依次放开,此时也会导致背景移动。比较好的解决方法是增加滑动触发距离。
// Slide.js
onTouchEnd (event) {
// 获取手指终点坐标
let endPos = this.node.convertToNodeSpaceAR(event.getLocation());
let disX = endPos.x - this.startPos.x; // x方向滑动距离
let disY = endPos.y - this.startPos.y; // y方向滑动距离
let triggerDis = this.canvasWidth / 20; // 屏幕宽度的百分之几作为滑动触发宽度
// 如果滑动距离大于等于屏幕宽度的百分之几则滑动背景
if (disX >= triggerDis) {
// 手指往右滑
this.nowX -= 1;
let isNew = this.addToMap(this.nowX, this.nowY);
if (isNew)
{this.node.width = this.node.width + this.bgStartWidth*2;}
}
else if (disX<0 && Math.abs(disX)>=triggerDis) {
// 手指往左滑
this.nowX += 1;
let isNew = this.addToMap(this.nowX, this.nowY);
if (isNew)
{this.node.width = this.node.width + this.bgStartWidth*2;}
}
else if (disY >= triggerDis) {
// 手指往上滑
this.nowY -= 1;
let isNew = this.addToMap(this.nowX, this.nowY);
if (isNew)
{this.node.height = this.node.height + this.bgStartHeight*2;}
}
else if (disY<0 && Math.abs(disY)>triggerDis) {
// 手指往下滑
this.nowY += 1;
let isNew = this.addToMap(this.nowX, this.nowY);
if (isNew)
{this.node.height = this.node.height + this.bgStartHeight*2;}
}
// 设置文本内容
this.posLabel.string = '(' + this.nowX + ', ' + this.nowY + ')';
// 移动背景(子节点也会移动)
let moveAction = cc.moveTo(0.8, cc.v2(-this.nowX*this.bgStartWidth, -this.nowY*this.bgStartHeight));
this.node.runAction(moveAction);
},
1. 首先获取手指离开时的坐标点,分别获取x方向上和y方向上移动的距离。
2. 将屏幕宽度的5%作为移动触发距离(读者可自行修改这一值),也就是说当玩家手指在x方向或y方向滑动的距离大于等于该触发距离的话,背景就移动。
3. 通过if判断玩家滑动的方向,然后相应的修改this.nowX和this.nowY的值。
4. 将坐标点加入到this.map中。addToMap方法编写如下:
addToMap (x, y) {
// 首先循环查看是否已经存在
for (let i=0; i<this.map.length; i++) {
if (this.map[i][0]==x && this.map[i][1]==y)
{return false;}
}
// 如果没有则加到map中
this.map.push([x, y]);
return true;
},
如果当前坐标点已经存在,就返回false;否则加入到this.map数组中,并返回true。
5. addToMap的返回值用于判断是否要增加背景大小。如果是左右滑动,且之前没有到达过这个坐标,那么就让场景横向增长;如果是上下活动,且没有到过这个坐标,就竖向增长。
注:背景大小不改变的话,玩家滑动就会出现黑色背景了。当然如果读者的游戏是已经确定好滑动之后的背景图片的话,那么这里就不需要改变背景图片的大小了。
6. 最后设置posLabel文本内容以及通过动作来移动背景节点。
注:在移动背景节点时,要将this.nowX和this.nowY的值设为相反数。相信大家可以看懂。
最后是我们还原按钮的事件函数:
// Slide.js
restore () {
// 还原文本和位置到(0, 0)
this.nowX = 0;
this.nowY = 0;
this.posLabel.string = '(0, 0)';
let moveAction = cc.moveTo(0.8, cc.v2(0, 0));
this.node.runAction(moveAction);
}
还原this.nowX和this.nowY的值,重设文本内容,然后让背景节点返回最初的位置即可。
那本节教程就到这,炒鸡简单的吧~