Starling的Display Objects介紹(二)

上一篇:Starling的Display Objects介紹(一)
下一篇:Starling的Display Objects介紹(三)

這篇會介紹下圖裡的starling.text.TextField
class_hierarchy

TextField物件介紹

官方手冊請見此:http://doc.starling-framework.org/core/starling/text/TextField.html

下面是一個最簡單的使用範例:

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);
		}
	}
}

內嵌字型方式比較

在Starling裡的TextField可以用兩種方式去嵌入特殊字型,如下圖所示:
2014-01-17_153055
從上圖我們可以發現,原始的字體嵌入方式,在1到2的部份,將字型從ttf裡抽取出來壓成Bitmap Snapshot,這部份會需要使用到CPU來做運算。因為會多一個程序,在效能上,會比右邊的方式慢一些。Bitmap Font則是使用一份字型列表的圖檔(如下圖),去比對xml的字型資訊檔,它完全只會用到GPU的運算,在效能上優於傳統字體嵌入的方式。
fontRegular字型範例下載:fontRegular

但是若我們要求字體在各種解析度都要能夠有很高的解析,由於原始的字型嵌入方式是即時將字型轉換成Bitmap圖檔,在各種大小都可以有良好的表現。而若我們想要使用不同大小的Bitmap字型,則需要在產生文字圖檔時就決定要使用那些大小的字型,而不能在執行時才決定要顯示的文字大小為何。

在下面的Bitmap Font產生工具裡都可以有設定的選項,包括要使用那些文字、字體、等等…,以及字型要叫什麼都可以在產生時設定好。

Bitmap Font產生工具

這邊有幾個可以產生Bitmap文字圖檔及.fnt檔案的工具:

  1. Glyph Designer(適用於Mac)
    螢幕快照 2014-02-07 下午9.58.42
  2. BMFont(適用於Windows)
    螢幕快照 2014-02-07 下午9.59.34

內嵌字型實作範例

下面我們簡介一下這兩種方式的實作方式:

  1. 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);
    		}
    	}
    }
    
  2. 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);
    		}
    	}
    }

參考資料

  1. The Starling Manual » Displaying Text
  2. TextField API
  3. Starting with Starling – Ep 10: Text and Fonts

Starling的Display Objects介紹(一)

上一篇:Starling Framework簡介
下一篇:Starling的Display Objects介紹(二)

Starling framework啟動方式

所有使用Starling framework的應用程式的起始點,都是由一個Starling物件,來創建整個Starling世界(Starling物件說明可見此:Starling),下面是一個最簡單的範例:

package{
    import starling.core.Starling;
    import starling.display.Sprite;

    [SWF(width="1280", height="752", frameRate="60", backgroundColor="#000000")]
    public class Startup extends Sprite
    {
        private var mStarling:Starling;
        public function Startup() {
            // 建立Starling物件
            mStarling = new Starling(Game, stage);
            // start it!
            mStarling.start();
        }
    }
}

Starling世界的物件樹

官方的說明文件裡可以看到在Starling裡,畫面物件的繼承樹是長這樣的:
class_hierarchy
從上圖可看出在Starling裡面,DisplayObject是一切畫面物件的祖先,繼承於EventDispatcher。

DisplayObject物件介紹

官方手冊請見此:http://doc.starling-framework.org/core/starling/display/DisplayObject.html

這是所有物件樹的根物件,他的子孫包含像Quad、Image、MovieClip,這一邊是在做動畫影片的。另一邊像是DisplayObjectContainer則是放物件的容器,顧名思義,它可以再加入其他的DisplayObject在裡面。反向來說,在Starling世界裡面的MovieClip,是沒有辦法使用addChild的,它只能像是一個動畫影片一樣的單純被播放、控制位置、旋轉、或偵測碰撞,而無法在MovieClip裡面加入其他的MovieClip

在Starling的DisplayObject其實只是一個abstract class,他沒有辦法被直接new出來,一定要被繼承並實作這兩個方法:

//要實作要如何利用Stage3D來產生畫面的方式
function render(support:RenderSupport, parentAlpha:Number):void;
//實作物件碰撞偵測的方式
function getBounds(targetSpace:DisplayObject, resultRect:Rectangle=null):Rectangle

從上面的繼承樹我們可以發現MovieClip與DisplayObjectContainer是採用不一樣的碰撞偵測方法以及圖形render方式的。

在Starling裡的DisplayObject則有偵測多點觸控,以及設定物件坐標、及與不同層DisplayObjectContent的坐標轉換功能。

Stage物件介紹

官方手冊請見此:http://doc.starling-framework.org/core/starling/display/Stage.html

Starling物件有它主場景物件Stage,也就是上圖的Starling.display.Stage,它和flash裡的Stage一樣,是放所有物件的母容器(The Starling stage object, which is the root of the display tree that is rendered)。

這個物件裡面只能夠有繼承於starling.display.DisplayObject的物件,而無法包含任何flash.display.DisplayObject相關的物件,這兩種類別是完全不能兼容的。雖然在Starling裡面,可以用

Starling.current.nativeOverlay.addChild(textInput);

來加入原生flash物件,但就如我前一篇簡介所說,其實他也只是會取得flash.display.Stage的物件把元件放到裡面而已,它永遠都會被放在畫面的最上層。
螢幕快照 2014-02-01 下午11.45.51

Stage會在創建Starling物件時被自動創建,所以不用自己去建立它。

