Object positioning is off

╄→尐↘猪︶ㄣ 提交于 2019-12-11 23:36:45

问题


Hi, I’m trying to get an object (in this case a green frog) to spawn in line with the player sprite (the red frog) on a platform which is as wide as the scene and what i mean by this, is getting the object to spawn so that when the player advances it doesn’t overlap the object. (The picture shows how the green frog is between two red frogs and not in line with one of the red frogs)

My code for positioning of the objects is as follows

obstacle.position = CGPointMake(-(backgroundSprite.size.width / 2) + CGFloat(randomX) + (spacing * CGFloat(i)), 0)

this currently spawns it on the left side the screen half off the scene. the background sprite is what the object is being added to which is defined like so:

let theSize:CGSize = CGSizeMake(levelUnitWidth, levelUnitHeight)       
let tex:SKTexture = SKTexture(imageNamed: imageName)          
backgroundSprite = SKSpriteNode(texture: tex, color: SKColor.blackColor(), size: theSize)

random x is also what spawns them randomly on the x axis of the background sprite (which I have also tried adjusting with no luck)

let randomX = arc4random_uniform(  UInt32 (backgroundSprite.size.height) )

lastly spacing is the distance between the objects in the same level unit.

let spacing:CGFloat = 250

I have tried implementing the player sprites width as a reference and is hasn’t worked. Can some please tell me what i’m doing wrong here.

Here is the full code if you need to look at it all:

if (theType == LevelType.road) {

for (var i = 0; i < Int(numberOfObjectsInLevel); i++) {

     let obstacle:Object = Object()


     obstacle.theType = LevelType.road


     obstacle.createObject()
     addChild(obstacle)


     let spacing:CGFloat = 250
     obstacle.position = CGPointMake((backgroundSprite.size.width / 4) + CGFloat(randomX) + (spacing * CGFloat(i)), 0)

    }

EDIT:

I have tried implementing that code you made in your edit post with code I had already and this is what I got.

  if (theType == LevelType.road) {


        let xAxisSpawnLocations: [CGFloat] = {

            var spawnLocations:[CGFloat] = []

            //Create 5 possible spawn locations
            let numberOfNodes = 5

            for i in 0...numberOfNodes - 1 {

                /*
                Spacing between nodes will change if:

                1) number of nodes is changed,
                2) screen width is changed,
                3) node's size is changed.
                */

                var xPosition = (frame.maxX - thePlayer.size.width) / CGFloat((numberOfNodes - 1)) * CGFloat(i)

                //add a half of a player's width because node's anchor point is (0.5, 0.5) by default
                xPosition += thePlayer.size.width/2.0

                spawnLocations.append( xPosition )
            }

            return spawnLocations
        }()

        print(xAxisSpawnLocations)

        let yAxisSpawnLocations: [CGFloat] = [0]

        let obstacle:Object = Object()

        obstacle.theType = LevelType.road


        obstacle.createObject()
        addChild(obstacle)

        let randx = xAxisSpawnLocations[Int(arc4random_uniform(UInt32(xAxisSpawnLocations.count)))]

        obstacle.position = CGPoint(x: randx, y: yAxisSpawnLocations[0] )
        obstacle.zPosition = 200

    }

EDIT 2:

so implemented the code again this time the right way and I got this:

So the player still isn't in line with the objects and for some reason it only spawns on the right side of the screen. I think it is because I have a worldNode that holds everything.

the worldNode holds the player which has a starting point of (0,0) in the worldNode and it also holds the level units which holds the objects. the camera position is centered on the player node I'm not sure if this is the problem but i'll provide the code below so you can have a look at it.

let startingPosition:CGPoint = CGPointMake(0, 0)

The woldNode Code:

let worldNode:SKNode = SKNode()


//creates the world node point to be in the middle of the screen
self.anchorPoint = CGPointMake(0.5, 0.5)
addChild(worldNode)

//adds the player as a child node to the world node 
worldNode.addChild(thePlayer)
thePlayer.position = startingPosition
thePlayer.zPosition = 500   

The camera positioning code:

 override func didSimulatePhysics() {

    self.centerOnNode(thePlayer) 
}

//centers the camera on the node world.
func centerOnNode(node:SKNode) {

    let cameraPositionInScene:CGPoint = self.convertPoint(node.position, fromNode: worldNode)
    worldNode.position = CGPoint(x: worldNode.position.x , y:worldNode.position.y - cameraPositionInScene.y  )

}

I pretty sure this is my problem but tell me what you think.


回答1:


Like I said in comments, the key is to predefine coordinates for x (and y) axis and spawn nodes based on that. First, let's define a player inside your GameScene class:

 let player = SKSpriteNode(color: .redColor(), size: CGSize(width: 50, height: 50))

Now, predefine spawn locations (for both x and y axis):

let xAxisSpawnLocations: [CGFloat] = [50.0, 125.0, 200.0, 275.0, 350.0, 425.0]
let yAxisSpawnLocations: [CGFloat] = [50.0, 125.0,  200.0, 275.0]

Now when we know possible positions, let position our player first and add it to the scene:

player.position = CGPoint(x: xAxisSpawnLocations[0], y: yAxisSpawnLocations[0])
player.zPosition = 10
addChild(player)

You could create those positions based on player's width and height and screen's size, but because of simplicity, I've hardcoded everything.

So, lets fill one row, right above the player with green frogs:

for xLocation in xAxisSpawnLocations {

     let greenFrog = SKSpriteNode(color: .greenColor(), size: player.size)
     greenFrog.position = CGPoint(x: xLocation, y: yAxisSpawnLocations[1])
      addChild(greenFrog)
}

The result would be something like this:

Or, for example, move the player by one place to the right, and make a column of green frogs right above him:

player.position = CGPoint(x: xAxisSpawnLocations[1], y: yAxisSpawnLocations[0])


 for yLocation in yAxisSpawnLocations {

      let greenFrog = SKSpriteNode(color: .greenColor(), size: player.size)
       greenFrog.position = CGPoint(x: xAxisSpawnLocations[1], y: yLocation)
      addChild(greenFrog)
  }

And it should look like this:

EDIT:

Based on your comments, this is how you could distribute nodes across the screen based on number of nodes, screen width and node's size:

let xAxisSpawnLocations: [CGFloat] = {

    var spawnLocations:[CGFloat] = []

    //Create 5 possible spawn locations
    let numberOfNodes = 5

    for i in 0...numberOfNodes - 1 {

        /*
            Spacing between nodes will change if:

            1) number of nodes is changed,
            2) screen width is changed,
            3) node's size is changed.
        */

        var xPosition = (frame.maxX - player.size.width) / CGFloat((numberOfNodes - 1)) * CGFloat(i)

        //add a half of a player's width because node's anchor point is (0.5, 0.5) by default
        xPosition += player.size.width/2.0

        spawnLocations.append( xPosition )
    }

    return spawnLocations
}()

print(xAxisSpawnLocations)

You should handle what is happening when too much nodes are added, or if nodes are too big, but this can give you a basic idea how to distribute nodes along x axis and preserve the same distance between them.



来源:https://stackoverflow.com/questions/35101219/object-positioning-is-off

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