在Sprite Kit中复制粒子发射器效果

时间:2023-01-22 23:59:18

I need to have a particle emitters effects to appear duplicated in 2 spots (For split screen purposes), I am wondering if anybody has come across a way of doing this. My goal is to have this running on iOS 10. Here is what I have tried so far.

我需要有一个粒子发射器效果在2个点出现重复(为了分屏目的),我想知道是否有人遇到过这样做的方法。我的目标是让它在iOS 10上运行。这是我到目前为止所尝试的。

  1. Assigning targetNode to an SKNode and then copying SKNode every frame: targetNode does not work in iOS 10 for me.
  2. 将targetNode分配给SKNode,然后每帧复制SKNode:targetNode对我来说在iOS 10中不起作用。
  3. Assigning the particle emitter to an SKNode, and using view.textureFromNode to make a texture to copy every frame : takes 1/120th of a frame, too slow for me.
  4. 将粒子发射器分配给SKNode,并使用view.textureFromNode制作纹理以复制每一帧:占用帧的1/120,对我来说太慢了。
  5. Assigning a custom action to a particle node that duplicates the node into another SKNode : Actions will not run on iOS 10
  6. 将自定义操作分配给将节点复制到另一个SKNode的粒子节点:操作不会在iOS 10上运行
  7. Copying the existing particle node in hopes that the seed is not random : The seed is random
  8. 复制现有的粒子节点,希望种子不是随机的:种子是随机的
  9. Tried copying the particle emitter on update : Particle just spawns at origin
  10. 试图在更新时复制粒子发射器:粒子只在原点产生
  11. Tried SKReferenceNode : Just a copy of the emitter, runs on its own
  12. 尝试SKReferenceNode:只是发射器的副本,自己运行

The only option I am left for true emitting is writing my own particle emitter, which I am trying to avoid, so I am wondering if anybody else had this problem and knew of a solution to achieve desired effect.

我留给真正发光的唯一选择是写我自己的粒子发射器,我试图避免,所以我想知道是否有其他人有这个问题,并知道一个解决方案,以达到预期的效果。

The other thing I could do is prerendering the emitters, but this will take up a lot of texture memory if I go this route.

我能做的另一件事是预渲染发射器,但如果我走这条路线,这将占用大量纹理内存。

Edit: To help visualize, I drew a picture, The white border shows where the Split Screen happens. The black border shows where the scene wrapping happens. 在Sprite Kit中复制粒子发射器效果

编辑:为了帮助可视化,我绘制了一张图片,白色边框显示了分屏的位置。黑色边框显示场景包装发生的位置。

As of right now, both Player 1 and Player 2 are on the original scene.

截至目前,播放器1和播放器2都在原始场景中。

Player 2 is walking right and is about to hit a world wrap to move him to the left hand side of the world, but he has not hit it yet. So I need to have a copy of the scene happening so that it visually looks like one scene. Since player 1 is still on the original scene, the original emitter needs to stay in place. Player 2 is going to have to see the same image happening in the copy, otherwise once he passes that border, a "glitchy" effect will happen, and the illusion of wrapping is now gone.

球员2正在向右走,即将击中一个世界包裹,将他移到世界的左手边,但他还没有击中它。所以我需要有一个场景的副本,以便它在视觉上看起来像一个场景。由于播放器1仍然在原始场景上,因此原始发射器需要保持在原位。玩家2将不得不在副本中看到相同的图像,否则一旦他通过该边界,就会发生“毛刺”效果,现在包裹的幻觉消失了。

Final Result:

最后结果:

We just said F%%% it, Player 1 and Player 2 will be looking at different emitter nodes, we will just attach the emitters to each players camera when needed.

我们只是说F %%%它,播放器1和播放器2将查看不同的发射器节点,我们将在需要时将发射器连接到每个播放器相机。

1 个解决方案

#1


7  

This just works (I guess as intended), but I have no idea how much is performant or how it fits your needs and your current game. Anyways, maybe it can help you in some way. First, in your GameViewController...Split screen :)

这只是起作用(我想是按照预期的),但我不知道它的性能有多大,或者它如何适合你的需求和当前的游戏。无论如何,也许它可以在某种程度上帮助你。首先,在你的GameViewController中......分屏:)

#import "GameViewController.h"
#import "GameScene.h"