參考資料

  1. The Starling Manual > Display Objects
  2. Display Object API
  3. Juggler API
  4. Starling API

Starling Framework簡介

下一篇:Starling的Display Objects介紹(一)

Starling的技術基礎

Starling是基於Stage3D來實作的,因此在學習Starling之前,我建議應該要對Stage3D的特性有基礎的了解。有關於Stage3D的介紹可以看這篇文章:Stage3D運作原理。在這篇文章裡,我們可以知道Stage3D比起OpenGL及DirectX等傳統3D的APIs的優勢與劣勢。

Stage3D會依發佈平台的不同而使用不一樣的GPU運算引擎,例如在mac電腦上所使用的是OpenGL,而在Windows則會視電腦所使用的硬體設備去選擇所使用的基礎技術。值得一提的是,即使遇到不支援的硬體,Stage3D仍然可以使用軟件模式去做3D運算,只是會變得十分的緩慢。這邊有一個簡單的性能比較:Stage3D vs WebGL 性能較量

下圖是Starling的技術基礎示意圖:

image

Starling運作模式

過去我們很容易因為Stage3D這個名字而誤會這是專門為3D而做的引擎,而不能使用在2D的技術上。3D引擎的運算與2D運算最大的差異點,在於3D畫面是由一個個三角型為基礎,去建構整個畫面。而2D的向量圖形,則是由多個頂點組合而成的複雜多邊型。

要將3D的技術使用在2D上,便是將圖片整理成png或jpg等圖片,然後將圖片視為兩個三角型去繪製物件,再加上貼材質的方式,將人物的圖片貼至範圍裡。這樣便可以利用GPU去執行它最擅長的三角型繪製以及材質貼圖的動作。

 

螢幕快照 2014-02-01 下午11.37.51

Starling簡單範例

這是一個最簡單的Starling Sample:StarlingTest
StarlingTest.as

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);
		}
	}
}

全新的影格運作方式

從上面的Code來看,Flash programmer似乎會覺得好像和原本的程式幾乎一模一樣,其實這是Staring刻意希望讓程式師可以無痛學習Starling,刻意去這樣設計的。在很像的外表下,若我們使用Starling去建置我們的flash程式,不論在影格、圖形渲染方式、碰撞偵測方式、事件傳遞方式等。其實與原生程式,在根本上是完全不一樣的東西。也因為在基本概念上就有很大的不同(starling是以3D去模擬2D的環境,而原有的Flash則是完全使用CPU去做畫面的運算)。我建議所有Flash的開發者還是要以全新的角度去學習這套framework,並且要了解其根本的運作原理,這樣在操作上才不會被它與原生語言的不同之處搞混淆。

因此我們要知道,上面範例裡面的starling.display.MovieClip與原生的flash.display.MovieClip在本質上便已經是完全不同的東西了。在表現的圖層上也並不相同,下圖是圖層的示意圖:
螢幕快照 2014-02-01 下午11.45.51
從上圖可以看到,所有原來我們用flash.display.*去產生的畫面,一律會被放在最上面那層的『Display List』,而所有stage3D(在這裡也就是Starling)的物件則會放在它下面。另外StageVideo則是可以使用GPU去播放的影片,則會放在最下面一層。

這也可以看出,若是想要採用starling去開發你的應用程式,不太可能混合starling和原生的flash DisplayObject一起使用,因為原生的flash所產生的畫面會永遠的被放在starling之上(請見註一)。另外,若是使用starling,在嵌入swf至網頁時,一定要將wmode設成direct,starling不支援透明的嵌入方式,否則會跳出如下圖的錯誤訊息。

螢幕快照 2014-02-07 下午2.42.20

另外,雖然Starling很多類別的名稱或屬性都很相似,或者一樣,但用法其實也是有很大的不同。這邊是Starling的API手冊:Starling Framework Reference

註一:
我們可以利用nativeOverlay將原生的flash的displayObject放到starling的場景上。
請見下面的範例,下面範例是如何在starling裡加入可打字的文字框的方式。

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.

參考資料

Stage3D運作原理

本文為此文章的中文重點翻譯:How Stage3D works

3D技術的突破

在過去幾年中,開發人員已經用FLASH創造了許多3D工具,如Papervision3D,Away3D和Alternativa3D,以及所有類似的3D引擎,顯示Flash對即時3D渲染的強烈需求。

過去Flash 3D的渲染是在不使用3D硬件加速的情況下進行的。 事實上,所有在Flash Player 11之前版本的3D渲染是依靠CPU的完成,我稱之為軟件模式(software mode)。 軟件模式是緩慢的,不能用來呈現細緻的3D場景。 到目前為止,軟件模式不能渲染出我們今天3D遊戲中常見的高級的圖形效果。

隨著Flash Player 11的發布,新的可能性已被實現。 開發人員可以利用3D硬件(顯卡)加速,而不是僅僅依靠計算機的CPU渲染。在新的渲染模式中Flash可以使用一個被稱為圖形處理單元(GPU)的副處理器。 GPU是設計完全用來圖形渲染的物理硬件。Stage3D API的公佈對Flash開發者是一個重大的事件。 在Flash中使用3D加速,使許多以前不能實現的Flash遊戲和Flash應用成為可能。

