对象定位关闭 [英] Object positioning is off

查看:88
本文介绍了对象定位关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试让一个物体(在这种情况下为绿色青蛙)与玩家精灵(红色青蛙)一致地在与场景相同的平台上生成,这是我的意思.会产生物体,因此玩家前进时不会与物体重叠. (图片显示了绿色青蛙是如何在两个红色青蛙之间,而不是与其中一个红色青蛙对齐的.)

我用于定位对象的代码如下

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

当前在屏幕左侧离开场景一半时生成它.背景精灵是对象的添加对象,其定义如下:

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

随机x也是在背景精灵的x轴上随机生成它们的东西(我也曾尝试过在没有运气的情况下进行调整)

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

最后一个间距是同一级别单位中对象之间的距离.

let spacing:CGFloat = 250

我尝试将播放器精灵的宽度作为参考,但是没有用.可以告诉我我在做什么错.

以下是完整的代码,如果您需要查看全部内容:

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)

    }

我已经尝试使用您已经拥有的代码来实现您在编辑帖子中编写的代码,这就是我所得到的.

  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

    }

所以这次再次以正确的方式实现了代码,我明白了:

因此,播放器仍未与对象对齐,并且由于某种原因,它仅在屏幕的右侧生成.我认为这是因为我拥有一个可以容纳所有东西的worldNode.

worldNode拥有一个玩家,该玩家在worldNode中的起点为(0,0),并且还拥有用于放置对象的关卡单位.摄像机的位置位于播放器节点的中心,我不确定是否是问题所在,但我将在下面提供代码,以便您查看一下.

let startingPosition:CGPoint = CGPointMake(0, 0)

woldNode代码:

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   

相机定位代码:

 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  )

}

我很确定这是我的问题,但请告诉我您的想法.

就像我在评论中说的那样,关键是预先定义x(和y)轴的坐标,并基于该坐标生成节点.首先,让我们在GameScene类中定义一个玩家:

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

现在,预定义产卵位置(对于x和y轴):

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]

现在,当我们知道可能的位置时,让我们先定位玩家并将其添加到场景中:

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

您可以根据播放器的宽度和高度以及屏幕的大小来创建这些位置,但是由于简单起见,我已经对所有内容进行了硬编码.

因此,让玩家在绿色青蛙上方填充一行:

for xLocation in xAxisSpawnLocations {

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

结果将是这样的:

或者,例如,将玩家向右移动一个位置,并在其上方立一列绿色青蛙:

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

它应该看起来像这样:

根据您的评论,这是根据节点数,屏幕宽度和节点大小在屏幕上分配节点的方式:

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)

您应该处理添加过多节点或节点太大时发生的情况,但这可以使您基本了解如何沿x轴分布节点并保持它们之间的相同距离.

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.

解决方案

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.

这篇关于对象定位关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