I'm having issues with getting ALL elements of an array to fall using the Gravity module. I have managed to get the LAST element in the array to fall and then the remaining elements just stay at the top of the screen during testing. Upon debugging
I am using UIKit and want to understand this language thoroughly before using other various engines such as SpriteKit and 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()
}
With the game so far the last car in the array falls and the main player car that I control has collision behaviour, which is a big step for me!
UIKitDynamics is backwards of most similar frameworks. You don't animate the object. You have an animator and attach objects to it. As Clever Error notes, you only want one animator in this case.
The key point is that you don't attach gravity to cars; you attach cars to behaviors (gravity), and then behaviors to the animator. Yes, that's bizarre and backwards.
I haven't tested this, but the correct code would be closer to this:
The main way that UIKitDynamics is different than most animation frameworks is that things that are animated don't know they're being animated. You can't ask a car what behaviors it has, because it doesn't have any. A UIDynamicAnimator basically is a timing loop that updates the
center
andtransform
of its targets. There's really not anything fancy about it (in contrast to something like Core Animation which has many fancy things going on). With a little iOS experience, you could probably implement all of UIKitDynamics by hand with a single GCD queue (it probably doesn't even need that, since it runs everything on main....)