回顧過往,硬件加速的來到,永遠改變了世界上3D編碼方式。 遊戲質量和複雜性成倍增加。 硬件加速使得3D遊戲畫面渲染能力大大提高,迅速的渲染複雜的模型,逼真的效果,低延遲的遊戲體驗都成為可能。

使用3D硬件加速(hardware acceleration)

3D硬件加速利用現代普通PC就包含的GPU進行渲染。 GPU完全致力於圖形渲染和呈現3D內容的任務。通過這種方法,各類軟件以及你的Flash應用程序,只需要定義一個3D場景。 通過將3D場景定義數據送到GPU,GPU就能渲染出指定場景。 這個過程比使用軟件模式(software mode)通過CPU渲染3D內容快得多。

下面我們將花點時間比較軟件模式(software mode)和硬件模式(hardware mode)渲染的差異。

一般來說3D場景定義為一組3D幾何形狀或稱網格(meshes)。 每個幾何形狀又是一組三角形,對於每個三角形,又是一個由3個頂點組成的集合。 因此,一個3D場景只需要定義一個頂點集和一些相關的渲染信息,例如紋理或頂點著色。當您使用以前的軟件模式(software mode)時,3D引擎(如Away3D)就會收到這個頂點流。 它會計算三角形的屏幕位置,然後逐個通過一些填充操作(drawTriangles(),fill()) 驅動Flash Player在舞台上顯示這些三角形。即使3D引擎編碼優秀,這個過程仍然是極其緩慢的。 在某些情況下渲染的結果還不是特別準確。 3D內容顯現是按每個三角形為最小單位,而不是每個像素。 這將引起深度排序錯誤。 渲染後的三角形有時會出現在錯誤的地方或在錯誤的深度上。

在可接受的腳本運行幀數下,Flash Player 10軟件模式(software mode)通常呈現最多4000三角形的場景。

使用最新的Stage3D API後。 在3D硬件加速下開發者只需定義幾何形狀,然後將數據傳遞到GPU。 幾何形狀將到上載到GPU顯存(這片數據記憶空間充當GPU數據存儲空間)。 GPU將處理接收到的數據,完成渲染3D內容的整個工作。

由於只需要將渲染參數上載到GPU,基於此的應用將變得更有效。 例如:程序只需要在三維場景中指定觀測點(3D場景中攝像機位置),設置場景中的燈光位置以及其他影響3D呈現對象的細節。接收上載數據後, 它通過從分析頂點流開始,開始一個接一個渲染(由頂點流描述)三角形。 GPU將渲染最終在用戶屏幕上顯示的圖像,這一切步驟都是封閉在顯卡物理硬件內部完成的。

GPU的渲染速度遠遠高於CPU的軟件模式(software mode)。 這是因為GPU設計的重點著眼於一個非常具體的任務:計算頂點集和渲染由頂點集合所表述的三角形。由於這是一個非常具體的任務,3D硬件渲染過程是非常高效迅速的。相比之下CPU是通用處理器。 它不對呈現三角形的具體任務進行優化。因此軟件模式要低效的多。

通過統計對比,使用硬件加速渲染包含幾百萬個三角形的情況並不在少數。 相比在軟件模式(software mode)下提供的4000個三角形可是一個顯著的改善

3D rendering pipeline

3D rendering pipeline的作用是將渲染操作轉化為一組基本數據操作。GPU邏輯上由許多功能明確的功能區塊組成,每一塊對應著某種基本數據操作。在一條流水線中,這些區塊設置為一連續的操作,也就是說上一個區塊的輸出結果作為下一個區塊的輸入。最簡單的3D圖形渲染管線被叫做固定功能管線。稱之為固定是有原因的,因為該管線是不可不可編碼的,固定管線所以顯得有些僵化,因為它只是把輸入的形狀數據經過管線(一系列級聯的區塊)處理後成為用來顯示的最終圖像。

螢幕快照 2014-01-30 下午1.03.12

固定功能管線以以下參數作為輸入:幾何描述(頂點集合和三角形)、幾何形狀所應用的紋理數據、3D場景的幾何結構位置和方向,攝像機的位置和方向,光線數據(每組光線的顏色、位置、強度等等數據),和一些設置管線如何渲染呈現的額外參數。換句話說,你只要提供頂點集合、三角形、紋理數據,硬件就可以完成渲染。固定功能管線通過一個坐標變換和光照區塊(transform and lighting),把頂點集合從模型(model)本地坐標轉換為屏幕舞台坐標。這個區塊也負責處理頂點照明,緊接著的區塊是視角剪裁區塊(viewport clipping),主要負責對上一個區塊處理後場景數據進行剪裁(關係到是否參與此區塊以後的渲染和是否在可見等)以符合實際顯示視角的需要。

這部份的3D運算原理的詳細說明,可看這篇文章:初探Stage3D(一) 3D渲染基礎原理

經過處理和剪裁場景數據將送入下一個被稱為光柵器(rasterizer)的區塊,這個區塊除了執行紋理映射(texture mapping),也對模型進行霧化,透明通道混合效果和以深度排序的順序呈現三角形像素所需的深度緩衝測試。固定功能管線已經應用多年,但隨著時間的推移渲染過程僵化的缺點就暴露出來。 特別是關於光照的處理,渲染被限制使用標準著色器模型,如基本Goraud和Phong著色模型。 固定功能管線不夠靈活以至於開發人員不能添加更多創造性和有趣的效果, 在管線的渲染下大多數產品效果看上去是相似的。

