实现自己的SKTileGroupRule进行箭头可视化,以显示SKTileMapNode中的角色移动

时间:2019-03-26 17:01:48

标签: ios swift sprite-kit sktilemapnode

目前,我正在开发一款新游戏,其中有一个名为background的SKTileMapNode,作为供角色在各个瓷砖之间行走的游乐场。除此之外,我还有一个名为objects的SKTileMapNode,它显示在background(z方向)的顶部,在这里我对于树或岩石等字符的移动有不同的障碍。 “我的场景”包含一个光标和一个游戏控制器,并带有上,下,左,右,A和B按钮。
我已经实现了逻辑,可以将光标移动到字符上方并选择它。选择之后,如果没有障碍物,我可以选择平铺以移动所选角色。至此一切都按需进行。
我现在想要的是实现一种方法,使玩家在选择角色后能够看到箭头,从而显示角色必须走到的瓷砖,然后才能将光标移至当前光标所在的瓷砖,然后再选择该瓷砖作为目标。
我的想法是为object创建我自己的SKTileGroupRule或在两者之上创建一个新的SKTileMapNode,它们会自动选择正确的SKTileDefinition来显示正确的箭头纹理。如果玩家绕过弯道将光标移动到所需的图块并检测到周围有障碍物,它还应该自动更正箭头。
所以我的问题是:如何使用给定的规则实现我自己的SKTileGroup。即使您只是想创建一个SKTileGroupRule仅用于绕障碍TileSizes进行绘制或如前所述在绕行时自动校正,也请随时回答。

具有相同逻辑的另一款游戏的图片:

A picture of another game with the same logic

import SpriteKit

