我想在cocos2d-x中通过旋转实现跟踪(跟随)触摸。你可以在这里看到这种效果:https://www.youtube.com/watch?v=RZouMyyNGG8(2:10)。
这是我在touchMove中的代码:
_destinationX = touchPoint.x;
_destinationY = touchPoint.y;
_dx = _destinationX - draggedItem->getPositionX();
_dy = _destinationY - draggedItem->getPositionY();
_vx = _dx;
_vy = _dy;
float d = sqrtf((_dx*_dx)+(_dy*_dy));
//nice easing when near destination
if (d < 50 && d > 3){
_vx *= d / 50.0f;
_vy *= d / 50.0f;
}
else if(d <= 3){
_vx = _vy = 0;
}
draggedItem->setPosition(draggedItem->getPosition() + Point(_vx, _vy));
float rad = atan2(_dy, _dx);
float rotateTo = CC_RADIANS_TO_DEGREES(-rad);
if (rotateTo > draggedItem->getRotation() + 180) rotateTo -= 360;
if (rotateTo < draggedItem->getRotation() - 180) rotateTo += 360;
draggedItem->setRotation(rotateTo);
它有效,但精灵目的地点在它的中心位置,所以如果我在触摸开始时不会从它的中心开始它看起来不太好。
所以我计算触摸开始和初始旋转的偏移量:
offsetPoint = Point(touchPoint.x - draggedItem->getPositionX(), touchPoint.y - draggedItem->getPositionY());
offsetRotation = atan2(offsetPoint.y, offsetPoint.x);
我还在触摸移动中添加了这些线条(在顶部):
float alfa = offsetRotation;
float beta = CC_DEGREES_TO_RADIANS(draggedItem->getRotation());
float gamma = alfa + beta;
float radius = offsetPoint.length();
float ax = cosf(gamma) * radius;
float ay = sinf(gamma) * radius;
所以目的地是:
_destinationX = touchPoint.x + ax;
_destinationY = touchPoint.y + ay;
但它不起作用,哪里有问题?雪碧四处跳跃。
答案 0 :(得分:2)
由于我对Obj-C或C ++一点都不熟悉,我会在Swift中给你答案。然后,您将能够将其插入到项目中或“翻译”到Obj-C / C ++。无论如何:
在代表您的游戏场景的文件中,声明一个跟踪用户当前是否正在触摸屏幕的变量。我还假设你想要跟随触摸的精灵由一些变量表示(这里名为'精灵'):
var touchingScreen:Bool = false // needs 'false' as initial value.
weak var sprite:CCSprite!; // represents a connection to the sprite.
然后,你还需要一个变量来表示当前被触摸的点的值与你的精灵在x和y轴上的点之间的差异:
var diffTouchSpriteX:CGFloat!; // not necessary to initialize it with any default value.
var diffTouchSpriteY:CGFloat!; // same.
下一步是在必要时更新这两个变量的值。让我们为此创建一个方法:
func updateDiff(touchX: CGFloat, touchY: CGFloat) {
self.diffTouchSpriteX = touchX - self.sprite.position.x;
self.diffTouchSpriteY = touchY - self.sprite.position.y;
}
现在是时候利用为特定时刻处理触摸输入而提供的触摸方法。我们为
diffTouchSpriteX
和diffTouchSpriteY
变量分配值,并在用户触摸屏幕时将touchingScreen
设置为true
,更新diffTouchSpriteX
和diffTouchSpriteY
值当用户在屏幕上移动手指并在触摸中断后最终将touchingScreen
设置为false
:
override func touchBegan(touch: CCTouch!, withEvent event: CCTouchEvent!) {
self.updateDiff(touch.locationInWorld().x, touch.locationInWorld().y);
self.touchingScreen = true;
}
override func touchMoved(touch: CCTouch!, withEvent event: CCTouchEvent!) {
self.updateDiff(touch.locationInWorld().x, touch.locationInWorld().y);
}
override func touchEnded(touch: CCTouch!, withEvent event: CCTouchEvent!) {
self.touchingScreen = false;
}
override func touchCancelled(touch: CCTouch!, withEvent event: CCTouchEvent!) {
self.touchingScreen = false;
}
最后,最后一步。在Cocos2d方法
fixedUpdate()
内,添加条件以在当前触摸屏幕时移动角色:
override func fixedUpdate(delta: CCTime) {
if (self.touchingScreen) {
self.sprite.runAction(CCActionMoveBy(duration: 1/ 60, position: CGPoint(x: self.diffTouchSpriteX / 60, y: self.diffTouchSpriteY / 60)));
}
}
fixedUpdate()
cocos2d方法以恒定速率运行(如果我记得很清楚的话,每秒1次)。这里的runAction()
方法将通过将'x'添加到其当前位置的'x'值并将'y'添加到其当前位置的'y'值来更新精灵位置。所以,按照这个速度,精灵需要一秒钟才能到达当前的触摸位置,但这当然是你可以轻松操控的。