Search code examples
iosobjective-csprite-kitskaction

Endless Action with SKActions Objective C


I am building a game with sprite kit and have a sprite moving from left to right with an endless action.

SKAction *moveRight = [SKAction moveByX:3.0 y:0 duration:3.5];
SKAction *moveLeft = [SKAction moveByX:-3.0 y:0 duration:3.5];
SKAction *reversedMoveRight = [moveRight reversedAction];
SKAction *reversedMoveLeft = [moveLeft reversedAction];

SKAction *completion = [SKAction runBlock:^{

    SKAction *sequence = [SKAction sequence:@[moveRight, moveLeft, reversedMoveRight,reversedMoveLeft]];
    SKAction *endlessAction = [SKAction repeatActionForever:sequence];
    [snake runAction:endlessAction];
}];

[snake runAction:completion withKey:@"KeySnake"];

This works, but after a short period of time my game slows down. The CPU and memory usage continues to grow in the debug navigator in Xcode. I think the endless action is causing the problem, but I don't know any other way to move it constantly like I want to.


Solution

  • From your comment I understand you are calling

    [snake runAction:completion withKey:@"KeySnake"];
    

    inside the update method. This is the problem, infact you are creating and running a new action every frame.

    Move the whole block of code (you showed in your question) inside a method that is called only once.

    Example: here I also refactored the construction of your action and changed the x value (in the action) from 3.0 to 100.0

    #import "GameScene.h"
    
    @implementation GameScene
    {
        SKSpriteNode * _snake;
    }
    
    - (void)didMoveToView:(SKView *)view {
        [self addSnake];
        [self startSnakeMoving];
    }
    
    - (void)addSnake{
        _snake = [SKSpriteNode spriteNodeWithImageNamed:@"Snake"];
        _snake.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
        [self addChild:_snake];
    }
    
    - (void)startSnakeMoving {
        SKAction * moveRight = [SKAction moveByX:100.0 y:0 duration:3.5];
        SKAction * sequence = [SKAction sequence:@[moveRight, moveRight.reversedAction, moveRight.reversedAction, moveRight]];
        SKAction * endlessAction = [SKAction repeatActionForever:sequence];
        [_snake runAction:endlessAction withKey:@"KeySnake"];
    }
    @end