Demo:
https://dl.dropboxusercontent.com/u/10581994/ZSortTest/index.html
Github:
https://github.com/hsienwei/zSort_cocos2dx_html5
2014/01/16:cocos2d-x 2.2.2已修正此問題
2013/11/24 : 目前在chrome中會無法顯示(火狐可以), 為cocos2d-x html5的bug
這個專案主要是以cocos2d-x html5版本來實作一個我之前在工作中使用的45度角地圖Z-Sort演算法,一來練習cocos2d-x html5,一來為之前的工作內容做一個記錄。
開啟後一開始的狀況是沒有使用演算法排序的狀況,單純依照加入的順序去排序,按下"Sort"後就會依照演算法的結果為各個Sprite設定Z值。
當初主要導入這個做法的是我同事,我只是後來有在稍微修改
演算法參考網頁:https://wgcode.iteye.com/blog/847695
Sprite沒有使用圖,直接用drawingUtil來繪圖,發現用手機來看的話線條會沒辦法出來,也許是一個bug,也有可能是因為手機部分還沒有完善。
另外在點擊事件上也有一點問題,導致必須做很多處理才能達到縮放後也可以正確點擊,不確定這是我的用法錯誤還是這部分本身還不完整,可參照 https://github.com/hsienwei/zSort_cocos2dx_html5/blob/master/src/myApp.js
Line 53
Demo:https://dl.dropboxusercontent.com/u/10581994/pinball/pinball.html Github:https://github.com/hsienwei/pinball_unity
玩法就是按一下滑鼠左鍵放球,再按著滑鼠左鍵蓄力,放開後發射,當球都打完後按一下滑鼠左鍵會讓球掉到下面重來。
感覺上沒有花太多時間在寫程式,反而弄Model跟動作的處理比較花時間。
物理部分就完全用Unity內建的功能,主要只有調整Physic material來做到彈珠打到釘子會有彈回的效果,另外有將Time.fixedDeltaTime調小,不然速度快的時候球會飛出去,或者物理的行為不精準。
動作部分,球台下面的檔板基本上使用3ds Max中作的動畫,發射的動畫本來也是要用3ds Max來做,但是由於放到Unity中位置會跑掉,所以後來直接用Unity的Animation來處理。
Shader部分由於本來美術就不是專長,所以直接用一個內建的shader;另外沒有2D介面,之後再來試試看4.3的2D功能。
20151011補:
新版本(3.x)用cliping node即可
這裡指的mask是說一張圖但我要將指定一部分挖掉這樣,我在做的時候都是以一張圖為主圖,另一張mask圖以alpha值指定要挖空的地方
目前有試過兩種做法
大概程式碼如下
CCSprite* createMaskSprite()
{
cocos2d::ccBlendFunc bf;
bf.src = GL_DST_ALPHA;//GL_ONE_MINUS_DST_ALPHA;
bf.dst = GL_ZERO;
CCSprite* selfSprite = /*主圖的sprite*/;
CCSprite* maskSprite = /*mask圖的sprite*/;
selfSprite->setPosition(ccp(selfSprite->getContentSize().width/2, selfSprite->getContentSize().height/2));
maskSprite->setPosition(ccp(maskSprite->getContentSize().width/2, maskSprite->getContentSize().height/2));
selfSprite->setBlendFunc(bf);
CCRenderTexture *rt = CCRenderTexture::create((int)selfSprite->getContentSize().width, (int)selfSprite->getContentSize().height);
rt->beginWithClear(0, 0, 0, 0);
maskSprite->visit();
selfSprite->visit();
rt->end();
CCSprite *retval = CCSprite::createWithTexture(rt->getSprite()->getTexture());
retval->getTexture()->setAntiAliasTexParameters();
retval->setFlipY(true);
return retval;
}
主要是使用BlendFunc的方法,在RenderTexture畫出想要的效果之後再使用,但如果只直接用BlendFunc可能會被其他的sprite影響產不出想要的效果
Shader程式碼處理起來比較麻煩,建議看cocos2d-x範例程式的shader部分
下面是我寫的一個小範例
https://github.com/hsienwei/shader_cocos2dx
cocos2d-x的部分主要是參考範例程式改的
重要的是shader部分
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D u_texture;
uniform sampler2D u_mask;
void main() {
vec4 mainColor = texture2D(u_texture, v_texCoord);
vec4 maskColor = texture2D(u_mask, v_texCoord);
vec4 srcColor = vec4(mainColor.r * maskColor.a,
mainColor.g * maskColor.a,
mainColor.b * maskColor.a,
mainColor.a * maskColor.a);
gl_FragColor = srcColor;
}
將主圖的rgba值都乘以mask圖的alpha值即可,要達到這個效果只要動Fragment Shader即可
在一般的狀況下最為人所知產出apk的方法是使用ADT eclipse plugin功能來產出APK檔
(Android Tools->Export Signed/Unsigned Application Package)
但除此之外android也提供開發者經由ant產出apk檔
mac中有內建ant
所以可以在mac的終端機下指令來產出apk檔
那為何要使用ant
如果今天要產出多種版本 你必須要打開你的eclipse分別打開多個專案然後Export Signed/Unsigned Application Package
等於同樣步驟要作三次
而且還需要輸入密碼
而且你必須待在電腦旁邊
如果今天用ant來編的話 你可以指定一次編多種版本 也不用在輸入任何東西(前提是有寫到設定檔)
像我之前有產出10個檔案的需求(五個market api * 2(debug/release))
通常在離開公司時執行
隔天就可以寄出檔案了
以下寫一些在cocos2d-x中使用ant的經驗
使用cocos2d-x建立的android專案中
會比一般的android project多出以下的檔案
build.xml - ant使用的專案設置
local.properties - 裡面會有sdk的路徑設定值
ant.properties - 預設是空的 但可以在這裡設置編apk檔時使用的key相關設定
要注意的是如果你的android專案有使用其他的android專案當作library
那個專案也需要有這三個檔案
編譯的方式是在終端機下指令
ant <target>
如果沒有給target的話 會跑設定的預設target
在build.xml當中會匯入另一個custom_rules.xml,如果沒有的話就不會處理custom_rules.xml
<import file="custom_rules.xml" optional="true" />
在這裡的註解中有提到你可以在custom_rules.xml使用的target
-pre-build
-pre-compile
-post-compile
-post-package
-post-build
-pre-clean
基本上就如同target的名稱一樣 你在哪個階段有需求就去寫那個target
比方說我有需求是將編出來的檔案集中到一個資料夾中並讓檔名出現編譯時間, 版本資訊 所以我用到-post-build 內容如下
<target name="-post-build">
<tstamp>
<format property="package.time" pattern="yyyyMMdd_HHmm"/>
</tstamp>
<property name="apk.copy.name" location="../android_build_apk/${ant.project.name}_${apk.tag}_${build.android.param}_${package.time}.apk" />
<echo>copy ${out.final.file}</echo>
<echo>to ${apk.copy.name}</echo>
<copy file="${out.final.file}" tofile="${apk.copy.name}"/>
</target>
上面這個target會將編譯產出的apk複製到指定目錄並變更檔名
build.android.param 這個property是設定編譯時是測試版(debug)還是正式版(release)
apk.tag是我設定在ant.properties中用來表示這是那個市場的版本
這樣產出來的檔名會是project.name_xxx_release_20130705_1453.apk的樣子
如果是產出signed Application Package
在編譯的過程中會要求你輸入key的相關資訊
表示你產出多個檔的話就要輸入多次
其實可以把相關需要的參數設定到ant.properties中
就不需要輸入了
詳細的參數名稱可以參閱${sdk.dir}/tools/ant/build.xml
看看需要哪個property
我的狀況如下
key.store=../libs/android/keystore/igsgames.keystore
key.alias=xxx
key.store.password=xxxxxxxx
key.alias.password=xxxxxxxx
apk.tag=gplay
這樣可以不用每次輸入
但相對表示你把密碼打在檔案中給人看
所以你可以在執行ant時使用-Dproperty="xxx"這樣的方式輸入property
就不會有這樣的問題了
用ant其實還滿方便但是資料不太多
除了ant in action這本書外就是網站資料
另外在Android Studio中使用Gradie又是不同的系統
不知道下個專案還會不會有機會用ant