@implementation GameViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Configure the view.
    SKView * leftSKView = (SKView *)self.leftScene;
    leftSKView.ignoresSiblingOrder = YES;
    leftSKView.showsFPS = YES;
    leftSKView.showsNodeCount = YES;

    SKView * rightSKView = (SKView *)self.rightScene;
    rightSKView.ignoresSiblingOrder = YES;
    rightSKView.showsFPS = YES;
    rightSKView.showsNodeCount = YES;




    // Create and configure the scene.
    GameScene *scene = [GameScene nodeWithFileNamed:@"GameScene"];
    scene.scaleMode = SKSceneScaleModeAspectFill;

    // Present the scene.
    [leftSKView presentScene:scene];
    [rightSKView presentScene:scene];

}

leftScene and rightScene are UIViews defined in a storyboard using autolayout to take half of a screen each. Also a class is changed to SKView (it was UIView). Pretty trivial...

leftScene和rightScene是在故事板中使用autolayout定义的UIViews,每个屏幕占用一半的屏幕。另外一个类被改为SKView(它是UIView)。非常琐碎......

Then in your game scene just add an emitter which will be shared between these two views. Because only one emitter is used, particles emitting (how they move) will be mirrored. So in game scene, just add a particle:

然后在你的游戏场景中添加一个将在这两个视图之间共享的发射器。因为只使用了一个发射器,所以发射粒子(它们如何移动)将被镜像。所以在游戏场景中,只需添加一个粒子:

-(void)didMoveToView:(SKView *)view {
    /* Setup your scene here */


    SKEmitterNode *emitter =  [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"MyParticle" ofType:@"sks"]];
    emitter.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidX(self.frame));
    emitter.name = @"explosion";
    emitter.targetNode = self;
    [self addChild:emitter];
}

I know that you don't need all this code, but if this is what you want in some way, I will post it for completeness. And here is the result: 在Sprite Kit中复制粒子发射器效果

我知道你不需要所有这些代码,但如果这是你想要的某种方式,我会发布它是为了完整性。这是结果:

#1


7  

This just works (I guess as intended), but I have no idea how much is performant or how it fits your needs and your current game. Anyways, maybe it can help you in some way. First, in your GameViewController...Split screen :)

这只是起作用(我想是按照预期的),但我不知道它的性能有多大,或者它如何适合你的需求和当前的游戏。无论如何,也许它可以在某种程度上帮助你。首先,在你的GameViewController中......分屏:)

#import "GameViewController.h"
#import "GameScene.h"

@implementation GameViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Configure the view.
    SKView * leftSKView = (SKView *)self.leftScene;
    leftSKView.ignoresSiblingOrder = YES;
    leftSKView.showsFPS = YES;
    leftSKView.showsNodeCount = YES;

    SKView * rightSKView = (SKView *)self.rightScene;
    rightSKView.ignoresSiblingOrder = YES;
    rightSKView.showsFPS = YES;
    rightSKView.showsNodeCount = YES;




    // Create and configure the scene.
    GameScene *scene = [GameScene nodeWithFileNamed:@"GameScene"];
    scene.scaleMode = SKSceneScaleModeAspectFill;

    // Present the scene.
    [leftSKView presentScene:scene];
    [rightSKView presentScene:scene];

}

leftScene and rightScene are UIViews defined in a storyboard using autolayout to take half of a screen each. Also a class is changed to SKView (it was UIView). Pretty trivial...

leftScene和rightScene是在故事板中使用autolayout定义的UIViews,每个屏幕占用一半的屏幕。另外一个类被改为SKView(它是UIView)。非常琐碎......

Then in your game scene just add an emitter which will be shared between these two views. Because only one emitter is used, particles emitting (how they move) will be mirrored. So in game scene, just add a particle:

然后在你的游戏场景中添加一个将在这两个视图之间共享的发射器。因为只使用了一个发射器,所以发射粒子(它们如何移动)将被镜像。所以在游戏场景中,只需添加一个粒子:

-(void)didMoveToView:(SKView *)view {
    /* Setup your scene here */


    SKEmitterNode *emitter =  [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"MyParticle" ofType:@"sks"]];
    emitter.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidX(self.frame));
    emitter.name = @"explosion";
    emitter.targetNode = self;
    [self addChild:emitter];
}

I know that you don't need all this code, but if this is what you want in some way, I will post it for completeness. And here is the result: 在Sprite Kit中复制粒子发射器效果

我知道你不需要所有这些代码,但如果这是你想要的某种方式,我会发布它是为了完整性。这是结果: