ipad:如何通过滑动移动精灵,并根据滑动速度继续前进
我有一个精灵(一个球的图像),我可以使用触摸和移动来移动它。我还根据滑动周期确定了该精灵的位置(x轴,y轴)的变化率。ipad:如何通过滑动移动精灵,并根据滑动速度继续前进
现在我需要继续按照它的速度和方向继续这个精灵。这里是我的代码 -
Touch Event
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint location = [touch locationInView: [touch view]];
CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];
self.touchStartTime = [event timestamp];
self.touchStartPosition = location;
if (YES == [self isItTouched:self.striker touchedAt:convertedLocation]) {
self.striker.isInTouch = YES;
}
return YES;
}
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint location = [touch locationInView: [touch view]];
CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];
self.touchLastMovedTime = [event timestamp];
self.touchMovedPosition = convertedLocation;
if(self.striker.isInTouch == YES){
self.striker.position = self.touchMovedPosition;
}
}
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint location = [touch locationInView: [touch view]];
CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];
self.touchEndTime = [event timestamp];
self.touchEndPosition = location;
if(self.striker.isInTouch == YES
&& (self.touchEndTime - self.touchLastMovedTime) <= MAX_TOUCH_HOLD_DURATION)
{
float c = sqrt(pow(self.touchStartPosition.x - self.touchEndPosition.x, 2)
+ pow(self.touchStartPosition.y - self.touchEndPosition.y, 2));
self.striker.speedx = (c - (self.touchStartPosition.y - self.touchEndPosition.y))
/((self.touchEndTime - self.touchStartTime) * 1000);
self.striker.speedy = (c - (self.touchStartPosition.x - self.touchEndPosition.x))
/((self.touchEndTime - self.touchStartTime) * 1000);
self.striker.speedx *= 4;
self.striker.speedy *= 4;
self.striker.isInTouch = NO;
[self schedule:@selector(nextFrame) interval:0.001];
}
}
Scheduled Method to move Sprite
- (void) nextFrame {
[self setPieceNextPosition:self.striker];
[self adjustPieceSpeed:self.striker];
if(abs(self.striker.speedx) <= 1 && abs(self.striker.speedy) <= 1){
[self unschedule:@selector(nextFrame)];
}
}
SET next Position
- (void) setPieceNextPosition:(Piece *) piece{
CGPoint nextPosition;
float tempMod;
tempMod = (piece.position.x + piece.speedx)/SCREEN_WIDTH;
tempMod = (tempMod - (int)tempMod)*SCREEN_WIDTH;
nextPosition.x = tempMod;
tempMod = (piece.position.y + piece.speedy)/SCREEN_HEIGHT;
tempMod = (tempMod - (int)tempMod)*SCREEN_HEIGHT;
nextPosition.y = tempMod;
piece.position = nextPosition;
}
Set new Speed
- (void) adjustPieceSpeed:(Piece *) piece{
piece.speedx =(piece.speedx>0)? piece.speedx-0.05:piece.speedx+0.05;
piece.speedy =(piece.speedy>0)? piece.speedy-0.05:piece.speedy+0.05;
}
虽然,目前我使用静态速度调整技术,但我希望让它动视初始速度(我明白任何想法)
谢谢@all。 我有我的解决方案,如下─
//in adjustSpeed method
piece.speedx -= piece.speedx * DEACCLERATION_FACTOR;
piece.speedy -= piece.speedy * DEACCLERATION_FACTOR;
//and simply, free the sprite to move from ccTouchMoved method not ccTouchEnd
if(self.striker.isInTouch == YES && distance_passed_from_touch_start>=a_threashold){
//calculate speed and position here as it was in ccTouchEnd method
self.striker.isInTouch = NO;
[self schedule:@selector(nextFrame) interval:0.001];
}
看起来你有它八九不离十。您正在调度触摸板上的选择器,计算速度,并根据该速度移动精灵,直到它消失,所以所有机械碎片都在那里。
看起来iffy是物理学。例如,你用速度来做一些奇怪的事情来减慢球的速度,这些球看起来并不现实。
你想要做的是找到手指抬起时精灵的“速度矢量”。虽然你可以尝试为此做一个瞬间速度,但我发现它可以更好地回溯到几个周期,并对它们进行平均以获得最终速度。
然后,一旦你已经得到了矢量(它看起来像一个x和y的速度,像你现在),你想要做这样的事情(提前未经考验的伪代码),以抑制速度:
float speed = sqrt(speedx * speedx + speedy * speedy);
if (speed == 0) {
// kill motion here, unschedule or do whatever you need to
}
// Dampen the speed.
float newSpeed = speed * .9;
if (newSpeed < SOME_THRESHOLD) newSpeed = 0;
speedx = speedx * newSpeed/speed;
speedy = speedy * newSpeed/speed;
// Move sprite according to the new speed
这样可以使球沿着与释放时相同的方向运动,逐渐减速直至停止。欲了解更多信息,特别是如果你想做一些反弹或任何事情,谷歌的矢量代数的介绍。
感谢@cc,我会尽快尝试,让你知道。 – Sadat 2010-07-14 05:51:08
@cc如果我没看错,这类似于 “ speedx = speedx * 0.9; 快速=快速* 0.9; ” 那么我为什么要使用newSpeed还是那些计算? 请让我知道如果你有任何其他解释。 – Sadat 2010-07-14 06:02:09
除了您想要知道当前速度的部分以便将速度降至明确为零以外,情况并不相同。通常,当你从“非零速度”转变为“零速度”时,你会想做一些特殊的事情,所以这就是我一直使用的框架。在上面的例子中,我只是将速度设置为零,但是很可能,您还将不想调度您选择的选择器或设置其他“静止”标志。当然,你可以用“如果speedx
为进一步信息,请让我知道 – Sadat 2010-07-13 08:46:54