Maso Blog View RSS

Flash, Actionscript, Animation, Game, Multimedia, User Interface,Mobile...
Hide details



[作品]包子先生貼圖 24 Oct 2015 7:13 PM (9 years ago)

有一天突然覺得想畫一組Line貼圖自己用,然後就這樣了

>> 前往貼圖購買頁

推薦一下,這組貼圖完全是用procreate在iPad2上繪製完成,十分好用。
>> http://procreate.si/

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

[作品]夢幻航空Airline Fantasy 28 Feb 2015 9:11 PM (10 years ago)


任職於IGS時的作品之一,於2012.10~2014.9期間上線,個人負責職務為Product Owner,在此做點記錄



>>GamesLands介紹
>>巴哈姆特新聞介紹
>>Facebook Fan Page

由於遊戲已下線,遊戲內容請參考以下影片


Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

[筆記]從Flash到LWF再到Unity 4 Sep 2014 2:23 AM (10 years ago)


簡單記錄一下如何透過LWF將Flash的動畫輸出到Unity裏運用。

§ 安 裝 §


.在Unity開啟一個新專案。

.到LWF官網 http://gree.github.io/lwf/ 下載最新的版本。

.解壓縮後,在解壓目錄/csharp/unity/dist/ 下可以找到一個lwf.unitpackage,執行它並安裝到剛剛開的unity專案裏。

[註]最新版的LWF需要Unity4.5以上環境

以上就做完Unity這邊初步的環境建置。接著是準備Flash的轉檔環境。


LWF官網本身有提供JSFL方式的轉檔script,可在剛剛的壓縮裏找到。不過網路上有另一個更方便的工具LWFS。


.到 https://github.com/gree/lwfs/releases下載最新版的LWFS,有分OSX及Wins版,要注意看一下。

.解開後會得到一個LWFS的目錄,裏面有start.app及stop.app,是兩支python寫的程式。執行start.app,正常的話會自動啟動瀏覽器,並出現類似這樣的畫面:




另外還會自動在桌面上產生兩個資料夾:LWFS_work及LWFS_work_output


[註]Mac OSX 10.9以上的話,要先針對LWFS資料夾的執行權限做設定,依照裏面README.txt寫的步驟去做就可以了。
[註2]LWFS放置的路徑中,最好不要有中文、空格之類字元出現,否則start.app可能會無法執行。


§ 轉 檔 §


.把swf檔案放在桌面上的LWFS_work資料夾內,幾秒內就會自動轉檔,產生的檔案會在LWFS_owrk_output裏。

.swf在製作上有一些注意事項,請參照官網提供的Flash Production Guideline(pdf)

.另外如果要用程式控制場景上的MovieClip,則必需設定好instance name。

.若要動態從Library裏叫出做好的元件,則需要設定好Linkage id。

[註]SWF在製作時需注意一點。在Unity中使用LWFObject呼叫LWF.Movie出來時,至少一定會有一個Movie會強制出現在depth最底層,即使去設定他的sortingLayer也無法改變,而除了這個Movie外,其他Movie則正常。這裏想到簡單的解決方式是在SWF的root stage上放一個空白的movie clip,到Unity裏使用時,該空白mc就會出現在depth最底層,而之後出現的Movie就能正常表現


§ 匯 入 §


.swf成功轉檔的話,會在LWFS_work_output/unity/找到與swf同名的資料夾,例如test.swf會輸出一個test.swf的資料夾,裏面應該會有素材圖檔及一個test.bytes的文字檔。

.將整個test.swf資料夾複制到Unity專案底下的Assets/Resource s/裏。

  void Start () {
  gameObject.AddComponent<LWFObject>();
  LWFObject _lwfObj = gameObject.GetComponent<LWFObject>();
  _lwfObj.Load("test.swf/test","test.swf/");//.bytes文字檔的路徑及存放素材圖檔的路徑
  LWF.Movie _movie = _lwfObj.lwf.rootMovie.AttachMovie("linkage_id","instance_id");
 }


.如果是放在stage上的動畫,在_lwfObj.Load這行執行後就會出現了。

.lwf.rootMovie.AttachMovie這段則是從Library中叫出動畫。

.更多程式控制的方式要多參閱官網的文件,另外LWF似乎以日本使用者居多,所以也可以找到一些日文blog有使用心得。



§ 補 充 §


(update 2015/12/23)
有些去背的png素材,在實際播時,原本透明的地方出現莫明的雜線,在texture設定裏把Alpha Is Transparency給uncheck掉可解

(update 2014/10/11)
若要從swf內去呼叫unity的C#,可以在Flash內用fscaommand:
  fscommand("event", "sendMessage");

而在C#這邊:
  //在LWFObject裏
  SetEventHandler("sendMessage", (movie, button) => {
            // doSomeThing
        });

這邊要注意一點是,LWF只支援AS2,雖然以AS3輸出的動畫它仍可正常播放,但這邊用到fscommand則必需要是AS2才能正常執行,所以務必用Flash CS6或以下的版本來製作SWF。

(update 2014/9/7)
後來在官網看到目前scale上似乎是有問題的,作者建議素材的texture設定如下:
Texture Type: Advanced
Non Power of 2: None
Generate Mip Map: Unchecked
Wrap Mode: Clamp
Filter Mode: Point (Bilinear is okay if the scale is one)



§ 參 考 §


LWF official page

LWF Demo page

Unity API Reference

LWF wiki For Flash (JP only)

LWFS

Notes on Lightweight SWF (LWF) framework for Unity(裏面的LWFAnimator已無法在最新版的LWF使用,不過一些語法可以參考)

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

TexturePacker的十個好棒啊 12 Jun 2013 6:24 AM (11 years ago)


使用TexturePacker也有一段時間了,今天就來介紹一下他的一些優點
由於網路上已有不少介紹文,且這軟體本身也不難操作,所以我就簡單列一下我喜歡這工具的十個優點。

**TexturePacker官網


1.支援各平台,Win, Mac, Linux都可以用,好棒啊~



2.使用超方便,拉進圖檔,設定格式,最後按一下Publish!不用20秒就搞定,好棒啊~


3.支援30多種輸出格式,不爽還可以自己定義新的,好棒啊~

支援目前絕大多數的2D遊戲引擎、Framework,共30多種,如果這些還沒有你要的,也可以自行定義你要的格式。
**自定義格式參考文件

4.可自定義多個解析度需求,一鍵輸出所有格式,AutoSD功能好棒啊~

尤其是同時要輸出Retina及非Retina的素材時,以往是需要返覆切換設定,各別按Publish到不同的路徑,現在只要在AutoSD裏設定好,一鍵就可輸出了。
**詳細可參考fallhunter的這篇TexturePacker 3.0 使用教程

5.方便把SWF轉成SpriteSheet,好棒啊~

用過幾套SWF轉SpriteSheet的工具,但大部份就只做到把SWF的圖擷出來再併成一張而已,一些細節設定就比較少。而大多專門在做合併SpriteSheet的工具軟體則不一定都會支援SWF import的功能。所以兩者兼備的TexturePacker確實是值得推薦。 **關於SWF輸出功能,可參考Gray Liao這篇「再次介紹TexturePacker」

6.SmartFolder,資料夾有任何變動就會自動更新,好棒啊~
做遊戲的過程經常是在修修改改的,圖的素材也是會增增減減的,如果每次變動就要重拉一次圖檔那就很累了。SmartFolder是只要你指定這個Folder為素材來源後,Folder只要有變動,TexturePacker就會自動更新(但還是要記得按Publish啦),確實很方便

7.支援十多種圖檔格式,包括Photoshop沒有的RGBA4444, PVRTC等,好棒啊~

**關於PVRTC,可參考這篇「助你開發iOS game的基礎知識」
**關於RGBA4444,可參考這篇「使用 RGBA4444 與 Dithering 減少記憶體用量」

8.功能完整的免費版、試用版還有佛心推廣版,好棒啊~
TexturePacker下載後,可選擇使用免費版(輸出圖會有浮水印),或是完整功能七天試用版,另外針對開發者或Blog作者也提供了佛心版,只要符合TexturePacker提出的條件,就可以跟他申請免費的License,請參考這頁的申請書

9.Xcode指令整合,省下很多重複動作的時間,好棒啊~
如果是使用Xcode開發的話,TexturePacker有提供與Xcode整合的指令,使用方式請參考這篇Tutorial: XCode4 integration of TexturePacker for Cocos2d and Sparrow framework

10.素材加密保護功能(Cocos2d Only),好棒啊~
怕畫好的圖素被偷走嗎?新版的TexturePacker提供了素材加密的功能,但目前只有Cocos2D-iPhone版有支援,未來也許會再支援到其他平台,詳細請參考這篇Protect your game assets (currently cocos2d only)


看完這麼多個好棒啊,不會想趕快來用看看嗎?快上TexturePacker官網試用看看吧!!

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

[Unity] Futile + GoKit 的打地鼠練習 8 May 2013 3:42 AM (11 years ago)


為了多熟悉Futile及其內建的GoKit,於是做了個打地鼠的練習。
觀看範例

寫在前頭

這篇僅挑重點寫,若對Unity或Futile完全沒碰過的,請先看完上一篇再來。
另外,這篇也是參考Futile作者的教學影片來的,有興趣的話也可過去看看。

Texture打包

使用Texture Packer打包所需的圖形,設定上的重點是:
輸出Data Format選Unity3D
Layout的Algorithm選Basic, Trim Mode選None
然後按Publish輸出,本範例輸出命名為:textures.png及textures.txt

另外字型圖也可包進同一張Texture圖裏。我是用bmGlyph這套軟體做字型圖,我選"Impact"這個字型來做,產生了ImpactFont.png及ImpactFont.txt兩個檔案,然後ImpactFont.png這個也可拉進Texture Packer裏一起輸出。如下圖


所以最後會得到texture.png, texture.txt及ImpactFont.txt三個檔,就一併放到Unity專案路徑裏的/Assets/Resources/Atlases/裏吧
專案設定

本範例長寬設為960x640,其他就沒有特別做什麼設定了

Pixel Style

因為我個人滿偏好Pixel Style的,所以特別想知道Futile在開發Pixel Style時的設定方式,尤其Unity這種3D環境經常預設就會幫你做一些反鋸齒之類的效果,但這反而會把銳利的Pixel給模糊掉,因此首先要知道如何設定texture才能得到我們想要的效果。本範例對Texture的設定如下



Textures Atlas的載入與使用

上一篇只單純載入一張png圖,這次是把一堆圖及字型,都拼成一塊再載入,不過用法是差不多的:

Futile.atlasManager.LoadAtlas("Atlases/textures");
Futile.atlasManager.LoadFont("ImpactFont","ImpactFont.png","Atlases/ImpactFont");

//使用圖形時:
_background = new FSprite("background.png");

//使用字型時:
_label = new FLabel("ImpactFont","Tap the BaoZi to Start!!");

FSprite與FContainer

FSprite不能再包別的FSprite,更不能包FContainer。它只有一層,不像Flash那樣可以層層包。
FSprite在生成時直接就可以塞一張圖進去,FContainer不行。
只有FContainer可以包東西,除了可包FSprite外,也可包FContainer。
FContainer有scale, scaleX, scaleY等屬性,但卻沒有width, height。

FButton與 FLabel

//Button用法
_myBtn = new FButton("原本的圖.png", "壓下去的圖.png ", "音效名");
//event是用+的方式偵聽
_myBtn.SignalRelease += onTapFunction;
private void onTapFunction(FButton obj){
  Main.instance.gotoTitle();
}

//Label
_myLabel = new FLabel("字型名稱","文字內文");
_myLabel.text = "改字的內容"
//Label本身沒有width, height,要用textRect
Debug.Log(_myLabel.textRect.width)
Debug.Log(_myLabel.textRect.height)


TouchManager