隨著技術發展,可編碼圖形渲染管線被開發出來,下面是可編碼圖形渲染管線的邏輯流程圖:

螢幕快照 2014-01-30 下午1.03.21
頂點著色器(Vertex Shader)和片段著色器(Fragment Shader)的引入帶來了巨大的變革。當你使用可編碼渲染管線時,開發者可以寫一些被稱之為著色器(Shaders)的代碼片段,這些代碼片段將會影響管線中的渲染過程。

著色器的應用這一看似小小的改變,使得3D渲染髮生了天翻地覆的變化,通過編寫影響頂點轉換和修改的頂點著色器(Vertex Shaders)和填充三角形每個像素呈現的片段著色器(Fragment Shaders),我們將有能力創造之前無法體驗的美妙效果。例如:使用著色器你運用各種光照手段甚至自定義有特性的應用,而不是使用預設的管線照明模型。 著色器使模型陰影成為可能,並加速了骨骼系統,很酷的效果也變得司空見慣了。

使用Stage3D的優勢

開始創建一個基於DirectX和OpenGL的3D應用程序不是一件容易的事。 的確渲染一個簡單的三角形是十分容易的,但使用C++編寫一個成熟的3D應用程序則需要相當的技巧。 對於經驗尚淺的程序員來說無疑是很艱巨的任務。創建一個本地3D應用程序的困難之一是使用標準的DirectX和OpenGL API。為了保證利用圖形硬件的全部能力,項目必須支持全部硬件特性的選項。

原生API是專門針對硬件的。項目的開發工作不得不包括對特定GPU性能的優化(如同現在的遊戲開發商要同時支持nVIDIA和ATI顯卡一樣).通過大量的調整代碼,使項目能夠充分發揮硬件的強大能力。這對開發者是很有誘惑的,因為你將憑藉最強大的硬件創造最絢麗的特效.但同時這也意味著,應用程序必須進行調整和測試以適應不同的硬件。

在使用Stage3D工作時情況並非如此。開發者只需面向Stage3D對象如Context3D和Program3D編程,你創建的應用程序將運行在每一個支持Flash Player或AIR的平台上。

在某種程度上,Stage3D比原生API更抽象也離特定硬件更遙遠一點。 因此Stage3D更容易使用,這一點當然也是能算是一種缺點,為了多平台性,Stage3D不得不放棄針對特定硬件編碼。這樣做的一大好處是:使用Stage3D可以用同一個應用程序把3D硬件加速和功能強大且易用的普通2D FLASH創作結合起來.

一個基於原生API的3D應用,2D UI往往需要定製的解決方案,很少有像FLASH這般靈活的創作工具。在新API下,原先的2D顯示對象和Stage3D對象可以共存。 所以你會保留所有Flash的優點同時你也可以使用經過3D渲染的內容。 開發者可以選擇創建一個由3D場景作為背景的應用,也可以將3D對象嵌入往常的2D內容中

Stage3D應用可以運行在多種平台。 Stage3D也被應用於AIR應用程序中就像由Flash Player運行一樣。此功能意味著開發者可以使用Stage3D創建桌面3D應用程序(AIR)就像開發標準3D的PC遊戲一樣。 在iOS和Android移動平台上亦可使用相同的代碼。

認識Stage3D的限制

主要缺點是針對多平台開發應用程序的能力。 由於使用一個統一的基於多平台API,Stage3D無法應用當下最先進的3D圖形渲染特性。為了確保應用程序可跨多平台,Stage3D必須針對一個抽象的3D硬件設備操作,而為了面面俱到這個抽象層硬件僅僅包含所有硬件圖形特性的公共部分。例如:現代GPU支持Shader Model(頂點和片段著色器使用的標準)4.0版。 然而Stage3D僅僅支持Shader Model 2.0版本。

這代表當我們使用Stage3D編碼時將會遇到一些限制,各個不同的GPU可能有其擅長的優勢,這些將不會被使用到。 例如: AGAL可以使用的著色寄存器將相當有限。 您可以使用最多8個臨時寄存器,而基於Shader Model 4.0的GLSL最多可使用的寄存器為4096個。

Stage3D著色器代碼長度只能包含最多200操作碼,而Shader Model 4.0支持4096個。又如 Shader Model3.0和4.0支持循環和條件語義,而Stage3D不支持。換句話說,Stage3D著色器代碼設計的將是比較簡單的程序,而不是面向更先進的硬件和Shader Model的編碼。 因此在今天的AAA遊戲中使用的著色器代碼和一些高級效果可能無法應用於Stage3D。

另外Stage3D的技術在下面這些平台上可能無法正常運作:Stage3D unsupported chipsets, drivers | Flash Player 11, AIR 3

Stage3D:舞台背後的「舞台」

螢幕快照 2014-01-30 下午10.41.32

一組Stage3D舞台位於主Flash舞台後面。 這意味著每個Stage3D創建3D內容分別呈現在各自的Stage3D的矩形視野中,而普通2D 顯示對象都呈現在3D內容上面。 你可以試想如何兩全其美:你應用3D場景渲染使用硬件加速,而2D的顯示對象在最上面(如遊戲UI)。 UI可以使用強大的FLASH直接創建,而不是一些特殊定製的UI創建工具。

