Martin Jones Martin Jones - 7 days ago 4x
Swift Question

Swift 3 Expect Argument Error

I am creating some functions in order to make a game similar to Flappy Bird. I am a complete beginner and am trying to understand everything fully as I go before moving on. I have been able to get my obstacle to move but when I attempt to put it into a function to allow me more flexibility later on with multiple obstacles I receive an error.

'Cannot convert type '()' to expected argument type 'SKAction'

class GameScene : SKScene, SKPhysicsContactDelegate {

var Player = SKSpriteNode()
var Ground = SKSpriteNode()
var Roof = SKSpriteNode()
var Background = SKSpriteNode()
let Obstacle1 = SKSpriteNode(imageNamed: "Fire Barrel 1")

override func didMove(to view: SKView) {

// Create Background Color
backgroundColor = bgColor

// Set World Gravity
self.physicsWorld.gravity = CGVector(dx: 0.0, dy: -4.0)

// Create Player
Player = SKSpriteNode(imageNamed: "Player")
Player.position = CGPoint(x: -self.frame.width / 2 + 100, y: -Player.frame.height / 2)


// Create Ground
Ground = SKSpriteNode(imageNamed: "BGTileBtm")
Ground.anchorPoint = CGPoint(x: 0,y: 0.5)
Ground.position = CGPoint(x: -self.frame.width / 2, y: -self.frame.height / 2)


// Create Roof
Roof = SKSpriteNode(imageNamed: "BGTileTop")
Roof.anchorPoint = CGPoint(x: 1,y: 1)
Roof.position = CGPoint(x: -self.frame.width / 2, y: self.frame.height / 2 - Roof.frame.height)
Roof.zRotation = CGFloat(M_PI)


// Set Physics Rules
Player.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Player"), size: Player.size)
Player.physicsBody!.affectedByGravity = true
Player.physicsBody!.allowsRotation = false

Ground.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Ground"), size: Ground.size)
Ground.physicsBody!.affectedByGravity = false
Ground.physicsBody!.isDynamic = false

// Obstacle
func addObstacle1(){

Obstacle1.position = CGPoint(x: self.frame.width / 2, y: -self.frame.height / 2 + Obstacle1.frame.height)
Obstacle1.zPosition = 1

func moveObstacle1(){

let distance = CGVector(dx: -self.frame.width, dy: 0)
let moveDistance = SKAction.move(by: distance, duration: 5)





Change the declaration of moveObstacle1 to this:

func moveObstacle1() -> SKAction{

    let distance = CGVector(dx: -self.frame.width, dy: 0)
    let moveDistance = SKAction.move(by: distance, duration: 5)
    return moveDistance



Regarding your comment,

run is a method. When you call it, it runs the SKAction you passed in. That's it! What you are trying to do is run(moveObstacle1()). What does that mean exactly? How can you pass a method call as a parameter? At runtime, the return value of moveObstacle1() is passed to run. In other words, for run(moveObstacle1()) to compile, moveObstacle1() must return a value using the return statement. And that value must be of type SKAction, since that's the thing you're passing to run.

return is used to return a value from a moveObstacle1(), so that you can call run(moveObstacle1()).

run is just a regular old method.