PIXNET Logo登入

太陽系後援會

跳到主文

部落格全站分類:職場甘苦

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 8月 18 週一 200801:08
  • 劍魂4的自創角色

http://www.gametrailers.com/player/38353.html
超搞笑的自創角色
第一對的快打旋風的倩咪和布蘭卡
第二對是春麗和貝卡
我還在網路上看過魯夫與麥當勞姐姐
真是超酷的啦
改天我也要自創一個角色來玩玩
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(0) 人氣(481)

  • 個人分類:遊戲新聞
▲top
  • 8月 18 週一 200800:22
  • 劍魂4(Soul Calibur 4)XBOX360版與PS3版的比較

最近在GameTrailers.com看到一段影片
http://www.gametrailers.com/player/37719.html
裡面是比較劍魂4的XBOX360版與PS3版的畫面比較
首先看到的是戰鬥前的In-Game明顯的不同,不僅僅是腳色的動畫就連運鏡也都有不一樣的手法,雖然大同小異,但是還是覺得做的很用心。不會是因為是做跨平台就搞同一套,有一種量身打造的感動。
再來就是腳色的細節,PS3版表現上細節比較看的出來,膚色與膚質較真實。XBOX360版看起來就像充氣娃娃,膚質太過光滑了(請看蘇菲亞的那段In-Game)。而且可以仔細看到PS3版乳搖程度比較劇烈,這應該是因為PS3版的玩家大部分是日本人的關係,NBGI比較照顧日本。可惡!!應該買PS3版的。
最後就是直接拼接兩個畫面來比較,仔細一看,兩個畫面對不太起來。這可能有兩個原因,第一個就是由於In-Game的鏡頭表現不一樣,所以運鏡時不是很match。第二個就是原生解析度兩個版本不同。再仔細一看,PS3版比較暗,XBOX360版比較亮,這應該是HDR參數調整的關係。兩個版本因為硬體性能的關係,對後製的調整參數多少都會不同,要調整到一樣的品質也是很難。除此之外,PS3版的鋸齒狀很嚴重,我記得以前看過一篇文章上面提到PS3的HDR與反鋸齒只能選一個開啟,原因好像是Render Buffer的關係,詳細情形還要去找找那篇文章。除了鋸齒,連model好像都有做的不一樣,仔細一看,PS3版的女性腳色眼睛比較大比較有神,XBOX360版的女性腳色兩眼都無神。這樣一來我覺得應該就是版本區域不同所做的特殊設計,為了因應市場考量,日本人總是比較喜歡大眼看起來可愛的女性,而歐美比較喜歡冷艷酷酷的女性。
這樣看了之後,總歸一句話
XBOX360在畫面上略勝一籌,原因可以歸因於XBOX360在開發上可能比較佔優勢畢竟已經開發多款遊戲而且硬體性能上比較平易近人。但是PS3版的Model個人感覺比較好,比例和表現方式我個人比較喜歡,再加上乳搖效果比較強烈,而且運鏡感覺有魄力。
可惜我已經先買XBOX360版了,不然我就買PS3版了。
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(0) 人氣(813)

  • 個人分類:遊戲新聞
▲top
  • 8月 16 週六 200822:37
  • Coding Style


