How i can call functions from other class? Swift, Xcode - ios

I have a class ACCreateObject. They have a function circlePhysicsDefault.
I want to call this function other file by push the Button.
In GameViewController i type:
#IBAction func addOneCircle(sender: AnyObject) {
ACCreateObject.circlePhysicsDefault(ACCreateObject)
}
But i have a issue: '(ACCreateObject).Type' is not convertible to 'ACCreateObject'. How can i call the function?
What am doing wrong?
Thanks!
ACCreateObject.swift
class ACCreateObject: SKScene {
func circlePhysicsDefault() {
var Circle = SKShapeNode(circleOfRadius: 40)
Circle.position = CGPointMake(500, 500)
Circle.name = "defaultCircle"
Circle.strokeColor = SKColor.blackColor()
Circle.glowWidth = 10.0
Circle.fillColor = SKColor.yellowColor()
Circle.physicsBody = SKPhysicsBody(circleOfRadius: 40)
Circle.physicsBody.dynamic = true
self.addChild(Circle)
}
}

You are calling an instance method on a class object. You have two solutions :
Create a new instance and calls it's method
ACCreateObject().circlePhysicsDefault()
OR
Make it a class function
// In your class file
class func circlePhysicsDefault() {
....
}
And then call
ACCreateObject.circlePhysicsDefault()

Not sure if I'm understanding you right but by what you are saying you want to call a method on the type instead on an object
The first thing that comes to mind is this:
var x = ACCreateObject()
x.circlePhysicsDefault()
I think this is the way you should do this.I know there are options of making a class circlePhysicsDefault

Related

Why can't I call my function with gestureTapRecogniser

I have this simple function that when someone taps the screen, the code inside the function executes, I know the code in the function works and I get no error when it is typed.
func reload(gestureRecognizer: UITapGestureRecognizer) {
let skView = self.view!
skView.presentScene(scene)
}
I have this if statement, and all the code work except for when I ry to run the function after a certain event has occurred. In the line where I try and call 'reload()' I get the error 'Use of unresolved identifier reload'. Can you please tell me what I've done wrong. Thanks!
if score[0] >= 10 {
pauseGame()
let textLabel = SKLabelNode(fontNamed: "Helvetica")
textLabel.fontSize = 30
textLabel.fontColor = SKColor.white
textLabel.position = CGPoint(x: 20, y: 20)
textLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center
textLabel.text = "HELLO"
addChild(textLabel)
reload()
}
else if
score [1] >= 10 {
pauseGame()
sleep(5)
let textLabel = SKLabelNode(fontNamed: "ChalkboardSE-Bold")
textLabel.fontSize = 30
textLabel.fontColor = SKColor.white
textLabel.position = CGPoint(x: 20, y: 20)
textLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center
textLabel.text = "HELLO"
addChild(textLabel)
reload()
}
Just change
reload()
to
reload(gestureRecognizer: nil)
and reload method parameter should be UITapGestureRecognizer? optional.
func reload(gestureRecognizer: UITapGestureRecognizer?) {
let skView = self.view!
skView.presentScene(scene)
}
Another short way is
change action method that declared with UITapGestureRecognizer
...action: #selector(self.reload())...
means remove (_:) no need to do anythings more just call reload() function.

SKAction not running on SKSpriteNode