//要先加入MultiTouch的介面
public class PageGame : FContainer, FMultiTouchableInterface {

override public void HandleAddedToStage(){
        //啟用
 Futile.touchManager.AddMultiTouchTarget(this);
 base.HandleAddedToStage();
}
 
override public void HandleRemovedFromStage(){
        //停用
 Futile.touchManager.RemoveMultiTouchTarget(this);
 base.HandleRemovedFromStage();
}

//touches包含了目前所有動作中的點的資訊
public void HandleMultiTouch(FTouch[] touches){
 foreach(FTouch _touch in touches){
  if(_touch.phase == TouchPhase.Began){
   //do something 
  }
 }
}


}


一些Event的設置


//把某個function加入到Futile系統的Update事件中,效果類似於Flash的EnterFrame
Futile.instance.SignalUpdate += myFunction;
private void myFunction () {
    //do something
}
//取消就用減的
Futile.instance.SignalUpdate -= myFunction;


//加入跟移出場景時的事件,名稱及效果都與Flash的類似,FSprite, FContainer, FButton這些都有這個事件
override public void HandleAddedToStage(){
} 
override public void HandleRemovedFromStage(){
}



FRenderLayer發生GameObject.active的問題

目前這個版本(0.67 alpha)在Unity 4.1的環境下,輸出時會出現類似這樣的錯誤訊息:
Assets/Plugins/Futile/Core/FRenderLayer.cs(110,29): warning CS0618: UnityEngine.GameObject.active' is obsolete:GameObject.active is obsolete. Use GameObject.SetActive(), GameObject.activeSelf or GameObject.activeInHierarchy.'
作者有在github上說明問題點,並已在dev版本修正了。所以下一版的Futile release時這問題應該就不會有了。
目前的話,可自行修改,改的地方只有三行,很容易。
打開FRenderLayer.cs這個檔,可找到三行 _gameObject.active = XXX; 的程式,自行改成 _gameObject.SetActive(XXX); 即可。
(這問題應該在下一版的Futile release後就不會吧)
GoKit的使用

GoKit是一個類似AS3裏的Tween Library,用法也類似,Futile有把GoKit包進來,所以可直接用
//基本用法,寫法跟TweenLite很像
Go.to( someTransform, 4f, new GoTweenConfig().position( new Vector3( 10, 10, 10 ) ) );
//由於GoKit不是只設計給Futile用的,而是設計給Unity用的,所以上一行會用3d的座標
//在Futile裏用的話,可以這樣寫
Go.to( instanceOfMyClass, 3f, new TweenConfig().floatProp("scale",scaleTarget*0.25f) );
//同時要變多個屬性的話,可以一直接在後面:
Go.to( instanceOfMyClass, 3f, new TweenConfig().floatProp("scale",scaleTarget*0.25f).floatProp("y",100) );

//也可以用TweenChain一次設定一整串Tween
var tween1 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*0.3f).floatProp("scaleX",scaleTarget*1.4f).floatProp("y",_yTarget)); 
  var tween2 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*1.4f).floatProp("scaleX",scaleTarget*0.3f).floatProp("y",_yTarget + height)); 
  var tween3 = new Tween(this, 0.1f, new TweenConfig().floatProp("scale",scaleTarget*0.25f).floatProp("y",_yTarget)); 
  
var chain = new TweenChain();
chain.append(tween1).append(tween2).append(tween3);
chain.setOnCompleteHandler(C=>{
  //do something 
 }
);
chain.play();


其他更詳細的用法,請自己上官網去看
最後是原始碼大爆發
Main.cs:
using UnityEngine;
using System.Collections;

public class Main : MonoBehaviour {

 private FContainer _currentPage;
 
 public static Main instance;
 
 // Use this for initialization
 void Start () {
   instance = this;
   FutileParams futileParams = new FutileParams (true,true,false,false);
   futileParams.AddResolutionLevel(960,1,1,"");
   futileParams.origin = new Vector2(0.5f,0.5f);
   Futile.instance.Init(futileParams);
   
   Futile.atlasManager.LoadAtlas("Atlases/textures");
   Futile.atlasManager.LoadFont("ImpactFont","ImpactFont.png","Atlases/ImpactFont");
   
   //FSprite _bg = new FSprite("background.png");
   //Futile.stage.AddChild(_bg);
  
   gotoTitle();
 }
 
 
 public void gotoTitle(){
  if(_currentPage != null)_currentPage.RemoveFromContainer();
  _currentPage = new PageTitle();
  Futile.stage.AddChild(_currentPage);
 }
 
 public void gotoGame(){
  if(_currentPage != null)_currentPage.RemoveFromContainer();
  _currentPage = new PageGame();
  Futile.stage.AddChild(_currentPage);
 }
 
 // Update is called once per frame
 void Update () {
 
 }
}


PageTitle.cs:
using UnityEngine;
using System.Collections;

public class PageTitle : FContainer, FSingleTouchableInterface {
 
 private FSprite _background;
 private FSprite _mainLogo;
 private FLabel _label;
 
 
 public PageTitle(){
  _background = new FSprite("background.png");
  AddChild(_background);
  
  _mainLogo = new FSprite("mainLogo.png");
  AddChild(_mainLogo);
  
  
  _label = new FLabel("ImpactFont","Tap the BaoZi to Start!!");
  _label.color = Color.white;
  _label.y = -260;
  _label.scale = 2;
  AddChild(_label);
  
  doBreath();
  doShake ();
  
  FContainer _test = new FContainer ();
  AddChild (_test);
  //var bb = new FButton(
  //bb.SignalRelease += onRelease;
  
 }
 
 
 override public void HandleAddedToStage(){
  Futile.touchManager.AddSingleTouchTarget(this);
 
  base.HandleAddedToStage();
 }
 override public void HandleRemovedFromStage(){
  Futile.touchManager.RemoveSingleTouchTarget(this);
  base.HandleRemovedFromStage();
 }
 
 public bool HandleSingleTouchBegan(FTouch touch)
 {
  //Debug.Log("Touch");
  return true;
 }
 public void HandleSingleTouchMoved(FTouch touch)
 {
  //Debug.Log("Move");
 }
 public void HandleSingleTouchEnded(FTouch touch)
 {
  //Debug.Log("Ended");
  Vector2 pos = _mainLogo.GlobalToLocal(touch.position);
  if(_mainLogo.textureRect.Contains(pos)){
   //Debug.Log("Oh");
   Main.instance.gotoGame();
  }
 }
 public void HandleSingleTouchCanceled(FTouch touch)
 {
  //Debug.Log("Canceled");
 }
 
 private void doBreath(){
  //Debug.Log("doBreath");
  var tween1 = new Tween(_mainLogo, 2.5f, new TweenConfig().floatProp("scale",1.05f).setEaseType(EaseType.QuadInOut)); 
  var tween2 = new Tween(_mainLogo, 2.5f, new TweenConfig().floatProp("scale",1).setEaseType(EaseType.QuadInOut)); 
  var chain = new TweenChain();
  chain.append(tween1).append(tween2);
  chain.setOnCompleteHandler(C=>{
    doBreath();
   }
  );
  chain.play();
 }
 
 private void doShake () {
  //Debug.Log("doShake");
  
  var r = RXRandom.Float()*16 - 8;
  
  var tween1 = new Tween(_mainLogo, 0.05f, new TweenConfig().floatProp("rotation",r).setEaseType(EaseType.BackOut)); 
  var tween2 = new Tween(_mainLogo, 0.1f, new TweenConfig().floatProp("rotation",-r).setEaseType(EaseType.BackOut)); 
  var tween3 = new Tween(_mainLogo, 0.1f, new TweenConfig().floatProp("rotation",r).setEaseType(EaseType.BackOut)); 
  var tween4 = new Tween(_mainLogo, 0.1f, new TweenConfig().floatProp("rotation",-r).setEaseType(EaseType.BackOut)); 
  var tween5 = new Tween(_mainLogo, 0.05f, new TweenConfig().floatProp("rotation",0).setEaseType(EaseType.BackOut)); 
  
  
  
  var chain = new TweenChain();
  chain.appendDelay(RXRandom.Float()*5+3).append( tween1).append(tween2).append(tween3).append(tween4).append(tween5);
  chain.setOnCompleteHandler(C=>{
   doShake();
  }
   );
  chain.play();
  
 }
 
 // Update is called once per frame
 void Update () {
  
 }
}

PageGame.cs:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PageGame : FContainer, FMultiTouchableInterface {
 
 private FSprite _background;
 private FButton _exitBtn;
 private int _frameCount;
 private int _createBaoziTime;
 private int _baoziMaxCount;
 private int _liveTimeLimit;
 private FContainer _baozisContainer;
 private FContainer _baozisCrushContainer;
 private List _baoziList;
 private FLabel _scoreLabel;
 private FLabel _lifeLabel;
 private FLabel _overLabel;
 private int _score;
 private int _life ;
 private bool _isPlaying;
  
 
 //private List
 
 // Use this for initialization
 public PageGame () {
  //Debug.Log("OOOKKK");
  _background = new FSprite("background.png");
  AddChild(_background);
  
  init();
 }
 
 private void setDiffcult(){
  if(_score < 10){
   _createBaoziTime = 45;
   _baoziMaxCount = 5;
   _liveTimeLimit = 300;
  }else if(_score < 30 && _score >=10){
   _createBaoziTime = 40;
    _baoziMaxCount = 10;
   _liveTimeLimit = 250;
  }else if(_score < 70 && _score >=30){
   _createBaoziTime = 30;
    _baoziMaxCount = 15;
   _liveTimeLimit = 250;
  }else if(_score < 100 && _score >=70){
   _createBaoziTime = 25;
    _baoziMaxCount = 20;
   _liveTimeLimit = 200;
  }else if(_score >=100){
   _createBaoziTime = 20;
   _baoziMaxCount = 25;
   _liveTimeLimit = 150;
  }
  
  
  
 }
 
 private void init(){
 
  _baoziList = new List();
  
  _baozisContainer = new FContainer();
  AddChild(_baozisContainer);
  
  _baozisCrushContainer = new FContainer();
  AddChild(_baozisCrushContainer);
  
  
  _scoreLabel = new FLabel("ImpactFont","SCORE: 000");
  _scoreLabel.y = Futile.screen.halfHeight-32;
  _scoreLabel.scale = 2;
  _scoreLabel.x = -Futile.screen.halfWidth+_scoreLabel.textRect.width;
  
  AddChild(_scoreLabel);
  
  
  _lifeLabel = new FLabel("ImpactFont","LIFE: 010");
  _lifeLabel.y = Futile.screen.halfHeight-32;
  _lifeLabel.scale = 2;
  _lifeLabel.x = Futile.screen.halfWidth-_lifeLabel.textRect.width;
  
  AddChild(_lifeLabel);
  
  
  _overLabel = new FLabel("ImpactFont","GAME OVER");
  _overLabel.scale = 5;
  AddChild(_overLabel);
  
  
  _exitBtn = new FButton("exit.png");
  AddChild(_exitBtn);
  _exitBtn.SignalRelease += onClickExit;
  
  _exitBtn.x = Futile.screen.halfWidth-_exitBtn.sprite.width/2 -8;
  _exitBtn.y =  -Futile.screen.halfHeight + _exitBtn.sprite.height/2 + 8;
  
  
 }
 
 private void onClickExit(FButton obj){
  Main.instance.gotoTitle();
 }
 
 
 
 override public void HandleAddedToStage(){
  _frameCount = 0;
  _score = 0;
  setDiffcult();
  _life = 10;
  _isPlaying = true;
  _overLabel.isVisible = false;
  Futile.instance.SignalUpdate += signalUpdate;
  Futile.touchManager.AddMultiTouchTarget(this);
  base.HandleAddedToStage();
 }
 
 override public void HandleRemovedFromStage(){
  Futile.instance.SignalUpdate -= signalUpdate;
  Futile.touchManager.RemoveMultiTouchTarget(this);
  base.HandleRemovedFromStage();
 }
 
 private void addScore(){
  
  _score ++;
  setDiffcult();
  string _str = _score.ToString();
  while(_str.Length < 3){
   _str = "0"+_str;
  }
  _scoreLabel.text = "SCORE: "+_str;
 }
 
 
 
 
 public void HandleMultiTouch(FTouch[] touches){
  if(!_isPlaying)return;
  foreach(FTouch _touch in touches){
   if(_touch.phase == TouchPhase.Began){
    for(int i = _baoziList.Count -1; i>=0; i--){
     Baozi _baozi = _baoziList[i];
     Vector2 _touchPos = _baozi.GlobalToLocal(_touch.position);
     if(_baozi.textureRect.Contains(_touchPos)){
      crushBaozi(_baozi);
      addScore();
      break;
     }
    }
    
   }
  }
 }
 
 private void decLife(){
  _life --;
  string _str = _life.ToString();
  while(_str.Length < 3){
   _str = "0"+_str;
  }
  _lifeLabel.text = "LIFE: "+_str;
  if(_life<=0){
   gameOver();
  
  }
 }
 
 private void gameOver(){
  _overLabel.isVisible = true;
  _isPlaying = false;
 }
 
 // Update is called once per frame
 private void signalUpdate () {
  
  if(!_isPlaying)return;
  
  if(_frameCount % _createBaoziTime ==0 && _baoziList.Count<_baoziMaxCount){
   createBaozi();
  }
  _frameCount++;
  
  for(int i = _baoziList.Count -1; i>=0; i--){
   Baozi _baozi = _baoziList[i];
   
   _baozi.liveTime ++;
   if(_baozi.liveTime >= _liveTimeLimit){
    _baoziList.Remove(_baozi);
    _baozi.doHiding();
    decLife ();
    //_baozi.RemoveFromContainer();
   }
   //Vector2 _touchPos = _baozi.GlobalToLocal(_touch.position);
   //if(_baozi.textureRect.Contains(_touchPos)){
    //crushBaozi(_baozi);  
    //break;
   //}
  }
  
 }
 
 private void crushBaozi(Baozi _baozi){
  BaoziCrush _baoziCrush = new BaoziCrush();
  //_baoziCrush.scale = _baozi.scale;
  _baoziCrush.x = _baozi.x;
  _baoziCrush.y = _baozi.y-_baozi.height*0.3f;
  _baoziCrush.setCrush(_baozi.scaleTarget);
  
  _baozisCrushContainer.AddChild(_baoziCrush);
  _baoziList.Remove(_baozi);
  _baozi.RemoveFromContainer();
  
 }
 
 private void createBaozi(){
  Baozi _baozi = new Baozi();
  //_baozi.x = RXRandom.Range(-Futile.screen.halfWidth,Futile.screen.halfWidth);
  //_baozi.y = RXRandom.Range(-Futile.screen.halfHeight,Futile.screen.halfHeight);
  _baozisContainer.AddChild(_baozi);
  _baozi.doIntro();
  _baoziList.Add(_baozi);
 }
}

