使 SKLabelNode 的触摸区域对于小字符更大 [英] Make touch-area for SKLabelNode bigger for small characters

查看:22
本文介绍了使 SKLabelNode 的触摸区域对于小字符更大的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的游戏中添加了一个老式的高分输入屏幕,用户可以在其中点击每个字母来输入他们的名字.

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

每个字母、符号或短语('DEL'、'SP' 等)都是一个 SKLabelNode,很难点击,"和."字符和一些符号.通过通常的 touchesBegan

Each letter, symbol or phrase ('DEL', 'SP' etc) is a single SKLabelNode and it's very difficult to tap on the ',' and '.' characters and some of the symbols though. Each tap is detected via the usual touchesBegan

为了使拘留更容易,我计划在每个字母后面放置一个更大的节点并更新 touchesBegan 以检测标签本身或其他标签上的触摸,在这种情况下只需使用子节点触摸(将是字母或短语).

To make detention easier I plan on placing a larger node behind each letter and update touchesBegan to either detect a touch on the label itself or on this other label, in which case just use the child node for the touch (which will be the letter or phrase).

在我这样做之前,我想知道是否有一种简单的方法来实现我想要的,可以通过检测离触摸最近的 SKLabelNode 等来实现.

Before I do this I was wondering if there is an easy way to achieve what I want, possible by detecting the nearest SKLabelNode to a touch etc.

推荐答案

基于@KnightOfDragon 所说的,我将为每个键创建一个 SKSpriteNode 的子类.这样可以让你的代码保持客观和漂亮!

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!

这里还有很多可以做的事情,但我匆匆忙忙地做了这件事.它没有所有的字母,也不知道如何处理 del、space、return,但我认为您的代码已经知道如何处理这些.

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.

Key 类使用协议来发送按下哪个键,因此您不必担心捕获场景中的每个关键区域

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

这篇关于使 SKLabelNode 的触摸区域对于小字符更大的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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