@@ -8,9 +8,11 @@ var Class = require('../utils/Class');
88var DegToRad = require ( '../math/DegToRad' ) ;
99var Extend = require ( '../utils/object/Extend' ) ;
1010var Formats = require ( './Formats' ) ;
11+ var GetFastValue = require ( '../utils/object/GetFastValue' ) ;
1112var LayerData = require ( './mapdata/LayerData' ) ;
1213var Rotate = require ( '../math/Rotate' ) ;
1314var SpliceOne = require ( '../utils/array/SpliceOne' ) ;
15+ var Sprite = require ( '../gameobjects/sprite/Sprite' ) ;
1416var Tile = require ( './Tile' ) ;
1517var TilemapComponents = require ( './components' ) ;
1618var TilemapLayer = require ( './TilemapLayer' ) ;
@@ -630,87 +632,188 @@ var Tilemap = new Class({
630632 } ,
631633
632634 /**
633- * Creates a Sprite for every object matching the given gid in the map data. All properties from
634- * the map data objectgroup are copied into the `spriteConfig`, so you can use this as an easy
635- * way to configure Sprite properties from within the map editor. For example giving an object a
636- * property of alpha: 0.5 in the map editor will duplicate that when the Sprite is created.
635+ * This method will iterate through all of the objects defined in a Tiled Object Layer and then
636+ * convert the matching results into Phaser Game Objects (by default, Sprites)
637637 *
638- * Custom object properties not sharing names with the Sprite's own properties are copied to the
639- * Sprite's {@link Phaser.GameObjects.Sprite#data data store}.
638+ * Objects are matched on one of 3 criteria: The Object ID, the Object GID or the Object Name.
639+ *
640+ * Within Tiled, Object IDs are unique per Object. Object GIDs, however, are shared by all objects
641+ * using the same image. Finally, Object Names are strings and the same name can be used on multiple
642+ * Objects in Tiled, they do not have to be unique.
643+ *
644+ * You set the configuration parameter accordingly, based on which type of criteria you wish
645+ * to match against. For example, to convert all items on an Object Layer with a `gid` of 26:
646+ *
647+ * ```javascript
648+ * createFromObjects(layerName, {
649+ * gid: 26
650+ * });
651+ * ```
652+ *
653+ * Or, to convert objects with the name 'bonus':
654+ *
655+ * ```javascript
656+ * createFromObjects(layerName, {
657+ * name: 'bonus'
658+ * });
659+ * ```
660+ *
661+ * Or, to convert an object with a specific id:
662+ *
663+ * ```javascript
664+ * createFromObjects(layerName, {
665+ * id: 9
666+ * });
667+ * ```
668+ *
669+ * You should only specify either `id`, `gid`, `name`, or none of them. Do not add more than
670+ * one criteria to your config. If you do not specify any criteria, then _all_ objects in the
671+ * Object Layer will be converted.
672+ *
673+ * By default this method will convert objects into `Sprite` instances, but you can override
674+ * this by providing your own class type:
675+ *
676+ * ```javascript
677+ * createFromObjects(layerName, {
678+ * gid: 26,
679+ * classType: Coin
680+ * });
681+ * ```
682+ *
683+ * This will convert all Objects with a gid of 26 into your custom `Coin` class. You can pass
684+ * any class type here, but it _must_ extend `Phaser.GameObjects.GameObject` as its base class.
685+ * Your class will always be passed 1 parameter: `scene`, which is a reference to either the Scene
686+ * specified in the config object or, if not given, the Scene to which this Tilemap belongs.
687+ *
688+ * All properties from object are copied into the Game Object, so you can use this as an easy
689+ * way to configure properties from within the map editor. For example giving an object a
690+ * property of `alpha: 0.5` in Tiled will be reflected in the Game Object that is created.
691+ *
692+ * Custom object properties that do not exist as a Game Object property are set in the
693+ * Game Objects {@link Phaser.GameObjects.GameObject#data data store}.
694+ *
695+ * You can use set a `container` property in the config. If given, the class will be added to
696+ * the Container instance instead of the Scene.
697+ *
698+ * Finally, you can provide an array of config objects, to convert multiple types of object in
699+ * a single call:
700+ *
701+ * ```javascript
702+ * createFromObjects(layerName, [
703+ * {
704+ * gid: 26,
705+ * classType: Coin
706+ * },
707+ * {
708+ * id: 9,
709+ * classType: BossMonster
710+ * },
711+ * {
712+ * name: 'lava',
713+ * classType: LavaTile
714+ * }
715+ * ]);
716+ * ```
717+ *
718+ * The signature of this method changed significantly in v3.50.0. Prior to this, it did not take config objects.
640719 *
641720 * @method Phaser.Tilemaps.Tilemap#createFromObjects
642721 * @since 3.0.0
643722 *
644- * @param {string } name - The name of the object layer (from Tiled) to create Sprites from.
645- * @param {(integer|string) } id - Either the id (object), gid (tile object) or name (object or
646- * tile object) from Tiled. Ids are unique in Tiled, but a gid is shared by all tile objects
647- * with the same graphic. The same name can be used on multiple objects.
648- * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig } spriteConfig - The config object to pass into the Sprite creator (i.e.
649- * scene.make.sprite).
650- * @param {Phaser.Scene } [scene=the scene the map is within] - The Scene to create the Sprites within.
723+ * @param {string } objectLayerName - The name of the Tiled object layer to create the Game Objects from.
724+ * @param {Phaser.Types.Tilemaps.CreateFromObjectLayerConfig|Phaser.Types.Tilemaps.CreateFromObjectLayerConfig[] } config - A CreateFromObjects configuration object, or an array of them.
651725 *
652- * @return {Phaser.GameObjects.Sprite [] } An array of the Sprites that were created.
726+ * @return {Phaser.GameObjects.GameObject [] } An array containing the Game Objects that were created. Empty if invalid object layer, or no matching id/gid/name was found .
653727 */
654- createFromObjects : function ( name , id , spriteConfig , scene )
728+ createFromObjects : function ( objectLayerName , config )
655729 {
656- if ( spriteConfig === undefined ) { spriteConfig = { } ; }
657- if ( scene === undefined ) { scene = this . scene ; }
730+ var results = [ ] ;
658731
659- var objectLayer = this . getObjectLayer ( name ) ;
732+ var objectLayer = this . getObjectLayer ( objectLayerName ) ;
660733
661734 if ( ! objectLayer )
662735 {
663- console . warn ( 'Cannot create from object. Invalid objectgroup name given: ' + name ) ;
736+ console . warn ( 'createFromObjects: Invalid objectLayerName given: ' + objectLayerName ) ;
664737
665- if ( typeof layerID === 'string' )
666- {
667- console . warn ( 'Valid objectgroup names:\n\t' + this . getObjectLayerNames ( ) . join ( ',\n\t' ) ) ;
668- }
738+ return results ;
739+ }
669740
670- return null ;
741+ if ( ! Array . isArray ( config ) )
742+ {
743+ config = [ config ] ;
671744 }
672745
673746 var objects = objectLayer . objects ;
674- var sprites = [ ] ;
675747
676- for ( var i = 0 ; i < objects . length ; i ++ )
748+ for ( var c = 0 ; c < config . length ; c ++ )
677749 {
678- var found = false ;
679- var obj = objects [ i ] ;
750+ var singleConfig = config [ c ] ;
751+
752+ var id = GetFastValue ( singleConfig , 'id' , null ) ;
753+ var gid = GetFastValue ( singleConfig , 'gid' , null ) ;
754+ var name = GetFastValue ( singleConfig , 'name' , null ) ;
755+
756+ var obj ;
757+ var toConvert = [ ] ;
680758
681- if ( obj . gid !== undefined && typeof id === 'number' && obj . gid === id ||
682- obj . id !== undefined && typeof id === 'number' && obj . id === id ||
683- obj . name !== undefined && typeof id === 'string' && obj . name === id )
759+ // Sweep to get all the objects we want to convert in this pass
760+ for ( var s = 0 ; s < objects . length ; s ++ )
684761 {
685- found = true ;
762+ obj = objects [ s ] ;
763+
764+ if (
765+ ( id === null && gid === null && name === null ) ||
766+ ( id !== null && obj . id === id ) ||
767+ ( gid !== null && obj . gid === gid ) ||
768+ ( name !== null && obj . name === name )
769+ )
770+ {
771+ toConvert . push ( obj ) ;
772+ }
686773 }
687774
688- if ( found )
775+ // Now let's convert them ...
776+
777+ var classType = GetFastValue ( singleConfig , 'classType' , Sprite ) ;
778+ var scene = GetFastValue ( singleConfig , 'scene' , this . scene ) ;
779+ var container = GetFastValue ( singleConfig , 'container' , null ) ;
780+ var texture = GetFastValue ( singleConfig , 'key' , null ) ;
781+ var frame = GetFastValue ( singleConfig , 'frame' , null ) ;
782+
783+ for ( var i = 0 ; i < toConvert . length ; i ++ )
689784 {
690- var config = Extend ( { } , spriteConfig , obj . properties ) ;
785+ obj = toConvert [ i ] ;
691786
692- config . x = obj . x ;
693- config . y = obj . y ;
787+ var sprite = new classType ( scene ) ;
694788
695- var sprite = scene . make . sprite ( config ) ;
789+ sprite . setName ( obj . name ) ;
790+ sprite . setPosition ( obj . x , obj . y ) ;
791+ sprite . setTexture ( texture , frame ) ;
696792
697- sprite . name = obj . name ;
793+ if ( obj . width )
794+ {
795+ sprite . displayWidth = obj . width ;
796+ }
698797
699- if ( obj . width ) { sprite . displayWidth = obj . width ; }
700- if ( obj . height ) { sprite . displayHeight = obj . height ; }
798+ if ( obj . height )
799+ {
800+ sprite . displayHeight = obj . height ;
801+ }
701802
702- // Origin is (0, 1) in Tiled, so find the offset that matches the Sprite's origin.
703- // Do not offset objects with zero dimensions (e.g. points).
803+ // Origin is (0, 1) in Tiled, so find the offset that matches the Sprites origin.
804+ // Do not offset objects with zero dimensions (e.g. points).
704805 var offset = {
705806 x : sprite . originX * obj . width ,
706807 y : ( sprite . originY - 1 ) * obj . height
707808 } ;
708809
709- // If the object is rotated, then the origin offset also needs to be rotated.
810+ // If the object is rotated, then the origin offset also needs to be rotated.
710811 if ( obj . rotation )
711812 {
712813 var angle = DegToRad ( obj . rotation ) ;
814+
713815 Rotate ( offset , angle ) ;
816+
714817 sprite . rotation = angle ;
715818 }
716819
@@ -722,23 +825,38 @@ var Tilemap = new Class({
722825 sprite . setFlip ( obj . flippedHorizontal , obj . flippedVertical ) ;
723826 }
724827
725- if ( ! obj . visible ) { sprite . visible = false ; }
828+ if ( ! obj . visible )
829+ {
830+ sprite . visible = false ;
831+ }
726832
833+ // Set properties the class may have, or setData those it doesn't
727834 for ( var key in obj . properties )
728835 {
729- if ( sprite . hasOwnProperty ( key ) )
836+ if ( sprite [ key ] !== undefined )
837+ {
838+ sprite [ key ] = obj . properties [ key ] ;
839+ }
840+ else
730841 {
731- continue ;
842+ sprite . setData ( key , obj . properties [ key ] ) ;
732843 }
844+ }
733845
734- sprite . setData ( key , obj . properties [ key ] ) ;
846+ if ( container )
847+ {
848+ container . add ( sprite ) ;
849+ }
850+ else
851+ {
852+ scene . add . existing ( sprite ) ;
735853 }
736854
737- sprites . push ( sprite ) ;
855+ results . push ( sprite ) ;
738856 }
739857 }
740858
741- return sprites ;
859+ return results ;
742860 } ,
743861
744862 /**
0 commit comments