【问题标题】:Make touch-area for SKLabelNode bigger for small characters使 SKLabelNode 的触摸区域对于小字符更大
【发布时间】:2017-02-03 14:45:03
【问题描述】:

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

每个字母、符号或短语(“DEL”、“SP”等)都是一个 SKLabelNode,很难点击“,”和“。”字符和一些符号。通过通常的touchesBegan 检测每个点击

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

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

【问题讨论】:

  • 只是想知道如果你只是让这两个节点的“框架”与其他标签一样,你的触摸应该可以工作。这里的框架尺寸更小吗?
  • @Tushar - 不确定。我会查明真相的。我认为不会(因为小标签很难触摸)而且我认为如果我只是增加尺寸,字母会变大。
  • 除非你设置更大的字体大小,否则它们不会变大 :) 所以尝试为它们设置一个可点击的框架。
  • @Tushar SKLabelNodes 似乎没有 frame 或 size 属性,所以我将不得不尝试更大的父节点。
  • Steve,将每个标签放置为固定大小的 SKSpriteNode 的子节点,然后在精灵而不是标签上启用触摸

标签: swift sprite-kit touch sklabelnode


【解决方案1】:

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

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

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

所以我输入了其余的键,并为间距添加了一些空白填充选项。我没有和你一样的字体,但看起来很酷

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

【讨论】:

  • 谢谢罗恩 - 我会检查一下并回复你。
  • 没问题,您可能会自己弄清楚,但键不必有边框。他们基本上可以看起来像你的布局,只需从键初始化中删除形状节点,并将 super.init 颜色更改为 .clear
  • 我完成了按键的重置以及按键的一些间距选项,并移除了按键背景颜色
  • 抱歉 - 刚开始看这个。不确定我会想出他的解决方案——还没有深入研究协议。我需要一段时间才能理解这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
  • 2011-04-24
相关资源
最近更新 更多