Here’s your license key for TexturePacker:
TP-xxxxxxxxxxxxxxxx
I’ve added a license for PhysicsEditor (see file attached) in case you might want to try it too 😉
Nice blog! I would be happy to get a (short) blog post in return.
In case you do a tutorial post about my tools I can link back to your blog from the tutorials section on my page. That might give you some more visitors on your page!
I sent you a blogger license for TexturePacker some time ago,
and I am curious how you like the program.
Did you get it running successfully? Or do you need some assistance?
I would be happy to get a (short) blog post in return.
package
{
import flash.display.Sprite;
import starling.core.Starling;
[SWF(frameRate="60",Width="800",Height="600")]
public class StarlingTest extends Sprite
{
public function StarlingTest()
{
var star:Starling = new Starling(Main, stage);
star.start();
}
}
}
Main.as
package {
import flash.display.Bitmap;
import starling.core.Starling;
import starling.display.MovieClip;
import starling.display.Sprite;
import starling.events.Touch;
import starling.events.TouchEvent;
import starling.events.TouchPhase;
import starling.textures.Texture;
import starling.textures.TextureAtlas;
public class Main extends Sprite {
[Embed(source = 'test.xml', mimeType = 'application/octet-stream')]
private var AtlasXML:Class;
[Embed(source = 'test.png')]
private var AtlasTexture:Class;
private var mc:AlphaMovieClip ;
public function Main() {
var bitmap:Bitmap = new AtlasTexture();
var texture:Texture = Texture.fromBitmap(bitmap);
var xml:XML = XML(new AtlasXML());
var atlas:TextureAtlas = new TextureAtlas(texture, xml);
mc = new AlphaMovieClip("run",atlas, bitmap.bitmapData,30);
var m2:MovieClip = new MovieClip(atlas.getTextures("run"),30);
m2.loop = false;
m2.x = 200;
mc.addEventListener(TouchEvent.TOUCH, touchEventHandler);
addChild(mc);
addChild(m2);
Starling.juggler.add(mc);
Starling.juggler.add(m2);
}
private function touchEventHandler(event:TouchEvent):void {
var touch:Touch = event.getTouch(this);
if(!touch ) return;
if (touch.phase == TouchPhase.BEGAN){
mc.pause();
}else if(touch.phase == TouchPhase.ENDED){
mc.play();
}
}
}
}
AlphaMovieClip.as
package {
import flash.display.BitmapData;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Dictionary;
import starling.display.DisplayObject;
import starling.display.MovieClip;
import starling.textures.SubTexture;
import starling.textures.Texture;
import starling.textures.TextureAtlas;
public class AlphaMovieClip extends MovieClip
{
private var m_TexturePrefix :String = "";
private var m_TextureAtlas :TextureAtlas = null;
private var m_Textures :Vector. = null;
private var m_TextureInfo :Dictionary = null;
private var m_BitmapData :BitmapData = null;
public function AlphaMovieClip(texturePrefix:String, textureAtlas:TextureAtlas, bitmapData:BitmapData, fps:Number = 12)
{
m_TextureInfo = new Dictionary();
var names:Vector. = textureAtlas.getNames(texturePrefix);
for each (var name:String in names)
{
var textureInfo:Object = { };
textureInfo.name = name;
textureInfo.texture = textureAtlas.getTexture(name);
m_TextureInfo[name] = textureInfo;
}
m_TexturePrefix = texturePrefix;
m_TextureAtlas = textureAtlas;
m_Textures = textureAtlas.getTextures(texturePrefix);
m_BitmapData = bitmapData;
super(m_Textures, fps);
}
override public function hitTest(localPoint:Point, forTouch:Boolean = false):DisplayObject
{
if (forTouch && visible && touchable)
{
if (getBounds(this).containsPoint(localPoint))
{
var texture:Texture = getFrameTexture(currentFrame);
var subtexture:SubTexture = texture as SubTexture;
var textureFrame:Rectangle = subtexture.frame;
var clipping:Rectangle = subtexture.clipping;
var frameBound:Rectangle = new Rectangle(
Math.abs(textureFrame.x),
Math.abs(textureFrame.y),
clipping.width * m_TextureAtlas.texture.width,
clipping.height * m_TextureAtlas.texture.height
);
clipping.x *= m_TextureAtlas.texture.width;
clipping.y *= m_TextureAtlas.texture.height;
var final_x:uint = (frameBound.containsPoint(localPoint) ? localPoint.x - frameBound.x : uint.MAX_VALUE);
var final_y:uint = (frameBound.containsPoint(localPoint) ? localPoint.y - frameBound.y : uint.MAX_VALUE);
if (final_x != uint.MAX_VALUE && final_y != uint.MAX_VALUE)
{
var pixel:uint = m_BitmapData.getPixel32(clipping.x + final_x, clipping.y + final_y);
if (uint((pixel >> 24) & 0xFF) == 0)
{
return null;
}
}
else
{
return null;
}
}
}
return super.hitTest(localPoint, forTouch);
}
}
}
public function Game2() {
addEventListener(Event.ADDED_TO_STAGE, onAdded);
}
private function onAdded (e:Event):void {
// create a Bitmap object out of the embedded image
var sausageBitmap:Bitmap = new Sausage();
// create a Texture object to feed the Image object
var texture:Texture = Texture.fromBitmap(sausageBitmap);
for (var i:int = 0; i < NUM_SAUSAGES; i++) {
// create a Image object with our one texture
var image:Image = new Image(texture);
// set a random alpha, position, rotation
image.alpha = Math.random();
// define a random initial position
image.x = Math.random()*stage.stageWidth
image.y = Math.random()*stage.stageHeight
image.rotation = deg2rad(Math.random()*360);
// show it
addChild(image);
// store references for later
sausagesVector[i] = image;
}
}
}
}[/code]
package {
import flash.display.Bitmap;
import starling.display.Button;
import starling.display.Sprite;
import starling.events.Event;
import starling.textures.Texture;
public class Game extends Sprite {
[Embed(source = "../media/textures/button_up.png")]
private static const Button_UP:Class;
[Embed(source = "../media/textures/button_down.png")]
private static const Button_DOWN:Class;
public function Game() {
addEventListener(Event.ADDED_TO_STAGE, onAdded);
}
private function onAdded (e:Event):void {
// create a Bitmap object out of the embedded image
var buttonSkinUp:Bitmap = new Button_UP();
var buttonSkinDown:Bitmap = new Button_DOWN();
// 創建按鈕
var myButton:Button = new Button(Texture.fromBitmap(buttonSkinUp), "這是按鈕", Texture.fromBitmap(buttonSkinDown));
// 創建Menu容器並把按鈕加上去
var menuContainer:Sprite = new Sprite();
menuContainer.addChild(myButton);
// centers the menu
menuContainer.x = stage.stageWidth - menuContainer.width >> 1;
menuContainer.y = stage.stageHeight - menuContainer.height >> 1;
// show the button
addChild(menuContainer);
}
}
}
public override function hitTest( localPoint:Point, forTouch:Boolean=false ) :DisplayObject
{
// on a touch test, invisible or untouchable objects cause the test to fail
if( forTouch && (!visible || !touchable) )
{
return null;
}
// otherwise, check bounding box of hitArea (which is a Rectangle here)
var result:DisplayObject = null;
if( _hitArea.containsPoint( localPoint ) )
{
result = this;
}
return result;
}
package {
import starling.display.Sprite;
import starling.events.Event;
import starling.text.TextField;
public class Game extends Sprite {
public function Game() {
addEventListener(Event.ADDED_TO_STAGE, onAdded);
}
private function onAdded (e:Event):void {
// create the TextField object
var legend:TextField = new TextField(300, 300, "簡單的文字範例", "Verdana", 38, 0xFFFFFF);
// centers the text on stage
legend.x = stage.stageWidth - legend.width >> 1;
legend.y = stage.stageHeight - legend.height >> 1;
// show it
addChild(legend);
}
}
}
Standard TrueType fonts:也就是一般內嵌字型的方式,將.ttf的文字檔案直接用embed的方式嵌入swf裡。
下面是一個簡單的範例:
package {
import flash.text.Font;
import starling.display.Sprite;
import starling.events.Event;
import starling.text.TextField;
public class Game extends Sprite {
[Embed(source='/../media/fonts/Abduction.ttf', embedAsCFF='false', fontName='Abduction')]
public static var Abduction:Class;
public function Game() {
addEventListener(Event.ADDED_TO_STAGE, onAdded);
}
private function onAdded (e:Event):void {
// create the font
var font:Font = new Abduction();
// create the TextField object
var legend:TextField = new TextField(300, 300, "使用內嵌字型的簡單範例!", font.fontName, 38, 0xFFFFFF);
// centers the text on stage
legend.x = stage.stageWidth - legend.width >> 1; legend.y = stage.stageHeight - legend.height >> 1;
// show it
addChild(legend);
}
}
}

