青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

勤能補拙,Expter

成都游戲Coder,記錄游戲開發過程的筆記和心得!

2011年4月9日 #

關于 warning C4715問題。

介紹:
 
   關于warning C4715:not all control paths return a value
  (不是所有的控件路徑都返回值).

問題:
    一個函數,不是所有路徑都有返回值,如下:

    1) 基本數據類型
    對于函數的并不是每個分支都有返回值,那么這樣警告會提示不是所有路徑都有返回值。

int   test( int value )
{
     
if ( value > 0 ) return value;
}


   調用 int value = test( -1 );

   看下test的匯編代碼.

關于8個程序寄存器一般只有esp寄存器作為入棧,出棧,調用和返回指令作為棧指針,其余

比如eax,exc等寄存器都沒有固定的含義和固定值.
看下面test匯編代碼.
int   test( int value )
{

; 4個寄存器入棧
; ebp 用于存放函數棧的棧頂指針
; esp 用于存放函數棧的棧底指針

004113A0  push        ebp              ;將寄存器ebp的內容壓入程序棧
004113A1  mov         ebp,esp             ;保留esp寄存器
004113A3  sub         esp,0C0h             ;為該函數留出臨時存儲區
004113A9  push        ebx  
004113AA  push        esi  
004113AB  push        edi  

; 用0CCCCCCCCh初始化堆棧                
004113AC  lea         edi,[ebp
-0C0h]        ;lea直接尋址
004113B2  mov         ecx,30h             ;利用編譯器的offset立即尋址
004113B7  mov         eax,0CCCCCCCCh         ;eax
=0CCCCCCCCh
004113BC  rep stos    dword ptr es:[edi]     ;根據edi的大小來重復指令執行次數

; 如果 cmp為真則把value的值保存到eax寄存器中
; 否則跳轉到地址4113C7h,并沒有對eax做處理

     
if ( value > 0 ) return value;
004113BE  cmp         dword ptr [value],
0 
004113C2  jle         test
+27h (4113C7h) 
004113C4  mov         eax,dword ptr [value] 
}


;各指針出棧,對應前面3條push

004113C7  pop         edi              ;彈出edi
004113C8  pop         esi              ;彈出esi
004113C9  pop         ebx              ;彈出ebx
004113CA  mov         esp,ebp             ;把esp重新指向ebp(函數棧的棧頂指

針,test函數棧頂)
004113CC  pop         ebp              ;ebp重新指向test調用函數返回地址
004113CD  ret


調用匯編代碼

int value = test ( 1 );
004113FE  push        
1    
00411400  call        test (4110AFh) 
00411405  add         esp,4             ;Call test 函數時將壓入棧數據,

由于只有一個參數,所以只有4字節
00411408  mov         dword ptr [value],eax 

當test 調用小于0時最后value指向的eax是一個0CCCCCCCCh,而對于基本數據類型大多value得到的是0CCCCCCCCh值.
如果我們的test函數:

int   test( int value )
{
     
if ( value > 0 ) return value;
     
return 0;
}

那么匯編代碼會如下:

     if ( value > 0 ) return value;
004113EE  cmp         dword ptr [value],
0 
004113F2  jle         test
+29h (4113F9h) 
004113F4  mov         eax,dword ptr [value] 
004113F7  jmp         test
+2Bh (4113FBh) 
     
return 0;
004113F9  xor         eax,eax   ;將eax清零,作為返回值



   2 )如果返回的是一個引用對象
    

obj &  test( type value )
{
    
if( type2 ) return obj;
}


obj 
& ob = test( type1 );

   如果ob是個空引用的話,就出出錯,關于這種出錯是否可以通過什么方式避免呢?

   我覺得warning C4715就應該是error C4715.讓開發者從最開始就避免這種錯誤的發生。

 

posted @ 2011-04-09 12:52 expter 閱讀(5856) | 評論 (3)編輯 收藏

2011年3月23日 #

利用Win32消息來解決MyGui中文完整輸入

date:  3/23/2011

介紹:
    利用Win32 來處理MyGui 3.0.1的中文輸入。

實現:
    配置還是參考網上的配置,主要再加中文字體.
   如下:
□ 更改配置文件MyGUI3.0\Media\MyGUI_Media下

☆ core_font.xml添加

<Resource type="ResourceTrueTypeFont" name="font_Simhei">
        
