發佈日期: 1 則留言

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束手無策(衝突感),去體現兩個關係

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

發佈日期:

[2013-GDC]創造遊戲之新體驗與故事性的重要性

這是我去GDC大會早上的第二場演講

講者相關資訊

講者:馬場英雄 總監製 NAMCO BANDAI
維基資料:傳奇系列
遊戲影片:時空幻境:無盡傳奇 宣傳影片
巴哈報導:GDC 台北峰會《時空幻境》製作人馬場英雄 闡述家用遊戲開發要旨

我的小小心得

這一場演講算是這兩天GDC大會中我很喜歡的演說之一。

這位製作人在看待遊戲的出發點,讓我回想起小時候玩遊戲時所獲得的那種感動。在他的想法中,遊戲是一種傳達思想與理念的方式,並期待能帶給使用者成長與感動。

現在很多人在發想遊戲時,總是會變得先去思考【如何讓使用者付錢】,而不是想做個好玩的、讓玩家感動、陪伴他成長的遊戲。【回歸最初的感動】,是我從這場演講中所獲得的收獲。

演講筆記

在這場演講中,NAMCO講了幾點他認為在遊戲中很重要的要素:

  1. 主題
  2. 信息

首先,一個遊戲一定要有主要想讓使用者獲得的東西,像是訓練反應(像Dimond Dash)、腦力激盪(Candy Crush)、物理計算(小頑皮、憤怒鳥)。
或者是像RPG,則可以傳達一個故事,讓使用者感動、或從中體驗到一些我們想傳達的東西,例如他們就有說,在他們最新的一款遊戲裡,想傳達給使用者的意念就是【選擇】,讓他們了解,人生的現在,是過去眾多的選擇所演變而成的,而未來,則是由現在的每個小選擇去決定的。

另外,因為遊戲很容易一玩就玩很久,因此信息也格外重要,要能夠讓使用者在進行遊戲的當中得到樂趣。以動作遊戲而言,就是像音效、特效等感觀刺激,以RPG而言,就是戰鬥系統(因為要練功)的製作。
玩家在玩遊戲的過程中所得到的反饋,也是遊戲裡很重要的要素之一。

Tales 系列遊戲介紹

【戰鬥系統】

戰鬥系統的操作,應要讓輕度玩家和重度玩家同時可以上手,不應只針對重度玩家,要讓所有人都可以上手。

在Tales系列開發了一個線性動作戰鬥系統,同一個場地的所有敵人怪物及小組成員,以即時反應行動進行戰鬥。戰鬥系統設計為在戰鬥時可以前後左右移動時釋出他的絕招,不需要很困難的操作就可以有一定的攻擊水準,但可以經由技術去更加加強攻擊力。

有些角色的魔法強,有些則是速度強,另外,沒有直接操作的角色可以用AI去指定。

用刀箭也有它的技巧,例如:屬性、風屬性特色等。在戰鬥時就可以抓住對方弱點去行使技巧。

在戰鬥系統要創造新的體驗,讓使用者不要膩,自己也要有成長,在這個戰鬥和遊戲的過成要伴隨著成長。

要怎麼創造新的體驗,讓玩家體驗什麼,是非常重要的!

【和主角一起成長】

遊戲應要有故事性,並且讓玩家能把自己代入遊戲的角色之中。就像電影或小說,可以從電影內容或小說情節裡面獲得感動,並隨著遊戲情節而獲得成長(傳達具有教育性的思想)。

一款好的遊戲,要讓玩家從遊戲裡可以有新的體驗。

信息的傳遞非常重要(音效、特效)

和電影或小說不同的是,遊戲是透過【操作】來讓玩家和遊戲世界互動,所以操作很重要透過操作可以傳遞多少的訊息給使用者,讓使用者能融入這個遊戲世界,隨著角色的境遇而覺得感動或傷心,是成功的遊戲不可缺少的要素。怪物和成員角色都應該有各自的個性和特性

舉例來說,在Tales裡的戰鬥系統有以下特色:

  1. 要考量雙方位置後去操作
  2. 速度感、快感、動態
  3. 操作簡單
  4. 有協助的角色
  5. 透過不同的角色的合作還深化遊戲性。(要怎麼提供新的玩法)

一個吸引人的遊戲-故事性

遊戲應要有故事的,不只是故事,而且要透過這個故事,去傳達一個想法、感受給使用者,每一個GAME都會有它的故事概念,透過故事可以把主題傳遞給使用者。(例:不可動搖的信念、貫徹正義)

樂趣(融入遊戲世界)

自己是否能夠讓玩家透過操控性去讓玩家演變成主角,像是玩家玩一玩流淚、融入故事當中。因此主題和訊息非常重要也是遊戲的特色。

去創造新玩法體驗,要傳遞什麼要去思考。

共存(用正反兩面角色去體現非單一的價值觀)