開發者可以使用多個Stage3D. 每個Stage3D擁有自己的矩形視界(簡單說就是width,height和x,y)。這意味著你可以在屏幕一部分區域添加一個Stage3D,然後在另一個地方添加另一個,最後傳統的2D顯示對象顯示在最上層。 每一個Stage3D和StageVideo層可以部分(甚至完全)重疊。 然而現在我們的Stage3D版本不支持層與層之間的混合模式。 因此上層的Stage3D覆蓋下層的Stage3D,你只能夠看到頂層和下面一層的未被遮擋部分內容。

參考文章

  1. Stage3D vs WebGL 性能較量
  2. 初探Stage3D(一) 3D渲染基礎原理
  3. Stage3D unsupported chipsets, drivers | Flash Player 11, AIR 3
  4. How Stage3D works

套件管理工具CocoaPods介紹

這是1/9的cocoaHeads裡,SuperBil分享的套件管理工具。
之前小岡也有和我推薦過這個工具,當時沒有去深入研究如何使用。
這次與會完後,便開始試著學習使用這個管理套件。(裝完後心得:天呀!實在太好用了!必裝~)

分享資料

投影片:做自己的可可豆夾
錄影檔:CocoaPods

CocoaPods介紹

CocoaPods是一個管理套件的工具。

過去在開發app時,如果我們想要用一些第三方的Library,通常會要到GitHub下載專案到本地端,然後把它載入專案裡。這樣如果套件有更新時,都要手動更新,若是不同版本的ios要用到不同的library,又要手動去管理,會比較麻煩。

並且如果是直接把原始碼放到專案裡,會很容易和自己寫的code混在一起,管理和瀏覽都會較為困難。

CocoaPods就是用來管理這些第三方套件,使用CocoaPods之後,專案會變這樣:

螢幕快照 2014-01-12 下午4.48.50
要改成點選GourmentGroup.xcworkspace開啟專案
螢幕快照 2014-01-12 下午4.44.44
下方會多一個Pods的套件資料,裡面放的是所有使用到的套件

 安裝方法

這篇文章有非常詳細的方法:CocoaPods

比較要注意的是,我今天在安裝時,因為Podfile檔案所使用的編碼錯誤,會出現如下錯誤
incompatible character encodings: ASCII-8BIT and UTF-8 cocoaPods
後來我雖然把檔案改成utf-8,還是一直跑出同樣的錯誤。
後來才發現,如果有錯誤,要先把終端機關掉再打開,才會再一次執行。

接下來,如果要更新Podfile,到終端機打入
$pod update
就可以了!