<Property key="Source" value="simhei.ttf"/>
        
<Property key="Size" value="19"/>
        
<Property key="Resolution" value="50"/>
        
<Property key="Antialias" value="false"/>
        
<Property key="SpaceWidth" value="4"/>
        
<Property key="TabWidth" value="8"/>
        
<Property key="CursorWidth" value="2"/>
        
<Property key="Distance" value="6"/>
        
<Property key="OffsetHeight" value="0"/>
        
<Codes>
            
<Code range="33 126"/>
            
<Code range="19969 40869"/>
            
<Code hide="128"/>
            
<Code hide="1026 1039"/>
            
<Code hide="1104"/>
        
</Codes>
    
</Resource>

☆ simhei.ttf要從系統目錄下的Fonts拷貝到當前目錄。

☆ core_settings.xml中將默認字體改成

    
<MyGUI type="Font">
        
<Property key="Default" value="font_Simhei"/>
    
</MyGUI> 


     運行Demo解決方案:   solution_directx。

       給BaseManager添加Win32消息響應函數void ProcIO(UINT messgae, WPARAM wParam, LPARAM lParam ).
      
case WM_CHAR:
        
case WM_KEYDOWN:
        
case WM_KEYUP:
            
{
                
base::BaseManager *baseManager = (base::BaseManager*)GetWindowLongPtr(hWnd, GWL_USERDATA);

                
if ( baseManager )
                    baseManager
->ProcIO( uMsg , wParam , lParam );
                
break;
            }

   ProcIO主要是對
   WM_CHAR                                   字符響應
   WM_KEYDOWN/WM_KEYUP  按鍵響應

   在處理字符響應的時候需要區分輸入法狀態和非輸入法狀態的字符響應。
case WM_CHAR:
            
{
                
if ( ImmIsIME( GetKeyboardLayout(0) ))
                    ProcChar( wParam , lParam );
                
else
                
{                     
                    MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(scan_code), code_point);
                }
;
            }

            
break;

ProcChar函數主要處理中文。因為漢字為8個字節會響應WM_CHAR2次。需要進行組合一次。
WM_KEYDOWN:主要處理一些Widget字符輸入。同時還可以做全局鍵盤信息監控(快捷鍵).

判斷一個Widget是否可以進行字符輸入:
\MyGUIEngine\include\MyGUI_InputManager.cpp
bool     InputManager::isKeyInputCapture()
    
{
        
if!mWidgetKeyFocus ) return false;

        std::
string  strName = mWidgetKeyFocus->getTypeName();
        
if ( strName == "ComboBox" ||
            strName 
== "Edit" ||
            strName 
== "Message" ||
            strName 
== "List")
        
{
            
return true;
        }

        
return false;
    }

由于采用Win32鍵盤消息,應該屏蔽自帶OIS的。
Input\OIS\InputManager.cpp
void InputManager::captureInput()
 
{
  
if (mMouse) mMouse->capture();
  
//mKeyboard->capture();
 }

在Demo中監控按鍵消息( DemoKeeper功能是UIManager )。
void DemoKeeper::injectKeyPress(MyGUI::KeyCode _key, MyGUI::Char _text)
    
{
        
if (_key == MyGUI::KeyCode::Grave)
        
{
            mConsole
->setVisible(!mConsole->isVisible());
            
return;
        }
  
        
else if (_key == MyGUI::KeyCode::F2 )
        
{
            MyGUI::Message::createMessageBox(
"Message""Info""Press F2 ", MyGUI::MessageBoxStyle::Ok | MyGUI::MessageBoxStyle::IconInfo);
            
return;
        }

        
else if (_key == MyGUI::KeyCode::F3 )
        
{
            MyGUI::Message::createMessageBox(
"Message""Info""Press F3 ", MyGUI::MessageBoxStyle::Ok | MyGUI::MessageBoxStyle::IconInfo);
            
return;
        }


        
base::BaseManager::injectKeyPress(_key, _text);
    }


最后附上源碼解決方案:
/Files/expter/MyGuiDemo.rar

圖片:

posted @ 2011-03-23 15:20 expter 閱讀(3955) | 評論 (3)編輯 收藏

2011年2月24日 #

