Starling API – 17 – Création des éléments du décor avec BlockFactory, TerrainFactory et EnemyFactory
Dans le monde que l'on va créer, on va avoir des blocks, de plusieurs couleurs, de plusieurs tailles et plus ou moins résistants. Pour faire simple, j'ai repris les SpriteSheet d'un célèbre jeu par dessus laquelle j'ai "calqué" les formes. Les transparences (80/60/40%) représentent l'état de destruction du bloc:
Du coup, je peux profiter de leur Atlas de Texture. Sauf que dans leur cas, l'atlas est au format JSON et pas au format XML:
http://www.flex-tutorial.fr/wp-content/uploads/aquarium/r/blocks.json
Création d'un parser d'Atlas JSON
C'est pas grave, on va créer la classe TextureAtlasJSON, qui reprend les méthodes de TextureAtlas, adaptées pour du JSON:
package utils
{
import flash.geom.Rectangle;
import flash.utils.Dictionary;
import starling.textures.Texture;
public class TextureAtlasJSON
{
private var _atlasTexture:Texture;
private var _textureRegions:Dictionary;
private var _textureFrames:Dictionary;
public function TextureAtlasJSON(texture:Texture, atlas:Object = null)
{
_textureRegions = new Dictionary();
_textureFrames = new Dictionary();
_atlasTexture = texture;
if (atlas){
parseAtlas(atlas);
}
}
/** Disposes the atlas texture. */
public function dispose():void
{
_atlasTexture.dispose();
}
private function parseAtlas(atlas:Object):void
{
for (var key:String in atlas){
var subTexture:Object = atlas[key];
if (subTexture.hasOwnProperty("id")){
var name:String = subTexture.id;
var x:Number = parseFloat(subTexture.x);
var y:Number = parseFloat(subTexture.y);
var width:Number = parseFloat(subTexture.width);
var height:Number = parseFloat(subTexture.height);
var frameX:Number = parseFloat(subTexture.frameX);
var frameY:Number = parseFloat(subTexture.frameY);
var frameWidth:Number = parseFloat(subTexture.frameWidth);
var frameHeight:Number = parseFloat(subTexture.frameHeight);
var region:Rectangle = new Rectangle(x, y, width, height);
var frame:Rectangle = frameWidth > 0 && frameHeight > 0 ?
new Rectangle(frameX, frameY, frameWidth, frameHeight) : null;
addRegion(name, region, frame);
}
}
}
/** Retrieves a subtexture by name. Returns <code>null</code> if it is not found. */
public function getTexture(name:String):Texture
{
var region:Rectangle = _textureRegions[name];
if (region == null) return null;
else
{
var texture:Texture = Texture.fromTexture(_atlasTexture, region);
texture.frame = _textureFrames[name];
return texture;
}
}
/** Returns all textures that start with a certain string, sorted alphabetically
* (especially useful for "MovieClip"). */
public function getTextures(prefix:String=""):Vector.<Texture>
{
var textures:Vector.<Texture> = new <Texture>[];
var names:Vector.<String> = new <String>[];
var name:String;
for (name in _textureRegions)
if (name.indexOf(prefix) == 0)
names.push(name);
names.sort(Array.CASEINSENSITIVE);
for each (name in names)
textures.push(getTexture(name));
return textures;
}
/** Creates a region for a subtexture and gives it a name. */
public function addRegion(name:String, region:Rectangle, frame:Rectangle=null):void
{
_textureRegions[name] = region;
if (frame) _textureFrames[name] = frame;
}
/** Removes a region with a certain name. */
public function removeRegion(name:String):void
{
delete _textureRegions[name];
}
}
}
Création de la BlockFactory
Vous avez l'habitude, on va maintenant, on va créer une Factory qui va nous retourner nos blocks. ceux-ci sont en fait des MovieClip à plusieurs Textures.
package com.fnicollet {
import flash.display.Bitmap;
import starling.display.Image;
import starling.display.MovieClip;
import starling.textures.Texture;
import utils.TextureAtlasJSON;
public class BlockFactory {
[Embed(source = "/assets/atlas/blocks.json", mimeType = "application/octet-stream")]
public static const SpriteSheet:Class;
[Embed(source = "/assets/spritesheet/blocks.png")]
private static const imageSpriteSheet:Class;
private static var bitmap:Bitmap = Bitmap(new imageSpriteSheet());
private static var _textureAtlas:TextureAtlasJSON = null;
public function BlockFactory() {
}
public static function get(id:String):MovieClip {
if (!_textureAtlas) {
_textureAtlas = new TextureAtlasJSON(Texture.fromBitmap(bitmap), JSON.parse(new SpriteSheet()));
}
var textures:Vector.<Texture> = _textureAtlas.getTextures(id + "_");
if (!textures || textures.length < 1) {
return null;
}
var ret:MovieClip = new MovieClip(textures);
ret.pivotX = ret.width >> 1;
ret.pivotY = ret.height >> 1;
ret.scaleX = ret.scaleY = 0.61;
return ret;
}
}
}
Création de TerrainFactory
On va faire exactement la même chose avec TerrainFactory:
décrit pas la SpriteSheet suivante:
http://www.flex-tutorial.fr/wp-content/uploads/aquarium/r/terrain.json
Pour le code de la Factory, c'est le même que celui de la BlockFactory mais avec une spritesheet et un atlas différent, je ne vous le répète pas.
Création de la EnemyFactory
Rebelotte
avec:
http://www.flex-tutorial.fr/wp-content/uploads/aquarium/r/enemies.json
Conclusion
Bon, ce billet ne servait pas à grand chose, à part vérifier que vous avez bien suivi ce que l'on a dit plus tôt avec les Factory
. Dans le prochain billet, on va construire automatiquement le niveau grâce à une description JSON de celui-ci. Vous verrez que grâce à nos Factory, le code sera très lisible.
Articles similaires
- Starling API – 4 – Créer une animation simple avec MovieClip
- Starling API – 8 – Créer un personnage avec plusieurs états
- Starling API – 12 – Détecter la collision entre 2 MovieClip
- Starling API – 10 – Afficher des bonus de manière aléatoire
- Starling API – 6 – Animer des propriétés avec Tween (déplacement, rotation, …)








