Spawning a circle in a random spot on screen

前端 未结 3 530
闹比i
闹比i 2021-01-15 03:05

I\'ve been racking my brain and searching here and all over to try to find out how to generate a random position on screen to spawn a circle. I\'m hoping someone here can he

相关标签:
3条回答
  • 2021-01-15 03:33

    First: Determine the area that will be valid. It might not be the frame of the superview because perhaps the ball (let's call it ballView) might be cut off. The area will likely be (in pseudocode):

    CGSize( Width of the superview - width of ballView , Height of the superview - height of ballView)
    

    Once you have a view of that size, just place it on screen with the origin 0, 0.

    Secondly: Now you have a range of valid coordinates. Just use a random function (like the one you are using) to select one of them.

    Create a swift file with the following:

    extension Int
    {
        static func random(range: Range<Int>) -> Int
        {
            var offset = 0
    
            if range.startIndex < 0   // allow negative ranges
            {
                offset = abs(range.startIndex)
            }
    
            let mini = UInt32(range.startIndex + offset)
            let maxi = UInt32(range.endIndex   + offset)
    
            return Int(mini + arc4random_uniform(maxi - mini)) - offset
        }
    }
    

    And now you can specify a random number as follows:

    Int.random(1...1000) //generate a random number integer somewhere from 1 to 1000.
    

    You can generate the values for the x and y coordinates now using this function.

    0 讨论(0)
  • 2021-01-15 03:41

    Given the following random generators:

    public extension CGFloat {
        public static var random: CGFloat { return CGFloat(arc4random()) / CGFloat(UInt32.max) }
    
        public static func random(between x: CGFloat, and y: CGFloat) -> CGFloat {
            let (start, end) = x < y ? (x, y) : (y, x)
            return start + CGFloat.random * (end - start)
        }
    }
    
    public extension CGRect {
        public var randomPoint: CGPoint {
            var point = CGPoint()
            point.x = CGFloat.random(between: origin.x, and: origin.x + width)
            point.y = CGFloat.random(between: origin.y, and: origin.y + height)
            return point
        }
    }
    

    You can paste the following into a playground:

    import XCPlayground
    import SpriteKit
    
    let view = SKView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
    XCPShowView("game", view)
    
    let scene = SKScene(size: view.frame.size)
    view.presentScene(scene)
    
    let wait = SKAction.waitForDuration(0.5)
    let popIn = SKAction.scaleTo(1, duration: 0.25)
    let popOut = SKAction.scaleTo(0, duration: 0.25)
    let remove = SKAction.removeFromParent()
    
    let popInAndOut = SKAction.sequence([popIn, wait, popOut, remove])
    
    let addBall = SKAction.runBlock { [unowned scene] in
        let ballRadius: CGFloat = 25
        let ball = SKShapeNode(circleOfRadius: ballRadius)
        var popInArea = scene.frame
        popInArea.inset(dx: ballRadius, dy: ballRadius)
        ball.position = popInArea.randomPoint
        ball.xScale = 0
        ball.yScale = 0
        ball.runAction(popInAndOut)
        scene.addChild(ball)
    }
    
    scene.runAction(SKAction.repeatActionForever(SKAction.sequence([addBall, wait])))
    

    (Just make sure to also paste in the random generators, too, or to copy them to the playground's Sources, as well as to open the assistant editor so you can see the animation.)

    0 讨论(0)
  • 2021-01-15 03:48

    The problem there is that you scene is bigger than your screen bounds

    let viewMidX = view!.bounds.midX
    let viewMidY = view!.bounds.midY
    print(viewMidX)
    print(viewMidY)
    
    let sceneHeight = view!.scene!.frame.height
    let sceneWidth = view!.scene!.frame.width
    print(sceneWidth)
    print(sceneHeight)
    
    let currentBall = SKShapeNode(circleOfRadius: 100)
    currentBall.fillColor = .green
    
    let x = view!.scene!.frame.midX - viewMidX + CGFloat(arc4random_uniform(UInt32(viewMidX*2)))
    let y = view!.scene!.frame.midY - viewMidY + CGFloat(arc4random_uniform(UInt32(viewMidY*2)))
    print(x)
    print(y)
    
    currentBall.position = CGPoint(x: x, y: y)
    view?.scene?.addChild(currentBall)
    
    self.removeAllChildren()
    self.addChild(currentBall)
    
    0 讨论(0)
提交回复
热议问题