根據子類類型訪問其特有操作

     摘要: 描述:   一個常見遇到的解決方案,下面記錄下來。   1個功能模塊,有一個簡單的繼承體系,基類假設為Base.   然后通過一個接口,如何訪問子類的特有操作?     /// 外部提供一個下面接口:   virutal   Base*  ...  閱讀全文

posted @ 2011-02-24 23:23 expter 閱讀(2255) | 評論 (4)編輯 收藏

2011年1月18日 #

針對一個內存池測試相關介紹

目的:
針對自己的一個內存池如何測試其性能.

介紹:
1.內存池測試用例的選取.
1.單線程的分配和釋放.
2.內存回收.
3.性能關注.

關于內存池的設計和實現網上遍地都是,本文不具體介紹關于內存池的具體實現和方式,主要是介紹設計一個內存池怎樣去測試其性能和安全處理,有一個開源的內存池項目tcmalloc也有介紹很多,但是為了滿足多種需求,代碼過于龐大,最后我用來測試分配性能測試。

1個內存池的測試用例應該包含:
1)該項目內存分配概率隨機性.
2)同時保證釋放的隨機性.
3)可以支持多種分配方式(不同大小,不同對象參數等).


要達到上面要求則可以設計
1.一個數組來設定需要分配的大小。
   long  arr[ ] = { 16,32,64,128,256,512,1024,2048,5120,5130,7000,6000,10240,15000,20000};

2.根據需求來指定各個大小的分配幾率,這好比有多少概率選中某個數(需特定的分配):
   

 A.針對這個需求可以設定定一個概率數組Odds,數組值arrArr的索引。
    B.針對Odds指定數組數據,使其數據分配達到arr需要分配概率。
       
///   被分配的概率
       long  Odds[ ] = 0,0,0,1,1,2,2,2,3,3,4,4,4,4,5,5,5,5,6,6,,7,7,7,8,8,8,8,9,9,9,10,10,11,12,12};
    C.隨機Odds數組,然后得到其值分配,其值則為Arr的索引。
        
long  Asize= arr[ Odds[ rand()%size ] ] ;



3.釋放保證隨機性。
     什么時候釋放,以及分配了做什么用,都是又應用層決定的,所以需要把分配出來的內存通過一個容器來存儲.
     由于分配是隨機性,那么釋放的時候也保證了隨機性。

4.支持多種分配方式。
     A. 對象分配:     

MemFactory  Memory;

    A
* a = Memory.Alloc<A>( );
    B
* b = Memory.Alloc<B,int>2 );

    Memory.FreeObj( a );
    Memory.FreeObj( b );

    B.直接分配

void* p1 = Memory.Alloc( Asize );


5.性能測試
   為了測試性能,我選擇了分配1000W次,其中用一個容器保存分配的數據,然后當容器到達100W的時候釋放60W數據(保證數據正在使用,隨機釋放)。
   下面的Alloc time 只是統計的Alloc時間累加,Free time只是統計的Free 時間累加,Total time記錄這次測試總共花費時間。

 1測試結果如下:
 2MemPool Alloc time 3242 ms  Free time: 2412 ms Total time 22535 ms
 3System    Alloc time 33616 ms Free time: 6676 ms Total time 55013 ms
 4TCMalloc Alloc time 3451 ms   Free time 1896 ms  Toal  time 21078 ms
 5
 6可以看到TCMalloc的分配和釋放都比較快。。
 7
 8其中arr每個分配的大小命中概率。
 9Count[ 1 ] = 2436395
10Count[ 2 ] = 1281728
11Count[ 3 ] = 1026009
12Count[ 4 ] = 769123
13Count[ 5 ] = 768911
14Count[ 6 ] = 769335
15Count[ 7 ] = 640757
16Count[ 8 ] = 640974
17Count[ 9 ] = 512378
18Count[ 10 ] = 384841
19Count[ 11 ] = 256135
20Count[ 12 ] = 257367
21Count[ 13 ] = 256047



PS:
1.內存池的使用:
  

   一般情況下內存池,是整理一整塊內存,然后通過一個list串連起來,然后分配的時候從鏈表中獲取,釋放也是插入到鏈表中。
    為了方便多對象的多參數以及無參數的分配,可以一些列宏和模板來實現:
    
    具體的可以參考后面附帶的內存池實現的代碼:
    
    
#define DEFINE_CALL_CON( paramcount ) template <class T, DP_STMP_##paramcount( typename, tp ) >\
    inline T 
