c++ - Sprite 跟踪触摸

标签 c++ cocos2d-x

我想在 cocos2d-x 中通过旋转的 Sprite 实现跟踪(跟随)触摸。你可以在这里看到这个效果: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);

它有效,但 Sprite 目标点在它的中心,所以如果我在 touchBegin 上不会从它的中心开始它看起来不太好。

所以我正在计算触摸开始和初始旋转的偏移量:

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;

但是不行,请问是哪里出了问题?雪碧四处跳跃。

最佳答案

由于我对 Obj-C 或 C++ 一点都不熟悉,所以我会用 Swift 给你答案。然后,您将能够将它插入到您的项目中或“翻译”为 Obj-C/C++。无论如何:

Inside the file that represents your gameplay scene, declare a variable that keeps track of whether the user is currently touching the screen or not. I'll also assume the sprite you want to follow the touch is represented by some variable (named 'sprite' here):

var touchingScreen:Bool = false // needs 'false' as initial value.
weak var sprite:CCSprite!; // represents a connection to the sprite.

Then, you'll also want a variable that represents the difference between the value of the point currently being touched and the point your sprite is located in the x and y axises:

var diffTouchSpriteX:CGFloat!; // not necessary to initialize it with any default value.
var diffTouchSpriteY:CGFloat!; // same.

The next step is to update these two variables' values when necessary. Lets create a method for that:

func updateDiff(touchX: CGFloat, touchY: CGFloat) {
  self.diffTouchSpriteX = touchX - self.sprite.position.x;
  self.diffTouchSpriteY = touchY - self.sprite.position.y;
}

Now it's time to make use of the touch methods provided for handling the touch input at specific moments. Let's assign a value to diffTouchSpriteX and diffTouchSpriteY variables and set touchingScreen to true when the user touches the screen, update diffTouchSpriteX and diffTouchSpriteY values when the user moves its finger on the screen and finally set touchingScreen to false once the touch is interrupted:

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

Finally, the last step. Inside the Cocos2d method fixedUpdate(), add a conditional to move the character if the screen is being currently touched:

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)));
  }
}

The fixedUpdate() cocos2d method runs at a constant rate (1 time each second, if I remember well). The runAction() method here will update the sprite position by adding 'x' to its 'x' value of its current position and 'y' to its 'y' value of its current position. So, at this rate it would take one second for the sprite to reach the current touch location, but this of course is something you can easily manipulate.

关于c++ - Sprite 跟踪触摸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31407764/

相关文章:

C++,用define声明一个数组;怎么了? (简单快捷)

C++:根据模板参数设置指针的常量性

c++ - 从 'int' 到 'long int' 性能显着下降

c++ - 花栗鼠碰撞太软

c++ - cocos2dX 方向支持

android - 在android中改变位图中的蓝色和红色 channel

c++ - Qt5 构建失败

c++ - 在 OpenMP 中重置线程局部变量

android - Android 上的 cocos2d-x 屏幕闪烁

c++ - cocos2dx 中的重写函数