我想在 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
anddiffTouchSpriteY
variables and settouchingScreen
totrue
when the user touches the screen, updatediffTouchSpriteX
anddiffTouchSpriteY
values when the user moves its finger on the screen and finally settouchingScreen
tofalse
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). TherunAction()
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/