Play Uidynamics iOS 9 (go)

Source: Internet
Author: User
Tags new set

Transfer from http://www.cocoachina.com/ios/20150716/12613.html

This article is translated from Fancypixel's blog by Cocoachina translation team member Agspider ( Weibo),

Original: Playing with Uidynamics in IOS 9

Uidynamics is a popular new feature in the IOS7 SDK, which is basically a physics engine that supports UIView, allowing us to customize the physical nature of the UI controls. This API is easy to understand and you can easily create great animations or transitions. I've covered the basics in this article before, and this time we'll look at what's new in iOS 9 for uidynamics.

Collision Boundary (Collision Bounds)

The first version of Uidynamics with a collision system (in Uicollisionbehavior) only supports rectangles. This is understandable, because uiviews are rectangular, but round is not common, let alone optimizing a custom Bezier curve. In iOS 9, the Uidynamicitem protocol has a new attribute: Uidynamicitemcollisionboundstype, which supports the following enumeration types:

    • Rectangle

    • Ellipse

    • Path

This property is read-only, and if we want to modify it, we need to provide our sub-class:

12345 class Ellipse: UIView {  override varcollisionBoundsType: UIDynamicItemCollisionBoundsType {    return.Ellipse  }}

This is the uiview of the default collision boundary.

And this is the same band. The UIView of the Ellipse property.

This covers the circular view, and if we have a whim to draw a more complex, continuous rigid body, we can use the. Path enumeration type, and also override the property:

1 varcollisionBoundingPath: UIBezierPath { get }

This route can be anything you can think of, as long as it is convex (that is, any two points within the polygon, the line between two points is completely contained within the polygon), and is counterclockwise around. Convex this condition may be limited too dead, so introduced Uidynamicitemgroup, it can be described in detail a set of different shapes of the combined graphics. This way, as long as each shape in the combination is convex, even if the resulting polygon is concave, OK.

Field Behavior

Field behavior is a new behavior used throughout the scene. One of the most common examples is the uigravitybehavior we have been using silently, where each object in the scene is subjected to a downward gravity. Now we can use a new set of field forces, like the radial (the closer to the center of the scene, the greater the Force), the noise (the different forces generated randomly in the scene), and so on.

Dynamic Item Behavior (dynamic element behavior)

Uidynamicitembehavior contains a couple of interesting new features:

    • var charge:cgfloat

    • var Anchored:bool

The charge represents an electric charge that affects how an element moves on the electromagnetic field (yes, it sounds crazy), while anchored essentially turns the graphic into a static object in the collision, but does not respond to the event (if something hits it, it does not move), So it can be used perfectly to represent the floor or wall.

Attachment Behavior (adsorption behavior)

Uiattachmentbehavior improved, now looks like a detective with new methods and properties, like Frictiontorque and Attachmentrange. Now that the adsorption behavior becomes more flexible, we can specify a relatively sliding action, a fixed adsorption, a rope link and my favorite: needle-type adsorption. Imagine two objects nailed together and you'll see. These basically cover the new features of Uidynamics, and now it's time to drop the changelog and start building something very two.

Let's play ball.

I spent a lot of time last week on ball King. This is a great time-wasting thing, the concept of the game is very simple, but the performance is very good. And it uses the same philosophy of Crossy Roadde, which won the Apple Design Award: It doesn't affect players in any way, like in-game honors.

One thing I really like about it is the physical model of the ball and the rebound response when the ball hits the rebound. It seems like using it to test the Uidynamics new features mentioned above should be very good. Let's take a look at how to build your own simple version in one step: ballswift

Basket box

Basketball rack can use a uiview as a rebound, a few uiview as the left and right sides of the basket, the front view as the basket itself (without physical rigid body). Using the class ellipse we defined earlier, we can create visual representation of our game scene:

12345678910111213141516171819202122232425262728293031 /*Build the hoop, setup the world appearance*/func buildViews() {  board = UIView(frame: CGRect(x: hoopPosition.x, y: hoopPosition.y, width: 100, height: 100))  board.backgroundColor = .whiteColor()  board.layer.borderColor = UIColor(red: 0.98, green: 0.98, blue: 0.98, alpha: 1).CGColor  board.layer.borderWidth = 2   board.addSubview({    let v = UIView(frame: CGRect(x: 30, y: 43, width: 40, height: 40))    v.backgroundColor = .clearColor()    v.layer.borderColor = UIColor(red: 0.4, green: 0.4, blue: 0.4, alpha: 1).CGColor    v.layer.borderWidth = 5    returnv    }())   leftHoop = Ellipse(frame: CGRect(x: hoopPosition.x + 20, y: hoopPosition.y + 80, width: 10, height: 6))  leftHoop.backgroundColor = .clearColor()  leftHoop.layer.cornerRadius = 3   rightHoop = Ellipse(frame: CGRect(x: hoopPosition.x + 70, y: hoopPosition.y + 80, width: 10, height: 6))  rightHoop.backgroundColor = .clearColor()  rightHoop.layer.cornerRadius = 3   hoop = UIView(frame: CGRect(x: hoopPosition.x + 20, y: hoopPosition.y + 80, width: 60, height: 6))  hoop.backgroundColor = UIColor(red: 177.0/255.0, green: 25.0/255.0, blue: 25.0/255.0, alpha: 1)  hoop.layer.cornerRadius = 3   [board, leftHoop, rightHoop, floor, ball, hoop].map({self.view.addSubview($0)})}