The SKAction on my SKShapeNode isn't working, the code isn't getting executed, and the node isn't moving, even though the console is logging "Snake is moving". Is is because the node is a property of the SKScene and the actions are part of lower scope functions?
class LevelScene: SKScene, SnakeShower {
var snake: Snake {
let theSnake = Snake(inWorld: self.size)
return theSnake
}
override func didMove(to view: SKView) {
self.backgroundColor = .green
snake.delegate = self
}
var myNode: SKShapeNode {
let node = SKShapeNode(rectOf: snake.componentSize)
node.position = snake.head
node.fillColor = .red
return node
}
func presentSnake() { // function called by the snake in the delegate (self)
self.addChild(myNode)
startMoving()
}
func startMoving() {
print("snake is moving")
myNode.run(SKAction.repeatForever(SKAction.sequence([
SKAction.move(by: self.snake.direction.getVector(), duration: 0.2),
SKAction.run({
if self.myNode.position.y > (self.size.height / 2 - self.snake.componentSize.height / 2) {
self.myNode.removeAllActions()
}
})
])))
}
}
It used to work when they property was declared in the same function as the action
myNode is a computed property. self.addChild(myNode) adds a node, but there is no myNode stored property.
myNode.run First computes a new node without adding it to the scene. Then it calls the run the action on it. but since it's a different node that is not on the scene, it will never run.
Change your myNode defintion to:
var myNode : SKShapeNode!
and in didMove(to view: add:
myNode = SKShapeNode(rectOf: snake.componentSize)
myNode.position = snake.head
myNode.fillColor = .red
I had an issue almost identical to this, where I had unresponsive child nodes in a referenced node. Turns out that referenced nodes default to isPaused being true (answer thread found here)
The solution was to change the isPaused property to false.
referencedNode.isPaused = false

Can I use a Selector with parenthesis in Swift?

I was wondering how can I use a Selector in Swift 3 including a value in the parenthesis that the func requires.
let fireRecogniser = UISwipeGestureRecognizer(target: self, action: Selector(("shootShot")))
^ That is the recogniser I have but the method 'shootShot' has a parameter for an Element which is an enum that I have.
Here is the 'shootShot' function:
func shootShot(type: Element) {
let shot = SKSpriteNode(imageNamed: "\(type)Shot")
shot.texture?.filteringMode = SKTextureFilteringMode.nearest
shot.position = CGPoint(x: -self.frame.width / 2 /*playerframe*/, y: -(self.frame.height / 2) + grnd.frame.height)
shot.setScale(1)
shot.physicsBody = SKPhysicsBody(circleOfRadius: (shot.frame.height / 2))
shot.physicsBody?.affectedByGravity = false
shot.physicsBody?.allowsRotation = true
shot.physicsBody?.isDynamic = true
shot.physicsBody?.restitution = 0
shot.physicsBody?.angularDamping = 0
shot.physicsBody?.linearDamping = 0
shot.physicsBody?.friction = 0
shot.physicsBody?.categoryBitMask = Contact.Shot.rawValue
shot.physicsBody?.contactTestBitMask = Contact.Enemy.rawValue
self.addChild(shot)
// THIS WILL DEPEND ON DIFFICULTY
let spin = SKAction.rotate(byAngle: 1, duration: 0.3)
shot.run(SKAction.repeatForever(spin))
let move = SKAction.moveTo(x: self.frame.width / 2, duration: 3.0)
let remove = SKAction.removeFromParent()
shot.run(SKAction.sequence([move, remove]))
}
As you can see, the method has an Element that the function requires.
Any help as to how I can include that parameter in my Selector?
Thanks. :)
Type your selector like this in Swift 3
let fireRecogniser = UISwipeGestureRecognizer(target: self, action: #selector(shootShot(element:)))
It is possible... if you are the one performing the selector.
There is an overload of perform() that has a with: argument. The argument you pass in the with: argument will be passed to the selector method.
Example:
// in some NSObject subclass's method
perform(#selector(myMethod), with: "Hello")
// in the same class
func myMethod(x: String) {
print(x)
}
If the first line is executed, "Hello" will be printed.
However, in yor case, since you are not the performer of the selector, you can't perform the selector with the arguments you want.
You can workaround this by adding a class level variable that indicates which Element you want to call the method with:
var shotElement: Element!
You can set this to some value before you pass the target and action to the gesture recognizer.
Then, access it in shootShot:
let shot = SKSpriteNode(imageNamed: "\(shotElement)Shot")
I admit this isn't the perfect workaround, but it's the most straightforward.

Swift: Init parameter is unresolved

I'm trying to do something that seems straightforward, but I'm getting "use of unresolved identifier" instead of the variable I'm expecting.
In one class I'm instantiating an object:
let sprite = Hero(view: view)
View is a valid variable, and I can po it in this class.
In Hero, I have my init function setup as follows:
init(view: SKView) {
...
}
But when I try to po view from this initializer, I get the "use of unresolved identifier" error. Any idea why?
EDIT:
Here's all my relevant code:
GameScene.swift
import SpriteKit
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
let sprite = Hero(view: view)
self.addChild(sprite)
}
}
Hero.swift
import SpriteKit
class Hero: SKSpriteNode {
init(view: SKView) {
let texture = SKTexture(imageNamed:"Spaceship")
let color = SKColor(white: 0, alpha: 0)
let size = CGSizeMake(100, 100)
super.init(texture:texture, color:color, size:size)
self.xScale = 1.0
self.yScale = 1.0
self.position = CGPointMake((view.bounds.width / 2) - (size.width / 2), view.bounds.height - 200)
}
}
Everything about this code works, the spaceship will show up if I set the position to, let's say CGPointMake(200,200), only view is unresolved in Hero. I'm passing view so that Hero knows the bounds of the view it's being added to and can center itself.
So, I got the code to perform the way I was expecting. I ended up changing Hero's init definition to look like this:
init(addToView view: SKView)
And then initialized a new object by doing:
let hero = Hero(addToView: view)
Now, everything works as I expect, view is passed to init as a resolved variable. But what's funny is #connor's recommendation to use let sprite = Hero(view) should have worked when init was defined as init(view: SKView). "view:" in that case was a local parameter name and should not have been required in the function call. At least, that's what I'm lead to believe based on the Functions chapter of The Swift Programming Language book. I have no idea why Xcode complained about a missing "view:" in the function call, which would have been an external parameter name never listed in the init definition.

UIDynamics not working in Swift

I'm attempting to convert the Ray Wenderlich's tutorial on UIDynamics to swift code, but I'm stuck on the very first part.
http://www.raywenderlich.com/50197/uikit-dynamics-tutorial
Here's what I'm doing:
created a square UIView
added a UIDynamicAnimator to the main view
added a UIGravityBehavior and initialized it with the square
added gravity behavior to the animator
It all compiles and runs fine but the square doesn't move. Can anybody see what I'm doing wrong?
https://github.com/oisinlavery/UIDynamics-Swift
You've created your animator as a local variable to your go method, so it disappears as soon as that method is finished. It needs to be an instance variable on your ViewController class so that it will stick around and do the work of animating the square:
class ViewController: UIViewController {
var animator: UIDynamicAnimator?
#IBAction func go(sender : UIButton) {
var square = UIView(frame: CGRectMake(100, 100, 100, 100))
square.backgroundColor = UIColor.blackColor()
self.view.addSubview(square)
self.animator = UIDynamicAnimator(referenceView: self.view)
var grav = UIGravityBehavior(items:[square])
self.animator!.addBehavior(grav)
}
}

Resources