每個人在寫文章時都有自己的風格,這會依據自己的文學造詣和思考邏輯而有不同。想想看,以前在聯考或是在作文課時,明明就是大家的題目都一樣,可是卻有人寫的好有人寫的差。而且是不可能會有相同的文章出現。但是照樣造句的話呢?那就會有可能出現一樣的造句,因為大家是在同一個規範之下寫簡短的句子(可能是抄參考書的)。
把相同的情形拿到寫程式這件事來看。在一個團隊中每個人的程度都不同,就算不會因為程度的關係,但是寫出來的程式碼卻會因為自己的習慣而大不相同。如果把相同的工作交待給兩個人同時去執行,姑且不論寫好寫壞,也不論完成的時間點與效果。這兩個人所設計出來的資料結構,類別的命名,再者介面與註解等等,都不會一樣。
這樣看來,相同的工作都會有不同的程式碼出現,那不相同的就更不可能會有機會一樣了(除非是用copy的)。
這麼說,一個專案的程式碼就像一本散文集。
其實散文集也沒有什麼不好,就當做看一篇一篇的短篇故事吧。
但是!
散文裡有參雜火星文或是古文就不好了吧!
有人或許會問
為什麼要擔心風格問題?
如果程式能夠Run的話,誰在乎裡面是什麼?
讓程式碼看起來漂亮不是很花時間嗎?
這些規則是不是太武斷?
事實證明,會有這種想法的人不適合當Programmer。(因為一定會被公幹到死)
寫的好的程式碼比較易於閱讀與了解,而且幾乎是錯誤比較少,並且比漫不經心又未修飾過的程式碼來的小又快。
想想看,在一個看似功能正常的程式,展開來的程式碼卻是一坨屎。
雜亂無章,演算法邏輯有問題,多做了重複的事情等等。
如果你看到了這樣的程式碼,心中一定會有一團無名火從"懶趴"那裏衝上來,甚至會嚴重的影響到你工作的情緒與進度。
許多Game Programmer都會埋怨美術或是企劃資料沒有用好。
批評美術為什麼要在很遠的地方放一個幾千面幾萬面的物件,批評企劃設計不好或是資料沒填正確。但是卻忽略了自己程式碼的品質與風格帶給團隊的殺傷力。
這遠遠比美術與企劃資料有錯來的難查,因為美術和企劃的資料都是把問題清楚的攤開來讓大家檢驗,惟獨程式碼是沒辦法被大家檢驗的,也只有Programer可以來審視,但監守自盜總是不好的吧,如果沒有把好的習慣養成,實在是很難說服別人自己的程式碼是沒有問題的。
命名
命名通常可區分為變數的命名與函式的命名,想像一下就跟你寫句子要有主詞與動詞一樣,主詞就是變數,動詞就是函式。以下是命名時的習慣與比較好的建議。
1.  全域變數在字首加上g_,成員變數在字首加上m_,靜態成員變數在字首加上ms_,區域變數也可加上l_或是不加,變數的型態是指標時加上p,例如g_pScene, ms_pSingleton, m_pNode, pAI。class和struct在字首加上C或S,或是由團隊共同指定字首(通常會利用專案或是公司的縮寫)。
變數的型態是int時加上i, unsigned int 加上ui, float 加上f, double 加上 d, char加上c, char * 加上pc。加上這些最主要是能夠快速辨識變數的型別,以免還要回到宣告的地方才能知道型別定義。如果是自己宣告的struct或是class通常不會加上型別識別,而是直接宣告描述性意思與strcut或class的名稱,例如有一個class叫做Node, 宣告一個m_SceneNode。
2. 全域變數(global)和成員變數(member)使用描述性名稱,區域變數(local)使用簡短的名稱。
3. const的變數使用大寫,例如:const float PI = 3.1415962f;。define的巨集或是常數也用大寫。
4. 維持一致性,給相關的事物取相關的名字,這些名字要能顯示之間的關係並指出彼此的差異。例如:
class CUserQueue 
{
public:
    int m_iNoOfItemInQ, m_iFrontofThequeue, m_iQueueCapacity;
};
[queue]這個字分別以Q, Quene, queue三種形式出現。然而變數只能經由UserQueue來存取,所以成員根本不需要提及[Queue]。而且一次出現三種形式反而更讓人混淆其意義。以下版本會比較好一點。
class CUserQueue
{
public:
    int m_iItems, m_iFront, m_iCapacity;
};
5. 函式使用主動名稱。函式名稱應該以主動動詞為基礎,後面可以加上名詞。例如float GetTime();。但是會傳回bool的函式名稱,就應該以可以從函式名字上看出傳回值所代表的意義。例如:bool CheckOctal(int iNumber);,並沒有指明哪個值代表true哪個值代表false。而bool IsOctal(int iNumber);,就清楚多了,因為引數是八進位就回傳true,否則就回傳false。
6. 名稱要精確。名稱不指示標籤,還會傳達資訊給讀者。一個誤導的名字會引發奇怪的臭蟲。例如:
bool InTable(Object * pObj)
{
    int j = this.getIndex(pObj);
    return (j == m_iTableCount);
}
如果發現物件的話,getIndex會回傳一個0到m_iTableCount-1的索引值,如果沒有則回傳m_iTableCount。因此InTable回傳的值和這個名稱所代表的意思正好相反。這樣會讓其他使用的人產生困擾,甚至要花一些時間來除錯,最後才發現產品外觀與內容不符。
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(4) 人氣(181)

  • 個人分類:程式設計
