已解决:在平铺地图中移动角色时锚定控制按钮?
SOLVED: Anchor control button when moving the character in tile map?
我正在开发一款游戏,其中的角色将由一组 4 个按钮控制,就像在旧游戏机中一样。我使用 spritekit 中的 Tile Map 来创建地图。
一切正常(玩家在按下按钮时移动,场景跟随玩家)除了我的 4 个按钮在角色移动时也会移动。直到 4 个按钮移出屏幕,我再也无法控制它了。
我们如何将 4 个按钮固定到屏幕的右下角?
下面是我用来创建受控按钮的代码
func controlButton() {
button = SKNode()
moveUpButton = SKSpriteNode(imageNamed: "moveup")
moveUpButton.alpha = 1
moveUpButton.setScale(1.5)
moveUpButton.position = CGPoint(x: 400 - self.frame.size.width/2, y: 0 - self.frame.size.height/2)
moveUpButton.zPosition = 2
moveLeftButton = SKSpriteNode(imageNamed: "moveleft")
...
moveRightButton = SKSpriteNode(imageNamed: "moveright")
...
moveDownButton = SKSpriteNode(imageNamed: "movedown")
...
button.addChild(moveUpButton)
button.addChild(moveLeftButton)
button.addChild(moveRightButton)
button.addChild(moveDownButton)
self.addChild(button)
}
这里是我用来创建瓦片地图的代码,为包含墙的瓦片添加物理体节点:
func setUpSceneWithMap(map: SKTileMapNode) {
let tileMap = map
tileMap.setScale(1)
tileMap.position = CGPoint(x: 0 - self.frame.size.width/2, y: 0 - self.frame.size.height/2)
let tileSize = tileMap.tileSize
let halfWidth = CGFloat(tileMap.numberOfColumns) / 2.0 * tileSize.width
let halfHeight = CGFloat(tileMap.numberOfRows) / 2.0 * tileSize.height
for col in 0..<tileMap.numberOfColumns {
for row in 0..<tileMap.numberOfRows {
let tileDefinition = tileMap.tileDefinition(atColumn: col, row: row)
let isEdgeTile = tileDefinition?.userData?["isWalls"] as? Bool
if (isEdgeTile ?? false) {
let x = CGFloat(col) * tileSize.width - halfWidth
let y = CGFloat(row) * tileSize.height - halfHeight
let rect = CGRect(x: 0, y: 0, width: tileSize.width, height: tileSize.height)
let tileNode = SKShapeNode(rect: rect)
tileNode.position = CGPoint(x: x, y: y)
tileNode.physicsBody = SKPhysicsBody.init(rectangleOf: tileSize, center: CGPoint(x: tileSize.width / 2.0, y: tileSize.height / 2.0))
tileNode.physicsBody?.categoryBitMask = gamePhysics.Wall
tileNode.physicsBody?.collisionBitMask = gamePhysics.Player
tileNode.physicsBody?.contactTestBitMask = gamePhysics.Player
tileNode.physicsBody?.isDynamic = false
tileMap.addChild(tileNode)
}
}
}
}
下面也是我将地图添加到场景的代码:
func createScene() {
self.physicsWorld.contactDelegate = self
for node in self.children {
if (node is SKTileMapNode){
if let theMap:SKTileMapNode = node as? SKTileMapNode {
setUpSceneWithMap(map: theMap)
}
}
}
createPlayer()
createCamera()
}
基本上,SpriteKit 订阅了一个子-父节点结构。
我用一张图来说明。
其中每个圆圈代表一个节点。当前,您正在移动 SKScene 节点(自身)。子节点的位置是相对于它附加到的父节点的。当您移动 SKScene 节点时,所有附加到它的节点都会跟着移动,因为它们是子节点。
例如,将节点定位在 (0,0),然后将节点附加到位置 (10,0) 的该节点。将父节点移动到(10,0),在(10,0)的子节点会移动到(20,0),因为它的原点是相对于它的父节点,而不是一般的场景。
要解决您的问题,您需要创建另一层节点。让我用另一张图来说明。
如果您只对地图节点应用移动,则只有子节点(附加到地图节点的节点)会移动。
所以总而言之,您的代码应该是这样的。
class GameScene: SKScene
{
let MapNode,
UINode = SKNode; //This is a fancy way to declare multiple variables of the same type
func controlButton()
{
... //Your other code here
UINode.addChild(button) //Instead of self.addChild(button)
}
func setUpSceneWithMap(map: SKTileMapNode)
{
//Your other code in here
MapNode.addChild(map)
// I don't know where you are adding your tile map to your scene
// However, it most likely is self.addChild(map) which needs to be changed to MapNode.addChild(map)
}
}
将所有场景元素附加到 MapNode,并将所有 UI 元素附加到 UINode。仅将位置更改应用于 MapNode。 UI 元素不会四处移动,除非您希望它们移动。
我正在开发一款游戏,其中的角色将由一组 4 个按钮控制,就像在旧游戏机中一样。我使用 spritekit 中的 Tile Map 来创建地图。 一切正常(玩家在按下按钮时移动,场景跟随玩家)除了我的 4 个按钮在角色移动时也会移动。直到 4 个按钮移出屏幕,我再也无法控制它了。 我们如何将 4 个按钮固定到屏幕的右下角? 下面是我用来创建受控按钮的代码
func controlButton() {
button = SKNode()
moveUpButton = SKSpriteNode(imageNamed: "moveup")
moveUpButton.alpha = 1
moveUpButton.setScale(1.5)
moveUpButton.position = CGPoint(x: 400 - self.frame.size.width/2, y: 0 - self.frame.size.height/2)
moveUpButton.zPosition = 2
moveLeftButton = SKSpriteNode(imageNamed: "moveleft")
...
moveRightButton = SKSpriteNode(imageNamed: "moveright")
...
moveDownButton = SKSpriteNode(imageNamed: "movedown")
...
button.addChild(moveUpButton)
button.addChild(moveLeftButton)
button.addChild(moveRightButton)
button.addChild(moveDownButton)
self.addChild(button)
}
这里是我用来创建瓦片地图的代码,为包含墙的瓦片添加物理体节点:
func setUpSceneWithMap(map: SKTileMapNode) {
let tileMap = map
tileMap.setScale(1)
tileMap.position = CGPoint(x: 0 - self.frame.size.width/2, y: 0 - self.frame.size.height/2)
let tileSize = tileMap.tileSize
let halfWidth = CGFloat(tileMap.numberOfColumns) / 2.0 * tileSize.width
let halfHeight = CGFloat(tileMap.numberOfRows) / 2.0 * tileSize.height
for col in 0..<tileMap.numberOfColumns {
for row in 0..<tileMap.numberOfRows {
let tileDefinition = tileMap.tileDefinition(atColumn: col, row: row)
let isEdgeTile = tileDefinition?.userData?["isWalls"] as? Bool
if (isEdgeTile ?? false) {
let x = CGFloat(col) * tileSize.width - halfWidth
let y = CGFloat(row) * tileSize.height - halfHeight
let rect = CGRect(x: 0, y: 0, width: tileSize.width, height: tileSize.height)
let tileNode = SKShapeNode(rect: rect)
tileNode.position = CGPoint(x: x, y: y)
tileNode.physicsBody = SKPhysicsBody.init(rectangleOf: tileSize, center: CGPoint(x: tileSize.width / 2.0, y: tileSize.height / 2.0))
tileNode.physicsBody?.categoryBitMask = gamePhysics.Wall
tileNode.physicsBody?.collisionBitMask = gamePhysics.Player
tileNode.physicsBody?.contactTestBitMask = gamePhysics.Player
tileNode.physicsBody?.isDynamic = false
tileMap.addChild(tileNode)
}
}
}
}
下面也是我将地图添加到场景的代码:
func createScene() {
self.physicsWorld.contactDelegate = self
for node in self.children {
if (node is SKTileMapNode){
if let theMap:SKTileMapNode = node as? SKTileMapNode {
setUpSceneWithMap(map: theMap)
}
}
}
createPlayer()
createCamera()
}
基本上,SpriteKit 订阅了一个子-父节点结构。
我用一张图来说明。
其中每个圆圈代表一个节点。当前,您正在移动 SKScene 节点(自身)。子节点的位置是相对于它附加到的父节点的。当您移动 SKScene 节点时,所有附加到它的节点都会跟着移动,因为它们是子节点。
例如,将节点定位在 (0,0),然后将节点附加到位置 (10,0) 的该节点。将父节点移动到(10,0),在(10,0)的子节点会移动到(20,0),因为它的原点是相对于它的父节点,而不是一般的场景。
要解决您的问题,您需要创建另一层节点。让我用另一张图来说明。
如果您只对地图节点应用移动,则只有子节点(附加到地图节点的节点)会移动。
所以总而言之,您的代码应该是这样的。
class GameScene: SKScene
{
let MapNode,
UINode = SKNode; //This is a fancy way to declare multiple variables of the same type
func controlButton()
{
... //Your other code here
UINode.addChild(button) //Instead of self.addChild(button)
}
func setUpSceneWithMap(map: SKTileMapNode)
{
//Your other code in here
MapNode.addChild(map)
// I don't know where you are adding your tile map to your scene
// However, it most likely is self.addChild(map) which needs to be changed to MapNode.addChild(map)
}
}
将所有场景元素附加到 MapNode,并将所有 UI 元素附加到 UINode。仅将位置更改应用于 MapNode。 UI 元素不会四处移动,除非您希望它们移动。