class Spielfeld: SKScene {

var x: Int = 0     // columns
var y: Int = 0     // rows
var background: SKTileMapNode = SKTileMapNode()
var 

objects: SKTileMapNode = SKTileMapNode()

enum State {
    case initial
    case selected
    case menu
}

var state: State = .initial // Initial state

var selected: Charakter!

var menu: Menu = Menu(0)

var up: SKSpriteNode = SKSpriteNode()
var down: SKSpriteNode = SKSpriteNode()
var left: SKSpriteNode = SKSpriteNode()
var right: SKSpriteNode = SKSpriteNode()
var buttonA: SKSpriteNode = SKSpriteNode()
var buttonB: SKSpriteNode = SKSpriteNode()

let cursor: SKSpriteNode = SKSpriteNode(imageNamed: "Cursor1Blue")
var cursor_x: Int = 0
var cursor_y: Int = 0

let charInfo: SKNode = SKNode()
let charInfoBG: SKSpriteNode = SKSpriteNode(imageNamed: "CharInfo")
let charInfoLabel: SKLabelNode = SKLabelNode()

var reach: [SKSpriteNode] = []

let ike: Ike = Ike()
let boyd: Boyd = Boyd()

override func sceneDidLoad() {
    background = self.childNode(withName: "Background") as! SKTileMapNode
    objects = self.childNode(withName: "Objects") as! SKTileMapNode

    calibrateMap()

    addController()
    addCursor()

    ike.position = objects.centerOfTile(atColumn: 0, row: 1)
    ike.x = 0
    ike.y = 1
    objects.addChild(ike)

    boyd.position = objects.centerOfTile(atColumn: 6, row: 3)
    boyd.x = 6
    boyd.y = 3
    boyd.team = 2
    objects.addChild(boyd)

    initCharInfo()
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let touch:UITouch = touches.first! as UITouch
    let positionInScene = touch.location(in: self)
    let touchedNode = self.atPoint(positionInScene)
    print(touchedNode.name!)
    if(touchedNode.name == "Objects") {
        let map = touchedNode as! (SKTileMapNode)
        let positionInMap = touch.location(in: map)
    } else if(isCursor(touchedNode.name!)) {
        switch state {
        case .initial, .selected:
            moveCursor(button: touchedNode.name!)
            if let char = atCursor() {
                print(char.name!)
                changeCursorColor(team: char.team)
                charInfoLabel.text = char.getInfo()
                charInfo.isHidden = false
            } else {
                changeCursorColor(team: 0)
                charInfo.isHidden = true
            }
        case .menu:
            switch touchedNode.name! {
            case "Up":
                menu.moveUp()
            case "Down":
                menu.moveDown()
            default:
                break
            }
        }
    } else if(touchedNode.name == "ButtonA") {
        print("Button A pressed")
        buttonAPressed()
    } else if(touchedNode.name == "ButtonB") {
        print("Button B pressed")
        buttonBPressed()
    }
}

func calibrateMap() {
    background.position.x += (background.mapSize.width/2 - 32)
    background.position.y += (background.mapSize.width/2 - 5 * 32)
    objects.position.x += (background.mapSize.width/2 - 32)
    objects.position.y += (background.mapSize.width/2 - 5 * 32)
}

func addController() {
    up = self.childNode(withName: "Up") as! SKSpriteNode
    down = self.childNode(withName: "Down") as! SKSpriteNode
    left = self.childNode(withName: "Left") as! SKSpriteNode
    right = self.childNode(withName: "Right") as! SKSpriteNode
    buttonA = self.childNode(withName: "ButtonA") as! SKSpriteNode
    buttonB = self.childNode(withName: "ButtonB") as! SKSpriteNode
}

func addCursor() {
    cursor_x = 0
    cursor_y = 1
    cursor.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
    cursor.zPosition = 2
    cursor.name = "Cursor"
    self.addChild(cursor)

    var cursorTextures: [SKTexture] = Array(repeating: SKTexture(), count: 3)
    cursorTextures[0] = SKTexture(imageNamed: "Cursor1Blue")
    cursorTextures[1] = SKTexture(imageNamed: "Cursor2Blue")
    cursorTextures[2] = SKTexture(imageNamed: "Cursor3Blue")

    var cursorAnimation = SKAction.animate(with: cursorTextures, timePerFrame: 0.5)
    cursorAnimation = SKAction.repeatForever(cursorAnimation)

    cursor.run(cursorAnimation, withKey: "CursorAnimation")
}

func isCursor(_ name: String) -> Bool {
    if(name == "Up" || name == "Down" || name == "Left" || name == "Right") {
        return true
    } else {
        return false
    }
}

func moveCursor(button: String) {
    if(button == "Up" && cursor_y != y-1) {
        cursor_y += 1
        background.position.y -= 64
        objects.position.y -= 64
    } else if(button == "Down" && cursor_y != 0) {
        cursor_y -= 1
        background.position.y += 64
        objects.position.y += 64
    } else if(button == "Left" && cursor_x != 0) {
        cursor_x -= 1
        background.position.x += 64
        objects.position.x += 64
    } else if(button == "Right" && cursor_x != x-1) {
        cursor_x += 1
        background.position.x -= 64
        objects.position.x -= 64
    }
}

func atCursor() -> Charakter? {
    let char = self.atPoint(cursor.position) as? Charakter
    return char
}

func changeCursorColor(team: Int) {
    cursor.removeAction(forKey: "CursorAnimation")

    var cursorTextures: [SKTexture] = Array(repeating: SKTexture(), count: 3)

    switch team {
    case 0:
        cursorTextures[0] = SKTexture(imageNamed: "Cursor1White")
        cursorTextures[1] = SKTexture(imageNamed: "Cursor2White")
        cursorTextures[2] = SKTexture(imageNamed: "Cursor3White")
    case 1:
        cursorTextures[0] = SKTexture(imageNamed: "Cursor1Blue")
        cursorTextures[1] = SKTexture(imageNamed: "Cursor2Blue")
        cursorTextures[2] = SKTexture(imageNamed: "Cursor3Blue")
    case 2:
        cursorTextures[0] = SKTexture(imageNamed: "Cursor1Red")
        cursorTextures[1] = SKTexture(imageNamed: "Cursor2Red")
        cursorTextures[2] = SKTexture(imageNamed: "Cursor3Red")
    case 3:
        cursorTextures[0] = SKTexture(imageNamed: "Cursor1Green")
        cursorTextures[1] = SKTexture(imageNamed: "Cursor2Green")
        cursorTextures[2] = SKTexture(imageNamed: "Cursor3Green")
    case 4:
        cursorTextures[0] = SKTexture(imageNamed: "Cursor1Yellow")
        cursorTextures[1] = SKTexture(imageNamed: "Cursor2Yellow")
        cursorTextures[2] = SKTexture(imageNamed: "Cursor3Yellow")
    default:
        print("Team doesnt exist!")
    }

    var cursorAnimation = SKAction.animate(with: cursorTextures, timePerFrame: 0.5)
    cursorAnimation = SKAction.repeatForever(cursorAnimation)

    cursor.run(cursorAnimation, withKey: "CursorAnimation")
}

func buttonAPressed() {
    switch state {
    case .initial:
        if let char = atCursor() {
            selected = char
            state = .selected
            showReach(char)
        }
    case .selected:
        if selected.inReach(x: cursor_x, y: cursor_y) {
            if let _ = atCursor() {

            } else {
                let isTree = objects.tileDefinition(atColumn: cursor_x, row: cursor_y)?.userData?["isTree"] as? Bool
                if(isTree == true) {
                    print("tree!")
                } else {
                    state = .menu
                    menu = Menu(3)
                    menu.position = CGPoint(x: self.size.width/2 + 128, y: self.size.height/2)
                    self.addChild(menu)
                }
            }
        }

    case .menu:
        switch menu.getSelectedOption() {
        case.warten:
            selected.move(to: background.centerOfTile(atColumn: cursor_x, row: cursor_y))
            selected.x = cursor_x
            selected.y = cursor_y
            state = .initial
            background.removeChildren(in: reach)
            reach = []
            self.removeChildren(in: [menu])
        default: break
        }
    }
}

func buttonBPressed() {
    switch state {
    case .selected:
        state = .initial
        background.removeChildren(in: reach)
        reach = []
    case .menu:
        state = .selected
        self.removeChildren(in: [menu])
    default:
        break
    }
}

func initCharInfo() {
    charInfoBG.name = "CharInfoBG"
    charInfoBG.anchorPoint = CGPoint(x: 0, y: 1)
    charInfoBG.zPosition = 3
    charInfo.addChild(charInfoBG)

    charInfoLabel.name = "CharInfoLabel"
    charInfoLabel.text = ike.getInfo()
    charInfoLabel.horizontalAlignmentMode = .left
    charInfoLabel.fontName = "Papyrus"
    charInfoLabel.fontColor = .black
    charInfoLabel.fontSize = 22
    charInfoLabel.position = CGPoint(x: 23, y: -33)
    charInfoLabel.zPosition = 4
    charInfo.addChild(charInfoLabel)

    charInfo.name = "CharInfo"
    charInfo.position = CGPoint(x: 0, y: 375)
    self.addChild(charInfo)
}

func showReach(_ char: Charakter) {
    background.removeChildren(in: reach)
    reach = []
    let node: SKSpriteNode = SKSpriteNode(color: .blue, size: CGSize(width: 64, height: 64))
    node.zPosition = 2
    node.alpha = 0.25
    reach.append(node.copy() as! SKSpriteNode)
    reach.last!.position = background.centerOfTile(atColumn: char.x, row: char.y)
    reach.last?.name = "Reichweite"
    background.addChild(reach.last!)
    for i in 1...char.bew {
        if(char.x+i <= x-1) {
            let isTree = objects.tileDefinition(atColumn: char.x+i, row: char.y)?.userData?["isTree"] as? Bool
            if (isTree == false || isTree == nil) {
                reach.append(node.copy() as! SKSpriteNode)
                reach.last!.position = background.centerOfTile(atColumn: char.x+i, row: char.y)
                reach.last?.name = "Reichweite"
                background.addChild(reach.last!)
            }
        }
        if(char.x-i >= 0) {
            let isTree = objects.tileDefinition(atColumn: char.x-i, row: char.y)?.userData?["isTree"] as? Bool
            if (isTree == false || isTree == nil) {
                reach.append(node.copy() as! SKSpriteNode)
                reach.last!.position = background.centerOfTile(atColumn: char.x-i, row: char.y)
                background.addChild(reach.last!)
                reach.last?.name = "Reichweite"
            }
        }
        if(char.y+i <= y-1) {
            let isTree = objects.tileDefinition(atColumn: char.x, row: char.y+i)?.userData?["isTree"] as? Bool
            if (isTree == false || isTree == nil) {
                reach.append(node.copy() as! SKSpriteNode)
                reach.last!.position = background.centerOfTile(atColumn: char.x, row: char.y+i)
                background.addChild(reach.last!)
                reach.last?.name = "Reichweite"
            }
        }
        if(char.y-i >= 0) {
            let isTree = objects.tileDefinition(atColumn: char.x, row: char.y-i)?.userData?["isTree"] as? Bool
            if (isTree == false || isTree == nil) {
                reach.append(node.copy() as! SKSpriteNode)
                reach.last!.position = background.centerOfTile(atColumn: char.x, row: char.y-i)
                background.addChild(reach.last!)
                reach.last?.name = "Reichweite"
            }
        }
        for j in 0...char.bew-i {
            if(j == 0) {
                continue
            }
            if(char.x+i <= x-1) {
                if(char.y+j <= y-1) {
                    let isTree = objects.tileDefinition(atColumn: char.x+i, row: char.y+j)?.userData?["isTree"] as? Bool
                    if (isTree == false || isTree == nil) {
                        reach.append(node.copy() as! SKSpriteNode)
                        reach.last!.position = background.centerOfTile(atColumn: char.x+i, row: char.y+j)
                        background.addChild(reach.last!)
                        reach.last?.name = "Reichweite"
                    }
                }
                if(char.y-j >= 0) {
                    let isTree = objects.tileDefinition(atColumn: char.x+i, row: char.y-j)?.userData?["isTree"] as? Bool
                    if (isTree == false || isTree == nil) {
                        reach.append(node.copy() as! SKSpriteNode)
                        reach.last!.position = background.centerOfTile(atColumn: char.x+i, row: char.y-j)
                        background.addChild(reach.last!)
                        reach.last?.name = "Reichweite"
                    }
                }
            }
            if(char.x-i >= 0) {
                if(char.y-j >= 0) {
                    let isTree = objects.tileDefinition(atColumn: char.x-i, row: char.y-j)?.userData?["isTree"] as? Bool
                    if (isTree == false || isTree == nil) {
                        reach.append(node.copy() as! SKSpriteNode)
                        reach.last!.position = background.centerOfTile(atColumn: char.x-i, row: char.y-j)
                        background.addChild(reach.last!)
                        reach.last?.name = "Reichweite"
                    }
                }
                if(char.y+j <= y-1) {
                    let isTree = objects.tileDefinition(atColumn: char.x-i, row: char.y+j)?.userData?["isTree"] as? Bool
                    if (isTree == false || isTree == nil) {
                        reach.append(node.copy() as! SKSpriteNode)
                        reach.last!.position = background.centerOfTile(atColumn: char.x-i, row: char.y+j)
                        background.addChild(reach.last!)
                        reach.last?.name = "Reichweite"
                    }
                }
            }
        }
    }
}

}

0 个答案:

没有答案