▲top
  • 8月 16 週六 200820:59
  • Refactoring to Patterns~Creation~Singleton

最後一個是為了確保Factory唯一性所做的機制
也就是DesignPatterns裡面的Singleton
相信很多人都有使用過的經驗
但是書中提到的卻是使用過度的Singletonitis(指沈迷於
Singleton)
裡面講了很多不需要使用Singleton的情形
它最大的問題就是製造了全域的變數
而且還是一個工廠(Factory)的大小!
並不是說不要使用Singleton
而是使用它之前一定要慎重的思考其必要性
到最後得到一個結論:
『當你可以設計出一種避免使用Singleton的方法時

就不要使用它』

再回到AI的建立
假設今天要建立物理的Shape
而且一隻AI可能需要多個Shape
可能會有這樣的設計:
class ShapeFactory
{
public:
    static
ShapeFactory * GetInstance()
    {
        static
ShapeFactory *ms_pFactory = NULL;
        if (
ms_pFactory == NULL)
           
ms_pFactory = new ShapeFactory();
        return
ms_pFactory;
    };
    NxShape *CreateShape(iType, vExtend, kTransform)
    {
        switch (iType)
        {
            case NxBoxShape:
                return ksPhysX::Get()->CreateBoxShape(
vExtend, kTransform);
            case NxSphereShape:
                return ksPhysX::Get()->CreateSphereShape(
                                   vExtend, kTransform);
            case NxCapsultShape:
                return ksPhysX::Get()->CreateCapsultShape(
                                   vExtend, kTransform);
        }
    };
private:
   
ShapeFactory();
    ~
ShapeFactory();
};
class PhysXKit
{
public:
    NxShape *CreateShape(iType, vExtend, kTransform);
    {
        return 
ShapeFactory::GetInstance()->CreateShape(
                        iType, vExtend, kTransform);
    }
};
嗯,我需要建立很多不同種類的Shape
所以我建立了一個Shpae Factory來處理這件事情
而且還是一個Singleton的Factory
但是有這個必要嗎?
事實上這個Factory只會被
PhysXKit使用
卻被建立為全域的Singleton Instance
理論上它應該被合併到
PhysXKit裡面,如下:
class PhysXKit
{
public:
    NxShape *CreateShape(iType, vExtend, kTransform)
    {
        switch (iType)
        {
            case NxBoxShape:
                return ksPhysX::Get()->CreateBoxShape(
vExtend, kTransform);
            case NxSphereShape:
                return ksPhysX::Get()->CreateSphereShape(
                                          vExtend, kTransform);
            case NxCapsultShape:
                return ksPhysX::Get()->CreateCapsultShape(
                                          vExtend, kTransform);
        }
    };
};
這就是書上提到的Inline Singleton(Singleton內置化)
如果再看詳細一點,會發現ksPhysX似乎也有同樣的問題
如此一直改下去,就能夠把不該存在的Singleton消除了
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(1) 人氣(51)

  • 個人分類:Refactory
▲top
  • 8月 16 週六 200813:28
  • 遊戲鐵三角

何謂[遊戲鐵三角]? 
每個遊戲創作都會有所謂的遊戲鐵三角,他們分別是企劃、程式、美術,這三大類型的人又被分作許多細類型,這群奇葩在遊戲工作中分工著不同的事務,也在不同企業文化的公司有著不同的稱號...

