搜尋文章

2013年9月3日 星期二

使用android support V7 Demo

1.引入android-support-v7-appcompat、android-support-v7-gridlayout、android-support-v7-mediarouter三個android-support-v7的library。
先點選File/New/other/Android/Android Project from Existing Code,再點選Browse選擇androidSDK資料夾裡的extras/android/support/v7/appcompat、gridlayout、mediarouter按確定(這邊要分三次做),然後把project to import裡的專案給勾選起來,還有下面的copy projects into workspace也要勾選起
來之後按finish就可以了。

2.更改library SDK Version。
在android-support-v7-appcompat專案資料夾上按右鍵點選propertices然後選擇androidSDK的版本這邊要選擇android4.0,API LEVEL14。
在android-support-v7-mediarouter專案資料夾上按右鍵點選propertices然後選擇androidSDK的版本這邊要選擇android4.2,API LEVEL17,之後在下面Library的地方點選add然後選擇android-support-v7-appcompat再按OK。

3.加入android support V7 Demo。
先點選File/New/other/Android/Android Sample Project,之後選擇android4.1(Min SDK 7、Target SDK 17)然後選擇Support7Demos[Android Support Library]然後再按finish加入專案。

4.為support V7 Demo加入support V7 Library。
一樣在Support7Demos的資料夾上按右鍵點選propertices,然後再Library的地方按add加入第一個步驟引入的android-support-v7-appcompat、android-support-v7-gridlayout、android-support-v7-mediarouter這三個Library就可以發佈了。


2013年8月27日 星期二

AS3 Rect & java Rect 傻傻分不清~

今天在看android用canves畫圖案,有用到drawRect跟drawRoundRect這兩個方法,一個是畫矩形的另一個也是畫矩形的不過可以再多畫圓角。
這兩個方法都要帶一個Rect進去,想說Rect這東西在AS3的時候就用過很多次了,就覺得這四個值分別是帶x、y、width、height,然後就這樣帶進去了,想當然是畫出很奇怪的型狀或是根本沒圖形。在試驗很多次之後才發現原來AS3的Rect跟java的Rect是不一樣的阿~~

AS3裡如果是帶Rect(100,100,200,200)的值的話,會在x 100,y 100的地方畫一個寬200高200的矩形,不過在java裡這四個值分別是起始點與結束點,前面兩個值是起始點,後面兩個值是結束點,所以跟上面一樣帶Rect(100,100,200,200)的值的話,其實畫出來的會是在x 100,y 100的地方畫一個寬100高100得值,因為第三個值-第一個值=寬,第四個值-第二個值=高。

結案 !

2013年6月12日 星期三

android-透過webView加上userAgent


用userAgent判斷使用者是電腦或是行動裝置觀看網頁這一篇

記錄了如何用navigator.userAgent去判斷是在行動裝置上觀看網頁還是用電腦看

但如果是要在android上判斷是在行動裝置上的瀏覽器看還是用應用程式裡面的webView看的話

就需要再webView上下一點工夫了

下面直接上code

WebVIew mWebView = new WebView(context);
//先用webview的getSettings()取得webSettings再用getUserAgentString()
//取得userAgent,這邊取出來的值會跟在網頁用js的navigator.userAgent取的
//值是一樣的
String userAgentStr = mWebView.getSettings().getUserAgentString();
//之後用setUserAgentString()設定新的userAgent
//這邊設定新的UserAgent的時候用記得用舊的UserAgent去加入新的字串
//不然UserAgent的瀏覽器及系統訊息都會被你設定的新字串覆蓋過去
mWebView.getSettings().setUserAgentString(userAgentStr+"/ON_WEBVIEW");


