我想这样做,当玩家按下标签时,他必须再次按下屏幕上的一个点来选择建造房屋的地方。到目前为止,这就是我所拥有的:当玩家按下标签" build"时,布尔值(" wantsToBuild")设置为true,但是现在显然房子就建在标签的顶部。我不知道如何检查那个地方是否已经忙碌,或者玩家是否可以在那里建造。我想过有一些占位符,但我不知道如何正确设置它们。你能帮我解决这个问题吗?谢谢。 编辑:我已经根据答案中的建议更改了问题中的代码,但现在我遇到了一些问题:操纵杆(之前我没有提到)移动即使我没有碰到操纵杆本身。即使我已经使用print语句检查了wantToBuild的值,并且它似乎设置为false,每当我按下屏幕时,一个房子总是被建造。你能帮我进一步吗?
类GameScene:SKScene {
var ship = LCDShip()
var shipSpeed : CGFloat = 0.08
var base = SKSpriteNode(imageNamed: "base")
var joystick = SKSpriteNode(imageNamed: "joystick")
var joystickActive = false
var length:CGFloat! = nil
var xDist:CGFloat! = nil
var yDist:CGFloat! = nil
var deltaVector:CGVector! = nil
let build = SKLabelNode()
var wantsToBuild = false
override func didMoveToView(view: SKView) {
build.name = "build"
build.fontName = "Chalkduster"
build.fontSize = 25
build.text = "Build a house"
build.zPosition = 2
build.position = CGPoint(x: self.frame.width/2, y: self.frame.height/2)
addChild(build)
backgroundColor = SKColor.blackColor()
ship.position = CGPoint(x: self.frame.width/2, y: self.frame.height/2)
addChild(ship)
base.position = CGPoint(x: 150, y: 200)
base.setScale(2)
base.alpha = 0.3
addChild(base)
joystick.position = base.position
joystick.setScale(2)
joystick.alpha = 0.4
joystick.name = "base"
addChild(joystick)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let house = SKSpriteNode(imageNamed: "house")
let location = touch.locationInNode(self)
let node = nodeAtPoint(location)
let label = self.childNodeWithName("build")!
if node.name == "build"{
print("where should i build the hosue?")
wantsToBuild = true
} else if wantsToBuild == true && node.name != "house" && location.x <= label.position.x - 15 || location.x >= label.position.x + 15 || location.y >= label.position.y + 15 || location.y <= label.position.y - 15 {
house.position = location
house.name = "house"
addChild(house)
wantsToBuild = false
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
deltaVector = CGVector(dx: location.x - base.position.x, dy: location.y - base.position.y)
let angle = atan2(deltaVector.dy, deltaVector.dx)
length = base.frame.size.height/2
xDist = sin(angle - 1.57079633) * length
yDist = cos(angle - 1.57079633) * length
if(CGRectContainsPoint(base.frame, location)){
joystick.position = location
} else {
joystick.position = CGPointMake(base.position.x - xDist, base.position.y + yDist)
}
ship.zRotation = angle - 1.57079633
}
}
override func update(currentTime: NSTimeInterval) {
if deltaVector != nil {
ship.position.x += deltaVector.dx * shipSpeed
ship.position.y += deltaVector.dy * shipSpeed
}
}
}
答案 0 :(得分:0)
我认为你的情况不好,我没有什么可以尝试但是我会做这样的事情:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
let node = nodeAtPoint(location)
if node.name == "build"{
print("where should i build the house?")
wantsToBuild = true
}
else if wantsToBuild == true && node.name != "house" {
let sprite = SKSpriteNode(imageNamed: "house")
sprite.position = location
sprite.name = "house"
addChild(sprite)
wantsToBuild = false
}
}
}
答案 1 :(得分:0)
Bogy的方法可行,但您可能希望它为&& node.name!=
"build"
,除非您要构建多个房屋,在这种情况下您可能需要node.name != "build" && node.name != "house"
总之... 这种方法是有效的,除非你的房子精灵足够大,然后当你触摸标签旁边,而不是在实际标签上,房子可能会重叠标签,并且基本上正好在标签的顶部。同样,IDK的精灵大小和一切。要处理这种情况,您可以在标签周围创建一个不允许放置的范围:
let label = self.childNodeWithName("build")!
if wantsToBuild == true && (location.x <= label.position.x - 15 || location.x >= label.position.x + 15 || location.y <= label.position.y - 15 || location.y >= label.position.y + 15) {
let sprite = SKSpriteNode(imageNamed: "house")
sprite.position = location
addChild(sprite)
wantsToBuild = false
}
这样可以在标签周围创建一个更大的盒子,并且不允许你将房子放在那个盒子里,所以如果你把盒子放得足够大(你可能不得不修补+ 15)并且 - 15&s;),即使你尽可能地贴在标签上,你也不能把它放得足够接近重叠。
如果您的标签是精灵而不是SKLabelNode,您可以按照Bogy的说法进行操作,只需在实际的精灵图像中添加一个不可见空间的边框,因此最接近精灵的最近点就是&#39;精灵中的t将足够远,不会重叠。
答案 2 :(得分:0)
所以我实际上设法通过清理代码并更好地使用您的建议来解决问题。不确定它是很棒的代码,但它确实有用。我添加了一个成本和几个if语句。这就是我现在所拥有的,以防有人发现它有用:)
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
let node = nodeAtPoint(location)
if CGRectContainsPoint(base.frame, location){
joystickActive = true
}else {
joystickActive = false
if node.name == "build" {
wantsToBuild = true
} else if node.name != "house" {
checkPlace(location)
wantsToBuild = false
}
}
}
}
func checkPlace(location : CGPoint) {
let label = self.childNodeWithName("build")!
let deltaX = location.x - label.position.x
let deltaY = location.y - label.position.y
let houseRadius : CGFloat = 60
let distance = sqrt(deltaX * deltaX + deltaY * deltaY)
if distance <= houseRadius{
print("YOU CANNOT BUILD HERE")
} else if distance > houseRadius && wantsToBuild == true{
if money > 0 {
buildConstruction(10, location: location)
}
}
}
func buildConstruction(cost: Int, location: CGPoint) {
let house = SKSpriteNode(imageNamed: "house")
house.position = location
house.name = "house"
addChild(house)
money -= cost
print(money)
}
再次感谢@Arkidillo和@Bogy让我走上正轨:)