cc.Class({
extends: cc.Component,
properties: {
canvas: cc.Node,
target: cc.Node
},
onLoad: function () {
var self = this, parent = this.node.parent;
self.canvas.on(cc.Node.EventType.TOUCH_MOVE, function (event) {
var touches = event.getTouches();
if (touches.length >= 2) {
var touch1 = touches[0], touch2 = touches[1];
// 获取触点距离上一次事件移动的距离对象,对象包含 x 和 y 属性。
var delta1 = touch1.getDelta(), delta2 = touch2.getDelta();
// 将一个点转换到节点 (局部) 空间坐标系,这个坐标系以锚点为原点。
var touchPoint1 = parent.convertToNodeSpaceAR(touch1.getLocation());
//用event.getTouches() 获取触摸事件的集合, touch1.getLocation() 获取触摸点的集合
var touchPoint2 = parent.convertToNodeSpaceAR(touch2.getLocation());
//缩放
var distance = touchPoint1.sub(touchPoint2);
var delta = delta1.sub(delta2);
var scale = 1;
//如果横向移动大于纵向移动,就缩放x
if (Math.abs(distance.x) > Math.abs(distance.y)) {
scale = (distance.x + delta.x) / distance.x * self.target.scale;
}
//如果横向移动小于纵向移动,就缩放y
else {
scale = (distance.y + delta.y) / distance.y * self.target.scale;
}
self.target.scale = scale < 0.1 ? 0.1 : scale;
}
}, self.node);
}
// self.node.on(cc.Node.EventType.TOUCH_MOVE, function (event) {
// var touches = event.getTouches();
// if (touches.length < 2) {
// var touch1 = touches[0];
// // 获取触点距离上一次事件移动的距离对象,对象包含 x 和 y 属性。
// var delta1 = touch1.getDelta();
// // 将一个点转换到节点 (局部) 空间坐标系,这个坐标系以锚点为原点。
// // var touchPoint1 = parent.convertToNodeSpaceAR(touch1.getLocation());
// var rotateBy = cc.rotateBy(.3, delta1.x * 2);
// self.node.runAction(rotateBy);
// }
// }, self.node);
// // 如题所想,需要在TOUCH_MOVE 时,立即执行 rotateBy动作,真机上测试发现,单手指 慢慢TOUCH_MOVE,
// //完全不执行rotateBy 动作,当单手指,快速滑动时,则会被执行,请问大神们有什么好的处理方法吗?
});
const i18n = require(‘i18n’);
cc.Class({
extends: cc.Component,
properties: {
canvas: cc.Node,
touchLocationDisplay: {
default: null,
type: cc.Label
},
follower: {
default: null,
type: cc.Node
},
followSpeed: 200
},
// use this for initialization
onLoad: function () {
var self = this;
self.moveToPos = cc.v2(0, 0);
self.isMoving = false;
self.canvas.on(cc.Node.EventType.TOUCH_START, function (event) {
var touches = event.getTouches();
var touchLoc = touches[0].getLocation();
self.isMoving = true;
self.moveToPos = self.follower.parent.convertToNodeSpaceAR(touchLoc);
self.touchLocationDisplay.textKey = i18n.t("cases/03_gameplay/01_player_control/On/OnTouchCtrl.js.1") + Math.floor(touchLoc.x) + ', ' + Math.floor(touchLoc.y) + ')';
}, self.node);
self.canvas.on(cc.Node.EventType.TOUCH_MOVE, function (event) {
var touches = event.getTouches();
var touchLoc = touches[0].getLocation();
self.moveToPos = self.follower.parent.convertToNodeSpaceAR(touchLoc);
self.touchLocationDisplay.textKey = i18n.t("cases/03_gameplay/01_player_control/On/OnTouchCtrl.js.1") + Math.floor(touchLoc.x) + ', ' + Math.floor(touchLoc.y) + ')';
}, self.node);
self.canvas.on(cc.Node.EventType.TOUCH_END, function (event) {
self.isMoving = false; // when touch ended, stop moving
}, self.node);
},
// called every frame
update: function (dt) {
if (!this.isMoving) return;
var oldPos = this.follower.position;
// get move direction
var direction = this.moveToPos.sub(oldPos).normalize();
// multiply direction with distance to get new position
var newPos = oldPos.add(direction.mul(this.followSpeed * dt));
// set new position
this.follower.setPosition(newPos);
}
});
//******************************* 键盘按下 keyDown 某个键的回调 **********************************//
cc.Class({
extends: cc.Component,
properties: {
sheep: {
default: null,
type: cc.Node
}
},
// use this for initialization
onLoad () {
// set initial move direction
this.turnRight();
//add keyboard input listener to call turnLeft and turnRight
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
},
onDestroy () {
cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
},
onKeyDown (event) {
var macro = cc.macro;
switch(event.keyCode) {
case macro.KEY.a:
case macro.KEY.left:
console.log('turn left');
this.turnLeft();
break;
case macro.KEY.d:
case macro.KEY.right:
console.log('turn right');
this.turnRight();
break;
}
},
// called every frame
update (dt) {
this.sheep.x += this.speed * dt;
},
turnLeft () {
this.speed = -100;
this.sheep.scaleX = 1;
},
turnRight () {
this.speed = 100;
this.sheep.scaleX = -1;
}
});
//示例代码***//
onLoad: function () {
// add key down and key up event
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
},
onDestroy () {
cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
},
//键盘控制代码***//
KeyUpCallBack() {
this.hero.y += 13
//this.hero.rotation = -90
let t = cc.tween;
t(this.hero)
// 同时执行两个 cc.tween
.parallel(
t().to(0.3, { rotation: -90 }),
t().to(0.3, { scale: 1.2 })
)
.to(0.3, { scale: 1 })
.call(() => {
console.log(‘All tweens finished.’)
})
.start()
},
KeyDownCallBack() {
this.hero.y -= 13;
//this.hero.rotation = 90
let t = cc.tween;
t(this.hero)
// 同时执行两个 cc.tween
.parallel(
t().to(0.3, { rotation: 90 }),
t().to(0.3, { scale: 1.2 })
)
.to(0.3, { scale: 1 })
.call(() => {
console.log('All tweens finished.')
})
.start()
//this.hero.rotateTo(1, this.hero.x , -dy);
},
KeyLeftCallBack() {
this.hero.x -= 13;
//this.hero.rotation = 180
let t = cc.tween;
t(this.hero)
// 同时执行两个 cc.tween
.parallel(
t().to(0.3, { rotation: 180 }),
t().to(0.3, { scale: 1.2 })
)
.to(0.3, { scale: 1 })
.call(() => {
console.log('All tweens finished.')
})
.start()
//this.hero.rotateTo(1, -dx , this.hero.y);
//cc.lookAt(new Vec3(-1, 0, 0)); //看向某个位置,通常由于摄像机
},
KeyRightCallBack() {
this.hero.x += 13;
// this.hero.rotation = 0
let t = cc.tween;
t(this.hero)
// 同时执行两个 cc.tween
.parallel(
t().to(0.3, { rotation: 0 }),
t().to(0.3, { scale: 1.2 })
)
.to(0.3, { scale: 1 })
.call(() => {
console.log('All tweens finished.')
})
.start()
// var angle = cc.v2(1, 0).signAngle(dir);
//this.hero.rotateTo(1, dx , this.hero.y);//旋转到某个指定的位置
},
onKeyDown(event) {
switch (event.keyCode) {
case cc.macro.KEY.a:
console.log('Press a key');
break;
case cc.macro.KEY.d:
console.log('Press d key');
break;
case cc.macro.KEY.w:
console.log('Press w key');
break;
case cc.macro.KEY.s:
console.log('Press s key');
break;
case cc.macro.KEY.up:
console.log('Press up key');
this.KeyUpCallBack();
break;
case cc.macro.KEY.down:
console.log('Press down key');
this.KeyDownCallBack();
break;
case cc.macro.KEY.left:
console.log('Press left key');
this.KeyLeftCallBack();
break;
case cc.macro.KEY.right:
console.log('Press right key');
this.KeyRightCallBack();
break;
}
},
//*************************************旋转 示例2 *******************************************//
let action = null;
if (this.direction === “bottom”)
this.direction = “down”;
switch (this.direction) {
case ‘left’:
action = cc.rotateTo(0.2, -90);
break;
case ‘right’:
action = cc.rotateTo(0.2, 90);
break;
case ‘top’:
action = cc.rotateTo(0.2, 0);
break;
case ‘down’:
action = cc.rotateTo(0.2, 180);
break;
}
this.player.runAction(action);
//***************************************触摸 遥杆控制移动 ***************************************//
this.dir = cc.v2(0, 0);
this.controller.on(‘touchstart’, function (e) {
var dx = e.getLocationX() - this.node.x - this.controller.x;
var dy = e.getLocationY() - this.node.y - this.controller.y;
this.rocker.setPosition(dx, dy);
var dir = cc.v2(dx, dy).normalize();
// this.hero.getComponent(‘hero’).setDir(dir);
this.hero.getComponent(‘hero’).dir = dir;
}.bind(this));
this.controller.on(‘touchmove’, function (e) {
var dx = e.getLocationX() - this.node.x - this.controller.x;
var dy = e.getLocationY() - this.node.y - this.controller.y;
var dir = cc.v2(dx, dy);
// this.hero.getComponent(‘hero’).setDir(dir.normalize());
this.hero.getComponent(‘hero’).dir = dir.normalize();
if (dir.mag() < 100) {
this.rocker.setPosition(dir);
} else {
var angle = cc.v2(1, 0).signAngle(dir);
var x = 90 * Math.cos(angle);
var y = 90 * Math.sin(angle);
this.rocker.setPosition(x, y);
}
}.bind(this));
this.controller.on(‘touchend’, function (e) {
this.rocker.setPosition(0, 0);
// this.hero.getComponent(‘hero’).setDir(cc.v2(0,0));
this.hero.getComponent(‘hero’).dir = cc.v2(0, 0);
}.bind(this));
this.controller.on(‘touchcancel’, function (e) {
this.rocker.setPosition(0, 0);
// this.hero.getComponent(‘hero’).setDir(cc.v2(0,0));
this.hero.getComponent(‘hero’).dir = cc.v2(0, 0);
}.bind(this));
cc.game.on(cc.game.EVENT_HIDE, function () {
cc.audioEngine.stopAll();
if (BO.isMusicOn) {
this.AudioSource_game.stop();
}
console.log("进入后台");
});
cc.game.on(cc.game.EVENT_SHOW, function () {
cc.audioEngine.stopAll();
if (BO.isMusicOn) {
this.AudioSource_game.play();
}
console.log("进入前台");
});
if (BO.isMusicOn) {
this.AudioSource_game.play();
} else {
this.AudioSource_game.stop();
}
},
//*********************************** 碰撞检测 ********************************//
onCollisionEnter(other,self){
if(other.node.group == ‘exp’){
// console.log(‘吃到了’);
this.getExp(other.getComponent(‘expPice’).type);
BO.expPicePool.put(other.node);
}else if(other.node.group == ‘fist-hero’ || other.node.group == ‘fist-enemy’){
if(other.node.name == ‘fist’){
if(other.node.parent.parent.parent == self.node){
return;
}
this.hitEnemyName = other.node.parent.parent.parent.getComponent(‘hero’).name;
this.hit(other.node.parent.parent.parent.getComponent(‘hero’));
other.node.group = ‘default’;
}else{
if(other.node.parent.parent == self.node){
return;
}
this.hitEnemyName = other.node.parent.parent.getComponent(‘hero’).name;
this.hit(other.node.parent.parent.getComponent(‘hero’));
}
}
}
//Vec3.Lerp vec2.Lerp Quat.lerp四元素,Math.Lerp Color.lerp 等等 插值运算//
//********************** lerp 插值 【逐元素向量线性插值: A + t * (B - A)】******************//
//*************************** sqlerp 球面插值*************************//
var quat = new cc.Quat(1,2,3,4); //四个分量(x,y,z,w), //默认四元数是 {x=0,y=0,z=0,w=1}
cc.Quat.rotateX(quat, quat, 90);
cc.Quat.rotateX(quat, quat, -90);
console.log(quat);
期望结果:
quat 为 Quat(1,2,3,4) 与旋转前不变
实际结果
Quat {x: 0.6563156479251437, y: 0, z: 0, w: 0.3236432453668684}
经测试,似乎 cc.Quat.rotateX 方法 第一个参数 和 第二个参数 不能是同一个Quat,否则计算结果就会出错。
不确定类似的还有多少,感觉3D的向量计算的基础类,使用多少有些不方便,需要创建大量的临时变量。
官方回答:【非常抱歉,三个 rotate 函数的确有问题,1.1 会修复,急用的话参考这个 PR:】
// ******************* Quat() 四元数设计旋转 【也是通过两个向量计算旋转】 **************************//
可以试试这个方法
const dir = targetPos.sub(this.node.position).normalizeSelf()
const q_tmp = new cc.Quat()
cc.Quat.rotationTo(q_tmp, cc.v3(0, -1, 0), dir)//设置四元数为两向量间的最短路径旋转,默认两向量都已 //归一化 【q_tmp是被设置的四元数】 【cc.v3(0, -1, 0)是两向量的第一个向量】【dir是是两向量的第二个向量】,返回的结果 q_tmp 就是最短路径的旋转,传递到下面的this.node.setRotation中
this.node.setRotation(q_tmp)
cc.v3(0, -1, 0)这个参数指的是 node 指向的方向,比如一个子弹的图片头部是朝下的,这个参数就填 cc.v3(0, -1, 0), 如果是朝上的就是 cc.v3(0, 1, 0)