* Alloc(DP_MTMP_##paramcount( tp, p ) ){\
           unsigned 
long lSize = sizeof(T);\
           
void* ptMem = Alloc(lSize);\
         
if!ptMem) return NULL; \
          T 
* pt = new(ptMem)T( LP_SNMP_##paramcount( p ) );\
         
return pt;\
      }

    
    A. 對象分配:      
    MemFactory  Memory;

    A
* a = Memory.Alloc<A>( );
    B
* b = Memory.Alloc<B,int>2 );
    C* c = Memory.Alloc<C,int,const char*>(1,"dd");
    Memory.FreeObj( a );
    Memory.FreeObj( b );
       Memory.FreeObj( c );

    B.直接分配
    
void* p1 = Memory.Alloc( Asize );
        memset(p1,0,ASize);


2.內存池的代碼:
   1)   實現全是利用的freelist,減少內存開銷,分配速度,直接定位。
   2)   管理都是通過工廠類來同一的管理。
   3)   指定分配策略.

   源碼為Vs2008版本...

   /Files/expter/Pool.rar

關于實現有疑問和建議,可以提出寶貴的意見。。

posted @ 2011-01-18 21:20 expter 閱讀(3495) | 評論 (3)編輯 收藏

2011年1月14日 #

一個關于容器選取的刪除問題。


問題描述:
1個容器有大量元素,需要進行erase大部分數據的時候,需要遍歷這些元素,然后釋放item的空間,還要erase刪除其item。

一個庫,為了測試其性能的時候,需要保存所有外部使用者的數據,這里選取了map,vector和list.

為了簡化問題,我寫了下面測試代碼來測試各個操作:
數據節點:

struct node
{
    node(
int i){data = i;}
    
int data;
}

 1int _tmain(int argc, _TCHAR* argv[])
 2{
 3    typedef std::map<long,node*> Mptable;
 4    typedef std::vector<node*>   Vec;
 5    typedef std::list<node*>     List;
 6    
 7    Mptable        mapnode;
 8    Vec            vecnode;
 9    List        listnode;
10
11    for(int i = 1 ; i <= 100000 ; i++ )
12    {     
13        mapnode [ i ] = new node(i);
14        vecnode.push_back( new node(i) );
15        listnode.push_back( new node(i));
16    }

17
18    long time = timeGetTime( );
19    
20    for( Mptable::iterator itr = mapnode.begin() ; itr != mapnode.end() ;  )
21    {
22         delete itr->second;
23         mapnode.erase( itr++ );
24    }

25
26    std::cout <<"map : spend " << timeGetTime() - time << " msec " << std::endl;
27
28
29    time = timeGetTime( );
30    
31    for( Vec::iterator itr = vecnode.begin() ; itr != vecnode.end() ;  )
32    {
33         delete *itr;
34         itr = vecnode.erase( itr );
35    }

36
37    std::cout <<"vector : spend " << timeGetTime() - time << " msec " << std::endl;
38
39
40    time = timeGetTime( );
41    
42    for( List::iterator itr = listnode.begin() ; itr != listnode.end() ;  )
43    {
44         delete *itr;
45         itr = listnode.erase( itr );
46    }

47
48    std::cout <<"list : spend " << timeGetTime() - time << " msec" << std::endl;
49
50
51    return 0;
52}
Release下運行結果:
map : spend 31 msec
vector : spend 3734 msec
list : spend 35 msec


發現map的速度最快,vector最慢,list相當。

其實vector就是一個Array,只是Array是靜態大小,vector可以擴展,然后查看vector的erase的源碼:
iterator erase(const_iterator _Where)
        
{    // erase element at where
        _Move(_VIPTR(_Where) + 1this->_Mylast,
            _VIPTR(_Where));
        _Destroy(
this->_Mylast - 1this->_Mylast);
        
--this->_Mylast;
        
return (_Make_iter(_Where));
        }
有一個move操作,原來把當前iterator+1的往前移了,這樣的話會遍歷iterator后面所有的元素。


關于map的erase原理可以查看map的實現源碼:
由于map的erase后有一個維護過程,其實map是一個RB-Tree,刪除算法相對比較麻煩,刪除某個item會查找下一個item替換刪除的節點,同時還要考慮紅和黑的節點處理。同時還要保證map的erase后,平衡且有序。
所以map的erase主要做:
1.刪除item.
2.讓樹平衡,且有序。

