精灵套件中的iCarousel [英] iCarousel in Sprite Kit

查看:74
本文介绍了精灵套件中的iCarousel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

解释



我正在尝试建立一个类似于Crossy Road的字符选择菜单(如你所见





提前致谢,
Luiz。

解决方案

您可以使用NSNotifications显示您的角色选择器。您只需要观察 SKScene 发布的通知。您的 viewDidLoad 应如下所示:

 覆盖func viewDidLoad(){ 
super.viewDidLoad()

carousel.type = .CoverFlow
carousel.reloadData()

let spriteKitView = SKView()
spriteKitView.frame = self.view.bounds
self.view.insertSubview(spriteKitView,belowSubview:self.carousel)

spriteKitView.showsFPS = true
spriteKitView.showsNodeCount = true
spriteKitView.ignoresSiblingOrder = true

self.gameScene = GameScene(size:self.view.bounds.size)
self.gameScene.scaleMode = .AspectFill
self。 gameScene.imageName = self.images [0] as! String

self.carousel.hidden = true
spriteKitView.presentScene(self.gameScene)

NSNotificationCenter.defaultCenter()。addObserver(self,selector:#selector (self.showCarousel),name:gameScene.kShowNotification,object:nil)
}

你需要实现 carousel(carousel:iCarousel,didSelectItemAtIndex index:NSInteger),这样你才能知道所选内容,这样你就可以返回游戏。例如:

  func carousel(carousel:iCarousel,didSelectItemAtIndex index:NSInteger)
{
self。 gameScene.imageName = self.images [index] as!字符串
self.hideCarousel()
}

您还需要删除观察在取消分配视图控制器之前。

  deinit 
{
NSNotificationCenter.defaultCenter()。removeObserver(self )
}

您的 SKScene 然后可以发布通知:

  import SpriteKit 

class GameScene:SKScene {
var imageName =square1{
didSet {
self.hidden = false
self.childNode.texture = SKTexture(imageNamed:imageName)
}
}

让kShowNotification =showPicker

var childNode = SKSpriteNode()
覆盖func didMoveToView(查看:SKView){
/ *在这里设置场景* /

self.childNode = SKSpriteNode(imageNamed:imageName)
self.childNode.anchorPoint = CGPointZero
self.childNode.position = CGPoi ntZero
self.addChild(self.childNode)
}

覆盖func touchesBegan(触摸:设置< UITouch>,withEvent事件:UIEvent?){
self。 showCharPicker()
}

func showCharPicker()
{
self.hidden = true
NSNotificationCenter.defaultCenter()。postNotificationName(kShowNotification,object:零)
}

}

如果你想改变命中检测,您需要子类化您需要更改的视图。这种情况下你的 iCarousel 视图。



然后你可以覆盖 hitTest pointInside 。我创建了一个 iCarousel 子类并覆盖了 pointInside ,只有当该点位于其中一个轮播内时才返回true code> contentView 的子视图。

  class CarouselSubclass:iCarousel {

覆盖func pointInside(点:CGPoint,withEvent事件:UIEvent?) - > Bool {
var inside = false
for self.contentView.subviews中的视图
{
inside = CGRectContainsPoint(view.frame,point)
如果在$ b $内b {
返回
}
}
返回
}
}

您需要记住在界面构建器中更改轮播的类别并更新您的插座。


Explanation

I'm trying to build a character selection menu similar to Crossy Road's one (as you can see here). So I found this iCarousel, which would help me with all of it, but everything I read talk about implementing it to a ViewController, which isn't my case. I'm using GameScene and I didn't found anything talking about it. Is there anyway I could implement it to my game? or even another effect similar to the character selection menu I mentioned above?


Attempt (beyowulf)

You can download it here.


GameScene.swift

import SpriteKit

class GameScene: SKScene {

    var show = SKSpriteNode()
    var hide = SKSpriteNode()

    func showCharPicker(){
        NSNotificationCenter.defaultCenter().postNotificationName("showCharPicker", object: nil)
    }
    func hideCharPicker(){
        NSNotificationCenter.defaultCenter().postNotificationName("hideCharPicker", object: nil)
    }

    override func didMoveToView(view: SKView) {
        /* Setup your scene here */

        print("didMoveToView")

        show = SKSpriteNode(imageNamed: "show")
        show.anchorPoint = CGPointZero
        show.position = CGPointZero
        addChild(show)

        hide = SKSpriteNode(imageNamed: "hide")
        hide.anchorPoint = CGPointZero
        hide.position = CGPoint(x: self.frame.width / 2 - hide.frame.width / 2, y: 0)
        addChild(hide)
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

        for touch in touches{

            let location = touch.locationInNode(self)
            let node = nodeAtPoint(location)

            if node == show{
                print("show")
                showCharPicker()
            }
            else if node == hide{
                print("hide")
                hideCharPicker()
            }
        }
    }
}

GameViewController.swift

import UIKit
import SpriteKit

class GameViewController: UIViewController, iCarouselDataSource, iCarouselDelegate{

    var squaresArray : NSMutableArray = NSMutableArray()

    @IBOutlet weak var carousel: iCarousel!

    deinit{
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

    func showCarousel(){
        self.carousel.hidden = false
    }
    func hideCarousel(){
        self.carousel.hidden = true
    }

    override func viewDidLoad(){
        super.viewDidLoad()

        // Configure iCarousel
        carousel.dataSource = self
        carousel.delegate = self
        carousel.type = .CoverFlow
        carousel.reloadData()

        self.carousel.hidden = true

        // Register showCarousel and hideCarousel functions
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.showCarousel), name: "showCharPicker", object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.hideCarousel), name: "hideCharPicker", object: nil)

        // Configure view
        let skView = SKView()
        self.view.insertSubview(skView, belowSubview: self.carousel)
        skView.frame = self.view.bounds

        // Additionals
        skView.showsFPS = true
        skView.showsNodeCount = true
        skView.ignoresSiblingOrder = true

        // Configure scene
        let scene = GameScene(size:self.view.bounds.size)
        scene.scaleMode = .ResizeFill
        scene.size = self.view.bounds.size

        skView.presentScene(scene)
    }

    //iCarousel
    override func awakeFromNib(){
        super.awakeFromNib()
        squaresArray = NSMutableArray(array: ["square1","square2","square3"])
    }
    func numberOfItemsInCarousel(carousel: iCarousel) -> Int{
        return squaresArray.count
    }
    func carousel(carousel:iCarousel, didSelectItemAtIndex index:NSInteger){
        //self.hideCarousel()
    }
    func carousel(carousel: iCarousel, viewForItemAtIndex index: Int, reusingView view: UIView?) -> UIView{

        var itemView: UIImageView

        if (view == nil){
            itemView = UIImageView(frame:CGRect(x:0, y:0, width:200, height:200))
            itemView.contentMode = .Center
        }
        else{
            itemView = view as! UIImageView;
        }

        itemView.image = UIImage(named: "\(squaresArray.objectAtIndex(index))")
        return itemView
    }
    func carousel(carousel: iCarousel, valueForOption option: iCarouselOption, withDefault value: CGFloat) -> CGFloat{

        if (option == .Spacing){
            return value * 2
        }
        return value
    }
}


