我在使用Gravity模块获取数组的所有元素时遇到问题。我已经设法让数组中的LAST元素掉落,然后剩下的元素在测试期间保持在屏幕顶部。经过调试
我正在使用UIKit,并希望在使用其他各种引擎(如SpriteKit和GameplayKit)之前彻底理解这种语言。
func mainGame()
{
let cars = ["car5", "car1", "car6", "car3", "car2", "car4"]
var random2 = Int(arc4random_uniform(UInt32(cars.count))) + 1
for i in 1...random2
{
let image = UIImage(named: cars[i - 1])
let carView = UIImageView(image: image!)
carView.frame = CGRect(x:i * 52, y:0 , width: 40, height: 50)
view.addSubview(carView)
dynamicAnimator = UIDynamicAnimator(referenceView: self.view)
gravityBehavior = UIDynamicItemBehavior(items: [carView]) //cars falling
dynamicAnimator.addBehavior(gravityBehavior)
collisionBehavior = UICollisionBehavior(items: [carView, mainCar]) //collide
collisionBehavior.translatesReferenceBoundsIntoBoundary = false
gravityBehavior.addLinearVelocity(CGPoint(x: 0, y: 200), for: carView)
dynamicAnimator.addBehavior(collisionBehavior)
}
collisionBehavior.addBoundary(withIdentifier: "Barrier" as NSCopying, for: UIBezierPath(rect: mainCar.frame))
collisionBehavior.removeAllBoundaries()
}
到目前为止,阵列中的最后一辆车掉落了,而我控制的主要玩家车有碰撞行为,这对我来说是一大步!
您将在循环的每次迭代中创建一个新的UIDynamicAnimator
并将其分配给dynamicAnimator
。这就是为什么只有最后一个元素正在工作,因为它是分配给该变量的最后一个元素。
要修复它,只需将此行移动到只调用一次的位置。
dynamicAnimator = UIDynamicAnimator(referenceView: self.view)
viewDidLoad
是一个应该工作的地方。
UIKit Dynamics是大多数类似框架的倒退。您没有为对象设置动画。你有一个动画师并附加对象。正如Clever Error所说,在这种情况下你只需要一个动画师。
关键是你不要将重力附着在汽车上;您将汽车附加到行为(重力),然后将行为附加到动画师。是的,这是奇怪的和倒退的。
我没有测试过这个,但正确的代码将更接近于此:
func mainGame()
{
let cars = ["car5", "car1", "car6", "car3", "car2", "car4"]
var random2 = Int(arc4random_uniform(UInt32(cars.count))) + 1
var carViews: [UIImageView] = []
dynamicAnimator = UIDynamicAnimator(referenceView: self.view)
// First create all the views
for i in 1...random2
{
let image = UIImage(named: cars[i - 1])
let carView = UIImageView(image: image!)
carView.frame = CGRect(x:i * 52, y:0 , width: 40, height: 50)
view.addSubview(carView)
carViews.append(carView)
}
// and then attach those to behaviors:
gravityBehavior = UIGravityBehavior(items: carViews) //cars falling
dynamicAnimator.addBehavior(gravityBehavior)
collisionBehavior = UICollisionBehavior(items: carView + mainCar) //collide
collisionBehavior.translatesReferenceBoundsIntoBoundary = false
dynamicAnimator.addBehavior(collisionBehavior)
collisionBehavior.addBoundary(withIdentifier: "Barrier" as NSCopying, for: UIBezierPath(rect: mainCar.frame))
collisionBehavior.removeAllBoundaries()
// You don't need this; it's built into Gravity
// gravityBehavior.addLinearVelocity(CGPoint(x: 0, y: 200), for: carView)
}
UIKitDynamics与大多数动画框架不同的主要方式是动画的东西不知道它们是动画的。你不能问汽车它有什么行为,因为它没有任何行为。 UIDynamicAnimator基本上是一个更新其目标的center
和transform
的定时循环。对它来说真的没什么好看的(与像Core Animation这样有很多花哨的东西相比)。有了一点iOS经验,你可以用一个GCD队列手动实现所有UIKitDynamics(它可能甚至不需要它,因为它在main上运行所有东西......)