There's really nothing new here, the basket is created programmatically on the constant Cgpoint hoopposition. But the order of the views is important because we want the basket to be higher than the basketball (throwing point).

Nuts and bolts (Nuts and bolts)

The most important part of the basket is the left and right arms, which require a physical round body (which makes the collision with the ball appear natural) and needs to be bolted to the plate and the front frame. These two will become the basic uidynamicitems, and will not collide directly with the collisions involved. The new needle-type adsorption is the result of this, it can combine everything perfectly together, because we can see in this more rough picture:

Within a given deterministic space point, the PIN can only connect several views at a time:

1234567891011 let bolts = [  CGPoint(x: hoopPosition.x + 25, y: hoopPosition.y + 85), // leftHoop -> Board  CGPoint(x: hoopPosition.x + 75, y: hoopPosition.y + 85), // rightHoop -> Board  CGPoint(x: hoopPosition.x + 25, y: hoopPosition.y + 85), // hoop -> Board (L)  CGPoint(x: hoopPosition.x + 75, y: hoopPosition.y + 85)] // hoop -> Board (R) // Build the boardzip([leftHoop, rightHoop, hoop, hoop], offsets).map({  (item, offset) in  animator?.addBehavior(UIAttachmentBehavior.pinAttachmentWithItem(item, attachedToItem: board, attachmentAnchor: bolts))})

If you're not ready to look at the amazing features in version swfit, you're probably not familiar with zip and map. This may seem a bit deliberate at first, but it's simple: Each view is pinned with an offset point, and then we get a series of tuples that will be used later in the mapping function. As the name implies, it creates a mapping between each element in the array of the given object. This allows the left and right sides of the basket to be bolted to the plate and the front frame, as follows:

    • Left arm bolted to the right side of the backboard.

    • The right arm is bolted to the backboard.

    • The basket is bolted to the left side of the backboard.

The next step requires that we hang the backboard and don't fix it, so that a collision can make it turn, as in Ball King's game:

12345678910111213141516171819202122 // Set the density of the hoop, and fix its angle// Hang the hoopanimator?.addBehavior({  let attachment = UIAttachmentBehavior(item: board, attachedToAnchor: CGPoint(x: hoopPosition.x, y: hoopPosition.y))  attachment.length = 2  attachment.damping = 5  returnattachment  }()) animator?.addBehavior({  let behavior = UIDynamicItemBehavior(items: [leftHoop, rightHoop])  behavior.density = 10  behavior.allowsRotation = false  returnbehavior  }())  // Block the board rotationanimator?.addBehavior({  let behavior = UIDynamicItemBehavior(items: [board])  behavior.allowsRotation = false  returnbehavior  }())

The basket is ready, and it's time to go to basketball, with a round custom Uiimageview sub-Class View, like the Ellipse class:

We can then instantiate the ball as a normal Uiimageview:

12345 let ball: Ball = {  let ball = Ball(frame: CGRect(x: 0, y: 0, width: 28, height: 28))  ball.image = UIImage(named: "ball")  returnball}()

Finally, we set his physical properties:

12345678910111213 // Set the elasticity and density of the ballanimator?.addBehavior({  let behavior = UIDynamicItemBehavior(items: [ball])  behavior.elasticity = 1  behavior.density = 3  behavior.action = {    if!CGRectIntersectsRect(self.ball.frame, self.view.frame) {      self.setupBehaviors()      self.ball.center = CGPoint(x: 40, y: self.view.frame.size.height - 100)    }  }  returnbehavior  }())

In this code I set the size of the elasticity (the amplitude of the bounce after the collision), the density (think of it as weight), and the event that ends the game as soon as the ball goes out of range, that is, the game state (in the main view).

Collisions and gravity (collision and Gravity)

I mentioned the new attribute anchored of Uidynamicitembehavior, which disables the dynamic behavior of the object while preserving it in the collision loop. It sounds good to use it to build a sturdy floor:

123456 // Anchor the flooranimator?.addBehavior({  let behavior = UIDynamicItemBehavior(items: [floor])  behavior.anchored = true  returnbehavior  }())

If you forget to set this property, you will be scratching. Anyway, that's what I am.

Well, it's all set, now it's just a matter of gravity and a set of collisions:

12 animator?.addBehavior(UICollisionBehavior(items: [leftHoop, rightHoop, floor, ball]))animator?.addBehavior(UIGravityBehavior(items: [ball]))

Gravity is the scene behavior that applies the downward force to the default per second point. Collision behavior as a parameter of the view that collides with each other. The game has been set up and now we can apply a momentary force to the ball and use our fingers across the screen:

1234 let push = UIPushBehavior(items: [ball], mode: .Instantaneous)push.angle = -1.35push.magnitude = 1.56animator?.addBehavior(push)

You should understand that, although the edge of the scene is really low, it is really interesting to build it (yes, the clouds and bushes are the same, like the Super Mariori).

The usual, you can find the source code on our GitHub page.

See you next time.

Andre-@theandreamazz

Play Uidynamics iOS 9 (go)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.