Make touch-area for SKLabelNode bigger for small characters

前端 未结 1 1055
青春惊慌失措
青春惊慌失措 2021-01-15 13:08

I\'m adding an old-school high-score entry screen to my game, in which the users tap each letter to enter their name.

Each letter, symbol or phrase (\'DEL\

相关标签:
1条回答
  • 2021-01-15 13:53

    Just building on what @KnightOfDragon said, I would just create a subclass of SKSpriteNode for each key. That way it keeps your code objectified and pretty!

    There is so much more that can be done here, but I whipped this up in a hurry. It doesn't have all the letters and it doesn't know how to handle del, space, return, but I figured your code already knew what to do with those.

    The Key class uses a protocol to send down which key was pushed, so you don't have to worry about capturing each key area in the scene

    So I entered the rest of the keys and added some blank filler options for spacing. I don't have the same font as you but it looks pretty cool

    import SpriteKit
    
    protocol KeyDelegate: NSObjectProtocol {
        func keyWasPressed(sender: Key)
    }
    
    enum KeyType: Int {
    
        case a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, comma, period, del, space, ret, dash, lb, rb, pound, exclaim, quest, filler, halfFiller
    
        var height: CGFloat {
            return 60
        }
    
        var width: CGFloat {
    
            switch self {  
                case .del: return 150
                case .space: return 180
                case .ret: return 150
                case .halfFiller: return 30
                default: return 60
            }
        }
    
        var keyValue: String {
    
            switch self {
    
                case .filler: return ""
                default: return String(describing: self)
            }
        }
    
        var keyText: String {
    
            switch self {
    
                case .del: return "DEL"
                case .space: return "SP"
                case .ret: return "ENT"
                case .lb: return "("
                case .rb: return ")"
                case .exclaim: return "!"
                case .comma: return ","
                case .period: return "."
                case .dash: return "-"
                case .pound: return "#"
                case .quest: return "?"
                case .filler, .halfFiller: return ""
    
                default: return String(describing: self).uppercased()
            }
        }
    
        var keyTextColor: SKColor {
    
            switch self {
    
                case .del, .space, .ret: return .red
                case .lb, .rb, .exclaim, .dash, .pound, .quest: return .green
                default: return .blue
            }
        }
    
        var filler: Bool {
    
            switch self {
                case .filler, .halfFiller: return true
                default: return false
            }
        }
    }
    
    class Key: SKSpriteNode {
    
        var keyType: KeyType = .a
        private var keyValue = ""
        var keyText: String = ""
        weak var keyDelegate: KeyDelegate!
    
        init(keyType: KeyType) {
    
            //let backgroundColor: SKColor = keyType.filler ? .clear : .red
    
            super.init(texture: nil, color: .clear, size: CGSize.zero)
    
            self.isUserInteractionEnabled = true
            self.size = CGSize(width: keyType.width, height: keyType.height)
            self.anchorPoint = CGPoint(x: 0, y: 0)
            self.keyType = keyType
            self.keyValue = keyType.keyValue
            self.keyText = keyType.keyText
    
            guard !keyType.filler else { return }
    
    //        let square = SKShapeNode(rectOf: size)
    //        square.strokeColor = .white
    //        square.position = CGPoint(x: self.size.width / 2, y: self.size.height / 2)
    //        square.zPosition = 1
    //        addChild(square)
    
            let titleLabel = SKLabelNode(fontNamed: "04b_19")
            titleLabel.fontColor = keyType.keyTextColor
            titleLabel.fontSize = 56
            titleLabel.horizontalAlignmentMode = .center
            titleLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center
            titleLabel.position = CGPoint(x: self.size.width / 2, y: self.size.height / 2)
            titleLabel.zPosition = 10
            titleLabel.text = self.keyText
            self.addChild(titleLabel)
    
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        func getKeyValue() -> String {
    
            return self.keyValue
        }
    
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    
            guard !keyType.filler else { return }
    
            self.keyDelegate.keyWasPressed(sender: self)
        }
    }
    
    
    
    class GameScene: SKScene, KeyDelegate {
    
        private var titleLabel = SKLabelNode()
    
        override func didMove(to view: SKView) {
    
            titleLabel.fontColor = .white
            titleLabel.fontSize = 68
            titleLabel.horizontalAlignmentMode = .left
            titleLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.baseline
                    titleLabel.position = CGPoint(x: 220, y: 800)
            titleLabel.zPosition = 10
            titleLabel.text = ""
            self.addChild(titleLabel)
    
            let keys: [[KeyType]] = [[.q, .w, .e, .r, .t, .y, .u, .i, .o, .p],
                                 [.halfFiller, .a, .s, .d, .f, .g, .h, .j, .k, .l],
                                 [.halfFiller, .filler, .z, .x, .c, .v, .b, .n, .m, .comma, .period],
                                 [.del, .filler, .halfFiller, .space, .filler, .halfFiller, .ret],
                                 [.filler, .filler, .dash, .lb, .rb, .pound, .exclaim, .quest]]
            let padding: CGFloat = 8
            let startPoint = CGPoint(x: 30, y: 700)
            var xOffset: CGFloat = 0
            var yOffset: CGFloat = 0
            var keyHeight: CGFloat = 0
    
            for row in keys {
    
                for keyType in row {
    
                    print("keyType \(keyType)")
                    let key = Key(keyType: keyType)
                    key.position = CGPoint(x: startPoint.x + xOffset, y: startPoint.y + yOffset)
                    key.keyDelegate = self
                    addChild(key)
    
                    xOffset += key.keyType.width + padding
                    keyHeight = key.keyType.height
                }
    
                xOffset = 0
                yOffset -= (keyHeight + padding)
            }
        }
    
        //MARK:- KeyDelegate Func 
    
        func keyWasPressed(sender: Key) {
    
            let text = titleLabel.text!
            titleLabel.text = text + sender.getKeyValue()
        }    
    }
    
    0 讨论(0)
提交回复
热议问题