Baozi.cs:
using UnityEngine;
using System.Collections;

public class Baozi : FSprite {
 public float scaleTarget;
 public int liveTime;
 private float _yTarget;
 // Use this for initialization
 public Baozi():base ("baozi.png"){
  
  x = RXRandom.Range(-Futile.screen.halfWidth + width/2,Futile.screen.halfWidth - width/2);
  _yTarget = y = RXRandom.Range(-Futile.screen.halfHeight + 100,Futile.screen.halfHeight - height/2-32);
  scaleTarget = scale = (1-(_yTarget+Futile.screen.halfHeight)/Futile.screen.height) + 0.3f;
  //scaleTarget = scale = RXRandom.Float()*0.5f + 0.5f;
 }
 
 public void doIntro(){
  
  //_scaleTarget *=1.05f;
  this.scale = scaleTarget*0.25f;
  var tween1 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*1.2f).floatProp("y",_yTarget + height*2)); 
  var tween2 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*0.3f).floatProp("scaleX",scaleTarget*1.4f).floatProp("y",_yTarget)); 
  var tween3 = new Tween(this, 0.1f, new TweenConfig().floatProp("scale",scaleTarget).setEaseType(EaseType.BackOut)); 
  
  var chain = new TweenChain();
  chain.append(tween1).append(tween2).append(tween3);
  chain.setOnCompleteHandler(C=>{
    liveTime = 0;
   }
  );
  chain.play();
 }
 
 public void doHiding(){
  
  var tween1 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*0.3f).floatProp("scaleX",scaleTarget*1.4f).floatProp("y",_yTarget)); 
  var tween2 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*1.4f).floatProp("scaleX",scaleTarget*0.3f).floatProp("y",_yTarget + height)); 
  var tween3 = new Tween(this, 0.1f, new TweenConfig().floatProp("scale",scaleTarget*0.25f).floatProp("y",_yTarget)); 
  
  var chain = new TweenChain();
  chain.append(tween1).append(tween2).append(tween3);
  chain.setOnCompleteHandler(C=>{
    this.RemoveFromContainer();
   }
  );
  chain.play();
  
  
  
  
 }
 
 // Update is called once per frame
 void Update () {
 
 }
}

BaoziCrush.cs:
using UnityEngine;
using System.Collections;

public class BaoziCrush : FSprite {

 // Use this for initialization
 public BaoziCrush():base ("baoziCrush.png"){
  //scale = RXRandom.Float()*0.5f + 0.5f;
  
  //x = RXRandom.Range(-Futile.screen.halfWidth + width/2,Futile.screen.halfWidth - width/2);
  //y = RXRandom.Range(-Futile.screen.halfHeight + 100,Futile.screen.halfHeight - height/2);
 }
 
 public void setCrush(float _scaleTarget){
  _scaleTarget *=1.05f;
  this.scale = _scaleTarget/2;
  var tween1 = new Tween(this, 0.1f, new TweenConfig().floatProp("scale",_scaleTarget).setEaseType(EaseType.BackOut)); 
  var tween2 = new Tween(this, 1.0f, new TweenConfig().floatProp("alpha",0f).setEaseType(EaseType.QuadInOut)); 
  var chain = new TweenChain();
  chain.append(tween1).append(tween2);
  chain.setOnCompleteHandler(C=>{
    this.RemoveFromContainer();
    //Debug.Log("Killed");
   }
  );
  chain.play();
  
 }
 
 //private void destory(){
 // this.RemoveFromContainer();
  
 //}
 // Update is called once per frame
 void Update () {
 
 }
}


寫在後面

接下來的目標是音效音樂的使用,以及近期會被導入的Spine動畫,還有一些gitHub上別人開發給Futile的小外掛。謝謝收看。

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

[Unity] Futile 2D Framework 試用心得 31 Mar 2013 3:43 AM (12 years ago)



Futile是一套給Unity 用的2D Framework, 架構類似於AS3及Cocos2D,有用過這兩種的人會很容易上手。

官網 & GitHub位置: https://github.com/MattRix/Futile

Demo及入門教學影片: http://struct.ca/futile/

最近上架的Nimble Quest即是用Futile所開發

這是我目前試用的幾個Unity 2D方案中,最適合Flash/AS3人員轉移的了。原因是Futile不需要在Unity IDE上做太多操作,大部份都是用code來完成的,有點像是在Flash Builder上做事。唯一差別是寫C#而非AS3。

而沒寫過C#的人也不用太擔心,大致上寫起來不會太難,與AS3也有許多相似之處,尤其Futile延用了許多AS3人員熟悉的概念(Sprite, Container, AddChild...etc.) 以致上手時備感親切。

實際操作

1.於Unity裏建立一個新project(File -> New Project...)

2.至GitHub網站下載Futile的檔案

3.解開zip後,開啟裏面的Futile.unitypackage或是在Unity裏從Assets->Import Package->Custom Package…去安裝Futile


4.至以上步驟為止,我們已經把Futile安裝至我們的Project中了。

5.在Unity裏,把預設的Main Camera刪除掉


6.建立一個空白的GameObject


7.為方便辨識,在Inspector面板裏把新建的Game Object重新命名為"FutileObject"


8.在專案資料夾中,Assets/Plugins/Futile/裏放著Futile的所有程式檔。這時需先把主程式Futile.cs與剛建立的FutileObject綁定在一起。可以從Project面板把Futile.cs直接拉到Hierarchy面板中的FutileObject中,如下圖


9.可以在Inspector面板中確認Futile是否有綁進FutileObject裏


10.為了方便之後的開發,我們可以在Assets裏新建一個"Scripts"的資料夾,放置我們自己寫的.cs檔


11.在Scripts裏新建一個C# script檔,命名為"MyGame"



12 .接著我們試著在Futile裏呈現一張圖。Futile預設的素材載入路徑為/Assets/Resources/,所以先隨便找一張圖放在此處。(我放了一張名為baozi.png的圖)


13.接下來在Project面板中點兩下MyGame.cs,此時Unity會自動開啟MonoDevelop,這是Unity自帶的程式撰寫工具。以下是MyGame.cs需撰寫的內容:


using UnityEngine;
using System.Collections;

public class MyGame : MonoBehaviour {

 // Use this for initialization
 void Start () {
  FutileParams futileParams = new FutileParams(true,true,true,true);
  
  futileParams.AddResolutionLevel(480,1,1,"");
  
  Futile.instance.Init(futileParams);
  
  Futile.atlasManager.LoadImage("baozi");
  
  FSprite mySprite = new FSprite("baozi");
  Futile.stage.AddChild(mySprite);
 }
 
 // Update is called once per frame
 void Update () {
 
 }
}





14.最後記得把MyGame.cs也拉進FutileObject裏


15.點擊preview看看圖片是否有正常出現在畫面中


16 .在撰寫FutileParams及AddResolutionLevel等程式時,MonoDevelop就會自動出現各參數的解說了,在此就不解釋了。

17.Update這個event會有點類似我們在Flash裏用的EnterFrame,是一個持續執行的function,我們改一下剛剛的程式:

using UnityEngine;
using System.Collections;

public class MyGame : MonoBehaviour {
 
 private FSprite _mySprite;
 
 // Use this for initialization
 void Start () {
  FutileParams futileParams = new FutileParams(true,true,true,true);
  
  futileParams.AddResolutionLevel(480,1,1,"");
  
  Futile.instance.Init(futileParams);
  
  Futile.atlasManager.LoadImage("baozi");
  
  _mySprite = new FSprite("baozi");
  Futile.stage.AddChild(_mySprite);
 }
 
 // Update is called once per frame
 void Update () {
  _mySprite.rotation ++;
 }
}



18.正確的話,應該會看到載入的圖片不斷的轉動,程式中的rotation就如同AS3的使用方式,也可以改成x, y, alpha, scale等屬性試試。


注意: Futile的座標系統與Flash大不相同,Futile的(0,0)在畫面的正中間,y值向上為正,向下為負。

以上便算完成一個最基本的入門範例。除了一開始的刪除Main Camera,建新Game Object,以及把程式與Game Object設綁定之外,幾乎所有開發都是在MonoDevelop裏寫code。這點對於尚不熟悉Unity介面的人來說,是一個不錯的優點。

下一篇應該會來寫一個簡單的打地鼠遊戲。(其實也只是照著Futile作者的教學影片做變化而已,有興趣的人不妨自己去官網看影片會比較快)

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Spriter好好玩系列 (四) ---- 使用SpriterMC 2 Mar 2013 11:11 PM (12 years ago)


說在前頭:
如果你看到上一篇的SpriterAS已經覺得很夠用的話,那這篇SpriterMC其實可以直接跳過。原因是我個人認為SpriterAS目前的實用性大過於SpriterMC,而寫這篇只是因為都花時間研究了,就留下點筆記而已。另外SpriterMC唯一較強的是目前有支援Spriter的Bones及IK,所以除非有此特別需求或是好奇想看看的話,個人建議可直接跳過。
(以上心得基於SpriterMC v1.3版的狀況)

.官網:http://www.sammyjoeosborne.com/SpriterMC/

.github載點:https://github.com/sammyjoeosborne/spritermc

.基本用法:http://wiki.starling-framework.org/extensions/spritermc#usage

先看一下範例:

(click to open)
Download Source

