精灵跟踪触摸
Sprite tracking touch
我想在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);
它可以工作,但是精灵的目标点在它的中心,所以如果我on touchBegin不会从它的中心开始,它看起来不太好
所以我在计算触点开始和初始旋转的偏移量:
offsetPoint = Point(touchPoint.x - draggedItem->getPositionX(), touchPoint.y - draggedItem->getPositionY());
offsetRotation = atan2(offsetPoint.y, offsetPoint.x);
我还在touch move(在顶部)中添加了这些行:
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++。总之:
在代表游戏场景的文件中,声明一个变量来跟踪用户当前是否触摸屏幕。我还假设你想要跟随触摸的精灵是由某个变量表示的(这里名为"sprite"):
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"来更新精灵的位置。所以,在这个速度下,精灵需要一秒钟才能到达当前的触摸位置,但这当然是你可以轻松操作的东西。
- 光线跟踪器灯光反射错误
- 人脸跟踪arduino代码的优化
- 跟踪滚动条上的鼠标事件
- 如何使用新运算符跟踪在循环中创建的 QLabel
- C++:跟踪类对象
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 跟踪日志中的T.11803()是什么意思?
- 我能做些什么来跟踪矢量元素?
- 两个进程可以通过跟踪附加到同一个 PID 吗?
- 提升堆栈跟踪不显示函数名称和行号
- cygwin_exception::open_stackdumpfile:将堆栈跟踪转储到 class4.exe.sta
- 检测 OpenCV C++窗口上的触摸
- 如何按指针查看堆栈跟踪
- WinDbg 不显示某些小型转储文件的完整堆栈跟踪
- C++ MFC 跟踪事件调用
- 是否可以/希望创建不可复制的共享指针模拟(以启用weak_ptr跟踪/借用类型语义)?
- 使用 Dijkstra 算法跟踪两个节点之间的最短路径
- 发布代码的 gdb 堆栈跟踪可读性如何影响 x64?
- MATLAB:跟踪imufilter对象中的状态变化
- 精灵跟踪触摸