Bitmap fonts:If you need speed or fancy font effects, use a bitmap font instead. That is a font that has its glyphs rendered to a texture atlas. To use it, first register the font with the method registerBitmapFont, and then pass the font name to the corresponding property of the text field.
一個使用Bitmap來當作字型檔案的簡單範例如下:
字型檔案下載:fontRegular
package
{
import flash.display.Bitmap;
import starling.display.Sprite;
import starling.events.Event;
import starling.text.BitmapFont;
import starling.text.TextField;
import starling.textures.Texture;
import starling.utils.Color;
public class Game extends Sprite {
[Embed(source = "../media/fonts/fontRegular.png")]
private static const BitmapChars:Class;
[Embed(source="../media/fonts/fontRegular.fnt", mimeType="application/octet-stream")]
private static const BritannicXML:Class;
public function Game() {
addEventListener(Event.ADDED_TO_STAGE, onAdded);
}
private function onAdded (e:Event):void {
// creates the embedded bitmap (spritesheet file)
var bitmap:Bitmap = new BitmapChars();
// creates a texture out of it
var texture:Texture = Texture.fromBitmap(bitmap);
// create the XML file describing the glyphes position on the spritesheet
var xml:XML = XML(new BritannicXML());
// register the bitmap font to make it available to TextField
TextField.registerBitmapFont(new BitmapFont(texture, xml));
// create the TextField object
var bmpFontTF:TextField = new TextField(400, 400, "使用內嵌字型的簡單範例!", "BritannicBold", 10);
// the native bitmap font size, no scaling
bmpFontTF.fontSize = BitmapFont.NATIVE_SIZE;
// use white to use the texture as it is (no tinting)
bmpFontTF.color = Color.WHITE;
// centers the text on stage
bmpFontTF.x = stage.stageWidth - bmpFontTF.width >> 1;
bmpFontTF.y = stage.stageHeight - bmpFontTF.height >> 1;
// show it
addChild(bmpFontTF);
}
}
}
//要實作要如何利用Stage3D來產生畫面的方式
function render(support:RenderSupport, parentAlpha:Number):void;
//實作物件碰撞偵測的方式
function getBounds(targetSpace:DisplayObject, resultRect:Rectangle=null):Rectangle
Starling物件有它主場景物件Stage,也就是上圖的Starling.display.Stage,它和flash裡的Stage一樣,是放所有物件的母容器(The Starling stage object, which is the root of the display tree that is rendered)。
Stage3D會依發佈平台的不同而使用不一樣的GPU運算引擎,例如在mac電腦上所使用的是OpenGL,而在Windows則會視電腦所使用的硬體設備去選擇所使用的基礎技術。值得一提的是,即使遇到不支援的硬體,Stage3D仍然可以使用軟件模式去做3D運算,只是會變得十分的緩慢。這邊有一個簡單的性能比較:Stage3D vs WebGL 性能較量
package
{
import flash.display.Sprite;
import starling.core.Starling;
[SWF(frameRate="60",Width="800",Height="600")]
public class StarlingTest extends Sprite
{
public function StarlingTest()
{
var star:Starling = new Starling(Main, stage);
star.start();
}
}
}
Main.as
package
{
import starling.core.Starling;
import starling.display.MovieClip;
import starling.display.Sprite;
import starling.textures.Texture;
import starling.textures.TextureAtlas;
public class Main extends Sprite
{
[Embed(source = 'test.xml', mimeType = 'application/octet-stream')]
private var AtlasXML:Class;
[Embed(source = 'test.png')]
private var AtlasTexture:Class;
public function Main()
{
var texture:Texture = Texture.fromBitmap(new AtlasTexture());
var xml:XML = XML(new AtlasXML());
var atlas:TextureAtlas = new TextureAtlas(texture, xml);
var mc:MovieClip = new MovieClip(atlas.getTextures("run"),30);
addChild(mc);
Starling.juggler.add(mc);
}
}
}
var textInput:flash.text.TextField = new flash.text.TextField();
textInput.type = TextFieldType.INPUT;
Starling.current.nativeOverlay.addChild(textInput);
因為starling的textField本身是不能直接設定為可打字的,因此如果想要在場景上加一個可輸入文字的文字欄位,這邊有很詳細的方法介紹:Text Input with Starling framework。
不過要注意,使用nativeOverlay所加進場景裡的物件,也是永遠會在最上層。下面是官網對於Native overlay的說明:
Sometimes you will want to display native Flash content on top of Starling. That’s what the nativeOverlay property is for. It returns a Flash Sprite lying directly on top of the Starling content. You can add conventional Flash objects to that overlay.
Beware, though, that conventional Flash content on top of 3D content can lead to performance penalties on some (mobile) platforms. For that reason, always remove all child objects from the overlay when you don’t need them any longer. Starling will remove the overlay from the display list when it’s empty.