大家都有不同的想法,有時會衝擊思考,但大家都是共存的,要透過合作去達到目標,在說故事中,主角有各種類型的,不論是主角或敵人都應該有想法,每種想法都有正確的一面,最後若無法讓步就要透過劍與劍來戰鬥。

不同的價值感非常重要,但透過討論可以互相理解對方,Tales系列非常重視這點,小組成員也是。(傳遞訊息)

透過遊戲玩家可以去思考這些事情,這可以提高玩家對這些遊戲的認知度,帶給玩家正向影響和思考上的鼓勵。

透過遊戲的完成可以有所成長、去思考,這是為什麼Tales系列如此重視【傳遞的訊息】這塊的原因。

傳遞思想-遊戲中心思想

最新的game以【選擇】為主題,人生因為選擇而讓每個人的未來有所不同,現在是由過去的許多選擇所累積而來的

發佈日期:

UITableView的小問題

紀錄一下今天開發我的APP時遇到的小問題,
因為要使用UITableView,發現UITableView放在UIView裡時,
若要使用static cells是不能直接使用的。

當我們要用UIView,裡面有放一些自己的東西,再加上一個Static cells的UITableView時,
會發現雖然在storyboard裡能夠正常的顯示表格的樣子,如下圖
螢幕快照 2013-12-11 下午6.28.52
但是當執行出來卻無法顯示已設定好的static cells,而會顯示為一片空白,如下圖
螢幕快照 2013-12-11 下午6.31.55
查問Google大神後,在這邊有看到文章有相關的建議,也就是要我們不要實作下面這三個方法

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
}

不過,我檢查過後,我並沒有設定這三種方法,但是還是一樣無法正常顯示定義好的static cells,
最後這篇文章解決了我的疑問:How do I put a UITableView into a UIView
原來,我們不能夠直接在UITableView裡直接使用static cells,
如果必需在static cells的畫面裡加上其他元素,則應該要在該位置放入Container,然後Container連接至UITableViewController畫面,
如下圖:
螢幕快照 2013-12-11 下午6.41.42

這樣子便能夠正常的顯示在storyboard裡設定的static cells的樣式了!
螢幕快照 2013-12-11 下午8.15.14
PS:這邊有Container View與母容器互動的範例文章與範例專案

發佈日期:

iOS6以上控制螢幕旋轉

一般的設定方式

//支援Xcode 4.5
- (NSUInteger) supportedInterfaceOrientations{
//僅正面
// return UIInterfaceOrientationMaskPortrait;

//支援縱向 (利用 | 設定多參數)
// return UIInterfaceOrientationMaskPortrait
// | UIInterfaceOrientationMaskPortraitUpsideDown;

//支援橫向
//UIInterfaceOrientationMaskLandscape: 支援按鈕在左、按鈕在右
// return UIInterfaceOrientationMaskLandscape;

//支援四個方向
return UIInterfaceOrientationMaskAll;

}

- (BOOL) shouldAutorotate {
return YES;
}

TabBarController設定方式

假使今天要控制所有畫面中,某些可支援旋轉,某些不行,
在有使用Navigation Controller和TabBarController的狀況時,
則需要這樣設定:

  1. 勾選支援畫面旋轉
    螢幕快照 2013-12-11 下午3.36.26
  2. 在AppDelegate加上這段程式碼
    - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
    {
        NSUInteger orientations = UIInterfaceOrientationMaskAll;
    
        if (self.window.rootViewController) {
            UIViewController* presented = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
            orientations = [presented supportedInterfaceOrientations];
        }
        return orientations;
    }
  3. 在tabBarController裡加上
    -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
        return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
    }
    
    -(NSUInteger)supportedInterfaceOrientations{
        if (self.selectedViewController)
            return [self.selectedViewController supportedInterfaceOrientations];
    
        return UIInterfaceOrientationMaskPortrait;
    }
    
    -(BOOL)shouldAutorotate{
        return [self.selectedViewController shouldAutorotate];
    }
  4. 支援旋轉的子畫面加上
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }
    
    - (BOOL)shouldAutorotate
    {
        return NO;
    }
    
    - (NSUInteger)supportedInterfaceOrientations
    {
        return UIInterfaceOrientationMaskPortrait;
    }
  5. 要支援旋轉的子畫面加上
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        return YES;
    }
    
    - (BOOL)shouldAutorotate
    {
        return YES;
    }
    
    - (NSInteger)supportedInterfaceOrientations
    {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }

Navigation Controller設定方式

若要控制在Navigation Controller之下的單獨畫面是否支援旋轉,則需要在Controller裡加上這段

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return [self.visibleViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}

- (BOOL)shouldAutorotate {
    return [self.visibleViewController shouldAutorotate];
}

- (NSUInteger)supportedInterfaceOrientations {
    return [self.visibleViewController supportedInterfaceOrientations];
}