比如說:企劃會稱作編導、製作人(掛著好聽的名字依然是作相同的事情 :p),還有許多分身被稱作執行企劃、創意企劃、關卡企劃、系統企劃等等;而程式也有不同的稱號與專業分工人稱:程序、編程或工程師,也有依照「使用功能」被分作搞系統的、搞規劃的、成像類的、資料庫的、搞網路的、還有寫3D的,當然也會有萬能的神(........經病),自以為是萬能的「神」想要把所有的事情都覽在自己身上(也有一種說法是因為本身能力不足,在工作上沒有辦法作出適度的分工與切割);而美術分類就更為廣泛,大分為2D與3D,在對岸則是稱作二維與三維(搞曖昧的詞),兩大類之後又要分作造型設定、人物、場景、物件...公司規模越大他們ㄉ名目就會被分的更多更細,其中的派閥就會相對的增加,有趣的戲碼就會上演的更加厲害...

 

一舉成名天下知 一夜成屍無人問 
這三大類族群的人,大多躲在陰暗的角落裡(也有人稱為象牙塔)研發著不為人知的驚世駭俗的大作,個個期望一舉成名,但是彼此之間經常因為理念、立場、風格而產生不同的派系,彼此之間的合縱連橫,天天上演著「如何有效的將責任推卸給別人之後享受更多的權力(利)」的戲碼,但是螳螂與蟬的殊死戰中往往不自知最大隻的麻雀通常就是公司的決策者與殘酷且現實的玩家與市場。
雖然現實總是殘酷的,但是過程比結果重要的論點之下,讓遊戲研發人個個化悲憤為力量,又再一次的往下一套美麗的虛幻之火中投身而去,而前仆後繼樂此不疲,直到看破之後離開卻又遠遠的躲在一旁看笑話...