list其實是一個雙向鏈表:
關于刪除其實是0(1)的操作,我們查看list的erase的操作:
    iterator erase(const_iterator _Where)
        
{    // erase element at _Where
 #if _ITERATOR_DEBUG_LEVEL == 2
        
if (_Where._Getcont() != this || _Where._Ptr == this->_Myhead)
            _DEBUG_ERROR(
"list erase iterator outside range");
        _Nodeptr _Pnode 
= (_Where++)._Mynode();
        _Orphan_ptr(
*this, _Pnode);

 
#else /* _ITERATOR_DEBUG_LEVEL == 2 */
        _Nodeptr _Pnode 
= (_Where++)._Mynode();
 
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */

        
if (_Pnode != this->_Myhead)
            
{    // not list head, safe to erase
            this->_Nextnode(this->_Prevnode(_Pnode)) =
                
this->_Nextnode(_Pnode);
            
this->_Prevnode(this->_Nextnode(_Pnode)) =
                
this->_Prevnode(_Pnode);

            _Dest_val(
this->_Alnod, _Pnode);
            
this->_Alnod.deallocate(_Pnode, 1);

            
--this->_Mysize;
            }

        
return (_Make_iter(_Where));
        }
主要代碼刪除就是下面刪除部分:
對prev和next節點進行處理即可。

關于list的移除竟然比map還要慢.

PS:測試為單線程。

當為100W數據的時候:
map : spend 300 msec
list :   spend 385 msec

咋list比map容器還要慢?
還是上面的代碼不能說明問題。

posted @ 2011-01-14 14:58 expter 閱讀(2610) | 評論 (2)編輯 收藏

2010年7月31日 #

在CEGUI顯示GIF圖像,簡單的聊天窗口實現方式.

       author:expter
       date:   2010/07/31
   
    上次寫的超鏈接是重寫了一個單獨的超鏈接控件,主要實現文本的鼠標事件和文本下劃線,靜態圖像的顯示,主要寫的渲染過程,這次為了解決動態圖片(比如gif有多幀實現的解決方案).

    注:主要針對當前CEGUI的最新庫0.7.1。

    目的:在游戲聊天框中可能有一個聊天表情,次表情是動態的,需要顯示動態表情圖片,同時可能有超鏈接等功能,我們約定一種解析格式,然后輸入表情代碼或者超鏈接內容即可顯示我們需要的功能。
 
    實現方式: 
        由于針對聊天窗口,所以這里聊天窗口內容采用CEGUI::ListBox,每條消息內容為ListBoxTextItem,由于ListBox有滾動horzScrollbar條,而一般聊天窗口沒有horzScrollbar此功能,所以假設一段話過長我們需要才分內容,可能一條消息包括多條ListBoxTextItem。每行里面可能有文本,表情,圖片,以及超鏈接等.
      
       由于CEGUi不能直接解析Gif文件,我們需要把gif的每一幀全部到出來,然后實現一個當前表情anim控制類,表情管理變量,文件解析類TalkRenderedStringParser。
       Anim主要記錄當前表情應該為那幀的哪張圖片。
      表情管理主要記錄當前所有的動態表情,每幀時間到達的時候開始渲染。
      TalkRenderedStringParser還是一個文本解析類。

 

簡單的ChatList的主要文本如下:
[C FFFF0000]StaticTxt test1![\\ 1] [\\ 3]
dasd[\\ 2] [\\ 3] [\\ 4] [\\ 1] [\\ 5]

其實是動態表情,只是切的圖片不能顯示了:

要實現一個與游戲相關的聊天窗口基本功能都具備了,這里包括實現超鏈接,表情圖片,圖片的功能。

然后只需要制定分頻道等功能分別顯示不同的聊天信息。



源碼功能上相對比較簡單,CEGUI庫做了相應的修改。


               

posted @ 2010-07-31 11:58 expter 閱讀(3871) | 評論 (6)編輯 收藏

2010年7月22日 #

基于CEGUI的StaticText的超級鏈接實現

    基本上實現一個基于靜態文本多任務的過程.

注:主要針對當前CEGUI的最新庫0.7.1。

目的:游戲制作過程中一般打開NPC會彈出一個對話框,一般對話框就是顯示一段話,有圖片,超鏈接,文字,同時文本分別有不同的顏色!
那么只要我們輸入一段文本,對話框的控件解析文本定義好的標簽然后顯示所有文本內容和圖片即可。

