[Stage3D] StarlingでFFParticleSystemを試すのだ! (2) ~炎と煙, 火の粉~

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

starling_FFParticleSystem2

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/fire.png")]
  private static const FireTexture:Class;
  [Embed(source="assets/fire.xml", mimeType="application/octet-stream")]
  private static const FireAtlas:Class;
  [Embed(source="assets/fire.pex", mimeType="application/octet-stream")]
  private static const FireConfig:Class;
  [Embed(source="assets/sparks.png")]
  private static const SparksTexture:Class;
  [Embed(source="assets/sparks.xml", mimeType="application/octet-stream")]
  private static const SparksAtlas:Class;
  [Embed(source="assets/sparks.pex", mimeType="application/octet-stream")]
  private static const SparksConfig:Class;
  // プロパティ
  private var basic:Quad;
  private var night:Quad;
  private var atween:Tween24;
  private var texture:Texture;
  private var atlas:TextureAtlas;
  private var piyo:MovieClip;
  private var fire:FFParticleSystem;
  private var sparks: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;
    initialize();
    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 = 275;
    addChild(piyo);

    Starling.juggler.add(piyo);
    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 fireconfig:XML = XML(new FireConfig());
    var firetexture:Texture = Texture.fromBitmap(new FireTexture());
    var fireatlas:XML = XML(new FireAtlas());

    var fireoptions:SystemOptions = SystemOptions.fromXML(fireconfig, firetexture, fireatlas);
    fireoptions.appendFromObject({isAnimated: false, randomStartFrames: true, sourceX: 300, sourceY: 265});
    fire = new FFParticleSystem(fireoptions);
    addChild(fire);

    fire.start();
    var sparksconfig:XML = XML(new SparksConfig());
    var sparkstexture:Texture = Texture.fromBitmap(new SparksTexture());
    var sparksatlas:XML = XML(new SparksAtlas());

    var sparksoptions:SystemOptions = SystemOptions.fromXML(sparksconfig, sparkstexture, sparksatlas);
    sparksoptions.appendFromObject({isAnimated: false, randomStartFrames: true, sourceX: 300, sourceY: 265});
    sparks = new FFParticleSystem(sparksoptions);
    addChild(sparks);

    sparks.start();
  }
  private function start():void {
    atween = Tween24.serial(
      Tween24.wait(4.0),
      Tween24.func(wind, 80),
      Tween24.tween(night, 1.6, Tween24.ease.Linear).fadeIn(),
      Tween24.func(wind, 0),
      Tween24.wait(4.0),
      Tween24.tween(night, 1.6, Tween24.ease.Linear).fadeOut()
    );
    atween.addEventListener(Tween24Event.COMPLETE, complete, false, 0, true);
    atween.play();
  }
  private function wind(vx:Number):void {
    fire.gravityX = vx;
    spark.gravityX = vx*2;
  }
  private function complete(evt:Tween24Event):void {
    atween.removeEventListener(Tween24Event.COMPLETE, complete);
    start();
  }

}

sparks.png (透過PNG)

starling_FFParticleSystem2_sparks

sparks.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<TextureAtlas imagePath="sparks.png">
  <SubTexture name="sparks0" x="34" y="0" width="7" height="10"/>
  <SubTexture name="sparks1" x="21" y="0" width="9" height="12"/>

    (中略)

  <SubTexture name="sparks14" x="11" y="22" width="7" height="8"/>
  <SubTexture name="sparks15" x="50" y="19" width="7" height="8"/>
</TextureAtlas>

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

  <tinted value="1"/>
  <spawnTime value="0" />
  <fadeOutTime value="0.2" />
  <emitterType value="0"/>
  <maxParticles value="400"/>
  <sourcePosition x="0" y="0"/>
  <sourcePositionVariance x="30.00" y="0.00"/>

  <particleLifeSpan value="3"/>
  <particleLifespanVariance value="1.000"/>
  <angle value="270.00"/>
  <angleVariance value="10.00"/>
  <startParticleSize value="1.00"/>
  <startParticleSizeVariance value="0.50"/>
  <finishParticleSize value="1.00"/>
  <FinishParticleSizeVariance value="0.50"/>

  <rotationStart value="0.00"/>
  <rotationStartVariance value="360.00"/>
  <rotationEnd value="0.00"/>
  <rotationEndVariance value="360.00"/>
  <duration value="-1.00"/>
  <gravity x="0" y="0"/>
  <speed value="150.00"/>
  <speedVariance value="50.00"/>

  <radialAcceleration value="-50.00"/>
  <radialAccelVariance value="15.00"/>
  <tangentialAcceleration value="0.00"/>
  <tangentialAccelVariance value="15.00"/>
  <maxRadius value="0.00"/>
  <maxRadiusVariance value="0.00"/>
  <minRadius value="0.00"/>
  <rotatePerSecond value="0.00"/>
  <rotatePerSecondVariance value="0.00"/>
  <startColor red="1" green="1" blue="0" alpha="1"/>
  <startColorVariance red="0" green="0" blue="0" alpha="0"/>
  <finishColor red="1" green="0" blue="0.0" alpha="1"/>
  <finishColorVariance red="0.25" green="0" blue="0" alpha="0"/>

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

</particleEmitterConfig>

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

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


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