What's happening:


Thanks in advance,
Luiz.

解决方案

You can use NSNotifications to show your character picker. You just need to observe the notifications posted by your SKScene. Your viewDidLoad should look something like:

override func viewDidLoad(){
    super.viewDidLoad()

    carousel.type = .CoverFlow
    carousel.reloadData()

    let spriteKitView = SKView()
    spriteKitView.frame = self.view.bounds
    self.view.insertSubview(spriteKitView, belowSubview: self.carousel)

    spriteKitView.showsFPS = true
    spriteKitView.showsNodeCount = true
    spriteKitView.ignoresSiblingOrder = true

    self.gameScene = GameScene(size:self.view.bounds.size)
    self.gameScene.scaleMode = .AspectFill
    self.gameScene.imageName = self.images[0] as! String

    self.carousel.hidden = true
    spriteKitView.presentScene(self.gameScene)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.showCarousel), name: gameScene.kShowNotification, object: nil)
}

You'll want to implementing carousel(carousel:iCarousel, didSelectItemAtIndex index:NSInteger) so you know what is selected, and so you can return to game play. For example:

func carousel(carousel:iCarousel, didSelectItemAtIndex index:NSInteger)
{
    self.gameScene.imageName = self.images[index] as! String
    self.hideCarousel()
}

You also need to remove observing before your view controller is deallocated.

deinit
{
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

Your SKScene can then post a notifications:

import SpriteKit

class GameScene: SKScene {
    var imageName = "square1"{
        didSet{
            self.hidden = false
            self.childNode.texture = SKTexture(imageNamed: imageName)
        }
    }

    let kShowNotification = "showPicker"

    var childNode = SKSpriteNode()
    override func didMoveToView(view: SKView) {
        /* Setup your scene here */

        self.childNode = SKSpriteNode(imageNamed: imageName)
        self.childNode.anchorPoint = CGPointZero
        self.childNode.position = CGPointZero
        self.addChild(self.childNode)
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.showCharPicker()
    }

    func showCharPicker()
    {
        self.hidden = true
        NSNotificationCenter.defaultCenter().postNotificationName(kShowNotification, object: nil)
    }

}

If you want to change hit detection, you need to subclass the view for which you need it to change. This case your iCarousel view.

You can then either override hitTest or pointInside. I've created an iCarousel subclass and overrode pointInside to only return true when the point is inside one of the carousel's contentView's subviews.

class CarouselSubclass: iCarousel {

    override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
        var inside = false
        for view in self.contentView.subviews
        {
            inside = CGRectContainsPoint(view.frame, point)
            if inside
            {
                return inside
            }
        }
        return inside
    }
}

You need to remember to change the class of your carousel in interface builder and update your outlet as well.

这篇关于精灵套件中的iCarousel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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