載入SCML:
在官網中是這樣寫的:

var monster1:SpriterMC = SpriterMCFactory.createSpriterMC("monster", "xml/monster.scml");
monster1.play(); //Note: SpriterMC's will not actually start playing or show up on stage until SpriterMC.SPRITER_MC_READY is broadcast
 
//Add each SpriterMC to a Juggler, just like a regular Starling MovieClip
myJuggler.add(monster1);
但他們另外提供了事先做好TextureAtlas的做法,並且推薦用這種:
   var monster1:SpriterMC = SpriterMCFactory.createSpriterMC("monster", "xml/monster.scml", _textureAtlas);
monster1.playbackSpeed = 1.5; //Demonstrating playbackSpeed, which is like Scale, 1 == 100%. You can also set negative values to play backward
monster1.play(); //Note: SpriterMC's will not actually start playing or show up on stage until SpriterMC.SPRITER_MC_READY is broadcast
 
//Add each SpriterMC to a Juggler, just like a regular Starling MovieClip
myJuggler.add(monster1);
但我個人測試結果是,你必需使用TextureAtlas的寫法,否則使用第一種的話,執行時會出現error。

如何使用TextureAtlas:
照SpriterMC官網的說明,在他解析並產生這些SCML動畫時,會動態將所有的元件圖檔拼成一張大張的TextrueAtlas,這樣更能符合Starling的圖形加速處理,所以他建議使用者不如一開始自己就先手動做好拼圖這個動作。這件事我們可以利用TexturePacker來做(格式選AS3/Starling)。做完會像這樣:

一張大拼圖及一個xml描述檔。而AS3寫法可參考以下:
protected function init():void{
   loadTexture('assets/heroTA.png') 
  }
  
  private function loadTexture(_url:String):void
  {
   var _loader:Loader = new Loader();
   _loader.contentLoaderInfo.addEventListener(starling.events.Event.COMPLETE, textureLoadedHandler);
   _loader.load(new URLRequest(_url));
  }
  
  private function textureLoadedHandler(e:*):void 
  {
   
   _heroTexture = Texture.fromBitmap(Bitmap(e.target.loader.content));
   loadTextureAtlasXML("assets/heroTA.xml");
  }
  
  private function loadTextureAtlasXML(_url:String):void 
  {
   var _urlLoader:URLLoader = new URLLoader(new URLRequest(_url));
   _urlLoader.addEventListener(starling.events.Event.COMPLETE, atlasXMLLoadedHandler);
  }
  
  private function atlasXMLLoadedHandler(e:*):void 
  {
   var _xml:XML = XML(e.target.data);
   _textureAtlas = new TextureAtlas(_heroTexture, _xml);
   createCharacters();
  }
  
  private function createCharacters():void
  { 
    _hero = SpriterMCFactory.createSpriterMC("heroIK", "assets/heroIK/heroIK.scml",_textureAtlas,spriterReadyHandler,true);
  }
  private function spriterReadyHandler(e:starling.events.Event):void 
  {
   _hero.x= 100
   _hero.y=380
   
   
   _hero.setAnimationByName('idle')
   _hero.play();
   
   addChild(_hero);
   Starling.juggler.add(_hero)
   
  }

頭尾相連的動畫
成功讀入scml後,首先會發現動畫有點問題,就是原本來Spriter裏,最後一個keyframe都會自動做tween連回第一個keyframe,除非你自己取消這個功能。但是從SpriterMC讀進來的動畫卻完全都沒有這個效果。

正常來說,我們在Spriter裏可以透過上圖a點來切換是否要開啟"頭尾相連"的功能,但在SpriterMC裏目前完全無效,所以變通的方法就是自行將0ms的keyframe複製到動畫最尾處,如上圖b點。

動畫播完的callBack
這個功能對遊戲開發十分重要,例如我們做完一個攻擊、做完一個跳躍動畫,都會需要馬上切換至一般狀態的動畫,所以動畫播完呼叫一個callback會是十分常做的事情。在SpriterAS裏有提供了addCallBack這樣的method,但SpriterMC目前尚未提供這樣的api,我只能先用變通的方式來處理。
   private function onClickJump(e:MouseEvent):void{
   if(_hero.currentAnimation.name == 'jump')return;
   
   _hero.setAnimationByName('jump')
   _hero.loop=false;
   _hero.play()
   _hero.addEventListener(starling.events.Event.ENTER_FRAME,onEnterCheck);
  
  }
  
  protected function onEnterCheck(e:starling.events.Event):void{
   if(_hero.isComplete){
    _hero.removeEventListener(starling.events.Event.ENTER_FRAME,onEnterCheck);
    _hero.setAnimationByName('idle')
    _hero.loop=true;
   }
  }
這邊我使用ENTER_FRAME不斷去check他的isComplete是否為true,如此才能知道他是不是播完了。而在使用isComplete時,有兩個注意事項:
1.需把loop設為false,如此isComplete才有機會變成true,否則會永遠得不到true。
2.我個人懷疑這是bug。當我設_hero.setAnimationByName('jump')並成功播完一次後,下次再執行_hero.play()時,isComplete會在一開始就是true了,也就是它並沒有因為重新play,而重設為false。為了解決這問題,我直接修改了SpriterMC裏Animation.as這支檔案的play函式:
internal function play():void
  {
   //if we aren't looping and play was called while the animation was on its last frame, restart it
   if (!_loop && _currentKeyIndex == _lastFrameIndex)
   {
    _currentTime = mainKeys[_firstFrameIndex].time; //this is gonna make currentTime 0 or the length of the animation, depending on which way the animation is playing
    _currentKeyIndex = _firstFrameIndex;
    
   }
   _animationEnded = false;//maso add
   _isPlaying = true;
  }
修改過後就能正常執行了。

其他心得
SpriterMC目前能做的應用很少,所以試到這裏就沒什麼好繼續了,所以其他請自行參閱官網。倒是有一點較特別的是,Spriter的timeline是以ms為單位,但SpriterMC裏卻提到了一個叫currentFrame屬性,這裏試了一下,所謂的frame其實是Spriter中的Keyframe,第一個Keyframe得到是0,第二個是1,以此類推。不過在沒有call back的應用下,這個currentFrame其實也沒太大的用處。


Index:
Spriter好好玩系列 (一) ---- 什麼是Spriter ?
Spriter好好玩系列 (二) ---- Spriter 基本操作
Spriter好好玩系列 (三) ---- 使用SpriterAS
Spriter好好玩系列 (四) ---- 使用SpriterMC

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Spriter好好玩系列 (三) ---- 使用SpriterAS 1 Mar 2013 7:26 AM (12 years ago)


這篇要來把動畫跟AS3串接起來。用SpriterAS+Starling來做。

SpriterAS是一款基於Starling架構,專門播放Spriter動畫的AS3 Library。由加拿大的TreeFortress小組所開發。(TreeFortress專注於Mobile Game開發,成員包括了知名的gskinner大神)

.先看一下範例:

(click to open)
Download Source

上述範例我在Spriter裏做了三則animation,分別是idle(平常狀況)、fight_0(輕拳)、fight_1(重拳)。其他如眨眼、拳頭上的特效、頭掉下來,都是由程式控制的,而SpriterAS也支援Playback Speed的控制,這也是突顯了元件動畫優於連續圖檔的一大強項。

TreeFortress有寫了一篇Introducting SpriterAS - Play Spriter Animations with Starling。算是SpriterAS的入門介紹文,本篇範例也是看完他們的介紹文後的產物。建議有空可以先去看看,以下我只挑幾個重點介紹。

.github載點 https://github.com/treefortress/SpriterAS

.載入scml並叫出動畫

//**注意:SpriterAS是建立在Starling之上的,必需在Starling內
//**使用下列程式才能有作用。

protected var spLoader:SpriterLoader;

protected function init():void{
   
 spLoader = new SpriterLoader();
 spLoader.completed.add(onSpriterLoadComplete);
 //SpriterLoader可一次載入多個scml檔,所以參數是填一個array,可代入多個scml位置
 spLoader.load(['assets/hero/hero.scml'],1)
  
   
}
protected function onSpriterLoadComplete(spLoader:SpriterLoader):void
  {
   //從loader中取得動畫,以scml名稱為索引
   hero = spLoader.getSpriterClip('hero')
   //idle是hero.scml裏其中一段animation的名稱
   hero.play("idle")
   hero.x = 100
   hero.y =300
   addChild(hero)
   Starling.juggler.add(hero) 
}
這裏需要注意一點是,spLoader必需是class內的固定成員,不可以是function中的區域變數,例如我試過以下這樣寫的話,onSpriterLoadComplete將無法被觸發:
protected function init():void{
   
 var spLoader:SpriterLoader = new SpriterLoader();//不能用區域宣告
 spLoader.completed.add(onSpriterLoadComplete);
 spLoader.load(['assets/hero/hero.scml'],1)
  
   
}


.按下button切換animation至"fight_0"(輕拳),並在播放完畢時,切回"idle"
private function onClickFight0(e:MouseEvent):void
  {
   hero.play("fight_0")
   hero.addCallback(onOverFight,400)//400ms後呼叫onOverFight
}
protected function onOverFight():void{
 if(hero.animation.name != 'idle')hero.play("idle")
} 
直接使用 play("animation名稱"),即可切換動畫。
而 addCallback則是一個相當實用的method,可設定動畫播到多少ms時回call某個function,而此ms數會依照當初在Spriter裏設定的timeline來執行,因此不會受playback speed而受影響。
完整使用方式是:
addCallback(回call的function, 回call時間, 是否只執行一次)

.眨眼功能(動態切換元件)
private function onClickBlink(e:MouseEvent):void
  {
   hero.swapPiece("head_0", "head_1");
   TweenLite.delayedCall(.1,hero.unswapPiece,['head_0'])
}
swapPiece("A", "B")可將動畫中的A圖換成B圖。
unswapPiece("A")則是取消加諸在"A"身上的任何swapPiece效果。

.附著在拳頭上的粒子效果:
private function getHandPos():Point{
  var handImg:Image //Starling中的Image
  handImg = hero.getImage("leftHand_0");
  return new Point(handImg.x,handImg.y)
}
粒子效果非本篇重點,所以特效的部份就不多寫,上述程式只針對取得拳頭位置做示範,不過這邊要注意,取得的handImg.x及y後,記得還要加上hero.x及y,才是拳頭在畫面上看到的位置。

.頭掉下來(動態將元件拆離scml設定,或再組合回去)
private function onClickDropHead(e:MouseEvent):void
  {
   var headImg:Image = hero.getImage("head_0")
   if(headImg.y>-100){//弱弱的用y的位置來判斷目前頭的狀況
    hero.includePiece(headImg);//組回
    return;
   }
   
   hero.excludePiece(headImg,true)//脫離
   
   TweenLite.to(headImg,.6,{y:25,ease:Bounce.easeOut})
  }

.playback speed 控制
private function onSlideFPS(e:Event):void
  {
   _stage.frameRate = _fpsSlider.value
  } 
  private function onSlideSpeed(e:Event):void
  {
   hero.playbackSpeed = _speedSlider.value
  } 
這邊就沒什麼好解說的了,playbackSpeed代1的話表示正常進度,2為兩倍,0.5為半速,以此類推。

.動態才用到的元件
這邊算是個人使用心得。當我在製作範例中的眨眼功能,遇到了點小問題。原本我在Spriter裏編輯時只有三段animations,分別是idle, fight_0, fight_1,而這三段動畫完全沒用到眨眼的那張圖(head_1.png),使得當我在用hero.swapPiece("head_0", "head_1")時,會完全沒有做用。原因是當我查看scml檔的內容,發現scml在最前頭會先將所有圖檔列一份清單,之後的keyframe資訊就只會記下清單中的id,而這時又發現scml內只會記錄所有animation有用到過的圖檔,而不是所有放在project folder中的圖檔,所以它並沒有將我的head_1.png存進去,導致讓swapPiece("head_0", "head_1")無效。
變通的辨法是,再開一個新的animation,把所有程式會用到的圖都放進去,再輸出成scml即可。

