Converting Position of SKEmitterNode - ios

I am trying to convert the SKEmitterNode position to the view, but I don't know how. I've tried using the code to convert SKSpriteNode from Apple, but it doesn't work. Here is my original code, which doesn't work:
override func touchesMoved(touches: Set<UITouch>, withEvent: UIEvent?) {
let traces: [SKEmitterNode]? = self.trace!.children as? [SKEmitterNode]
if (traces != nil && traces?.isEmpty != nil) {
for trace in traces! {
trace.particlePosition = (touches.first?.locationInView(trace))!
}

Related

How stop SKAction background music

I'm trying to make a game and in the main menu, there is a label to start music, and another to stop music.
let backgroundMusic = SKAction.playSoundFileNamed("background.mp3", waitForCompletion: false)
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location(in: self)
let touchedNode = atPoint(location)
if touchedNode.name == self.BEGIN_MUSIC {
// start music
self.run(backgroundMusic)
}
if touchedNode.name == self.STOP_MUSIC {
// stop music
SKAction.stop()
}
}
}
the music starts fine and works on all scenes which is what i wanted. But when I press the stop music, the music keeps playing. How do I stop the music.
I've tried SKAction.pause(), i've tried using withKey: "music" and then self.removeAction(forKey: "music").
I also tried making backgroundMusic: SKAudioNode and this worked but once i stopped the music i couldn't turn it back on, also it doesn't work on any other scene just the main menu.
How do I stop the sound?
I've had the same issue a while ago: This is how I got it working. This is specific for background music.
var backgroundMusic: AVAudioPlayer!
func playMusic() {
if let musicURL = Bundle.main.url(forResource: "musicSource", withExtension: "wav") {
if let audioPlayer = try? AVAudioPlayer(contentsOf: musicURL) {
backgroundMusic = audioPlayer
backgroundMusic.numberOfLoops = -1
backgroundMusic.play()
backgroundMusic.volume = 0.2
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
if let touch = touches.first {
let pos = touch.location(in: self)
let node = self.atPoint(pos)
let musicOff = UserDefaults.standard.bool(forKey: "musicOff")
if node == musicButton && musicOff == false {
backgroundMusic.stop()
UserDefaults.standard.set(true, forKey: "musicOff")
}
if node == musicButton && musicOff == true {
backgroundMusic.play()
backgroundMusic.volume = 0.3
UserDefaults.standard.set(false, forKey: "musicOff")
}
}
}

pattern.firstMatch is get Error : Expression type '#lvalue String?' is ambiguous without more context

I'm the first iPhone developer. What I want to do is distinguish special characters in text fields. So I tried to use a regular expression. But it shows me the error.
#IBOutlet weak var walletNameField: UITextField!
#IBAction func nextButtonFuc(_ sender: UIButton) {
let pattern = try! NSRegularExpression(pattern: "^[a-zA-Z0-9가-힣ㄱ-하-ㅣ\\s]$", options: .caseInsensitive)
if walletNameField.text!.isEmpty {
callAlert("test")
} else if walletPasswordField.text!.isEmpty {
callAlert("test")
} else if confirmField.text!.isEmpty {
callAlert("test")
} else if walletPasswordField.text != confirmField.text {
callAlert("test")
} else if walletNameField.text!.count > 10 {
callAlert("test")
} else if walletPasswordField.text!.count < 8 ||
walletPasswordField.text!.count >= 20 {
callAlert("test")
} else if pattern.firstMatch(in: "\(walletNameField.text!)", options: NSRegularExpression.MatchingOptions.reportCompletion, range: NSMakeRange(0, walletNameField.text!.count)) { //get Error Expression type '#lvalue String?' is ambiguous without more context
callAlert("test")
}
}
Error is
Expression type '#lvalue String?' is ambiguous without more context
What did I do wrong? I find it difficult to solve this problem.
And I try to hide my keyboard when I touch anywhere. However, the function itself is an error. Why is there an error?
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
// Error is Declaration 'touchesBegan(touches:withEvent:)' has different argument labels from any potential overrides
Thanks in advance
You need to compare firstMatch with a value as if expects A BOOL
} else if pattern.firstMatch(in: "\(walletNameField.text!)", options: NSRegularExpression.MatchingOptions.reportCompletion,range: NSRange(location:0,length:walletNameField.text!.count)) != nil {
}
Or use if let
} else if let first = pattern.firstMatch(in: "\(walletNameField.text!)", options: NSRegularExpression.MatchingOptions.reportCompletion,range: NSRange(location:0,length:walletNameField.text!.count)) {
print(first)
}
Regrading touchesBegan you need to use latest syntax Here
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
In your second problem i.e. hiding the keyboard the function should be :-
override func touchesBegan(touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}

