精灵跟踪触摸

时间:2015-07-14 13:16:33

标签: c++ cocos2d-x

我想在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;

但它不起作用,哪里有问题?雪碧四处跳跃。

1 个答案:

答案 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;
}
  

现在是时候利用为特定时刻处理触摸输入而提供的触摸方法。我们为diffTouchSpriteXdiffTouchSpriteY变量分配值,并在用户触摸屏幕时将touchingScreen设置为true,更新diffTouchSpriteXdiffTouchSpriteY值当用户在屏幕上移动手指并在触摸中断后最终将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'值来更新精灵位置。所以,按照这个速度,精灵需要一秒钟才能到达当前的触摸位置,但这当然是你可以轻松操控的。