例如上圖我就是把程式才會用到的圖,都放在"assets"這段animation裏。

.心得與注意事項:
SpriterAS使用下來,我個人覺得功能算是很完整了,已能符合大多數需求,唯一缺點是Spriter中的Bones功能尚未支援(如果有帶bone的scml,在spriterAS裏會爛掉),SpriterAS在官方blog是說未來會支援。不過我個人心得是,這部份還好,在我們真的在調比較細緻的動畫時,bones及IK其實沒什麼太大的幫助。另外作者群還有提到未來可能會推出JS版,有用JS的人可以期待一下。

*另一個library: SpriterMC有支援bones及IK,我在下一篇會簡單介紹一下SpriterMC


Index:
Spriter好好玩系列 (一) ---- 什麼是Spriter ?
Spriter好好玩系列 (二) ---- Spriter 基本操作
Spriter好好玩系列 (三) ---- 使用SpriterAS
Spriter好好玩系列 (四) ---- 使用SpriterMC

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Spriter好好玩系列 (二) ---- Spriter 基本操作 28 Feb 2013 10:42 PM (12 years ago)


這篇來講基本操作。

首先到這個頁面去下載,Spriter 同時支援了win及mac,請找自己需要的版本去下載


目前免費提供的版本是alpha4.1版,未來正式版也會分free及pro付費版,free版會有一些功能限制,這個頁面有詳細說明,有興趣可以看看。

各位應該有注意到下載頁面右邊有放了兩支影片,上面還寫了"Don't try Spriter without watching these first"。對,沒錯,請務必看過這兩支影片再來試會比較快。因為目前還在alpha 版,作者幾乎沒有提供任何教學、範例、說明書之類的,而軟體本身介面也沒有簡單到像iPhone一樣可以不看說明書就會用,所以建議是先耐心看過影片後,再來使用。

以下我就挑一些重點來說明

.新建Project時會請你選擇一個folder,請直接選擇你放置動畫元件的folder,這些元件才會出現在你右邊的清單裏,然後就可以從右邊的清單拉進stage裏。(如下圖)


.如下圖,當游標在A區時,滑鼠滾輪可縮放stage;當游標在B區時,滾輪可縮放timeline;C區也可設定stage的縮放,但他會自動隱藏,游標移到A及C區時會出現。


.下圖為Timeline區。Spriter的Timeline是以ms為單位,這樣比較能通用於各種平台。圖中a處為playhead,拖動playhead至你要新增keyframe的地方,然後直接調整你的角色,keyframe就會自動產生。另外也可以在拖動playhead至某時間點後,直接按下Add Keyframe(圖中b點),便會以當下角色的狀態產生一個新的keyframe。最後c點的按鈕為"是否要將最後一個keyframe做tween回到第0ms的keyframe"。(也就是頭尾串接的動畫)

另外上圖有顯示"CurrentPlaybackTime:391",為目前playhead所在的詳細位置,你可以在"391"那個地方點擊滑鼠,會出現手動輸入框,可精準調整playhead位置。

.左邊是目前出現在stage上的元件列表,可drag移動上下層關係,愈下面的layer在Stage裏表示愈上層。

值得一提的是,Spriter可在不同Keyframe中變換Layer的順序,這在以往Flash上是十分麻煩的事情。

.點擊Stage上的元件都會出現如下圖的畫面,元件四週的九個方塊是形變控制點,而a點可控旋轉,另外b點是中心點,所有形變、旋轉都是以b為中心。如果想直接輸入數字來控制元件,可點擊c點開啟詳細面板。


.提到旋轉,就不能不知如何調整中心點位置。一般情況下,只要拖曳中心點的那個圓圈即可,但一個新拉進stage的元件,Spriter預設會把中心點設在左上角,與左上角的形變控制點重疊在一起,直接移動的話會變成是點到形變,而不是中心點,所以在點擊時要注意一下游標位置。

當游標移至重疊的中心點時,中心點的圓圈會放大以方便分辨,這時若點擊在綠色區域,則會移動中心點,若點擊在紅色區域,則做形變控制。

.Spriter也支援元件中途變換不同圖片的功能,只要在stage上以右鍵點擊元件,就會秀出小面板讓你切換。此變換只對目前的keyframe有作用,之前的keyframe還會是舊的那張圖。也就是"換圖"這件事也是keyframe包括的內容之一。


.再來是類似Flash中的Onion Skin功能,可以讓你看到前幾格或後幾格keyframe的位置,這是2D動畫中十分重要的功能。開啟後效果如下圖

紅色表示前幾格,綠色表示後幾格。開始方式請參考下圖紅、綠色塊的位置,以playhead為分界點,timeline線以上的這塊區域,在紅色範圍內按右鍵拖拉即可設定過去的keyframes顯示,而綠色範圍內右鍵拖拉即可設定未來的keyframes顯示


.在Timeline上也以一次選取多個Keyframes,下圖中,先點一下a,按著"shift"不放再點一下b,即可選取多個keyframes。選取後,可進行移動、複製貼上等功能,也可在選取多個的狀態下,按著"alt"不放,去拖拉a點或b點,即可做整串keyframe的壓縮及放大。


.Spriter也提供了Bones系統及IK功能,只要在stage上空白處,按著"alt"同時以滑鼠點擊拖拉即可拉出一個Bone。在選取某個Bone的狀況下新增Bone的話,則新的Bone則會是原來選取的Bone的Child。選取任何Bone時,都會以顏色提示其主從關係,如下圖


.另外也可以在左側的Bone Hierarchy面板調整Bone的主從關係,在這面板也可以為各個Bone命名,以及將元件與Bone綁定,如下圖,head_2.png即與bone_000綁定在一起。這個面板是以樹狀結構呈現,一切都用拖拉即可完成。最後要注意一點,這個面板會列出所有Bones及stage上的元件,如果沒看到元件,可能是右上角的眼睛沒點開。(Show Sprites in Heirarchy)


.在調整Bone時,一樣有方形的形變控制點及圓形的旋轉控制點,當按著"shift"同時調整旋轉控制點的話,即可開啟IK功能。而在Bone上按下右鍵的話,會出現IK的錨點功能,也就是這段Bone的終點會釘在某個位置,並牽制其他Bone的變動。


.完成一串動畫即可存成一則animation,右側下的Animations可檢視目前所有的animation,並可在此面板中新增、複製、刪除animation,一個SCML檔可存入多個animations


.最後當所有動作都完成時,選擇"File"->"Save Project"即可存檔(同時會產生scml檔),然後就可以拿去做程式開發了。

.Spriter目前還在alpha,所以還有很多bug,例如偶爾會無預警關閉,用IK時bone會往奇怪的角度旋轉、莫明產生keyframe…等,都不是什麼大問題,不過建議就是勤於存檔,並期待正式版時這些bug都清掉。若發現什麼bug想通報作者的話,可參考這篇的回報方式。


Index:
Spriter好好玩系列 (一) ---- 什麼是Spriter ?
Spriter好好玩系列 (二) ---- Spriter 基本操作
Spriter好好玩系列 (三) ---- 使用SpriterAS
Spriter好好玩系列 (四) ---- 使用SpriterMC

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Spriter好好玩系列 (一) ---- 什麼是Spriter ? 28 Feb 2013 6:45 AM (12 years ago)


Spriter 是一套專門製作2D 遊戲動畫用的工具,官方自稱的副標是:
"The Ultimate 2D Game Animation Solution"
最近試玩幾天的心得是:假如他把一些小細節修得更完善的話,確實是有潛力揹起這樣的稱號。

Spriter 最早是出現在Kickstarter 上,並於2012/4 完成募資。可以先看一下他在Kickstarter上的介紹影片,之後再到他們的官網看看介紹及教學,還有目前版本狀況。
(本文撰寫時仍為alpha 4.1版,可免費下載,正式版預計2013 Q1 release)

簡單來說,目前2D遊戲的開發,不論是用什麼工具或程式語言,其動畫部份大多都會先請美術人員輸出一份SpriteSheet圖及描述檔。

(大概像這樣的東西)

上圖的動畫是用Flash繪製的,角色是由許多parts組成,然後在時間軸上設定多個keyframe,並於各個keyframe上將角色擺成不同的姿勢,最後才串成動畫

上圖動畫共使用了18個parts,拆解後的樣子如下圖:

利用這18個parts,我們可以擺出至少十多種不同的姿勢,但隨之而來的問題是,動作愈多最後產生的SpriteSheet檔就會愈大;而且不是只有關鍵姿勢而已,為了讓動畫效果流暢,姿勢與姿勢之間還會需要許多keyframes來串接。

以上面動畫的為例,從揮拳出去,再收拳回來到原點,一個簡單的動畫就用了8個keyframes來組成,如此不難想像一個完整的遊戲角色,全部動畫輸出的SpriteSheet檔後會有多大張,這些都會在程式開發階段,對記憶體管理及效能優化上造成負擔。

尤其近年來大家特別關注的手機、平板遊戲市場,在記憶體、CPU有限,但畫質又要與桌機品質相似(retina display)的狀況下,這種問題就格外需要注意。

而Spriter就是因應這樣的問題而生,他提供了一個像是陽春版的Flash介面,有timeline、keyframe這些東西。

(介面大致如上圖)

我們可以import多個png檔,當做組成角色的parts,然後在他的timeline上設計不同的動作並標示成keyframe,而keyframe完成後,中間的tween會自動產生。最後Spriter 會將所有keyframe的資訊輸出成一份SCML檔,我們只要將這份SCML檔連同那些parts圖檔,import到任何支援Spriter 格式的開發平台後,即可播放這些動畫。
(這邊可以查詢目前已支援Spriter的技術有哪些)

而SCML的內容其實只是XML,裏面是只記錄了每個keyframe的時間及各個parts所在的位置、尺寸、角度等資訊,如此即使再多的動作,也只是增加文字資訊,圖檔則只有一開始的那些parts而已。這種做法會比傳統的SpriteSheet省下許多的檔案大小負擔。

這種模式其實會讓人想起90年代末期,Flash崛起的過程。當時也是頻寬不足的狀況下,一般動畫格式不是GIF就是MPG,AVI等影片檔,但不論哪種,其原理都是連續圖檔播放,檔案都會很大,讓user難以下載。而Flash就是改以元件化的播放格式,大大減小了動畫檔的大小。而Spriter目前做的事情,便是類似的邏輯。
所以我個人認為:下一版的Flash應該要做出類似或直接支援SCML格式,不要再像CS6一樣,輸出了一堆SpriteSheet格式給別人用,然後自己一點符合時勢的創新都沒有。

最後,Spriter這套軟體目前還在alpha中,有許多UI操作上的小細節我個人覺得還不是很順手,期望他未來的版本可以更加成熟。


Index:
Spriter好好玩系列 (一) ---- 什麼是Spriter ?
Spriter好好玩系列 (二) ---- Spriter 基本操作
Spriter好好玩系列 (三) ---- 使用SpriterAS
Spriter好好玩系列 (四) ---- 使用SpriterMC

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

《Indie Game: The Movie》觀後心得 25 Jun 2012 5:58 AM (12 years ago)

Indie Game: The Movie screening at #GDC2012 #ohyes #sohappy
「做遊戲這件事,只有在一兩個人執行時,才能得到最大的快樂吧!」
這是我看完這部片,立即想到的簡短心得。


關於這部片子…
先簡單介紹一下片子本身。整部片訪談了許多Indie Game創作者,並以三個作品做為此片的主軸:

Super Meat Boy(點擊進入官網)

FEZ(點擊進入官網)

Braid(點擊進入官網)


整部片的主軸環繞在這三款遊戲的開發過程,記錄著他們某段時間的心路歷程,來讓觀眾體會到獨立遊戲開發者的各種辛酸、快樂及心境變化。很推薦給曾經、正在或未來試圖進行任何獨立遊戲開發計畫的朋友們來看此片。(而我想,會注意這部片的,大概也只有這三種人吧)


