45度角地圖 Z-Sort 實作

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值。

當初主要導入這個做法的是我同事,我只是後來有在稍微修改
演算法參考網頁:http://wgcode.iteye.com/blog/847695

Sprite沒有使用圖,直接用drawingUtil來繪圖,發現用手機來看的話線條會沒辦法出來,也許是一個bug,也有可能是因為手機部分還沒有完善。

另外在點擊事件上也有一點問題,導致必須做很多處理才能達到縮放後也可以正確點擊,不確定這是我的用法錯誤還是這部分本身還不完整,可參照 https://github.com/hsienwei/zSort_cocos2dx_html5/blob/master/src/myApp.js Line 53

Unity練習:夜市彈珠台

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功能。

cocos2d-x mask 作法嘗試

20151011補:
新版本(3.x)用cliping node即可


這裡指的mask是說一張圖但我要將指定一部分挖掉這樣,我在做的時候都是以一張圖為主圖,另一張mask圖以alpha值指定要挖空的地方

目前有試過兩種做法

RenderTexture + BlendFunc

大概程式碼如下

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

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即可

剖析HTML資料轉為JSON

之前有一陣子很迷Puzzle & Dragon,所以常常查閱http://zh.pad.wikia.com/wiki/ 這個wiki網站,有一次用手機查的時候感覺他的手機板介面不太方便,而且如果可以用該資料為基礎讓手機通知我事件發生似乎不錯,所以就開始寫一個parser來處理網頁資料,把”緊急/降臨時間表”與”活動時間表”取需要的資料處理為JSON格式。

結果大概如下:
http://gcmtesthhhw.appspot.com/WikiData

那時候的大概想法是這樣:
用server跑一個排程,定時更新資料並用手機去取用。

Server端主要使用GAE,主要原因在我對server管理沒有經驗,用GAE我可以跳過server設定這一塊,Java基本上也是很熟了,所以寫起來沒啥問題,只是要了解一下CRON的排程設定。

剖析程式庫那時候選擇了http://jsoup.org/,使用上並不難,基本上就是實作NodeVisitor,然後使用head與tail方法的Node參數來判斷要取的資料,只是那時候有無法取執行javascript的問題,所幸影響不大,所以基本上就是取網頁程式碼,曾經有試過用JavaUnit想要取執行完javascript的網頁但還是失敗,所以這部分我後來就沒處理,JSON部分就直接用Java的JSONObject即可。

另外一個問題就是由於wiki資料由眾人維護,沒有一個既定格式,常常會有變更;取資料也不方便,沒有類似id的東西可以辨識,最後只好用標題來找,再取相對應的結構部分。

最後因為專案太趕就沒時間再進行,後來再去查已經有人出了一個相似但各方面都比較好用的APP,似乎沒有做的必要了。