投影片另外有講到podSpec,如果有在cocoaPods裡面沒有包含的Library
(現有的Library可到http://cocoapods.org/去輸入函式庫的名稱找有沒有現有的)
如果沒有的話(或者是自己製作的Library),就可以自己去寫spec
這邊有教學:Specs and the Specs Repo

參考資料

AutoLayout介紹

投影片分享

過去的作法…

  1. 使⽤用frame和bounds去決定物件的位置和⼤小。
  2. 使用autosizing masks
    1. 設定當畫⾯面⼤大⼩小變動時,要固定 那些值(struts)。
    2. 在view的⼤大⼩小改變時,可以偵測 super view的⼤大⼩小改變去改變物 件的寬和⾼高的值(springs)。

AUTOLAYOUT和AUTORESIZING MASK的區別

Autoresizing Mask是AutoLayout的⼦子集。 AutoLayout更多的功能

    1. 指定任意兩個view的相對位置
    2. 可指定⾮非相等約束(⼤大於或者⼩小於等)
    3. 可以設定約束的優先級

WHAT IS AUTO LAYOUT

一種基於約束的,描述性的佈局系統。 Auto Layout Is a Constraint-Based, Descriptive Layout System.

      • 基於約束 – 以所謂相對位置的約束來定義的
      • 描述性 – 使⽤用接近⾃自然語⾔言的⽅方法來進⾏行描 述
      • 佈局系統 – 設計界⾯面的各個元素的位置。

使⽤用約束條件來描述佈局,view的frame會依據這 些約束來進⾏行計算。
Describe the layout with constraints, and frames are calculated automatically.

影片分享

在Windows下產生.p12及.mobileprovision

在 Windows 產生憑證簽名要求

對 Windows 開發人員而言,最簡單的方法是取得 Mac 電腦上的 iPhone 開發人員憑證。不過,他們也可以在 Windows 電腦上取得憑證。首先,使用 OpenSSL 建立憑證簽名要求 (CSR 檔):

  1. 在 Windows 電腦上安裝 OpenSSL (移至http://www.openssl.org/related/binaries.html,或直接在此下載openssl-0.9.8k_X64)。
    開啟 Windows 命令工作階段,然後使用 CD 命令切換至 OpenSSL bin 目錄 (例如 c:\OpenSSL\bin\)。在命令列輸入以下命令以建立專用密鑰:
    openssl genrsa -out mykey.key 2048
    儲存此專用密鑰。您稍後將會用到它。使用 OpenSSL 時,請勿忽略錯誤訊息。OpenSSL 即使產生錯誤訊息,可能仍會輸出檔案。但這些檔案可能無法使用。如果發生錯誤,請檢查您的語法並重新執行命令。
  2. 在命令列輸入以下命令以建立 CSR 檔:
    openssl req -new -key mykey.key -out CertificateSigningRequest.certSigningRequest -subj “/emailAddress=yourAddress@example.com, CN=John Doe, C=US”
    以您自己的值取代電子郵件地址、CN (憑證名稱) 及 C (國家/地區) 值。

至APPLE申請.cer檔案

  1. https://developer.apple.com/membercenter/index.action以開發者身份登入。
  2. 選擇Certificates, Identifiers & Profiles,如下圖
    2014-01-07_153638
  3. 選擇Certificates
    2014-01-07_153659
  4. 接著按右上角的+
    2014-01-07_155542
  5. 身份選【iOS App Development】
    2014-01-07_155602
  6. 在最後會要求上傳.certSigningRequest,選擇剛剛在【在 Windows 產生憑證簽名要求】所產生的檔案,按確認。
    2014-01-07_155713
  7. 下載.cer檔
    2014-01-07_155843

將開發人員憑證轉換成 P12 檔案

  1. 將從 Apple 收到的開發人員憑證檔案轉換成 PEM 憑證檔案。從 OpenSSL bin 目錄執行以下命令列陳述式:
    openssl x509 -in developer_identity.cer -inform DER -out developer_identity.pem -outform PEM
  2. 現在可以根據 iPhone 開發人員憑證的密鑰及 PEM 密鑰,產生有效的 P12 檔案:
    openssl pkcs12 -export -inkey mykey.key -in developer_identity.pem -out iphone_dev.p12

產生.mobileprovision檔案

  1. 首先先產生一個APP的ID(已註冊過1~2項可跳過),選左側的”Identifier=>App IDs”,註冊一個APP的ID。
    2014-01-07_160759
  2. 填寫你要做的APP的前置字等識別,若是只想練習則選”Wildcard App ID”,然後Bundle ID填入”*”
    2014-01-07_161119
  3. 接著註冊你的測試機(已註冊過3~5項可跳過),再選左邊側欄的Devices=>All,新增開發機的UUID
    2014-01-07_162122
  4. 打開iTunes,連接iPhone,打開摘要頁,點紅框處的序號一下,會變成顯示UUID,把它記下來。
    2014-01-07_162323
  5. 回到網頁,把上面的UUID填入下面UUID那欄,並且為這隻手機取個名字
    2014-01-07_162508
  6. 現在要去產生.mobileprovision檔案。點選左邊側欄的”Provisioning Profiles”,接著按右上的+號新增一個Profiles
    2014-01-07_160633
  7. 身份選擇【iOS App Development】
    2014-01-07_160650
  8. App ID選擇剛剛所產生的ID
    2014-01-07_161714
  9. 選擇剛剛產生的certificates身份
    2014-01-07_161843
  10. 選擇要測試發佈的手機
    2014-01-07_163645
  11. 為這個發佈設定命名
    2014-01-07_163655
  12. 下載.mobileprovision檔案,完成。

在Flex裡設定發佈檔案

  1. 在專案點右鍵,選Properties,在此選擇要使用的檔案
    2014-01-07_164424

自適網頁RWD開發心得

最近大家有發現部落格的樣子隨著日子在偷偷的改變嗎?

是的!最近我在進行部落格的版面小修改!
主要訴求是要將版面改版成具有專業感、清楚、易讀,
然後呀,本部落格現在開始支援Responsive Web Design囉!(灑花~~灑花!!

其實自適網頁說穿了,只是用多組的CSS,可以在不同瀏覽環境下切換畫面的CSS,
這可以讓同一個網頁在手機以及電腦上,呈現不一樣的樣子。

RWD一般最常見是使用media queries,利用條件設定去設定裡面所設定的CSS要在何種狀況被使用。

我的開發心得

那這次的改版過程中,下面幾點是我覺得在開發RWD時要去注意的

  1. 若有需要使用JS去做網頁動態,不要將CSS直接在JS裡面加,例如
    $(".content").css("display","none");//js

    類似上面的這種的作法都要通通避免,JS一定要避免掉所有和版面有關的設定
    像上面這種寫法,應改成:

    $(".content").addClass("display-none");//js
    .display-none{display:none;}/*CSS*/

    這樣可以避免在切換為不同顯示方式時彼此互鄉干擾到。

  2. CSS選擇器的優先順序:
    因為在套用時,會有共通的、在某些解析度才要使用的CSS設定。
    假如當今天總共有四種不同瀏覽裝置有四種不同版面,其中想在某一種特別的裝置上套用一系列不同的CSS(只是改字體什麼等)。會需要更清楚的了解各種選擇方法在執行時的優先順序,才能用不同的選擇器去覆蓋原有設定。
    這邊有關於選擇器優先順序的詳細說明:如何撰寫有效率的CSS選擇器(CSS Selector)
  3. HTML格式架構:
    因為要應付多種的CSS套版,HTML的格式設計就很重要,應要能夠清楚表達各元素之間的子從關係,並且符合W3C的規範,這樣子在換CSS時才可以順利在不更改HTML的狀況下去更動顯示方式。

Media Queries設定方式

  1. 直接分成不同的CSS檔案,在HTML載入時宣告此CSS作用的對象
    		<link href="/style.css" rel="stylesheet" media="all and (color)" type="text/css" />
    
    <!--?xml-stylesheet media="all and (color)" rel="stylesheet" href="example.css" ?-->
  2. 在CSS檔裡面設定作用對象
    @import url(/style.css) all and (color);
    
    @media all and (color) {
      ⋮ one or more rule sets…
    }

條件的用法

@media [media type] and [(media feature)]

例:如果視窗最小寬度為500px,就套用這些CSS
@media screen and (min-width:500px) {.....}

例:如果視窗為直立,就套用這些CSS
@media screen and (orientation: portrait) {.....}

例:如果視窗在400px和700px之間(兩者需同時符合),就套用這些CSS
@media screen and (min-width: 400px) and (max-width: 700px)

例:如果是彩色螢幕或彩色投影機兩者之一(兩者符合一種即可),就套用這些CSS
@media screen and (color), projection and (color) {.....}

屬性和值

  1. media type類型:
    2013-12-30_175631
    比較要注意的是,handheld這個值其實並沒有辦法有效的判別是否為手持設備,現在會讀handheld的手機瀏覽器有:OpenWave, Nokia lite-web browsers, Netfront, Digia, BlackBerry browser, Opera Mini until v4, Opera Mobile until v9,Palm’s Blazer, Nokia S40 browser, IEMobile 6.x and 8.x。所以若是要判別是否是使用iPhone或Android手機,可以使用下面的判斷式:

    // target mobile devices
    @media only screen and (max-device-width: 480px) {
        body { max-width: 100%; }
    }
    
    // recent Webkit-specific media query to target the iPhone 4's high-resolution Retina display
    @media only screen and (-webkit-min-device-pixel-ratio: 2) {
        // CSS goes here
    }
    
    // should technically achieve a similar result to the above query,
    // targeting based on screen resolution (the iPhone 4 has 326 ppi/dpi)
    @media only screen and (min-resolution: 300dpi) {
        // CSS goes here
    }
  2. media features
    * (max-或min-)width:[數字]
    * (max-或min-)height:[數字]
    * (max-或min-)device-width:[數字]
    * (max-或min-)device-height:[數字]
    * orientation:portrait 或 landscape
    * aspect-ratio:[比值]
    * (max-或min-)device-aspect-ratio:[比值]
    * color
    * color-index
    * monochrome
    * (max-或min-)resolution:[數字]dpi
    * scan(只對tv)
    * grid
  3. 在JS裡取得螢幕的真實寬度:
    function getWindowWidth() {
    	var windowWidth = 0;
    	if (typeof(window.innerWidth) == 'number') {
    		windowWidth = window.innerWidth;
    	}
    	else {
    		if (document.documentElement &amp;&amp; document.documentElement.clientWidth) {
    			windowWidth = document.documentElement.clientWidth;
    		}
    		else {
    			if (document.body &amp;&amp; document.body.clientWidth) {
    				windowWidth = document.body.clientWidth;
    			}
    		}
    	}
    	return windowWidth;
    }

參考資料

[2013-GDC]製作一個全球熱銷的遊戲

這是第一天下午的第一場演講

講者相關資訊

講者:Tap4Fun創意總監 Charlie Moseley
Email:charlie!@tap4fun.com
Twitter:@justcharlie

我的小小心得

這一場演講的講者,主要是在開發手機的APP遊戲。

手機遊戲由於可以很容易的在世界各國上架,在行銷費用不足的前提下,多一個市場就等於多一個機會,很多時候,你的遊戲會在那一個國家突然紅起來,其實是很難預測的。因此他們建議盡量要選擇一個適合在全世界都可以發行的主題來做遊戲發想

首先他們講到的是文化,應該要選擇世界各國的人都較能了解的文化做為遊戲背景。

在最後在地化的地方,他有講一句話我很喜歡:【當你的團隊裡,有越多不同屬性的人聚集在一起,你的團隊就會更強大】。他鼓勵不同國家、不同語言、不同文化的人一起共事,並認為這會讓整個團隊更加強大。我覺得這是開發遊戲非常重要的一個重點【兼容】,我們必須放開心胸去接受更多與我們不同的背景與知識,這樣我們才可以變得更加強壯。(並且可以發想的遊戲類型也會更多)

如何發想一個國際化的遊戲

Creating concepts可以有很多創意,喜歡簡單、直觀的概念。概念越簡單越好。

  1. 概念要簡單(Simple ideas)
  2. 可以用一句話形容這個GAME
  3. 在新舊概念、熟悉與不熟間取得一個平衡(創新與熟悉的平衡)
    dd
  4. 最大挑戰:怎麼吸引所有文化的人(要了解不同文化的交集在那邊,是否有文化偏見,是否有別人不熟悉的文化背景)。例如創意來自文化或歷史,像美國禁酒時代的故事,但這段歷史很多人不了解。
  5. 以成功的Spartan Wars這個遊戲為例,這遊戲主題為斯巴達戰役及嚴酷的訓練,因為有【300壯士】這部電影為其打了基礎,人們透過這部電影,能夠對斯巴達的文化有基礎的認識,那以此為基礎的遊戲也才容易被使用者所接受。
    未命名-1
  6. 關於歷史的東西對於國際市場會較難推動(除了有該文化的國家外會不能了解),因此要檢視人們對於這些概念可以激起一些火花,文化高速公路讓大家可以理解並感受到這些概念。

自己一定要愛自己所做的事和遊戲,如果不是很愛,就繼續找下一個idea,很多好的概念不會被實現。不要擔心失敗也不要擔心失敗了會如何,失敗的教訓是很重要的。

賈伯斯說:”The only way to do great work is to love what you do. If you haven’t found it yet, keep looking.”

一定會犯錯,不能怕犯錯,要去了解如何面對失敗。成功的人知道成功前要歷經失敗。行動遊戲非常年輕,大家都在學習。

螢幕快照 2013-12-22 下午8.24.55

不能只想著如何賺錢,舉例來說,Zynga因為花了太多時間研究使用者心態,怎麼讓使用者沉迷,怎樣賺更多錢,但因為他們要賺錢,卻賺不到。在做遊戲時,賺錢很重要,但弱因此忽略了要做『好的遊戲』的想法,卻反而會賺不到錢。

另一款遊戲Punch Quest,則是因為給玩家太多甜頭,使得玩家幾乎不用花錢就可以玩,所以下載量很高,收入卻不高。所以一開始時就要把賺錢的因素考慮進去。

另一款Tiny Tower,則是一個成功讓使用者願意花錢的遊戲。這個遊戲在猴子靈藥的部落格上面,有很詳細的遊戲性分析,請見此文:http://blog.monkeypotion.net/gamedesign/case/tiny-tower

Data Analysis

看資料要很小心,要了解使用者為什麼砍掉你的APP,一個人不可能又開發又分析,所以一定要有人來看,看資料分析可以獲得非常多的獲益。跳入資料海才可以找出獲益的供應鍊

螢幕快照 2013-12-22 下午8.25.05

螢幕快照 2013-12-22 下午8.10.51
Monetization funnel

行銷是必需的

行銷不是一個選擇,而是必需的,要成為國際熱銷的遊戲,一定要行銷,不然太難了。一般遊戲分為大眾遊戲及小眾遊戲,在投入太多的資源之前,應審慎的評估。
螢幕快照 2013-12-22 下午8.18.01

遊戲很難預期在那個市場會特別成功,都會需要一個個去試試,在每個市場都應做好在地化。

日本、英國、南韓、美國是競爭大、收益高的國家,或也可選擇市場小、競爭小的市場,有時遊戲在那紅也很難預料,因此嘗試各國的在地化非常重要。

同時包括客服、語言支援也要有在地化支援,願意給你回應的使用者是最需要去重視的

螢幕快照 2013-12-22 下午8.22.17

講者亦有嘗試過把同樣語言、不同國家的玩家放在一起,結果反應還蠻成功的。

[2013-GDC]探索過場動畫的故事

這是GDC第一天的第三場演講

講者相關資訊

講者:Brian Kindregan 首席文案 暴雪娛樂
講者信箱:bkindregan@blizzard.com
巴哈報導:探討過場動畫的故事

我的小小心得

我對過場動畫的製作比較沒有去用心了解過,之前玩魔獸時的過場動畫其實我也都是【SKIP】….(遮臉)。

所以對於這場主題比較沒有共鳴性,但據我所知,還是很多人會想要了解遊戲的故事的。雖然像我,都打到巫妖王困難模式了,還搞不清楚阿薩斯就是巫妖王的人也是有的啦….。

演講主題

  1. 過場動畫究竟有多難
  2. 很多遊戲都有動畫,怎麼串很重要

為何要有過場動畫

做動畫的,要先想為什麼要用動畫來表現效果,在玩時是讓玩家變成主角,動畫則變成旁觀者。

  1. 可用動畫重現場景。(或許玩家玩GAME時沒注意到場景的宏偉,用動畫可以更突顯場景的宏偉
  2. 其他角色更人性化。(表現其他角色個性)
  3. 衝擊最大化。(讓玩家感覺到更在槍林彈雨中)=>更了解下一個GAME在幹麻
  4. 華麗視覺的呈現。
  5. 呈現玩家的希望即恐懼感
  6. 創造一個挑戰或很艱辛的故事
  7. 遊戲的主題是什麼,讓玩家看到遊戲的進程

開場動畫讓你感到有興趣(What happen?)、希望和恐懼,女主在那?怎麼了,讓玩家有好奇心想玩下去。

開場動畫的目的

  1. 大量問題
  2. 串連兩個遊戲
  3. 引入GAME

優先選項

  1. 權力轉移
  2. 故事的建構

通常過場動畫都很緊張,要去思考這樣做好嗎?  關鍵信息有沒有表現出來。

上一段動畫裡,有表現出中心思想,吉姆代表希望,莎拉代表憤怒,以及兩者之間的核心衝突。

但沒起作用的則有:吉姆的戰敗(不再像之前一樣是個英雄,而很背動)、劇情(這兩者之前的糾結)、刀鋒女王莎拉(這次GAME的主角)、答案、故事節奏(太慢會讓玩家沒耐心)

具體實例如吉姆酗酒(電梯時已不再喝酒)

在製作動畫時,要小心不要自己沉浸在動畫裡。有幾個點要注意:

  1. 長度:兩個角色的糾葛很多,要確保對話是牽著中心思想盡量越少越好
  2. 人物與動作:要用過場動畫說明或解釋主角的狀況

因此,他們製作了第二個動畫

下面幾項在第二段動畫中有了表現

  1. 人物的動力
  2. 權力的轉移
  3. 吉姆與莎拉的角色張力
  4. 人物張力:記取教訓,問題從來不是我們看到的,像影片中硬漢對Sara束手無策(衝突感),去體現兩個關係

回到中心思想,當今天要截短節奏,要對照一下遊戲的中心思想,去比對一下,再決定內容的時候,不管講什麼都會有人有意見,所以要知道自己要的是什麼,別人要的是什麼,要記得別人的評語,但不一定要聽他的。(了解,但要知道自己的立場和一致的信念)