實現方式: 
1.超鏈接控件既要響應點擊消息,又要有超級鏈接標記的下劃線。實現方式主要參考了Button的Clicked事件,StaticText的render渲染過程,重新寫的一個基于超級鏈接組件。
2.文本解析利用了當前CEGUI的版本的BasicRenderedStringParser類,我們只需要繼承此類,然后設置系統默認的文本解析類為我們當前的類。
3.寫超級鏈接組件的渲染過程主要方便支持CELayoutEditor的可視化編輯。

實現結果:
1.文本顯示顏色。
2.換行操作。
3.支持超級鏈接的顯示,以及事件響應和事件處理,事件響應為CEGUI::HyperText::EventClicked。
4.超鏈接的下劃線繪制。
5.支持圖片顯示和支持圖片事件響應。


假設我們的解析文本如下:
標簽定義如下
[N]則是換行字符
[C]字體顏色
[A]超級鏈接
[M]圖片

相對來說編寫此文本比較簡單.

具體用法
xxx             顯示文本xxx
[C  XX]      xx表示32位的字體顏色
[A 1: XX]   xx 超級鏈接顯示內容。
[M  xx]       xx表示圖片名字

colorTest:[N]
StaticTxt test1![N]
[C FFFF0000]StaticTxt test2!    [N]
[C FFFFFF00]StaticTxt test3!   [N] [N] [N]

[C FFFF0000]HyperLink Test:  [N]
[A 1:this is the Hyperlink!this is the  Hyperlink!][N]
[A 2:this is the second Hyperlink! this is hyperlink!!!][N]
[A 3:this is the third hyperlink!this is hyperlink!this is hyperlink!this is hyperlink!]
[N] [N] [N]
Image Text:[M 381] [M 286] [M 669]


具體過程:


后期目標支持動畫的顯示,比如GIF格式圖片.

實現過程相對繁瑣,而且涉及datafiles配置一些處理。

可能真正游戲界面上的實現可能會更豐富,其實也就是增加幾個標簽然后解析即可。


注:上次聽蓋老板說有本書專門介紹足球AI,然后專門去買了,看其介紹他實現上足球仿真AI專門實現比較智能,先學習學習他的在繼續寫我的了。。

posted @ 2010-07-22 22:12 expter 閱讀(2802) | 評論 (9)編輯 收藏

2010年6月30日 #

一個基于足球AI仿真機的模擬實現

       author:expter
       date   2010/06/30
 
       介紹:  世界杯現在如此的備受矚目和關注,本文介紹如何實現一個基于足球AI的實現,而作為程序員我們關注的不是目標用其贏得世界杯,而是創造一個把球踢好的智能體,加上最近上班輕松,晚上較閑,加上去年實現的一個AI模型與平時寫的游戲智能算法,想組織起來完成一個足球模擬玩玩。
      
      本文會首先介紹一種基于AI仿真機的實現流程圖,后面我將會用大量的篇幅詳細介紹各個實現細節,與具體足球戰術,此足球AI主要是主動攻擊性AI,所以還需要具體完善加強防御性的AI,所以具體代碼現在將不會現在放出。以后實現完整過后會完整公開,現在主要設計描述如下。
  
        足球的游戲規則不是很復雜,就是2個球隊,然后每個球隊一個守門員與幾名球員,目的就是踢進對方的球門。簡單的足球是沒有傻子的,也就沒有犯規,越位,頭球,點球以及烏龍球。以后可能會增加上面幾種。

        一個簡單的游戲的具體環境如下:
         1.一個足球場(FootBallPitch)
         2.一個足球     FootBall
         3.二個球門     Goal
         4.二個球隊     FootBallTeam
         5.場上12名足球隊員(每隊6名,期中5名為球員2名后衛3名前鋒,還有1名守門員)
         6.球員             FootBaller    守門員  GoalKeeper
  
     然后只要理清上面的描述然后把具體的實現封裝到每個類中,就實現了1個簡單的足球仿真模擬,實現上面的功能代碼還是簡單,但是如何組織強大攻擊性強大,防御性強的AI還是挺復雜的。
    
       下面將給出具體UML實現類圖:   
       
          
         由于是基于智能體的足球AI所以還是借鑒了FSM模型,我們可以把每個Player處于不同的狀態進行不同的操作,具體把操作類型和事件處理都放在具體的狀態中。
         基于球場上運球的FootBaller有下列狀態ChaseBall 追球狀態,Dribble運球  Gohome 歸位   KickBall 踢球  ReceviveBall傳球 
         基于守門員GoalKeeper有InterceptBall 攔截  PutBallBackInPlay發球.
  
        這里為了區分隊員是前鋒還是后衛,我們給隊員增加一個行為Behaviors,讓其根據自己的行為做相應的事情.。

        其中所有的圖像處理都是用的GDI的繪制,程序采用的Win32編寫方式。

       上面的設計基本是現在程序的設計方案和流程圖。

        后期完善部分:
        1.引入基于事件響應,FootBaller 可以通知同隊FootBaller 的接收響應的消息處理,比如A發現B的位置很好,A可以通知B我要傳球到一個坐標點。
       2.加強防御和攻擊AI。
       3.完成具體方案后,公布所有的方案設計和具體算法,后期引入腳本機制,通過外部編寫腳本實現不同隊伍AI模擬。       

          

