[Stage3D] StarlingでFFParticleSystemを試すのだ! (4) ~雪~

Flash Player 11 から採用された Stage3D を学習するよ。 :bouzu:
Starling Framework を試しちゃうんだからね。 :girl:

starling_FFParticleSystem4

FFParticleSystemクラスで、高速パーティクルシステムを試してみちゃうよ。 :boy:

:caution: 要 Flash Player 11.8 以上

This movie requires Flash Player 11.8.0

Main.as
package {

  import flash.display.Sprite;
  import flash.display.StageScaleMode;
  import flash.display.StageAlign;
  import flash.display3D.Context3DRenderMode;
  import flash.display3D.Context3DProfile;

  import starling.core.Starling;

  [SWF(backgroundColor="#FFFFFF", width="600", height="300", frameRate="60")]

  public class Main extends Sprite {
    // プロパティ
    private var starling:Starling;

    // コンストラクタ
    public function Main() {
      stage.scaleMode = StageScaleMode.NO_SCALE;
      stage.align = StageAlign.TOP_LEFT;
      init();
    }

    // メソッド
    private function init():void {
      starling = new Starling(MainView, stage, null, null, Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
      starling.showStats = true;
      starling.enableErrorChecking = true;
      starling.start();
    }
  }

}



import starling.core.Starling;
import starling.display.Sprite;
import starling.display.MovieClip;
import starling.textures.Texture;
import starling.textures.TextureAtlas;
import starling.events.Event;

import de.flintfabrik.starling.display.FFParticleSystem;
import de.flintfabrik.starling.display.core.SystemOptions;

import a24.tween.Tween24;
import a24.tween.events.Tween24Event;


internal class MainView extends Sprite {
  [Embed(source="assets/piyo.png")]
  private var PiyoTexture:Class;
  [Embed(source="assets/piyo.xml", mimeType="application/octet-stream")]
  private var PiyoAtlas:Class;
  [Embed(source="assets/snow.png")]
  private static const SnowTexture:Class;
  [Embed(source="assets/snow.pex", mimeType="application/octet-stream")]
  private static const SnowConfig:Class;
  [Embed(source="assets/snow_blur.png")]
  private static const SnowBlurTexture:Class;
  [Embed(source="assets/snow_blur.pex", mimeType="application/octet-stream")]
  private static const SnowBlurConfig:Class;
  // プロパティ
  private var basic:Quad;
  private var night:Quad;
  private var ground:Quad;
  private var atween:Tween24;
  private var texture:Texture;
  private var atlas:TextureAtlas;
  private var back:Sprite;
  private var piyo:MovieClip;
  private var front:Sprite;
  private var snow1:FFParticleSystem;
  private var snow2:FFParticleSystem;
  private var snow3:FFParticleSystem;

  // コンストラクタ
  public function MainView() {
    FFParticleSystem.init(2048, false, 2048, 16);
    addEventListener(Event.ADDED_TO_STAGE, init);
    addEventListener(Event.REMOVED_FROM_STAGE, remove);
  }

  // メソッド
  private function init(evt:Event):void {
    removeEventListener(Event.ADDED_TO_STAGE, init);
    basic = new Quad(600, 300, 0x002267);
    addChild(basic);
    night = new Quad(600, 300, 0x008A42);
    addChild(night);
    night.alpha = 0;
    ground = new Quad(600, 75, 0xFFFFFF);
    addChild(ground);
    ground.y = 225;
    ground.alpha = 0;
    back = new Sprite();
    addChild(back);

    texture = Texture.fromBitmap(new PiyoTexture());
    atlas = new TextureAtlas(texture, XML(new PiyoAtlas()));

    piyo = new MovieClip(atlas.getTextures(), 60);
    piyo.currentFrame = Math.random()*60;
    piyo.pivotX = 26;
    piyo.pivotY = 59;
    piyo.x = 300;
    piyo.y = 250;
    addChild(piyo);

    Starling.juggler.add(piyo);
    front = new Sprite();
    addChild(front);

    initialize();
    start();
  }
  private function remove(evt:Event):void {
    removeEventListener(Event.REMOVED_FROM_STAGE, remove);
    Starling.juggler.remove(piyo);
  }
  override public function dispose():void {
    removeEventListener(Event.ADDED_TO_STAGE, init);
    removeEventListener(Event.REMOVED_FROM_STAGE, remove);
    super.dispose();
  }
  private function initialize():void {
    var snowconfig:XML = XML(new SnowConfig());
    var snowtexture:Texture = Texture.fromBitmap(new SnowTexture());

    var snowoptions1:SystemOptions = SystemOptions.fromXML(snowconfig, snowtexture);
    snowoptions1.appendFromObject({
      isAnimated: false, randomStartFrames: false, sourceX: 300, sourceY: -20,
      maxParticles: 500, startParticleSize: 5, finishParticleSize: 5, gravityY: 10
    });

    var snowoptions2:SystemOptions = SystemOptions.fromXML(snowconfig, snowtexture);
    snowoptions2.appendFromObject({
      isAnimated: false, randomStartFrames: false, sourceX: 300, sourceY: -20,
      maxParticles: 200, startParticleSize: 10, finishParticleSize: 10, gravityY: 20
    });

    var snowblurconfig:XML = XML(new SnowBlurConfig());
    var snowblurtexture:Texture = Texture.fromBitmap(new SnowBlurTexture());

    var snowoptions3:SystemOptions = SystemOptions.fromXML(snowblurconfig, snowblurtexture);
    snowoptions3.appendFromObject({
      isAnimated: false, randomStartFrames: false, sourceX: 300, sourceY: -20,
      maxParticles: 20, startParticleSize: 40, finishParticleSize: 40, gravityY: 80
    });

    snow1 = new FFParticleSystem(snowoptions1);
    snow2 = new FFParticleSystem(snowoptions2);
    back.addChild(snow1);
    back.addChild(snow2);
    snow3 = new FFParticleSystem(snowoptions3);
    front.addChild(snow3);
    snow1.start();
    snow2.start();
    snow3.start();
  }
  private function start():void {
    atween = Tween24.serial(
      Tween24.func(snow, 0.2),
      Tween24.wait(1.6),
      Tween24.tween(ground, 1.6, Tween24.ease.QuadIn).fadeOut(),
      Tween24.wait(0.8),
      Tween24.func(snow, 1),
      Tween24.parallel(
        Tween24.tweenFunc(wind, 0.4, [0], [100], Tween24.ease.QuadOut),
        Tween24.tween(night, 1.6, Tween24.ease.Linear).fadeIn(),
        Tween24.tween(ground, 3.2, Tween24.ease.QuadOut).fadeIn()
      ),
      Tween24.wait(2.4),
      Tween24.parallel(
        Tween24.tweenFunc(wind, 0.4, [100], [0], Tween24.ease.QuadOut),
        Tween24.tween(night, 1.6, Tween24.ease.Linear).fadeOut()
      )
    );
    atween.addEventListener(Tween24Event.COMPLETE, complete, false, 0, true);
    atween.play();
  }
  private function snow(rate:Number):void {
    snow1.emissionRate = (500/2.25)*rate;
    snow2.emissionRate = (200/2.25)*rate;
    snow3.emissionRate = (20/2.00)*rate;
  }
  private function wind(vx:Number):void {
    snow1.gravityX = vx;
    snow2.gravityX = vx*2;
    snow3.gravityX = vx*4;
  }
  private function complete(evt:Tween24Event):void {
    atween.removeEventListener(Tween24Event.COMPLETE, complete);
    start();
  }

}

snow.png (透過PNG)

starling_FFParticleSystem4_snow

snow.pex
<?xml version="1.0"?>
<particleEmitterConfig>
  <animation>
    <isAnimated value="0"/>
    <loops value="1"/>
    <firstFrame value="0"/>
    <lastFrame value="-1"/>
    <randomStartFrames value="0"/>
  </animation>

  <tinted value="1"/>
  <spawnTime value="0" />
  <fadeInTime value="0" />
  <fadeOutTime value="0.1" />
  <emitterType value="0"/>
  <maxParticles value="500"/>
  <texture name="snow.png"/>
  <sourcePosition x="-320" y="0"/>
  <sourcePositionVariance x="640.00" y="0.00"/>

  <particleLifeSpan value="2.2500"/>
  <particleLifespanVariance value="0.0000"/>
  <angle value="90.00"/>
  <angleVariance value="0.00"/>
  <startParticleSize value="10.00"/>
  <startParticleSizeVariance value="0.00"/>
  <finishParticleSize value="10.00"/>
  <FinishParticleSizeVariance value="0.00"/>

  <rotationStart value="0.00"/>
  <rotationStartVariance value="180.00"/>
  <rotationEnd value="0.00"/>
  <rotationEndVariance value="0.00"/>
  <duration value="-1.00"/>
  <gravity x="0" y="-10"/>
  <speed value="100.00"/>
  <speedVariance value="10.00"/>

  <radialAcceleration value="-5.00"/>
  <radialAccelVariance value="10.00"/>

  <tangentialAcceleration value="0.00"/>
  <tangentialAccelVariance value="0.00"/>
  <maxRadius value="0.00"/>
  <maxRadiusVariance value="0.00"/>
  <minRadius value="0.00"/>
  <rotatePerSecond value="0.00"/>
  <rotatePerSecondVariance value="0.00"/>
  <startColor red="2.55" green="2.55" blue="2.55" alpha="2.55"/>
  <startColorVariance red="0" green="0" blue="0" alpha="0"/>
  <finishColor red="2.55" green="2.55" blue="2.55" alpha="1"/>
  <finishColorVariance red="0" green="0" blue="0" alpha="0"/>

  <blendFuncSource value="SOURCE_ALPHA"/>
  <blendFuncDestination value="ONE_MINUS_SOURCE_ALPHA"/>

</particleEmitterConfig>

参考資料「Improved Particle System for Starling | code·math·motion·jutsu
:check: 「shin10/Starling-FFParticleSystem · GitHub

そのままのソースだとエラーが出るので、ちょっとごにょごにょする。 😀


[修正] (14/06/25 Wed 15:30)
Starling 1.5 にバージョンアップ。
[修正] (14/06/25 Wed 17:19)
Starling 1.5.1 にバージョンアップ。
[修正] (14/10/08 Wed 15:02)
Tween24 2.1 にバージョンアップ。
[修正] (14/12/14 Sun 21:04)
Starling 1.6 にバージョンアップ。