Redirect SKNode SkAction direction while touching

While a player is touching, the code below is suppose to move a node to the MaxX. Once they hit that point it is suppose to redirect the node's movement towards the MinX and vice versus.
As it stands right now, I can only move the player in once direction and it is ignoring the movePlayer() logic.
Action Declarations
var moveRightTest:Bool = true;
var moveLeftTest:Bool = false;
let moveRight = SKAction.moveByX(1000, y: 0, duration: 2);
let moveLeft = SKAction.moveByX(-1000, y: 0, duration: 2);
Inside the GameScene:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
movePlayer();
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
stopPlayer();
}
func movePlayer() {
if(moveRightTest == true) {
if(player.position.x <= CGRectGetMaxX(self.frame)) {
player.runAction(moveRight);
} else {
moveRightTest = false;
moveLeftTest = true;
}
}
else if(moveLeftTest == true) {
if(player.position.x >= CGRectGetMinX(self.frame)) {
player.runAction(moveLeft);
} else {
moveLeftTest = false;
moveRightTest = true;
}
}
}
func stopPlayer() {
player.removeAllActions();
}
Note: I subbed out some vars with ints/floats to remove the calculation from the code in order to present. Its not related to the issue. Im also just learning Swift.
Now your function movePlayer is performed only once when you're calling it, so the player comes to the right edge and stops. You need to repeat it after each run the following steps. To do this, you can use runAction with completion like this:
isRight: Bool = true
let moveRight = SKAction.moveToX(CGRectGetMaxX(self.frame), duration: 2)
let moveLeft = SKAction.moveToX(CGRectGetMinX(self.frame), duration: 2)
func movePlayer() {
if isRight {
player.runAction(moveRight, completion: { () -> Void in
isRight = false
self.movePlayer()
})
} else {
player.runAction(moveLeft, completion: { () -> Void in
isRight = true
self.movePlayer()
})
}
}

Swift returns error "method 'beginTrackingWithTouch(_:withEvent:)' with Objective-C selector 'beginTrackingWithTouch:withEvent:' conflicts"

I got this error message after upgrade from XCode 6.2 to XCode 7.0.1.
/Users/ZERO/Documents/Xcode/XXXXX/Library/SegmentedControl/SegmentedControl.swift:124:10:
Method 'beginTrackingWithTouch(:withEvent:)' with Objective-C
selector 'beginTrackingWithTouch:withEvent:' conflicts with method
'beginTrackingWithTouch(:withEvent:)' from superclass 'UIControl'
with the same Objective-C selector
My code:
func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent) -> Bool {
let location = touch.locationInView(self)
var calculatedIndex : Int?
for (index, item) in labels.enumerate() {
if item.frame.contains(location) {
calculatedIndex = index
}
}
if calculatedIndex != nil {
selectedIndex = calculatedIndex!
sendActionsForControlEvents(.ValueChanged)
}
return false
}
The method it has the almost same signature is defined in UIContol.
beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?)
The difference is event parameter has been optional.
So the compiler cannot distinguish them. .
If you'd like to override beginTrackingWithTouch() method, you can change the type of event parameter to UIEvent?, and add override annotation like following:
override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool {
...
return false
}

Gamescene does not have a member named "waitEvent" error

I am currently learning Apple's new software programming language (Swift) and I have encountered this error:
Gamescene does not have a member named "waitEvent"
This is becoming quite frustrating, if anyone knows why this might be please respond.
This is in Swift and Sprite Kit!
Here is the code:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if (destroyerNode? != nil){
destroyerNode!.position = location
destroyerNode!.physicsBody?.velocity = CGVectorMake(0, 0)
destroyerNode!.physicsBody?.dynamic = true
let waitAction = SKAction.waitForDuration(2)
destroyerNode!.runAction(waitAction, completion: {
self.waitEvent()
//there is an issue with someEvent
}
)
}
else{
println("that destroyer was really not there")
}
}
func waitEvent(){
//make the destroyer a dynamic object
destroyerNode!.makeBodyDynamic()
println("The wait is up")
}
func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}

Resources