In my GameScene, when I update variables using 'touchesBegan()' it works fine, but when I pass 'pressesBegan()' from the GameViewController to the GameScene, the code gets excited, but the changes get ignored.
GameViewController:
class GameViewController: UIViewController {
...
override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
let scene = GameScene(fileNamed: "GameScene")
scene?.pressesBegan(presses, withEvent: event)
}
GameScene:
class GameScene: SKScene {
var test = true
...
override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
test = false
print(test)
}
override func update(currentTime: CFTimeInterval) {
print(test)
}
}
This code will result in "false" then "true" in the console.
Every time you call pressesBegan, you are creating a new Gamescene, you need to do
override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
if let skView = self.view as? SKView
{
skView.scene?.pressesBegan(presses, withEvent: event)
}
}
Related
I have a subclassed node called LocationNode, where touch is enabled. It looks like this.
class LocationNode: SKSpriteNode, CustomNodeEvents {
func didMoveToScene() {
self.isUserInteractionEnabled = true
}
}
I haven't overriden touchesBegan in this subclass file, because I want to control all touch events like this in the actual scene file:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touchLocation = touches.first!.location(in: self)
let touchedNode = self.atPoint(touchLocation)
//if touchedNode.name != nil {
print("touched")
//}
}
When I try do this, however, it doesn't work. How can I control touch events for a subclassed node in the scene file?
EDIT:
Here's what my override function looks like in the scene.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touchLocation = touches.first!.location(in: self)
let touchedNode = self.atPoint(touchLocation)
print("TOUCHED")
}
You could implement this code below in your custom class, in this case LocationNode, to have a "return of touches" to the parent class, then you can handle the touches in both places (also to the main scene) :
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
print("touched!")
}
guard let parent = self.parent else { return }
parent.touchesBegan(touches, with: event)
}
Everything works fine,but then when I add the apple,it only stays on screen for a very short amount of time, and then it goes away/disappears. Why is this? any help would be much appreciated.
import SpriteKit
class GameScene: SKScene {
var bg=SKSpriteNode()
var apple=SKSpriteNode()
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let bg_texture=SKTexture(imageNamed: "wood-texture-pattern.jpg")
bg=SKSpriteNode(texture: bg_texture)
bg.position=CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
bg.size.height=self.frame.height
bg.size.width=self.frame.width
self.addChild(bg)
let applePic=SKTexture(imageNamed:"apple.png")
apple=SKSpriteNode(texture:applePic)
apple.position=CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame))
// apple.size.height=50
// apple.size.width=50
apple.setScale(0.25)
self.addChild(apple)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
Change the zPosition of the skspritenode
Does anybody know how to detect a forced touch/click on the remote control with tvOS?
I want to use the click in a Sprite Kit scene to open a 'game paused alert'. I have no UIKit controls which have the focus and will react on the click.
I'm already using the 'normal' touch events on the remote control to move my sprites around.
Apple suggests using UIPressesEvent's to detect presses/clicks.
override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
for item in presses {
if item.type == .Select {
self.view.backgroundColor = UIColor.greenColor()
}
}
}
override func pressesEnded(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
for item in presses {
if item.type == .Select {
self.view.backgroundColor = UIColor.whiteColor()
}
}
}
override func pressesChanged(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
// ignored
}
override func pressesCancelled(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
for item in presses {
if item.type == .Select {
self.view.backgroundColor = UIColor.whiteColor()
}
}
}
I am working on this project in Xcode, where I am making animations. I have perfectly working program where little character walks around the screen. If I press on screen, that is direction the character is going. What I want to do here is to add a background image and make it follow where character is going. Basically, I want character to be able to walk around big map while he does not go out of the image. Something like scrollView, but only in gamescene.
P.S. All the code below is working, I just want to add the background image that moves along.
Here is some code for my main gamescene
override func didMoveToView(view: SKView) {
/* Setup your scene here */
// the hero is initialized with a texture
hero = Player(named: "hero_walk_down_0")
hero.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
self.addChild(hero)
if Settings.sharedInstance.virtualPad {
controller = ControllerNode(position: CGPoint(x:0, y: 0))
self.addChild(controller)
}
backgroundColor = SKColor.blueColor()
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if Settings.sharedInstance.virtualPad == false {
hero.destination = location
}
}
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
let previousLocation = touch.previousLocationInNode(self)
if Settings.sharedInstance.virtualPad == false {
hero.destination = location
}
}
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
touchesEndedOrCancelled(touches, withEvent: event)
}
override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
touchesEndedOrCancelled(touches, withEvent: event)
}
func touchesEndedOrCancelled(touches: NSSet, withEvent event: UIEvent) {
// when a touch is ended, remove it from the list
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
let previousLocation = touch.previousLocationInNode(self)
if Settings.sharedInstance.virtualPad == false {
hero.destination = nil
}
}
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
if Settings.sharedInstance.virtualPad {
hero.walk(self.controller!.pressedDirections())
}
else {
if hero.destination != nil {
hero.walkTowards(hero.destination!)
}
}
}
You create two SKNodes - one for the character and one for the background and add them to each group separately.
Whenever you move the SKNode of the character, you replicate the same action on the background node.
I can not get the touchesBegan function to fire. It isn't being called when a user touched the node.
import SpriteKit
class SimpleButton: SKSpriteNode {
//called when the user taps the button
override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
println("touches began")
}
//called when the user finishes touching the button
override func touchesEnded(touches: NSSet!, withEvent event: UIEvent!) {
println("touches ended")
}
override func touchesMoved(touches: NSSet!, withEvent event: UIEvent!) {
println("touches moved")
}
}
The answer is, You need to enable touches using the userInteractionEnabled parameter.
let imageTexture = SKTexture(imageNamed: "a_button")
let sprite: SimpleButton = SimpleButton(texture: imageTexture)
sprite.userInteractionEnabled = true // <--- This is required, it defaults to false.
sprite.position = CGPoint(x:CGRectGetMidX(self.frame) - 200, y:CGRectGetMidY(self.frame));
sprite.color = UIColor.blackColor()
sprite.colorBlendFactor = 1.0
self.addChild(sprite)