Spawning a circle in a random spot on screen

风格不统一 提交于 2019-12-02 00:34:35

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 = UIColor.greenColor()

let xPosition = view!.scene!.frame.midX - viewMidX + CGFloat(arc4random_uniform(UInt32(viewMidX*2)))
let yPosition = view!.scene!.frame.midY - viewMidY + CGFloat(arc4random_uniform(UInt32(viewMidY*2)))
print(xPosition)
print(yPosition)

currentBall.position = CGPointMake(xPosition,yPosition)
view?.scene?.addChild(currentBall)

self.removeAllChildren()
self.addChild(currentBall)
TheFriendlyDinkleberg

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.

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.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!