以下才是心得…
整片看完對我來說,感觸是深刻的,畢竟自己也曾經歷過一小段獨立遊戲開發的日子,而目前也處在商業遊戲公司的體制下工作著。所以在經歷過獨立及非獨立的遊戲開發流程後,再來看這部片子時,確實是會被片中不少橋段及對白,激起一些共鳴。

舉例來說

「做這遊戲就像是挖掘出我最深沉的缺點及弱點,然後放到遊戲裏」
這點尤其發生在遊戲開發的過程當中,在開發低潮時特別明顯…

「作家為什麼寫作,因為這是他們表達自己最有效的方式,所以我做Game,對我來說這也是最有效的方式」
這應該也是不論何種型式的創作者,最基本的出發點!

「遊戲是終極的藝術型式,它是古今所有媒介的總和,再加上互動性,這超讚,我想成為它的一部份,我想在定義電玩遊戲這件事裏有發言權」
深表同意,自己也曾在一些演講場合說過類似的話,而這也是我認為做獨立遊戲開發最迷人之處。

「我們是第一批跟著電玩一起長大的世代」
這句話說在電影前的5分鐘那段,會讓我感覺在暗示某種使命感…(但也可能只是我一廂情願吧XD)

「他們有一千人在做耶,而我們只有兩個人耶。但大家還是說:『你怎麼做這麼慢啊?』,我咧…(中指)」
這句很好笑也很直接,也很讓我有共鳴,因為我也不只一次跟我朋友們說過「你是在靠北啥小啊,不然你來做嘛」XD

「如果做不出來,我想我會自殺」 「這不只是一個遊戲,因為他與我緊緊相連,它就是我,我的自我意識,我對自我的認知…這是我的身份,我就是做FEZ的那個人」
這段很直接點出獨立遊戲創作時,作者與作品間的連結關係,而這層關係會在你放棄許多事物後,全心全意只為此作品時,變得非常非常非常地強烈…

另外還有一幕讓我印象深刻,就是Braid上市後,幾個黑人在Youtube上嘲笑著遊戲本身,而鏡頭停留在作者Jon的側影…
Indie Game: The Movie

我想這裏點出了做創作(不只遊戲)過程中最殘酷的一點:即使你已經精疲力盡,交出了你自認最好的作品,但仍必需要保留最後一絲氣力,來面對世上各種最嚴厲的批評與最膚淺的嘲笑。

沒錯,這也許讓人十分傷心,但這也是做為創作者所必需承受的;而另一方面,當有人對作品給與掌聲時,你也將獨享所有的榮耀!


看完片子後想到的一些事情
我想到的是獨立與非獨立,極少數人或一大群人,在開發遊戲上的差別。

相信大部份投入遊戲業的人,都曾懷著「我以後一定要做出像XXXX一樣的史詩鉅作!!」那種氣勢我想應該是不亞於「我要成為海賊王!」這樣的句子。不過電子遊戲發展至今已超過30個年頭,想要像Richard Garriott當年那樣,獨力開發Ultima,並成為當代的"鉅作",基本上不已不太可能在現代實現。

現在所謂的商業鉅作,如果沒有個幾百人,應該會很難完成,光是一個片頭動畫,可能就耗掉一個數十人的團隊,半年以上的時間。而暫且 撇開製作面,當遊戲製作完,要上架,要通路,要行銷,要廣告…這些一連串可能又與另外數百個人牽動著。而要完成這一大堆事情,除了你要超會做遊戲外,還要跟一大堆人討論、溝通、談判、妥協、爭吵、看臉色以及忍氣吞聲。最後好不容易完成後,你才發現整個遊戲跟你一開始想像的完全不一樣,而你在裏面其實也只扮演著無足輕重的角色,遊戲裏除了各種迎合市場的設計因素外,也幾乎完全找不到你自己存在的影子。

又或者是你很希望加入某個因素,但你必需要說服一堆工作伙伴,與一群人在"好不好玩"這樣主觀的議題上,做各種莫明奇妙的嘴炮攻防,最後不是你累了,就是對方妥協了,但同時遊戲本身可能也爛掉了…

所以如果本身對製作遊戲這件事,不是只是當作一個賺錢的Job,而是保有一些些遊戲設計的熱血的話,可能多多少少都會在商業開發體制下遭遇到挫折後,偷偷將眼光望向Indie Game這樣的領域…

另一方面,如同電影裏提到的,現在這個時機與環境,對Indie Game來說是正面的。有網路,有手機,有各種可以快速發佈及獨立銷售的管道。當這些種種條件都出現在面前時,原本就渴望創作遊戲的人怎麼可能不熱血起來呢?

最後…
整篇心得其實寫得有點凌亂,因為我認為完整的心得,我可能要慢慢思考,慢慢體會後才能成形。不過仍然想在剛看完電影的片刻,快速記錄一些當下的想法。還有,其實我也只是想抽個獎而已XD

總之,做遊戲這件事,只有在一兩個人執行時,才能得到最大的快樂吧!我想…

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

AIR2.6 for iOS試用筆記 20 Apr 2011 7:10 AM (14 years ago)

無標題

延續上一篇[*],本篇要做進一步的開發筆記
[*]這篇本來是寫在3/25日左右,也就是AIR 2.6 公佈的那時候,主要是想針對2.6+Burrito在開發時,要注意的一些小重點。
不過草稿寫一半後,就先去忙別的事了,然不久後,CS5.5, FB 4.5也發佈了,所以推論差不多5月下旬就會上市,到時這篇筆記其實就沒有太多價值了。
所以不如就現在把這篇寫一半的筆記,先po出來好了,也許有需要的人,可以參考看看~



基本發佈:
以command line輸入下列即可

*各參數細節可查閱文末的Package for iPhone文件

[推薦]嫌麻煩的話,也可用羊小咩開發的iOS Package Tools for AIR (懶人封裝工具)

Retina Display Support:
若直接以上述指令發佈ipa,安裝於iPhone4的話,會發現實際秀出的尺寸只有320x480,此時可在YourApp-app.xml裏,修改requestedDisplayResolution屬性為high即可,如下


自訂icon:
同樣在YourApp-app.xml裏可設定app於home screen上的icon,如下

只是光這樣並不足夠,在compile時,也需把要加的icon檔路徑一併加進去,如下:

不過這樣打指令很長,日後要調整也很不方便,所以建議改用

這樣不只是icon圖,日後只要是有用到的外部檔,統統丟進asset/下,就都會一併包進去了
Initial Screen
就是點進app時,一開始呈現的畫面,可用一張png圖來設定(若無設定則會是一片黑色)
這部份只要做一張640x960的png,取名為"Default.png",並在打包時一併包進去即可

StageWebView
內嵌網頁的功能,是目前要做Facebook, Twitter服務連結的必要功能,此外也可以拿來做一些UI上的協助。基本語法:

另外2.6新提供了drawViewPortToBitmapData函式,這東西算是滿實用的,簡單說他是可以針對網頁做一個快照,方便我們做其他用途,例如我們可以抓到圖之後,做旋轉、移動等效果。另外,正常在使用StageWebView時,Flash其他content是無法再疊在網頁上面的,這時我們就可以用drawViewPortToBitmapData,先做快照,再把StageWebView暫時隱藏,待上方的效果做完後,再恢復原來的WebView即可。用法如下:


Microphone
麥克風的支援與原來AS3提供的麥克風支援語法一樣,這部份用原來的方式去寫就可以了
[AS3 Microphone官方文件]

小結
本來要再往下寫的,例如Camera, CameraRoll, CameraUI等,但近來有些事要忙,有興趣的人請先自行參閱AS3相關文件。
也許我哪天有閒可能會再接著寫吧...

參考:
Adobe AIR 2.6 Developer Release Notes
Building Adobe AIR Applications with the Package for iPhone

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

[簡報]AIR on Mobile (2011) 18 Apr 2011 7:14 AM (14 years ago)

今天在AS讀書會分享的簡報, 簡單介紹了一下AIR 在 iOS 及Android上的發展現況

Air on Mobile (2011)
View more presentations from Maso Lin.

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

[新聞稿]奧多比宣佈推出新一代 Creative Suite 5.5 產品系列 12 Apr 2011 6:48 AM (14 years ago)

奧多比宣佈推出新一代 Creative Suite 5.5 產品系列
期中重大更新版本將為 Flash、HTML5、影像、行動數位出版帶來絕佳創意工具,並將平板領域整合至創意工作流程中

【2011 年 4 月 12 日,台北訊】全球軟體大廠奧多比今日宣布推出最新一代 Adobe® Creative Suite 5.5 產品系列,將為設計與開發人員針對新興智慧手機與平板電腦平台提供強大創意能量 - 行動溝通革命潮流正在全面改變內容傳遞與消費模式。今日的新產品發表為 Creative Suite 產品推出策略帶來重大變革,這項業界領導的設計及開發軟體完整涵蓋印刷、影像及線上媒體創意工作流程領域。而奧多比也決定在 Creative Suite 產品原本 24 個月的新版推出週期外,從 Creative Suite 5.5 開始推出期中更新,這項期中版本更新將能讓全球創意社群領先以最即時的速度趕上內容編輯設計趨勢。



「Creative Suite 5.5 將能為所有裝置帶來嶄新的數位開發體驗,包括已躍為市場主流的智慧手機及平板電腦產品。」奧多比總裁暨執行長 Shantanu Narayen 表示:「出版商、媒體公司、廣告商與企業主正在轉變他們的內容開發及傳遞方式。而奧多比將持續以技術創新支援他們製作、管理、評估與傳遞各種令人驚嘆的內容。」

奧多比大中華區總經理黃耀輝表示:「亞太地區市場,尤其是台灣,正領先全球大量製作及消費數位內容。台灣地區向來擁有非常高的新產品市場接受度,同時也有極高的手機網際網路服務應用率。我們已經看到越來越多的領域,像企業或政府服務、遊戲及娛樂、甚至教育單位對於透過智慧手機及平板電腦等多樣裝置傳遞數位內容呈現出高度需求。而 Creative Suite 5.5 的推出將能協助台灣延續此一重要進展,帶來所需技術與工具,讓各領域能夠持續提供最具創意及高品質的本地內容,滿足廣大用戶渴求。」

最新一代 Creative Suite 5.5 Web Premium 套裝產品整合 HTML5 及 Adobe Flash ®編輯工具,讓用戶針對所有螢幕裝置,製作、傳遞及標準化最為創新、豐富的內容及應用程式。新產品協助設計與開發人員推出Android™、BlackBerry® Tablet OS、iOS 及其他平台的行動應用程式;運用 HTML5,製作能跨越所有螢幕裝置的豐富瀏覽器內容;以及發揮 Flash Player 強大效能,傳遞高品質影像內容、娛樂遊戲及豐富型網路應用程式(RIA)。

透過今日的新產品發表,奧多比更能將平板裝置納入創意工作流程中,將設計環境大幅延伸至桌面以外。Adobe Photoshop的全新腳本引擎(scripting engine)與強化的 Photoshop 軟體開發套件(SDK)能讓開發人員由 Android、BlackBerry 及 iOS裝置與 Photoshop 互動創作平板應用程式。奧多比同時宣佈推出三項最新 iPad 應用程式- Adobe Color Lava for Photoshop、Adobe Eazel for Photoshop 及 Adobe Nav for Photoshop,展示使用平板電腦帶動 Photoshop 工作流程的創意可能‡。

針對影像及音訊專業人員,Adobe Creative Suite 5.5 Production Premium 套裝產品能帶來突破性的效能、工作流程改進、創意創新、及強大嶄新的音訊編輯功能,讓 Production Premium 將更為廣泛地由全球廣播、電影製作及影像專業人員採用。在 Adobe Premiere® Pro CS5 時所推出的多項創新功能之一的強大 Adobe Mercury Playback Engine 播放引擎,更將擴大圖形處理器(GPU)硬體支援範圍,涵蓋筆記型電腦及其他顯示卡,讓用戶能更快速開啟專案,取得即時回應及執行更加流暢的高解析度作業。

