Opengl es Spritekit和OpenGL:平滑的烟雾轨迹

Opengl es Spritekit和OpenGL:平滑的烟雾轨迹,opengl-es,sprite-kit,glsl,skemitternode,Opengl Es,Sprite Kit,Glsl,Skemitternode,我想在我的Spritekit游戏中实现这种效果,在游戏中,角色后面有一条平滑的轨迹 查看jetpack joyride中硬币后面的轨迹: 木星跳跃英雄身后的轨迹: 或者滑雪旅行英雄身后的这条超级平滑的小路: 这似乎是其他游戏引擎的标准功能,也许?我认为spritekit粒子发射器只能提供块状/压印的轨迹,而不是平滑的轨迹。我应该使用某种精灵自定义着色器吗?还有其他创造性的想法吗?你的问题没有包括一个关键问题,那就是要使用的运动类型。我的答案是基于触摸屏幕上的目标点,但另一种选择是使用核心运

我想在我的Spritekit游戏中实现这种效果,在游戏中,角色后面有一条平滑的轨迹

查看jetpack joyride中硬币后面的轨迹:

木星跳跃英雄身后的轨迹:

或者滑雪旅行英雄身后的这条超级平滑的小路:


这似乎是其他游戏引擎的标准功能,也许?我认为spritekit粒子发射器只能提供块状/压印的轨迹,而不是平滑的轨迹。我应该使用某种精灵自定义着色器吗?还有其他创造性的想法吗?

你的问题没有包括一个关键问题,那就是要使用的运动类型。我的答案是基于触摸屏幕上的目标点,但另一种选择是使用核心运动。无论使用哪种方法,基本代码主体都保持不变。只有实施才会改变

我在示例中使用了一个矩形尾部图像,因为我希望您能够复制并运行示例代码。您应该用圆形图像/纹理替换矩形,以使尾部的侧面更平滑

修改淡出持续时间值将导致更长或更短的尾部

修改stepsDivider将在尾部产生或多或少的节点

#import "GameScene.h"

@implementation GameScene {
    SKSpriteNode *playerNode;
    CGPoint destinationPoint;
    NSMutableArray *myArray;
    NSMutableArray *myDiscardArray;
    BOOL working;
    int numberOfSteps;
    float xIncrement;
    float yIncrement;
    float fadeOutDuration;
    int stepsDivider;
}

-(void)didMoveToView:(SKView *)view {
    self.backgroundColor = [SKColor blackColor];

    playerNode = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(30, 30)];
    playerNode.position = CGPointMake(200, 200);
    [self addChild:playerNode];

    myArray = [[NSMutableArray alloc] init];
    myDiscardArray = [[NSMutableArray alloc] init];

    working = false;
    fadeOutDuration = 0.5;
    stepsDivider = 10;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UITouch *touch in touches) {
        CGPoint location = [touch locationInNode:self];

        if(working == false) {
            destinationPoint = location;

            if(fabsf(location.x - playerNode.position.x) > fabsf(location.y - playerNode.position.y)) {
                numberOfSteps = fabsf(location.x - playerNode.position.x) / 10;
            } else {
                numberOfSteps = fabsf(location.y - playerNode.position.y) / 10;
            }

            xIncrement = (location.x - playerNode.position.x) / numberOfSteps;
            yIncrement = (location.y - playerNode.position.y) / numberOfSteps;

            working = true;
        }
    }
}

-(void)update:(CFTimeInterval)currentTime {

    if (working == true) {

        // create trail node at current player's position
        SKSpriteNode *myNode = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(30, 30)];
        myNode.position = playerNode.position;
        [self addChild:myNode];
        [myArray addObject:myNode];
        [myNode runAction:[SKAction fadeOutWithDuration:fadeOutDuration]];

        // check array for any nodes with zero alpha
        for(SKSpriteNode *object in myArray) {
            if(object.alpha == 0) {
                [myDiscardArray addObject:object];
            }
        }

        // remove zero alpha nodes
        if([myDiscardArray count] > 0) {
            [myArray removeObjectsInArray:myDiscardArray];
            [myDiscardArray removeAllObjects];
        }

        // update player's new position
        playerNode.position = CGPointMake(playerNode.position.x+xIncrement, playerNode.position.y+yIncrement);

        // check if player has arrived at destination
        if(((int)playerNode.position.x == (int)destinationPoint.x) && ((int)playerNode.position.y == (int)destinationPoint.y)) {
            working = false;
        }
    }
}

@end

这样的效果肯定是自定义代码。可能是类似于使用淡出alpha持续时间计时器创建有方向角度的并排矩形。这样避免锯齿边似乎很棘手。我要用CG画样条曲线吗?感觉效率很低…谢谢Sangony的努力。正如你所说,我认为这是一个很好的近似效果。当我看原稿时,我想知道它是贝塞尔路径上的某种颜色渐变,还是某种GLSL着色器。@PaddyCollins-无论你最终选择什么方法,其原理都将保持不变。在某些情况下,您必须“绘制”一个具有alpha淡入寿命的形状/节点/数据包。如果最终分辨率非常好,可能会因为这种效果而给处理器带来沉重的负载,并可能导致FPS计数紧张。也许这种效果是Unity等其他语言的标准部分,但我确信SpriteKit没有这样的内置功能。有人能将其转换为swift代码吗?我不太精通Obj-C。谢谢@sangony我已经将这段优秀的代码改编成我的Xamarin iOS项目,并取得了巨大的成功,非常感谢。只有一个小问题:是否存在小内存泄漏?如果我读对了,一旦playerNode到达它的目的地,working就被设置为false,因此更新中的块将不再被调用。这意味着最后一次“清理”褪色的节点将无法完成,留下它们四处游荡。我可以在我的SKView节点计数器上看到。Objective-C在这里清理了吗?这就是为什么你不必担心它,但我必须做一个单独的处理?