之後在網頁上把UserAgent alert出來就可以看到剛剛新加入的字串了
Mozilla/5.0 (Linux; U; Android 4.1.2; zh-tw; GT-P3100 Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30/ON_WEBVIEW

再來就是作一樣的判斷
var userAgent = navigator.userAgent;
if(/ON_WEBVIEW/i.test(userAgent)){
          //是否在webview上面看
     }

javascript-用userAgent判斷使用者是電腦或是行動裝置觀看網頁

要判斷是否再行動裝置上或是電腦上觀看網頁

甚至要判斷是哪個瀏覽器都可以用 navigator.userAgent

這個屬性會返回使用者的瀏覽器及使用系統

返回值是一個字串所以可以用陣則式或是找字串的相關方法判斷



var userAgent = navigator.userAgent;

     if(/Android/i.test(userAgent)){
          //是否為Android
     }else if(/iPhone|iPad/i.test(userAgent)){
          //是否為iPhone或iPad
     }else if(/Windows/i.test(userAgent)){
   //使否是用電腦觀看
     }

     //判斷瀏覽器
     if(/Chrome/i.test(userAgent)){
           //是否為Chrome
     }else if(/Firefox/i.test(userAgent)){
           //是否為Chrome
     }

如果不知道要用什麼字串判斷的話,就先把navigator.userAgent給alert出來看吧 !

另外在android上如果是要判斷是在android上的browser還是在webView上面看的話

就要在android上的webView動手腳了~

要如何動手腳可以看這一篇透過webView加上userAgent

android-canvas set bitmap IllegalStateException error

最近在android上試做了一個畫筆的功能

然後要能把畫的圖片儲存跟讀取

讀取的方法我是用BitmapFactory.decodeFile把檔案圖片轉成bitmap

然後再把這個bitmap畫在canvas上,但時候遇到了一個error

錯誤訊息是這樣的

java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor

股溝了一下發現也有人遇到這樣的問題

其原因是被載入的bitmap是不可被改變的,所以也不能用來畫在canvas上

如果是把bitmap帶入canvas的建構涵式的話就會出現上面的錯誤訊息

但如果是用canvas.setBitmap()的話只會出現這樣的錯誤訊息

java.lang.IllegalStateException

這一點真的想要抱怨一下android,錯誤訊息劈哩啪啦列了一大堆

唯一看到有用的訊息就是這一串然後也講得不清不楚了

但我想錯誤的原因應該都是一樣的,都是不可改變bitmap

解決的方法是把載入的bitmpa在複製一份出來用就好了~

Canvas mCanvas ;
File bimapFile = new File("mmt\sdcard","pic.png");
Bitmap orgBitmap = BitmapFactory.decodeFile(bimapFile.getAbsolutePath());
Bitmap copyBitmap = orgBitmap.copy(Bitmap.Config.ARGB_8888, true);

//用建構帶入bitmap或是用setBitmap方法帶入都可以
mCanvas = new Canvas(copyBitmap)

//or
//mCanvas = new Canvas();
//mCanvas.setBitmap(copyBitmap)

2013年6月3日 星期一

starling-AssetManager使用方法

在starling 1.3版中多增加了許多功能其中一個就是AssetManager。

AssetManager顧名思義就是用來管理素材的class

這邊就來記錄一下要如何使用


1.用Embed素材加入Texture
//先Embed圖片
[Embed(source="assets/bg.jpg")]
public static const BG:Class;

//先實體化AssetManager
vra am:AssetManager = new AssetManager();

//再把圖片加入AssetManager中
//第一個參數是這個texture在AssetManager中所註冊的名字
//第二個參數當然就是要放進AssetManager的texture
am.addTexture("BG", Texture.fromBitmap(new BG()));


//要從AssetManager抓取texture使用的話就使用getTexture方法
//參數就帶當初註冊名字
am.getTexture("BG");

//另外如果想知道所有有註冊的texture的名字可以使用getTextureNames方法
//這個方法會列出所有註冊過的名字
am.getTextureNames();

已經註冊的名字是不能重複註冊的,不然會報Error。

add的方法除了addTexture外還有addSound、addTextureAtlas

其實使用的方法都大同小異只是差在要丟什麼類型素材而已。




2.用enqueue方法加入素材,enqueue方法可以一次塞很多參數進去

也就是一次可以載入很多素材,就像他的名字一樣用列隊的方式依序載入

素材,而且enqueue是很強大的,它除了可以使用檔案路徑之外還可以

使用靜態的類別,甚至是可以搜尋整個資料夾路徑並且分門別類的幫你

自動載入自動註冊(AIR),下面就繼續記錄用不同的參數類型來使用enqueue載入素材。




第一種方法使用路徑載入檔案,使用檔案路徑的方式載入素材時比較要注意的地方是

AssetManager會自動使用檔案的檔名來註冊,例如是載入assets/bg.jpg這個

路徑裡的圖片,就會用bg這個名字來註冊,所以要用getTexture()方法取texture時

也是要用這個名字。

//一樣還是先實體化AssetManager
var am:AssetManager = new AssetManager();


am.enqueue("assets/bg.jpg");

//也可以一次給很多路徑中間用逗號格開就好
am.enqueue("assets/1.jpg","assets/2.jpg","assets/3.jpg");



第二種方法使用靜態類別載入,下面有一個用來embed檔案的靜態類別
package src.embed
{
 /**
  * ...
  * @author kuro
  */
 public class EmbedAsset 
 {
   
   //textureAtlas的圖片
   [Embed(source = "assets/lee.png")]
   public static const lee:Class;
   //textureAtlas的xml
   [Embed(source = "assets/leeXml.xml" , mimeType = "application/octet-stream")]
   public static const LeeAtlasXml:Class;
   
   //圖片
   [Embed(source="assets/bg.jpg")]
   public static const BGG:Class;
   
   //聲音
   [Embed(source="assets/yours.mp3")]
   public static const bgSound:Class;
   
   //字型
   [Embed(source="assets/font.png")]
   public static const font:Class
   [Embed(source="assets/font.fnt", mimeType="application/octet-stream")]
   public static const FontXml:Class
 }

}


使用靜態類別當作素材來源時要注意的地方是,AssetManager是用class名稱來註冊的

當要embed動畫所需要的textureAtlas素材的時候要注意一件事那就是

textureAtlas素材的圖片名稱跟embed的class名稱要一樣

但xml的名稱就不一定要跟embed的class名稱一樣了。


如果有去看過原始碼的話,就會發現AssetManager是先把class的lee先註冊到了

texture的Dictionary裡,之後載入textureAtlas的xml之後發現被註冊到

texture的Dictionary裡的lee是作為textureAAtlas需要的素材,所以就把

texture的Dictionary裡的lee移除掉,然後重新用lee這個名字去textureAAtlas的

Dictionary裡註冊,所以當textureAtlas註冊名字之後,你用getTexture()方法去

找lee的這個texture是找不到的,你只能用lee這個名字並且使用getTextureAtlas()這個方法

找到已經加入的textureAtlas素材。

//使用的話就這樣使用
var am:AssetManager = new AssetManager();

am.enqueue(EmbedAsset);

var lee:MovieClip = new MovieClip(mAssetManager.getTextureAtlas("lee").getTextures("lee_idle"), 24);
Starling.juggler.add(lee);
addChild(lee);


剛剛有說了註冊的名字是使用class名稱,所以如果是用靜態類別載入素材的話

要取得bg.jpg這張圖片就要用BGG的這個名稱。


如果是要取得聲音的話

可以用AssetManger裡的playSound("註冊的名字")取得聲音並且播放

playSound方法是會返回一個soundChannel,在呼叫這個方法時還可以帶

有關soundChannel的參數給他可給可不可。



如果是字型的話AssetManager會自動註冊字型到textField裡面,不用再呼叫

TextField.registerBitmapFont()註冊字型,而且也沒有方法可以抓取

載入進來的bitmapFont圖片,另外跟textureAtlas比較不一樣的地方是

要使用的時候不是用class的名稱,是要用這個字型的名稱,那字型的名稱

要去哪裡找呢?請把.fnt的這個檔案打開,其實裡面也是xml的結構

在第二行的地方會看到face="Brisk",這個face的地方就是字型的名稱

所以就要用Brisk這個名字,下面是使用方法

var text:TextField = new TextField(700, 100, "", "Brisk", 50, 0x000000, false);
   
text.hAlign = HAlign.LEFT;
text.text = "This is Bitmap Font Generator Test !";
addChild(text);

再來就是要講使用AIR在行動裝置上時要怎麼AssetManager

用AIR的話第一個還是可以使用上面所說的靜態類別的方法因為

那是把素材內嵌至swf裡比較沒有路徑的問題,但如果沒有要用embed的話

可以先把素材一起放在app的資料夾底下需要的時候在叫來用就好了

那要怎麼把宿才放在app資料夾底下呢?這邊我是用flash cs6所以我就來

講一下怎麼做。

第一步:選取檔案/android設定(如果是ios的話就是ios設定)

第二步:會看到下面有一個包含的檔案,然後會有三顆按鈕分別是

加入檔案、刪除檔案、加入資料夾,如果是只有幾個檔案的話可以

選擇加入檔案,但如果是有很多素材在同一個資料夾裡的話就可以選

加入資料夾,這樣這個資料夾裡的素材就都會被加入了

加入了檔案之後就要來看程式要怎麼寫了
//使用File類別,然後用applicationDirectory的屬性取得app根目錄
var appDir:File = File.applicationDirectory;

//之後再使用File的resolvePath()方法取得相對路徑
//如果是直接寫檔案路徑的話就會找到app/assets/bg.jpg;
am.enqueue(appDir.resolvePath("assets/bg.jpg"));

//這邊也可以直接寫資料夾名稱,AssetManager會自動搜尋可以用的
//全部素材並且載入註冊,非常的方便
am.enqueue(appDir.resolvePath("assets"))

再來講一下如何抓取檔案讀取的進度,AssetManager裡有一個loadQueue()

這也是呼叫AssetManager開始異步載入列隊裡的素材,這個方法必須帶一個function

給他,以便AssetManager callBack回來載入的進度

mAssetManager.loadQueue(onProgress);

private function onProgress(number:Number):void {
 var percent:int = Math.round(number * 100);
 trace("progress = " + percent + " %");
 if (number == 1) {
      (mStarling.root as Game).start(am);
 }
}



另外AssetManager 也可以載入網路上的資源下來,就把路徑換成http路徑就好了

還有載入的方法可以混著用類似像是下面這樣

//可以同時擺路徑也可以擺靜態類別
am.enqueue("asset/bg,jpg",EmbedAsset);

有關AsetManager的document可以來這邊看

AssetManager

2013/07/17更新

後來又自己鬼打牆遇到了一些問題,就再來記錄一下

1.用enqueue()放入要載入的檔案後,要記的要用loadQueue()載入檔案阿 !
就算沒有要知道載入進度也是一樣

2.在air的時候如果要用enqueue()掃資料夾的檔案的時候
要記得資料夾要跟fla檔案放在一起(用flash ide編譯的話)
這樣用appDir.resolvePath("assets")才會找的到檔案
千萬不要放在不同層,因為就算在路徑上加上../
air應用程式在找的時候也是從app路徑下開始找
所以還是找不到


2013年5月12日 星期日

unity3d-利用Command line開啟exe執行檔並傳值

上次有說過如果要使unity執行檔不要產生log檔或是要用popwindow的方式開啟


就要在程式命令集後面加上-nolog或是-popupwindow

關於有什麼參數可以使用可以參考下面連結


不過如果想要自訂義要傳給執行檔的參數的話該怎麼做呢?

其實還是跟上面一樣只要在.exe的後面加上參數就可以了

記得每個參數之間要以空白作為間隔

例如:c:\game\myGame.exe aa bb cc 123

之後在程式加上


var arguments : String[] = System.Environment.GetCommandLineArgs();


就可以抓到需要的參數了。

下面是log出來的結果

arguments[0] = c:\game\myGame.exe
arguments[1] = aa
arguments[2] = bb
arguments[3] = cc
arguments[4] = 123


2013年5月7日 星期二

Starling 相關資料

什麼是Starling?

以下是簡體中文官方的解釋


Starling是一个ActionScript类库,它模仿了传统的Flash显示列表。然而,和传统的显示对象不

同,Starling对象完全存在于Stage3D环境。这意味着,所有的显示对象都直接由GPU渲染,这

会带来非常明显的性能提升。

Starling并不是直接1:1的复制Flash API。所有的类都针对GPU模式进行了精简和优化。Starling向

开发者隐藏了Stage3D的内部细节,但如果您想创建自定义显示对象,也可以很容易访问到它

们。

就像它在iOS平台的姐妹框架,Sparrow Framework, Starling的设计宗旨是尽可能轻量级,易

于使用。作为一个开源项目,我们非常小心,保证代码易于阅读,理解和扩展

簡單的一句話來講就是

基於GPU加速的2D Flash API,使用Stage3D的宣染技術使

2D圖像能夠展現更好更快的效能,尤其是在行動裝置上更

有明顯的效果。

starling還有個好處是他可以跟許多的framework作結合,不管是物理引擎的Box2d、Nap

或是3D引擎的away3d、alternative3d都能透過starling使其效能更為提升


下面列一些有關Starling的學習資料,及基於Starling所擴展出來的framework

1.Starling英文官網

2.Starling中文站

這個網站就有點像官方英文的中文網站,由很多好心的人翻譯的,裡面有很多學習的資料

連document都有中文翻譯不過也是簡體的,裡面還有很多範例可以學習,建議一開始學習

starling的人可以先去這邊晃一圈就會對starling有個大概的了解。

3.hungry hero game

使用Starling所作的橫向捲軸遊戲,有發佈成網頁版及IOS版,最好的是他有公佈所有的

source code,學完這個大部分starling的功能都會知道怎麼用了

4.Hungry Hero Game Video Tutorials

除了公布了source之外還提供了影片教學,教你一步步熟習starling framework,不過主講人是

印度人,那個恐怖的口音實在讓我有點‧‧‧‧‧‧‧

5.Feathers

基於starling的UI類別,有很多在行動裝置上會用的UI及組件,讓這些UI透過starling的宣染

可以在行動裝置上讓用戶有更好的使用體驗。

6.Starling-Extension-Particle-System

starling的粒子特效,裡面還有介紹線上的粒子系統編輯器,以及在Mac上使用的編輯器

7.citrus Engine(2、3D橫向捲軸遊戲引擎)

結合Starling+away3d+box2d + Nape + awayPhysics的遊戲引擎

8.Dragon Bones

Dragon Bones是flash 2d的骨架動畫,使用Flasg製作素材後,再透過Dragon Bones的Flash IDE

的擴充套件來完成骨架動畫,其好處是能比用spriteSheets還要少的圖像完成複雜的骨架動畫

當然也支持starling
。作为
访问到

2013年5月6日 星期一

Starling-用setTexCoords-位移圖片UV

Starling-用setTexCoords-製做無接縫延伸背景圖這篇實現了無接縫的拼接背景

現在要再多一點變化讓背景圖片可以作無限的延伸,圖片一樣是拿那隻鳥來素材


一樣先把無接縫拼貼的部分先完成

//原圖為256*256,因為要讓圖片小一點所以設置作後一個參數2,使圖片縮小為原尺寸的1/2,BirdClass為Embed的圖片Class
var birdTexure:Texture = Texture.fromBitmap(new BirdClass(), true, false, 2);
//設置Texture為重複
birdTex.repeat = true;
var birdBackground:Image = new Image(birdTex);
//把Image的寬和高設置為跟螢幕一樣大
birdBackground.width = this.stage.stageWidth;
birdBackground.height = this.stage.stageHeight;
//橫向重複數量
var horizontalSize:int = 8;
//直向重複數量
var verticalSize:int = 8
 
birdBackground.setTexCoords(1, new Point(horizontalSize, 0));
birdBackground.setTexCoords(2, new Point(0, verticalSize));
birdBackground.setTexCoords(3, new Point(horizontalSize, verticalSize));
addChild(birdBackground);

之後在加上兩個全域變數

private var bird:Image;
//紀錄滑鼠作標位置
private var mMousePos:Point = new Point();

以及enterFrame跟Touch事件的監聽

addEventListener(Event.ENTER_FRAME, loop);
addEventListener(TouchEvent.TOUCH, onTouch)


 private function onTouch(event:TouchEvent):void
 {
        //這裡用滑鼠的全域作標-圖片的一半寬和一半高是為了讓滑鼠坐標以圖片中心當(0,0)的位置           
         mMousePos.x = event.getTouch(this).globalX - ( this.stage.stageWidth >> 1);
           mMousePos.y = event.getTouch(this).globalY - (this.stage.stageHeight >> 1);
      
}
  
private function loop(e:Event):void 
{
       //迴圈跑UV的四個頂點
        for (var i:int = 0; i < 4; i++) {
           //用getTexCoords方法取得每個UV點的Point
           var p:Point = bird.getTexCoords(i);
           //在改變每個UV點的位置的X、Y
           p.x += mMousePos.x * .00002
           p.y += mMousePos.y * .00002
           //最後用setTexCoords方法設置圖片的頂點以及坐標位置
            bird.setTexCoords(i, p);
       }


}
這樣移動滑鼠時就會看到圖片會跟著滑鼠的移動無限制的延伸背景




參考資料
Best way to do a scroll background

http://www.cnblogs.com/sevenyuan/archive/2013/01/22/2871634.html

Starling框架——UV坐标控制纹理贴图滚动

UV Scrolling in Starling


Starling中实现形状不规则的卷轴地图滚动

2013年4月26日 星期五

Starling-用setTexCoords-製做無接縫延伸背景圖

在上一篇Starling-用setTexCoords-裁切圖片中有講到了一些UV坐標的概念

這次要繼續使用Image的setTexCoords的方法來產生無接縫延伸背景圖

這邊先分享一個線上製做無接縫圖片的地方


這邊有很多現成的素材可以下載,另外也可以利用他線上的編輯器去編輯

素材的顏色等等 . . .

之後就可以下載png圖檔下來,下載png是不用付費的,功能很簡單應該

就不用再另外教學了,隨便摸一摸應該就會了

無接縫的素材做好了後就可以把素材Embed到程式了

不過我這邊先不用無接縫的素材,因為如果用了就看不出來到底拼接了幾個出來了

為了好了解我這邊還是先用上個範例的鳥~

程式碼如下



//原圖為256*256,因為要讓圖片小一點所以設置作後一個參數2,使圖片縮小為原尺寸的1/2,BirdClass為Embed的圖片Class
var birdTexure:Texture = Texture.fromBitmap(new BirdClass(), true, false, 2);
//設置Texture為重複
birdTex.repeat = true;
var birdBackground:Image = new Image(birdTex);
//把Image的寬和高設置為跟螢幕一樣大
birdBackground.width = this.stage.stageWidth;
birdBackground.height = this.stage.stageHeight;
//橫向重複數量
var horizontalSize:int = 8;
//直向重複數量
var verticalSize:int = 8

birdBackground.setTexCoords(1, new Point(horizontalSize, 0));
birdBackground.setTexCoords(2, new Point(0, verticalSize));
birdBackground.setTexCoords(3, new Point(horizontalSize, verticalSize));
addChild(birdBackground);

這邊其實我也不是很懂其原理,只知道這樣做可以達到無接縫拼貼的效果

當然每個位置的的值也不一定要像我上面寫的一樣,自己可以隨便填個值看看效果

也許會產生出很奇特的形狀貼圖

Starling-用setTexCoords-裁切圖片

在starling的教學範例Hungry Hero裡,遊戲下方的街景以及遊戲背景的滾動方式是用

兩張圖片不斷的輪流交替來產生背景滾動的效果,不過要滾動背景的話其實還有

另一種方式是改變圖片的頂點位置以及紋理的UV坐標,在starling中預設的DisplayObject

都是四邊形,圖形的UV作標點分別為下圖所示

0  ─ ─ ─ 1
│            │
│            │
│            │
2  ─ ─ ─ 3

設置頂點位置以及紋理的UV坐標可以達到許多效果,例如上述所說的滾動視圖達到

橫向捲軸遊戲裡的無限延伸背景的效果,另外也可以拿來作裁切圖片和無接縫圖片的

背景延伸等等等 . . . .下面就來示範一下怎麼分別達成這些效果

1.裁切圖片
下面這邊有一張圖


















如果要裁切這張圖片的右下角1/4的圖的話要怎麼做呢?

我們可以用Image裡的setTexCoords方法裁切


var image:Image = new Image(texture);
addChild(image);
var point:Point = new Point();

//第一個點
point.x = 0.5;
point.y = 0.5;
image.setTexCoords(0, point);

//第二個點
point.x = 1;
point.y = 0.5;
image.setTexCoords(1, point);

//第三個點
point.x = 0.5;
point.y = 1;
image.setTexCoords(2, point);

//第四個點
point.x =1;
point.y = 1;
image.setTexCoords(3, point);

解釋一下上面程式碼的意思

假設圖片的四邊長分別都為1

那要裁切圖片的1/4右下角的話

第一個點當然是圖片的正中心拉

假設圖片的四邊長分別都為1

最左上角坐標為(0,0),右上角坐標為(1,0),左下角坐標為(0,1),右下角坐標為(1,1),


那要裁切圖片的1/4右下角的話第一個點當然是圖片的正中心拉


所以會看到第一個點是設在(0.5,0.5)的位置上,第二個點就會在(1,0.5)


以此類推就會推出上面所設的座標位置拉


裁切出來之後你應該會發現裁切出來的部分被放大成原圖片的大小,以上圖為例

圖片為256*256裁切出來的右下角應該要是128*128,可是卻被放大為256*256了

因此會變得有點模糊,所以如果要裁切後不被放大的話就手動把圖片縮回來就好了

image.width = image.width >> 1;
image.height = image.height >> 1;

//
設置

2013年4月16日 星期二

new google developer console upload expansion files(新版google play上傳擴充檔)

今天上 developer console 要幫已經上傳的apk附加擴充檔(expansion files)

發現上傳完apk之後,完全沒有可以選擇上傳擴充檔的地方

然後連返回舊版google play的按鈕都消失了是哪招?!

所以之後又找了股溝大神,找了很多文章很多人都說上傳完apk後

可以看到下面的畫面


問題是我上傳之後都沒看到阿 ! ! !

之後又繼續找資料發現google android developer 的 using APK expansion file有寫解決方法

不過我看了中、英還是看了霧煞煞最後是看日文的才看懂

中文:
注意:由於 Google Play 開發人員控制台目前的限制,在上傳新的應用程式後,您無法將額外的擴充程式檔新增到其所上傳的第一個 APK 檔案。做為替代方法,請先上傳 placeholder APK 檔案,然後以包含所需額外擴充程式檔的 APK 檔案取而代之您可以在應用程式處於草稿狀態時進行以上所有操作,這樣就不會影響到現有和未來的使用者

英文:
NOTE: due to a current limitation of the new Google Play Developer Console, you won't be able to add additional expansion files to the very first APK file that you upload for a new application. As a work-around, please upload first a placeholder APK file and then replace it with an APK file containing the additional expansion files you needAll of this can be performed while the application is still in draft state, so there is no impact on your (prospective) users.

日文:
: 現在のところ、新しい Google Play デベロッパー コンソールの制限により、新しいアプリをアップロードする最初の APK ファイルに拡張ファイルを追加することはできません。この問題を回避するには、まず APK ファイルのみをアップロードし、必要に応じて拡張ファイルを追加した APK ファイルで置き換えてくださいこれらの操作は下書き状態の APK でも行えますので、既存ユーザーや潜在ユーザーに影響が及ぶことはありません

發現中文跟英文當是講請先上傳 placeholder APK 檔案,靠 !誰知道placeholde apk是什麼鬼

東西阿 ! 

還有中日的這句話好像都有點問題

然後以包含所需額外擴充程式檔的 APK 檔案取而代之

拡張ファイルを追加した APK ファイルで置き換えてください

意思好像就是要你上傳把擴充檔加入需要上傳的apk裡面然後在上傳,可是事實好像不是這樣

但日文還是寫得比較容易懂,日文就是寫說請先上傳你的apk檔案,之後在置換成需要

加入擴充檔的apk。

所以結論就是你同一個apk上傳兩次,上傳第二次完成時就可以選擇是否要加入擴充檔

的選項了,如果apk檔很大的話也可以先上傳隨便一個小的apk之後再重新上傳真正要

上傳的檔案就可以了 !

結論:還是要幹ㄍㄧㄠˇ一下中文的說明寫的又夠爛,拜託可以白話一點嗎?!

2013年4月3日 星期三

unity3d 執行檔在光碟上運行錯誤

之前發佈unity執行檔時當是在本機運行,後來把執行檔燒入在光碟執行後

就發現遊戲一開啟就死當,然後強制關閉,拜見股溝大神後,發現應該是log檔的問題

在unity player設定有個選項是 use player log,把勾勾選起來的話就是在程式裡有寫

Debug.log的地方,他就會幫你再data資料夾裡開一個logout.txt的文字檔,然後把log資訊

寫進去,但因為是在光碟上執行所以他沒辦法寫檔所以就死當拉 !

解決方法有兩個,一個當然就是在包執行檔的時候在player setting那邊把use player log

給取消掉,另一個方法就是透過另一個檔案去開那個執行檔並且在後面加上 -nolog的

屬性,看是要用bat還是捷徑還是另外寫開檔的執行檔都可以,就是像這樣

text.exe -nolog

這邊順便再另外提一個東西是unity的全螢幕是改變螢幕解析度的作法

不過這種作法UI會被拉撐,如果不想被拉撐的話一樣可以用視窗模式

然後在開檔的屬性後面加上 -popupwindow就好

2013年4月2日 星期二

Shellrazer 付費內容的設計精神





作者一開始以他過去玩另一款遊戲Battleheart的經驗為例。Shane指出他非常非常喜歡這款遊戲,然而在最後打大魔王時卻不論怎麼打 都打不過。經過一段嘗試之後,Shane理解到以他在遊戲中所組的隊伍是無法擊敗魔王的,因此Shane只好回頭去"練功"升等,但是卻在這個過程中失去 了對遊戲的興趣...
Shellrazer的遊戲流程是遵照經典的RPG Loop: 戰鬥->獎勵->升級。但即便是遵循傳統模式,在設計上依然有許多需要花心思的地方,特別是針對不同的玩家必須要有不同的獎勵方式來鼓勵他們繼續玩下去。Shane則是根據玩家的強項將其區分為三類:技巧(Skill)時間(Time)金錢(Money)
1.技巧型玩家
技巧型玩家追求的是遊戲技巧的卓越,因此設計時要確定遊戲內容有足夠的深度。而所謂的技巧又可分為兩種:操作知識
操作技巧指 的是在遊戲中靈活地操作及熟練地下達各種指令。在Shellrazer中,玩家的烏龜上可以裝備許多個不同的武器,而要同時一一操作這些各自有不同特性的 武器是很需要技術的。此外,Shellrazer中還提供了兩種不同的控制模式讓玩家選擇(單指操作或雙指操作),由於這兩種模式各有優點,因此高手會根 據戰況在此二模式之間切換。以上種種都讓追求操作技巧及手速的玩家們有了奮鬥的目標。
知識指 的是透過對遊戲細節的理解來幫助破關。在Shellrazer中,武器和敵人之間有著如剪刀石頭布的相剋關係,而且根據敵人行動方式的不同也有相因應的武 器,比方說從空中來襲的敵人就適合用對空武器攻擊。因此,對遊戲內容理解程度越高的玩家,越懂得妥善運用金幣來購買最適當的武器。而遊戲中也會獎勵玩家花 費心思及時間來學習遊戲的內容:越了解遊戲的玩家越容易打出高Combo,而高Combo則會帶給玩家更多的金幣作為獎勵。
2.時間型玩家
時間型玩家,顧名思義即為花費許多時間在遊戲上,但不一定具有高超技巧的玩家。因此,為了照顧時間型玩家,必須要確保遊戲在經過長時間遊玩後依然能保持新鮮感及可玩性,同時也要確保遊戲不會"卡關"。
在Shellrazer中,對時間型玩家的照顧主要有下列四點:
  1. 關卡中的敵人是由程式隨機生成,因此每次玩的時候都會有些許不同,藉此確保新鮮感。
  2. 不採用social games中常見的能量系統(Energy),因此玩家每次想玩多久就能玩多久。
  3. 採用類似D&D的升級曲線。越高等級所需的升級經驗越多。參考
  4. 每次玩家打完一關,不論是否成功過關,均給予金幣獎勵(成功過關可另外獲得獎勵物品)。因此即便是技巧不足的玩家,只要花費足夠的時間進行遊戲,最終依然能購得強力的裝備來破關。
3.金錢型玩家
金錢型玩家可說是開發者的衣食父母,他們願意掏出信用卡來幫助自己破關。但是對金錢型玩家的照顧絕非只是設計各種要付費購買的強力武器或道具這麼膚淺。
在Shellrazer中,玩家並不直接用錢來購買武器,而是用錢購買遊戲金幣或是增加自己在遊戲中賺取金幣的速度。也就是說,金錢型玩家並不能夠透過花錢來取得別的玩家無法取得的物品,而是透過花錢來縮短他們取得物品所需要的時間。
此外,在設計Shellrazer中的付費內容時,最核心的宗旨則是尊重
許多開發者將金錢型玩家稱為鯨魚(Whale),意指肥美的獵物。而Shane對此表示不以為然。他認為當你將玩家視做獵物時,你心底其實是將他們當作笨蛋(fool),而難道我們要為笨蛋們做遊戲嗎?這顯然是不正確的。開發者必須尊重玩家,玩家才會尊重你及你的遊戲。
反 映在具體做法上,Shellrazer只有在玩家的金幣用罄時才會彈出讓玩家付費的推銷視窗,除此之外,Shellrazer也堅決不在UI上使手段誘使 玩家在不經意的情況下付錢。Shane同時也指出,他認定Shellrazer大約是$50美金的價值,因此只要玩家花了$50美金之後,基本上就能取得 遊戲中的所有內容,如果玩家花了超過$50,那多出的部分可以說是純粹樂捐給開發者。一但開發者心中有了這條底線,便不會為了追求所謂的"長尾" (Long Tail)而設計出貴而無當的付費內容。
Shellrazer的付費內容可說是相當有成效:約8%的玩家有購買付費內容,而約有30%的總收入是來自付費內容。
資料來源:CH Huang

Flash Professional CS6 透過USB 連接iOS 安裝發佈

在Flash Professional CS6 版本12.0.2.529 中

我們可以透過USB 連接iOS 裝置進行實機測試

在Windows 或MAC OS X 平台兩者皆可

過程無需透過iTunes 或越獄(Jailbreak) 後的iOS 裝置

純粹USB 連接,十分方便

(p.s:如果是用windows的flash發佈的話要先安裝windows版的iTunes)

以下是更新Flash Professional CS6 和連接iOS 發佈方法:
  1. 在官方下載最新Flash Professional CS6 更新:
  2. 安裝完成後, 在Help -> Aboout Adobe Flash Professional 看到新版本編號 (12.0.2.529).
  3. 下載Adobe AIR SDK, 然後設定路徑. (設定方法請參考)
  4. 開啟一個AIR for iOS  新專案.
  5. 設定發佈對象為AIR 3.4 for iOS 或以上版本.
  6. AIR for iOS Settings -> Deployment 中, 選擇以USB 連接iOS 裝置進行實機測試.
    (Install application on the connected iOS device)
注意事項:
若曾經修改host 檔案, 在更新過程會發生錯誤訊息, 請把host 檔案暫時回復, 待更新完成後才可修改.
(host 檔案路徑: C:\Windows\System32\drivers\etc\host)
低調 . . . .

在發佈的過程我自己有遇到 application verification failed ,然後錯誤訊息是寫說請確認裝置容量足夠

Device Error: Please check if there is enough free space on the device 

上網股溝了一下發現也有人遇到同樣的問題,簡單來說就是appid打錯了,不過不知道他為什麼

要報這個跟問題一點都沒關係的error,這是解決方法

不過我的情況有點不一樣因為我是用window的flash開發的,沒有ios的p12檔跟

mobilprovision,然後我又是上網下載之前某個好心的外國人上傳的fake p12檔

但就會一直出現上面的錯誤訊息,到最後請有app開發帳號的同事幫我發佈

一個p12檔跟mobilprovision才成功的

要如何用mac產生這兩個檔下面的連結有還蠻詳細的解說



另外如果有遇到找不到IOS裝置的情況的話,也有解決方法




2013年3月29日 星期五

Citrus Engine(2、3D橫向捲軸遊戲引擎)

最近發現了一個作橫向捲軸遊戲的引擎

名叫:Citrus Engine

他是結合許多flash的遊戲framework在封裝起來的遊戲引擎




















看上圖就知道了他結合哪些東西進去

有starling(flash gpu加速2D引擎)、away3d(flash 3d引擎)

還有三個物理引擎,最常聽到的box2d還有nape跟away3d自己家的awayPhysics

看起來是一個蠻方便的東西,不知道有沒有真的整合的很好

有時間再來研究看看,另外官網有影片教學也有範例檔可以下載


2013年3月28日 星期四

AS3-Vector 初始化

1.
var vec1:Vector.<int> = new Vector.<int>(5);
//第二個參數boolean代表是否能夠修改長度
//var vec1:Vector.<int> = new Vector.<int>(5,true);  
for(i = 0;i<vec1.length;i++){  
    vec1[i] = i;  
}  

2.
var vec2:Vector.<int> = Vector.<int>([1, 2, 3]);  

3. 
var vec3 = new <int>[1, 2, 3];   

2013年3月25日 星期一

starling framework (一)


最近開始想記錄一下starlin的學習過程也算是複習,不然老了很多事都記不得了(咳!

starling是什麼呢?

相信google會很清楚的告訴你的,但這邊還是簡單的一句話介紹一下

就是使用stage3D的GPU加速的2D引擎。

如果有聽沒有懂的話,直接看結果會比較清楚。

以下有兩個swf,滑鼠每click一次會產生一百隻鳥不斷的移動


上面的是沒有使用starling的,只是單純的產生bitmap然後不斷移動

下面的是使用starling,可以比較一下個別產生的物件數及FPS

要分開測試喔!先點清除按鈕清除其中一個內容,不要點了上面的又去點下面的這樣不管怎麼點都會慢唷 !








下面這邊有各種2D引擎的效能比較可以參考看看

2D引擎效能比較

我自己手邊的裝置有測過的

htc desire he  約600

SAMSUNG GALAXY Tab 7.0 700

ipad2 約700

new ipad 約1000

以上的數量是FPS維持在30左右的數目

2013年2月21日 星期四

as3-vector sort


在as3裡,vector可以透過sort()函數來進行排序
跟array比較不同的是,array的sort可以不帶參數或是用定義好的參數帶入
例如:
Array.CASEINSENSITIVE:這個選項會忽略大小寫限制加以排序。例如,小寫字母 b 會排在大寫字母 D 之前。

Array.DESCENDING:這會反轉預設的依遞增順序排序。例如,字母 B 會排在字母 A 之前。

Array.UNIQUESORT:這會在發現兩個相同的值時,中止排序作業。

Array.NUMERIC:這會進行數值排序,因此 3 會排在 10 之前。
在vector的sort裡一定要帶入一個自訂義用來執行排序的function,或是也可以使用上面的參數帶入
例如:vector.sort(Array.CASEINSENSITIVE);
如果今天有5個MovieClip要進行名字的排序的話,就可以用自定義的涵式來執行了。
import flash.display.MovieClip;
import flash.text.TextField;

//先建立5個MovieClip
var mc1:MovieClip = new MovieClip();
var mc2:MovieClip = new MovieClip();
var mc3:MovieClip = new MovieClip();
var mc4:MovieClip = new MovieClip();
var mc5:MovieClip = new MovieClip();
//命名
mc1.name = "mc_1";
mc2.name = "mc_2";
mc3.name = "mc_3";
mc4.name = "mc_4";
mc5.name = "mc_5";
//此時在mcVector裡的MovieClip已經不是按照mc_1、mc_2 ...的順序排列了
var mcVector:Vector.<MovieClip>  = new Vector.<MovieClip>();

mcVector[0] = mc3;
mcVector[1] = mc5;
mcVector[2] = mc1;
mcVector[3] = mc4;
mcVector[4] = mc2;
trace(showName(mcVector));
//output mc_3,mc_5,mc_1,mc_4,mc_2
mcVector.sort(vectorSortFunction);
trace(showName(mcVector));
//output mc_1,mc_2,mc_3,mc_4,mc_5

function vectorSortFunction(firstMc:MovieClip , secandMc:MovieClip)
{
  //先把名字後面的數字拆出來
  var number1:int = int(firstMc.name.split("_")[1]);
  var number2:int = int(secandMc.name.split("_")[1]);
  //之後在用數字去作排序
  if (number1 > number2)
  {
    //這邊返回1的意思是,如果前面的數字大於後面的數字,前面的對象就要往後排
    return 1;
  }
  else if (number1 < number2)
  {
    //返回-1的意思是,如果前面的數字小於後面的數字,前面的對象就要往前排
    return -1;
  }
  else
  {
    //返回0的意思是,一樣的話就不變動順序
    return 0;
  }
}

function showName(vector:Vector.<MovieClip>):String
{
  var _txt:TextField = new TextField();;
  for each (var mc:MovieClip in vector)
  {
    
    _txt.appendText(mc.name+",");
  }
  
  return _txt.text;
}