取得數位出版最新進展

Creative Suite 5.5 Design Premium 包含有奧多比多項最新創意數位出版產品,已由全球多家領導雜誌及商業出版集團導入,編輯製作出極具吸引力的平板電腦裝置數位內容。運用 InDesign® CS5.5,結合 Folios Producer 工具組,設計人員將能針對平板裝置為版面加入嶄新等級的互動元素。文件中能夠包含影像、聲音、全景閱覽、360 度物件轉向與影像縮放,同時還能整合 HTML 及 HTML5 內容與其他互動內容疊覆,帶來令人驚艷及最具吸引力的閱讀體驗。Creative Suite 5.5 能高度整合 Adobe Digital Publishing Suite,支援更多樣化的平板裝置出版、內容銷售與分析需求。

為 Android、BlackBerry Playbook 及 iOS 裝置設計行動應用軟體

推出新一代 Creative Suite 5.5 正迎合行動裝置銷售爆炸性成長及功能大幅進化時期,能滿足大量內容及應用程式的開發及消費需求。藉由 Adobe Flash® Builder™ 4.5(整合於 Creative Suite 5.5 Web Premium)及Flex® 4.5,開發人員將能輕鬆製作及部署行動應用程式至 Android、BlackBerry Playbook 及 iOS 裝置,預估到 2011 年底,市場上的裝置總數將突破2億台。

Flash 功能裝置快速成長

預估到年底前,市場上將有超過 1 億 3 千 1 百萬支安裝 Flash Player 的智慧手機,Adobe Flash 將讓內容可以透過瀏覽器傳遞至多樣化的桌面與裝置。Flash Player 目前支援 Android、HP webOS 及 Google TV,BlackBerry Tablet OS、下一版 Windows Phone、Samsung Smart TV 及其他平台也即將支援 Flash Player。如需更多 Adobe Flash 平台相關資訊,請造訪: http://www.adobe.com/flashplatform/。

加速完美創意工作流程

Adobe Creative Suite 5.5 整合了 Adobe CS Live*† 系列線上服務,能加速關鍵創意工作流程,讓設計人員更專注於最佳的創意工作。CS Live 線上服務包括:Adobe BrowserLab、Adobe CS Review、Acrobat.com及由 Omniture 提供的 Adobe SiteCatalyst® NetAverages™。

新一代 Creative Suite 產品系列,包含 Adobe Creative Suite 5.5 Master Collection 等多樣組合,其中分別包括奧多比多樣業界領導創意工具,例如 Photoshop、Illustrator®、InDesign、Acrobat®、Flash Builder、Flash Catalyst®、Flash Professional、Dreamweaver®、Adobe Premiere Pro 及 After Effects®,這些最新一代軟體可以單獨採購,或整合於 5 套 Creative Suite 版本銷售。完整的 Creative Suite 5.5 套裝產品系列,包括 Creative Suite 5.5 Master Collection、Creative Suite 5.5 Design Premium、Creative Suite 5.5 Web Premium、Creative Suite 5.5 Production Premium 及 Creative Suite 5.5 Design Standard。

價格與上市時間

Adobe Creative Suite 5.5 預定將於 30 天後,透過奧多比授權經銷商正式上市。預估市場建議售價:CS5.5 Master Collection 為 NT$111,200(未稅)、CS5.5 Design Premium 為 NT$81,260(未稅)、CS5.5 Web Premium 為 NT$76,980(未稅)以及CS5.5 Design Standard 為 NT$55,600(未稅)。另外還提供有升級與大量授權價格。

適合中學及高等教育機構學生、教職員的教育版本,可以透過奧多比授權教育經銷商取得。如需更多關於中學及高等教育機構的教育大量授權方案,請造訪: www.adobe.com/aboutadobe/volumelicensing/education

如需更多產品功能、作業系統支援、升級規定、價格及語言版本相關資訊,請造訪:www.adobe.com/go/creativesuitemaster

關於奧多比

奧多比藉由數位體驗正在改變世界!更多資訊請造訪:www.adobe.com


© 2011 Adobe Systems Incorporated. 版權所有。Adobe、Adobe logo、Adobe AIR and AIR、Adobe Premiere、After Effects、Creative Suite、Dreamweaver、Flash、Flash Builder、Flash Catalyst、Flex、Illustrator、InDesign、Photoshop 及SiteCatalyst NetAverages皆為奧多比在美國及其他國家地區的商標及註冊商標。Android商標隸屬Google公司。其他所有商標則分屬其擁有者所有。產品售價為市場建議售價,經銷定價可能會有所差異,價格不包含稅金及運費。



‡需要無線網際網路連結。行動及平板應用程式需要另外下載,同時必須同意其他條款規定,例如並非每個國家地區都能提供相同的應用程式或語言版本,或者可能因為其他原因,服務有所變更或終止而不會另行通知。另外可能會有額外的費用或月租費。



* CS Live線上服務提供限時免費試用,詳情請造訪 www.adobe.com/go/CSLive