posted @ 2010-06-30 23:36 expter 閱讀(3001) | 評論 (7)編輯 收藏

2010年4月14日 #

基于策略的一種高效內存池的實現

     摘要: 一.XXX      1)概念說明          這里不再具體描述內存池的概念和作用,需要了解請看http://baike.baidu.com/view/2659852.htm?fr=ala0_1_1。   &nbs...  閱讀全文

posted @ 2010-04-14 23:23 expter 閱讀(5503) | 評論 (11)編輯 收藏

2010年3月5日 #

一個高效的定時器分析及設計

     摘要:        對于一個游戲而言,定時器是必須的,而它一般作為一個游戲基本公共組件,而定時器在游戲邏輯中運用是非常明顯的(比如吃藥回血,每幾秒回血多少),而對于游戲邏輯而言需要開發一個高效率高精度(毫秒級別)的定時器。      一:分析Ace庫定時器實現方式   1.Ace種定...  閱讀全文

posted @ 2010-03-05 16:28 expter 閱讀(9163) | 評論 (12)編輯 收藏

僅列出標題  下一頁
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美专区亚洲专区| 亚洲图片在线观看| 老司机67194精品线观看| 午夜精品一区二区三区在线| 国产模特精品视频久久久久 | 欧美高清不卡| 亚洲肉体裸体xxxx137| 日韩亚洲欧美高清| 国产精品久久久久久久久久久久久久 | 欧美极品在线观看| 亚洲淫片在线视频| 欧美影院在线播放| 亚洲欧洲精品天堂一级| 日韩亚洲一区二区| 国内精品久久久久久久影视蜜臀| 老司机aⅴ在线精品导航| 欧美精品www| 欧美在线观看日本一区| 老司机精品福利视频| 国产精品99久久不卡二区| 午夜国产精品视频免费体验区| 国产一区二区三区在线观看视频 | 久久成人18免费网站| 久久看片网站| 亚洲一区二区日本| 久久人人爽人人爽| 亚洲欧美国产77777| 久久午夜羞羞影院免费观看| 久久婷婷国产综合国色天香| 亚洲经典自拍| 国产乱子伦一区二区三区国色天香| 狂野欧美一区| 国产精品v片在线观看不卡 | 久久久久国产成人精品亚洲午夜| 免费视频最近日韩| 久久久精品一区| 欧美网站在线观看| 亚洲福利视频网| 国产亚洲激情| 亚洲视频观看| 一区二区久久久久| 蜜臀久久99精品久久久画质超高清| 欧美一区1区三区3区公司| 欧美精品一区二区三区高清aⅴ| 久久黄色影院| 国产精品一区二区黑丝| 日韩一二三区视频| 亚洲精品欧美一区二区三区| 久久久久**毛片大全| 欧美一区二区成人6969| 欧美日韩另类一区| 亚洲人成人一区二区三区| 亚洲福利国产| 久久久久久亚洲精品中文字幕| 午夜精品在线视频| 国产精品毛片va一区二区三区 | 91久久综合| 免费国产自线拍一欧美视频| 久久综合中文字幕| 狠狠色丁香久久综合频道| 欧美一区二区三区四区视频| 新狼窝色av性久久久久久| 国产精品国产自产拍高清av| 在线亚洲一区观看| 午夜老司机精品| 国产精品久久久久久久久久尿| 日韩午夜一区| 亚洲女性裸体视频| 国产精品日韩久久久久| 亚洲永久精品大片| 久久国产精品99国产| 国产日韩欧美在线看| 午夜伦理片一区| 久久久999成人| 在线观看一区二区精品视频| 久久亚洲一区二区| 亚洲精品国产系列| 亚洲婷婷综合久久一本伊一区| 欧美了一区在线观看| 99精品免费| 久久国内精品自在自线400部| 国产一区二区三区四区老人| 久久综合电影一区| 99热在这里有精品免费| 亚洲免费在线观看| 国产日韩欧美日韩大片| 久久九九精品| 91久久国产自产拍夜夜嗨| 一本高清dvd不卡在线观看| 亚洲黄色影院| 日韩一级片网址| 亚洲综合二区| 国语自产偷拍精品视频偷 | 亚洲人成欧美中文字幕| 亚洲午夜精品一区二区| 国产欧美日韩在线 | 亚洲视频在线观看| 久久久久久黄| 亚洲精品一区中文| 国产美女精品视频免费观看| 狂野欧美一区| 亚洲桃花岛网站| 欧美1区2区3区| 亚洲在线播放| 亚洲人成在线免费观看| 国产乱码精品一区二区三区忘忧草| 久久久最新网址| 亚洲特级毛片| 亚洲人成在线观看网站高清| 久久这里有精品视频| 中日韩男男gay无套| 狠狠久久综合婷婷不卡| 国产精品久久久久久久久免费樱桃| 欧美在线网址| 亚洲夜间福利| 亚洲欧洲一区二区在线播放| 久久只有精品| 久久高清一区| 销魂美女一区二区三区视频在线| 亚洲精品视频免费在线观看| 国内一区二区在线视频观看| 国产精品久久久久7777婷婷| 欧美伦理在线观看| 免费人成精品欧美精品| 久久久午夜精品| 翔田千里一区二区| 亚洲一区三区视频在线观看| 亚洲精品国产拍免费91在线| 欧美电影在线观看| 久久综合激情| 久久久久久久成人| 久久精品动漫| 久久福利一区| 久久疯狂做爰流白浆xx| 欧美一区二区在线看| 亚洲女同精品视频| 午夜亚洲福利| 久久国产乱子精品免费女 | 在线观看欧美黄色| 韩日精品在线| 激情五月婷婷综合| 激情偷拍久久| 亚洲大胆人体视频| 亚洲精品一区在线观看香蕉| 亚洲毛片视频| 99国产精品国产精品久久| 亚洲精品三级| 亚洲午夜精品网| 欧美一级在线亚洲天堂| 欧美在线免费视屏| 久久久久久尹人网香蕉| 久热精品视频在线观看| 男女av一区三区二区色多| 欧美不卡视频一区| 亚洲激情在线激情| 亚洲性图久久| 久久国产精品网站| 麻豆91精品| 欧美亚州在线观看| 国产一级一区二区| 亚洲成色777777女色窝| 亚洲精品视频在线观看免费| 一区二区国产精品| 羞羞答答国产精品www一本| 久久精品国产99国产精品澳门| 欧美—级高清免费播放| 欧美一区激情| 免费成人高清在线视频| 欧美日韩国产综合视频在线观看中文 | 快射av在线播放一区| 欧美激情视频给我| 国产精品入口66mio| 亚洲福利在线看| 亚洲婷婷国产精品电影人久久| 欧美中在线观看| 欧美福利一区二区三区| 亚洲视频在线二区| 美国十次了思思久久精品导航| 欧美日韩精品欧美日韩精品一 | 蜜桃久久精品乱码一区二区| 欧美日韩一区自拍| 精品999网站| 亚洲综合首页| 欧美韩日精品| 亚洲免费在线播放| 欧美精品1区| 极品尤物一区二区三区| 亚洲一二三四久久| 欧美成人精品激情在线观看| 宅男噜噜噜66国产日韩在线观看| 久久青草久久| 国产欧美精品日韩精品| 日韩视频久久| 欧美寡妇偷汉性猛交| 午夜久久福利| 欧美午夜宅男影院| 亚洲麻豆视频| 欧美高清在线一区二区| 久久精品人人爽| 国产日韩欧美成人|