iPad:如何通过滑动并继续按照滑动速度来移动精灵
-
14-09-2020 - |
题
我有一个精灵(球的图像)我可以使用触摸和移动移动它。我还确定了该精灵的位置(x轴,y轴)的变化率,这取决于滑动周期。
现在我需要继续根据其速度和方向进行那个精灵。这是我的代码 -
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;
}
.
虽然,目前我正在使用静态速度调整技术,但我希望根据初始速度(我欣赏任何想法),使其动态(我欣赏任何想法) 解决方案 2
谢谢@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];
}
. 其他提示
看起来你很接近。您正在调度触摸端上的选择器,计算速度,并根据该速度移动精灵,直到它抑制出来,所以所有机械件都在那里。
如果是什么样子是物理学。例如,你正在做一些奇怪的事情,速度慢慢地慢一点,它根本不会看起来不太真实。
要做的是在提升手指时找到精灵的“速度向量”。虽然您可以尝试对此进行瞬间速度,但我发现它更好地对其进行了更好地样品,并将其平均到它们以获得最终速度。
然后,一旦你有那个向量(它看起来像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
.
这将保持球与释放时的相同方向,逐渐放慢速度,直到它停止。有关更多信息,特别是如果您想做一些弹跳或任何东西,谷歌介绍了向量代数。
不隶属于 StackOverflow