† Adobe線上服務包含Adobe CS Live Services,僅提供13歲以上成年用戶使用,同時必須遵守奧多比線上隱私策略條款(http://www.adobe.com/go/terms)。並非每個國家地區都提供相同的線上服務,用戶使用需要登錄,服務如有變更不另行通知。 服務可能會產生額外費用。

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

AIR 2.6 SDK發佈,更新iOS支援 21 Mar 2011 9:29 PM (14 years ago)

無標題

今早的新聞,我試了一下用Burrito(Flash Builder 4.5 preview版)搭配新的AIR 2.6 SDK,輸出至iOS的方式,步驟記錄如下



準備工作:
下載Burrito
下載AIR2.6 SDK

解開2.6SDK後,將檔案覆蓋到Burrito安裝目錄中的sdks/4.5.0/下,例如以Mac OSX為例
/Applications/Adobe Flash Builder Burrito/sdks/4.5.0/

開發:
之後你就可以依照原來的方式開發,開project可選Flex mobile project及AS mobile project
(本篇重點不在於開發過程,所以這部份請自行google:"burrito mobile development")
不過有一點需要注意是,spark元件目前並不支援iOS,所以如果你開了Flex mobile project並使用了spark 元件的話,到iOS上看會是空白的。所以要試iOS的話,請用AS mobile project。

輸出:
由於當初Burrito發佈時,裏面只包含發佈android所需的GUI介面選項,所以即使現在更新了AIR SDK後,仍無法很方便地點一點就產出.ipa檔。此時需用command line來完成這件事

早期我們用Flex for iOS時,可用Adobe提供的Package for iPhone來完成,現在AIR2.6則把PFI整合進來,所以command line的參數會跟PFI時用的一樣,只是指令由PFI改成ADT了,範例如下

adt -package -target ipa-test -provisioning-profile your.mobileprovision -storetype pkcs12 -keystore your.p12 HelloWorld.ipa HelloWorld-app.xml HelloWorld.swf

如此就能順利用Burrito產出AIR 2.6的iOS檔案

心得:
基本上AIR從2.0到2.6,於Mobile上的進展如下
AIR 2.0 ---- support iOS
AIR 2.5 ---- 多了support Android,並於Android方面多加數個API,如Camera, Microphone, WebView…等
AIR 2.6 ---- 把2.5新增於Android的API也同步支援於iOS,並對兩平台同步多了少數幾個API

*當然另外還有一些效能提昇等就不贅述了。另外在2.5~2.6中間還有出一個for BlackBerry的SDK,在此也不詳列了

所以說2.5時有玩過那些API的人,拿到2.6時可能覺得沒太多的新鮮感;不過總結來說,iOS方面API進度有跟上,仍算是一件可喜可賀的大事
反正有興趣的人就玩看看吧~

參考
Adobe AIR 2.6 Developer Release Notes
Adobe AIR 2.6 SDK now available with updated iOS support!

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Play with AIR for Android 簡報 18 Mar 2011 3:22 AM (14 years ago)

去年參加PTT Flash網聚時的簡報及錄影,題目是:Play with AIR for Android


Play with AIR for Android
View more presentations from Maso Lin






Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

分享於中國科大的三則簡報 18 Mar 2011 3:12 AM (14 years ago)

去年曾去中國科大做過三場簡報,整理歸檔於此


My trouble with Adobe Flash
View more presentations from Maso Lin

Flash on WebGame
View more presentations from Maso Lin

Multimedia And Mobile
View more presentations from Maso Lin


Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Corona SDK - Group內成員命名及取用 8 Feb 2011 2:41 PM (14 years ago)

無標題

好久沒碰Corona SDK了,因為過年前有人問到,所以來寫個小範例

問題:把東西insert進group後,一定要另外建個table用index來取這些東西嗎?

答:其實也可以用像AS2的 _a['_b']的方式來取物

重點是在當你把某物件insert進group後,此時他仍不是group的成員之一,所以必需自行將某物件定義為group的某成員才行
例如 local _obj
group._obj=_obj
之後就可以用 group._obj或group['_obj']等方式來控制物件了。

以下為範例:



Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

原來Backgrounder會讓Xcode在Device Build時出問題 13 Jan 2011 2:59 AM (14 years ago)

Continue給它按下去就對了

今天打開之前練習的Cocos2D iPhone練習檔,在Simulator 上一切正常;但只要用Device測時,一進app就會馬上hang住,且下面訊息會得到一段 Program received signal: “SIGUSR1”. 訊息

後來查詢才知道,原來是我用了Backgrounder,並且設定了"enable at launch"所造成。

解決方式很簡單,到Run->Debugger或Console叫出面板,按一下Continue 讓App繼續即可。

參考文章:Backgrounder vs Build and Run

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

關於KairoSoft最近幾個iPhone移殖作品的出版時間… 3 Jan 2011 7:31 PM (14 years ago)

Kairo Soft首頁logo按下去會出現Kairo君
(Kairo Soft首頁logo按下去會出現Kairo君)

可能由於Game Dev Story在App Story上的熱賣,使得KairoSoft陸續把以往的舊作拿來移殖了。


.遊戲發展國++ (Game Dev Story)
-2010/07/12 日文版於日本App Store上架
-2010/10/09 英文版於全球App Store上架
而遊戲發展國++又是從「ゲームスタジオ物語」(Game Studio物語)移殖而來
所以我們可以查一下「ゲームスタジオ物語」的出版時間
-2010/02/01 FeaturePhone版「ゲームスタジオ物語」上架


.ゆけむり温泉郷
-2010/12/16 日文版於全球App Store上架
-2009/10/30 FeaturePhone版本上架,可於DoCoMo, SoftBank 及Kairo Park下載


.ワイワイ!ゲーム販売店
-2010/12/31 日文版於日本App Store上架
-2009/06/26 FeaturePhone版本上架,可於DoCoMo, SoftBank 及Kairo Park下載







所以從原作的時間來看,出版順序其實是:
-2009/06 ワイワイ!ゲーム販売店
-2009/10 ゆけむり温泉郷
-2010/02 ゲームスタジオ物語 (=遊戲發展國++)

這也是為什麼有人(iPhone User)玩過GameDevStory後,再去玩後兩款反而覺得遊戲性比較弱的原因,反倒是移殖到TouchScreen上一些UI細節愈做愈好。
所以也別再說「Game Dev Story續作來了…」「KairoSoft新作來了…」這樣的標題了,因為都是舊作啊。

另外也不要再說「Game Dev Story以簡單致勝…」「Kairosoft以復古風致勝」之類為標題開始作文了,因為他並不是故意要做8-bit復古,而是他本來在FeaturePhone上就是做這樣的,iPhone/Android上都是移殖而已。

而且,在除去簡單的畫面/操作之後,這些遊戲中的平衡設計可說是十分的精巧複雜啊,所以也請別再說他是多麼簡單了。


最後說一下:
從調查KairoSoft的資料來看,會發現這家公司從2005年起(或更早)就開始做很多Mobile或PC Downloadable的小遊戲,且全部都是這種「經營模擬」類的遊戲,所以我們現在玩到這幾款有著精巧設計的作品,都是靠多年經驗累積出來的~
*有不少PC downloadable game都是無料下載的,有興趣的請到http://kairosoft.net/pc/找找,也有不少有被中文化,可google看看

另外值得一提的是,在Kairo眾多作品中,我個人發現有三個系列似乎是他們有在做長期發展的:

Game Shop系列
-『ゲームショップ物語』、『ゲームショップ物語2』、『ワイワイ!ゲーム販売店』
Game Dev系列
-『ゲーム発展途上国』、『ゲーム発展途上国2』、『ゲーム発展途上国 II DX』、『ゲーム発展途上国++』
漫畫家系列
-『まんが奥の細道』、『まんが奥の細道2』、『ワクワク!まんが道場』、『まんが一本道〆』

如果說Kairo有計畫把這三個系列都推出iPhone版的話,那下一款在App Store上出現的移殖,很有可能會是2009/08的『まんが一本道〆』。(我個人對漫畫家系列還滿期待的啊)
(圖片版權屬Kairosoft所有)
(圖片版權屬Kairosoft所有)


參考資料:
http://kairosoft.net/news.html
http://kairosoft.net/kairopark/
http://kairosoft.net/pc/

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

DIY iPhone Stylus 23 Dec 2010 3:00 AM (14 years ago)

1000000255

最近好想畫畫,想用iPhone + Brushes畫畫。但記得上次用手指頭畫的經驗不是很方便。
雖然坊間也有一些iPhone Stylus可買,但都不怎便宜。所以就來DIY一下。


從Google可找到至少三、四種不同的做法,我就挑個最簡單好做的試試

材料:斷水的原子筆一支、Mini士力架一包,如頁首那張照片
(其實是任何有鋁薄包裝的東西就可以了)

把士力架吃掉,並把包裝紙攤平,記得要把裏面擦乾淨
1000000256

包覆到筆上面
1000000257
這邊有個重點是,鋁薄要包長一點,一定要包到手可以握到的地方
因為其原理是利用鋁薄為導體,將手指的靜電傳至筆尖,所以鋁薄一定要包到手會握到的地方

另外有一點是,筆尖的地方也無法做太細太尖,至少要有一點點小平面,所以我塞了一點衛生紙在筆尖處
1000000260

最後用膠帶捆一捆就完工了
1000000263

試畫一下(以下用Brushes示範)
1000000265

1000000266

心得:
比用手指好畫多很多!
不過筆尖如果有辨法修細一點就更好了,不然在一些細微處還是不太好畫。
但還是比用手指好畫,這樣就滿值得了…

以下是其他各種做法的參考資料,有興趣的人自己去看看

日系精緻版


簡易鋁薄版


神奇鈕扣版

Make Your Own Stylus for Your IPod Touch/iPhone - For more funny movies, click here

3M海綿版


Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Flash for iPhone之「回來就好,其他都不重要」 9 Sep 2010 9:09 PM (14 years ago)

100064263

今早最讓Flash developer們注意的新聞莫過於Apple 對iOS app tools的解禁。有種「沉冤得雪」,或是「回來就好,其他都不重要」(註1)的感覺。在此整理一下個人對這件事的心得及蒐集到的相關資料。

註1:「回來就好」此語出自James在我噗裏的回文,感覺相當貼切微妙。

1.解禁的只是App開發tool,並不是Browser的Flash Player
很多人看到「Apple 對Flash解禁」的標題就會High過頭,但請注意這只是對app開發tool,而不是Browser Plugin。當初在Flash CS5裏的Package for iPhone本來就是配合著iOS的方式,生成符合iPhone格式的.ipa檔案,再用合法的方式上架。基本上對整個App store生態本來就不會有太大的影響(有也只是app量的增加速度),一切其實都很安份合理的,所以這也是當時3.3.1條款出現時,為什麼Flash Developer們很不能認同,因為禁得十分不合理。

而當時賈伯斯則指出,3rd tool效能差等等之類的言論做為解釋。我個人覺得如果效能不好,應該就會被市場機制淘汱了吧,有必要在開發階段就禁止大家用什麼工具嗎?然而最好笑是當時還有不少Apple教義派(註2)跟著幫腔好一陣子。

另一方面,如果今天是說「開放Browser plurgin Flash Player」,我個人覺得這才是比較有影響力的一步。因為這會影響App Store裏許多與現有Web Flash Content類似的App,其次也會影響目前User在選擇購買 iOS與Android間的判斷條件。

註2:當時常有人著文開頭就寫「先聲明我不是蘋果教義派,不過…」但實質上就是在賣一堆蘋果週邊產品的Blog/網站,根本就是超級大信徒,看了就很好笑。

2.Flash做為App開發工具的競爭力又如何?
首先談效能,Flash Package for iPhone(以下簡稱PFI)在3G上實測很差,3Gs上還ok,iPhone4我還沒試過,但如果是以同樣1G cpu的Nexus One來參考的話,個人覺得還算可以期待,至少在開發一些小Game,小Tool時,1G cpu上跑起來還算不錯。

另外我覺得效能問題,也會隨著硬體逐年的加強而慢慢降低,但不絕不會消逝。因為再怎樣Flash永遠比不上原生的obj-c效能好。所以未來有可能會有一大堆Flash做的小品在App Store上,只有大作強作才會是用obj-c來寫。而話說回來,在手機平台上,小品game的市場其實不見得就會比大作來得小。

再來談對系統API的支援。不知是不是之前被Apple氣到的關係,Flash在轉往Android後,API的加強突飛猛進,尤其近幾個月中加入好幾個實用的API,如相機相簿、WebView、存取檔案、P2P…等等,雖然還是不夠多,但光這些其實就能玩出許多花樣了。
但可惜的是,這些API都是PFI 版所沒有的,查詢一下最後一版的PFI,仍只有Accelerometer, GPS, MultiTouch三個比較能說嘴的API。所以如果要讓PFI成為有競爭力的開發工具的話,至少API的部份要加強到像目前for Android版本一樣才行。這點可以在未來幾個月持續關注Adobe Prerelease網站裏的消息。總之能support的API愈齊,工具的競爭力才愈高,目前的PFI還很弱就是了。

3.真的可以上架了嗎?
也許有些人還會存疑,會不會這只是玩文字遊戲,口頭說不擋,但實際上架時再給你卡關呢?好險賈伯斯霸道歸霸道,說話倒是算話,說禁就是禁,說開就是開,沒在玩文字遊戲。在消息發佈後沒多久,就有Flash Developer在Twitter上寫道之前一直審核不過的Flash app突然過關了。另外像這款這款,也都是Flash開發的,不約而同也都在今天上架/更新了。所以看來應該是無誤的了。

4.所以這之後會有什麼影響
最大受惠當然還是廣大的Flash開發眾,對大家來說是原來被關的門,現在又打開了。這樣的狀況下,可以想見未來會出現許多用Flash開發的小App小Game入侵App Store市場,而這些app會不會表現得很好?到時自然會分明。
目前可以想到的是將來很多Web Flash的案子,客戶可能會多問一句:「能不能做手機版」(其實現在就常在問了),而設計公司可以大聲回答說「ok啊~再加XXXX錢,就可以了」;或是很多原本對Obj-C頭痛(像我),或是根本沒在學Obj-C的人,也開始在個人profile的skill 上多加一條「iPhone app開發能力」,照這樣發展下去,我想iPhone app的外包案件價格也會備受影響吧,以往可能可以報價XXXX錢,之後可能會是XXXX 減 N 的錢了(真是不妙)。

寫一次code可同時跨Web/Android/iPhone,這還是Flash目前最大強項(Unity 3D雖然也有web player,但安裝率太低),所以其實影響比較大還是其他的app開發工具,尤其像是Corona SDK, PhoneGap這類的打著「簡單易學」口號的3rd Tool,都應該會被這事有所影響。未來這些Tools會怎麼樣競爭;Adobe會怎樣重啟PFI的開發,也或者將來又出現什麼更厲害的3rd Tool,則是我個人比較期待的。

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Flash CS5 Accelerometer 範例 9 May 2010 12:08 AM (14 years ago)

Mark Doherty 貼了一段CS5 accelerometer api功能的demo影片

Device Central CS5 - Accelerometer from Mark Doherty on Vimeo.

In this video we look at the Accelerometer API in Flash Player 10.1 and AIR and the integration with Device Central CS5


以下分享一下這個範例的原始碼及心得:


accelerometer就是我們常俗稱的g-sensor,用來測量重力的sensor。
一般來說這種accelerometer都會給三個軸向的數值,分別為x,y,z,且都會是正~負的一個範圍,例如1~-1, 100~-100這種的。
而Flash提供的是1~-1的範圍。以面對手機瑩幕來看,水平線為X,垂直線為Y,穿透瑩幕的縱向為z

在Flash中使用acceleration api其實沒什麼困難,設好update event後,就會持續收到訊號,訊號內容有三個值
accelerationX
accelerationY
accelerationZ
各別都是1 ~ -1的一個值,拿這些值來做應用即可

以下範例是做了一個小鋼珠在桌面滑來滑去的動態,除了用AccelerometerEvent外,另外多加了些摩擦力、慣性的模擬。

在電腦要測的話,可開啟Device Central CS5的3D模擬面板試玩。

最後有一點要注意,Accelerometer的靈敏度,甚至軸向,有時在不同的device上會有所不同,所以一些參數會需要因不同的機子調整,例如這個範例我在iPhone及Nexus One上測試,其X軸的正負值就完全相反,sensor回傳event的靈敏度也不太相同。

以下為範例code:


Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Flash CS5 multi-touch 範例 8 May 2010 10:16 AM (14 years ago)

Mark Doherty貼了一段Flash CS5 multi-touch的範例影片

Device Central CS5 - Flash Professional Integration from Mark Doherty on Vimeo.

In this video we look at the debugging capabilities using Device Central for mobile projects. The application, PhotoTouch by Maso Lin, demonstrates the multi-touch support added to the tool for testing your applications.


以下我分享一下這個範例的原始碼及心得…



Flash目前提供的multi-touch api大致可分成兩種:
.TouchEvent--直接取得各個點的事件
.TransformGestureEvent--只取多點所形成的gesture結果

先說說TransformGestureEvent,它可得到rotate, zoom, pan, swip等事件,如果你的需求是這些的話,用這個就可以了。
TransformGestureEvent另一個好處是,使用macbook/pro開發時,直接在觸控板上做這些gesture,這個api是可以收到訊號的,這樣就可以在電腦上實測了。

而TouchEvent的使用時機,我個人覺得是在TransformGestureEvent無法滿足時再用就可以了。
例如做一個動作遊戲,需要在畫面上做出虛擬手把時 (左邊十字方向鍵,右邊是攻擊、跳…等),就必需要用TouchEvent

最後有一點要注意是,Flash 目前只支援到2點觸控,再多的話就收不到了。 待測...

以下是範例code,大致上是把所有的event列出來而已,並應用在一張照片上,讓它可以zoom in/out、旋轉 ,雙指pan做移動…等





Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

BaoZi Jump! on Android by Adobe AIR 19 Apr 2010 11:55 PM (15 years ago)

AIR for Android





I was porting my iPhone game "BaoZi Jump!" to Android, it works fine and smoothly.

This app using the Accelerometer API to control the BaoZi move, and every thing works correctly.

It took me almost 3 hours to compile for Android and modify some accelerometer variables to fit the Nexus One.(there is a little different between the accelerometer sensor of iPhone and Nexus One)

昨天花了約3三小時左右把BaoZi Jump porting成Android版,其實過程很簡單,用的是同一份原始檔,code幾乎沒改。主要時間反而是花在第一次操作Android SDK及一些文件的部署。(如果你已經有開發過Android的話,這部份應該不會花太多時間)

其次是要熟悉Nexus One的accelerometer sensor訊號,它的靈敏度與iPhone有些不同,所以要配合他的靈敏度調了一下參數。

其他的就沒花什麼時間了,一切非常簡單。

接下來就期待Adobe AIR for Android正式release後,廣大的Flash高手們會在Android Market丟出什麼樣的創意了。

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?