Кто-нибудь знает некоторые из библиотек, которые могут обеспечить такие эффекты, как сотрясение камеры до SKNode
?Эффект дрожания камеры для SpriteKit
Если нет, то есть простой способ реализовать дрожание камеры с помощью действий?
Благодаря
Кто-нибудь знает некоторые из библиотек, которые могут обеспечить такие эффекты, как сотрясение камеры до SKNode
?Эффект дрожания камеры для SpriteKit
Если нет, то есть простой способ реализовать дрожание камеры с помощью действий?
Благодаря
Я нашел элегантный метод, использующий SKAction, который встряхивает ваш узел. Например, с горизонтальным дрожанием:
-(void)shake:(NSInteger)times {
CGPoint initialPoint = self.position;
NSInteger amplitudeX = 32;
NSInteger amplitudeY = 2;
NSMutableArray * randomActions = [NSMutableArray array];
for (int i=0; i<times; i++) {
NSInteger randX = self.position.x+arc4random() % amplitudeX - amplitudeX/2;
NSInteger randY = self.position.y+arc4random() % amplitudeY - amplitudeY/2;
SKAction *action = [SKAction moveTo:CGPointMake(randX, randY) duration:0.01];
[randomActions addObject:action];
}
SKAction *rep = [SKAction sequence:randomActions];
[self runAction:rep completion:^{
self.position = initialPoint;
}];
}
-(void)screen_shake
{
if (shake)
{
current_number_of_shakes++;
float randx = (float)[self randomValueBetween:1 and:90]/50.0f;
if ([self randomValueBetween:0 and:1] == 0)
randx = -randx;
float randy = (float)[self randomValueBetween:1 and:90]/50.0f;
if ([self randomValueBetween:0 and:1] == 0)
randy = -randy;
camera.position = CGPointMake(camera.position.x + randx, camera.position.y + randy);
if (current_number_of_shakes >= total_amount_of_shakes)
{
current_number_of_shakes = 0;
move_back_from_shake = YES;
[camera runAction:[SKAction sequence:@[[SKAction moveTo:start_point_before_shake duration:.7], [SKAction performSelector:@selector(shake_done) onTarget:self]]]];
}
}
}
После некоторых работ и ссылающихся как люди делают это Cocoa2D вот что я придумал. В вашем методе обновления вам нужно будет вызвать этот метод. Есть некоторые константы, которые вы можете заполнить пробелами, но я надеюсь, что это поможет всем, кто в этом нуждается. Также весь метод, который выполняет shake_done, обновляет Bool shake до false.
Если вы уже используете Swift вы можете использовать следующий код ...
let shake = SKAction.shake(node.position, duration: 0.3)
node.runAction(shake)
или для более интенсивного дрожания можно настроить амплитуду, а
let shake = SKAction.shake(node.position, duration: 0.3, amplitudeX: 12, amplitudeY: 3)
node.runAction(shake)
здесь является расширение ....
extension SKAction {
class func shake(initialPosition:CGPoint, duration:Float, amplitudeX:Int = 12, amplitudeY:Int = 3) -> SKAction {
let startingX = initialPosition.x
let startingY = initialPosition.y
let numberOfShakes = duration/0.015
var actionsArray:[SKAction] = []
for index in 1...Int(numberOfShakes) {
let newXPos = startingX + CGFloat(arc4random_uniform(UInt32(amplitudeX))) - CGFloat(amplitudeX/2)
let newYPos = startingY + CGFloat(arc4random_uniform(UInt32(amplitudeY))) - CGFloat(amplitudeY/2)
actionsArray.append(SKAction.moveTo(CGPointMake(newXPos, newYPos), duration: 0.015))
}
actionsArray.append(SKAction.moveTo(initialPosition, duration: 0.015))
return SKAction.sequence(actionsArray)
}
}
кредитов идут на Stephen Haney для реализации я просто переехал его в расширение
Спасибо за это! Мой код был основан на отмеченном ответе в этом потоке, поэтому мы официально написали полный круг;) – Stephen
Метод встряхивания в принятом ответе есть предостережения - он может быть применен только к узлам, которые не имеют их х, у координаты бытия изменен другим запуском SKActions. Это связано с тем, что после завершения тряски мы возвращаем позицию узла в исходное положение.
Если вам требуется действие shake, которое работает также с другими SKAction, которые изменяют положение встряхивающего узла (координаты x или y) последовательно/параллельно, вам нужно добавить обратное действие случайных трясков, которые вы применяете.
расширение Срочное для справки:
extension SKAction {
class func shake(duration:CGFloat, amplitudeX:Int = 3, amplitudeY:Int = 3) -> SKAction {
let numberOfShakes = duration/0.015/2.0
var actionsArray:[SKAction] = []
for index in 1...Int(numberOfShakes) {
let dx = CGFloat(arc4random_uniform(UInt32(amplitudeX))) - CGFloat(amplitudeX/2)
let dy = CGFloat(arc4random_uniform(UInt32(amplitudeY))) - CGFloat(amplitudeY/2)
let forward = SKAction.moveByX(dx, y:dy, duration: 0.015)
let reverse = forward.reversedAction()
actionsArray.append(forward)
actionsArray.append(reverse)
}
return SKAction.sequence(actionsArray)
}
}
Обратите внимание, что эта модификация не требует узла должны быть переданы в качестве аргумента
Pls также добавляет код ObjC. Спасибо: D – GeneCode
Это очень приятно, спасибо. –
Вот метод я использую. Надеюсь, поможет. Измените его по своему усмотрению.
-(void)shakeScreenFor:(int)numberOfShakes withIntensity:(CGVector)intensity andDuration:(CGFloat)duration{
UIView *sceneView = self.scene.view;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
[animation setDuration:(duration/numberOfShakes)];
[animation setRepeatCount:numberOfShakes];
[animation setAutoreverses:YES];
[animation setFromValue:[NSValue valueWithCGPoint: CGPointMake([sceneView center].x - intensity.dx, [sceneView center].y - intensity.dy)]];
[animation setToValue:[NSValue valueWithCGPoint: CGPointMake([sceneView center].x + intensity.dx, [sceneView center].y + intensity.dy)]];
[[sceneView layer] addAnimation:animation forKey:@"position"];
}
Это хорошо работало в моей игре, чтобы захлопнуть что-то на экране со значениями '[self shakeScreenFor: 2 withIntensity: CGVectorMake (2, 2) andDuration: 0.1];' – GilesDMiddleton
Это РАБОТАЕТ! Мне это нравится. Проголосовал. Спасибо друг. – GeneCode
Если вы хотите, чтобы встряхнуть всю эту сцену, вот вариант ответа Роба написано в Swift:
func sceneShake(shakeCount: Int, intensity: CGVector, shakeDuration: Double) {
let sceneView = self.scene!.view! as UIView
let shakeAnimation = CABasicAnimation(keyPath: "position")
shakeAnimation.duration = shakeDuration/Double(shakeCount)
shakeAnimation.repeatCount = Float(shakeCount)
shakeAnimation.autoreverses = true
shakeAnimation.fromValue = NSValue(cgPoint: CGPoint(x: sceneView.center.x - intensity.dx, y: sceneView.center.y - intensity.dy))
shakeAnimation.toValue = NSValue(cgPoint: CGPoint(x: sceneView.center.x + intensity.dx, y: sceneView.center.y + intensity.dy))
sceneView.layer.add(shakeAnimation, forKey: "position")
}
Я включил эту функцию в классе ребенка SKScene. Вот пример вызова:
sceneShake(shakeCount: 3, intensity: CGVector(dx: shakeIntensity, dy: shakeIntensity), shakeDuration: shakeDuration)
прохладный. Я попробую это и посмотрю, насколько это лучше, чем то, что я делаю сейчас. – Krzemienski
wow, это работает очень хорошо, хотелось бы, чтобы я мог голосовать дважды, потому что он также помог с некоторыми проблемами FPS, так как я мог очистить свой беспорядок в своем заявлении о обновлении. – Krzemienski
Это не работает для меня, я получаю сообщение об ошибке: Анимация позиции SKScene не влияет. - Есть идеи, что происходит? – user1216855