(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(4) 人氣(162)

  • 個人分類:遊戲開發
▲top
  • 8月 15 週五 200822:52
  • 中場休息時的小遊戲...

今日是公司聚餐...
我們這一桌在等待甜點來臨
正覺得無聊時
不知道是哪個該死的提議要玩數支遊戲
於是就拿起桌上的菜當作懲罰
第一輪是軟殼蟹
由艾文同學中獎
也激起了大家繼續玩的慾望
於是繼續下一輪
第二輪是湯裡面的丸子一顆
經過一番廝殺後
由傑斯特同學中獎
但是他心有不甘,決定要上訴
於是第三輪追加六顆丸子
中的人兩顆,下一個人四顆
這輪中獎的是川董
但重點是
下一個人是傑斯特兄
於是他就有了五顆丸子
傑兄不信邪,決定要賭到底
於是最後一輪是三隻軟殼蟹
中獎人的前一個後一個都要吃
結果,想當然爾的......他連莊三次
川董是他上一個,中了一隻
連我都被牽連到...
結算~
艾文:軟殼蟹一隻
李奧:軟殼蟹一隻
川董:軟殼蟹一隻 + 兩顆丸子
傑斯特:
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(5) 人氣(401)

  • 個人分類:閒聊八卦
▲top
  • 8月 13 週三 200801:32
  • Refactoring to Patterns~Creation~Builder

延續上一次的主題,再來看看Factory內部的建立流程
一個AI需要載入Model,需要建立FSM,需要建立Physics...
所以流程大概會有:
// Load model and create callback function
m_pAM = NiActorManager::Create( sFileName );
m_pkAnimCallback = NiNew AnimCallbackObject;
m_pAM->SetCallbackObject(m_pkAnimCallback);
// create state machine and some state node
m_pFSM = NiNew  ksFSM( iAgentType );
ksBaseStateNode *pIdleState = NiNew ksBaseStateNode(
                                                                                  IdleStateID );
m_pFSM->AddState(pIdleState);
ksBaseStateNode *pMoveState = NiNew ksBaseStateNode(
                                                                                      MoveStateID );
m_pFSM->AddState(pMoveState);
// create NxShape and NxActor for physcis
NxShapeDesc *pShapeDesc = ksPhysX::Get()->CreateBoxShape(
                                                                shapeflag, extension, transform);
m_pPhysXActor = ksPhysX::Get()->GetPhysXScene()->createActor(

                                        pShapeDesc);
嗯,看完頭也昏了,所以這也不是個好的建立方式
這時候Builder就出現了
這也是一種對於建構子的封裝方式
因為使用者建立AI的時候,通常不想知道太詳細的建立方式
而且寫太多雜七雜八很容易搞混或是漏寫
既然我們知道可以分成三大部分,就可以把建立的步驟拆解
每一個步驟都封裝成為function,只留下簡單的interface
首先把Builder建立出來:
class ksAIBuilder : public NiRefObject
{
public:
    ksAIBuilder();
    ~ksAIBuilder();
    // Load model and create callback function
   
NiActorManager *CreateActorManager();
    // create state machine and some state node
    ksFSM *CreateFSM();
    // create NxShape and NxActor for physcis
    NxActor *CreatePhysics();
};
建立完之後再來就是使用了,於是AI的建立流程就變成:
ksAIBuilder *pBuilder = NiNew ksAIBuilder();
m_pAM =
pBuilder->CreateActorManager();
m_pFSM =
pBuilder->CreateFSM();
m_pPhysXAcotr =
pBuilder->CreatePhysics();
這樣一來要建立AI就簡單多了,變化性又高
當我想要一個沒有物理的AI,只要不呼叫
CreatePhysics就可以了
既直覺又不容易出錯
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(1) 人氣(37)

  • 個人分類:Refactory
▲top
  • 8月 13 週三 200801:28
  • Refactoring to Patterns~Creation~Factory

首先要道歉一下,我看書的速度真的太慢了...
總之目前進入了第一大單元 - 創建(Creation)
顧名思義的它就是要教你怎麼用好的方式去建立一個Class
由於裡面內容牽扯到大量豬屎排程(Design Patterns)
不熟的人還請搭配書本服用
在我們建立一系列有繼承關係的Class,例如State Node
會很直覺的想要建立一個Factory來統一建立的介面
這樣做除了可以統一Client端呼叫建立的介面之外
維護起來也會比較簡單(不用到處東找西找)
但是怎麼建立那個Factory卻是個大學問
首先是Factory的介面
一般來說,以建立AI的例子來講,如下:
ksAI *pAI = AIFactory->CreateAI();
假如今天想要建立不同種類的怪物AI呢?
ksAI *pAI = AIFactory->CreateAI( iAIType );
複雜一點,建立AI的時候必須給他一些初始值:
ksAI *pAI = AIFactory->CreateAI( iAIType, iInitHP );
好像不夠,產生器需要生產的種類跟速度,有些怪物一開始要隱形
有些怪物需要Ragdoll Model:
ksAI *pAI = AIFactory->CreateAI( iAIType, iInitHP,
                            iChildType, fGeneraeSpeed, bVisiable,
                            sRagdollModelName...... );
是不是開始覺得複雜起來?因為初始值的種類太多了
當然你可以把初始值的資料包裝成Class或是Structure
但是總覺得包裝起來很麻煩,還要多建立一個物件,是否有其他方式呢?
書上提供一種Creation Method的方法
簡單來說就是對建構子(Constructor)作封裝的動作
例如我們確定了怪物的大分類,可以把介面再細分一下:
ksAI *pNormalAI = AIFactory->CreateNormalAI( iAIType,
                                           iInitHP, bVisiable);
ksAI *pGeneratorAI = AIFactory->CreateGeneratorAI( iAIType,
                                                iInitHP, iChildType, fGeneraeSpeed);
ksAI *pRagdollAI = AIFactory->CreateRagdollAI( iAIType, iInitHP,
                                            sRagdollModelName);
這樣一來一方面你可以很清楚知道你建立了哪個種類的AI
另一方面還可以簡化和控制傳入的參數數量
並且把子類別的建構子也封裝了起來
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(1) 人氣(63)

  • 個人分類:Refactory
▲top
  • 8月 09 週六 200813:22
  • 效能測試

製作遊戲時常常需要測試記憶體的使用量以及效能的評估
通常這種動作稱之為Profiling
這種通常會有強大的工具來輔助取得這些資訊
甚至更多的資訊
但是這種強大的工具通常會中斷遊戲的測試
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(0) 人氣(226)

  • 個人分類:遊戲開發
▲top
  • 8月 09 週六 200813:13
  • #,##的功能


# 和 ##這兩個是個非常好用的前置定義語法,通常搭配#define出現
1. #的用途是將啣接的符號轉換成字串
example
#define to_string(s) #s
使用方法
cout << to_string(Hello World!) << endl;
看清楚,Hello World並沒有"",因此它並不是字串,但是透過定義的巨集to_string可以將Hello World!符號轉換為字串。
以上程式片斷等於
cout << "Hello World!" << endl;
2. ##的用是將兩個程式片斷合併
example
#define concatenate( x, y) x##y
....
int xy = 10;
....
cout << concatenate( x, y) << endl;
等同於
cout << xy << endl;
##,#的功能太強大了,這裡實在說不清楚,畢竟要實作時才能體會它的強大威力
大家有興趣可以去看RTTI2部曲有用到##與#這兩個強大功能
至於其他使用的地方,就請大家仔細看看以後發的文章吧
讓我們一起大喊
彼得哥萬歲~~~~~~~~
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(0) 人氣(113)

  • 個人分類:C++
▲top
«1...456»

自訂側欄

個人頭像

kgsprogrammer
暱稱:
kgsprogrammer
分類:
職場甘苦
好友:
累積中
地區:

近期文章

  • 輕鬆愜意,沁涼消暑----轉吧!流麵
  • Hook 4 Fun ---- 終極派對遊戲
  • Design Pattern -- Observer
  • Design Pattern -- Strategy
  • Template
  • Shaders for Game Programmers and Artists--Chap1_welcome to the world of shaders (閱讀心得)
  • 基本演算法分析
  • 『The Making of God of War III』讀後雜談
  • 求整數以2為底的Log運算
  • 很有台灣味的國產元創iPhone, iPod Touch遊戲----Sliding War

最新迴響

  • [14/05/14] 阿信 於文章「基本演算法分析...」留言:
    當n小於3時,n!會比2^n還要快。 應該是 當...
  • [13/03/02] Wenjie Yao 於文章「遊戲鐵三角...」留言:
    太貼切了...
  • [12/06/18] KeystoneGame 於文章「輕鬆愜意,沁涼消暑----轉吧!流麵...」留言:
    寫得真好!!!XD...
  • [12/06/14] 隔行如隔山 於文章「提升效能的方法(一)...」留言:
    請問大哥的職業是什麼? 感覺好專業,有什麼入門的條件可...
  • [12/01/27] 王怡勻 於文章「Hook 4 Fun ---- 終極派對...」發表了一則私密留言
  • [10/07/19] 嘎布 於文章「為什麼Normal要乘上經過Invers...」留言:
    感謝分享~...
  • [10/06/18] allthen 於文章「求整數以2為底的Log運算...」留言:
    2和3都是二分搜尋,只是3比較淺顯易懂一點 用debug ...
  • [10/06/17] seeulin 於文章「求整數以2為底的Log運算...」留言:
    2看不懂啦 3是作弊的方法吧.........
  • [10/03/30] stranger 於文章「很有台灣味的國產元創iPhone, iP...」留言:
    版主很用心呢! 把這遊戲介紹的如此詳細 讓我也找回小時候...
  • [09/05/16] seeulin 於文章「快打旋風...」留言:
    樓上的同學你好像走錯地方了 這裡不是武術交流會喔...

文章彙整

文章分類

toggle 程式研究 (6)
  • Design Pattern (2)
  • Refactory (8)
  • AI (2)
  • 3D圖學 (4)
  • 程式設計 (7)
  • C++ (8)
toggle 遊戲研究 (3)
  • 遊戲設計 (5)
  • 遊戲新聞 (7)
  • 遊戲開發 (4)
toggle 閒聊八卦 (1)
  • 閒聊八卦 (4)
toggle 後援會 (1)
  • 後援會公告 (1)
toggle 彼得哥的生平事蹟 (1)
  • 名言錦句篇 (1)
  • Game Develepment (2)
  • C++ (3)
  • 未分類文章 (1)

部落格文章搜尋

誰來我家

參觀人氣

  • 本日人氣:
  • 累積人氣: