<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.GameObjs;
using System.Xml.Serialization;
using System.IO;
using TankEngine2D.Helpers;
using SmartTank.PhiCol;
using SmartTank.Shelter;
using SmartTank.Senses.Vision;
using Microsoft.Xna.Framework;
using SmartTank.Update;
using SmartTank.Draw;
using System.Xml;

namespace SmartTank.Scene
{
    /*
     * 对场景路径的说明：
     * 
     * 若TankGroup是SceneMgr的直接子组之一。
     * 
     * 而有一个名为Tank3的物体位于TankGroup下AlliedGroup中，
     * 则该物体的路径为"TankGroup\\AlliedGroup\\Tank3"
     * 
     * AlliedGroup组的路径则为"TankGroup\\AlliedGroup"。
     * 
     * */

    public class SceneMgr : ISceneKeeper
    {
        #region Serialize

        /// <summary>
        /// 序列化SceneMgr
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="sceneMgr"></param>
        /// <returns></returns>
        public static bool Save( Stream stream, SceneMgr sceneMgr )
        {
            try
            {
                XmlWriter writer = XmlWriter.Create( stream );

                stream.Close();
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="sceneFilePath"></param>
        /// <returns></returns>
        public static SceneMgr Load( string sceneFilePath )
        {
            try
            {
                //XmlSerializer serializer = new XmlSerializer( typeof( SceneMgr ) );
                //Stream file = File.OpenRead( sceneFilePath );
                //file.Close();
                //return (SceneMgr)serializer.Deserialize( file );
                return null;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        #endregion

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public SceneMgr()
        {
            phiGroups = new List<string>();
            colSinGroups = new List<string>();
            lapSinGroups = new List<string>();
            colPairGroups = new List<Pair>();
            lapPairGroups = new List<Pair>();
            shelterGroups = new List<MulPair>();
            visionGroups = new List<MulPair>();
            groups = new Group( "" );
        }

        #region Groups and Objs

        protected Group groups;

        /// <summary>
        /// 获得一个组
        /// </summary>
        /// <param name="groupPath"></param>
        /// <returns></returns>
        public Group GetGroup( string groupPath )
        {
            return FindGroup( groupPath );
        }

        /// <summary>
        /// 获得一个类型组
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="groupPath"></param>
        /// <returns></returns>
        public TypeGroup<T> GetTypeGroup<T>( string groupPath ) where T : class, IGameObj
        {
            Group result = FindGroup( groupPath );
            if (result != null && result is TypeGroup<T>)
                return result as TypeGroup<T>;
            else
                return null;
        }

        /// <summary>
        /// 制定场景物体的存放路径而获得场景物体
        /// </summary>
        /// <param name="objPath">物体的场景路径</param>
        /// <returns></returns>
        public IGameObj GetGameObj( string objPath )
        {
            return FindObj( objPath );
        }

        /// <summary>
        /// 添加组
        /// </summary>
        /// <param name="fatherPath">添加到的父组的路径，空则表示添加到根组下</param>
        /// <param name="group">要添加的组</param>
        /// <returns></returns>
        public bool AddGroup( string fatherPath, Group group )
        {
            Group fatherGroup = FindGroup( fatherPath );
            if (fatherGroup != null)
            {
                if (fatherGroup.AddChildGroup( group ))
                    return true;
            }
            return false;
        }

        /// <summary>
        /// 添加物体
        /// </summary>
        /// <param name="groupPath">要添加到的组的路径，该组必须为TypeGroup</param>
        /// <param name="obj"></param>
        /// <returns></returns>
        public bool AddGameObj( string groupPath, IGameObj obj )
        {
            Group fatherGroup = FindGroup( groupPath );
            if (fatherGroup != null && fatherGroup is TypeGroup)
            {
                obj.MgPath = groupPath + "\\" + obj.Name;
                return (fatherGroup as TypeGroup).AddObj( obj );
            }
            else
                return false;
        }
        /// <summary>
        /// 同时添加多个同组物体
        /// </summary>
        /// <param name="groupPath"></param>
        /// <param name="objs"></param>
        /// <returns></returns>
        public bool AddGameObj( string groupPath, params IGameObj[] objs )
        {
            bool success = true;
            foreach (IGameObj obj in objs)
            {
                success = success && AddGameObj( groupPath, obj );
            }
            return success;
        }

        /// <summary>
        /// 删除物体
        /// </summary>
        /// <param name="objPath">物体的路径</param>
        /// <returns></returns>
        public bool DelGameObj( string objPath )
        {
            int i;
            for (i = objPath.Length - 1; i >= 0; i--)
            {
                if (objPath[i] == '\\')
                    break;
            }
            if (i > 0)
            {
                string groupPath = objPath.Substring( 0, i );
                string objName = objPath.Substring( i + 1 );
                return DelGameObj( groupPath, objName );
            }
            return false;
        }
        /// <summary>
        /// 删除物体
        /// </summary>
        /// <param name="groupPath">物体所在组的路径</param>
        /// <param name="objName">物体的名称</param>
        /// <returns></returns>
        public bool DelGameObj( string groupPath, string objName )
        {
            Group fatherGroup = FindGroup( groupPath );
            if (fatherGroup != null && fatherGroup is TypeGroup)
                return (fatherGroup as TypeGroup).DelObj( objName );
            else
                return false;
        }

        #endregion

        #region Register groups to Game Components

        /// <summary>
        /// 表示组二元关系
        /// </summary>
        public struct Pair
        {
            public string groupPath1;
            public string groupPath2;

            public Pair( string groupPath1, string groupPath2 )
            {
                this.groupPath1 = groupPath1;
                this.groupPath2 = groupPath2;
            }
        }
        /// <summary>
        /// 表示一对多的关系
        /// </summary>
        public struct MulPair
        {
            public string groupPath;
            public List<string> groupPaths;

            public MulPair( string groupPath, List<string> groupPaths )
            {
                this.groupPath = groupPath;
                this.groupPaths = groupPaths;
            }
        }

        private List<string> phiGroups;
        private List<string> colSinGroups;
        private List<string> lapSinGroups;
        private List<Pair> colPairGroups;
        private List<Pair> lapPairGroups;

        private List<MulPair> shelterGroups;

        private List<MulPair> visionGroups;

        /// <summary>
        /// 将注册的物理更新组
        /// </summary>
        public List<string> PhiGroups
        {
            get { return phiGroups; }
        }
        /// <summary>
        /// 将注册的单独碰撞组
        /// </summary>
        public List<string> ColSinGroups
        {
            get { return colSinGroups; }
        }
        /// <summary>
        /// 将注册的单独重叠组
        /// </summary>
        public List<string> LapSinGroups
        {
            get { return LapSinGroups; }
        }
        /// <summary>
        /// 将注册的碰撞组对
        /// </summary>
        public List<Pair> ColPairGroups
        {
            get { return colPairGroups; }
        }
        /// <summary>
        /// 将注册的重叠组对
        /// </summary>
        public List<Pair> LapPairGroups
        {
            get { return lapPairGroups; }
        }
        /// <summary>
        /// 将注册的遮挡关系
        /// </summary>
        public List<MulPair> ShelterGroups
        {
            get { return shelterGroups; }
        }
        /// <summary>
        /// 将注册的可视关系
        /// </summary>
        public List<MulPair> VisionGroups
        {
            get { return visionGroups; }
        }

        /// <summary>
        /// 注册几个互相有碰撞关系的组
        /// </summary>
        /// <param name="groups"></param>
        public void AddColMulGroups( params string[] groups )
        {
            for (int i = 0; i < groups.Length - 1; i++)
            {
                for (int j = i + 1; j < groups.Length; j++)
                {
                    ForEachTypeGroup( FindGroup( groups[i] ), new ForEachTypeGroupHandler(
                        delegate( TypeGroup typeGroup1 )
                        {
                            ForEachTypeGroup( FindGroup( groups[j] ), new ForEachTypeGroupHandler(
                                delegate( TypeGroup typeGroup2 )
                                {
                                    colPairGroups.Add( new Pair( typeGroup1.Path, typeGroup2.Path ) );
                                } ) );
                        } ) );
                }
            }
        }
        /// <summary>
        /// 注册几个互相有重叠关系的组
        /// </summary>
        /// <param name="groups"></param>
        public void AddLapMulGroups( params string[] groups )
        {
            for (int i = 0; i < groups.Length - 1; i++)
            {
                for (int j = i + 1; j < groups.Length; j++)
                {
                    lapPairGroups.Add( new Pair( groups[i], groups[j] ) );
                }
            }
        }
        /// <summary>
        /// 注册遮挡关系
        /// </summary>
        /// <param name="raderOwnerGroup"></param>
        /// <param name="shelterGroups"></param>
        public void AddShelterMulGroups( string raderOwnerGroup, params string[] shelterGroups )
        {
            this.shelterGroups.Add( new MulPair( raderOwnerGroup, new List<string>( shelterGroups ) ) );
        }

        /// <summary>
        /// 往平台组件中注册物理更新
        /// </summary>
        /// <param name="manager"></param>
        public void RegistPhiCol( SmartTank.PhiCol.PhiColMgr manager )
        {
            foreach (string groupPath in phiGroups)
            {
                try
                {
                    TypeGroup group = FindGroup( groupPath ) as TypeGroup;
                    manager.AddPhiGroup( group.GetEnumerableCopy<IPhisicalObj>() );
                }
                catch (Exception ex)
                {
                    Log.Write( "RegistPhiGroup error: " + groupPath + ", " + ex.Message );
                }
            }

            foreach (string groupPath in colSinGroups)
            {
                try
                {
                    TypeGroup group = FindGroup( groupPath ) as TypeGroup;
                    manager.AddCollideGroup( group.GetEnumerableCopy<ICollideObj>() );
                }
                catch (Exception ex)
                {
                    Log.Write( "RegistColSinGroup error: " + groupPath + ", " + ex.Message );
                }
            }

            foreach (string groupPath in lapSinGroups)
            {
                try
                {
                    TypeGroup group = FindGroup( groupPath ) as TypeGroup;
                    manager.AddOverlapGroup( group.GetEnumerableCopy<ICollideObj>() );
                }
                catch (Exception ex)
                {
                    Log.Write( "RegistLapSinGroup error: " + groupPath + ", " + ex.Message );
                }
            }

            foreach (Pair pair in colPairGroups)
            {
                try
                {
                    TypeGroup group1 = FindGroup( pair.groupPath1 ) as TypeGroup;
                    TypeGroup group2 = FindGroup( pair.groupPath2 ) as TypeGroup;
                    manager.AddCollideGroup(
                        group1.GetEnumerableCopy<ICollideObj>(),
                        group2.GetEnumerableCopy<ICollideObj>() );
                }
                catch (Exception ex)
                {
                    Log.Write( "RegistColPairGroup error: " + pair.groupPath1 + ", " +
                        pair.groupPath2 + ", " + ex.Message );
                }
            }

            foreach (Pair pair in lapPairGroups)
            {
                try
                {
                    TypeGroup group1 = FindGroup( pair.groupPath1 ) as TypeGroup;
                    TypeGroup group2 = FindGroup( pair.groupPath2 ) as TypeGroup;
                    manager.AddOverlapGroup(
                        group1.GetEnumerableCopy<ICollideObj>(),
                        group2.GetEnumerableCopy<ICollideObj>() );
                }
                catch (Exception ex)
                {
                    Log.Write( "RegistLapPairGroup error: " + pair.groupPath1 + ", " +
                        pair.groupPath2 + ", " + ex.Message );
                }
            }
        }
        /// <summary>
        /// 往平台组件中注册遮挡关系
        /// </summary>
        /// <param name="manager"></param>
        public void RegistShelter( SmartTank.Shelter.ShelterMgr manager )
        {
            foreach (MulPair pair in shelterGroups)
            {
                try
                {
                    List<IEnumerable<IShelterObj>> shelGroups = new List<IEnumerable<IShelterObj>>();

                    foreach (string shelGroupPath in pair.groupPaths)
                    {
                        TypeGroup shelGroup = FindGroup( shelGroupPath ) as TypeGroup;
                        shelGroups.Add( shelGroup.GetEnumerableCopy<IShelterObj>() );
                    }

                    TypeGroup group = FindGroup( pair.groupPath ) as TypeGroup;

                    manager.AddRaderShelterGroup(
                        group.GetEnumerableCopy<IRaderOwner>(),
                        shelGroups.ToArray() );
                }
                catch (Exception ex)
                {
                    Log.Write( "RegistShelterGroup error: " + pair.groupPath + ex.Message );
                }
            }
        }
        /// <summary>
        /// 往平台组件中注册可绘制组
        /// </summary>
        /// <param name="manager"></param>
        public void RegistDrawables( SmartTank.Draw.DrawMgr manager )
        {
            ForEachTypeGroup( groups, new ForEachTypeGroupHandler(
                delegate( TypeGroup typeGroup )
                {
                    manager.AddGroup( typeGroup.GetEnumerableCopy<IDrawableObj>() );
                } ) );
        }
        /// <summary>
        /// 往平台组件中注册可更新组
        /// </summary>
        /// <param name="manager"></param>
        public void RegistUpdaters( SmartTank.Update.UpdateMgr manager )
        {
            ForEachTypeGroup( groups, new ForEachTypeGroupHandler(
                delegate( TypeGroup typeGroup )
                {
                    manager.AddGroup( typeGroup.GetEnumerableCopy<IUpdater>() );
                } ) );
        }
        /// <summary>
        /// 往平台组件中注册可视关系
        /// </summary>
        /// <param name="manager"></param>
        public void RegistVision( SmartTank.Senses.Vision.VisionMgr manager )
        {
            foreach (MulPair pair in visionGroups)
            {
                try
                {
                    //TypeGroup group1 = FindGroup( pair.groupPath ) as TypeGroup;
                    //TypeGroup group2 = FindGroup( pair.groupPath2 ) as TypeGroup;
                    //manager.AddVisionGroup(
                    //    group1.GetEnumerableCopy<IRaderOwner>(),
                    //    group2.GetEnumerableCopy<IEyeableObj>() );
                    List<IEnumerable<IEyeableObj>> EyeableGroups = new List<IEnumerable<IEyeableObj>>();

                    foreach (string eyeGroupPath in pair.groupPaths)
                    {
                        TypeGroup shelGroup = FindGroup( eyeGroupPath ) as TypeGroup;
                        EyeableGroups.Add( shelGroup.GetEnumerableCopy<IEyeableObj>() );
                    }

                    TypeGroup group = FindGroup( pair.groupPath ) as TypeGroup;

                    manager.AddVisionGroup(
                        group.GetEnumerableCopy<IRaderOwner>(),
                        EyeableGroups.ToArray() );
                }
                catch (Exception ex)
                {
                    Log.Write( "RegistVisionGroup error: " + pair.groupPath + ", " +
                        pair.groupPath.ToString() + ", " + ex.Message );
                }
            }
        }

        #endregion

        #region Prviate Methods

        private Group FindGroup( string groupPath )
        {
            if (groupPath == string.Empty)
                return this.groups;

            Group curGroup = this.groups;
            string[] paths;
            paths = groupPath.Split( '\\' );
            foreach (string path in paths)
            {
                curGroup = curGroup.GetChildGroup( path );
                if (curGroup == null)
                {
                    Log.Write( "FindGroup: 错误的组路径被传入或不存在匹配组" );
                    return null;
                }
            }
            return curGroup;
        }

        private IGameObj FindObj( string objPath )
        {
            Group curGroup = this.groups;
            string[] paths;
            paths = objPath.Split( '\\' );
            for (int i = 0; i < paths.Length - 1; i++)
            {
                curGroup = curGroup.GetChildGroup( paths[i] );
                if (curGroup == null)
                {
                    Log.Write( "FindObj: 错误的组路径被传入或不存在匹配组" );
                    return null;
                }
            }
            if (curGroup != null && curGroup is TypeGroup)
            {
                return (curGroup as TypeGroup).GetObj( paths[paths.Length - 1] );
            }
            return null;
        }

        private delegate void ForEachTypeGroupHandler( TypeGroup group );

        private static void ForEachTypeGroup( Group group, ForEachTypeGroupHandler handler )
        {
            if (group is TypeGroup)
                handler( group as TypeGroup );

            foreach (KeyValuePair<string, Group> child in group.Childs)
            {
                ForEachTypeGroup( child.Value, handler );
            }
        }

        #endregion

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using GameEngine.Graphics;
using Common.Helpers;

namespace GameEngine.Effects.Particles
{
    public delegate Vector2 PosFunc( float curTime, float deltaTime, Vector2 lastPos, Vector2 dir );

    public delegate Vector2 DirFunc( float curTime, float deltaTime, Vector2 lastDir );

    public delegate float RadiusFunc( float curTime, float deltaTime, float lastRadius );

    public delegate Color ColorSetTimeFunc( float curTime, float deltaTime, Color lastColor );

    public class Particle
    {
        #region Variables

        protected Vector2 basePos;

        protected Vector2 curPos;
        protected float curRadius;
        protected Vector2 curDir;
        protected Color curColor;
        protected float layerDepth;

        float curTime = 0;
        float duration;

        protected PosFunc posFunc;
        protected RadiusFunc radiusFunc;
        protected DirFunc dirFunc;
        protected ColorSetTimeFunc colorFunc;

        Texture2D tex;
        Vector2 texOrign;
        Nullable<Rectangle> sourceRect;

        bool isEnd = false;

        #endregion

        public Particle( float duration, Vector2 basePos, float layerDepth,
            PosFunc posFunc, DirFunc dirFunc, RadiusFunc radiusFunc,
            Texture2D orignTex, Vector2 texOrign, Nullable<Rectangle> sourceRect,
            ColorSetTimeFunc colorFunc )
        {
            this.duration = duration;
            this.basePos = basePos;
            this.layerDepth = layerDepth;

            this.posFunc = posFunc;
            this.dirFunc = dirFunc;
            this.radiusFunc = radiusFunc;
            this.colorFunc = colorFunc;

            this.tex = orignTex;
            this.texOrign = texOrign;
            this.sourceRect = sourceRect;

        }

        public bool Update( float seconds )
        {
            curDir = dirFunc( curTime, seconds, curDir );
            curPos = posFunc( curTime, seconds, curPos, curDir );
            curRadius = radiusFunc( curTime, seconds, curRadius );
            curColor = colorFunc( curTime, seconds, curColor );


            curTime += seconds;
            if (curTime > duration)
            {
                isEnd = true;
                return true;
            }

            
            return false;
        }

        public void Draw()
        {
            if (!isEnd)
                BaseGame.SpriteMgr.alphaSprite.Draw( tex, BaseGame.CoordinMgr.ScreenPos( basePos + curPos ), sourceRect, curColor, MathTools.AziFromRefPos( curDir ), texOrign,
                            curRadius / (float)tex.Width, SpriteEffects.None, layerDepth );
        }


        #region IDrawableObj ³ΙΤ±


        public Vector2 Pos
        {
            get { return basePos + curPos; }
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.AI
{
    [IAIAttribute( typeof( IAIOrderServerSinTur ), typeof( IAICommonServer ) )]
    public interface IAISinTur : IAI
    {

    }
}
<file_sep>#include "head.h"
#include "mythread.h"
#include "ClientManager.h"


extern pthread_mutex_t DD_ClientMgr_Mutex[MAXCLIENT];
extern bool g_isRuning;
extern int  g_MaxRoommate;
void LogOut(char *buff, int length);

/************************************************************************/
/* 服务器发送线程<传送控制台输入字符，可有可无的线程>         
/************************************************************************/
THREADHEAD ThreadSend(void* para)
{
    cout << "输入-?查看控制台命令." << endl;
    PThreadParam pp = (PThreadParam)para;
    ClientManager *pManager = pp->mgr;
    while (1)
    {    
        char buffOut[300] = "GameServer说:";
        char buff[255];
        memset( buff, 0, 255);

        /* 服务器io输入 */
        cin.getline(buff, sizeof(buff));
        if ( true == DoServercommand( pManager, buff) )
            continue;

        strcat( buffOut, buff);

        // 给所有客户广播消息包
        /*for ( int i = 0; i < pManager->GetNum(); i++)
        {
            if ( false == pManager->GetClient(i)->SendPacket(buffOut, strlen(buffOut) ) )
            {
                cout << errno << " : ThreadSend." << endl;
                pManager->DelClient( pManager->GetClient(i) );
            }
        }*/
    }
}
/************************************************************************/
/* Client接收线程         
/************************************************************************/
THREADHEAD ThreadClient(void* pparam)
{
#ifndef WIN32 
    pthread_detach(pthread_self());
#endif
    
    long recvPackets = 0;
    int ret;
    char buff[255];
    PThreadParam pp;
    pp = (PThreadParam)pparam; 
    ClientManager *pManager = pp->mgr;
    
    MySocket * pSockClient = pManager->AddClient(pp->sock);
    if ( NULL == pSockClient)
    {
        return 0;
    }
    sprintf(buff, "欢迎加入SmartTand聊天室!总用户:%d个,IP是%s : %d\n", 
        pManager->GetNum(),
        inet_ntoa(pSockClient->m_addr.sin_addr), pSockClient->m_addr.sin_port);
    //pSockClient->SendPacket(buff, long(strlen(buff)));
    cout << buff << endl;  

    /* Main Loop */
    while (1)
    {
        PacketHead packHead;
        Packet pack;
        memset(&packHead, 0, sizeof(PacketHead));
        memset(&pack, 0, sizeof(Packet));
        /* 收包头 */
        if ( 0 >= ( ret = recv(pSockClient->m_socket, (char*)&packHead, HEADSIZE, MSG_NOSIGNAL) ) )
        {   
            // 失败，删除该客户
            cout << "Recv Error." << endl;
            pManager->DelClient(pSockClient); 
            return 0;
        }
        // 确保包体长度有效性
        if ( packHead.length > PACKSIZE || packHead.length < 0)
        {
            char buff[255];
            sprintf( buff, "Error Length of Head : %d\n",GetMyError);
            LogOut(buff,strlen(buff));
            cout << "Error Length of Head : " << packHead.length << endl;
            continue;
        }
        // 继续收包体  
        if ( false == ( pSockClient->RecvPacket(packHead, pack) ) )
        {   // 失败，删除该客户
            char buff[255];
            sprintf( buff, "%d\n",GetMyError);
            LogOut(buff,strlen(buff));
            pManager->DelClient( pSockClient );
            cout << "Wrong recv pack body" << endl;
        }
        pack.iStyle = packHead.iStyle;

        /* 由GameProtocal定义的协议分析器来分析数据包 */
        switch(packHead.iStyle)
        { 
        
        /*  心跳包,暂时不用  */
        case HEART_BEAT:  
            //pManager->HeartBeatFun(pSockClient);
            break;

        /*  正常游戏包  */
        case USER_DATA:  
            if ( ++recvPackets%100 == 0)
                cout << "包头:" << packHead.iStyle << ',' << packHead.length << endl;
            pManager->GetProtocal()->SendToOthers(pSockClient, pack);
            break;

         /*  创建房间    */
        case ROOM_CREATE:  
            pManager->GetProtocal()->CreateRoom(pSockClient, pack);
            break;

        /*  进入房间    */
        case ROOM_JOIN:  
            pManager->GetProtocal()->EnterRoom(pSockClient, pack);
            break;

        /*  房间列表    */
        case ROOM_LIST:  
            pManager->GetProtocal()->ListRoom(pSockClient, pack);
            break;

        /*  房间玩家列表    */
        case ROOM_LISTUSER:  
            pManager->GetProtocal()->ListUser(pSockClient, pack);
            break;

        /*  房间有人离开  */
        case ROOM_EXIT:  
            pManager->GetProtocal()->ExitRoom(pSockClient, pack);       
            break;

        /*  排行榜列表    */
        case USER_RANK:  
            pManager->GetProtocal()->ListRank(pSockClient, pack);
            break;

        /*  用户注册    */
        case USER_REGIST:     
            break;

        /*  用户登录    */
        case LOGIN:    
            pManager->GetProtocal()->UserLogin(pSockClient, pack);
            break;

        /*  用户自己信息  */
        case USER_INFO:  
            pManager->GetProtocal()->MyInfo(pSockClient, pack);
            break;

        /*  游戏开始!  */
        case GAME_GO:  
            pManager->GetProtocal()->GameGo(pSockClient, pack);
            break;
        
        /*  保存游戏结果到数据库  */
        case GAME_RESULT:  
            pManager->GetProtocal()->SaveGameResult(pSockClient, pack);
            break;

        /*  用户离开  */
        case USER_EXIT:  
            pManager->GetProtocal()->UserExit(pSockClient);       
            return 0;// 退出线程

        /*  Unknow  */
        default:
            {
                cout << pSockClient->GetIP() <<" : Unknow Head: ";
                cout << ret << "byte: " << packHead.iStyle << endl;
                char buff[9];            
                sprintf(buff, (char*)&packHead);
                buff[8] = '\0';
                cout << buff << endl;
                break; 
            }
        }
    }// while

    pSockClient->Close();
    return 0;
}


bool  DoServercommand(ClientManager *pManager, char* msg)
{
    if ( 0 == strcmp(msg, "-q") )   /* exit */
    {
        DestroySocket();
        exit(0);
    }
    else   /* 房间信息 */
        if ( 0 == strcmp(msg, "-r") )
        {
            if (pManager->m_numOfRoom > 0)
            {
                int realPlayers;
                UserInfo  riOut[MAXROOMMATE]; 
                realPlayers = pManager->m_room->GetPlayers();
                pManager->m_room->GetPlayesInfo(riOut);
                cout << setw(-20)  << "玩家名" << setw(10) << "总分"<< endl;
                for ( int i = 0;   i < realPlayers; i++)
                {
                    cout << setw(-20) << riOut[i].Name ;
                    if ( riOut[i].ID == 1){
                        cout << "(房主)" ;
                    }
                    cout << setw(10) << riOut[i].Score <<  endl;
                }
            }
            else
            {
                cout <<"当前可用房间:" << pManager->m_numOfRoom  << endl;
            }
        }
        else   /* Look current clents */
            if ( 0 == strcmp(msg, "-t") )
            {
                cout << "当前连接总数:" << pManager->GetNum() << endl;
                for ( int i = 0; i < pManager->GetNum(); i++)
                {
                    cout << pManager->GetClient(i)->m_name << " : "
                        << pManager->GetClient(i)->GetIP()  << " : " 
                        << pManager->GetClient(i)->GetPort() << endl;
                }
            }else   /* Look for MySql */
                if ( 0 == strcmp(msg, "-all") )
                {
                    setiosflags(ios::left);
                    UserInfo ui[MAXCLIENT]; 
                    int nUsers = pManager->GetProtocal()->m_SQL.GetUserCount();
                    cout << setw(-10) << "ID" << setw(20) << "Name" << setw(10) << "Password" << 
                        setw(10) << "Rank" << setw(10) << "Score" << endl;
                    for ( int i = 0; i < pManager->m_protocol->m_SQL.GetUserList(0, nUsers, ui); i++)
                    {
                        cout << setw(-10) << ui[i].ID << setw(20) << ui[i].Name << setw(10) << ui[i].Password 
                            << setw(10)  << ui[i].Rank << setw(10) << ui[i].Score << endl;
                    }
                }
                if ( 0 == strcmp(msg, "-rank") )
                {
                    setiosflags(ios::left);
                    RankInfo ui[MAXCLIENT]; 
                    cout << setw(10) << "Rank"   
                         << setw(20) << "Name"<< setw(10) << "Score" << endl;
                    for ( int i = 0; i < pManager->GetProtocal()->m_SQL.GetRankList(0, MAXCLIENT, ui); i++)
                    {
                        cout <<  setw(10)  << ui[i].Rank 
                            << setw(20) << ui[i].Name << setw(10) << ui[i].Score << endl;
                    }
                }
                else   /* Look for MySql */
                    if ( 0 == strcmp(msg, "-kill") )
                    {
                        cout << "所有玩家都可以死了." << endl;
                        pManager->DelClientAll();
                    }
                    else   /* Look for MySql */
                        if ( 0 == strcmp(msg, "-add") )
                        {
                            char buffname[21], buffPass[21];
                            cout << "用户名:";          cin >> buffname;
                            cout << endl << "密码:";    cin >> buffPass;
                            if ( 0 == pManager->GetProtocal()->m_SQL.AddUserItem(buffname, buffPass,0) )
                                cout << "增加成功." << endl;
                        }
                        else   /* Look for MySql */
                            if ( 0 == strcmp(msg, "-del") )
                            {
                                char buffname[21];
                                cout << "用户名:";          cin >> buffname;
                                if ( 0 == pManager->GetProtocal()->m_SQL.DeleteUserItem(buffname) )
                                    cout << "删除成功.";
                            }
                            else   /* Look for MySql */
                                if ( 0 == strcmp(msg, "-?") )
                                {
                                    cout << "-q: 强制关闭." << endl;
                                    cout << "-t: 查看当前连接信息." << endl;
                                    cout << "-r: 查看当前房间信息." << endl;
                                    cout << "-all: 查看数据库." << endl;
                                    cout << "-add: 增加帐号." << endl;
                                    cout << "-del: 删除帐号." << endl;
                                    cout << "-rank: 查看积分榜." << endl;
                                    cout << "-kill: 杀灭所有玩家." << endl;
                                }
                                else    /* Bad command */
                                {
                                    return false;
                                }
                                return true;
}
void LogOut(char *buff, int length)
{
    ofstream  outLog;
    outLog.open("ThreadLog.txt", ios_base::app);
    outLog.write(buff, length);
    outLog.write("\n", 2);
    outLog.close();
}









<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Common.Helpers;
using System.IO;
using Common.DataStructure;

namespace GameEngine.Graphics
{
    /// <summary>
    /// 提供点，线，矩形的绘制功能
    /// </summary>
    public class BasicGraphics
    {

        #region Fields

        Texture2D pointTexture;
        Texture2D lineTexture;
        Texture2D retangleTexture;

        RenderEngine engine;

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="engine">渲染组件</param>
        public BasicGraphics ( RenderEngine engine )
        {
            pointTexture = Texture2D.FromFile( engine.Device, Path.Combine( engine.contentPath, "point.png" ) );
            lineTexture = Texture2D.FromFile( engine.Device, Path.Combine( engine.contentPath, "line.png" ) );
            retangleTexture = Texture2D.FromFile( engine.Device, Path.Combine( engine.contentPath, "retangle.png" ) );

            this.engine = engine;
        }

        #region Draw Point

        /// <summary>
        /// 绘制一个标注点
        /// </summary>
        /// <param name="pos">逻辑坐标</param>
        /// <param name="scale">大小</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        public void DrawPoint ( Vector2 pos, float scale, Color color, float layerDepth )
        {
            DrawPoint( pos, scale, color, layerDepth, SpriteBlendMode.AlphaBlend );
        }

        /// <summary>
        /// 绘制一个标注点
        /// </summary>
        /// <param name="pos">逻辑坐标</param>
        /// <param name="scale">大小</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        /// <param name="blendMode">混合模式</param>
        public void DrawPoint ( Vector2 pos, float scale, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            if (blendMode == SpriteBlendMode.Additive)
                engine.SpriteMgr.additiveSprite.Draw( pointTexture, engine.CoordinMgr.ScreenPos( pos ), null, color, 0, new Vector2( 16, 16 ), scale, SpriteEffects.None, layerDepth );
            else
                engine.SpriteMgr.alphaSprite.Draw( pointTexture, engine.CoordinMgr.ScreenPos( pos ), null, color, 0, new Vector2( 16, 16 ), scale, SpriteEffects.None, layerDepth );
        }

        #endregion

        #region Draw Line

        /// <summary>
        /// 在逻辑坐标中绘制一条直线
        /// </summary>
        /// <param name="startPoint">直线的起始点</param>
        /// <param name="endPoint">直线的终点</param>
        /// <param name="width">直线的宽度，以像素为单位</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        public void DrawLine ( Vector2 startPoint, Vector2 endPoint, float width, Color color, float layerDepth )
        {
            DrawLine( startPoint, endPoint, width, color, layerDepth, SpriteBlendMode.AlphaBlend );
        }

        /// <summary>
        /// 在逻辑坐标中绘制一条直线
        /// </summary>
        /// <param name="startPoint">直线的起始点</param>
        /// <param name="endPoint">直线的终点</param>
        /// <param name="width">直线的宽度，以像素为单位</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        /// <param name="blendMode">混合模式</param>
        public void DrawLine ( Vector2 startPoint, Vector2 endPoint, float width, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            float lengthPix = engine.CoordinMgr.ScrnLength( Vector2.Distance( startPoint, endPoint ) );
            Vector2 midPoint = engine.CoordinMgr.ScreenPos( new Vector2( 0.5f * (startPoint.X + endPoint.X), 0.5f * (startPoint.Y + endPoint.Y) ) );
            float rota = (float)Math.Atan( (double)engine.CoordinMgr.ScrnLengthf( startPoint.Y - endPoint.Y ) / (double)engine.CoordinMgr.ScrnLengthf( startPoint.X - endPoint.X ) );
            if (blendMode == SpriteBlendMode.Additive)
                engine.SpriteMgr.additiveSprite.Draw( lineTexture, new Rectangle( (int)(midPoint.X), (int)(midPoint.Y), (int)(lengthPix), (int)width ),
                    null, color, rota - engine.CoordinMgr.Rota, new Vector2( 64, 8 ), SpriteEffects.None, layerDepth );
            else
                engine.SpriteMgr.alphaSprite.Draw( lineTexture, new Rectangle( (int)(midPoint.X), (int)(midPoint.Y), (int)(lengthPix), (int)width ),
                null, color, rota - engine.CoordinMgr.Rota, new Vector2( 64, 8 ), SpriteEffects.None, layerDepth );
        }

        /// <summary>
        /// 在屏幕坐标中绘制一条直线
        /// </summary>
        /// <param name="startPoint">直线的起始点</param>
        /// <param name="endPoint">直线的终点</param>
        /// <param name="width">直线的宽度，以像素为单位</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        public void DrawLineInScrn ( Vector2 startPoint, Vector2 endPoint, float width, Color color, float layerDepth )
        {
            DrawLineInScrn( startPoint, endPoint, width, color, layerDepth, SpriteBlendMode.AlphaBlend );
        }

        /// <summary>
        /// 在屏幕坐标中绘制一条直线
        /// </summary>
        /// <param name="startPoint">直线的起始点</param>
        /// <param name="endPoint">直线的终点</param>
        /// <param name="width">直线的宽度，以像素为单位</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        /// <param name="blendMode">混合模式</param>
        public void DrawLineInScrn ( Vector2 startPoint, Vector2 endPoint, float width, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            float lengthPix = Vector2.Distance( startPoint, endPoint );
            Vector2 midPoint = new Vector2( 0.5f * (startPoint.X + endPoint.X), 0.5f * (startPoint.Y + endPoint.Y) );
            float rota = (float)Math.Atan( (double)(startPoint.Y - endPoint.Y) / (double)(startPoint.X - endPoint.X) );
            if (blendMode == SpriteBlendMode.Additive)
                engine.SpriteMgr.additiveSprite.Draw( lineTexture, new Rectangle( (int)(midPoint.X), (int)(midPoint.Y), (int)(lengthPix), (int)width ),
                    null, color, rota, new Vector2( 64, 8 ), SpriteEffects.None, layerDepth );
            else
                engine.SpriteMgr.alphaSprite.Draw( lineTexture, new Rectangle( (int)(midPoint.X), (int)(midPoint.Y), (int)(lengthPix), (int)width ),
                null, color, rota, new Vector2( 64, 8 ), SpriteEffects.None, layerDepth );
        }
        #endregion

        #region Draw Rectangle

        /// <summary>
        /// 在逻辑坐标中绘制矩形
        /// </summary>
        /// <param name="rect">要绘制的矩形</param>
        /// <param name="borderWidth">矩形的边线的宽度，以像素为单位</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        public void DrawRectangle ( Rectangle rect, float borderWidth, Color color, float layerDepth )
        {
            DrawRectangle( rect, borderWidth, color, layerDepth, SpriteBlendMode.AlphaBlend );
        }

        /// <summary>
        /// 在逻辑坐标中绘制矩形
        /// </summary>
        /// <param name="rect">要绘制的矩形</param>
        /// <param name="borderWidth">矩形的边线的宽度，以像素为单位</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        /// <param name="blendMode">混合模式</param>
        public void DrawRectangle ( Rectangle rect, float borderWidth, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            DrawLine( new Vector2( rect.Left, rect.Top ), new Vector2( rect.Right, rect.Top ), borderWidth, color, layerDepth, blendMode );
            DrawLine( new Vector2( rect.Left, rect.Top ), new Vector2( rect.Left, rect.Bottom ), borderWidth, color, layerDepth, blendMode );
            DrawLine( new Vector2( rect.Right, rect.Top ), new Vector2( rect.Right, rect.Bottom ), borderWidth, color, layerDepth, blendMode );
            DrawLine( new Vector2( rect.Left, rect.Bottom ), new Vector2( rect.Right, rect.Bottom ), borderWidth, color, layerDepth, blendMode );
        }

        /// <summary>
        /// 在逻辑坐标中绘制矩形
        /// </summary>
        /// <param name="rect">要绘制的矩形</param>
        /// <param name="borderWidth">矩形的边线的宽度，以像素为单位</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        public void DrawRectangle ( Rectanglef rect, float borderWidth, Color color, float layerDepth )
        {
            DrawRectangle( rect, borderWidth, color, layerDepth, SpriteBlendMode.AlphaBlend );
        }

        /// <summary>
        /// 在逻辑坐标中绘制矩形
        /// </summary>
        /// <param name="rect">要绘制的矩形</param>
        /// <param name="borderWidth">矩形的边线的宽度，以像素为单位</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        /// <param name="blendMode">混合模式</param>
        public void DrawRectangle ( Rectanglef rect, float borderWidth, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            DrawLine( new Vector2( rect.Left, rect.Top ), new Vector2( rect.Right, rect.Top ), borderWidth, color, layerDepth, blendMode );
            DrawLine( new Vector2( rect.Left, rect.Top ), new Vector2( rect.Left, rect.Bottom ), borderWidth, color, layerDepth, blendMode );
            DrawLine( new Vector2( rect.Right, rect.Top ), new Vector2( rect.Right, rect.Bottom ), borderWidth, color, layerDepth, blendMode );
            DrawLine( new Vector2( rect.Left, rect.Bottom ), new Vector2( rect.Right, rect.Bottom ), borderWidth, color, layerDepth, blendMode );
        }

        /// <summary>
        /// 在屏幕坐标中绘制矩形
        /// </summary>
        /// <param name="rect">要绘制的矩形</param>
        /// <param name="borderWidth">矩形的边线的宽度，以像素为单位</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        /// <param name="blendMode">混合模式</param>
        public void DrawRectangleInScrn ( Rectangle rect, float borderWidth, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            DrawLineInScrn( new Vector2( rect.Left, rect.Top ), new Vector2( rect.Right, rect.Top ), borderWidth, color, layerDepth, blendMode );
            DrawLineInScrn( new Vector2( rect.Left, rect.Top ), new Vector2( rect.Left, rect.Bottom ), borderWidth, color, layerDepth, blendMode );
            DrawLineInScrn( new Vector2( rect.Right, rect.Top ), new Vector2( rect.Right, rect.Bottom ), borderWidth, color, layerDepth, blendMode );
            DrawLineInScrn( new Vector2( rect.Left, rect.Bottom ), new Vector2( rect.Right, rect.Bottom ), borderWidth, color, layerDepth, blendMode );
        }

        /// <summary>
        /// 在屏幕坐标中绘制矩形
        /// </summary>
        /// <param name="rect">要绘制的矩形</param>
        /// <param name="borderWidth">矩形的边线的宽度，以像素为单位</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        public void DrawRectangleInScrn ( Rectangle rect, float borderWidth, Color color, float layerDepth )
        {
            DrawRectangleInScrn( rect, borderWidth, color, layerDepth, SpriteBlendMode.AlphaBlend );
        }
        #endregion

        #region Fill Rectangle

        /// <summary>
        /// 在逻辑坐标中绘制一个填充的矩形
        /// </summary>
        /// <param name="rect">要填充的矩形</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        public void FillRectangle ( Rectangle rect, Color color, float layerDepth )
        {
            FillRectangle( rect, color, layerDepth, SpriteBlendMode.AlphaBlend );
        }

        /// <summary>
        /// 在逻辑坐标中绘制一个填充的矩形
        /// </summary>
        /// <param name="rect">要填充的矩形</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0表示最表层，1表示最深层</param>
        /// <param name="blenMode">混合模式</param>
        public void FillRectangle ( Rectangle rect, Color color, float layerDepth, SpriteBlendMode blenMode )
        {
            Vector2 scrnPos = engine.CoordinMgr.ScreenPos( new Vector2( rect.X, rect.Y ) );
            Rectangle destinRect = new Rectangle( (int)scrnPos.X, (int)scrnPos.Y, engine.CoordinMgr.ScrnLength( rect.Width ), engine.CoordinMgr.ScrnLength( rect.Height ) );
            if (blenMode == SpriteBlendMode.Additive)
                engine.SpriteMgr.additiveSprite.Draw( retangleTexture, destinRect, null, color, -engine.CoordinMgr.Rota, Vector2.Zero, SpriteEffects.None, layerDepth );
            else
                engine.SpriteMgr.alphaSprite.Draw( retangleTexture, destinRect, null, color, -engine.CoordinMgr.Rota, Vector2.Zero, SpriteEffects.None, layerDepth );
        }
        #endregion

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using GameEngine.Graphics;
using Common.DataStructure;
using Microsoft.Xna.Framework;

namespace GameEngine.Shelter
{
    /* 
     * 实现方式相对单一，所以姑且与检测方法耦合了。
     * 
     * */

    public interface IShelterObj : IHasBorderObj
    {
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Graphics;
using SmartTank.Draw;
using SmartTank.Effects.TextEffects;

namespace SmartTank.Effects.SceneEffects
{
    class EffectsMgr
    {
        static List<IManagedEffect> managedEffects = new List<IManagedEffect>();

        public static void AddManagedEffect ( IManagedEffect effect )
        {
            managedEffects.Add( effect );
        }

        public static void Update ( float seconds )
        {
            for (int i = 0; i < managedEffects.Count; i++)
            {
                managedEffects[i].Update( seconds );
                if (managedEffects[i].IsEnd)
                {
                    managedEffects.Remove( managedEffects[i] );
                    i--;
                }
            }
        }

        internal static void Draw ( DrawCondition condition )
        {
            BaseGame.AnimatedMgr.Draw();

            TextEffectMgr.Draw();

            foreach (IManagedEffect effect in managedEffects)
            {
                if (condition != null)
                {
                    if (condition( effect ))
                        effect.Draw();
                }
                else
                    effect.Draw();
            }
        }

        internal static void Clear ()
        {
            BaseGame.AnimatedMgr.Clear();
            managedEffects.Clear();
        }


    }
}
<file_sep>//=================================================
// xWinForms
// Copyright ?2007 by <NAME>
// http://psycad007.spaces.live.com/
//=================================================
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.IO;
using TankEngine2D.Helpers;
using TankEngine2D.Graphics;
using SmartTank.Helpers;

namespace SmartTank.Draw.UI.Controls
{
    public class RadioButton : Control
    {
        #region Fields
        Texture2D[] texture;

        //int charWidth = 9;

        MouseState ms;

        public bool bPressed = false;
        public bool bMouseOver = false;

        public event EventHandler OnPress;
        public void checkbox_onPress( Object obj, EventArgs e ) { bPressed = true; bChecked = !bChecked; }
        #endregion

        #region Consturtion
        public RadioButton( string name, Vector2 position, string text, bool bChecked )//, Font font, Form.Style style)
        {
            //Console.WriteLine("New Radio Button");

            this.Type = ControlType.RadioButton;
            this.name = name;
            this.position = position;
            this.text = text;
            this.bChecked = bChecked;

            texture = new Texture2D[2];
            texture[0] = BaseGame.ContentMgr.Load<Texture2D>( Path.Combine( Directories.UIContent, "radio_button" ) );
            texture[1] = BaseGame.ContentMgr.Load<Texture2D>( Path.Combine( Directories.UIContent, "radio_button_checked" ) );

            OnPress += new EventHandler( checkbox_onPress );
        }
        #endregion

        #region Update
        public override void Update()//Vector2 formPosition, Vector2 formSize )
        {
            //position = origin + formPosition;

            //CheckVisibility( formPosition, formSize );

            //if (!Form.isInUse)
            CheckSelection();
        }

        //private void CheckVisibility ( Vector2 formPosition, Vector2 formSize )
        //{
        //    if (position.X + texture[0].Width + charWidth * text.Length > formPosition.X + formSize.X - 15f)
        //        bVisible = false;
        //    else if (position.Y + texture[0].Height > formPosition.Y + formSize.Y - 25f)
        //        bVisible = false;
        //    else
        //        bVisible = true;
        //}

        private void CheckSelection()
        {
            ms = Mouse.GetState();
            if (ms.LeftButton == ButtonState.Pressed)
            {
                if (!bPressed && bIsOverButton())
                    OnPress( this, EventArgs.Empty );
            }
            else if (bPressed)
                bPressed = false;
            else
            {
                if (!bMouseOver && bIsOverButton())
                    bMouseOver = true;
                else if (bMouseOver && !bIsOverButton())
                    bMouseOver = false;
            }
        }

        private bool bIsOverButton()
        {
            if (ms.X > position.X && ms.X < position.X + texture[0].Width)
                if (ms.Y > position.Y && ms.Y < position.Y + texture[0].Height)
                    return true;
                else
                    return false;
            else
                return false;
        }
        #endregion

        #region Draw
        public override void Draw( SpriteBatch spriteBatch, float alpha )
        {
            Color dynamicColor = new Color( new Vector4( 1f, 1f, 1f, alpha ) );
            Color dynamicTextColor = new Color( new Vector4( 0f, 0f, 0f, 1f ) * alpha );

            if (bChecked)
                spriteBatch.Draw( texture[1], position, dynamicColor );
            else
                spriteBatch.Draw( texture[0], position, dynamicColor );

            //font.Draw( text, position + new Vector2( texture[0].Width + 5f, 0f ), 1f, dynamicTextColor, spriteBatch );
            BaseGame.FontMgr.DrawInScrnCoord( text, position + new Vector2( texture[0].Width + 5f, 0f ), Control.fontScale, dynamicTextColor, 0f, Control.fontName );
        }
        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.PhiCol;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework;
using SmartTank.GameObjs;

namespace SmartTank.PhiCol
{
    public class NonInertiasColUpdater : NonInertiasPhiUpdater, IColChecker
    {
        Sprite[] collideSprites;
        SpriteColMethod colMethod;

        public NonInertiasColUpdater( GameObjInfo objInfo, Sprite[] collideSprites )
            : base( objInfo )
        {
            this.collideSprites = collideSprites;
            colMethod = new SpriteColMethod( collideSprites );
        }

        public NonInertiasColUpdater( GameObjInfo objInfo, Vector2 pos, Vector2 vel, float azi, float angVel, Sprite[] collideSprites )
            : base( objInfo, pos, vel, azi, angVel )
        {
            this.collideSprites = collideSprites;
            colMethod = new SpriteColMethod( collideSprites );
        }

        #region IColChecker ³ΙΤ±

        public virtual void HandleCollision( CollisionResult result, ICollideObj objB )
        {
            Pos += result.NormalVector * BaseGame.CoordinMgr.LogicLength( 0.5f );

            if (OnCollied != null)
                OnCollied( null, result, (objB as IGameObj).ObjInfo );
        }

        public virtual void HandleOverlap( CollisionResult result, ICollideObj objB )
        {
            if (OnOverlap != null)
                OnOverlap( null, result, (objB as IGameObj).ObjInfo );
        }

        public virtual void ClearNextStatus()
        {
            nextPos = Pos;
            nextAzi = Azi;
        }

        public IColMethod CollideMethod
        {
            get
            {
                foreach (Sprite sprite in collideSprites)
                {
                    sprite.Pos = nextPos;
                    sprite.Rata = nextAzi;
                }
                return colMethod;
            }
        }

        #endregion

        #region Event

        public event OnCollidedEventHandler OnCollied;

        public event OnCollidedEventHandler OnOverlap;

        #endregion




    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.Update;
using TankEngine2D.DataStructure;
using TankEngine2D.Helpers;

namespace SmartTank.AI.AIHelper
{
    public class ConsiderCenter : IUpdater
    {
        #region Type Define

        struct ConsiderWithPRI
        {
            public IConsider consider;
            public int PRI;

            public ConsiderWithPRI ( IConsider consider, int PRI )
            {
                this.consider = consider;
                this.PRI = PRI;
            }
        }

        class PRIHelper
        {
            class Comparision : IComparer<ConsiderWithPRI>
            {

                #region IComparer<ConsiderWithPRI> 成员

                public int Compare ( ConsiderWithPRI x, ConsiderWithPRI y )
                {
                    if ((int)x.consider.CurPriority > (int)y.consider.CurPriority)
                        return -1;
                    else if ((int)x.consider.CurPriority < (int)y.consider.CurPriority)
                        return 1;
                    else
                    {
                        if (x.PRI > y.PRI)
                            return -1;
                        else if (x.PRI < y.PRI)
                            return 1;
                        else
                            return 0;
                    }

                }

                #endregion
            }

            bool RotaAuthorized = false;
            bool RotaTurretAuthorized = false;
            bool RotaRaderAuthorized = false;
            bool MoveAuthorized = false;

            List<IConsider> authorizeList;

            public PRIHelper ( List<ConsiderWithPRI> ConsiderWithPRIs )
            {
                authorizeList = new List<IConsider>();

                List<ConsiderWithPRI> PriorityList = new List<ConsiderWithPRI>();

                foreach (ConsiderWithPRI considerWithPRI in ConsiderWithPRIs)
                {
                    if (considerWithPRI.consider.CurPriority != ConsiderPriority.Vacancy)
                        PriorityList.Add( considerWithPRI );
                }

                PriorityList.Sort( new Comparision() );

                foreach (ConsiderWithPRI considerWithPRI in PriorityList)
                {
                    ActionRights needRights = considerWithPRI.consider.NeedRights;

                    bool canAuthorize = true;

                    if ((needRights & ActionRights.Rota) == ActionRights.Rota)
                    {
                        if (RotaAuthorized)
                            canAuthorize = false;

                    }
                    if ((needRights & ActionRights.RotaTurret) == ActionRights.RotaTurret)
                    {
                        if (RotaTurretAuthorized)
                            canAuthorize = false;
                    }
                    if ((needRights & ActionRights.RotaRader) == ActionRights.RotaRader)
                    {
                        if (RotaRaderAuthorized)
                            canAuthorize = false;
                    }
                    if ((needRights & ActionRights.Move) == ActionRights.Move)
                    {
                        if (MoveAuthorized)
                            canAuthorize = false;
                    }

                    if (canAuthorize)
                        AddConsiderAuthorized( considerWithPRI.consider );
                }
            }

            public List<IConsider> AuthorizeList
            {
                get { return authorizeList; }
            }

            private void AddConsiderAuthorized ( IConsider consider )
            {
                ActionRights needRights = consider.NeedRights;
                if ((needRights & ActionRights.Rota) == ActionRights.Rota)
                {
                    RotaAuthorized = true;
                }
                if ((needRights & ActionRights.RotaTurret) == ActionRights.RotaTurret)
                {
                    RotaTurretAuthorized = true;
                }
                if ((needRights & ActionRights.RotaRader) == ActionRights.RotaRader)
                {
                    RotaRaderAuthorized = true;
                }
                if ((needRights & ActionRights.Move) == ActionRights.Move)
                {
                    MoveAuthorized = true;
                }

                authorizeList.Add( consider );
            }
        }

        #endregion

        IAIOrderServer orderServer;

        List<ConsiderWithPRI> considers;

        PRIHelper curPRI, lastPRI;

        public ConsiderCenter ( IAIOrderServer orderServer )
        {
            considers = new List<ConsiderWithPRI>();
            this.orderServer = orderServer;
        }

        public void AddConsider ( IConsider consider, int PRI )
        {
            consider.OrderServer = orderServer;
            considers.Add( new ConsiderWithPRI( consider, PRI ) );
        }

        public void ClearAllConsider ()
        {
            considers.Clear();
        }

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            foreach (ConsiderWithPRI considerWithPRI in considers)
            {
                considerWithPRI.consider.Observe();
            }

            curPRI = new PRIHelper( considers );

            if (lastPRI != null)
            {
                foreach (IConsider last in lastPRI.AuthorizeList)
                {
                    if (curPRI.AuthorizeList.IndexOf( last ) == -1)
                    {
                        last.Bereave();
                    }
                }
                foreach (IConsider cur in curPRI.AuthorizeList)
                {
                    if (lastPRI.AuthorizeList.IndexOf( cur ) == -1)
                    {
                        cur.Authorize();
                    }
                }
            }
            else
            {
                foreach (IConsider cur in curPRI.AuthorizeList)
                {
                    cur.Authorize();
                }
            }

            foreach (IConsider consider in curPRI.AuthorizeList)
            {
                consider.Update( seconds );
            }

            lastPRI = curPRI;
        }

        #endregion
    }

    public enum ConsiderPriority
    {
        Vacancy,
        Low,
        Middle,
        High,
        Urgency,
    }

    public interface IConsider : IUpdater
    {
        ActionRights NeedRights { get;}
        IAIOrderServer OrderServer { set;}
        ConsiderPriority CurPriority { get;}
        void Observe ();
        void Authorize ();
        void Bereave ();
    }

    /// <summary>
    /// 当离边界的距离小于警戒距离时将优先级设为Urgency，并转向。
    /// </summary>
    public class ConsiderAwayFromBorder : IConsider
    {
        #region Type Define

        enum Area
        {
            Middle = 0,
            Left = 1,
            Right = 2,
            Up = 4,
            Dowm = 8,
            UpLeft = 5,
            UpRight = 6,
            DownLeft = 9,
            DownRight = 10,
        }

        #endregion

        #region Constants

        const float defaultGuardDestance = 20;
        const float defaultSpaceForTankWidth = 10;

        #endregion

        #region Variables

        IAIOrderServer orderServer;

        ConsiderPriority curPriority;

        Rectanglef mapSize;

        Area lastArea;

        float rotaAng;

        bool turning;

        float turnRightSpeed;

        float forwardSpeed;

        public float guardDestance = defaultGuardDestance;

        public float spaceForTankWidth = defaultSpaceForTankWidth;

        #endregion

        #region Construction

        public ConsiderAwayFromBorder ( Rectanglef mapSize )
        {
            this.mapSize = mapSize;
            curPriority = ConsiderPriority.Vacancy;
        }

        public ConsiderAwayFromBorder ( Rectanglef mapSize, float guardDestance, float spaceForTankWidth )
        {
            this.mapSize = mapSize;
            this.guardDestance = guardDestance;
            this.spaceForTankWidth = spaceForTankWidth;

            curPriority = ConsiderPriority.Vacancy;
        }

        #endregion

        #region IConsider 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.Rota | ActionRights.Move; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = value;
            }
        }

        public ConsiderPriority CurPriority
        {
            get { return curPriority; }
        }

        public void Observe ()
        {
            Vector2 curPos = orderServer.Pos;
            if (curPos.X < mapSize.X + guardDestance || curPos.X > mapSize.X + mapSize.Width - guardDestance ||
                curPos.Y < mapSize.Y + guardDestance || curPos.Y > mapSize.Y + mapSize.Height - guardDestance)
            {
                curPriority = ConsiderPriority.Urgency;
            }
        }

        public void Authorize ()
        {
            lastArea = FindCurArea();

            Vector2 curDir = orderServer.Direction;
            Vector2 aimDir = Vector2.Zero;

            if (lastArea == Area.UpLeft || lastArea == Area.UpRight ||
                lastArea == Area.DownLeft || lastArea == Area.DownRight)
                aimDir = FindMirrorNormal( lastArea );

            else
            {
                Vector2 mirrorNormal = FindMirrorNormal( lastArea );
                if (Vector2.Dot( mirrorNormal, curDir ) > -0.5)
                    aimDir = mirrorNormal;
                else
                    aimDir = MathTools.ReflectVector( curDir, mirrorNormal );
            }

            rotaAng = MathTools.AngBetweenVectors( curDir, aimDir );
            float turnRight = MathTools.Vector2Cross( curDir, aimDir );

            Vector2 curPos = orderServer.Pos;

            float r = CalTurnRadius( curPos, curDir, turnRight );

            turnRightSpeed = orderServer.MaxRotaSpeed * Math.Sign( turnRight == 0 ? 1 : turnRight );
            forwardSpeed = orderServer.MaxRotaSpeed * r;

            orderServer.TurnRightSpeed = turnRightSpeed;
            orderServer.ForwardSpeed = forwardSpeed;

            turning = true;
        }


        public void Bereave ()
        {

        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            Area curArea = FindCurArea();
            if (curArea != lastArea && curArea != Area.Middle)
            {
                Authorize();
                return;
            }

            if (turning)
            {
                orderServer.TurnRightSpeed = turnRightSpeed;
                orderServer.ForwardSpeed = forwardSpeed;
                rotaAng -= orderServer.MaxRotaSpeed * seconds;
                if (rotaAng <= 0)
                {
                    turning = false;
                    orderServer.TurnRightSpeed = 0;
                    orderServer.ForwardSpeed = orderServer.MaxForwardSpeed;
                }
            }
            if (curArea == Area.Middle)
            {
                curPriority = ConsiderPriority.Vacancy;
                orderServer.ForwardSpeed = 0;
                orderServer.TurnRightSpeed = 0;
            }
        }

        #endregion

        #region Private Functions

        private Area FindCurArea ()
        {
            int sum = 0;
            Vector2 pos = orderServer.Pos;
            if (pos.X < mapSize.X + guardDestance)
                sum += 1;
            if (pos.X > mapSize.X + mapSize.Width - guardDestance)
                sum += 2;
            if (pos.Y < mapSize.Y + guardDestance)
                sum += 4;
            if (pos.Y > mapSize.Y + mapSize.Height - guardDestance)
                sum += 8;

            return (Area)sum;
        }

        private Vector2 FindMirrorNormal ( Area area )
        {
            if (area == Area.Left)
                return new Vector2( 1, 0 );
            else if (area == Area.Right)
                return new Vector2( -1, 0 );
            else if (area == Area.Up)
                return new Vector2( 0, 1 );
            else if (area == Area.Dowm)
                return new Vector2( 0, -1 );
            else if (area == Area.UpLeft)
                return Vector2.Normalize( new Vector2( mapSize.Width, mapSize.Height ) );
            else if (area == Area.UpRight)
                return Vector2.Normalize( new Vector2( -mapSize.Width, mapSize.Height ) );
            else if (area == Area.DownLeft)
                return Vector2.Normalize( new Vector2( mapSize.Width, -mapSize.Height ) );
            else if (area == Area.DownRight)
                return Vector2.Normalize( new Vector2( -mapSize.Width, -mapSize.Height ) );
            else
                return Vector2.Zero;
        }

        private float CalTurnRadius ( Vector2 curPos, Vector2 curDir, float turnRight )
        {
            Vector2 vertiDir = turnRight > 0 ? new Vector2( -curDir.Y, curDir.X ) : new Vector2( curDir.Y, -curDir.X );
            vertiDir.Normalize();

            float defaultRadius = orderServer.MaxForwardSpeed / orderServer.MaxRotaSpeed;

            float r = defaultRadius;

            for (; r > 0; r--)
            {
                Vector2 center = curPos + vertiDir * r;
                if (center.X > r + mapSize.X + spaceForTankWidth && mapSize.X + mapSize.Width - center.X > r + spaceForTankWidth &&
                    center.Y > r + mapSize.Y + spaceForTankWidth && mapSize.Y + mapSize.Height - center.Y > r + spaceForTankWidth)
                    break;
            }

            return r;
        }

        #endregion

    }


}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.IO;
using TankEngine2D.Helpers;
using TankEngine2D.Graphics;
using TankEngine2D.DataStructure;

namespace SmartTank.Shelter
{
    /*
     * 遮挡关系管理类。
     * 
     * */
    public partial class ShelterMgr
    {
        #region Private Type Def
        struct RaderShelterGroup
        {
            public IEnumerable<IRaderOwner> raderOwners;
            public IEnumerable<IShelterObj>[] shelterGroups;

            public RaderShelterGroup( IEnumerable<IRaderOwner> raderOwners, IEnumerable<IShelterObj>[] shelterGroups )
            {
                this.shelterGroups = shelterGroups;
                this.raderOwners = raderOwners;
            }
        }
        #endregion

        #region Constants

        public const int gridSum = 150;

        public const int texSize = 300;
        public const int texSizeSmall = 40;

        #endregion

        #region Variables

        List<RaderShelterGroup> raderShelterGroups = new List<RaderShelterGroup>();

        RaderDrawer raderDrawer;

        #endregion

        #region Construction
        public ShelterMgr()
        {
            raderDrawer = new RaderDrawer();
        }
        #endregion

        #region Group Methods

        public void AddRaderShelterGroup( IEnumerable<IRaderOwner> raderOwners, IEnumerable<IShelterObj>[] shelterGroups )
        {
            raderShelterGroups.Add( new RaderShelterGroup( raderOwners, shelterGroups ) );
        }

        public void ClearGroups()
        {
            raderShelterGroups.Clear();
        }

        #endregion

        #region Update

        public void Update()
        {
            foreach (RaderShelterGroup group in raderShelterGroups)
            {
                foreach (IRaderOwner rader in group.raderOwners)
                {
                    rader.Rader.Update();
                    CalRaderMap( rader.Rader, group.shelterGroups );
                }
            }
        }

        /* 
         * 更新雷达中的可见区域贴图
         * 
         * 
         * 分为以下几个步骤：
         * 
         * <1>获得可能在雷达范围中的所有遮挡物
         * 
         * <2>将遮挡物的边界点坐标转换到雷达空间中，并在已经栅格化的雷达空间中填充边界点的深度信息，获得深度图。
         * 
         * <3>用显卡计算出可见区域贴图
         * 
         * */
        private void CalRaderMap( Rader rader, IEnumerable<IShelterObj>[] shelterObjGroup )
        {
            // 获得可能在雷达范围中的所有遮挡物。
            List<IShelterObj> sheltersInRader = new List<IShelterObj>( 16 );

            foreach (IEnumerable<IShelterObj> group in shelterObjGroup)
            {
                foreach (IShelterObj shelter in group)
                {
                    if (shelter.BoundingBox.Intersects( rader.BoundBox ))
                        sheltersInRader.Add( shelter );
                }
            }

            // 将遮挡物的边界点坐标转换到雷达空间中，并在已经栅格化的雷达空间中填充边界点的深度信息，获得深度图。
            rader.depthMap.ClearMap( 1 );

            foreach (IShelterObj shelter in sheltersInRader)
            {
                rader.depthMap.ApplyShelterObj( rader, shelter );
            }

            // 用显卡计算出可见区域贴图
            raderDrawer.DrawRader( rader );

            // 更新各项数据
            rader.UpdateTexture();
        }



        #endregion


    }




}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.IO;
using TankEngine2D.Helpers;
using SmartTank.Helpers;

namespace SmartTank.Draw.UI.Controls
{
    public class Button : Control
    {
        #region Constants
        #endregion

        #region Variables
        Texture2D texture;

        public Color Color;
        Color currentColor;

        MouseState ms;

        public Point size;
        public string textureName;

        public ButtonState state = ButtonState.MouseOut;
        public enum ButtonState
        {
            MouseOver,
            MouseOut,
            Pressed,
            Released
        }

        #endregion

        #region Events
        public event EventHandler OnMouseOver;

        public event EventHandler OnMouseOut;

        public event EventHandler OnMousePress;

        public event EventHandler OnMouseRelease;

        #endregion

        #region Construction
        public Button ( string name, string textureName, Vector2 position, Color color )//, /*Style style,*/ bool bUseStyle )
        {
            this.Type = ControlType.Button;
            this.name = name;
            this.position = position;
            this.Color = color;
            this.currentColor = color;
            this.textureName = textureName;
            this.text = text;


            #region Old Code
            //if (File.Exists(filePath + style.ToString() + "\\" + textureName + ".xnb"))
            //    texture = Game1.content.Load<Texture2D>(filePath + this.style.ToString() + "\\" + textureName);
            //else if (File.Exists(filePath + textureName + ".xnb"))
            //    texture = Game1.content.Load<Texture2D>(filePath + textureName); 
            #endregion

            if (File.Exists( Directories.UIContent + "\\" + textureName + ".xnb" ))
            {
                texture = BaseGame.ContentMgr.Load<Texture2D>( Path.Combine( Directories.UIContent, textureName ) );
            }
            else
                throw new Exception( "Btn TextureFile don't exist!" );


            this.size = new Point( texture.Width, texture.Height );

            //OnMouseOver += new EventHandler( buttonMouseOver );
            //OnMouseOut += new EventHandler( buttonMouseOut );
            //OnMousePress += new EventHandler( buttonMousePress );
            //OnMouseRelease += new EventHandler( buttonMouseRelease );
        }
        #endregion

        #region Update

        void HandleMouseOver ( Object obj, EventArgs e )
        {
            state = ButtonState.MouseOver;
            if (OnMouseOver != null)
                OnMouseOver( obj, e );
            currentColor = ColorHelper.InterpolateColor( Color, Color.White, 0.3f );
        }

        void HandleMouseOut ( Object obj, EventArgs e )
        {
            state = ButtonState.MouseOut;
            if (OnMouseOut != null)
                OnMouseOut( obj, e );
            currentColor = Color;
        }

        void HandleMousePress ( Object obj, EventArgs e )
        {
            state = ButtonState.Pressed;
            if (OnMousePress != null)
                OnMousePress( obj, e );
            currentColor = ColorHelper.InterpolateColor( Color, Color.Black, 0.3f );
        }

        void HandleMouseRelease ( Object obj, EventArgs e )
        {
            state = ButtonState.Released;
            if (OnMouseRelease != null)
                OnMouseRelease( obj, e );
            currentColor = ColorHelper.InterpolateColor( Color, Color.White, 0.3f );
        }


        public override void Update ()
        {
            if (benable)
                UpdateButtonState();
        }

        //public override void Update ( Vector2 formPosition, Vector2 formSize )
        //{
        //    position = origin + formPosition;

        //    if (benable)
        //        UpdateButtonState();

        //    CheckVisibility( formPosition, formSize );
        //}

        private void UpdateButtonState ()
        {
            ms = Mouse.GetState();

            Rectangle Border = new Rectangle( (int)position.X, (int)position.Y, texture.Width, texture.Height );
            if (Border.Contains( ms.X, ms.Y ))
            {
                if (state == ButtonState.MouseOut)
                {
                    HandleMouseOver( this, EventArgs.Empty );
                }

                if (ms.LeftButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
                {
                    if (state != ButtonState.Pressed)
                    {
                        HandleMousePress( this, EventArgs.Empty );
                    }
                }

                if (ms.LeftButton == Microsoft.Xna.Framework.Input.ButtonState.Released)
                {
                    if (state == ButtonState.Pressed)
                    {
                        HandleMouseRelease( this, EventArgs.Empty );
                    }
                }

            }
            else
            {
                if (state != ButtonState.MouseOut)
                {
                    HandleMouseOut( this, EventArgs.Empty );
                }
            }
        }

        private void CheckVisibility ( Vector2 formPosition, Vector2 formSize )
        {
            if (position.X + size.X > formPosition.X + formSize.X - 15f)
                bVisible = false;
            else if (position.Y + size.Y > formPosition.Y + formSize.Y - 25f)
                bVisible = false;
            else
                bVisible = true;
        }
        #endregion

        #region Public Functions
        public void MoveTo ( Vector2 newPosition )
        {
            position = newPosition;
        }
        #endregion

        #region Draw
        #region Old Code
        //public void Draw ( SpriteBatch spriteBatch, Vector2 formPosition, float alpha )
        //{
        //    Color dynamicColor = new Color( new Vector4( currentColor.ToVector3(), alpha ) );
        //    position = formPosition + origin;
        //    spriteBatch.Draw( texture, position, dynamicColor );
        //} 
        #endregion

        public override void Draw ( SpriteBatch spriteBatch, float alpha )
        {
            Color dynamicColor = new Color( new Vector4( currentColor.ToVector3(), alpha ) );
            spriteBatch.Draw( texture, position, dynamicColor );
        }
        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Shelter;
using SmartTank.GameObjs;
using Microsoft.Xna.Framework;
using SmartTank.PhiCol;
using TankEngine2D.DataStructure;
using TankEngine2D.Helpers;
using SmartTank.Senses.Memory;
using TankEngine2D.Graphics;

namespace SmartTank.Senses.Vision
{
    public delegate IEyeableInfo GetEyeableInfoHandler( IRaderOwner raderOwner, IEyeableObj obj );

    public class VisionMgr
    {
        #region Private type

        //[Obsolete]
        //struct BinGroup
        //{
        //    public IEnumerable<IRaderOwner> raderOwners;
        //    public IEnumerable<KeyValuePair<IEyeableObj, GetEyeableInfoHandler>> eyeableSets;
        //    public BinGroup ( IEnumerable<IRaderOwner> raderOwners, IEnumerable<KeyValuePair<IEyeableObj, GetEyeableInfoHandler>> eyeableSets )
        //    {
        //        this.raderOwners = raderOwners;
        //        this.eyeableSets = eyeableSets;
        //    }
        //}

        struct BinGroup
        {
            public IEnumerable<IRaderOwner> raderOwners;
            public IEnumerable<IEyeableObj>[] eyeableObjs;

            public BinGroup( IEnumerable<IRaderOwner> raderOwners, IEnumerable<IEyeableObj>[] eyeableObjs )
            {
                this.raderOwners = raderOwners;
                this.eyeableObjs = eyeableObjs;
            }
        }

        #endregion

        #region Variables

        //[Obsolete]
        //List<BinGroup> groups = new List<BinGroup>();

        List<BinGroup> groups = new List<BinGroup>();

        #endregion

        #region Public Methods

        //[Obsolete( "修改了IEyeableObj接口，现在将由IEyeableObj保存GetEyeableInfoHandler" )]
        //public void AddVisionGroup ( IEnumerable<IRaderOwner> raderOwners, IEnumerable<KeyValuePair<IEyeableObj, GetEyeableInfoHandler>> set )
        //{
        //    groups.Add( new BinGroup( raderOwners, set ) );
        //}

        public void AddVisionGroup( IEnumerable<IRaderOwner> raderOwners, IEnumerable<IEyeableObj>[] eyeableObjs )
        {
            groups.Add( new BinGroup( raderOwners, eyeableObjs ) );
        }

        public void ClearGroups()
        {
            //groups.Clear();
            groups.Clear();
        }

        #endregion

        #region Update

        public void Update()
        {
            foreach (BinGroup group in groups)
            {
                foreach (IRaderOwner raderOwner in group.raderOwners)
                {
                    CheckVisible( group, raderOwner );
                }
            }

        }

        //[Obsolete]
        //private static void CheckVisible ( BinGroup group, IRaderOwner raderOwner )
        //{
        //    List<IEyeableInfo> inRaderObjInfos = new List<IEyeableInfo>();

        //    //List<IHasBorderObj> inRaderHasBorderNonShelterObjs = new List<IHasBorderObj>();

        //    List<EyeableBorderObjInfo> EyeableBorderObjs = new List<EyeableBorderObjInfo>();

        //    foreach (KeyValuePair<IEyeableObj, GetEyeableInfoHandler> set in group.eyeableSets)
        //    {
        //        if (raderOwner == set.Key)
        //            continue;

        //        // 检查是否为当前雷达的遮挡物体

        //        bool isShelter = false;
        //        foreach (ObjVisiBorder objBorder in raderOwner.Rader.ShelterVisiBorders)
        //        {
        //            if (objBorder.Obj == set.Key)
        //            {
        //                IEyeableInfo eyeableInfo = set.Value( raderOwner, set.Key );
        //                inRaderObjInfos.Add( eyeableInfo );

        //                EyeableBorderObjs.Add( new EyeableBorderObjInfo( eyeableInfo, objBorder ) );

        //                isShelter = true;
        //                break;
        //            }
        //        }

        //        // 检查非遮挡物体是否可见
        //        if (!isShelter)
        //        {
        //            foreach (Vector2 keyPoint in set.Key.KeyPoints)
        //            {
        //                if (raderOwner.Rader.PointInRader( Vector2.Transform( keyPoint, set.Key.TransMatrix ) ))
        //                {
        //                    IEyeableInfo eyeableInfo = set.Value( raderOwner, set.Key );
        //                    inRaderObjInfos.Add( eyeableInfo );

        //                    if (set.Key is IHasBorderObj)
        //                    {
        //                        ObjVisiBorder border = CalNonShelterVisiBorder( (IHasBorderObj)set.Key, raderOwner.Rader );
        //                        if (border != null)
        //                            EyeableBorderObjs.Add( new EyeableBorderObjInfo( eyeableInfo, border ) );
        //                    }
        //                    break;
        //                }
        //            }
        //        }
        //    }

        //    raderOwner.Rader.CurEyeableObjs = inRaderObjInfos;
        //    raderOwner.Rader.EyeableBorderObjInfos = EyeableBorderObjs.ToArray();
        //}

        /*
         * 将作为CheckVisible的替代，尚未测试。
         * */
        private static void CheckVisible( BinGroup group, IRaderOwner raderOwner )
        {
            List<IEyeableInfo> inRaderObjInfos = new List<IEyeableInfo>();

            List<EyeableBorderObjInfo> EyeableBorderObjs = new List<EyeableBorderObjInfo>();

            foreach (IEnumerable<IEyeableObj> eyeGroup in group.eyeableObjs)
            {
                foreach (IEyeableObj obj in eyeGroup)
                {
                    if (raderOwner == obj)
                        continue;

                    // 检查是否为当前雷达的遮挡物体

                    bool isShelter = false;
                    foreach (ObjVisiBorder objBorder in raderOwner.Rader.ShelterVisiBorders)
                    {
                        if (objBorder.Obj == obj)
                        {
                            IEyeableInfo eyeableInfo = obj.GetEyeableInfoHandler( raderOwner, obj );
                            inRaderObjInfos.Add( eyeableInfo );

                            EyeableBorderObjs.Add( new EyeableBorderObjInfo( eyeableInfo, objBorder ) );

                            isShelter = true;
                            break;
                        }
                    }

                    // 检查非遮挡物体是否可见
                    if (!isShelter)
                    {
                        foreach (Vector2 keyPoint in obj.KeyPoints)
                        {
                            if (raderOwner.Rader.PointInRader( Vector2.Transform( keyPoint, obj.TransMatrix ) ))
                            {
                                IEyeableInfo eyeableInfo = obj.GetEyeableInfoHandler( raderOwner, obj );
                                inRaderObjInfos.Add( eyeableInfo );

                                if (obj is IHasBorderObj)
                                {
                                    ObjVisiBorder border = CalNonShelterVisiBorder( (IHasBorderObj)obj, raderOwner.Rader );
                                    if (border != null)
                                        EyeableBorderObjs.Add( new EyeableBorderObjInfo( eyeableInfo, border ) );
                                }
                                break;
                            }
                        }
                    }
                }
            }

            raderOwner.Rader.CurEyeableObjs = inRaderObjInfos;
            raderOwner.Rader.EyeableBorderObjInfos = EyeableBorderObjs.ToArray();
        }

        private static ObjVisiBorder CalNonShelterVisiBorder( IHasBorderObj obj, Rader rader )
        {
            CircleListNode<BorderPoint> curNode = obj.BorderData.First;
            CircleList<BordPoint> points = new CircleList<BordPoint>();
            for (int i = 0; i < obj.BorderData.Length; i++)
            {
                if (rader.PointInRader( Vector2.Transform( ConvertHelper.PointToVector2( curNode.value.p ), obj.WorldTrans ) ))
                {
                    points.AddLast( new BordPoint( i, curNode.value.p ) );
                }
                curNode = curNode.next;
            }
            if (points.Length != 0)
                return new ObjVisiBorder( obj, points );
            else
                return null;
        }

        #endregion

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.GameObjs.Tank;
using SmartTank.GameObjs.Tank.SinTur;
using TankEngine2D.Input;
using SmartTank.Senses.Vision;
using TankEngine2D.Helpers;
using InterRules.ShootTheBall;
using SmartTank.AI;
using Microsoft.Xna.Framework;
using SmartTank.AI.AIHelper;

namespace InterRules.ShootTheBall
{
    [AIAttribute( "AutoShootAI", "SmartTank Team", "A Simple Linear Aimming AI", 2007, 10, 31 )]
    class AutoShootAI : IAISinTur
    {
        IAIOrderServerSinTur orderServer;

        AIActionHelper action;

        Vector2 lastItemPos;

        bool aimming = false;
        float aimmingTime;

        Vector2 aimPos;
        Vector2 vel;

        bool lastRaderRotaWise = true;

        #region IAI ³ΙΤ±

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = (IAIOrderServerSinTur)value;
                action = new AIActionHelper( orderServer );
            }
        }

        public IAICommonServer CommonServer
        {
            set { }
        }

        #endregion

        #region IUpdater ³ΙΤ±

        public void Update ( float seconds )
        {
            #region OLDCODE
            //if (InputHandler.IsKeyDown( Keys.W ))
            //{
            //    orderServer.ForwardSpeed = 1000;
            //}
            //else if (InputHandler.IsKeyDown( Keys.S ))
            //{
            //    orderServer.ForwardSpeed = -1000;
            //}
            //else
            //{
            //    orderServer.ForwardSpeed = 0;
            //}

            //if (InputHandler.IsKeyDown( Keys.D ))
            //{
            //    orderServer.TurnRightSpeed = 20;
            //}
            //else if (InputHandler.IsKeyDown( Keys.A ))
            //{
            //    orderServer.TurnRightSpeed = -20;
            //}
            //else
            //{
            //    orderServer.TurnRightSpeed = 0;
            //}
            #endregion

            aimmingTime -= seconds;

            List<IEyeableInfo> eyeableInfos = orderServer.GetEyeableInfo();
            if (eyeableInfos.Count != 0)
            {


                orderServer.TurnRaderWiseSpeed = 0;

                if (eyeableInfos[0] is ItemEyeableInfo)
                {
                    lastRaderRotaWise = MathTools.AziFromRefPos( ((ItemEyeableInfo)eyeableInfos[0]).Pos - orderServer.Pos ) > 0;
                    action.AddOrder( new OrderRotaRaderToPos( ((ItemEyeableInfo)eyeableInfos[0]).Pos ) );
                }
                else if (eyeableInfos[0] is TankSinTur.TankCommonEyeableInfo)
                {
                    lastRaderRotaWise = MathTools.AziFromRefPos( ((TankSinTur.TankCommonEyeableInfo)eyeableInfos[0]).Pos - orderServer.Pos ) > 0;
                    action.AddOrder( new OrderRotaRaderToPos( ((TankSinTur.TankCommonEyeableInfo)eyeableInfos[0]).Pos ) );
                }

                if (eyeableInfos[0] is ItemEyeableInfo)
                {
                    lastItemPos = ((ItemEyeableInfo)eyeableInfos[0]).Pos;
                    vel = ((ItemEyeableInfo)eyeableInfos[0]).Vel;
                }
                else if (eyeableInfos[0] is TankSinTur.TankCommonEyeableInfo)
                {
                    lastItemPos = ((TankSinTur.TankCommonEyeableInfo)eyeableInfos[0]).Pos;
                    vel = ((TankSinTur.TankCommonEyeableInfo)eyeableInfos[0]).Vel;
                }


                if (!aimming)
                {

                    float curTurretAzi = orderServer.TurretAimAzi;

                    float t = 0;

                    float maxt = 30;
                    bool canShoot = false;
                    while (t < maxt)
                    {
                        aimPos = lastItemPos + vel * t;
                        float timeRota = Math.Abs( MathTools.AngTransInPI( MathTools.AziFromRefPos( aimPos - orderServer.TurretAxePos ) - curTurretAzi ) / orderServer.MaxRotaTurretSpeed );
                        float timeShell = (Vector2.Distance( aimPos, orderServer.TurretAxePos ) - orderServer.TurretLength) / orderServer.ShellSpeed;
                        if (MathTools.FloatEqual( timeRota + timeShell, t, 0.03f ))
                        {
                            canShoot = true;
                            break;
                        }
                        t += 0.03f;
                    }

                    if (canShoot)
                    {
                        aimming = true;
                        aimmingTime = t;
                        action.AddOrder( new OrderRotaTurretToPos( aimPos, 0,
                            delegate( IActionOrder order )
                            {
                                orderServer.Fire();
                                aimming = false;
                            }, false ) );
                    }
                    else
                    {
                        action.AddOrder( new OrderRotaTurretToPos( lastItemPos ) );
                    }
                }
                else
                {
                    if ((lastItemPos + aimmingTime * vel - aimPos).Length() > 4)
                    {
                        aimming = false;
                    }
                }
            }
            else
            {
                orderServer.TurnRaderWiseSpeed = orderServer.MaxRotaRaderSpeed * (lastRaderRotaWise ? 1 : -1);
                
            }

            action.Update( seconds );
        }

        #endregion

        public void Draw ()
        {
            
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Common.DataStructure;
using Microsoft.Xna.Framework.Graphics;

namespace Common.Helpers
{
    /// <summary>
    /// 类型转换辅助类
    /// </summary>
    public static class ConvertHelper
    {
        /// <summary>
        /// 将Point类型转换为Vector2类型
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static Vector2 PointToVector2 ( Point p )
        {
            return new Vector2( p.X, p.Y );
        }
        /// <summary>
        /// 将Vector2类型转换为Point类型，进行四舍五入操作
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static Point Vector2ToPoint ( Vector2 v )
        {
            return new Point( MathTools.Round( v.X ), MathTools.Round( v.Y ) );
        }
        /// <summary>
        /// 将Rectangle类型转换为Rectanglef类型
        /// </summary>
        /// <param name="rect"></param>
        /// <returns></returns>
        public static Rectanglef RectangleToRectanglef ( Rectangle rect )
        {
            return new Rectanglef( rect.X, rect.Y, rect.Width, rect.Height );
        }
        /// <summary>
        /// 将Rectanglef类型转换为Rectangle类型，进行取整操作
        /// </summary>
        /// <param name="rect"></param>
        /// <returns></returns>
        public static Rectangle RectanglefToRectangle ( Rectanglef rect )
        {
            return new Rectangle( (int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height );
        }
        /// <summary>
        /// 将C#标准库中的Color类型转换为XNA的Color类型
        /// </summary>
        /// <param name="sysColor"></param>
        /// <returns></returns>
        public static Color SysColorToXNAColor ( System.Drawing.Color sysColor )
        {
            return new Color( sysColor.R, sysColor.G, sysColor.B, sysColor.A );
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Common.Helpers;

namespace GameEngine.Effects.TextEffects
{
    /// <summary>
    /// 字体效果的管理类
    /// </summary>
    public static class TextEffectMgr
    {
        static LinkedList<ITextEffect> sEffects = new LinkedList<ITextEffect>();

        /// <summary>
        /// 绘制当前的特效字体并更新他们
        /// </summary>
        static public void Draw ()
        {
            LinkedListNode<ITextEffect> node;
            for (node = sEffects.First; node != null; )
            {
                if (node.Value.Ended)
                {
                    node = node.Next;
                    if (node != null)
                        sEffects.Remove( node.Previous );
                    else
                        sEffects.RemoveLast();
                }
                else
                {
                    node.Value.Draw();
                    node = node.Next;
                }
            }
        }

        /// <summary>
        /// 指定逻辑坐标添加一个RiseFade文字特效。
        /// 注意，如果文字内容中包含中文，必须选用中文字体
        /// </summary>
        /// <param name="text">文字内容</param>
        /// <param name="pos">显示的逻辑位置</param>
        /// <param name="Scale">大小</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">绘制深度</param>
        /// <param name="fontType">字体</param>
        /// <param name="existedFrame">保持在屏幕中的时间循环次数</param>
        /// <param name="step">每次时间循环中，上升的高度，以像素为单位</param>
        static public void AddRiseFade ( string text, Vector2 pos, float Scale, Color color, float layerDepth,string fontType, float existedFrame, float step )
        {
            sEffects.AddLast( new FadeUpEffect( text, true, pos, Scale, color, layerDepth, fontType, existedFrame, step ) );
        }

        /// <summary>
        /// 在屏幕坐标中添加一个RiseFade文字特效。
        /// 注意，如果文字内容中包含中文，必须选用中文字体
        /// </summary>
        /// <param name="text">文字内容</param>
        /// <param name="pos">显示的屏幕位置</param>
        /// <param name="Scale">大小</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">绘制深度</param>
        /// <param name="fontType">字体</param>
        /// <param name="existedFrame">保持在屏幕中的时间循环次数</param>
        /// <param name="step">每次时间循环中，上升的高度，以像素为单位</param>
        static public void AddRiseFadeInScrnCoordin ( string text, Vector2 pos, float Scale, Color color, float layerDepth, string fontType, float existedFrame, float step )
        {
            sEffects.AddLast( new FadeUpEffect( text, false, pos, Scale, color, layerDepth, fontType, existedFrame, step ) );
        }

        /// <summary>
        /// 清楚所有的文字特效
        /// </summary>
        public static void Clear ()
        {
            sEffects.Clear();
        }

    }

    /// <summary>
    /// 定义文字特效的一般方法
    /// </summary>
    public interface ITextEffect
    {
        /// <summary>
        /// 绘制并更新自己
        /// </summary>
        void Draw ();

        /// <summary>
        /// 是否已经结束
        /// </summary>
        bool Ended { get;}
    }
    
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace TankEngine2D.DataStructure
{
    /// <summary>
    /// 一个用Hash实现的容器。
    /// 
    /// 如果其中的元素类型继承于某个接口（或父类），就能获取该容器的一个可以以该接口（或父类）进行迭代的副本。
    /// 当原容器中元素有所改动时，副本和原容器始终保持一致。
    /// 
    /// 容器对其中的每一个元素使用一个string类型的名称作为Hash表的主键，通过该主键达到快速的查找。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class MultiList<T> : IEnumerable<T> where T : class
    {
        Dictionary<string, T> dic;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public MultiList ()
        {
            dic = new Dictionary<string, T>();
        }

        /// <summary>
        /// 添加元素
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Add ( string name, T value )
        {
            if (dic.ContainsKey( name ))
                return false;
            else
            {
                dic.Add( name, value );
                return true;
            }
        }

        /// <summary>
        /// 删除元素
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool Remove ( string name )
        {
            if (dic.ContainsKey( name ))
            {
                dic.Remove( name );
                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// 获得元素的值
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public T this[string name]
        {
            get
            {
                try
                {
                    if (dic.ContainsKey(name))
                        return dic[name];
                    else
                        return null;
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }

        #region IEnumerable<T> 成员

        /// <summary>
        /// 获得枚举器
        /// </summary>
        /// <returns></returns>
        public IEnumerator<T> GetEnumerator ()
        {
            foreach (KeyValuePair<string, T> pair in dic)
            {
                yield return pair.Value;
            }
        }

        #endregion

        #region IEnumerable 成员

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
        {
            return GetEnumerator();
        }

        #endregion

        /// <summary>
        /// 获得副本
        /// </summary>
        /// <typeparam name="CopyType"></typeparam>
        /// <returns></returns>
        public MultiCopy<CopyType, T> GetCopy<CopyType> () where CopyType : class
        {
            Type copyType = typeof( CopyType );
            Type valueType = typeof( T );
            if (copyType.IsInterface)
            {
                if (valueType.GetInterface( copyType.Name ) == null)
                    throw new Exception( "Can not convert ValueType to CopyType!" );
            }
            else
            {
                if (!typeof( T ).IsSubclassOf( typeof( CopyType ) ))
                    throw new Exception( "Can not convert ValueType to CopyType!" );
            }

            MultiCopy<CopyType,T> copy = new MultiCopy<CopyType,T>( this );
            return copy;
        }
    }

    /// <summary>
    /// MultiList的副本
    /// </summary>
    /// <typeparam name="CopyType"></typeparam>
    /// <typeparam name="T"></typeparam>
    public class MultiCopy<CopyType, T> : IEnumerable<CopyType>
        where T : class
        where CopyType : class
    {
        MultiList<T> mother;

        /// <summary>
        /// MultiList的副本
        /// </summary>
        /// <param name="mother">原容器</param>
        public MultiCopy ( MultiList<T> mother )
        {
            this.mother = mother;
        }

        #region IEnumerable<CopyType> 成员

        /// <summary>
        /// 获得枚举器
        /// </summary>
        /// <returns></returns>
        public IEnumerator<CopyType> GetEnumerator ()
        {
            foreach (T value in mother)
            {
                yield return value as CopyType;
            }
        }

        #endregion

        #region IEnumerable 成员

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
        {
            return GetEnumerator();
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.AI;
using SmartTank.AI.AIHelper;
using TankEngine2D.DataStructure;
using TankEngine2D.Graphics;
using SmartTank.GameObjs;

namespace InterRules.Duel
{
    [AIAttribute( "Dueler No.1", "Wufei", "", 2007, 11, 7 )]
    class DuelerNoFirst : IDuelAI
    {
        IDuelAIOrderServer orderServer;
        AICommonServer commonServer;

        AIActionHelper action;

        Rectanglef mapBorder;

        ConsiderCenter considerCenter;

        public DuelerNoFirst ()
        {

        }

        #region IAI 成员

        public IAICommonServer CommonServer
        {
            set
            {
                commonServer = (AICommonServer)value;
                mapBorder = commonServer.MapBorder; ;

            }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = (IDuelAIOrderServer)value;
                orderServer.OnCollide += new OnCollidedEventHandlerAI( CollideHandler );
                action = new AIActionHelper( orderServer );

                considerCenter = new ConsiderCenter( orderServer );
                considerCenter.AddConsider( new ConsiderAwayFromBorder( mapBorder, 30, 10 ), 5 );
                considerCenter.AddConsider( new ConsiderSearchEnemy( mapBorder, orderServer.RaderRadius ), 3 );
                considerCenter.AddConsider( new ConsiderRaderScan( mapBorder ), 3 );
                considerCenter.AddConsider( new ConsiderAwayFromEnemyTurret( mapBorder ), 4 );
                considerCenter.AddConsider( new ConsiderRaderLockEnemy(), 4 );
                considerCenter.AddConsider( new ConsiderKeepDistanceFromEnemy(), 4 );
                considerCenter.AddConsider( new ConsiderShootEnemy(), 5 );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            considerCenter.Update( seconds );
        }

        #endregion

        void CollideHandler ( CollisionResult result, GameObjInfo objB )
        {
            if (objB.ObjClass == "Border")
            {
            }
            else if (objB.ObjClass == "ShellNormal")
            {
            }
            else if (objB.ObjClass == "DuelTank")
            {
            }

        }

        #region IAI 成员


        public void Draw ()
        {
            
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.Rule
{
    [AttributeUsage( AttributeTargets.Class, Inherited = false )]
    public class RuleAttribute : Attribute
    {
        public string Name;
        public string RuleInfo;
        public string Programer;
        public DateTime time;


        public RuleAttribute ( string name, string ruleInfo, string programer, int year, int mouth, int day )
        {
            this.Name = name;
            this.RuleInfo = ruleInfo;
            this.Programer = programer;
            time = new DateTime( year, mouth, day );
        }


    }
}
<file_sep>#define SHOWERROR

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections;
using TankEngine2D.DataStructure;
using TankEngine2D.Helpers;


namespace TankEngine2D.Graphics
{
    using BorderNode = CircleListNode<BorderPoint>;
    using BorderCircleList = CircleList<BorderPoint>;

    /// <summary>
    /// 
    /// </summary>
    public class BorderBulidException : Exception
    {
        /// <summary>
        /// 
        /// </summary>
        public Point curPoint;
        /// <summary>
        /// 
        /// </summary>
        public Point prePoint;
        /// <summary>
        /// 
        /// </summary>
        public SpriteBorder.BorderMap borderMap;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="curPoint"></param>
        /// <param name="prePoint"></param>
        /// <param name="borderMap"></param>
        public BorderBulidException ( Point curPoint, Point prePoint, SpriteBorder.BorderMap borderMap )
        {
            this.curPoint = curPoint;
            this.prePoint = prePoint;
            this.borderMap = borderMap;
        }
    }

    /// <summary>
    /// 表示精灵边界上的点
    /// </summary>
    public class BorderPoint
    {
        /// <summary>
        /// 设置该点的贴图坐标
        /// </summary>
        /// <param name="setp"></param>
        public BorderPoint ( Point setp )
        {
            p = setp;
        }

        /// <summary>
        /// 该点的贴图坐标
        /// </summary>
        public Point p;

        /// <summary>
        /// 获得该点的贴图坐标
        /// </summary>
        public Point Point
        {
            get { return p; }
        }

        /// <summary>
        /// 获得该点的相邻点
        /// </summary>
        public Point[] NeiborNodes
        {
            get
            {
                return new Point[4]
                    {
                        new Point(p.X - 1, p.Y),
                        new Point(p.X, p.Y - 1),
                        new Point(p.X, p.Y + 1),
                        new Point(p.X + 1, p.Y)//,
                        //new Point(p.X - 1, p.Y - 1),
                        //new Point(p.X + 1, p.Y - 1),
                        //new Point(p.X - 1, p.Y + 1),
                        //new Point(p.X + 1, p.Y + 1)
                    };
            }
        }
    }

    /// <summary>
    /// 表示精灵的边界
    /// </summary>
    public class SpriteBorder
    {
        #region DataStruct Definition

        /// <summary>
        /// 确定原图中一个像素处是否是物体部分的Alpha通道阀值
        /// </summary>
        public const int minBlockAlpha = 10;

        /// <summary>
        /// 边界图。
        /// 生成物体边界中间步骤的数据，表示贴图中的Alpha值变化边界点
        /// </summary>
        public class BorderMap
        {
            bool[,] borderMap;

            internal BorderMap ( int width, int height )
            {
                borderMap = new bool[height + 4, width + 4];
                borderMap.Initialize();
            }

            /// <summary>
            /// 检索当前某坐标上是否为一个Alpha值变化的边界点
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            public bool this[int x, int y]
            {
                get
                {
                    if (x < -2 || x >= borderMap.GetLength( 1 ) ||
                        y < -2 || y >= borderMap.GetLength( 0 ))
                    {
                        throw new IndexOutOfRangeException();
                    }

                    return borderMap[y + 2, x + 2];
                }

                set
                {
                    if (x < -2 || x >= borderMap.GetLength( 1 ) ||
                        y < -2 || y >= borderMap.GetLength( 0 ))
                    {
                        throw new IndexOutOfRangeException();
                    }

                    borderMap[y + 2, x + 2] = value;
                }
            }
            /// <summary>
            /// 获得边界图的宽度
            /// </summary>
            public int Width
            {
                get { return borderMap.GetLength( 1 ); }
            }
            /// <summary>
            /// 获得边界图的高度
            /// </summary>
            public int Height
            {
                get { return borderMap.GetLength( 0 ); }
            }

            #region Functions for test
            /// <summary>
            /// 将边界图的信息显示到控制台上
            /// </summary>
            public void ShowDataToConsole ()
            {
                Console.WriteLine( "BorderMap:" );

                for (int y = -2; y < this.Height - 2; y++)
                {
                    for (int x = -2; x < this.Width - 2; x++)
                    {
                        Console.Write( this[x, y] ? "■" : "□" );
                    }
                    //Console.Write( "" + y );
                    Console.WriteLine();
                }
            }
            #endregion
        }

        private class TextureData
        {


            Color[] texData;

            int texWidth,
                texHeight;

            public TextureData ( Texture2D tex )
            {
                texData = new Color[tex.Width * tex.Height];
                tex.GetData<Color>( texData );
                texWidth = tex.Width;
                texHeight = tex.Height;
            }

            public bool this[int x, int y]
            {
                get
                {
                    if (x < 0 || x >= texWidth || y < 0 || y >= texHeight)
                        return false;
                    else
                        return texData[y * texWidth + x].A >= minBlockAlpha;
                }
            }
        }

        #endregion

        #region Variables

        List<BorderCircleList> borderCircles;

        TextureData texData;

        BorderMap borderMap;

        /// <summary>
        /// 用于获得边界的辅助对象，参见InitialSurroundPoint函数、
        /// SetPrePointFirstTime函数、SurroundQueue函数以及BuildCircle函数。
        /// </summary>
        private CircleList<Point> SurroundPoint;

        #endregion

        #region Properties

        /// <summary>
        /// 获得边界环链表
        /// </summary>
        public BorderCircleList BorderCircle
        {
            get { return borderCircles[0]; }
        }

        #endregion

        #region Construction

        /// <summary>
        /// 构造制定贴图的边界。
        /// </summary>
        /// <param name="tex"></param>
        public SpriteBorder ( Texture2D tex )
        {
            InitialSurroundPoint();

            borderCircles = new List<BorderCircleList>();
            texData = new TextureData( tex );
            borderMap = new BorderMap( tex.Width, tex.Height );

            CreateBorderCircles( tex );
        }

        /// <summary>
        /// 构造指定贴图的边界，为了测试，返回borderMap
        /// </summary>
        /// <param name="tex"></param>
        /// <param name="borderMap"></param>
        public SpriteBorder ( Texture2D tex, out SpriteBorder.BorderMap borderMap )
            : this( tex )
        {
            borderMap = this.borderMap;
        }

        #region Private Functions

        const int minBorderListLength = 10;


        private void CreateBorderCircles ( Texture2D tex )
        {
            LinkedList<BorderPoint> leftBorderNodes = new LinkedList<BorderPoint>();

            for (int y = -1; y <= tex.Height; y++)
            {
                for (int x = -1; x <= tex.Width; x++)
                {
                    BorderPoint cur = new BorderPoint( new Point( x, y ) );
                    if (NodeIsBorder( cur ))
                    {
                        borderMap[x, y] = true;
                        leftBorderNodes.AddLast( cur );
                    }
                }
            }

            while (leftBorderNodes.Count != 0)
            {
                BorderPoint first = leftBorderNodes.First.Value;

                BorderCircleList list = BuildCircle( first );
                if (list.isLinked && list.Length >= minBorderListLength)
                {
                    borderCircles.Add( list );
                }

                // Delete Circles' node from LeftBorderNodes
                foreach (BorderPoint border in list)
                {
                    LinkedListNode<BorderPoint> node = leftBorderNodes.First;
                    for (int i = 0; i < leftBorderNodes.Count - 1; i++)
                    {
                        node = node.Next;
                        if (node.Previous.Value.p == border.p)
                        {
                            leftBorderNodes.Remove( node.Previous );
                        }
                    }
                    if (leftBorderNodes.Last != null && leftBorderNodes.Last.Value.p == border.p)
                        leftBorderNodes.RemoveLast();
                }
            }


        }

        private void InitialSurroundPoint ()
        {
            SurroundPoint = new CircleList<Point>();
            SurroundPoint.AddLast( new Point( -1, -1 ) );
            SurroundPoint.AddLast( new Point( 0, -1 ) );
            SurroundPoint.AddLast( new Point( 1, -1 ) );
            SurroundPoint.AddLast( new Point( 1, 0 ) );
            SurroundPoint.AddLast( new Point( 1, 1 ) );
            SurroundPoint.AddLast( new Point( 0, 1 ) );
            SurroundPoint.AddLast( new Point( -1, 1 ) );
            SurroundPoint.AddLast( new Point( -1, 0 ) );
            SurroundPoint.LinkLastAndFirst();
        }

        private bool NodeIsBlock ( Point node )
        {
            return texData[node.X, node.Y];
        }

        private bool NodeIsBorder ( BorderPoint node )
        {
            if (NodeIsBlock( node.p )) return false;

            foreach (Point p in node.NeiborNodes)
            {
                if (NodeIsBlock( p ))
                    return true;
            }
            return false;
        }

        /// <summary>
        /// 按逆时针方向获得边界圈
        /// </summary>
        /// <param name="first"></param>
        /// <returns></returns>
        private BorderCircleList BuildCircle ( BorderPoint first )
        {
            BorderCircleList result = new BorderCircleList();

            BorderNode firstNode = new BorderNode( first );
            result.AddLast( firstNode );

            Point prePoint = new Point();
            Point curPoint = firstNode.value.p;

            try
            {
                //set the prePoint at the first time!
                SetPrePointFirstTime( firstNode.value.p, ref prePoint );


                bool linked = false;
                while (!linked)
                {
                    bool findNext = false;

                    foreach (Point p in SurroundQueue( curPoint, prePoint ))
                    {
                        if (borderMap[p.X, p.Y] && p != prePoint)
                        {
                            findNext = true;

                            if (p == firstNode.value.p)
                            {
                                linked = true;
                                result.LinkLastAndFirst();
                                break;
                            }

                            result.AddLast( new BorderPoint( p ) );
                            prePoint = curPoint;
                            curPoint = p;
                            break;
                        }
                    }
                    if (!findNext)
                    {
#if SHOWERROR
                        //ShowDataToConsole();
                        //ShowCurListResult( result );
#endif
                        throw new BorderBulidException( curPoint, prePoint, borderMap );
                    }
                }

            }
            // 如果此处出现异常，往往是导入的图片不能满足要求。
            // 将在输出中打印出图片上具体出错的位置。
            // 需要重新修改图片以正常使用。
            catch (BorderBulidException e)
            {
#if SHOWERROR
                //ShowDataToConsole();
                //ShowCurListResult( result );
#endif
                throw e;
                //return result;
            }
            return result;
        }



        private void SetPrePointFirstTime ( Point firPoint, ref Point prePoint )
        {
            CircleListNode<Point>[] surroundBorder =
                SurroundPoint.FindAll( delegate( Point p )
                    {
                        if (borderMap[p.X + firPoint.X, p.Y + firPoint.Y])
                            return true;
                        else
                            return false;
                    } );

            if (surroundBorder.Length == 2)
            {
                int IndexA = SurroundPoint.IndexOf( surroundBorder[0] );
                int IndexB = SurroundPoint.IndexOf( surroundBorder[1] );

                int BsubA = IndexB - IndexA;
                if (BsubA <= 4)
                {
                    Point refPos = surroundBorder[0].value;
                    prePoint = new Point( firPoint.X + refPos.X, firPoint.Y + refPos.Y );
                }
                else
                {
                    Point refPos = surroundBorder[1].value;
                    prePoint = new Point( firPoint.X + refPos.X, firPoint.Y + refPos.Y );
                }
            }
            //else if (surroundBorder.Length == 3)
            else
                throw new BorderBulidException( firPoint, prePoint, borderMap );
        }


        private Point[] SurroundQueue ( Point point, Point prePoint )
        {
            CircleList<Point> result = SurroundPoint.Clone();
            result.ForEach( delegate( ref Point p )
                {
                    p = new Point( p.X + point.X, p.Y + point.Y );
                } );

            CircleListNode<Point> find = result.FindFirst( delegate( Point p )
                {
                    if (p == prePoint)
                        return true;
                    else
                        return false;
                } );

            return result.ToArray( find, true );
        }

        #endregion

        #endregion

        #region Public Functions

        /// <summary>
        /// 获得一个边界点处的法向量
        /// </summary>
        /// <param name="node"></param>
        /// <param name="sumAverage"></param>
        /// <returns></returns>
        public Vector2 GetNormalVector ( BorderNode node, int sumAverage )
        {
            if (sumAverage < 1)
                sumAverage = 1;

            Vector2 sumTang = Vector2.Zero;
            BorderNode cur = node;
            for (int i = 0; i < sumAverage; i++)
            {
                cur = cur.pre;
            }
            for (int i = -sumAverage; i <= sumAverage; i++)
            {
                if (i == 0) i++;

                cur = cur.next;
                Point curPoint = cur.value.p;
                Point prePoint = cur.pre.value.p;
                Vector2 tang = new Vector2( curPoint.X - prePoint.X, curPoint.Y - prePoint.Y );
                tang.Normalize();
                tang *= Right( Math.Abs( i ), sumAverage );
                sumTang += tang;
            }
            Vector2 result = new Vector2( sumTang.Y, -sumTang.X );
            // sprite类中会进行标准化，此处略掉
            //result.Normalize();
            return result;
        }

        private float Right ( int destance, int sumAverage )
        {
            return sumAverage;// -destance;
        }

        #endregion

        #region Fuctions for test

        /// <summary>
        /// 将当前的链表信息输出到控制台中。
        /// </summary>
        public void ShowDataToConsole ()
        {
            Console.WriteLine( "SpriteBorder class:" );
            Console.WriteLine();
            borderMap.ShowDataToConsole();
            Console.WriteLine();
            ShowCirclesData();
        }

        private void ShowCirclesData ()
        {
            foreach (BorderCircleList list in borderCircles)
            {
                BorderMap map = new BorderMap( borderMap.Width - 4, borderMap.Height - 4 );
                foreach (BorderPoint bord in list)
                {
                    Point p = bord.p;
                    map[p.X, p.Y] = true;
                }
                map.ShowDataToConsole();
                Console.WriteLine();
            }
        }

        private void ShowCurListResult ( BorderCircleList result )
        {
            BorderMap map = new BorderMap( borderMap.Width - 4, borderMap.Height - 4 );
            foreach (BorderPoint bord in result)
            {
                Point p = bord.p;
                map[p.X, p.Y] = true;
            }
            map.ShowDataToConsole();
            Console.WriteLine();
        }

        #endregion


    }
}
<file_sep>
void myError()
{
    
#ifdef WIN32
    perror("Socket Error.");
#else
    perror("Socket Error.");
#endif
}

<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.GameObjs;
using System.Xml;
using TankEngine2D.Helpers;

namespace SmartTank.Scene
{
    public class Group
    {
        protected string name;

        protected Group father;

        protected Dictionary<string, Group> groups;

        /// <summary>
        /// 获得组名
        /// </summary>
        public string Name
        {
            get { return name; }
        }

        /// <summary>
        /// 获得父节点
        /// </summary>
        public Group Father
        {
            get { return father; }
        }

        /// <summary>
        /// 获得子组
        /// </summary>
        public Dictionary<string, Group> Childs
        {
            get { return groups; }
        }

        /// <summary>
        /// 获得组的路径
        /// </summary>
        public string Path
        {
            get
            {
                Group cur = this;
                string result = this.name;
                if (cur.father != null)
                    while (cur.father.father != null)
                    {
                        cur = cur.father;
                        result = string.Concat( cur.name, "\\", result );
                    }
                return result;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name">组名</param>
        public Group( string name )
        {
            this.name = name;
            groups = new Dictionary<string, Group>();
        }

        /// <summary>
        /// 获得子组
        /// </summary>
        /// <param name="groupName">组名</param>
        /// <returns></returns>
        public Group GetChildGroup( string groupName )
        {
            if (groups.ContainsKey( groupName ))
            {
                return groups[groupName];
            }
            return null;
        }

        /// <summary>
        /// 添加子组
        /// </summary>
        /// <param name="group">要添加的子组</param>
        /// <returns></returns>
        public bool AddChildGroup( Group group )
        {
            if (groups.ContainsKey( group.name ))
            {
                Log.Write( "在添加子组时，存在相同的子组名" + name + ", " + group.name );
                return false;
            }
            else
            {
                groups.Add( group.name, group );
                group.father = this;
                return true;
            }
        }

        /// <summary>
        /// 删除子组
        /// </summary>
        /// <param name="group">要删除的子组</param>
        /// <returns></returns>
        public bool DelChildGroup( Group group )
        {
            if (groups.ContainsKey( group.name ) && groups[group.name] == group)
            {
                groups.Remove( group.name );
                group.father = null;
                return true;
            }
            else
            {
                Log.Write( "删除子组时，未找到相符子组" + name + ", " + group.name );
                return false;
            }
        }
        /// <summary>
        /// 删除子组
        /// </summary>
        /// <param name="groupName">要删除子组的组名</param>
        /// <returns></returns>
        public bool DelChildGroup( string groupName )
        {
            if (groups.ContainsKey( groupName ))
            {
                groups.Remove( groupName );
                return true;
            }
            else
            {
                Log.Write( "删除子组时，未找到相符子组" + name + ", " + groupName );
                return false;
            }
        }

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="writer"></param>
        //public void Save ( XmlWriter writer )
        //{

        //}

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="reader"></param>
        ///// <returns></returns>
        //public static Group Load ( XmlReader reader )
        //{
        //    return null;
        //}
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Helpers;
using SmartTank.Draw.UI.Controls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TankEngine2D.Graphics;
using TankEngine2D.Input;
using SmartTank;
using SmartTank.Helpers.DependInject;
using SmartTank.Helpers;

namespace SmartTank.Screens
{

    class RuleSelectScreen : IGameScreen
    {
        Listbox rulesList;

        TextButton btn;

        int selectIndex = -1;

        public RuleSelectScreen()
        {
            BaseGame.ShowMouse = true;
            RuleLoader.Initial();
            string[] ruleLists = RuleLoader.GetRulesList();
            rulesList = new Listbox( "rulelist", new Vector2( 200, 150 ), new Point( 400, 300 ), Color.WhiteSmoke, Color.Green );
            foreach (string rulename in ruleLists)
            {
                rulesList.AddItem( rulename );
            }
            rulesList.OnChangeSelection += new EventHandler( rulesList_OnChangeSelection );
            btn = new TextButton( "OkBtn", new Vector2( 700, 500 ), "Begin", 0, Color.Blue );
            btn.OnClick += new EventHandler( btn_OnPress );
        }

        void btn_OnPress( object sender, EventArgs e )
        {
            if (selectIndex >= 0 && selectIndex <= rulesList.Items.Count)
            {
                GameManager.ComponentReset();
                GameManager.AddGameScreen( RuleLoader.CreateRuleInstance( selectIndex ) );
            }
        }

        void rulesList_OnChangeSelection( object sender, EventArgs e )
        {
            selectIndex = rulesList.selectedIndex;
        }

        #region IGameScreen ³ΙΤ±

        public bool Update( float second )
        {
            rulesList.Update();
            btn.Update();

            if (InputHandler.JustPressKey( Microsoft.Xna.Framework.Input.Keys.Escape ))
                return true;

            return false;
        }

        public void Render()
        {
            BaseGame.Device.Clear( Color.LightSkyBlue );
            rulesList.Draw( BaseGame.SpriteMgr.alphaSprite, 1 );
            btn.Draw( BaseGame.SpriteMgr.alphaSprite, 1 );
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.PhiCol;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework;

namespace SmartTank.GameObjs.Item
{
    public abstract class ItemStatic : IGameObj, ICollideObj, IColChecker
    {
        public event OnCollidedEventHandler OnCollide;
        public event OnCollidedEventHandler OnOverLap;

        protected SpriteColMethod colMethod;
        protected Sprite sprite;

        #region ICollideObj 成员

        public IColChecker ColChecker
        {
            get { return this; }
        }

        #endregion

        #region IGameObj 成员

        protected float azi;
        public float Azi
        {
            get { return azi; }
        }

        protected string mgPath;
        public string MgPath
        {
            get
            {
                return mgPath;
            }
            set
            {
                mgPath = value;
            }
        }

        protected string name;
        public string Name
        {
            get { return name; }
        }

        protected GameObjInfo objInfo;
        public GameObjInfo ObjInfo
        {
            get { return objInfo; }
        }

        protected Vector2 pos;
        public Microsoft.Xna.Framework.Vector2 Pos
        {
            get
            {
                return pos;
            }
            set
            {
                pos = value;
            }
        }

        #endregion

        #region IUpdater 成员

        public abstract void Update(float seconds);

        #endregion

        #region IDrawableObj 成员

        public abstract void Draw();

        #endregion

        #region IColChecker 成员

        public void ClearNextStatus()
        {
        }

        public IColMethod CollideMethod
        {
            get { return colMethod; }
        }

        public void HandleCollision(TankEngine2D.Graphics.CollisionResult result, ICollideObj objB)
        {
            if (OnCollide != null)
                OnCollide(this, result, (objB as IGameObj).ObjInfo);
        }

        public void HandleOverlap(TankEngine2D.Graphics.CollisionResult result, ICollideObj objB)
        {
            if (OnOverLap != null)
                OnOverLap(this, result, (objB as IGameObj).ObjInfo);
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace GameEngine.Draw
{
    public interface IDrawableObj
    {
        void Draw ();
        Vector2 Pos { get;}
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using GameEngine.Shelter;

namespace GameEngine.Senses.Vision
{
    public interface IEyeableObj
    {
        Vector2[] KeyPoints { get;}
        Matrix TransMatrix { get;}
        Vector2 Pos { get;}

        GetEyeableInfoHandler GetEyeableInfoHandler { get;set;}
    }

    public interface IEyeableInfo
    {
        Vector2 Pos { get;}
        Vector2[] CurKeyPoints { get;}
        Matrix CurTransMatrix { get;}
    }

    public class EyeableInfo : IEyeableInfo
    {
        Vector2 pos;
        Vector2[] curKeyPoints;
        Matrix curTransMatrix;

        static public IEyeableInfo GetEyeableInfoHandler ( IRaderOwner raderOwner, IEyeableObj obj )
        {
            return new EyeableInfo( obj );
        }

        public EyeableInfo ( IEyeableObj obj )
        {
            this.pos = obj.Pos;
            this.curTransMatrix = obj.TransMatrix;

            curKeyPoints = new Vector2[obj.KeyPoints.Length];
            for (int i = 0; i < obj.KeyPoints.Length; i++)
            {
                curKeyPoints[i] = Vector2.Transform( obj.KeyPoints[i], obj.TransMatrix );
            }
        }

        #region IEyeableInfo ³ΙΤ±

        public Vector2 Pos
        {
            get { return pos; }
        }

        public Vector2[] CurKeyPoints
        {
            get { return curKeyPoints; }
        }

        public Matrix CurTransMatrix
        {
            get { return curTransMatrix; }
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.CompilerServices;
using Microsoft.Xna.Framework;
using Common.DataStructure;
using Common.Helpers;


namespace GameEngine.Graphics
{
    /// <summary>
    /// 逻辑坐标与屏幕坐标之间转换的管理类
    /// </summary>
    public class CoordinMgr
    {
        #region Variables

        private Vector2 logicCenter;

        private Vector2 scrnCenter;

        private float rota;

        private Matrix rotaMatrix;
        private Matrix rotaMatrixInvert;


        private Rectangle gameViewRect;

        private float scale;

        #endregion

        #region Properties

        /// <summary>
        /// 获得绘制区在视口中的区域
        /// </summary>
        public Rectangle ScrnViewRect
        {
            get { return gameViewRect; }
        }

        /// <summary>
        /// 获得绘制区的宽度
        /// </summary>
        public int ViewWidth
        {
            get { return gameViewRect.Width; }
        }
        /// <summary>
        /// 获得绘制区的高度
        /// </summary>
        public int ViewHeight
        {
            get { return gameViewRect.Height; }
        }

        /// <summary>
        /// 获得一个屏幕像素的逻辑大小
        /// </summary>
        public Vector2 TexelSize
        {
            get { return new Vector2( 1 / scale, 1 / scale ); }
        }

        /// <summary>
        /// 获得或设置摄像机的方位角
        /// </summary>
        public float Rota
        {
            get { return rota; }
            set
            {
                this.rota = value;
                rotaMatrix = Matrix.CreateRotationZ( rota );
                rotaMatrixInvert = Matrix.CreateRotationZ( -rota );
            }
        }

        /// <summary>
        /// 获得或设置摄像机的缩放率（屏幕坐标/逻辑坐标）
        /// </summary>
        public float Scale
        {
            get { return scale; }
            set { scale = value; }
        }

        /// <summary>
        /// 获得或设置摄像机焦点的逻辑位置
        /// </summary>
        public Vector2 LogicCenter
        {
            get { return logicCenter; }
            set { logicCenter = value; }
        }

        /// <summary>
        /// 获得从逻辑坐标到屏幕坐标的旋转转换矩阵
        /// </summary>
        public Matrix RotaMatrixFromLogicToScrn
        {
            get { return rotaMatrixInvert; }
        }
        /// <summary>
        /// 获得从屏幕坐标到逻辑坐标的旋转转换矩阵
        /// </summary>
        public Matrix RotaMatrixFromScrnToLogic
        {
            get { return rotaMatrix; }
        }


        #endregion

        #region SetFunctions Called By Platform

        /// <summary>
        /// 设置绘制区域
        /// </summary>
        /// <param name="rect"></param>
        public void SetScreenViewRect ( Rectangle rect )
        {
            gameViewRect = rect;
            scrnCenter = new Vector2( rect.X + 0.5f * rect.Width, rect.Y + 0.5f * rect.Height );
        }

        /// <summary>
        /// 设置摄像机
        /// </summary>
        /// <param name="setScale">缩放率(屏幕坐标/逻辑坐标)</param>
        /// <param name="centerLogicPos">摄像机焦点所在逻辑位置</param>
        /// <param name="setRota">设置摄像机的旋转角</param>
        public void SetCamera ( float setScale, Vector2 centerLogicPos, float setRota )
        {
            scale = setScale;
            rota = setRota;
            rotaMatrix = Matrix.CreateRotationZ( rota );
            rotaMatrixInvert = Matrix.CreateRotationZ( -rota );
            logicCenter = centerLogicPos;
        }

        #endregion

        #region HelpFunctions

        /// <summary>
        /// 将屏幕长度转换到逻辑长度
        /// </summary>
        /// <param name="scrnLength"></param>
        /// <returns></returns>
        public float LogicLength ( int scrnLength )
        {
            return scrnLength / scale;
        }
        /// <summary>
        /// 将屏幕长度转换到逻辑长度
        /// </summary>
        /// <param name="scrnLength"></param>
        /// <returns></returns>
        public float LogicLength ( float scrnLength )
        {
            return scrnLength / scale;
        }
        /// <summary>
        /// 将逻辑长度转换到屏幕长度
        /// </summary>
        /// <param name="logicLength"></param>
        /// <returns></returns>
        public int ScrnLength ( float logicLength )
        {
            return MathTools.Round( logicLength * scale );
        }
        /// <summary>
        /// 将逻辑长度转换到屏幕长度
        /// </summary>
        /// <param name="logicLength"></param>
        /// <returns></returns>
        public float ScrnLengthf ( float logicLength )
        {
            return logicLength * scale;
        }

        /// <summary>
        /// 将屏幕位置转换到逻辑位置
        /// </summary>
        /// <param name="screenPos"></param>
        /// <returns></returns>
        public Vector2 LogicPos ( Vector2 screenPos )
        {
            return Vector2.Transform( screenPos - scrnCenter, rotaMatrix ) / scale + logicCenter;
        }
        /// <summary>
        /// 将逻辑位置转换到屏幕位置
        /// </summary>
        /// <param name="logicPos"></param>
        /// <returns></returns>
        public Vector2 ScreenPos ( Vector2 logicPos )
        {
            return Vector2.Transform( logicPos - logicCenter, rotaMatrixInvert ) * scale + scrnCenter;
        }

        /// <summary>
        /// 将屏幕向量转换到逻辑向量
        /// </summary>
        /// <param name="screenVector"></param>
        /// <returns></returns>
        public Vector2 LogicVector ( Vector2 screenVector )
        {
            return new Vector2( LogicLength( screenVector.X ), LogicLength( screenVector.Y ) );
        }

        #endregion

        /// <summary>
        /// 在逻辑坐标中平移摄像机
        /// </summary>
        /// <param name="delta"></param>
        public void MoveCamera ( Vector2 delta )
        {
            logicCenter += delta;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.GameObjs;
using TankEngine2D.DataStructure;
using SmartTank.PhiCol;
using SmartTank.Shelter;
using SmartTank.Draw;
using SmartTank.Update;
using SmartTank.Senses.Vision;
using EyeableSet = System.Collections.Generic.KeyValuePair<SmartTank.Senses.Vision.IEyeableObj, SmartTank.Senses.Vision.GetEyeableInfoHandler>;

namespace SmartTank.Scene
{
    /*
     * 一个场景数据储存类。
     * 
     * 具体化碰撞关系和遮挡关系。适用一般情况。
     * 
     * */
    [Obsolete( "该场景管理类的设计存在问题，将要删除" )]
    public class SceneKeeperCommon : ISceneKeeper
    {
        #region Keepers

        /// <summary>
        /// 场景物体集，用于统一调用Updata函数和绘制函数。
        /// </summary>
        MultiLinkedList<IGameObj> SenceObjs = new MultiLinkedList<IGameObj>();

        /// <summary>
        /// 物理更新物体集，用于物理更新和碰撞组件（PhiColManager）。
        /// </summary>
        MultiLinkedList<IPhisicalObj> phisicalObjs = new MultiLinkedList<IPhisicalObj>();

        /*
         * 遮挡关系方面，暂且只定义一种类型的雷达——坦克雷达。
         * 
         * */

        /// <summary>
        /// 坦克雷达的所有者集。
        /// </summary>
        MultiLinkedList<IRaderOwner> tankRaderOwners = new MultiLinkedList<IRaderOwner>();

        /// <summary>
        /// 遮挡坦克雷达的物体集。
        /// </summary>
        MultiLinkedList<IShelterObj> tankRaderShelters = new MultiLinkedList<IShelterObj>();


        /*
         * 按场景层次具体化碰撞关系。
         * 
         * 
         * 碰撞关系如下所示：
         * 
         *              凹陷        低突出      高突出      低空        高空        边界        
         * ———————————————————————————————————————
         * 凹陷                     碰撞        碰撞                    
         * ———————————————————————————————————————
         * 低突出       碰撞                    碰撞        
         * ———————————————————————————————————————
         * 高突出       碰撞        碰撞        碰撞        碰撞        重叠        碰撞
         * ———————————————————————————————————————
         * 低空                                 碰撞                    重叠        重叠
         * ———————————————————————————————————————
         * 高空                                 重叠        重叠                        
         * ———————————————————————————————————————
         * 边界                                 碰撞        重叠       
         * ———————————————————————————————————————
         * 
         * 
         * 其中，坦克属于高突出，而炮弹属于低空物体，场景交互物体可以放置在高空物体中。
         * 
         * 地形限制物体依据被限制的对象分别放置在凹陷、低突出和高突出中。
         * 
         * 
         * 这些关系是可以在SenceKeeper的继承类中修改的。
         * 
         * */


        /// <summary>
        /// 凹陷物体集。
        /// </summary>
        MultiLinkedList<ICollideObj> concaveObjs = new MultiLinkedList<ICollideObj>();

        /// <summary>
        /// 低突出物体集。
        /// </summary>
        MultiLinkedList<ICollideObj> lowBulgeObjs = new MultiLinkedList<ICollideObj>();

        /// <summary>
        /// 高突出物体集。
        /// </summary>
        MultiLinkedList<ICollideObj> highBulgeObjs = new MultiLinkedList<ICollideObj>();

        /// <summary>
        /// 低空物体集。
        /// </summary>
        MultiLinkedList<ICollideObj> lowFlyingObjs = new MultiLinkedList<ICollideObj>();

        /// <summary>
        /// 高空物体集
        /// </summary>
        MultiLinkedList<ICollideObj> highFlyingObjs = new MultiLinkedList<ICollideObj>();



        /// <summary>
        /// 场景边界。
        /// </summary>
        Border border;

        /// <summary>
        /// 对坦克可见物
        /// </summary>
        Dictionary<IEyeableObj, GetEyeableInfoHandler> visibleObjs = new Dictionary<IEyeableObj, GetEyeableInfoHandler>();

        #endregion

        int assignedID = -1;

        #region RegistGroups

        public void RegistPhiCol ( PhiColMgr manager )
        {
            ICollideObj[] boders = new ICollideObj[] { border };

            manager.AddPhiGroup( phisicalObjs );

            manager.AddCollideGroup( concaveObjs, lowBulgeObjs );
            manager.AddCollideGroup( concaveObjs, highBulgeObjs );
            manager.AddCollideGroup( lowBulgeObjs, highBulgeObjs );
            manager.AddCollideGroup( highBulgeObjs );
            manager.AddCollideGroup( highBulgeObjs, lowFlyingObjs );
            manager.AddOverlapGroup( highBulgeObjs, highFlyingObjs );
            manager.AddCollideGroup( highBulgeObjs, boders );
            manager.AddOverlapGroup( lowFlyingObjs, boders );
        }

        public void RegistShelter ( ShelterMgr manager )
        {
            manager.AddRaderShelterGroup( tankRaderOwners, new MultiLinkedList<IShelterObj>[] { tankRaderShelters } );
        }

        public void RegistDrawables ( DrawManager manager )
        {
            manager.AddGroup( SenceObjs.GetConvertList<IDrawableObj>() );
        }

        public void RegistUpdaters ( UpdateMgr manager )
        {
            manager.AddGroup( SenceObjs.GetConvertList<IUpdater>() );
        }

        public void RegistVision ( VisionMgr manager )
        {
            manager.AddVisionGroup( tankRaderOwners, visibleObjs );
        }

        #endregion

        #region Add && Remove Obj

        /// <summary>
        /// 定义场景的不同层。
        /// </summary>
        public enum GameObjLayer
        {
            /// <summary>
            /// 凹陷物体
            /// </summary>
            Convace,
            /// <summary>
            /// 低突出物体
            /// </summary>
            LowBulge,
            /// <summary>
            /// 高突出物体
            /// </summary>
            HighBulge,
            /// <summary>
            /// 低空物体
            /// </summary>
            lowFlying,
            /// <summary>
            /// 高空物体
            /// </summary>
            highFlying
        }

        public void AddGameObj ( IGameObj obj, bool asPhi, bool asShe, bool asRaderOwner, GameObjLayer layer )
        {
            if (obj == null)
                throw new NullReferenceException( "GameObj is null!" );

            if (asPhi && !(obj is IPhisicalObj))
                throw new Exception( "obj isn't a IPhisicalObj!" );
            if (!(obj is ICollideObj))
                throw new Exception( "obj isn't a ICollideObj!" );
            if (asShe && !(obj is IShelterObj))
                throw new Exception( "obj isn't a IShelterObj!" );
            if (asRaderOwner && !(obj is IRaderOwner))
                throw new Exception( "obj isn't a IRaderOwner!" );


            SenceObjs.AddLast( obj );

            if (asPhi)
                phisicalObjs.AddLast( (IPhisicalObj)obj );
            if (asShe)
                tankRaderShelters.AddLast( (IShelterObj)obj );
            if (asRaderOwner)
                tankRaderOwners.AddLast( (IRaderOwner)obj );


            if (layer == GameObjLayer.Convace)
                concaveObjs.AddLast( (ICollideObj)obj );
            else if (layer == GameObjLayer.LowBulge)
                lowBulgeObjs.AddLast( (ICollideObj)obj );
            else if (layer == GameObjLayer.HighBulge)
                highBulgeObjs.AddLast( (ICollideObj)obj );
            else if (layer == GameObjLayer.lowFlying)
                lowFlyingObjs.AddLast( (ICollideObj)obj );
            else if (layer == GameObjLayer.highFlying)
                highFlyingObjs.AddLast( (ICollideObj)obj );

            assignedID++;
            obj.ObjInfo.SetID( assignedID );

            //bool isTankObstacle = layer == GameObjLayer.HighBulge || layer == GameObjLayer.Convace || layer == GameObjLayer.LowBulge;
            //obj.ObjInfo.SetSceneInfo( new SceneCommonObjInfo( asShe, isTankObstacle ) );

        }

        public void AddGameObj ( IGameObj obj, bool asPhi, bool asShe, bool asRaderOwner, GameObjLayer layer, GetEyeableInfoHandler getEyeableInfo )
        {
            AddGameObj( obj, asPhi, asShe, asRaderOwner, layer );

            visibleObjs.Add( (IEyeableObj)obj, getEyeableInfo );
        }

        public void RemoveGameObj ( IGameObj obj, bool asPhi, bool asShe, bool asRaderOwner, bool asEyeable, GameObjLayer layer )
        {
            if (obj == null)
                throw new NullReferenceException( "GameObj is null!" );

            if (asPhi && !(obj is IPhisicalObj))
                throw new Exception( "obj isn't a IPhisicalObj!" );
            if (!(obj is ICollideObj))
                throw new Exception( "obj isn't a ICollideObj!" );
            if (asShe && !(obj is IShelterObj))
                throw new Exception( "obj isn't a IShelterObj!" );
            if (asRaderOwner && !(obj is IRaderOwner))
                throw new Exception( "obj isn't a IRaderOwner!" );
            if (asEyeable && !(obj is IEyeableObj))
                throw new Exception( "obj isn't a IEyeableObj!" );

            SenceObjs.Remove( obj );

            if (asPhi)
                phisicalObjs.Remove( (IPhisicalObj)obj );
            if (asShe)
                tankRaderShelters.Remove( (IShelterObj)obj );
            if (asRaderOwner)
                tankRaderOwners.Remove( (IRaderOwner)obj );

            if (layer == GameObjLayer.Convace)
                concaveObjs.Remove( (ICollideObj)obj );
            else if (layer == GameObjLayer.LowBulge)
                lowBulgeObjs.Remove( (ICollideObj)obj );
            else if (layer == GameObjLayer.HighBulge)
                highBulgeObjs.Remove( (ICollideObj)obj );
            else if (layer == GameObjLayer.lowFlying)
                lowFlyingObjs.Remove( (ICollideObj)obj );
            else if (layer == GameObjLayer.highFlying)
                highFlyingObjs.Remove( (ICollideObj)obj );

            if (asEyeable)
            {
                visibleObjs.Remove( (IEyeableObj)obj );
            }

        }

        #endregion

        #region SetBorder

        public void SetBorder ( float minX, float minY, float maxX, float maxY )
        {
            border = new Border( minX, minY, maxX, maxY );
        }

        public void SetBorder ( Rectanglef mapBorder )
        {
            border = new Border( mapBorder.X, mapBorder.Y, mapBorder.X + mapBorder.Width, mapBorder.Y + mapBorder.Height );
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using TankEngine2D.DataStructure;
using TankEngine2D.Graphics;

namespace SmartTank.Shelter
{
    public interface IHasBorderObj
    {
        CircleList<BorderPoint> BorderData { get;}
        
        /// <summary>
        /// 暂时定义为贴图坐标到屏幕坐标的转换，当改写Coordin类以后修该为贴图坐标到逻辑坐标的转换。
        /// </summary>
        Matrix WorldTrans { get;}

        Rectanglef BoundingBox { get;}
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using System.IO;
using TankEngine2D.Helpers;

namespace SmartTank.GameObjs.Tank.SinTur
{
    struct TankSkinSinTurData
    {
        #region Old Code

        //public static TankSkinSinTurData M1A2 = new TankSkinSinTurData(
        //    "M1A2\\base", "M1A2\\turret", 0.1f,
        //    new Vector2( 43, 100 ), new Vector2( 43, 100 ), new Vector2( 38, 145 ), 145,
        //    3, 7, 2 );

        //public static TankSkinSinTurData Tiger = new TankSkinSinTurData(
        //    "Tiger\\base", "Tiger\\turret", 0.12f,
        //    new Vector2( 36, 59 ), new Vector2( 36, 62 ), new Vector2( 21, 101 ), 101, 3, 7, 2 );

        //public static TankSkinSinTurData M60 = new TankSkinSinTurData(
        //    "M60\\base", "M60\\turret", 0.1f,
        //    new Vector2( 41, 81 ), new Vector2( 41, 68 ), new Vector2( 35, 131 ), 131, 3, 7, 2 );

        //public static TankSkinSinTurData M1A2 = CreateM1A2();

        //public static TankSkinSinTurData Tiger = CreateTiger();

        //public static TankSkinSinTurData M60 = CreateM60();

        //private static TankSkinSinTurData CreateM1A2 ()
        //{
        //    string path = Path.Combine( Directories.ItemDirectory, "Internal\\M1A2" );
        //    GameObjData data = GameObjData.Load( File.OpenRead( Path.Combine( path, "M1A2.xml" ) ) );

        //    return new TankSkinSinTurData( path, data );
        //}

        //private static TankSkinSinTurData CreateTiger ()
        //{
        //    string path = Path.Combine( Directories.ItemDirectory, "Internal\\Tiger" );
        //    GameObjData data = GameObjData.Load( File.OpenRead( Path.Combine( path, "Tiger.xml" ) ) );

        //    return new TankSkinSinTurData( path, data );
        //}

        //private static TankSkinSinTurData CreateM60 ()
        //{
        //    string path = Path.Combine( Directories.ItemDirectory, "Internal\\M60" );
        //    GameObjData data = GameObjData.Load( File.OpenRead( Path.Combine( path, "M60.xml" ) ) );

        //    return new TankSkinSinTurData( path, data );
        //}

        #endregion

        #region Variables

        readonly public string baseTexPath;
        readonly public string turretTexPath;

        /// <summary>
        /// Âß¼­³ß´ç/Ô­Í¼³ß´ç
        /// </summary>
        readonly public float texScale;

        readonly public Vector2 baseTexOrigin;
        readonly public Vector2 turretAxesPos;
        readonly public Vector2 turretTexOrigin;
        readonly public float TurretTexels;

        readonly public float recoilTexels;

        readonly public int backFrame;
        readonly public int recoilFrame;

        readonly public Vector2[] visiKeyPoints;

        //readonly public string texPath;

        #endregion

        #region Construction
        public TankSkinSinTurData ( string baseTexPath, string turretTexPath, float texScale,
            Vector2 baseTexOrigin, Vector2 turretAxesPos, Vector2 turretTexOrigin,
            float TurretTexels, Vector2[] visiKeyPoints, int backFrame, int recoilFrame, float recoilTexels )
        {
            this.baseTexPath = baseTexPath;
            this.turretTexPath = turretTexPath;
            this.texScale = texScale;
            this.baseTexOrigin = baseTexOrigin;
            this.turretAxesPos = turretAxesPos;
            this.turretTexOrigin = turretTexOrigin;
            this.TurretTexels = TurretTexels;
            this.recoilTexels = recoilTexels;
            this.backFrame = backFrame;
            this.recoilFrame = recoilFrame;
            this.visiKeyPoints = visiKeyPoints;
        }

        public TankSkinSinTurData ( string texPath, GameObjData data )
            : this( Path.Combine( texPath, data.baseNode.texPaths[0] ), Path.Combine( texPath, data.baseNode.childNodes[0].texPaths[0] ), data.baseNode.floatDatas[0],
            data.baseNode.structKeyPoints[0], data.baseNode.structKeyPoints[1], data.baseNode.childNodes[0].structKeyPoints[0],
            data.baseNode.childNodes[0].structKeyPoints[0].Y, data.baseNode.visiKeyPoints.ToArray(), 3, 7, data.baseNode.intDatas[0] )
        {

        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using SmartTank.AI.AIHelper;
using TankEngine2D.Input;

namespace SmartTank.AI
{
    [AIAttribute( "ManualControl", "SmartTank Team", "manualControl for test", 2007, 10, 25 )]
    public class ManualControl : IAISinTur
    {
        IAIOrderServerSinTur orderServer;

        AIActionHelper action;

        #region IAI 成员

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = (IAIOrderServerSinTur)value;
                action = new AIActionHelper( orderServer );
            }
        }

        public IAICommonServer CommonServer
        {
            set { }
        }

        #endregion

        #region IUpdater 成员

        public void Update( float seconds )
        {
            if (InputHandler.IsKeyDown( Keys.W ))
            {
                orderServer.ForwardSpeed = 1000;
            }
            else if (InputHandler.IsKeyDown( Keys.S ))
            {
                orderServer.ForwardSpeed = -1000;
            }
            else
            {
                orderServer.ForwardSpeed = 0;
            }

            if (InputHandler.IsKeyDown( Keys.D ))
            {
                orderServer.TurnRightSpeed = 20;
            }
            else if (InputHandler.IsKeyDown( Keys.A ))
            {
                orderServer.TurnRightSpeed = -20;
            }
            else
            {
                orderServer.TurnRightSpeed = 0;
            }

            action.AddOrder( new OrderRotaTurretToPos( InputHandler.GetCurMousePosInLogic( BaseGame.RenderEngine ) ) );

            //if (InputHandler.IsKeyDown( Keys.K ))
            //{
            //    tankContr.TurnTurretWiseSpeed = 20;
            //}
            //else if (InputHandler.IsKeyDown( Keys.J ))
            //{
            //    tankContr.TurnTurretWiseSpeed = -20;
            //}
            //else
            //{
            //    tankContr.TurnTurretWiseSpeed = 0;
            //}



            if (InputHandler.JustPressKey( Keys.Space ) ||
                InputHandler.MouseJustPressLeft)
            {
                orderServer.Fire();
            }

            if (InputHandler.IsKeyDown( Keys.M ))
            {
                orderServer.TurnRaderWiseSpeed = 20;
            }

            if (InputHandler.IsKeyDown( Keys.N ))
            {
                orderServer.TurnRaderWiseSpeed = -20;
            }

            if (InputHandler.MouseJustPressRight)
            {
                action.AddOrder( new OrderRotaRaderToPos( InputHandler.GetCurMousePosInLogic( BaseGame.RenderEngine ) ) );
            }

            if (InputHandler.MouseWheelDelta != 0)
            {
                action.AddOrder( new OrderRotaRaderToAzi( orderServer.RaderAimAzi - (float)InputHandler.MouseWheelDelta / 300 ) );
            }

            // test

            if (InputHandler.JustPressKey( Keys.Y ))
            {
                //action.AddOrder( new OrderRotaRaderToAng( MathHelper.PiOver4 ) );
                action.AddOrder( new OrderScanRaderAzi( MathHelper.PiOver4, -MathHelper.PiOver4, 0, true ) );
            }

            action.Update( seconds );
        }

        #endregion


        #region IAI 成员


        public void Draw()
        {

        }

        #endregion
    }
}
<file_sep>/************************************************************
FileName: GameProtocal.h
Author:   DD.Li     Version :   1.0       Date:2009-4-6
Description: 游戏协议
***********************************************************/
#ifndef _GAMEPROTOCAL_H_
#define _GAMEPROTOCAL_H_

#include "head.h"
#include "mysocket.h"
#include "ClientManager.h"
#include "MyDataBase.h"
#include "MyRoom.h"
class ClientManager;

class GameProtocal
{
public:
    GameProtocal();
    ~GameProtocal();
    void AttachManager( ClientManager* pMgr){// 添加管理者
        pManager = pMgr;
    }	
    /*  发送给所有人，包括自己    */
    bool SendToAll(MySocket* pSockClient, Packet &pack);

    /*  发送给pSockClient玩家    */
    bool SendToOne(MySocket* pSockClient, Packet &pack);

    /*  发送给其他玩家    */
    bool SendToOthers(MySocket* pSockClient, Packet &pack);

    /*  发送包头    */
    bool SendHead(MySocket* pSockClient, PacketHead &packHead);

    /*  正常游戏数据    */
    bool SendGameData(MySocket *pSockClient, Packet &pack);

    /*  用户注册    */
    bool UserRegist(MySocket *pSockClient, Packet &pack);

    /*  用户登录    */
    bool UserLogin(MySocket *pSockClient, Packet &pack);

    /*  用户自己信息    */
    bool MyInfo(MySocket *pSockClient, Packet &pack);

    /*  用户列表    */
    bool ListUser(MySocket *pSockClient, Packet &pack);

    /*  排行列表    */
    bool ListRank(MySocket *pSockClient, Packet &pack);

    /*  创建房间    */
    bool CreateRoom(MySocket *pSockClient, Packet &pack);

    /*  刷新房间    */
    bool ListRoom(MySocket *pSockClient, Packet &pack);

    /*  进入房间 */
    bool EnterRoom(MySocket *pSockClient, Packet &pack);

    /*  离开房间 */
    bool ExitRoom(MySocket *pSockClient, Packet &pack);

    /*  游戏开始 */
    bool GameGo(MySocket *pSockClient, Packet &pack);

    /*  保存游戏结果到数据库 */
    bool SaveGameResult(MySocket *pSockClient, Packet &pack);

    /* 用户离开 */
    bool UserExit(MySocket *pSockClient);

    Team5_DB    m_SQL;       // 数据库   
private:
    ClientManager *pManager; // 管理者    
    static long m_recvPackNum;
    ofstream outLog;
};


#endif









<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace SmartTank.Effects.Particles
{
    public delegate Vector2 PosGroupFunc( float curPartiTime, Vector2 lastPos, Vector2 dir, int No );

    public delegate Vector2 DirGroupFunc( float curPartiTime, Vector2 lastDir, int No );

    public delegate float RadiusGroupFunc( float curPartiTime, float lastRadius, int No );

    public delegate Color ColorGroupFunc( float curPartiTime, Color lastColor, int No );

    public delegate int CreateSumFunc( float curTime );

    public class ParticleSystem
    {
        #region Variables

        Texture2D tex;

        Vector2 texOrigin;

        Nullable<Rectangle> sourceRect;

        float layerDepth;

        CreateSumFunc createSumFunc;

        PosGroupFunc posGroupFunc;

        DirGroupFunc dirGroupFunc;

        RadiusGroupFunc radiusGroupFunc;

        ColorGroupFunc colorGroupFunc;

        List<Particle> particles;

        float curTime = -1;

        float duration;
        float partiDura;

        Vector2 basePos;

        #endregion

        public Vector2 BasePos
        {
            get { return basePos; }
            set { basePos = value; }
        }

        public ParticleSystem( float duration, float partiDuration, Vector2 basePos,
            Texture2D tex, Vector2 texOrigin, Nullable<Rectangle> sourceRect, float layerDepth,
            CreateSumFunc createSumFunc, PosGroupFunc posGroupFunc, DirGroupFunc dirGroupFunc,
            RadiusGroupFunc radiusGroupFunc, ColorGroupFunc colorGroupFunc )
        {
            this.tex = tex;
            this.texOrigin = texOrigin;
            this.sourceRect = sourceRect;
            this.layerDepth = layerDepth;
            this.createSumFunc = createSumFunc;
            this.posGroupFunc = posGroupFunc;
            this.dirGroupFunc = dirGroupFunc;
            this.radiusGroupFunc = radiusGroupFunc;
            this.colorGroupFunc = colorGroupFunc;

            this.duration = duration;
            this.partiDura = partiDuration;
            this.basePos = basePos;

            this.particles = new List<Particle>();

        }

        #region Updates

        public bool Update()
        {
            curTime++;

            if (duration != 0 && curTime > duration)
                return true;

            CreateNewParticle();

            UpdateParticles();

            return false;
        }

        private void UpdateParticles()
        {
            foreach (Particle particle in particles)
            {
                particle.Update();
            }
        }

        private void CreateNewParticle()
        {
            int createSum = createSumFunc( curTime );

            int preCount = particles.Count;

            for (int i = 0; i < createSum; i++)
            {
                particles.Add( new Particle( partiDura, basePos, layerDepth,
                    delegate( float curParticleTime, Vector2 lastPos, Vector2 dir )
                    {
                        return posGroupFunc( curParticleTime, lastPos, dir, preCount + i );
                    },
                    delegate( float curParticleTime, Vector2 lastDir )
                    {
                        return dirGroupFunc( curParticleTime, lastDir, preCount + i );
                    },
                    delegate( float curParticleTime, float lastRadius )
                    {
                        return radiusGroupFunc( curParticleTime, lastRadius, preCount + i );
                    },
                    tex, texOrigin, sourceRect,
                    delegate( float curParticleTime, Color lastColor )
                    {
                        return colorGroupFunc( curParticleTime, lastColor, preCount + i );
                    } ) );
            }
        }

        #endregion

        #region IDrawableObj ³ΙΤ±

        public void Draw()
        {
            foreach (Particle parti in particles)
            {
                parti.Draw();
            }
        }

        #endregion

        #region IDrawableObj ³ΙΤ±


        public Vector2 Pos
        {
            get { return BasePos; }
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Storage;
using System.IO;

namespace SmartTank.Helpers
{
    public static class Directories
    {
        #region Game base directory
        public static readonly string GameBaseDirectory =
            StorageContainer.TitleLocation;

        #endregion

        #region Directories

        public static string ContentDirectory
        {
            get { return Path.Combine( GameBaseDirectory, "Content" ); }
        }

        public static string BasicGraphicsContent
        {
            get { return Path.Combine( ContentDirectory, "BasicGraphics" ); }
        }

        public static string FontContent
        {
            get { return Path.Combine( ContentDirectory, "Font" ); }
        }

        public static string UIContent
        {
            get { return Path.Combine( ContentDirectory, "UI" ); }
        }

        public static string TankTexture
        {
            get { return Path.Combine( ContentDirectory, "Tanks" ); }
        }

        public static string SoundDirectory
        {
            get { return Path.Combine( GameBaseDirectory, "Content\\Sounds" ); }
        }

        public static string AIDirectory
        {
            get { return Path.Combine( GameBaseDirectory, "AI" ); }
        }

        public static string MapDirectory
        {
            get { return Path.Combine( GameBaseDirectory, "Map" ); }
        }

        public static string GameObjsDirectory
        {
            get { return Path.Combine( GameBaseDirectory, "GameObjs" ); }
        }

        #endregion

        #region FilePath

        public static string AIListFilePath
        {
            get { return Path.Combine( AIDirectory, "AIList.txt" ); }
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.GameObjs
{
    [AttributeUsage( AttributeTargets.Property, Inherited = false )]
    public class EditableProperty : Attribute
    {
        public EditableProperty ()
        {

        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace GameEngine.Graphics
{
    /// <summary>
    /// 表示碰撞检测的结果
    /// </summary>
    public class CollisionResult
    {
        /// <summary>
        /// 是否存在碰撞
        /// </summary>
        public bool IsCollided;

        /// <summary>
        /// 碰撞位置，逻辑坐标
        /// </summary>
        public Vector2 InterPos;

        /// <summary>
        /// 碰撞单位法向量，指向自身
        /// </summary>
        public Vector2 NormalVector;

        /// <summary>
        /// 空构造函数
        /// </summary>
        public CollisionResult ()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="isCollided">是否发生碰撞</param>
        public CollisionResult ( bool isCollided )
        {
            this.IsCollided = isCollided;
        }

        /// <summary>
        /// 发生了碰撞情况下的构造函数
        /// </summary>
        /// <param name="interPos">碰撞位置，逻辑坐标</param>
        /// <param name="normalVector">碰撞单位法向量，指向自身</param>
        public CollisionResult ( Vector2 interPos, Vector2 normalVector )
        {
            IsCollided = true;
            InterPos = interPos;
            NormalVector = normalVector;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="isCollided">是否发生碰撞</param>
        /// <param name="interPos">碰撞位置，逻辑坐标</param>
        /// <param name="nornalVector">碰撞单位法向量，指向自身</param>
        public CollisionResult ( bool isCollided, Vector2 interPos, Vector2 nornalVector )
        {
            this.IsCollided = isCollided;
            this.InterPos = interPos;
            this.NormalVector = nornalVector;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework;
using TankEngine2D.DataStructure;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.GameObjs;

namespace SmartTank.PhiCol
{
    /// <summary>
    /// 场景边界
    /// </summary>
    public class Border : ICollideObj, IGameObj
    {
        Rectanglef borderRect;
        BorderChecker colChecker;

        GameObjInfo objInfo;

        /// <summary>
        /// 获得场景边界的范围
        /// </summary>
        public Rectanglef BorderRect
        {
            get { return borderRect; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="minX">边界的最小X坐标</param>
        /// <param name="minY">边界的最小Y坐标</param>
        /// <param name="maxX">边界的最大X坐标</param>
        /// <param name="maxY">边界的最大Y坐标</param>
        public Border( float minX, float minY, float maxX, float maxY )
            : this( new Rectanglef( minX, minY, maxX - minX, maxY - minY ) )
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="borderRect">边界矩形</param>
        public Border( Rectanglef borderRect )
        {
            this.borderRect = borderRect;
            colChecker = new BorderChecker( borderRect );
            objInfo = new GameObjInfo( "Border", "" );
        }

        #region ICollider 成员

        /// <summary>
        /// 获得冲突检查者
        /// </summary>
        public IColChecker ColChecker
        {
            get { return (IColChecker)colChecker; }
        }

        #endregion

        #region IGameObj 成员

        public GameObjInfo ObjInfo
        {
            get { return objInfo; }
        }

        public Vector2 Pos
        {
            get
            {
                return new Vector2( borderRect.X + borderRect.Width * 0.5f, borderRect.Y + borderRect.Height * 0.5f );
            }
            set
            {

            }
        }

        public float Azi
        {
            get { return 0; }
        }

        #endregion

        #region IUpdater 成员

        public void Update( float seconds )
        {

        }

        #endregion

        #region IDrawableObj 成员

        public void Draw()
        {

        }

        #endregion



        #region IGameObj 成员

        public string Name
        {
            get { return "Border"; }
        }

        #endregion
    }

    /// <summary>
    /// 边界对象的冲突检测方法
    /// </summary>
    public class BorderMethod : IColMethod
    {
        Rectanglef borderRect;

        #region IColMethod 成员

        /// <summary>
        /// 检测与另一对象是否冲突
        /// </summary>
        /// <param name="colB"></param>
        /// <returns></returns>
        public CollisionResult CheckCollision( IColMethod colB )
        {
            return colB.CheckCollisionWithBorder( this );
        }

        /// <summary>
        /// 检测与精灵对象是否冲突
        /// </summary>
        /// <param name="spriteChecker"></param>
        /// <returns></returns>
        public CollisionResult CheckCollisionWithSprites( SpriteColMethod spriteChecker )
        {

            foreach (Sprite sprite in spriteChecker.ColSprites)
            {
                CollisionResult result = sprite.CheckOutBorder( borderRect );
                if (result.IsCollided)
                {
                    float originX = result.NormalVector.X;
                    float originY = result.NormalVector.Y;

                    float x, y;

                    if (Math.Abs( originX ) > 0.5)
                        x = 1;
                    else
                        x = 0;
                    if (Math.Abs( originY ) > 0.5)
                        y = 1;
                    else
                        y = 0;

                    x *= Math.Sign( originX );
                    y *= Math.Sign( originY );


                    return new CollisionResult( result.InterPos, new Vector2( x, y ) );
                }
            }
            return new CollisionResult( false );
        }

        /// <summary>
        /// 检测与边界对象是否冲突，该方法无效
        /// </summary>
        /// <param name="Border"></param>
        /// <returns></returns>
        public CollisionResult CheckCollisionWithBorder( BorderMethod Border )
        {
            throw new Exception( "The method or operation is not implemented." );
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="borderRect">边界矩形</param>
        public BorderMethod( Rectanglef borderRect )
        {
            this.borderRect = borderRect;
        }

    }

    /// <summary>
    /// 边界对象的冲突检查者
    /// </summary>
    public class BorderChecker : IColChecker
    {
        BorderMethod method;

        #region IColChecker 成员

        /// <summary>
        /// 
        /// </summary>
        public IColMethod CollideMethod
        {
            get { return method; }
        }

        /// <summary>
        /// 处理碰撞，空函数
        /// </summary>
        /// <param name="result"></param>
        /// <param name="objB"></param>
        public void HandleCollision( CollisionResult result, ICollideObj objB )
        {

        }

        /// <summary>
        /// 处理重叠，空函数
        /// </summary>
        /// <param name="result"></param>
        /// <param name="objB"></param>
        public void HandleOverlap( CollisionResult result, ICollideObj objB )
        {

        }

        /// <summary>
        /// 撤销下一个物理状态，空函数
        /// </summary>
        public void ClearNextStatus()
        {

        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="borderRect">边界矩形</param>
        public BorderChecker( Rectanglef borderRect )
        {
            method = new BorderMethod( borderRect );
        }

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace GameEngine.PhiCol
{
    /// <summary>
    /// 表示一个物理更新器
    /// </summary>
    public interface IPhisicalUpdater
    {
        /// <summary>
        /// 计算下一个物理状态，并不生效
        /// </summary>
        /// <param name="seconds"></param>
        void CalNextStatus ( float seconds );

        /// <summary>
        /// 生效下一个物理状态
        /// </summary>
        void Validated ();
    }

    /// <summary>
    /// 表示一个能更新物理状态的物体
    /// </summary>
    public interface IPhisicalObj
    {
        /// <summary>
        /// 获得物理状态更新器
        /// </summary>
        IPhisicalUpdater PhisicalUpdater { get;}
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Graphics;
using TankEngine2D.DataStructure;
using Microsoft.Xna.Framework;
using SmartTank.GameObjs;

namespace SmartTank.Shelter
{
    /* 
     * 实现方式相对单一，所以姑且与检测方法耦合了。
     * 
     * */

    public interface IShelterObj : IHasBorderObj
    {
        GameObjInfo ObjInfo { get;}
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.IO;
using SmartTank.Rule;
using SmartTank.Screens;
using SmartTank.AI;
using SmartTank.GameObjs.Tank.SinTur;
using SmartTank.Effects.SceneEffects;
using SmartTank.GameObjs;
using SmartTank.Draw.UI.Controls;
using SmartTank.Helpers.DependInject;
using TankEngine2D.DataStructure;
using SmartTank.Scene;
using SmartTank.Draw;
using SmartTank.Draw.BackGround.VergeTile;
using SmartTank.GameObjs.Tank;
using TankEngine2D.Graphics;
using SmartTank;
using InterRules.ShootTheBall;
using TankEngine2D.Input;
using SmartTank.GameObjs.Shell;
using SmartTank.Helpers;
using TankEngine2D.Helpers;
using SmartTank.Senses.Vision;
using SmartTank.Update;
using SmartTank.Effects.TextEffects;
using SmartTank.Sounds;
using System.Windows.Forms;
using SmartTank.Effects;
using SmartTank.net;

namespace InterRules.Duel
{

    [RuleAttribute("DuelNet", "两个坦克在空旷的场景中搏斗（网络版）", "SmartTank编写组", 2009, 3, 30)]
    public class DuelNetRule : IGameRule
    {
        #region Variables

        Combo AIListForTank1;
        Combo AIListForTank2;
        SmartTank.Draw.UI.Controls.Checkbox CheckBoxIsHost;
        TextButton btn;

        int selectIndexTank1;
        int selectIndexTank2;

        AILoader aiLoader;

        #endregion

        #region IGameRule 成员

        public string RuleName
        {
            get { return "DuelNet"; }
        }

        public string RuleIntroduction
        {
            get { return "两个坦克在空旷的场景中搏斗（网络版）"; }
        }

        #endregion

        public DuelNetRule()
        {
            BaseGame.ShowMouse = true;

            AIListForTank1 = new Combo("AIListForTank1", new Vector2(100, 100), 250);
            AIListForTank2 = new Combo("AIListForTank1", new Vector2(100, 300), 250);

            AIListForTank1.OnChangeSelection += new EventHandler(AIListForTank1_OnChangeSelection);
            AIListForTank2.OnChangeSelection += new EventHandler(AIListForTank2_OnChangeSelection);

            CheckBoxIsHost = new Checkbox("CheckBoxIsHost", new Vector2(100, 500), "IsHost", false);

            aiLoader = new AILoader();
            aiLoader.AddInterAI(typeof(DuelerNoFirst));
            aiLoader.AddInterAI(typeof(ManualControl));
            aiLoader.AddInterAI(typeof(DuelAIModel));
            aiLoader.AddInterAI(typeof(AutoShootAI));
            aiLoader.InitialCompatibleAIs(typeof(IDuelAIOrderServer), typeof(AICommonServer));
            foreach (string name in aiLoader.GetAIList())
            {
                AIListForTank1.AddItem(name);
                AIListForTank2.AddItem(name);
            }
            btn = new TextButton("OkBtn", new Vector2(700, 500), "Begin", 0, Color.Yellow);
            btn.OnClick += new EventHandler(btn_OnPress);

            LoadResouce();
        }

        private void LoadResouce()
        {
            ShellExplode.LoadResources();
            Explode.LoadResources();
        }

        void btn_OnPress(object sender, EventArgs e)
        {
            GameManager.AddGameScreen(new DuelNetGameScreen(aiLoader.GetAIInstance(selectIndexTank1), aiLoader.GetAIInstance(selectIndexTank2), CheckBoxIsHost.bchecked));
        }

        void AIListForTank1_OnChangeSelection(object sender, EventArgs e)
        {
            selectIndexTank1 = AIListForTank1.currentIndex;
        }

        void AIListForTank2_OnChangeSelection(object sender, EventArgs e)
        {
            selectIndexTank2 = AIListForTank2.currentIndex;
        }

        #region IGameScreen 成员

        public void Render()
        {
            BaseGame.Device.Clear(Color.LawnGreen);

            AIListForTank1.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            AIListForTank2.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            btn.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            CheckBoxIsHost.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
        }

        public bool Update(float second)
        {


            AIListForTank1.Update();
            AIListForTank2.Update();
            btn.Update();
            CheckBoxIsHost.Update();

            if (InputHandler.JustPressKey(Microsoft.Xna.Framework.Input.Keys.Escape))
                return true;

            return false;
        }

        #endregion


        #region IGameScreen 成员

        public void OnClose()
        {

        }

        #endregion
    }

    class DuelNetGameScreen : RuleSupNet, IGameScreen
    {
        #region Constants
        readonly Rectangle scrnViewRect = new Rectangle(30, 30, 740, 540);
        readonly Rectanglef mapRect = new Rectanglef(0, 0, 300, 220);
        readonly float tankRaderLength = 90;
        readonly float tankMaxForwardSpd = 60;
        readonly float tankMaxBackwardSpd = 50;
        readonly float shellSpeed = 100;
        #endregion

        #region Variables

        Camera camera;

        VergeTileGround vergeGround;

        DuelTank tank1;
        DuelTank tank2;

        AICommonServer commonServer;

        bool gameStart = false;
        bool gameOver = false;

        #endregion

        #region Construction

        public DuelNetGameScreen(IAI TankAI1, IAI TankAI2, bool IsMainHost)
        {
            BaseGame.CoordinMgr.SetScreenViewRect(scrnViewRect);

            camera = new Camera(2.6f, new Vector2(150, 112), 0);
            camera.maxScale = 4.5f;
            camera.minScale = 2f;
            camera.Enable();

            InitialBackGround();

            sceneMgr = new SceneMgr();
            SceneInitial();
            GameManager.LoadScene(sceneMgr);

            InitialPurview(IsMainHost);

            RuleInitial();

            AIInitial(TankAI1, TankAI2);

            InitialDrawMgr(TankAI1, TankAI2);

            InitialStartTimer();


        }

        private void InitialPurview(bool IsMainHost)
        {
            PurviewMgr.IsMainHost = IsMainHost;
            PurviewMgr.RegistSlaveMgObj(tank2.MgPath);

            if (PurviewMgr.IsMainHost)
            {
                camera.Focus(tank1, true);
            }
            else
            {
                camera.Focus(tank2, true);
            }
        }

        private void AIInitial(IAI tankAI1, IAI tankAI2)
        {
            commonServer = new AICommonServer(mapRect);


            if (PurviewMgr.IsMainHost)
            {
                tankAI1.CommonServer = commonServer;
                tankAI1.OrderServer = tank1;
                tank1.SetTankAI(tankAI1);
            }
            else
            {
                tankAI2.CommonServer = commonServer;
                tankAI2.OrderServer = tank2;
                tank2.SetTankAI(tankAI2);
            }

            //GameManager.ObjMemoryMgr.AddSingle( tank1 );
            //GameManager.ObjMemoryMgr.AddSingle( tank2 );
        }

        private void InitialDrawMgr(IAI tankAI1, IAI tankAI2)
        {
            DrawMgr.SetCondition(
                delegate(IDrawableObj obj)
                {
                    return true;
                });
            //if (tankAI1 is ManualControl)
            //{
            //    DrawMgr.SetCondition(
            //        delegate(IDrawableObj obj)
            //        {
            //            if (tank1.IsDead)
            //                return true;

            //            if (tank1.Rader.PointInRader(obj.Pos) || obj == tank1 ||
            //                ((obj is ShellNormal) && ((ShellNormal)obj).Firer == tank1))
            //                return true;
            //            else
            //                return false;
            //        });
            //}
            //if (tankAI2 is ManualControl)
            //{
            //    DrawMgr.SetCondition(
            //        delegate(IDrawableObj obj)
            //        {
            //            if (tank2.IsDead)
            //                return true;

            //            if (tank2.Rader.PointInRader(obj.Pos) || obj == tank2 ||
            //                ((obj is ShellNormal) && ((ShellNormal)obj).Firer == tank2))
            //                return true;
            //            else
            //                return false;
            //        });
            //}
        }

        private void InitialBackGround()
        {
            VergeTileData data = new VergeTileData();
            data.gridWidth = 30;
            data.gridHeight = 22;
            data.SetRondomVertexIndex(30, 22, 4);
            data.SetRondomGridIndex(30, 22);
            data.texPaths = new string[]
            {
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_Dirt.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_DirtRough.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_DirtGrass.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_GrassDark.tga"),
            };
            vergeGround = new VergeTileGround(data, scrnViewRect, mapRect);
        }

        private void SceneInitial()
        {
            tank1 = new DuelTank("tank1", TankSinTur.M60TexPath, TankSinTur.M60Data, new Vector2(mapRect.X + 150 + RandomHelper.GetRandomFloat(-40, 40),
                mapRect.Y + 60 + RandomHelper.GetRandomFloat(-10, 10)),
                MathHelper.Pi + RandomHelper.GetRandomFloat(-MathHelper.PiOver4, MathHelper.PiOver4),
                "Tank1", tankRaderLength, tankMaxForwardSpd, tankMaxBackwardSpd, 10);
            tank2 = new DuelTank("tank2", TankSinTur.M1A2TexPath, TankSinTur.M1A2Data, new Vector2(mapRect.X + 150 + RandomHelper.GetRandomFloat(-40, 40),
                mapRect.Y + 160 + RandomHelper.GetRandomFloat(-10, 10)),
                RandomHelper.GetRandomFloat(-MathHelper.PiOver4, MathHelper.PiOver4),
                "Tank2", tankRaderLength, tankMaxForwardSpd, tankMaxBackwardSpd, 10);

            tank1.ShellSpeed = shellSpeed;
            tank2.ShellSpeed = shellSpeed;

            

            sceneMgr.AddGroup("", new TypeGroup<DuelTank>("tank"));
            sceneMgr.AddGroup("", new TypeGroup<SmartTank.PhiCol.Border>("border"));
            sceneMgr.AddGroup("", new TypeGroup<ShellNormal>("shell"));
            sceneMgr.PhiGroups.Add("tank");
            sceneMgr.PhiGroups.Add("shell");
            sceneMgr.AddColMulGroups("tank", "border", "shell");
            sceneMgr.ShelterGroups.Add(new SceneMgr.MulPair("tank", new List<string>()));
            sceneMgr.VisionGroups.Add(new SceneMgr.MulPair("tank", new List<string>(new string[] { "tank" })));

            sceneMgr.AddGameObj("tank", tank1);
            sceneMgr.AddGameObj("tank", tank2);
            sceneMgr.AddGameObj("border", new SmartTank.PhiCol.Border(mapRect));
        }

        private void InitialStartTimer()
        {
            new GameTimer(1,
                delegate()
                {
                    TextEffectMgr.AddRiseFadeInScrnCoordin("3", new Vector2(400, 300), 3, Color.Red, LayerDepth.Text, GameFonts.Lucida, 200, 1.4f);
                });

            new GameTimer(2,
                delegate()
                {
                    TextEffectMgr.AddRiseFadeInScrnCoordin("2", new Vector2(400, 300), 3, Color.Red, LayerDepth.Text, GameFonts.Lucida, 200, 1.4f);
                });

            new GameTimer(3,
                delegate()
                {
                    TextEffectMgr.AddRiseFadeInScrnCoordin("1", new Vector2(400, 300), 3, Color.Red, LayerDepth.Text, GameFonts.Lucida, 200, 1.4f);
                });

            new GameTimer(4,
                delegate()
                {
                    TextEffectMgr.AddRiseFadeInScrnCoordin("Start!", new Vector2(400, 300), 3, Color.Red, LayerDepth.Text, GameFonts.Lucida, 200, 1.4f);

                });
            new GameTimer(5,
                delegate()
                {
                    gameStart = true;
                });
        }

        private void RuleInitial()
        {
            tank1.onShoot += new Tank.ShootEventHandler(tank_onShoot);
            tank2.onShoot += new Tank.ShootEventHandler(tank_onShoot);

            tank1.onCollide += new OnCollidedEventHandler(tank_onCollide);
            tank2.onCollide += new OnCollidedEventHandler(tank_onCollide);

            SyncCasheReader.onCreateObj += new SyncCasheReader.CreateObjInfoHandler(SyncCasheReader_onCreateObj);
        }



        #endregion

        #region Rules

        int shellSum = 0;
        void tank_onShoot(Tank sender, Vector2 turretEnd, float azi)
        {
            if (PurviewMgr.IsMainHost)
            {
                ShellNormal shell = new ShellNormal("shell" + shellSum.ToString(), sender, turretEnd, azi, shellSpeed);
                sceneMgr.AddGameObj("shell", shell);

                shell.onCollided += new OnCollidedEventHandler(shell_onCollided);
                shellSum++;
                SyncCasheWriter.SubmitCreateObjMg("shell", typeof(ShellNormal), shell.Name, sender, turretEnd, azi, shellSpeed);
            }

            Sound.PlayCue("CANNON1");
        }

        void SyncCasheReader_onCreateObj(IGameObj obj)
        {
            if (obj is ShellNormal)
            {
                ShellNormal shell = obj as ShellNormal;
                shell.onCollided += new OnCollidedEventHandler(shell_onCollided);
                shellSum++;
            }
        }


        void tank_onCollide(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (objB.ObjClass == "ShellNormal")
            {
                if (Sender == tank1)
                {
                    tank1.Live--;
                    // 在此添加效果
                    tank1.smoke.Concen += 0.2f;

                    if (tank1.Live <= 0 && !tank1.IsDead)
                    {
                        new Explode(tank1.Pos, 0);

                        tank1.Dead();

                        new GameTimer(3,
                            delegate()
                            {
                                MessageBox.Show("Tank2胜利！");
                                gameOver = true;
                            });

                    }
                }
                else if (Sender == tank2)
                {
                    tank2.Live--;

                    tank2.smoke.Concen += 0.2f;
                    // 在此添加效果
                    if (tank2.Live <= 0 && !tank2.IsDead)
                    {
                        new Explode(tank2.Pos, 0);

                        tank2.Dead();

                        new GameTimer(3,
                            delegate()
                            {
                                MessageBox.Show("Tank1胜利！");
                                gameOver = true;
                            });
                    }
                }
            }
        }

        void shell_onCollided(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            sceneMgr.DelGameObj("shell", Sender.Name);

            new ShellExplodeBeta(Sender.Pos, ((ShellNormal)Sender).Azi);

            Quake.BeginQuake(10, 50);
            Sound.PlayCue("EXPLO1");

        }

        #endregion

        #region IGameScreen 成员

        public override bool Update(float seconds)
        {
            if (InputHandler.JustPressKey(Microsoft.Xna.Framework.Input.Keys.Escape))
            {
                GameManager.ComponentReset();
                return true;
            }

            if (!gameStart)
                return false;

            base.Update(seconds);

            if (InputHandler.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Left))
                camera.Move(new Vector2(-5, 0));
            if (InputHandler.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Right))
                camera.Move(new Vector2(5, 0));
            if (InputHandler.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Up))
                camera.Move(new Vector2(0, -5));
            if (InputHandler.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Down))
                camera.Move(new Vector2(0, 5));
            if (InputHandler.JustPressKey(Microsoft.Xna.Framework.Input.Keys.V))
                camera.Zoom(-0.2f);
            if (InputHandler.JustPressKey(Microsoft.Xna.Framework.Input.Keys.B))
                camera.Zoom(0.2f);
            if (InputHandler.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.T))
                camera.Rota(0.1f);
            if (InputHandler.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.R))
                camera.Rota(-0.1f);

            camera.Update(seconds);

            if (gameOver)
            {
                GameManager.ComponentReset();

                return true;
            }

            return false;
        }

        public override void Render()
        {
            vergeGround.Draw();

            GameManager.DrawManager.Draw();

            BaseGame.BasicGraphics.DrawRectangle(mapRect, 3, Color.Red, 0f);
            BaseGame.BasicGraphics.DrawRectangleInScrn(scrnViewRect, 3, Color.Green, 0f);

            //foreach (Vector2 visiPoint in tank1.KeyPoints)
            //{
            //    BasicGraphics.DrawPoint( Vector2.Transform( visiPoint, tank1.TransMatrix ), 0.4f, Color.Blue, 0f );
            //}

            //foreach (Vector2 visiPoint in tank2.KeyPoints)
            //{
            //    BasicGraphics.DrawPoint( Vector2.Transform( visiPoint, tank2.TransMatrix ), 0.4f, Color.Blue, 0f );
            //}

        }

        #endregion
    }


}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using GameEngine.Effects;

namespace GameEngine.Draw
{
    /*
     * 当前这个类只是一个简单的版本。将来要添加新的内容。
     * 
     * */

    public delegate bool DrawCondition ( IDrawableObj obj );

    public class DrawMgr
    {
        private static DrawCondition condition;

        List<IEnumerable<IDrawableObj>> drawableGroups = new List<IEnumerable<IDrawableObj>>();

        public void AddGroup ( IEnumerable<IDrawableObj> group )
        {
            drawableGroups.Add( group );
        }

        public void ClearGroups ()
        {
            drawableGroups.Clear();
        }

        public static void SetCondition ( DrawCondition condi )
        {
            condition = condi;
        }

        public void Draw ()
        {
            foreach (IEnumerable<IDrawableObj> group in drawableGroups)
            {
                foreach (IDrawableObj drawable in group)
                {
                    if (condition != null)
                    {
                        if (condition( drawable ))
                            drawable.Draw();
                    }
                    else
                        drawable.Draw();
                }
            }
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace Common.DataStructure
{
    #region Delegates

    /// <summary>
    /// 对数据容器中的每个对象进行一次处理。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="type"></param>
    public delegate void ForEachFunc<T> ( ref T type );

    /// <summary>
    /// 在容器中寻找想要找的对象。
    /// 当该对象是你需要的对象时，代理函数应返回true
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="type"></param>
    /// <returns></returns>
    public delegate bool FindFunc<T> ( T type );

    #endregion

    #region CircleListNode

    /// <summary>
    /// 环链表节点
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CircleListNode<T>
    {
        /// <summary>
        /// 表示一个值为空的节点
        /// </summary>
        static readonly public CircleListNode<T> empty = new CircleListNode<T>();

        /// <summary>
        /// 空构造函数
        /// </summary>
        public CircleListNode ()
        {
        }

        /// <summary>
        /// 将value作为该节点中储存的值
        /// </summary>
        /// <param name="value"></param>
        public CircleListNode ( T value )
        {
            this.value = value;
        }

        /// <summary>
        /// 节点中储存的值
        /// </summary>
        public T value;

        /// <summary>
        /// 该节点的前一个节点
        /// </summary>
        public CircleListNode<T> pre;

        /// <summary>
        /// 该节点的后一个节点
        /// </summary>
        public CircleListNode<T> next;

        /// <summary>
        /// 对节点进行深度复制。
        /// 节点中储存的值必须是ICloneable或是ValueType才可调用该函数，否则会出现异常。
        /// </summary>
        /// <returns></returns>
        public CircleListNode<T> Clone ()
        {
            if (this.value is ICloneable)
            {
                return new CircleListNode<T>( (T)(this.value as ICloneable).Clone() );
            }
            else if (this.value is ValueType)
            {
                return new CircleListNode<T>( this.value );
            }
            else
            {
                throw new Exception( "the T should be a ICloneable or a ValueType!" );
            }
        }
    }
    #endregion

    #region CircleList

    /*
     * 对平台而言意义非同小可。
     * 它是储存贴图边界点的数据结构，使精灵之间精确的冲突检测成为可能。
     * 
     * */


    /// <summary>
    /// 环形链表。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CircleList<T> : IEnumerable<T>
    {
        #region Emunerator
        private class CircleListEnumerator : IEnumerator<T>
        {
            public CircleListNode<T> curNode;
            CircleListNode<T> first;

            int EnumeLength = 0;

            public CircleListEnumerator ( CircleList<T> list )
            {
                this.first = list.first;
                EnumeLength = list.length;
            }

            #region IEnumerator<T> 成员

            public T Current
            {
                get { return curNode.value; }
            }

            #endregion

            #region IDisposable 成员

            public void Dispose ()
            {

            }

            #endregion

            #region IEnumerator 成员

            object IEnumerator.Current
            {
                get { return curNode; }
            }

            public bool MoveNext ()
            {
                if (--EnumeLength < 0) return false;

                if (curNode == null)
                {
                    curNode = first;
                    return true;
                }
                else if (curNode.next != null)
                {
                    curNode = curNode.next;
                    return true;
                }
                else
                    return false;
            }

            public void Reset ()
            {
                curNode = first;
            }

            #endregion
        }
        #endregion

        #region Variable & Properties

        CircleListNode<T> first;
        /// <summary>
        /// 获取链表中的第一个元素，当链表为空时返回null
        /// </summary>
        public CircleListNode<T> First
        {
            get { return first; }
        }
        CircleListNode<T> last;
        /// <summary>
        /// 获取链表中的最后一个元素，当链表为空时返回null
        /// </summary>
        public CircleListNode<T> Last
        {
            get { return last; }
        }

        bool linked = false;
        /// <summary>
        /// 获取一个值，表示该链表是否已经首尾相连。
        /// </summary>
        public bool isLinked
        {
            get { return linked; }
        }

        int length;

        /// <summary>
        /// 链表中元素的数量
        /// </summary>
        public int Length
        {
            get { return length; }
        }
        #endregion

        #region Methods

        /// <summary>
        /// 在链表的第一个元素前插入一个元素。
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public bool AddFirst ( CircleListNode<T> node )
        {
            if (first == null)
            {
                first = node;
                last = node;
            }
            else
            {
                node.next = first;
                first.pre = node;
                first = node;

                if (linked)
                {
                    first.pre = last;
                    last.next = first;
                }
            }
            length++;
            return true;
        }

        /// <summary>
        /// 在链表的第一个元素前插入一个元素。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool AddFirst ( T value )
        {
            return AddFirst( new CircleListNode<T>( value ) );
        }

        /// <summary>
        /// 在未首尾相连的条件下在链表的末尾加入一个元素。
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public bool AddLast ( CircleListNode<T> node )
        {
            if (linked) return false;
            length++;
            if (first == null)
            {
                first = node;
                last = node;
            }
            else
            {
                last.next = node;
                node.pre = last;
                last = node;
            }

            return true;
        }

        /// <summary>
        /// 在未首尾相连的条件下在链表的末尾加入一个元素。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool AddLast ( T value )
        {
            if (linked) return false;

            CircleListNode<T> node = new CircleListNode<T>( value );
            return AddLast( node );
        }

        /// <summary>
        /// 在链表中某一节点后插入一个新的节点。
        /// </summary>
        /// <param name="value"></param>
        /// <param name="node">必须是该链表中包含的节点</param>
        /// <returns></returns>
        public bool InsertAfter ( T value, CircleListNode<T> node )
        {
            CircleListNode<T> newNode = new CircleListNode<T>( value );
            newNode.next = node.next;

            if (node.next == null)
                return false;

            if (node == last)
                last = newNode;

            if (node.next != null)
                node.next.pre = newNode;
            node.next = newNode;
            newNode.pre = node;

            length++;

            return true;
        }

        /// <summary>
        /// 链接第一个和最后一个节点，使链表成为一个环链表。
        /// </summary>
        public void LinkLastAndFirst ()
        {
            linked = true;

            last.next = first;
            first.pre = last;
        }

        /// <summary>
        /// 对链表中的每个元素执行一次操作
        /// </summary>
        /// <param name="func"></param>
        public void ForEach ( ForEachFunc<T> func )
        {
            CircleListEnumerator iter = new CircleListEnumerator( this );
            while (iter.MoveNext())
            {
                func( ref iter.curNode.value );
            }
        }

        /// <summary>
        /// 用遍历的方式查找链表，返回符合要求的第一个节点
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        public CircleListNode<T> FindFirst ( FindFunc<T> func )
        {
            CircleListEnumerator iter = new CircleListEnumerator( this );
            while (iter.MoveNext())
            {
                if (func( iter.curNode.value ))
                {
                    return iter.curNode;
                }
            }
            return null;
        }

        /// <summary>
        /// 用遍历的方式查找链表，返回所以符合要求的节点
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        public CircleListNode<T>[] FindAll ( FindFunc<T> func )
        {
            List<CircleListNode<T>> result = new List<CircleListNode<T>>();

            CircleListEnumerator iter = new CircleListEnumerator( this );
            while (iter.MoveNext())
            {
                if (func( iter.curNode.value ))
                {
                    result.Add( iter.curNode );
                }
            }
            return result.ToArray();
        }

        /// <summary>
        /// 用遍历的方式获得该节点在链表中的位置。
        /// 如果节点不在链表中，返回-1
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public int IndexOf ( CircleListNode<T> node )
        {
            CircleListEnumerator iter = new CircleListEnumerator( this );

            int result = -1;
            while (iter.MoveNext())
            {
                result++;
                if (iter.curNode == node)
                    return result;
            }
            return -1;
        }

        /// <summary>
        /// 将链表从起始节点开始，向前或向后的顺序转换到一个数组中。
        /// </summary>
        /// <param name="startNode">起始节点，必须是链表中的节点</param>
        /// <param name="forward"></param>
        /// <returns></returns>
        public T[] ToArray ( CircleListNode<T> startNode, bool forward )
        {
            if (startNode == null)
                throw new Exception( "The startNode is null!" );

            CircleListEnumerator iter = new CircleListEnumerator( this );

            bool startNodeInList = false;
            while (iter.MoveNext())
            {
                if (iter.curNode == startNode)
                {
                    startNodeInList = true;
                }
            }
            if (!startNodeInList)
                throw new Exception( "the startNode should in current List!" );

            if (!this.isLinked)
                this.LinkLastAndFirst();

            T[] result = new T[this.Length];
            for (int i = 0; i < this.Length; i++)
            {
                result[i] = startNode.value;
                if (forward)
                    startNode = startNode.next;
                else
                    startNode = startNode.pre;
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CircleList<T> Clone ()
        {
            CircleList<T> result = new CircleList<T>();
            CircleListEnumerator iter = new CircleListEnumerator( this );
            while (iter.MoveNext())
            {
                result.AddLast( iter.curNode.Clone() );
            }
            if (this.isLinked)
                result.LinkLastAndFirst();
            return result;
        }

        #endregion

        #region IEnumerable<T> 成员

        /// <summary>
        /// 获得该链表的迭代器
        /// </summary>
        /// <returns></returns>
        public IEnumerator<T> GetEnumerator ()
        {
            return new CircleListEnumerator( this );
        }

        #endregion

        #region IEnumerable 成员

        IEnumerator IEnumerable.GetEnumerator ()
        {
            return GetEnumerator();
        }

        #endregion
    }
    #endregion
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.AI.AIHelper;
using SmartTank.AI;
using TankEngine2D.DataStructure;
using SmartTank.GameObjs.Tank.SinTur;
using SmartTank.Senses.Vision;
using TankEngine2D.Helpers;

namespace InterRules.Duel
{
    class ConsiderSearchEnemy : IConsider
    {
        #region Constants

        const float initialGridTime = -10;
        const float defaultDirWeightFactor = 5f;
        const float defaultDistanceWeightFactor = 0.2f;

        #endregion

        #region Variables

        IAIOrderServer orderServer;

        ConsiderPriority curPriority;

        Rectanglef mapSize;

        float[,] grids;

        float gridWidth, gridHeight;

        Point LastGrid;

        float curTime;

        AIActionHelper action;

        public float forwardSpd = 0;

        public float dirWeightFactor = defaultDirWeightFactor;

        public float distanceWeightFactor = defaultDistanceWeightFactor;

        bool enterNewGrid = false;


        #endregion

        #region Constructions

        public ConsiderSearchEnemy ( Rectanglef mapSize, float raderRadius )
        {
            this.mapSize = mapSize;
            curPriority = ConsiderPriority.Vacancy;

            int gridMaxX = (int)(mapSize.Width / raderRadius) + 1;
            int gridMaxY = (int)(mapSize.Height / raderRadius) + 1;

            grids = new float[gridMaxX, gridMaxY];
            for (int i = 0; i < gridMaxX; i++)
            {
                for (int j = 0; j < gridMaxY; j++)
                {
                    grids[i, j] = initialGridTime;
                }
            }

            gridWidth = mapSize.Width / gridMaxX;
            gridHeight = mapSize.Height / gridMaxY;


            curTime = 0;
        }

        public ConsiderSearchEnemy ( Rectanglef mapSize, float raderRadius, float dirWeight )
        {
            this.mapSize = mapSize;
            curPriority = ConsiderPriority.Vacancy;

            int gridMaxX = (int)(mapSize.Width / raderRadius) + 1;
            int gridMaxY = (int)(mapSize.Height / raderRadius) + 1;

            grids = new float[gridMaxX, gridMaxY];
            for (int i = 0; i < gridMaxX; i++)
            {
                for (int j = 0; j < gridMaxY; j++)
                {
                    grids[i, j] = initialGridTime;
                }
            }

            gridWidth = mapSize.X / gridMaxX;
            gridHeight = mapSize.Y / gridMaxY;

            curTime = 0;

            this.dirWeightFactor = dirWeight;
        }

        #endregion

        #region IConsider 成员

        public void Authorize ()
        {
            LastGrid = FindCurGrid();
            UpdateCurGridTime( LastGrid );

            Vector2 curDir = orderServer.Direction;
            Vector2 curPos = orderServer.Pos;
            float mapDistance = new Vector2( mapSize.Width, mapSize.Height ).LengthSquared();

            Vector2 aimGrid = Vector2.Zero;
            float maxWeight = 0;
            for (int x = 0; x < grids.GetLength( 0 ); x++)
            {
                for (int y = 0; y < grids.GetLength( 1 ); y++)
                {
                    if (LastGrid.X == x && LastGrid.Y == y)
                        continue;

                    Vector2 gridPos = new Vector2( (x + 0.5f) * gridWidth + mapSize.X, (y + 0.5f) * gridHeight + mapSize.Y );
                    Vector2 gridDir = gridPos - curPos;
                    float timeSpan = curTime - grids[x, y];
                    float dirWeight = Vector2.Dot( curDir, Vector2.Normalize( gridDir ) ) + 1;
                    dirWeight *= 0.5f * dirWeightFactor;

                    float distance = gridDir.LengthSquared();
                    float distanceWeight = mapDistance / distance * distanceWeightFactor;

                    float sumWeight = timeSpan + dirWeight + distanceWeight;

                    if (sumWeight > maxWeight)
                    {
                        maxWeight = sumWeight;
                        aimGrid = gridPos;
                    }
                }
            }


            action.AddOrder( new OrderMoveCircle( aimGrid, forwardSpd, orderServer,
                delegate( IActionOrder order )
                {
                    Authorize();
                } , false ) );

            //TextEffect.AddRiseFade( "aim", aimGrid, 2f, Color.Black, LayerDepth.Text, FontType.Lucida, 300, 0 );
        }

        public void Bereave ()
        {
        }

        public ConsiderPriority CurPriority
        {
            get { return curPriority; }
        }

        public ActionRights NeedRights
        {
            get { return ActionRights.Move | ActionRights.Rota; }
        }

        public void Observe ()
        {
            List<IEyeableInfo> eyeableInfo = orderServer.GetEyeableInfo();
            if (eyeableInfo.Count == 0)
            {
                curPriority = ConsiderPriority.Low;
            }


            Point curGrid = FindCurGrid();
            if (curGrid != LastGrid)
            {
                LastGrid = curGrid;
                UpdateCurGridTime( curGrid );
                enterNewGrid = true;
            }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = value;
                action = new AIActionHelper( orderServer );
                if (forwardSpd == 0)
                    forwardSpd = orderServer.MaxForwardSpeed;

                //averageTime = mapSize.X / orderServer.MaxForwardSpeed;

            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            curTime += seconds;

            if (enterNewGrid)
            {
                Authorize();
                enterNewGrid = false;
            }

            List<IEyeableInfo> eyeableInfo = orderServer.GetEyeableInfo();
            if (eyeableInfo.Count != 0)
            {
                curPriority = ConsiderPriority.Vacancy;
                action.StopMove();
                action.StopRota();
            }

            action.Update( seconds );
        }

        #endregion

        #region Private Functions

        private void UpdateCurGridTime ( Point curGrid )
        {
            grids[curGrid.X, curGrid.Y] = curTime;
        }

        private Point FindCurGrid ()
        {
            Vector2 pos = orderServer.Pos;
            return new Point( (int)((pos.X - mapSize.X) / gridWidth), (int)((pos.Y - mapSize.Y) / gridHeight) );
        }

        #endregion

    }

    class ConsiderRaderScan : IConsider
    {
        #region Type Define

        enum State
        {
            Start,
            Scan,
            Circle,
            Border,
        }

        enum Area
        {
            Middle = 0,
            Left = 1,
            Right = 2,
            Up = 4,
            Dowm = 8,
            UpLeft = 5,
            UpRight = 6,
            DownLeft = 9,
            DownRight = 10,
        }

        #endregion

        #region Constances

        const float defaultGuardDestance = 30;
        const float defaultCircleSpeedFactor = 0.3f;

        #endregion

        #region Variables

        IAIOrderServer orderServer;

        AIActionHelper action;

        ConsiderPriority curPriority;

        Rectanglef mapSize;

        float guardDestance = defaultGuardDestance;

        public float circleSpeedFactor = defaultCircleSpeedFactor;

        State lastState;

        bool firstCircleFinished;

        #endregion

        #region Constructions

        public ConsiderRaderScan ( Rectanglef mapSize )
        {
            this.mapSize = mapSize;
            curPriority = ConsiderPriority.Vacancy;
            firstCircleFinished = false;
            lastState = State.Start;
        }

        #endregion

        #region IConsider 成员

        public void Authorize ()
        {
            if (lastState == State.Start)
            {
                float curRaderAzi = orderServer.RaderAzi;
                action.AddOrder( new OrderRotaRaderToAng( curRaderAzi + 0.66f * MathHelper.Pi, 0,
                    delegate( IActionOrder order )
                    {
                        action.AddOrder( new OrderRotaRaderToAng( curRaderAzi + 1.23f * MathHelper.Pi, 0,
                            delegate( IActionOrder order1 )
                            {
                                action.AddOrder( new OrderRotaRaderToAng( curRaderAzi + 2 * MathHelper.Pi, 0,
                                    delegate( IActionOrder order2 )
                                    {
                                        firstCircleFinished = true;
                                    }, false ) );
                            }, false ) );
                    }, false ) );

            }
            else if (lastState == State.Scan)
            {
                float maxScanAng = MathHelper.PiOver2 - orderServer.RaderAng;
                action.AddOrder( new OrderScanRader( maxScanAng, 0, true ) );
            }
            else if (lastState == State.Circle)
            {
                orderServer.TurnRaderWiseSpeed = orderServer.MaxRotaRaderSpeed;
            }
            else if (lastState == State.Border)
            {
                float maxRaderAng;
                float interDir = FindInterDir( out maxRaderAng );
                action.AddOrder( new OrderScanRaderAzi( interDir + maxRaderAng, interDir - maxRaderAng, 0, true ) );
            }

        }

        public void Bereave ()
        {
            action.StopRotaRader();
            //orderServer.TurnRaderWiseSpeed = 0;
        }

        public ConsiderPriority CurPriority
        {
            get { return curPriority; }
        }

        public ActionRights NeedRights
        {
            get { return ActionRights.RotaRader; }
        }

        public void Observe ()
        {
            List<IEyeableInfo> eyeableInfo = orderServer.GetEyeableInfo();
            if (eyeableInfo.Count == 0)
            {
                curPriority = ConsiderPriority.Low;
            }
            else
            {
                curPriority = ConsiderPriority.Vacancy;
            }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = value;
                action = new AIActionHelper( orderServer );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            State curState = CheckState();
            if (curState != lastState)
            {
                lastState = curState;
                Authorize();
            }

            action.Update( seconds );


        }

        #endregion

        #region Private Functions

        private State CheckState ()
        {
            if (!firstCircleFinished)
                return State.Start;

            Vector2 curPos = orderServer.Pos;

            if (curPos.X < mapSize.X + guardDestance || curPos.X > mapSize.X + mapSize.Width - guardDestance ||
                curPos.Y < mapSize.Y + guardDestance || curPos.Y > mapSize.Y + mapSize.Height - guardDestance)
                return State.Border;

            float curSpeed = orderServer.ForwardSpeed;
            if (curSpeed < orderServer.MaxForwardSpeed * circleSpeedFactor)
            {
                return State.Circle;
            }

            return State.Scan;
        }

        private float FindInterDir ( out float maxRaderAng )
        {
            int sum = 0;
            Vector2 pos = orderServer.Pos;
            if (pos.X < mapSize.X + guardDestance)
                sum += 1;
            if (pos.X > mapSize.X + mapSize.Width - guardDestance)
                sum += 2;
            if (pos.Y < mapSize.Y + guardDestance)
                sum += 4;
            if (pos.Y > mapSize.Y + mapSize.Height - guardDestance)
                sum += 8;

            Area curArea = (Area)sum;
            if (curArea == Area.Dowm)
            {
                maxRaderAng = MathHelper.PiOver2 - orderServer.RaderAng;
                return 0;
            }
            else if (curArea == Area.Up)
            {
                maxRaderAng = MathHelper.PiOver2 - orderServer.RaderAng;
                return MathHelper.Pi;
            }
            else if (curArea == Area.Left)
            {
                maxRaderAng = MathHelper.PiOver2 - orderServer.RaderAng;
                return MathHelper.PiOver2;
            }
            else if (curArea == Area.Right)
            {
                maxRaderAng = MathHelper.PiOver2 - orderServer.RaderAng;
                return MathHelper.Pi + MathHelper.PiOver2;
            }
            else if (curArea == Area.UpLeft)
            {
                maxRaderAng = MathHelper.PiOver4 - orderServer.RaderAng;
                return MathHelper.PiOver2 + MathHelper.PiOver4;
            }
            else if (curArea == Area.UpRight)
            {
                maxRaderAng = MathHelper.PiOver4 - orderServer.RaderAng;
                return MathHelper.Pi + MathHelper.PiOver4;
            }
            else if (curArea == Area.DownRight)
            {
                maxRaderAng = MathHelper.PiOver4 - orderServer.RaderAng;
                return -MathHelper.PiOver4;
            }
            else if (curArea == Area.DownLeft)
            {
                maxRaderAng = MathHelper.PiOver4 - orderServer.RaderAng;
                return MathHelper.PiOver4;
            }
            maxRaderAng = 0;
            return 0;
        }

        #endregion
    }

    class ConsiderAwayFromEnemyTurret : IConsider
    {
        #region Type Define
        enum Area
        {
            Middle = 0,
            Left = 1,
            Right = 2,
            Up = 4,
            Dowm = 8,
            UpLeft = 5,
            UpRight = 6,
            DownLeft = 9,
            DownRight = 10,
        }
        #endregion

        #region Constants
        const float defaultGuardAng = MathHelper.Pi / 6;
        const float guardDestance = 50;
        #endregion

        #region Variables
        IAIOrderServer orderServer;

        AIActionHelper action;

        ConsiderPriority curPriority;

        public float guardAng = defaultGuardAng;

        TankSinTur.TankCommonEyeableInfo enemyInfo;

        bool lastDeltaAngWise;

        Rectanglef mapSize;

        #endregion

        #region Constrution
        public ConsiderAwayFromEnemyTurret ( Rectanglef mapSize )
        {
            curPriority = ConsiderPriority.Vacancy;
            this.mapSize = mapSize;
        }
        #endregion

        #region IConsider 成员

        public void Authorize ()
        {
            if (enemyInfo == null)
                return;

            Vector2 selfToEnemyVec = orderServer.Pos - enemyInfo.Pos;
            float selfToEnemyAzi = MathTools.AziFromRefPos( selfToEnemyVec );
            float deltaAzi = MathTools.AngTransInPI( selfToEnemyAzi - enemyInfo.TurretAimAzi );
            lastDeltaAngWise = deltaAzi > 0;

            Vector2 aimDir = Vector2.Transform( selfToEnemyVec,
                Matrix.CreateRotationZ( (deltaAzi > 0 ? MathHelper.PiOver2 : -MathHelper.PiOver2) + deltaAzi ) );

            Area curArea = FindArea();
            if (curArea != Area.Middle)
            {
                Vector2 borderDir = FindBorderDir( curArea );
                if (Vector2.Dot( aimDir, borderDir ) < 0)
                    aimDir = -aimDir;
            }

            float aimAzi = MathTools.AziFromRefPos( aimDir );

            Vector2 selfDir = orderServer.Direction;

            if (Vector2.Dot( selfDir, aimDir ) > 0)
            {
                action.AddOrder( new OrderRotaToAzi( aimAzi ) );
                action.AddOrder( new OrderMove( 100 ) );
            }
            else
            {
                action.AddOrder( new OrderRotaToAzi( aimAzi + MathHelper.Pi ) );
                action.AddOrder( new OrderMove( -100 ) );
            }
        }

        public void Bereave ()
        {

        }

        public ConsiderPriority CurPriority
        {
            get { return curPriority; }
        }

        public ActionRights NeedRights
        {
            get { return ActionRights.Move | ActionRights.Rota; }
        }

        public void Observe ()
        {
            List<IEyeableInfo> eyeableInfo = orderServer.GetEyeableInfo();
            if (eyeableInfo.Count != 0)
            {
                IEyeableInfo first = eyeableInfo[0];
                if (first is TankSinTur.TankCommonEyeableInfo)
                {
                    enemyInfo = (TankSinTur.TankCommonEyeableInfo)first;
                    float selfToEnemyAzi = MathTools.AziFromRefPos( orderServer.Pos - enemyInfo.Pos );
                    float enemyTurretAzi = enemyInfo.TurretAimAzi;
                    if (Math.Abs( MathTools.AngTransInPI( enemyTurretAzi - selfToEnemyAzi ) ) < guardAng)
                    {
                        curPriority = ConsiderPriority.High;
                        return;
                    }
                }
            }

            curPriority = ConsiderPriority.Vacancy;
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = value;
                action = new AIActionHelper( orderServer );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            if (enemyInfo == null)
                return;

            Vector2 selfToEnemyVec = orderServer.Pos - enemyInfo.Pos;
            float selfToEnemyAzi = MathTools.AziFromRefPos( selfToEnemyVec );
            float deltaAzi = selfToEnemyAzi - enemyInfo.TurretAimAzi;
            bool deltaAngWise = deltaAzi > 0;
            if (deltaAngWise != lastDeltaAngWise)
            {
                lastDeltaAngWise = deltaAngWise;
                Authorize();
            }
        }

        #endregion

        #region Private Functions

        private Area FindArea ()
        {
            int sum = 0;
            Vector2 pos = orderServer.Pos;
            if (pos.X < mapSize.X + guardDestance)
                sum += 1;
            if (pos.X > mapSize.X + mapSize.Width - guardDestance)
                sum += 2;
            if (pos.Y < mapSize.Y + guardDestance)
                sum += 4;
            if (pos.Y > mapSize.Y + mapSize.Height - guardDestance)
                sum += 8;

            return (Area)sum;
        }

        private Vector2 FindBorderDir ( Area area )
        {
            if (area == Area.Left)
                return new Vector2( 1, 0 );
            else if (area == Area.Right)
                return new Vector2( -1, 0 );
            else if (area == Area.Up)
                return new Vector2( 0, 1 );
            else if (area == Area.Dowm)
                return new Vector2( 0, -1 );
            else if (area == Area.UpLeft)
                return Vector2.Normalize( new Vector2( mapSize.Width, mapSize.Height ) );
            else if (area == Area.UpRight)
                return Vector2.Normalize( new Vector2( -mapSize.Width, mapSize.Height ) );
            else if (area == Area.DownLeft)
                return Vector2.Normalize( new Vector2( mapSize.Width, -mapSize.Height ) );
            else if (area == Area.DownRight)
                return Vector2.Normalize( new Vector2( -mapSize.Width, -mapSize.Height ) );
            else
                return Vector2.Zero;
        }

        #endregion

    }

    class ConsiderRaderLockEnemy : IConsider
    {
        #region Variables

        IAIOrderServer orderServer;

        AIActionHelper action;

        ConsiderPriority curPriority;

        Vector2 enemyPos;

        #endregion

        #region IConsider 成员

        public void Authorize ()
        {

        }

        public void Bereave ()
        {
            action.StopRotaRader();
        }

        public ConsiderPriority CurPriority
        {
            get { return curPriority; }
        }

        public ActionRights NeedRights
        {
            get { return ActionRights.RotaRader; }
        }

        public void Observe ()
        {
            List<IEyeableInfo> eyeableInfo = orderServer.GetEyeableInfo();
            if (eyeableInfo.Count != 0)
            {
                curPriority = ConsiderPriority.High;
                IEyeableInfo first = eyeableInfo[0];
                if (first is TankSinTur.TankCommonEyeableInfo)
                {
                    TankSinTur.TankCommonEyeableInfo enemyInfo = (TankSinTur.TankCommonEyeableInfo)first;
                    enemyPos = enemyInfo.Pos;
                }
            }
            else
                curPriority = ConsiderPriority.Vacancy;
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = value;
                action = new AIActionHelper( orderServer );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            action.AddOrder( new OrderRotaRaderToPos( enemyPos ) );
            action.Update( seconds );
        }

        #endregion
    }

    class ConsiderKeepDistanceFromEnemy : IConsider
    {
        #region Type Define
        enum State
        {
            Near,
            Mid,
            Far,
        }
        #endregion

        #region Constants

        const float defaultMaxGuardFactor = 0.6f;
        const float defaultMinGuardFactor = 0.4f;
        const float defaultDepartFactor = 1f;
        const float maxDistance = 1000;
        #endregion

        #region Variables
        IAIOrderServer orderServer;

        AIActionHelper action;

        ConsiderPriority curPriority;

        float raderRadius;

        float maxGuardFactor = defaultMaxGuardFactor;

        float minGuardFactor = defaultMinGuardFactor;

        Vector2 enemyPos;

        State lastState;

        float departFactor = defaultDepartFactor;
        #endregion

        #region Construction

        public ConsiderKeepDistanceFromEnemy ()
        {
            curPriority = ConsiderPriority.Vacancy;
        }
        #endregion

        #region IConsider 成员

        public void Authorize ()
        {
            Vector2 curPos = orderServer.Pos;
            Vector2 enemyVec = Vector2.Normalize( curPos - enemyPos );
            Vector2 curDir = orderServer.Direction;

            Vector2 lineVec = new Vector2( enemyVec.Y, -enemyVec.X );
            if (Vector2.Dot( lineVec, curDir ) < 0)
                lineVec = -lineVec;

            Vector2 departVec = Vector2.Zero;
            if (lastState == State.Far)
                departVec = -enemyVec;
            else
                departVec = enemyVec;

            Vector2 aimVec = Vector2.Normalize( lineVec * departFactor + departVec );

            action.AddOrder( new OrderRotaToAzi( MathTools.AziFromRefPos( aimVec ) ) );
            if (Vector2.Dot( departVec, curDir ) < 0 && lastState == State.Near)
                action.AddOrder( new OrderMove( -maxDistance ) );
            else if (RandomHelper.GetRandomFloat( -1, 1 ) > -0.3f)
                action.AddOrder( new OrderMove( maxDistance ) );
            else
                action.AddOrder( new OrderMove( -maxDistance ) );
        }

        public void Bereave ()
        {
            action.StopMove();
            action.StopRota();
        }

        public ConsiderPriority CurPriority
        {
            get { return curPriority; }
        }

        public ActionRights NeedRights
        {
            get { return ActionRights.Move | ActionRights.Rota; }
        }

        public void Observe ()
        {

            List<IEyeableInfo> eyeableInfo = orderServer.GetEyeableInfo();
            if (eyeableInfo.Count != 0)
            {
                IEyeableInfo first = eyeableInfo[0];
                if (first is TankSinTur.TankCommonEyeableInfo)
                {
                    TankSinTur.TankCommonEyeableInfo enemyInfo = (TankSinTur.TankCommonEyeableInfo)first;
                    enemyPos = enemyInfo.Pos;
                    float Distance = Vector2.Distance( enemyPos, orderServer.Pos );

                    Vector2 curPos = orderServer.Pos;
                    Vector2 enemyVec = Vector2.Normalize( curPos - enemyPos );
                    Vector2 curDir = orderServer.Direction;

                    Vector2 lineVec = new Vector2( enemyVec.Y, -enemyVec.X );
                    if (Vector2.Dot( lineVec, curDir ) < 0)
                        lineVec = -lineVec;
                    if (Distance > maxGuardFactor * raderRadius || Distance < minGuardFactor * raderRadius ||
                        Vector2.Dot( curDir, lineVec ) < 0.8)
                    {
                        curPriority = ConsiderPriority.Urgency;
                        return;
                    }
                }
            }

            curPriority = ConsiderPriority.Vacancy;

        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = value;
                action = new AIActionHelper( orderServer );
                this.raderRadius = orderServer.RaderRadius;
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            lastState = FindCurState();

            Authorize();

            //else
            //{
            //    curPriority = ConsiderPriority.Vacancy;
            //}

            action.Update( seconds );
        }

        private State FindCurState ()
        {
            List<IEyeableInfo> eyeableInfo = orderServer.GetEyeableInfo();
            if (eyeableInfo.Count != 0)
            {
                IEyeableInfo first = eyeableInfo[0];
                if (first is TankSinTur.TankCommonEyeableInfo)
                {
                    TankSinTur.TankCommonEyeableInfo enemyInfo = (TankSinTur.TankCommonEyeableInfo)first;
                    enemyPos = enemyInfo.Pos;
                    float Distance = Vector2.Distance( enemyPos, orderServer.Pos );
                    if (Distance > maxGuardFactor * raderRadius)
                        return State.Far;
                    else if (Distance < minGuardFactor * raderRadius)
                        return State.Near;
                    else
                        return State.Mid;
                }
            }
            return State.Mid;
        }

        #endregion
    }

    class ConsiderShootEnemy : IConsider
    {
        #region Variables

        IAIOrderServerSinTur orderServer;

        ConsiderPriority curPriority;

        AIActionHelper action;

        Vector2 enemyPos;

        Vector2 enemyVel;

        bool aimming;

        float aimmingTime;

        Vector2 aimmingPos;
        #endregion

        #region Consturtions
        public ConsiderShootEnemy ()
        {

        }
        #endregion

        #region IConsider 成员

        public void Authorize ()
        {

            float curTurretAzi = orderServer.TurretAimAzi;

            float t = 0;

            float maxt = 30;
            Vector2 aimPos = Vector2.Zero;
            bool canShoot = false;
            while (t < maxt)
            {
                aimPos = enemyPos + enemyVel * t;
                float timeRota = Math.Abs( MathTools.AngTransInPI( MathTools.AziFromRefPos( aimPos - orderServer.TurretAxePos ) - curTurretAzi ) / orderServer.MaxRotaTurretSpeed );
                float timeShell = (Vector2.Distance( aimPos, orderServer.TurretAxePos ) - orderServer.TurretLength) / orderServer.ShellSpeed;
                if (MathTools.FloatEqual( timeRota + timeShell, t, 0.05f ))
                {
                    canShoot = true;
                    break;
                }
                t += 0.05f;
            }

            if (canShoot)
            {
                aimmingTime = t;
                aimmingPos = aimPos;
                aimming = true;
                action.AddOrder( new OrderRotaTurretToPos( aimPos, 0,
                    delegate( IActionOrder order )
                    {
                        orderServer.Fire();
                        aimming = false;
                    }, true ) );
            }
        }

        public void Bereave ()
        {
            aimming = false;
        }

        public ConsiderPriority CurPriority
        {
            get { return curPriority; }
        }

        public ActionRights NeedRights
        {
            get { return ActionRights.RotaTurret; }
        }

        public void Observe ()
        {
            List<IEyeableInfo> eyeableInfo = orderServer.GetEyeableInfo();
            if (eyeableInfo.Count != 0)
            {
                IEyeableInfo first = eyeableInfo[0];
                if (first is TankSinTur.TankCommonEyeableInfo)
                {
                    TankSinTur.TankCommonEyeableInfo enemyInfo = (TankSinTur.TankCommonEyeableInfo)first;
                    enemyPos = enemyInfo.Pos;
                    enemyVel = enemyInfo.Vel;
                }
                curPriority = ConsiderPriority.Urgency;
            }
            else
                curPriority = ConsiderPriority.Vacancy;
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = (IAIOrderServerSinTur)value;
                action = new AIActionHelper( orderServer );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            if (aimming)
            {
                aimmingTime -= seconds;
                if ((enemyPos + aimmingTime * enemyVel - aimmingPos).Length() > 4)
                {
                    Authorize();
                }
            }
            else
            {
                Authorize();
            }

            action.Update( seconds );
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using SmartTank.Effects.Particles;
using TankEngine2D.Graphics;

namespace SmartTank.Effects.SceneEffects.BaseEffects
{
    public delegate float SingleFunc ( float curTime );

    class ScaleUp : IManagedEffect
    {
        Texture2D tex;

        Vector2 pos;
        Vector2 origin;

        RadiusFunc radiusFunc;
        SingleFunc rotaFunc;

        float duration;

        bool isEnd = false;

        float curTime = -1;

        float curRadius;
        float curRota = 0;

        float layerDepth;

        Rectangle DestinRect;

        public ScaleUp ( string texPath, Vector2 origin, float layerDepth,
            Vector2 pos, RadiusFunc radiusFunc, SingleFunc rotaFunc,
            float duration )
        {
            this.tex = BaseGame.ContentMgr.Load<Texture2D>( texPath );
            this.origin = origin;
            this.pos = pos;
            this.radiusFunc = radiusFunc;
            this.rotaFunc = rotaFunc;
            this.duration = duration;
            this.layerDepth = layerDepth;
            EffectsMgr.AddManagedEffect( this );
        }

        #region IManagedEffect 成员

        public bool IsEnd
        {
            get { return isEnd; }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            curTime++;

            if (curTime > duration)
            {
                isEnd = true;
                return;
            }

            curRadius = radiusFunc( curTime, curRadius );
            curRota = rotaFunc( curTime );

            UpdateDestinRect();
        }

        private void UpdateDestinRect ()
        {
            Vector2 ScrnPos = BaseGame.CoordinMgr.ScreenPos( pos );
            float ScrnRadius = BaseGame.CoordinMgr.ScrnLengthf( curRadius );
            DestinRect = new Rectangle( (int)ScrnPos.X, (int)ScrnPos.Y, (int)(2 * ScrnRadius), (int)(2 * ScrnRadius) );
        }

        #endregion

        #region IDrawableObj 成员

        public void Draw ()
        {
            BaseGame.SpriteMgr.alphaSprite.Draw( tex, DestinRect, null, Color.White, curRota, origin, SpriteEffects.None, layerDepth );
        }

        #endregion

        #region IDrawableObj 成员


        public Vector2 Pos
        {
            get { return pos; }
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace Common.DataStructure
{
    /// <summary>
    /// 表示一条直线
    /// </summary>
    public struct Line
    {
        /// <summary>
        /// 一个经过该直线的顶点
        /// </summary>
        public Vector2 pos;

        /// <summary>
        /// 表示该直线的方向
        /// </summary>
        public Vector2 direction;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pos">一个经过该直线的顶点</param>
        /// <param name="direction">表示该直线的方向</param>
        public Line ( Vector2 pos, Vector2 direction )
        {
            this.pos = pos;
            this.direction = direction;
        }

        /// <summary>
        /// 计算两点的中垂线
        /// </summary>
        /// <param name="point1"></param>
        /// <param name="point2"></param>
        /// <returns></returns>
        public static Line MidVerLine( Vector2 point1, Vector2 point2 )
        {
            return new Line( 0.5f * (point1 + point2), Vector2.Normalize( new Vector2( -point2.Y + point1.Y, point2.X - point1.X ) ) );
        }

        /// <summary>
        /// 计算通过定点并与指定直线垂直的直线
        /// </summary>
        /// <param name="line"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static Line VerticeLine( Line line, Vector2 point )
        {
            return new Line( point, Vector2.Normalize( new Vector2( -line.direction.Y, line.direction.X ) ) );
        }

        /// <summary>
        /// 计算两直线的交点，当两直线存在交点时返回true
        /// </summary>
        /// <param name="line1"></param>
        /// <param name="line2"></param>
        /// <param name="result"></param>
        /// <returns>当两直线存在交点时返回true</returns>
        public static bool InterPoint( Line line1, Line line2, out Vector2 result )
        {
            if (Vector2.Normalize( line1.direction ) == Vector2.Normalize( line2.direction ) ||
                Vector2.Normalize( line1.direction ) == -Vector2.Normalize( line2.direction ))
            {
                result = Vector2.Zero;
                return false;
            }
            else
            {
                float k = ((line2.pos.X - line1.pos.X) * line2.direction.Y - (line2.pos.Y - line1.pos.Y) * line2.direction.X) /
                    (line1.direction.X * line2.direction.Y - line1.direction.Y * line2.direction.X);
                result = line1.pos + line1.direction * k;
                return true;
            }
        }

        /// <summary>
        /// 判断两个Line对象是否相等
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals ( object obj )
        {
            return this.pos == ((Line)obj).pos && this.direction == ((Line)obj).direction;
        }
        /// <summary>
        /// 获得对象的Hash码。
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode ()
        {
            return pos.GetHashCode();
        }

        /// <summary>
        /// 将Line的信息转换为字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString ()
        {
            return pos.ToString() + " " + direction.ToString();
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using TankEngine2D.Helpers;

namespace TankEngine2D.Input
{
    /// <summary>
    /// XNA环境下的输入处理类
    /// </summary>
    /// test comment
    public static class InputHandler
    {
        #region Mouse

        #region Variables

        static MouseState curMouseState;
        static MouseState lastMouseState;

        #endregion

        #region Properties

        /// <summary>
        /// 上一帧鼠标的视口X坐标
        /// </summary>
        static public int LastMouseX
        {
            get { return lastMouseState.X; }
        }
        /// <summary>
        /// 上一帧鼠标的视口Y坐标
        /// </summary>
        static public int LastMouseY
        {
            get { return lastMouseState.Y; }
        }
        /// <summary>
        /// 上一帧鼠标的视口位置
        /// </summary>
        static public Point LastMousePos
        {
            get { return new Point( LastMouseX, LastMouseY ); }
        }
        /// <summary>
        /// 当前帧鼠标的视口X坐标
        /// </summary>
        static public int CurMouseX
        {
            get { return curMouseState.X; }
        }
        /// <summary>
        /// 当前帧鼠标的视口Y坐标
        /// </summary>
        static public int CurMouseY
        {
            get { return curMouseState.Y; }
        }
        /// <summary>
        /// 当前帧的鼠标视口位置
        /// </summary>
        static public Point CurMousePos
        {
            get { return new Point( CurMouseX, CurMouseY ); }
        }
        /// <summary>
        /// 获得当前帧鼠标的逻辑位置
        /// </summary>
        static public Vector2 GetCurMousePosInLogic ( RenderEngine engine )
        {
            return engine.CoordinMgr.LogicPos( ConvertHelper.PointToVector2( CurMousePos ) );
        }
        /// <summary>
        /// 当前帧与上一帧之间鼠标是否移动
        /// </summary>
        static public bool MouseMoved
        {
            get { return CurMouseX != LastMouseX || CurMouseY != LastMouseY; }
        }
        /// <summary>
        /// 当前帧与上一帧之间鼠标视口位置的X增量
        /// </summary>
        static public int MouseXDelta
        {
            get { return CurMouseX - LastMouseX; }
        }
        /// <summary>
        /// 当前帧与上一帧之间鼠标视口位置的Y增量
        /// </summary>
        static public int MouseYDelta
        {
            get { return CurMouseY - LastMouseY; }
        }
        /// <summary>
        /// 当前帧与上一帧之间鼠标滚轮的增量
        /// </summary>
        static public int MouseWheelDelta
        {
            get { return curMouseState.ScrollWheelValue - lastMouseState.ScrollWheelValue; }
        }
        /// <summary>
        /// 当前帧鼠标左键是否按下
        /// </summary>
        static public bool CurMouseLeftDown
        {
            get { return curMouseState.LeftButton == ButtonState.Pressed; }
        }
        /// <summary>
        /// 当前帧鼠标右键是否按下
        /// </summary>
        static public bool CurMouseRightDown
        {
            get { return curMouseState.RightButton == ButtonState.Pressed; }
        }
        /// <summary>
        /// 当前帧鼠标中键是否按下
        /// </summary>
        static public bool CurMouseMidDown
        {
            get { return curMouseState.MiddleButton == ButtonState.Pressed; }
        }
        /// <summary>
        /// 上一帧鼠标左键是否按下
        /// </summary>
        static public bool LastMouseLeftDown
        {
            get { return lastMouseState.LeftButton == ButtonState.Pressed; }
        }
        /// <summary>
        /// 上一帧鼠标右键是否按下
        /// </summary>
        static public bool LastMouseRightDown
        {
            get { return lastMouseState.RightButton == ButtonState.Pressed; }
        }
        /// <summary>
        /// 上一帧鼠标中键是否按下
        /// </summary>
        static public bool LastMouseMidDown
        {
            get { return lastMouseState.MiddleButton == ButtonState.Pressed; }
        }
        /// <summary>
        /// 鼠标是否在当前帧释放了左键
        /// </summary>
        static public bool MouseJustReleaseLeft
        {
            get { return LastMouseLeftDown && !CurMouseLeftDown; }
        }
        /// <summary>
        /// 鼠标是否在当前帧释放了右键
        /// </summary>
        static public bool MouseJustReleaseRight
        {
            get { return LastMouseRightDown && !CurMouseRightDown; }
        }
        /// <summary>
        /// 鼠标是否在当前帧释放了中键
        /// </summary>
        static public bool MouseJustReleaseMid
        {
            get { return LastMouseMidDown && !CurMouseMidDown; }
        }
        /// <summary>
        /// 鼠标是否在当前帧按下了左键
        /// </summary>
        static public bool MouseJustPressLeft
        {
            get { return !LastMouseLeftDown && CurMouseLeftDown; }
        }
        /// <summary>
        /// 鼠标是否在当前帧按下了右键
        /// </summary>
        static public bool MouseJustPressRight
        {
            get { return !LastMouseRightDown && CurMouseRightDown; }
        }
        /// <summary>
        /// 鼠标是否在当前帧按下了中键
        /// </summary>
        static public bool MouseJusePressMid
        {
            get { return !LastMouseMidDown && CurMouseMidDown; }
        }

        #endregion

        #region Help Functions

        /// <summary>
        /// 判断鼠标是否在矩形中
        /// </summary>
        /// <param name="rect"></param>
        /// <returns></returns>
        static public bool MouseInRect ( Rectangle rect )
        {
            return rect.Contains( new Point( CurMouseX, CurMouseY ) );
        }

        #endregion

        #endregion

        #region KeyBoard

        static KeyboardState curKeyboardState;
        static KeyboardState lastKeyboardState;

        /// <summary>
        /// 判断某按键当前是否处于按下状态
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        static public bool IsKeyDown ( Keys key )
        {
            return curKeyboardState.IsKeyDown( key );
        }
        /// <summary>
        /// 判断某按键是否在当前帧被按下
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        static public bool JustPressKey ( Keys key )
        {
            return curKeyboardState.IsKeyDown( key ) && lastKeyboardState.IsKeyUp( key );
        }
        /// <summary>
        /// 判断某按键是否在当前帧被释放
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        static public bool JustReleaseKey ( Keys key )
        {
            return curKeyboardState.IsKeyUp( key ) && lastKeyboardState.IsKeyDown( key );
        }

        #endregion

        #region Update

        /// <summary>
        /// 更新输入处理类
        /// </summary>
        static public void Update ()
        {
            MouseState MS = Mouse.GetState();
            KeyboardState KS = Keyboard.GetState();

            #region Update Mouse
            lastMouseState = curMouseState;
            curMouseState = MS;
            #endregion

            #region Update Keyboard

            lastKeyboardState = curKeyboardState;
            curKeyboardState = KS;

            #endregion
        }

        #endregion

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.Draw;
using Microsoft.Xna.Framework.Graphics;
using System.IO;
using SmartTank.Shelter;
using SmartTank.AI;
using SmartTank.Senses.Vision;
using TankEngine2D.DataStructure;
using TankEngine2D.Graphics;
using SmartTank.Senses.Memory;
using TankEngine2D.Helpers;
using SmartTank.Helpers;

namespace SmartTank.GameObjs.Tank.SinTur
{
    public class TankSinTur : Tank, IRaderOwner, IAIOrderServerSinTur, IEyeableObj
    {
        #region Statics

        static public string M1A2TexPath = Path.Combine( Directories.GameObjsDirectory, "Internal\\M1A2" );
        static public GameObjData M1A2Data = GameObjData.Load( File.OpenRead( Path.Combine( M1A2TexPath, "M1A2.xml" ) ) );

        static public string M60TexPath = Path.Combine( Directories.GameObjsDirectory, "Internal\\M60" );
        static public GameObjData M60Data = GameObjData.Load( File.OpenRead( Path.Combine( M60TexPath, "M60.xml" ) ) );

        static public string TigerTexPath = Path.Combine( Directories.GameObjsDirectory, "Internal\\Tiger" );
        static public GameObjData TigerData = GameObjData.Load( File.OpenRead( Path.Combine( TigerTexPath, "Tiger.xml" ) ) );

        #endregion

        #region Events

        public event ShootEventHandler onShoot;

        public event OnCollidedEventHandler onCollide;

        public event OnCollidedEventHandler onOverLap;

        public event BorderObjUpdatedEventHandler onBorderObjUpdated;

        #endregion

        #region Variables

        TankContrSinTur controller;

        TankSkinSinTur skin;

        Rader rader;

        float shellSpeed;

        #endregion

        #region Properties

        public float FireCDTime
        {
            get { return controller.fireCDTime; }
            set
            {
                controller.fireCDTime = Math.Max( 0, value );
            }
        }

        public override Vector2 Pos
        {
            get { return controller.Pos; }
            set { controller.Pos = value; }
        }

        public Vector2 TurretAxePos
        {
            get { return skin.Sprites[1].Pos; }
        }

        public override float Azi
        {
            get { return controller.Azi; }
            set { controller.Azi = value; }
        }

        public Vector2 Direction
        {
            get { return MathTools.NormalVectorFromAzi( Azi ); }
        }

        public float TurretAimAzi
        {
            get { return controller.Azi + controller.turretAzi; }
        }

        public float TurretAzi
        {
            get { return controller.turretAzi; }
        }

        public float RaderRadius
        {
            get
            {
                return rader.R;
            }
        }

        public float RaderAng
        {
            get
            {
                return rader.Ang;
            }
        }

        public float RaderAzi
        {
            get { return controller.raderAzi; }
        }

        public float RaderAimAzi
        {
            get { return controller.Azi + controller.raderAzi; }
        }

        public float MaxForwardSpeed
        {
            get { return controller.limit.MaxForwardSpeed; }
        }

        public float MaxBackwardSpeed
        {
            get { return controller.limit.MaxBackwardSpeed; }
        }

        public float MaxRotaSpeed
        {
            get { return controller.limit.MaxTurnAngleSpeed; }
        }

        public float MaxRotaTurretSpeed
        {
            get { return controller.limit.MaxTurretAngleSpeed; }
        }

        public float MaxRotaRaderSpeed
        {
            get { return controller.limit.MaxRaderAngleSpeed; }
        }

        public float ShellSpeed
        {
            get { return shellSpeed; }
            set { shellSpeed = value; }
        }

        public float TurretLength
        {
            get { return skin.TurretLength; }
        }

        public override CircleList<BorderPoint> BorderData
        {
            get { return skin.Sprites[0].BorderData; }
        }

        public override Matrix WorldTrans
        {
            get { return skin.Sprites[0].Transform; }
        }

        public override Rectanglef BoundingBox
        {
            get { return skin.Sprites[0].BoundRect; }
        }

        #endregion

        #region Consturction

        public TankSinTur( string name, GameObjInfo objInfo, string texPath, GameObjData skinData,
            float raderLength, float raderAng, Color raderColor,
            float maxForwardSpeed, float maxBackwardSpeed, float maxRotaSpeed,
            float maxTurretRotaSpeed, float maxRaderRotaSpeed, float fireCDTime,
            Vector2 pos, float baseAzi )
            : this( name, objInfo, texPath, skinData,
            raderLength, raderAng, raderColor, 0, maxForwardSpeed, maxBackwardSpeed, maxRotaSpeed, maxTurretRotaSpeed,
            maxRaderRotaSpeed, fireCDTime, pos, 0, 0 )
        {
        }

        public TankSinTur( string name, GameObjInfo objInfo, string texPath, GameObjData skinData,
            float raderLength, float raderAng, Color raderColor, float raderAzi,
            float maxForwardSpeed, float maxBackwardSpeed, float maxRotaSpeed,
            float maxTurretRotaSpeed, float maxRaderRotaSpeed, float fireCDTime,
            Vector2 pos, float baseRota, float turretRota )
        {
            this.name = name;
            this.objInfo = objInfo;
            this.skin = new TankSkinSinTur( new TankSkinSinTurData( texPath, skinData ) );
            skin.Initial( pos, baseRota, turretRota );
            controller = new TankContrSinTur( objInfo, new Sprite[] { skin.Sprites[0] } , pos, baseRota, maxForwardSpeed, maxBackwardSpeed, maxRotaSpeed, maxTurretRotaSpeed, maxRaderRotaSpeed, Math.Max( 0, fireCDTime ) );
            colChecker = controller;
            phisicalUpdater = controller;
            controller.onShoot += new EventHandler( controller_onShoot );
            controller.OnCollied += new OnCollidedEventHandler( controller_OnCollied );
            controller.OnOverlap += new OnCollidedEventHandler( controller_OnOverlap );
            rader = new Rader( raderAng, raderLength, pos, raderAzi + baseRota, raderColor );
        }

        #endregion

        #region Update

        public override void Update( float seconds )
        {
            base.Update( seconds );
            controller.Update( seconds );
            skin.Update( seconds );
        }


        #endregion

        #region Dead
        public override void Dead()
        {
            base.Dead();
            controller.Enable = false;
        }
        #endregion

        #region Draw

        public override void Draw()
        {
            skin.ResetSprites( controller.Pos, controller.Azi, controller.turretAzi );
            skin.Draw();

            if (!isDead)
            {
                rader.Pos = Pos;
                rader.Azi = controller.raderAzi + controller.Azi;
                rader.Draw();
            }

            base.Draw();
        }

        #endregion

        #region EventHandler

        void controller_onShoot( object sender, EventArgs e )
        {
            if (onShoot != null)
                onShoot( this, skin.GetTurretEndPos( controller.Pos, controller.Azi, controller.turretAzi ), controller.Azi + controller.turretAzi );

            skin.BeginRecoil();
        }

        void controller_OnOverlap( IGameObj Sender, CollisionResult result, GameObjInfo objB )
        {
            if (onOverLap != null)
                onOverLap( this, result, objB );

            if (OnOverLap != null)
                OnOverLap( result, objB );
        }

        void controller_OnCollied( IGameObj Sender, CollisionResult result, GameObjInfo objB )
        {
            if (onCollide != null)
                onCollide( this, result, objB );

            if (OnCollide != null)
                OnCollide( result, objB );
        }

        #endregion

        #region IRaderOwner 成员

        public Rader Rader
        {
            get { return rader; }
        }

        public List<IEyeableInfo> CurEyeableObjs
        {
            set
            {
                rader.CurEyeableObjs = value;
            }
        }

        public void BorderObjUpdated( EyeableBorderObjInfo[] borderObjInfo )
        {
            if (onBorderObjUpdated != null)
                onBorderObjUpdated( borderObjInfo );
        }

        #endregion

        #region IAIOrderServerSinTur 成员

        public List<IEyeableInfo> GetEyeableInfo()
        {
            return rader.CurEyeableObjs;
        }

        public float ForwardSpeed
        {
            get
            {
                return controller.ForwardSpeed;
            }
            set
            {
                controller.ForwardSpeed = value;
            }
        }

        public float TurnRightSpeed
        {
            get
            {
                return controller.TurnRightSpeed;
            }
            set
            {
                controller.TurnRightSpeed = value;
            }
        }

        public float TurnTurretWiseSpeed
        {
            get
            {
                return controller.TurnTurretWiseSpeed;
            }
            set
            {
                controller.TurnTurretWiseSpeed = value;
            }
        }

        public float FireLeftCDTime
        {
            get { return controller.FireLeftCDTime; }
        }

        public float TurnRaderWiseSpeed
        {
            get
            {
                return controller.TurnRaderWiseSpeed;
            }
            set
            {
                controller.TurnRaderWiseSpeed = value;
            }
        }

        public void Fire()
        {
            controller.Fire();
        }

        public float TankWidth
        {
            get { return skin.TankWidth; }
        }

        public float TankLength
        {
            get { return skin.TankLength; }
        }

        public event OnCollidedEventHandlerAI OnCollide;

        public event OnCollidedEventHandlerAI OnOverLap;

        public EyeableBorderObjInfo[] EyeableBorderObjInfos
        {
            get { return rader.ObjMemoryKeeper.GetEyeableBorderObjInfos(); }
        }

        public NavigateMap CalNavigateMap( NaviMapConsiderObj selectFun, Rectanglef mapBorder, float spaceForTank )
        {
            return rader.ObjMemoryKeeper.CalNavigationMap( selectFun, mapBorder, spaceForTank );
        }

        #endregion

        #region IEyeableObj 成员

        static public IEyeableInfo GetCommonEyeInfoFun( IRaderOwner raderOwner, IEyeableObj tank )
        {
            return new TankCommonEyeableInfo( (TankSinTur)tank );
        }

        public class TankCommonEyeableInfo : IEyeableInfo
        {
            EyeableInfo eyeableInfo;

            Vector2 vel;
            float azi;
            Vector2 direction;
            float turretAimAzi;

            public Vector2 Pos
            {
                get { return eyeableInfo.Pos; }
            }

            public Vector2 Vel
            {
                get { return vel; }
            }

            public float Azi
            {
                get { return azi; }
            }

            public Vector2 Direction
            {
                get { return direction; }
            }

            public float TurretAimAzi
            {
                get { return turretAimAzi; }
            }

            public TankCommonEyeableInfo( TankSinTur tank )
            {
                this.eyeableInfo = new EyeableInfo( tank );

                this.azi = tank.Azi;
                this.vel = tank.Direction * tank.ForwardSpeed;
                this.direction = tank.Direction;
                this.turretAimAzi = tank.TurretAimAzi;
            }

            #region IEyeableInfo 成员

            public GameObjInfo ObjInfo
            {
                get { return eyeableInfo.ObjInfo; }
            }

            public Vector2[] CurKeyPoints
            {
                get { return eyeableInfo.CurKeyPoints; }
            }

            public Matrix CurTransMatrix
            {
                get { return eyeableInfo.CurTransMatrix; }
            }

            #endregion
        }

        public Vector2[] KeyPoints
        {
            get { return skin.VisiKeyPoints; }
        }

        public Matrix TransMatrix
        {
            get { return skin.Sprites[0].Transform; }
        }

        GetEyeableInfoHandler getEyeableInfoHandler;

        public GetEyeableInfoHandler GetEyeableInfoHandler
        {
            get
            {
                return getEyeableInfoHandler;
            }
            set
            {
                getEyeableInfoHandler = value;
            }
        }

        #endregion

        #region IAIOrderServer 成员




        #endregion



    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Graphics;

namespace SmartTank.PhiCol
{
    /// <summary>
    /// 为精灵提供的碰撞检测方法
    /// </summary>
    public class SpriteColMethod : IColMethod
    {
        Sprite[] colSprites;

        /// <summary>
        /// 获得用于冲突检测的精灵
        /// </summary>
        public Sprite[] ColSprites
        {
            get { return colSprites; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="colSprites">用于冲突检测的精灵</param>
        public SpriteColMethod ( Sprite[] colSprites )
        {
            this.colSprites = colSprites;
        }

        #region IColMethod 成员

        /// <summary>
        /// 检测与另一对象是否冲突
        /// </summary>
        /// <param name="colB"></param>
        /// <returns></returns>
        public CollisionResult CheckCollision ( IColMethod colB )
        {
            return colB.CheckCollisionWithSprites( this );
        }

        /// <summary>
        /// 检测与精灵对象是否冲突
        /// </summary>
        /// <param name="spriteChecker"></param>
        /// <returns></returns>
        public CollisionResult CheckCollisionWithSprites ( SpriteColMethod spriteChecker )
        {
            foreach (Sprite spriteA in spriteChecker.colSprites)
            {
                foreach (Sprite spriteB in this.colSprites)
                {
                    CollisionResult result = Sprite.IntersectPixels( spriteA, spriteB );
                    if (result.IsCollided)
                        return result;
                }
            }
            return new CollisionResult( false );
        }

        /// <summary>
        /// 检测与边界对象是否冲突
        /// </summary>
        /// <param name="Border"></param>
        /// <returns></returns>
        public CollisionResult CheckCollisionWithBorder ( BorderMethod Border )
        {
            CollisionResult temp = Border.CheckCollisionWithSprites( this );
            return new CollisionResult( temp.IsCollided, temp.InterPos, -temp.NormalVector );
        }

        #endregion


    }

}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;

namespace TankEngine2D.Graphics
{
    /// <summary>
    /// 所有的动画的管理类
    /// </summary>
    public class AnimatedMgr
    {
        List<IAnimated> animates = new List<IAnimated>();

        /// <summary>
        /// 绘制当前活动的所有动画。
        /// 会更新所有的动画。但某动画结束时，会自动从保存的列表中删除。
        /// </summary>
        public void Draw ()
        {
            for (int i = 0; i < animates.Count; i++)
            {
                if (animates[i].IsStart)
                {
                    animates[i].DrawCurFrame();
                }

                if (animates[i].IsEnd)
                {
                    animates.Remove( animates[i] );
                    i--;
                }
            }
        }

        /// <summary>
        /// 清空保存的所有动画
        /// </summary>
        public void Clear ()
        {
            animates.Clear();
        }

        internal void Add ( IAnimated animatedSprite )
        {
            animates.Add( animatedSprite );
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Screens;

namespace SmartTank.Rule
{
    /*
     * 定义了平台规则需要继承的接口
     * 
     * */
    public interface IGameRule : IGameScreen
    {
        string RuleName { get;}
        string RuleIntroduction { get;}
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.Effects.SceneEffects.BaseEffects;
using System.IO;
using TankEngine2D.Helpers;
using SmartTank.Helpers;
using SmartTank.Draw;

namespace SmartTank.Effects.SceneEffects
{
    public class ShellExplodeBeta
    {
        ScaleUp scaleUp;

        public static void LoadResources ()
        {

        }

        public ShellExplodeBeta ( Vector2 pos, float rota )
        {
            scaleUp = new ScaleUp( Path.Combine( Directories.ContentDirectory, "SceneEffects\\star2" ), new Vector2( 64, 64 ), LayerDepth.EffectLow,
                pos,
                delegate( float curTime, float lastRadius )
                {
                    if (curTime == 0)
                        return 3f;
                    else
                        return lastRadius + 0.3f;
                },
                delegate( float curTime )
                {
                    return 0;
                }, 20 );
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.PhiCol;
using SmartTank.Shelter;
using SmartTank.Senses.Vision;
using TankEngine2D.Graphics;
using TankEngine2D.DataStructure;

namespace SmartTank.GameObjs.Item
{
    public class ObstacleCommon : IGameObj, ICollideObj, IShelterObj, IEyeableObj, IColChecker
    {
        //static public IEyeableInfo GetEyeableInfoHandlerCommon ( IRaderOwner raderOwner, IEyeableObj obstacle )
        //{
        //    return new ObstacleCommomEyeableInfo( (ObstacleCommon)obstacle );
        //}

        //public class ObstacleCommomEyeableInfo : IEyeableInfo
        //{
        //    EyeableInfo eyeableInfo;

        //    Vector2 pos;
        //    GameObjInfo objInfo;

        //    public ObstacleCommomEyeableInfo ( ObstacleCommon obstacle )
        //    {
        //        this.pos = obstacle.pos;
        //        this.objInfo = obstacle.objInfo;
        //    }

        //    public Vector2 Pos
        //    {
        //        get { return pos; }
        //    }

        //    #region IEyeableInfo 成员

        //    public GameObjInfo ObjInfo
        //    {
        //        get { return objInfo; }
        //    }

        //    #endregion
        //}

        public event OnCollidedEventHandler OnCollided;
        public event OnCollidedEventHandler OnOverLap;

        string name;
        GameObjInfo objInfo;
        Vector2 pos;
        float azi;
        SpriteColMethod colMethod;
        Sprite sprite;
        Vector2[] keyPoints;


        public ObstacleCommon( string name, GameObjInfo objInfo, Vector2 pos, float azi,
            string texAssetPath, Vector2 origin, float scale, Color color, float layerDepth, Vector2[] keyPoints )
        {
            this.name = name;
            this.objInfo = objInfo;
            this.pos = pos;
            this.azi = azi;
            this.sprite = new Sprite( BaseGame.RenderEngine, BaseGame.ContentMgr, texAssetPath, true );
            this.sprite.SetParameters( origin, pos, scale, azi, color, layerDepth, SpriteBlendMode.AlphaBlend );
            this.keyPoints = keyPoints;
            this.colMethod = new SpriteColMethod( new Sprite[] { this.sprite } );
        }

        #region IGameObj 成员

        public GameObjInfo ObjInfo
        {
            get { return objInfo; }
        }

        public Microsoft.Xna.Framework.Vector2 Pos
        {
            get
            {
                return pos;
            }
            set
            {
                pos = value;
            }
        }

        public float Azi
        {
            get { return azi; }
        }

        #endregion

        #region IUpdater 成员

        public void Update( float seconds )
        {
            sprite.UpdateTransformBounding();
        }

        #endregion

        #region IDrawableObj 成员

        public void Draw()
        {
            sprite.Draw();
        }

        #endregion

        #region ICollideObj 成员


        public IColChecker ColChecker
        {
            get { return this; }
        }

        #endregion

        #region IHasBorderObj 成员

        public CircleList<BorderPoint> BorderData
        {
            get { return sprite.BorderData; }
        }

        public Microsoft.Xna.Framework.Matrix WorldTrans
        {
            get { return sprite.Transform; }
        }

        public Rectanglef BoundingBox
        {
            get { return sprite.BoundRect; }
        }

        #endregion

        #region IEyeableObj 成员

        public Microsoft.Xna.Framework.Vector2[] KeyPoints
        {
            get { return keyPoints; }
        }

        public Microsoft.Xna.Framework.Matrix TransMatrix
        {
            get { return sprite.Transform; }
        }

        GetEyeableInfoHandler getEyeableInfoHandler;

        public GetEyeableInfoHandler GetEyeableInfoHandler
        {
            get
            {
                return getEyeableInfoHandler;
            }
            set
            {
                getEyeableInfoHandler = value;
            }
        }

        #endregion

        #region IColChecker 成员

        public IColMethod CollideMethod
        {
            get { return colMethod; }
        }

        public void HandleCollision( CollisionResult result, ICollideObj objB )
        {
            if (OnCollided != null)
                OnCollided( this, result, (objB as IGameObj).ObjInfo );
        }

        public void ClearNextStatus()
        {

        }

        public void HandleOverlap( CollisionResult result, ICollideObj objB )
        {
            if (OnOverLap != null)
                OnOverLap( this, result, (objB as IGameObj).ObjInfo );
        }

        #endregion



        #region IGameObj 成员

        public string Name
        {
            get { return name; }
        }

        #endregion

        #region IGameObj 成员

        string mgPath;
        public string MgPath
        {
            get
            {
                return mgPath;
            }
            set
            {
                mgPath = value;
            }
        }

        #endregion
    }
}
<file_sep>//=================================================
// xWinForms
// Copyright ?2007 by <NAME>
// http://psycad007.spaces.live.com/
//=================================================
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace SmartTank.Draw.UI.Controls
{
    public class NumericUpDown : Control
    {
        #region Variables
        Button buttonUp, buttonDown;
        Textbox textbox;

        public int width = 50;
        public int increment = 1; 

        #endregion

        #region Construction
        public NumericUpDown ( string name, Vector2 position, int width, int min, int max, int value, int increment )
        {
            Type = ControlType.NumericUpDown;
            this.name = name;
            this.position = position;
            this.width = width;
            this.min = min;
            this.max = max;
            this.value = value;
            this.increment = increment;

            if (this.increment == 0)
                this.increment = 1;

            textbox = new Textbox( "txt_numericUpDown", position, width, value.ToString(), true );//, HUD.TextFont, Form.Style.Default);
            buttonUp = new Button( "bt_numericUp", "numeric_up", new Vector2( position.X + width, position.Y - 2 ), new Color( new Vector4( 0.9f, 0.9f, 0.9f, 1f ) ) );//, Form.Style.Default, true);
            buttonDown = new Button( "bt_numericDown", "numeric_down", new Vector2( position.X + width, position.Y + buttonUp.size.Y ), new Color( new Vector4( 0.9f, 0.9f, 0.9f, 1f ) ) );//, Form.Style.Default, true);

            buttonUp.OnMouseRelease += new EventHandler( onButtonUp );
            buttonDown.OnMouseRelease += new EventHandler( onButtonDown );
            textbox.OnKeyPress += new EventHandler( onKeyPress );
        } 
        #endregion

        #region Update
        private void onButtonUp ( object obj, EventArgs e )
        {
            if (value.ToString() != textbox.text)
                SetValue( System.Convert.ToInt32( textbox.text ) );

            SetValue( value + increment );
            textbox.text = value.ToString();
        }

        private void onButtonDown ( object obj, EventArgs e )
        {
            if (value.ToString() != textbox.text)
                SetValue( System.Convert.ToInt32( textbox.text ) );

            SetValue( value - increment );
            textbox.text = value.ToString();
        }

        private void onKeyPress ( object obj, EventArgs e )
        {
            //Console.WriteLine("NumericUpDown_OnKeyPress");
            Keys key = (Keys)obj;

            if (key == Keys.Enter)
                SetValue( System.Convert.ToInt32( textbox.text ) );
        }

        public void SetValue ( int value )
        {
            this.value = value;

            if (this.value < min)
                this.value = min;
            else if (this.value > max)
                this.value = max;

            textbox.text = this.value.ToString();
        }

        public override void Update ()// Vector2 formPosition, Vector2 formSize )
        {
            textbox.Update();// formPosition, formSize );

            //base.Update( formPosition, formSize );

            buttonUp.position.X = position.X + width;
            buttonUp.position.Y = position.Y - 1;
            buttonUp.Update();

            buttonDown.position.X = buttonUp.position.X;
            buttonDown.position.Y = buttonUp.position.Y + buttonUp.size.Y - 1;
            buttonDown.Update();

            //CheckVisibility( formPosition, formSize );
        }

        //private void CheckVisibility ( Vector2 formPosition, Vector2 formSize )
        //{
        //    if (position.X + textbox.size.X + buttonUp.size.X > formPosition.X + formSize.X - 15f)
        //        bVisible = false;
        //    else if (position.Y + textbox.size.Y + 15f > formPosition.Y + formSize.Y - 25f)
        //        bVisible = false;
        //    else
        //        bVisible = true;
        //}

        #endregion

        #region Draw
        public override void Draw ( SpriteBatch spriteBatch, float alpha )
        {
            textbox.Draw( spriteBatch, alpha );
            buttonUp.Draw( spriteBatch, alpha );
            buttonDown.Draw( spriteBatch, alpha );

            base.Draw( spriteBatch, alpha );
        } 
        #endregion
    }
}
<file_sep>#include "head.h"
#include "mysocket.h"
#include "mythread.h"
#include "ClientManager.h"
#include "GameProtocol.h"
#include "MyDataBase.h"
using namespace std;

pthread_mutex_t DD_ClientMgr_Mutex[MAXCLIENT];
MySocket SockConn;
MySocket sockSrv;
int  g_MyPort;
int  g_MaxRoommate;
char g_mySqlUserlName[21];
char g_mySqlUserlPass[21];
char g_mySqlDatabase[128];
bool g_isConnect[MAXCLIENT]; // 心跳检测
ClientManager clientMgr;
void HeartBeatFun(int id);
int main()
{
	/* 初始化协议 */ 
    StartSocket();
    GameProtocal gameProtocal;
	clientMgr.AttachProtocal(&gameProtocal);
    gameProtocal.AttachManager(&clientMgr);
    /* 开启监听 */ 
    sockSrv.Bind(MYPORT);
    sockSrv.Listen(); 
    clientMgr.AddServer(&sockSrv);
    cout << "Now Listenning..." << endl;

    // 开启服务器发包线程，传送数据到
    ThreadParam para;
    PThreadParam pp = &para;
    pp->mgr = &clientMgr;

#ifdef WIN32    
    DWORD  threadID;
    CreateThread(0, 0, LPTHREAD_START_ROUTINE(ThreadSend), pp,NULL, &threadID);
#else 
    pthread_t threadID;
    pthread_create(&threadID, NULL, ThreadSend, (void*)pp);
    //signal(SIGALRM   ,HeartBeatFun );       /*   alarm   clock   timeout   */  
#endif
	
	// 主循环
	while ( true )
    {  
        int len = sizeof(sockaddr);
        int sockConn; 
        /*  测试accept返回的socket  */
        if ( -1 == (sockConn = sockSrv.Accept(&SockConn)) ){
            exit(1);
        }

        /* 连接成功，创建新的客户socket以及线程,传送数据到thread */
    	ThreadParam para;
		PThreadParam pp = &para; 
		para.sock = &SockConn;
        para.mgr  = &clientMgr;

        /* 开启客户线程 */
#ifdef WIN32
		CloseHandle(CreateThread(0, 0, LPTHREAD_START_ROUTINE(ThreadClient),
            pp,NULL, &threadID) );
#else
        pthread_t threadID;
        pthread_create(&threadID, NULL, ThreadClient, (void*)pp);
#endif
	}

    /* 清场 */
	sockSrv.Close();
	DestroySocket();
    return 0;
}


void HeartBeatFun(int id)
{
    for (int i = 0; i < clientMgr.GetNum(); i++)
    {
        MySocket *pSock = clientMgr.GetClient(i);
        if (pSock->IsLiving())
        {  
            pSock->m_isLiving = false;
        }
        else
        {
            clientMgr.GetProtocal()->UserExit(pSock);
        }
    }
    cout << "HeartBeat!" << endl;
}




<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using GameEngine.Graphics;
using Common.DataStructure;
using Microsoft.Xna.Framework;

namespace GameEngine.PhiCol
{
    /// <summary>
    /// 边界对象的冲突检测方法
    /// </summary>
    public class BorderColMethod : IColMethod
    {
        Rectanglef borderRect;

        #region IColMethod 成员

        /// <summary>
        /// 检测与另一对象是否冲突
        /// </summary>
        /// <param name="colB"></param>
        /// <returns></returns>
        public CollisionResult CheckCollision( IColMethod colB )
        {
            return colB.CheckCollisionWithBorder( this );
        }

        /// <summary>
        /// 检测与精灵对象是否冲突
        /// </summary>
        /// <param name="spriteChecker"></param>
        /// <returns></returns>
        public CollisionResult CheckCollisionWithSprites( SpriteColMethod spriteChecker )
        {

            foreach (Sprite sprite in spriteChecker.ColSprites)
            {
                CollisionResult result = sprite.CheckOutBorder( borderRect );
                if (result.IsCollided)
                {
                    float originX = result.NormalVector.X;
                    float originY = result.NormalVector.Y;

                    float x, y;

                    if (Math.Abs( originX ) > 0.5)
                        x = 1;
                    else
                        x = 0;
                    if (Math.Abs( originY ) > 0.5)
                        y = 1;
                    else
                        y = 0;

                    x *= Math.Sign( originX );
                    y *= Math.Sign( originY );


                    return new CollisionResult( result.InterPos, new Vector2( x, y ) );
                }
            }
            return new CollisionResult( false );
        }

        /// <summary>
        /// 检测与边界对象是否冲突，该方法无效
        /// </summary>
        /// <param name="Border"></param>
        /// <returns></returns>
        public CollisionResult CheckCollisionWithBorder( BorderColMethod Border )
        {
            throw new Exception( "The method or operation is not implemented." );
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="borderRect">边界矩形</param>
        public BorderColMethod( Rectanglef borderRect )
        {
            this.borderRect = borderRect;
        }

    }

    /// <summary>
    /// 边界对象的冲突检查者
    /// </summary>
    public class BorderColChecker : IColChecker
    {
        BorderColMethod method;

        #region IColChecker 成员

        /// <summary>
        /// 
        /// </summary>
        public IColMethod CollideMethod
        {
            get { return method; }
        }

        /// <summary>
        /// 处理碰撞，空函数
        /// </summary>
        /// <param name="result"></param>
        /// <param name="objB"></param>
        public void HandleCollision( CollisionResult result, ICollideObj objA, ICollideObj objB )
        {
        }

        
        /// <summary>
        /// 处理重叠，空函数
        /// </summary>
        /// <param name="result"></param>
        /// <param name="objB"></param>
        public void HandleOverlap( CollisionResult result, ICollideObj objA, ICollideObj objB )
        {
        }

        /// <summary>
        /// 撤销下一个物理状态，空函数
        /// </summary>
        public void ClearNextStatus()
        {

        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="borderRect">边界矩形</param>
        public BorderColChecker( Rectanglef borderRect )
        {
            method = new BorderColMethod( borderRect );
        }


    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.IO;
using Common.Helpers;

namespace GameEngine.Shelter
{
    public partial class ShelterMgr
    {

        class RaderDrawer
        {
            #region Variables

            readonly int partSum = 30;

            VertexDeclaration del;

            VertexBuffer sectorBuffer;

            Effect renderRaderEffect;

            EffectParameter depthMapPara;
            EffectParameter raderAngPara;
            EffectParameter raderRPara;
            EffectParameter raderColorPara;
            EffectParameter raderRotaMatrixPara;

            DepthStencilBuffer depthBuffer;
            DepthStencilBuffer depthBufferSmall;

            #endregion

            #region Construction

            public RaderDrawer()
            {
                del = new VertexDeclaration( BaseGame.Device, new VertexElement[]{
                new VertexElement(0,0, VertexElementFormat.Vector3,
                VertexElementMethod.Default, VertexElementUsage.Position,0)} );

                sectorBuffer = new VertexBuffer( BaseGame.Device, typeof( Vector3 ),
                    partSum + 2, BufferUsage.WriteOnly );

                InitialVertexBuffer();

                depthBuffer = new DepthStencilBuffer( BaseGame.Device, texSize, texSize, BaseGame.Device.DepthStencilBuffer.Format );
                depthBufferSmall = new DepthStencilBuffer( BaseGame.Device, texSizeSmall, texSizeSmall, BaseGame.Device.DepthStencilBuffer.Format );

                LoadEffect();
            }

            private void LoadEffect()
            {
                renderRaderEffect = BaseGame.ContentMgr.Load<Effect>( Path.Combine( Directories.ContentDirectory, "HLSL\\RaderMap" ) );

                depthMapPara = renderRaderEffect.Parameters["DepthMap"];
                raderAngPara = renderRaderEffect.Parameters["RaderAng"];
                raderRPara = renderRaderEffect.Parameters["RaderR"];
                raderColorPara = renderRaderEffect.Parameters["RaderColor"];
                raderRotaMatrixPara = renderRaderEffect.Parameters["RaderRotaMatrix"];
            }

            private void InitialVertexBuffer()
            {
                Vector3[] vertexData = new Vector3[partSum + 2];
                vertexData[0] = new Vector3( 0, 0, 0.5f );

                float length = 2f / (float)partSum;
                for (int i = 0; i <= partSum; i++)
                {
                    vertexData[i + 1] = new Vector3( -1 + length * i, 1, 0.5f );
                }

                sectorBuffer.SetData<Vector3>( vertexData );
            }
            #endregion

            #region DrawRader

            
            public void DrawRader( Rader rader )
            {
                try
                {
                    BaseGame.Device.RenderState.DepthBufferEnable = false;
                    BaseGame.Device.RenderState.DepthBufferWriteEnable = false;
                    BaseGame.Device.RenderState.AlphaBlendEnable = false;

                    Texture2D depthMapTex = rader.depthMap.GetMapTexture();
                    depthMapPara.SetValue( depthMapTex );

                    raderAngPara.SetValue( rader.Ang );
                    raderColorPara.SetValue( ColorHelper.ToFloat4( rader.RaderColor ) );
                    raderRotaMatrixPara.SetValue( rader.RotaMatrix );
                    renderRaderEffect.CommitChanges();

                    DepthStencilBuffer old = BaseGame.Device.DepthStencilBuffer;

                    BaseGame.Device.SetRenderTarget( 0, rader.target );
                    BaseGame.Device.DepthStencilBuffer = depthBuffer;

                    BaseGame.Device.Clear( Color.TransparentBlack );

                    renderRaderEffect.CurrentTechnique = renderRaderEffect.Techniques[0];
                    renderRaderEffect.Begin();
                    renderRaderEffect.CurrentTechnique.Passes[0].Begin();

                    BaseGame.Device.VertexDeclaration = del;
                    BaseGame.Device.Vertices[0].SetSource( sectorBuffer, 0, del.GetVertexStrideSize( 0 ) );
                    BaseGame.Device.DrawPrimitives( PrimitiveType.TriangleFan, 0, partSum );

                    renderRaderEffect.CurrentTechnique.Passes[0].End();
                    renderRaderEffect.End();

                    BaseGame.Device.SetRenderTarget( 0, rader.targetSmall );
                    BaseGame.Device.DepthStencilBuffer = depthBufferSmall;

                    BaseGame.Device.Clear( Color.TransparentBlack );

                    renderRaderEffect.CurrentTechnique = renderRaderEffect.Techniques[0];
                    renderRaderEffect.Begin();
                    renderRaderEffect.CurrentTechnique.Passes[0].Begin();

                    BaseGame.Device.VertexDeclaration = del;
                    BaseGame.Device.Vertices[0].SetSource( sectorBuffer, 0, del.GetVertexStrideSize( 0 ) );
                    BaseGame.Device.DrawPrimitives( PrimitiveType.TriangleFan, 0, partSum );

                    renderRaderEffect.CurrentTechnique.Passes[0].End();
                    renderRaderEffect.End();
                    BaseGame.Device.SetRenderTarget( 0, null );

                    BaseGame.Device.DepthStencilBuffer = old;

                    BaseGame.Device.RenderState.DepthBufferEnable = true;
                    BaseGame.Device.RenderState.DepthBufferWriteEnable = true;
                }
                catch (Exception ex)
                {
                    Log.Write( ex.Message );
                }
            }

            #endregion
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.Update
{
    /*
     * 需要进一步的完善，添加Interval功能
     * 
     * */

    public delegate void OnTimerCallHandler ();

    public class GameTimer : IUpdater
    {

        static List<GameTimer> sTimers = new List<GameTimer>();

        static public void UpdateTimers ( float seconds )
        {
            for (int i = 0; i < sTimers.Count; i++)
            {
                sTimers[i].Update( seconds );
                if (sTimers[i].isEnd)
                {
                    sTimers.Remove( sTimers[i] );
                    i--;
                }
            }
        }

        static public void ClearAllTimer ()
        {
            sTimers.Clear();
        }

        float curTime = 0;

        float callTime;

        bool isEnd = false;

        public event EventHandler onCall;

        OnTimerCallHandler handler;

        public GameTimer ( float callTime )
        {
            this.callTime = Math.Max( 0, callTime );

            sTimers.Add( this );
        }


        public GameTimer ( float callTime, OnTimerCallHandler handler )
        {
            this.callTime = Math.Max( 0, callTime );

            this.handler = handler;

            sTimers.Add( this );
        }



        #region IUpdater 成员

        public void Update ( float seconds )
        {
            curTime += seconds;

            if (curTime >= callTime)
            {
                if (onCall != null)
                    onCall( this, EventArgs.Empty );

                if (handler != null)
                    handler();

                isEnd = true;
            }
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.AI;
using SmartTank.AI.AIHelper;
using SmartTank.Senses.Memory;
using TankEngine2D.DataStructure;
using SmartTank.Shelter;
using TankEngine2D.Graphics;
using SmartTank;
using SmartTank.Draw;
using TankEngine2D.Input;

namespace InterRules.FindPath
{
    [AIAttribute( "PathFinder No.3", "SmartTank编写组", "利用导航图进行寻路的AI", 2007, 12, 3 )]
    class PathFinderThird : IAISinTur
    {
        IAIOrderServerSinTur orderServer;
        AICommonServer commonServer;
        AIActionHelper action;

        NavigateMap naviMap;
        Rectanglef mapSize;

        #region IAI 成员

        public IAICommonServer CommonServer
        {
            set
            {
                this.commonServer = (AICommonServer)value;
                this.mapSize = commonServer.MapBorder;
            }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                this.orderServer = (IAIOrderServerSinTur)value;
                action = new AIActionHelper( orderServer );
                orderServer.onBorderObjUpdated += new BorderObjUpdatedEventHandler( OnBorderObjUpdated );
            }
        }

        #endregion

        #region Draw

        public void Draw()
        {
            if (naviMap != null)
            {
                foreach (GraphPoint<NaviPoint> naviPoint in naviMap.Map)
                {
                    BaseGame.BasicGraphics.DrawPoint( naviPoint.value.Pos, 1f, Color.Yellow, 0.2f );

                    foreach (GraphPath<NaviPoint> path in naviPoint.neighbors)
                    {
                        BaseGame.BasicGraphics.DrawLine( naviPoint.value.Pos, path.neighbor.value.Pos, 3f, Color.Yellow, 0.2f );
                        BaseGame.FontMgr.Draw( path.weight.ToString(), 0.5f * (naviPoint.value.Pos + path.neighbor.value.Pos), 0.5f, Color.Black, 0f, GameFonts.Lucida );
                    }
                }

                foreach (Segment guardLine in naviMap.GuardLines)
                {
                    BaseGame.BasicGraphics.DrawLine( guardLine.startPoint, guardLine.endPoint, 3f, Color.Red, 0.1f, SpriteBlendMode.AlphaBlend );
                }

                foreach (Segment borderLine in naviMap.BorderLines)
                {
                    BaseGame.BasicGraphics.DrawLine( borderLine.startPoint, borderLine.endPoint, 3f, Color.Brown, 0.1f, SpriteBlendMode.AlphaBlend );
                }
            }

            if (this.path != null && this.path.Length > 0)
            {
                if (curPathIndex < path.Length)
                {
                    BaseGame.BasicGraphics.DrawLine( orderServer.Pos, path[curPathIndex].Pos, 5f, Color.Blue, 0f );

                    for (int i = curPathIndex; i < path.Length - 1; i++)
                    {
                        Vector2 start = path[i].Pos;
                        Vector2 end = path[i + 1].Pos;

                        BaseGame.BasicGraphics.DrawLine( start, end, 5f, Color.Blue, 0f );
                    }
                }
            }
        }

        #endregion

        #region IUpdater 成员

        Vector2 aimPos;
        bool hasOrder = false;

        NaviPoint[] path;
        int curPathIndex = 0;

        public void Update( float seconds )
        {
            CheckOrder();
            CheckOrderFinish();

            action.Update( seconds );
        }

        private void CheckOrder()
        {
            if (InputHandler.CurMouseRightDown)
            {
                if (mapSize.Contains( InputHandler.GetCurMousePosInLogic( BaseGame.RenderEngine ) ))
                {
                    aimPos = InputHandler.GetCurMousePosInLogic( BaseGame.RenderEngine );
                    UpdateNaviMap();
                    if (!naviMap.PointInConvexs( aimPos ))
                    {
                        hasOrder = true;
                        // 由于使用A*算法计算路径的方法已经被NavigateMap收录，故这里用NavigateMap的方法替换了原来的方法。
                        //CalPath();

                        path = naviMap.CalPathUseAStar( orderServer.Pos, aimPos );
                        curPathIndex = 0;

                        MoveToNextKeyPoint();
                    }
                }
            }
        }

        private void MoveToNextKeyPoint()
        {
            if (curPathIndex < path.Length)
            {
                while (curPathIndex < path.Length && Vector2.Distance( orderServer.Pos, path[curPathIndex].Pos ) < 0.3f * orderServer.TankLength)
                {
                    curPathIndex++;
                }
                if (curPathIndex < path.Length)
                    action.AddOrder( new OrderMoveToPosSmooth( path[curPathIndex].Pos, MathHelper.PiOver4, 0, 0,
                        delegate( IActionOrder order )
                        {
                            curPathIndex++;
                            MoveToNextKeyPoint();
                        }, false ) );
            }
        }

        private void CheckOrderFinish()
        {
            if (hasOrder)
            {
                Vector2 destance = orderServer.Pos - aimPos;
                if (destance.LengthSquared() < 1)
                {
                    hasOrder = false;
                    orderServer.ForwardSpeed = 0;
                    orderServer.TurnRightSpeed = 0;
                    orderServer.TurnTurretWiseSpeed = 0;
                    orderServer.TurnRaderWiseSpeed = 0;
                    action.StopMove();
                    action.StopRota();
                    action.StopRotaRader();
                }
            }
        }

        void OnBorderObjUpdated( EyeableBorderObjInfo[] borderObjInfos )
        {
            UpdateNaviMap();

            foreach (EyeableBorderObjInfo obj in orderServer.EyeableBorderObjInfos)
            {
                obj.UpdateConvexHall( orderServer.TankWidth );
            }

            if (hasOrder)
            {
                if (!naviMap.PointInConvexs( aimPos ))
                {
                    // 由于使用A*算法计算路径的方法已经被NavigateMap收录，故这里用NavigateMap的方法替换了原来的方法。
                    //CalPath();

                    path = naviMap.CalPathUseAStar( orderServer.Pos, aimPos );
                    curPathIndex = 0;

                    MoveToNextKeyPoint();
                }
                else
                {
                    hasOrder = false;
                    action.StopMove();
                    action.StopRota();
                    path = new NaviPoint[0] { };
                }
            }
        }

        //class NodeAStar
        //{
        //    public GraphPoint<NaviPoint> point;
        //    public NodeAStar father;

        //    public float G;
        //    public float H;
        //    public float F;

        //    public NodeAStar ( GraphPoint<NaviPoint> point, NodeAStar father )
        //    {
        //        this.point = point;
        //        this.father = father;
        //        this.G = 0;
        //        this.H = 0;
        //        this.F = 0;
        //    }
        //}

        //private void CalPath ()
        //{
        //    if (naviMap == null)
        //        return;

        //    #region 复制导航图
        //    GraphPoint<NaviPoint>[] map = new GraphPoint<NaviPoint>[naviMap.Map.Length + 2];
        //    GraphPoint<NaviPoint>[] temp = GraphPoint<NaviPoint>.DepthCopy( naviMap.Map );
        //    for (int i = 0; i < temp.Length; i++)
        //    {
        //        map[i] = temp[i];
        //    }
        //    #endregion

        //    #region 将当前点和目标点加入到导航图中
        //    int prePointSum = temp.Length;
        //    Vector2 curPos = orderServer.Pos;
        //    GraphPoint<NaviPoint> curNaviPoint = new GraphPoint<NaviPoint>( new NaviPoint( null, -1, curPos ), new List<GraphPath<NaviPoint>>() );
        //    GraphPoint<NaviPoint> aimNaviPoint = new GraphPoint<NaviPoint>( new NaviPoint( null, -1, aimPos ), new List<GraphPath<NaviPoint>>() );
        //    AddCurPosToNaviMap( map, curNaviPoint, prePointSum, naviMap.GuardLines, naviMap.BorderLines );
        //    AddAimPosToNaviMap( map, aimNaviPoint, curNaviPoint, prePointSum, naviMap.GuardLines, naviMap.BorderLines );

        //    #endregion

        //    #region 计算最短路径，使用A*算法

        //    List<NodeAStar> open = new List<NodeAStar>();
        //    List<NodeAStar> close = new List<NodeAStar>();
        //    open.Add( new NodeAStar( curNaviPoint, null ) );

        //    NodeAStar cur = null;
        //    while (open.Count != 0)
        //    {
        //        cur = open[open.Count - 1];

        //        if (cur.point == aimNaviPoint)
        //            break;

        //        open.RemoveAt( open.Count - 1 );
        //        close.Add( cur );

        //        foreach (GraphPath<NaviPoint> path in cur.point.neighbors)
        //        {
        //            if (Contains( close, path.neighbor ))
        //            {
        //                continue;
        //            }
        //            else
        //            {
        //                NodeAStar inOpenNode;
        //                if (Contains( open, path.neighbor, out inOpenNode ))
        //                {
        //                    float G = cur.G + path.weight;
        //                    if (inOpenNode.G > G)
        //                    {
        //                        inOpenNode.G = G;
        //                        inOpenNode.F = G + inOpenNode.H;
        //                    }
        //                }
        //                else
        //                {
        //                    NodeAStar childNode = new NodeAStar( path.neighbor, cur );
        //                    childNode.G = cur.G + path.weight;
        //                    childNode.H = Vector2.Distance( aimPos, childNode.point.value.Pos );
        //                    childNode.F = childNode.G + childNode.H;
        //                    SortInsert( open, childNode );
        //                }
        //            }
        //        }
        //    }

        //    if (cur == null)
        //        return;

        //    Stack<NodeAStar> cahe = new Stack<NodeAStar>();
        //    while (cur.father != null)
        //    {
        //        cahe.Push( cur );
        //        cur = cur.father;
        //    }

        //    this.path = new NaviPoint[cahe.Count];
        //    int j = 0;
        //    foreach (NodeAStar node in cahe)
        //    {
        //        this.path[j] = node.point.value;
        //    }
        //    curPathIndex = 0;

        //    #endregion
        //}

        //private void SortInsert ( List<NodeAStar> open, NodeAStar childNode )
        //{
        //    int i = 0;
        //    while (i < open.Count && open[i].F > childNode.F)
        //    {
        //        i++;
        //    }
        //    if (i == open.Count)
        //        open.Add( childNode );
        //    else
        //        open.Insert( i, childNode );
        //}

        //private bool Contains ( List<NodeAStar> list, GraphPoint<NaviPoint> graphPoint, out NodeAStar findNode )
        //{
        //    if ((findNode = list.Find( new Predicate<NodeAStar>(
        //        delegate( NodeAStar node )
        //        {
        //            if (node.point == graphPoint)
        //                return true;
        //            else
        //                return false;
        //        } ) )) == null)
        //        return false;
        //    else
        //        return true;
        //}

        //private bool Contains ( List<NodeAStar> list, GraphPoint<NaviPoint> graphPoint )
        //{
        //    if (list.Find( new Predicate<NodeAStar>(
        //        delegate( NodeAStar node )
        //        {
        //            if (node.point == graphPoint)
        //                return true;
        //            else
        //                return false;
        //        } ) ) == null)
        //        return false;
        //    else
        //        return true;
        //}

        //private void AddCurPosToNaviMap ( GraphPoint<NaviPoint>[] map, GraphPoint<NaviPoint> curNaviP,
        //    int prePointSum, List<Segment> guardLines, List<Segment> borderLines )
        //{
        //    map[prePointSum] = curNaviP;
        //    for (int i = 0; i < prePointSum; i++)
        //    {
        //        Segment seg = new Segment( curNaviP.value.Pos, map[i].value.Pos );

        //        bool cross = false;
        //        foreach (Segment guardLine in guardLines)
        //        {
        //            if (Segment.IsCross( guardLine, seg ))
        //            {
        //                cross = true;
        //                break;
        //            }
        //        }

        //        if (!cross)
        //        {
        //            foreach (Segment borderLine in borderLines)
        //            {
        //                if (Segment.IsCross( borderLine, seg ))
        //                {
        //                    cross = true;
        //                    break;
        //                }

        //            }
        //        }

        //        if (!cross)
        //        {
        //            float weight = Vector2.Distance( curNaviP.value.Pos, map[i].value.Pos );
        //            GraphPoint<NaviPoint>.Link( map[i], curNaviP, weight );
        //        }
        //    }
        //}

        //private void AddAimPosToNaviMap ( GraphPoint<NaviPoint>[] map, GraphPoint<NaviPoint> aimNaviP, GraphPoint<NaviPoint> curNaviP,
        //    int prePointSum, List<Segment> guardLines, List<Segment> borderLines )
        //{
        //    map[prePointSum + 1] = aimNaviP;
        //    for (int i = 0; i < prePointSum; i++)
        //    {
        //        Segment seg = new Segment( aimNaviP.value.Pos, map[i].value.Pos );

        //        bool cross = false;
        //        foreach (Segment guardLine in guardLines)
        //        {
        //            if (Segment.IsCross( guardLine, seg ))
        //            {
        //                cross = true;
        //                break;
        //            }
        //        }

        //        if (!cross)
        //        {
        //            foreach (Segment borderLine in borderLines)
        //            {
        //                if (Segment.IsCross( borderLine, seg ))
        //                {
        //                    cross = true;
        //                    break;
        //                }

        //            }
        //        }

        //        if (!cross)
        //        {
        //            float weight = Vector2.Distance( aimNaviP.value.Pos, map[i].value.Pos );
        //            GraphPoint<NaviPoint>.Link( map[i], aimNaviP, weight );
        //        }
        //    }

        //    Segment curToAim = new Segment( curNaviP.value.Pos, aimNaviP.value.Pos );

        //    bool link = true;
        //    foreach (Segment guardLine in guardLines)
        //    {
        //        if (Segment.IsCross( guardLine, curToAim ))
        //        {
        //            if (MathTools.Vector2Cross( guardLine.endPoint - guardLine.startPoint, curNaviP.value.Pos - guardLine.endPoint ) < 0)
        //            {
        //                link = false;
        //                break;
        //            }
        //        }
        //    }

        //    if (link)
        //    {
        //        foreach (Segment borderLine in borderLines)
        //        {
        //            if (Segment.IsCross( borderLine, curToAim ))
        //            {
        //                link = false;
        //                break;
        //            }

        //        }
        //    }

        //    if (link)
        //    {
        //        float weight = Vector2.Distance( curNaviP.value.Pos, aimNaviP.value.Pos );
        //        GraphPoint<NaviPoint>.Link( curNaviP, aimNaviP, weight );
        //    }
        //}

        private void UpdateNaviMap()
        {
            this.naviMap = orderServer.CalNavigateMap( new NaviMapConsiderObj(
                delegate( EyeableBorderObjInfo obj )
                {
                    return true;
                } ), mapSize, orderServer.TankWidth * 0.6f );
        }


        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework.Graphics;
using TankEngine2D.Helpers;
using Microsoft.Xna.Framework.Content;

namespace TankEngine2D
{
    /// <summary>
    /// 绘制模块，支持以下功能：
    ///     多视口的绘制；
    ///     自由平移缩放旋转的摄像机；
    ///     像素级的精灵冲突检测；
    ///     精灵动画绘制与切帧方案；
    ///     中文字体绘制。
    /// </summary>
    public class RenderEngine
    {
        internal readonly string contentPath;

        GraphicsDevice device;

        CoordinMgr coordinMgr;
        SpriteMgr spriteMgr;
        BasicGraphics basicGraphics;
        FontMgr fontMgr;
        AnimatedMgr animatedMgr;

        /// <summary>
        /// 获得图形设备
        /// </summary>
        public GraphicsDevice Device
        {
            get { return device; }
        }
        /// <summary>
        /// 获得坐标管理者
        /// </summary>
        public CoordinMgr CoordinMgr
        {
            get { return coordinMgr; }
        }
        /// <summary>
        /// 获得基础图形绘制者
        /// </summary>
        public BasicGraphics BasicGrahpics
        {
            get { return basicGraphics; }
        }
        /// <summary>
        /// 获得贴图管理者
        /// </summary>
        public SpriteMgr SpriteMgr
        {
            get { return spriteMgr; }
        }
        /// <summary>
        /// 获得文字管理者
        /// </summary>
        public FontMgr FontMgr
        {
            get { return fontMgr; }
        }
        /// <summary>
        /// 获得动画管理者
        /// </summary>
        public AnimatedMgr AnimatedMgr
        {
            get { return animatedMgr; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="device">图形设备</param>
        /// <param name="contentMgr">素材管理者</param>
        /// <param name="contentPath">引擎所需资源路径</param>
        public RenderEngine( GraphicsDevice device, ContentManager contentMgr, string contentPath )
        {
            if (device == null)
                throw new NullReferenceException();

            this.contentPath = contentPath;
            this.device = device;
            this.coordinMgr = new CoordinMgr();
            this.spriteMgr = new SpriteMgr( this );
            this.basicGraphics = new BasicGraphics( this );
            this.fontMgr = new FontMgr( this, contentMgr );
            this.animatedMgr = new AnimatedMgr();

            Log.Initialize();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="device">图形设备</param>
        /// <param name="contentPath">引擎所需资源路径</param>
        public RenderEngine( GraphicsDevice device, string contentPath )
            : this( device, null, contentPath )
        {
        }

        /// <summary>
        /// 开始绘制
        /// </summary>
        public void BeginRender()
        {
            this.spriteMgr.SpriteBatchBegin();
        }

        /// <summary>
        /// 结束绘制
        /// </summary>
        public void EndRender()
        {
            this.spriteMgr.SpriteBatchEnd();
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.net
{
    static public class PurviewMgr
    {
        static bool isMainHost;
        static public bool IsMainHost
        {
            get { return isMainHost; }
            set { isMainHost = value; }
        }

        static String serverAddress;
        static public String ServerAddress
        {
            get { return serverAddress; }
        }

        //static Dictionary<string, object> MainHostMgObjList = new Dictionary<string, object>();
        static Dictionary<string, object> SlaveMgList = new Dictionary<string, object>();


        //static public void RegistMainMgObj(string objMgPath)
        //{
        //    MainHostMgObjList.Add(objMgPath, null);
        //}

        static public void RegistSlaveMgObj(string objMgPath)
        {
            SlaveMgList.Add(objMgPath, null);
        }

        //internal static bool IsMainHostMgObj(string objMgPath)
        //{
        //    return MainHostMgObjList.ContainsKey(objMgPath);
        //}

        public static bool IsSlaveMgObj(string objMgPath)
        {
            return SlaveMgList.ContainsKey(objMgPath);
        }

        internal static void Close()
        {
            SlaveMgList.Clear();
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Rule;
using SmartTank.Screens;
using SmartTank.net;
using SmartTank.GameObjs;
using SmartTank.PhiCol;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TankEngine2D.Graphics;
using SmartTank;
using SmartTank.Draw;
using TankEngine2D.Helpers;
using TankEngine2D.Input;
using Microsoft.Xna.Framework.Input;
using SmartTank.Scene;
using System.IO;
using SmartTank.Helpers;
using SmartTank.GameObjs.Shell;
using TankEngine2D.DataStructure;
using SmartTank.Effects.SceneEffects;
using SmartTank.Effects;
using SmartTank.Sounds;
using SmartTank.Draw.UI.Controls;
using System.Runtime.InteropServices;
using System.Timers;

namespace InterRules.Starwar
{
    [RuleAttribute("Starwar", "支持多人联机的空战规则", "编写组成员：...", 2009, 4, 8)]



    class StarwarRule : IGameRule
    {
        [StructLayoutAttribute(LayoutKind.Sequential,Size=42, CharSet = CharSet.Ansi, Pack = 1)]
        struct LoginData
        {
            public const int size = 42;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)]
            public char[] Name;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)]
            public char[] Password;
        }


        
        public string RuleIntroduction
        {
            get { return "20090328~20090417:编写组成员：..."; }
        }

        public string RuleName
        {
            get { return "Starwar"; }
        }

        //Timer heartTimer;

        Texture2D bgTexture, npTexture;
        Rectangle bgRect;
        SpriteBatch spriteBatch;
        Textbox namebox, passbox;
        TextButton btnLogin, btnClear;
        int wait;
        bool bHasError;


        public StarwarRule()
        {
            BaseGame.ShowMouse = true;

            bgTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.BgContent, "bg"));
            npTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.UIContent, "namepass"));
            bgRect = new Rectangle(0, 0, 800, 600);
            namebox = new Textbox("namebox", new Vector2(320, 400), 150, "", false);
            passbox = new Textbox("passbox", new Vector2(320, 430), 150, "", false);
            passbox.bStar = true;
            namebox.maxLen = 20;
            passbox.maxLen = 20;
            btnLogin = new TextButton("OkLogin", new Vector2(320, 480), "Login", 0, Color.Gold);
            btnClear = new TextButton("ClearBtn", new Vector2(405, 480), "Clear", 0, Color.Gold);
            SocketMgr.OnReceivePkg += new SocketMgr.ReceivePkgEventHandler(OnReceivePack);
            btnLogin.OnClick += new EventHandler(btnLogin_OnPress);
            btnClear.OnClick += new EventHandler(btnClear_OnPress);
            wait = 0;
            bHasError = false;

            SocketMgr.Initial();

            //heartTimer = new Timer(1000);
            //heartTimer.Elapsed += new ElapsedEventHandler(heartTimer_Tick);
        }
        /*
        private void heartTimer_Tick(Object obj, ElapsedEventArgs e)
        {
            stPkgHead head = new stPkgHead();
            MemoryStream Stream = new MemoryStream();
            head.dataSize = 0;
            head.iSytle = 0;
            SocketMgr.SendCommonPackge(head, Stream);
            Stream.Close();
        }
        */
        void OnReceivePack(stPkgHead head, Byte[] data)
        {
            if (wait == 0)
                return;
            
            if (head.iSytle == 11)
            {
                wait--;
                //heartTimer.Start();
                GameManager.AddGameScreen(new Hall(namebox.text));
            }
            if (head.iSytle == 12)
            {
                wait--;
                namebox = new Textbox("namebox", new Vector2(320, 400), 150, "", false);
                passbox = new Textbox("passbox", new Vector2(320, 430), 150, "", false);
                passbox.bStar = true;
                namebox.maxLen = 20;
                passbox.maxLen = 20;
                SocketMgr.Close();
                System.Windows.Forms.MessageBox.Show("用户名密码错误或重登陆！");
            }
            else
            {
                bHasError = true;
            }
        }

        void btnClear_OnPress(object sender, EventArgs e)
        {
            namebox = new Textbox("namebox", new Vector2(320, 400), 150, "", false);
            passbox = new Textbox("passbox", new Vector2(320, 430), 150, "", false);
            passbox.bStar = true;
            namebox.maxLen = 20;
            passbox.maxLen = 20;
        }

        void btnLogin_OnPress(object sender, EventArgs e)
        {

            if (wait != 0)
                return;

            LoginData data;

            data.Name = new char[21];
            char[] temp = namebox.text.ToCharArray();
            for (int i = 0; i < temp.Length; i++)
            {
                data.Name[i] = temp[i];
            }


            data.Password = new char[21];
            temp = passbox.text.ToCharArray();
            for (int i = 0; i < temp.Length; i++)
            {
                data.Password[i] = temp[i];
            }
            stPkgHead head = new stPkgHead();
            MemoryStream Stream = new MemoryStream();
            Stream.Write(SocketMgr.StructToBytes(data), 0, LoginData.size);
            head.dataSize = (int)Stream.Length;
            head.iSytle = 10;
            
            SocketMgr.ConnectToServer();
            SocketMgr.StartReceiveThread();
            SocketMgr.SendCommonPackge(head, Stream);
            Stream.Close();
            
            wait++;
        }

        #region IGameScreen 成员

        public bool Update(float second)
        {

            namebox.Update();
            passbox.Update();
            btnLogin.Update();
            btnClear.Update();
            
            if (InputHandler.IsKeyDown(Keys.Escape))
                return true;

            return false;
        }

        public void Render()
        {   
            BaseGame.Device.Clear(Color.LightSkyBlue);
            spriteBatch = (SpriteBatch)BaseGame.SpriteMgr.alphaSprite;
            spriteBatch.Draw(bgTexture, Vector2.Zero, bgRect, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, LayerDepth.BackGround);
            spriteBatch.Draw(npTexture, new Vector2(230, 401), new Rectangle(0, 0, 88, 46), Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0f); 
            namebox.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            passbox.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            btnLogin.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            btnClear.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
        }

        public void OnClose()
        {
            //heartTimer.Stop();
            SocketMgr.OnReceivePkg -= OnReceivePack;
            SocketMgr.Close();
        }

        #endregion
    }


    


}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Common.DataStructure;
using Common.Helpers;

namespace GameEngine.Draw.BackGround.VergeTile
{

    /*
     * 使用WarCraft3中的地面资源图片拼接地面。
     * 
     * 主要技术是材质分层以及材质之间边缘的判断。
     * 
     * */
    public class VergeTileGround : IBackGround
    {
        #region private struct

        struct gridData
        {
            public int texIndex;
            public Rectangle sourceRect;

            public gridData ( int texIndex, Rectangle sourceRect )
            {
                this.texIndex = texIndex;
                this.sourceRect = sourceRect;
            }
        }

        #endregion

        #region Variables

        SpriteBatch[] batches;

        Rectangle screenViewRect;

        Rectanglef mapSize;

        int gridWidthSum;

        int gridHeightSum;

        float gridScale;

        int[] vertexTexIndexs;

        int[] gridTexIndexs;

        Texture2D[] TexList;

        gridData[][] gridTexData;

        float sourceWidth;

        #endregion

        #region Construction

        public VergeTileGround ( VergeTileData data, Rectangle screenViewRect, Rectanglef mapSize )
        {
            gridWidthSum = data.gridWidth;
            gridHeightSum = data.gridHeight;

            this.screenViewRect = screenViewRect;
            this.mapSize = mapSize;

            float gridScaleInWidth = mapSize.Width / (float)gridWidthSum;
            float gridScaleInHeight = mapSize.Height / (float)gridHeightSum;

            gridScale = Math.Max( gridScaleInWidth, gridScaleInHeight );

            vertexTexIndexs = new int[data.vertexTexIndexs.Length];
            data.vertexTexIndexs.CopyTo( vertexTexIndexs, 0 );

            gridTexIndexs = new int[data.gridTexIndexs.Length];
            data.gridTexIndexs.CopyTo( gridTexIndexs, 0 );

            InitialTexList( data );

            InitialGridTexData();

            CreateSpriteBatches();

            sourceWidth = gridTexData[0][0].sourceRect.Width;

            BaseGame.Device.DeviceReset += new EventHandler( Device_DeviceReset );
        }

        private void CreateSpriteBatches ()
        {
            batches = new SpriteBatch[TexList.Length];
            for (int i = 0; i < batches.Length; i++)
            {
                batches[i] = new SpriteBatch( BaseGame.Device );
            }
        }

        void Device_DeviceReset ( object sender, EventArgs e )
        {
            CreateSpriteBatches();
        }

        private void InitialGridTexData ()
        {
            gridTexData = new gridData[gridWidthSum * gridHeightSum][];
            for (int y = 0; y < gridHeightSum; y++)
            {
                for (int x = 0; x < gridWidthSum; x++)
                {
                    int[] weights = new int[TexList.Length];
                    weights.Initialize();

                    weights[vertexTexIndexs[x + 1 + (gridWidthSum + 1) * (y + 1)]] += 1;
                    weights[vertexTexIndexs[x + (gridWidthSum + 1) * (y + 1)]] += 2;
                    weights[vertexTexIndexs[x + 1 + (gridWidthSum + 1) * y]] += 4;
                    weights[vertexTexIndexs[x + (gridWidthSum + 1) * y]] += 8;

                    List<gridData> tempGridData = new List<gridData>();
                    tempGridData.Add( new gridData( 0, CalcuSourceRect( 0, TexList[0].Width, TexList[0].Height, 17 ) ) );
                    for (int i = 1; i < weights.Length; i++)
                    {
                        if (weights[i] != 0)
                            tempGridData.Add( new gridData( i, CalcuSourceRect( weights[i], TexList[i].Width, TexList[i].Height, gridTexIndexs[x + gridWidthSum * y] ) ) );
                    }
                    gridTexData[x + gridWidthSum * y] = tempGridData.ToArray();
                }
            }
        }

        private Rectangle CalcuSourceRect ( int weight, int texWidth, int texHeight, int gridIndex )
        {
            int tileWidth = texHeight / 4;
            int x = 0;
            int y = 0;



            bool squreMap = (texHeight == texWidth);


            if (weight != 0 && weight != 15)
            {
                x = weight % 4;
                y = weight / 4;
            }
            else if (squreMap)
            {
                if (gridIndex < 9)
                {
                    x = 0;
                    y = 0;
                }
                else
                {
                    x = 3;
                    y = 3;
                }
            }
            else
            {
                if (gridIndex < 16)
                {
                    x = gridIndex % 4 + 4;
                    y = gridIndex / 4;
                }
                else if (gridIndex == 16)
                {
                    x = 0;
                    y = 0;
                }
                else if (gridIndex == 17)
                {
                    x = 3;
                    y = 3;
                }
            }
            return new Rectangle( tileWidth * x, tileWidth * y, tileWidth, tileWidth );
        }

        private void InitialTexList ( VergeTileData data )
        {
            TexList = new Texture2D[data.texPaths.Length];
            for (int i = 0; i < data.texPaths.Length; i++)
            {
                TexList[i] = Texture2D.FromFile( BaseGame.Device, data.texPaths[i] );
            }
        }

        #endregion

        #region IBackGround 成员

        public void Draw ()
        {

            try
            {
                Rectanglef logicViewRect;

                Vector2 upLeft = BaseGame.CoordinMgr.LogicPos( new Vector2( screenViewRect.X, screenViewRect.Y ) );
                Vector2 upRight = BaseGame.CoordinMgr.LogicPos( new Vector2( screenViewRect.X + screenViewRect.Width, screenViewRect.Y ) );
                Vector2 downLeft = BaseGame.CoordinMgr.LogicPos( new Vector2( screenViewRect.X, screenViewRect.Y + screenViewRect.Height ) );
                Vector2 downRight = BaseGame.CoordinMgr.LogicPos( new Vector2( screenViewRect.X + screenViewRect.Width, screenViewRect.Y + screenViewRect.Height ) );

                logicViewRect = MathTools.BoundBox( upLeft, upRight, downLeft, downRight );

                int minX, minY, maxX, maxY;

                minX = Math.Max( 0, (int)((logicViewRect.X - mapSize.X) / gridScale) - 1 );
                minY = Math.Max( 0, (int)((logicViewRect.Y - mapSize.Y) / gridScale) - 1 );

                maxX = (int)((logicViewRect.X + logicViewRect.Width - mapSize.X) / gridScale) + 1;
                maxY = (int)((logicViewRect.Y + logicViewRect.Height - mapSize.Y) / gridScale) + 1;

                foreach (SpriteBatch batch in batches)
                {
                    batch.Begin( SpriteBlendMode.AlphaBlend, SpriteSortMode.FrontToBack, SaveStateMode.None );
                }

                float gridWidthInScrn = BaseGame.CoordinMgr.ScrnLengthf( gridScale );
                float gridHeightInScrn = BaseGame.CoordinMgr.ScrnLengthf( gridScale );

                Vector2 startPosInScrn = BaseGame.CoordinMgr.ScreenPos( new Vector2( minX * gridScale + mapSize.X, minY * gridScale + mapSize.Y ) );

                Vector2 UnitX = Vector2.Transform( new Vector2( gridWidthInScrn, 0 ), BaseGame.CoordinMgr.RotaMatrixFromLogicToScrn );
                Vector2 UnitY = Vector2.Transform( new Vector2( 0, gridHeightInScrn ), BaseGame.CoordinMgr.RotaMatrixFromLogicToScrn );

                float drawScale = gridWidthInScrn / sourceWidth;


                for (int y = minY; y <= maxY && y < gridHeightSum && y >= 0; y++)
                {
                    for (int x = minX; x <= maxX && x < gridWidthSum && x >= 0; x++)
                    {
                        Vector2 drawPos = startPosInScrn + (x - minX) * UnitX + (y - minY) * UnitY;

                        foreach (gridData data in gridTexData[x + gridWidthSum * y])
                        {
                            batches[data.texIndex].Draw( TexList[data.texIndex], drawPos, data.sourceRect, Color.White, -BaseGame.CoordinMgr.Rota, new Vector2( 0, 0 ), drawScale, SpriteEffects.None, 1f );
                        }
                    }
                }

                foreach (SpriteBatch batch in batches)
                {
                    batch.End();
                }
            }
            catch (Exception)
            {
                CreateSpriteBatches();
            }
        }

        #endregion


    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using TankEngine2D.Helpers;
using SmartTank.Draw;
using TankEngine2D;

namespace SmartTank.GameObjs.Tank.SinTur
{
    class TankSkinSinTur
    {

        #region Variables

        TankSkinSinTurData data;

        Sprite baseSprite;
        Sprite turretSprite;

        TurretLinker turretLinker;


        bool recoiling = false;
        bool backing = false;
        int leftBackingFrame;
        int leftRecoilFrame;

        /// <summary>
        /// 以原图像素为单位
        /// </summary>
        Vector2 curTurretAxesPosInPix;

        #endregion

        #region Properties

        public Vector2 Pos
        {
            get { return BasePos; }
        }

        public Vector2 BasePos
        {
            get { return baseSprite.Pos; }
        }

        public float BaseAzi
        {
            get { return baseSprite.Rata; }
        }

        public float TurretAimAzi
        {
            get { return turretSprite.Rata; }
        }

        public float TurretAzi
        {
            get { return turretSprite.Rata - baseSprite.Rata; }
        }

        public Vector2 TurretAxesPos
        {
            get
            {
                return turretSprite.Pos;
            }
        }

        public Vector2 TurretEndPos
        {
            get
            {
                return TurretAxesPos + MathTools.NormalVectorFromAzi( TurretAimAzi ) * data.TurretTexels;
            }
        }

        public float TankWidth
        {
            get { return baseSprite.Width; }
        }

        public float TankLength
        {
            get { return baseSprite.Height; }
        }

        #endregion

        #region Constuctions

        public TankSkinSinTur( TankSkinSinTurData data )
        {
            this.data = data;
        }

        public void Initial( Vector2 pos, float baseRota, float turretRota )
        {
            InitialTurretLinker();
            InitialSprites( pos, baseRota, turretRota );
        }

        private void InitialSprites( Vector2 pos, float baseRota, float turretRota )
        {
            baseSprite = new Sprite( BaseGame.RenderEngine );
            baseSprite.LoadTextureFromFile( data.baseTexPath, true );
            baseSprite.SetParameters( data.baseTexOrigin, pos, data.texScale, baseRota, Color.White, LayerDepth.TankBase, SpriteBlendMode.AlphaBlend );

            turretSprite = new Sprite( BaseGame.RenderEngine );
            turretSprite.LoadTextureFromFile( data.turretTexPath, true );
            turretSprite.SetParameters( data.turretTexOrigin, turretLinker.GetTexturePos( pos, baseRota ), data.texScale, turretRota + baseRota, Color.White, LayerDepth.TankTurret, SpriteBlendMode.AlphaBlend );
        }

        private void InitialTurretLinker()
        {
            curTurretAxesPosInPix = data.turretAxesPos;
            turretLinker = new TurretLinker( curTurretAxesPosInPix, data.baseTexOrigin, data.texScale );
        }

        #endregion

        #region IDrawableObj 成员

        public void Draw()
        {
            baseSprite.Draw();
            turretSprite.Draw();
        }

        #endregion

        #region ITankSkin 成员

        public Sprite[] Sprites
        {
            get { return new Sprite[] { baseSprite, turretSprite }; }
        }

        public void ResetSprites( Vector2 pos, float baseRota, float turretRota )
        {
            baseSprite.Pos = pos;
            baseSprite.Rata = baseRota;
            turretSprite.Pos = turretLinker.GetTexturePos( pos, baseRota );
            turretSprite.Rata = baseRota + turretRota;
        }

        public float TurretLength
        {
            get { return data.TurretTexels * data.texScale; }
        }

        #endregion

        #region GetTurretEndPos

        public Vector2 GetTurretEndPos( Vector2 tankPos, float tankAzi, float turretAzi )
        {
            return turretLinker.GetTexturePos( tankPos, tankAzi ) + MathTools.NormalVectorFromAzi( tankAzi + turretAzi ) * data.TurretTexels * data.texScale;
        }

        #endregion

        #region Recoil Animation

        public void BeginRecoil()
        {
            recoiling = true;
            backing = true;
            leftRecoilFrame = data.recoilFrame;
            leftBackingFrame = data.backFrame;
        }

        #endregion

        #region IUpdater 成员

        public void Update( float seconds )
        {
            if (recoiling)
            {
                if (backing)
                {
                    //Log.Write( "leftBackingFrame = " + leftBackingFrame.ToString() );
                    //curTurretAxesPosInPix = turretAxesPos - MathTools.NormalVectorFromAzi( TurretAzi ) * (backFrame - leftBackingFrame) * recoilTexels;
                    curTurretAxesPosInPix = data.turretAxesPos - MathTools.NormalVectorFromAzi( TurretAzi ) * data.backFrame * BaseGame.CoordinMgr.ScrnLengthf( data.recoilTexels );
                    leftBackingFrame--;
                    if (leftBackingFrame == 0)
                        backing = false;
                }
                else
                {
                    //Log.Write( "leftRecoilFrame = " + leftRecoilFrame.ToString() );

                    curTurretAxesPosInPix = data.turretAxesPos - MathTools.NormalVectorFromAzi( TurretAzi ) * leftRecoilFrame * BaseGame.CoordinMgr.ScrnLengthf( data.recoilTexels );
                    leftRecoilFrame--;
                    if (leftRecoilFrame == 0)
                        recoiling = false;
                }
                turretLinker.SetTurretAxes( curTurretAxesPosInPix );


            }
        }

        #endregion

        public Vector2[] VisiKeyPoints
        {
            get { return data.visiKeyPoints; }
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace MapEditor
{
    public partial class DeviceCanvas : Control
    {
        Timer timer = new Timer();

        public new event EventHandler Paint;

        public DeviceCanvas ()
        {
            InitializeComponent();
            timer.Interval = 30;
            timer.Enabled = true;
            timer.Tick += new EventHandler( timer_Tick );
        }

        void timer_Tick ( object sender, EventArgs e )
        {
            if (Paint != null)
                Paint( this, EventArgs.Empty );
        }


    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.Update
{
    public class UpdateMgr
    {
        List<IEnumerable<IUpdater>> updateGroups = new List<IEnumerable<IUpdater>>();

        public void AddGroup(IEnumerable<IUpdater> group)
        {
            updateGroups.Add( group );
        }

        public void ClearGroups ()
        {
            updateGroups.Clear();
        }

        public void Update ( float seconds )
        {
            foreach (IEnumerable<IUpdater> group in updateGroups)
            {
                foreach (IUpdater updater in group)
                {
                    updater.Update( seconds );
                }
            }
        }
    }
}
<file_sep>/************************************************************
FileName: head.h
Author:   DD.Li     Version :   1.0       Date:2009-2-26
Description:     // MySocket类，封装socket api实现平台无关
***********************************************************/
#ifndef _MYSOCKET_H_
#define _MYSOCKET_H_

#include "head.h"

class MySocket
{
public:
    
    MySocket();
    ~MySocket();         // 析构，关闭套接字

    void Bind(int port);
    void Listen();    // 监听
    void Close();     // 关闭
    int  Accept(MySocket *pSockConn);       // 接受连接<警告：不可传递MySocket引用,原因未知>
    bool Connect( char* chIP, long port);   // 连接

    char* GetIP();                    // 返回IP地址
    char* GetPort(char *outPort);     // 返回端口号(字符串形式)
    long  GetPort();                  // 返回端口号
    bool  GetUserInfo(UserInfo &ui);  // 返回用户信息
    bool  SendPacket( Packet& pack, int realSize);              // 发送数据包
    bool  SendPacketHead( PacketHead& packHead);                // 发送数据包头
    bool  SendPacketChat( char *msg, long leng );               // 发送chat包
    bool  RecvPacket( PacketHead& packHead, Packet& pack);      // 接受数据,返回接收数据长度
    bool  IsLiving(){
        return m_isLiving;
    }
    void  BindName(char* name){         // 绑定name
        strcpy( m_name, name);
    }
public:
    int m_socket;    // 兼容Linux Socket
    int m_ID;        // 标示ID
    char m_sIP[16];  // IP address  
    char m_name[21]; // 用户名
    bool m_bHost;      // 是否主机
    bool m_bInRoom;    // 在房间内
    int  m_score;      // 分数
    int  m_rank;       // 排行

    bool m_isLiving;
    struct sockaddr_in m_addr;
    static int m_sinSize; // 固定大小

private:
    bool Send(char *msg, long leng);        

};

// 其他全局socket函数
void  StartSocket();
void  DestroySocket();









#endif







<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Rule;
using SmartTank.Screens;
using SmartTank.net;
using SmartTank.GameObjs;
using SmartTank.PhiCol;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TankEngine2D.Graphics;
using SmartTank;
using SmartTank.Draw;
using TankEngine2D.Helpers;
using TankEngine2D.Input;
using Microsoft.Xna.Framework.Input;
using SmartTank.Scene;
using System.IO;
using SmartTank.Helpers;
using SmartTank.GameObjs.Shell;
using TankEngine2D.DataStructure;
using SmartTank.Effects.SceneEffects;
using SmartTank.Effects;
using SmartTank.Sounds;
using SmartTank.Draw.UI.Controls;
using System.Runtime.InteropServices;
using System.Threading;

namespace InterRules.Starwar
{
    class Hall2 : IGameScreen
    {
        [StructLayoutAttribute(LayoutKind.Sequential, Size = 36, CharSet = CharSet.Ansi, Pack = 1)]
        struct RoomInfo
        {
            public const int size = 36;

            public int id;
            public int players;
            public int bBegin;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
            public char[] name;
        }

        [StructLayoutAttribute(LayoutKind.Sequential, Size = 56, CharSet = CharSet.Ansi, Pack = 1)]
        struct UserInfo
        {
            public const int size = 56;

            public int state;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)]
            public char[] name;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 23)]
            public char[] pass;
            public int score;
            public int rank;
        }
        Texture2D bgTexture, rlTexture, riTexture;
        List<Texture2D> heads;
        List<int> ranks;
        List<int> scores;

        Rectangle bgRect;

        SpriteBatch spriteBatch;

        Listbox2 roomList;
        Listbox2 rankList;
        int playerCount;

        TextButton2 btnCreate, btnEnter, btnRank, btnRefresh;
        TextButton btnStart, btnQuit;

        stPkgHead headSend;
        MemoryStream Stream;

        string[] userNames;
        List<string> devHeads;

        int selectIndexRank = -1;
        int selectIndexRoom = -1;
        bool bHasError;

        bool bInRoom, bIsHost, bWaitEnter;

        int myRoomId;
        string myName;

        public Hall2(string tmpName)
        {

            devHeads = new List<string>();
            devHeads.Add("asokawu");
            devHeads.Add("ddli");
            devHeads.Add("jehutyhu");
            devHeads.Add("zashchen");
            devHeads.Add("orrischen");
            devHeads.Add("johntan");
            devHeads.Add("seekyao");
            myName = tmpName;

            heads = new List<Texture2D>();
            ranks = new List<int>();
            scores = new List<int>();
            
            BaseGame.ShowMouse = true;

            roomList = new Listbox2("roomlist", new Vector2(50, 120), new Point(200, 350), Color.White, Color.White);

            rankList = new Listbox2("ranklist", new Vector2(300, 120), new Point(450, 350), Color.White, Color.White);


            bgTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.BgContent, "bg21"));
            rlTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.UIContent, "roomlist2"));
            riTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.UIContent, "roominfo2"));

            bgRect = new Rectangle(0, 0, 800, 600);


            btnRefresh = new TextButton2("RefreshBtn", new Vector2(150, 480), "Refresh", 0, Color.Gold);
            btnCreate = new TextButton2("CreateBtn", new Vector2(310, 480), "Create a new room", 0, Color.Gold);
            btnQuit = new TextButton("QuitBtn", new Vector2(450, 410), "Quit", 0, Color.Gold);
            btnEnter = new TextButton2("EnterBtn", new Vector2(70, 480), "Enter", 0, Color.Gold);
            btnRank = new TextButton2("RankBtn", new Vector2(650, 480), "Rank List", 0, Color.Gold);
            btnStart = new TextButton("StartBtn", new Vector2(550, 410), "Start", 0, Color.Gold);

            btnRefresh.OnClick += new EventHandler(btnRefresh_OnPress);
            btnCreate.OnClick += new EventHandler(btnCreate_OnPress);
            btnQuit.OnClick += new EventHandler(btnQuit_OnPress);
            btnEnter.OnClick += new EventHandler(btnEnter_OnPress);
            btnRank.OnClick += new EventHandler(btnRank_OnPress);
            btnStart.OnClick += new EventHandler(btnStart_OnPress);

            rankList.OnChangeSelection += new EventHandler(rankList_OnChangeSelection);
            roomList.OnChangeSelection += new EventHandler(roomList_OnChangeSelection);

            SocketMgr.OnReceivePkg += new SocketMgr.ReceivePkgEventHandler(OnReceivePack);



            headSend = new stPkgHead();
            Stream = new MemoryStream();
            headSend.dataSize = 0;
            headSend.iSytle = 33;
            SocketMgr.SendCommonPackge(headSend, Stream);
            Stream.Close();
            bInRoom = false;
            bWaitEnter = false;
            bIsHost = false;
            bHasError = false;
        }
        
        void OnReceivePack(stPkgHead head, byte[] data)
        {

            if (head.iSytle == 40)
            {
                head.iSytle = 40;
            }
            if (head.iSytle == 33)
            {
                //刷房间列表成功
                string str;
                RoomInfo room;
                byte[] tmpData;
                roomList.Clear();

                tmpData = new byte[head.dataSize];

                for (int i = 0; i < head.dataSize; i += 36)
                {

                    str = "";
                    //data.Read(roomBuffer, 0, 32);

                    for (int k = 0; k < 36; ++k)
                    {
                        tmpData[k] = data[i + k];
                    }

                    room = (RoomInfo)SocketMgr.BytesToStuct(tmpData, typeof(RoomInfo));

                    for (int j = 0; room.name[j] != '\0'; ++j)
                    {
                        str += room.name[j];
                    }


                    roomList.AddItem(" " + str + " ( " + room.players + " / 2 )", room.id);

                }
            }
            else if (head.iSytle == 35)
            {
                //创建房间成功
                bWaitEnter = false;

                headSend = new stPkgHead();
                Stream = new MemoryStream();
                headSend.dataSize = 0;
                headSend.iSytle = 33;
                SocketMgr.SendCommonPackge(headSend, Stream);
                Stream.Close();
                bInRoom = true;

                headSend = new stPkgHead();
                Stream = new MemoryStream();
                headSend.dataSize = 0;
                headSend.iSytle = 34;
                SocketMgr.SendCommonPackge(headSend, Stream);
                Stream.Close();
                
 
            }
            else if (head.iSytle == 36)
            {
                //创建房间失败
                bWaitEnter = false;

                bInRoom = false;
                bIsHost = false;
            }
            else if (head.iSytle == 37)
            {
                //加入房间成功
                bWaitEnter = false;

                headSend = new stPkgHead();
                Stream = new MemoryStream();
                headSend.dataSize = 0;
                headSend.iSytle = 33;
                SocketMgr.SendCommonPackge(headSend, Stream);
                Stream.Close();
                bInRoom = true;

                headSend = new stPkgHead();
                Stream = new MemoryStream();
                headSend.dataSize = 0;
                headSend.iSytle = 34;
                SocketMgr.SendCommonPackge(headSend, Stream);
                Stream.Close();
 
            }
            else if (head.iSytle == 38)
            {
                //加入房间失败
                bWaitEnter = false;

                bInRoom = false;
                bIsHost = false;

            }
            else if (head.iSytle == 34)
            {
                //列举用户信息


                string str;
                UserInfo player;
                byte[] tmpData;

                Monitor.Enter(heads);
                Monitor.Enter(ranks);
                Monitor.Enter(scores);
                heads.Clear();
                ranks.Clear();
                scores.Clear();

                

                tmpData = new byte[head.dataSize];
                bIsHost = false;
                string[] tmpNames = new string[6];
                int playerNum = 0;
                for (int i = 0; i < head.dataSize; i += 56)
                {

                    str = "";
                    //data.Read(roomBuffer, 0, 32);

                    for (int k = 0; k < 56; ++k)
                    {
                        tmpData[k] = data[i + k];
                    }

                    player = (UserInfo)SocketMgr.BytesToStuct(tmpData, typeof(UserInfo));

                    for (int j = 0; player.name[j] != '\0'; ++j)
                    {
                        str += player.name[j];
                    }
                    if (str == myName && player.state == 1)
                        bIsHost = true;
                    tmpNames[playerNum] = str;//, Font font)
                    ranks.Add(player.rank);
                    scores.Add(player.score);
                    Texture2D tex;
                    if (devHeads.Contains(str))
                    {
                        tex = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.UIContent, str));
                    }
                    else
                    {
                        tex = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.UIContent, "head"));
                    }
                    if (tex == null)
                    {
                        throw new Exception("");
                    }



                    heads.Add(tex);
                    playerNum++;

                    //roomList.AddItem("room 1" + " ( " + room.players + " / 6 )", room.id);

                }
                playerCount = playerNum;

                userNames = new string[playerNum];
                for (int i = 0; i < playerNum; i++)
                {
                    userNames[i] = tmpNames[i];
                }

                Monitor.Exit(scores);
                Monitor.Exit(ranks);
                Monitor.Exit(heads);

                headSend = new stPkgHead();
                Stream = new MemoryStream();
                headSend.dataSize = 0;
                headSend.iSytle = 33;
                SocketMgr.SendCommonPackge(headSend, Stream);
                Stream.Close();
            }
            else if (head.iSytle == 70)
            {
                //开始游戏
                bWaitEnter = false;
                if (bIsHost)
                    GameManager.AddGameScreen(new StarwarLogic(0, userNames));
                else
                {
                    for (int i = 0; i < playerCount; i++)
                    {
                        if (userNames[i] == myName)
                            GameManager.AddGameScreen(new StarwarLogic(i, userNames));
                    }
                }
            }
            else if (head.iSytle == 71)
            {
                bWaitEnter = false;
            }
        }
        
        void roomList_OnChangeSelection(object sender, EventArgs e)
        {
            selectIndexRoom = roomList.selectedIndex;
        }

        void rankList_OnChangeSelection(object sender, EventArgs e)
        {
            selectIndexRank = rankList.selectedIndex;
        }

        void btnCreate_OnPress(object sender, EventArgs e)
        {
            if (bWaitEnter)
                return;

            if (bInRoom)
            {
                headSend = new stPkgHead();
                Stream = new MemoryStream();
                headSend.dataSize = 0;
                headSend.iSytle = 39;
                SocketMgr.SendCommonPackge(headSend, Stream);
                Stream.Close();

                bIsHost = false;
                bInRoom = false;
            }

            headSend = new stPkgHead();
            //head.iSytle = //包头类型还没初始化


            Stream = new MemoryStream();
            headSend.dataSize = 0;
            headSend.iSytle = 30;
            SocketMgr.SendCommonPackge(headSend, Stream);
            Stream.Close();
            bWaitEnter = true;
        }

        void btnStart_OnPress(object sender, EventArgs e)
        {
            headSend = new stPkgHead();
            Stream = new MemoryStream();
            headSend.dataSize = 0;
            headSend.iSytle = 70;
            SocketMgr.SendCommonPackge(headSend, Stream);
            Stream.Close();
            bWaitEnter = true;
        }

        void btnQuit_OnPress(object sender, EventArgs e)
        {
            headSend = new stPkgHead();
            Stream = new MemoryStream();
            headSend.dataSize = 0;
            headSend.iSytle = 39;
            SocketMgr.SendCommonPackge(headSend, Stream);
            Stream.Close();
            
            bIsHost = false;
            bInRoom = false;

            headSend = new stPkgHead();
            Stream = new MemoryStream();
            headSend.dataSize = 0;
            headSend.iSytle = 33;
            roomList.Clear();
            SocketMgr.SendCommonPackge(headSend, Stream);
            Stream.Close();
        }

        void btnEnter_OnPress(object sender, EventArgs e)
        {
            if (bWaitEnter || bInRoom)
                return;


            if (roomList.selectedIndex == -1)
                return;

            headSend = new stPkgHead();
            //byte[] roomid;

            //roomid = SocketMgr.StructToBytes(roomList.MyIDs[roomList.selectedIndex]);

            Stream = new MemoryStream();
            //Stream.Write(roomid, 0, 4);
            //head.dataSize = 4;
            headSend.dataSize = 0;
            headSend.iSytle = 31;
            SocketMgr.SendCommonPackge(headSend, Stream);
            Stream.Close();
            bWaitEnter = true;
        }

        void btnRefresh_OnPress(object sender, EventArgs e)
        {
            headSend = new stPkgHead();
            Stream = new MemoryStream();
            headSend.dataSize = 0;
            headSend.iSytle = 33;
            SocketMgr.SendCommonPackge(headSend, Stream);
            Stream.Close();
        }

        void btnRank_OnPress(object sender, EventArgs e)
        {
            //SocketMgr.OnReceivePkg -= OnReceivePack;
            GameManager.AddGameScreen(new Rank2());
        }

        #region IGameScreen 成员

        public bool Update(float second)
        {
            btnRefresh.Update();
            if (bInRoom)
                btnQuit.Update();

            btnCreate.Update();
            btnEnter.Update();
            btnRank.Update();
            if (bInRoom && bIsHost)
                btnStart.Update();
            
            
            roomList.Update();
            rankList.Update();

            if (InputHandler.IsKeyDown(Keys.Escape))
                return true;

            return false;
        }

        public void Render()
        {
            BaseGame.Device.Clear(Color.LightSkyBlue);
            spriteBatch = (SpriteBatch)BaseGame.SpriteMgr.alphaSprite;
            spriteBatch.Draw(bgTexture, Vector2.Zero, bgRect, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, LayerDepth.BackGround);
            spriteBatch.Draw(rlTexture, new Vector2(50, 102), new Rectangle(0, 0, 79, 18), Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0f);
            spriteBatch.Draw(riTexture, new Vector2(300, 102), new Rectangle(0, 0, 145, 18), Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0f);

            //roomList.Clear();
            roomList.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            rankList.Draw(BaseGame.SpriteMgr.alphaSprite, 1);

            btnEnter.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            btnCreate.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            btnRank.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            btnRefresh.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            if (bInRoom)
            {
                Monitor.Enter(heads);

                for (int i = 0; i < playerCount; i++)
                {
                    if (heads.Count >= i + 1)
                        spriteBatch.Draw(heads[i], new Vector2(334, 157 + i * 140), new Rectangle(0, 0, 70, 70), Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, LayerDepth.UI - 0.1f);
                    BaseGame.FontMgr.DrawInScrnCoord("Name: " + userNames[i], new Vector2(335, 230 + i * 140), Control.fontScale, Color.Black, 0f, Control.fontName);
                    BaseGame.FontMgr.DrawInScrnCoord("Score: " + scores[i], new Vector2(335, 245 + i * 140), Control.fontScale, Color.Black, 0f, Control.fontName);
                    BaseGame.FontMgr.DrawInScrnCoord("Rank:  " + ranks[i], new Vector2(335, 260 + i * 140), Control.fontScale, Color.Black, 0f, Control.fontName);
                }
                Monitor.Exit(heads);
            }

            if (bInRoom)
            {
                if  (bIsHost)
                    btnStart.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
                btnQuit.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            }
        }

        public void OnClose()
        {
            SocketMgr.OnReceivePkg -= OnReceivePack;
        }

        #endregion
    }





}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.Update
{
    public interface IUpdater
    {
        void Update ( float seconds );
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Rule;
using SmartTank.Screens;
using SmartTank.net;
using SmartTank.GameObjs;
using SmartTank.PhiCol;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TankEngine2D.Graphics;
using SmartTank;
using SmartTank.Draw;
using TankEngine2D.Helpers;
using TankEngine2D.Input;
using Microsoft.Xna.Framework.Input;
using SmartTank.Scene;
using System.IO;
using SmartTank.Helpers;
using SmartTank.GameObjs.Shell;
using TankEngine2D.DataStructure;
using SmartTank.Effects.SceneEffects;
using SmartTank.Effects;
using SmartTank.Sounds;
using System.Runtime.InteropServices;
using SmartTank.Draw.UI.Controls;

namespace InterRules.Starwar
{
    class StarwarLogic : RuleSupNet, IGameScreen
    {
        [StructLayoutAttribute(LayoutKind.Sequential, Size = 32, CharSet = CharSet.Ansi, Pack = 1)]
        struct RankInfo
        {
            public int Rank;
            public int Score;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
            public char[] Name;

            public const int TotolLength = 32;
            public const int NameLength = 24;
        };



        #region Variables

        const float AddObjSpace = 250;

        WarShip[] ships;
        Gold gold;
        List<Rock> rocks = new List<Rock>();
        int rockCount = 0;
        List<string> OutDateShellNames = new List<string>();

        Rectanglef mapRect = new Rectanglef(0, 0, 1600, 1200);
        Camera camera;

        Sprite backGround;

        int shellcount = 0;

        Rectanglef rockDelRect = new Rectanglef(-400, -400, 2400, 2000);
        float rockTimer = 0;

        int controlIndex = -1;

        float gameTotolTime = -1;

        public Vector2 MapCenterPos
        {
            get { return new Vector2(mapRect.X + mapRect.Width / 2, mapRect.Y + mapRect.Height / 2); }
        }

        bool isGameOver = false;

        string[] playerNames;

        #endregion

        #region HandlerObjEvent

        void Gold_OnLiveTimeOut(Gold sender)
        {
            SetGoldNewPos(sender);
        }

        void Warship_OnDead(WarShip sender)
        {
            //sceneMgr.DelGameObj(sender.MgPath);
            if (PurviewMgr.IsMainHost)
            {
                while (true)
                {
                    Vector2 newPos = RandomHelper.GetRandomVector2(0, 1);
                    newPos.X *= mapRect.Width;
                    newPos.X += mapRect.X;
                    newPos.Y *= mapRect.Height;
                    newPos.Y += mapRect.Y;
                    if (CanAddObjAtPos(newPos))
                    {
                        (sender as WarShip).Born(newPos);
                        SyncCasheWriter.SubmitUserDefineInfo("WarshipBorn", "", sender, newPos);
                        break;
                    }
                }
            }
        }

        void WarShip_OnShoot(WarShip firer, Vector2 endPoint, float azi)
        {
            if (PurviewMgr.IsMainHost)
            {
                WarShipShell shell = new WarShipShell("shell" + shellcount, firer, endPoint, azi);
                shell.onCollided += new OnCollidedEventHandler(Shell_onCollided);
                shell.OnOutDate += new WarShipShell.ShellOutDateEventHandler(Shell_OnOutDate);
                sceneMgr.AddGameObj("shell", shell);


                SyncCasheWriter.SubmitCreateObjMg("shell", typeof(WarShipShell), "shell" + shellcount, firer, endPoint, azi);
                shellcount++;
            }
        }

        void Shell_OnOutDate(WarShipShell sender, IGameObj shooter)
        {
            OutDateShellNames.Add(sender.Name);
        }

        void Shell_onCollided(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {

            if (objB.ObjClass == "WarShip")
            {
                if (PurviewMgr.IsMainHost)
                {
                    WarShipShell shell = Sender as WarShipShell;
                    WarShip firer = shell.Firer as WarShip;
                    if (objB.Script != firer.ObjInfo.Script)
                    {
                        (shell.Firer as WarShip).Score += SpaceWarConfig.ScoreByHit;
                        SyncShipScoreHp(shell.Firer as WarShip, true);
                    }
                }

                sceneMgr.DelGameObj("shell", Sender.Name);
                new ShellExplodeBeta(Sender.Pos, ((ShellNormal)Sender).Azi);

                Quake.BeginQuake(10, 50);
                Sound.PlayCue("EXPLO1");
            }
            else
            {
                WarShipShell shell = (WarShipShell)Sender;
                shell.MirrorPath(result);

                //
                //BroadcastObjPhiStatus(shell, true);
            }

        }

        void WarShip_OnCollied(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (objB.ObjClass == "WarShipShell")
            {
                WarShip ship = (WarShip)Sender;
                ship.BeginStill();
                if (PurviewMgr.IsMainHost)
                    ship.HitByShell();
                ship.Vel = result.NormalVector * SpaceWarConfig.ShellSpeed;

                SyncShipScoreHp(ship, false);
            }
            else if (objB.ObjClass == "WarShip")
            {
                WarShip ship = (WarShip)Sender;
                Vector2 newVel = CalMirrorVel(ship.Vel, result.NormalVector);
                ship.Vel = newVel;
                ship.BeginStill();
            }
            else if (objB.ObjClass == "Rock")
            {
                WarShip ship = (WarShip)Sender;
                Vector2 newVel = CalMirrorVel(ship.Vel, result.NormalVector);
                ship.Vel = newVel;
                ship.BeginStill();
            }
        }

        void Warship_OnOverLap(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (objB.ObjClass == "Gold")
            {
                WarShip ship = Sender as WarShip;
                ship.Score += SpaceWarConfig.GoldScore;

                SyncShipScoreHp(ship, true);
            }
        }

        private void SyncShipScoreHp(WarShip ship, bool subScore)
        {
            if (PurviewMgr.IsMainHost)
            {
                if (subScore)
                    SyncCasheWriter.SubmitUserDefineInfo("Score", "", ship, ship.Score);
                else
                    SyncCasheWriter.SubmitUserDefineInfo("Hp", "", ship, ship.HP);
            }
        }

        void Gold_OnOverLap(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            SetGoldNewPos(Sender as Gold);
        }

        void Rock_OnCollided(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (objB.ObjClass == "WarShip")// || objB.ObjClass == "Rock")
            {
                Vector2 newVel = CalMirrorVel((Sender as Rock).Vel, result.NormalVector);
                (Sender as Rock).Vel = newVel;
            }
            else if (objB.ObjClass == "Rock")
            {
                Vector2 newVel = CalMirrorVel((Sender as Rock).Vel, result.NormalVector);
                (Sender as Rock).Vel = newVel;
            }

            //BroadcastObjPhiStatus(Sender, true);
        }

        void SyncCasheReader_onUserDefineInfo(string infoName, string infoID, object[] args)
        {
            if (infoName == "WarshipBorn")
            {
                WarShip ship = args[0] as WarShip;
                if (!PurviewMgr.IsMainHost)
                    ship.Dead();
                ship.Born((Vector2)args[1]);
            }
            else if (infoName == "ObjPhiCollide")
            {
                if (args[0] != null)
                    ((NonInertiasPhiUpdater)((args[0] as IPhisicalObj).PhisicalUpdater))
                        .SetServerStatue((Vector2)args[1], (Vector2)args[2], (float)args[3], (float)args[4], phiSyncTime, true);
            }
            else if (infoName == "ObjPhi")
            {
                if (args[0] != null
                    && args[0] != ships[controlIndex])
                    ((NonInertiasPhiUpdater)((args[0] as IPhisicalObj).PhisicalUpdater))
                        .SetServerStatue((Vector2)args[1], (Vector2)args[2], (float)args[3], (float)args[4], phiSyncTime, false);
            }
            else if (infoName == "Score")
            {
                if (args[0] != null)
                {
                    WarShip ship = args[0] as WarShip;
                    ship.Score = (int)args[1];
                }
            }
            else if (infoName == "Hp")
            {
                if (args[0] != null)
                {
                    WarShip ship = args[0] as WarShip;
                    ship.HP = (int)args[1];
                }
            }
            else if (infoName == "GoldBorn")
            {
                if (args[0] != null)
                {
                    (args[0] as Gold).Born((Vector2)args[1]);
                }
            }
            else if (infoName == "Over")
            {
                isSendOver = true;
            }
        }

        void SyncCasheReader_onCreateObj(IGameObj obj)
        {
            if (obj is WarShipShell)
            {
                WarShipShell shell = obj as WarShipShell;
                shell.onCollided += new OnCollidedEventHandler(Shell_onCollided);
                shell.OnOutDate += new WarShipShell.ShellOutDateEventHandler(Shell_OnOutDate);
                shellcount++;
            }
            else if (obj is Rock)
            {
                Rock newRock = obj as Rock;
                newRock.OnCollided += new OnCollidedEventHandler(Rock_OnCollided);
                rocks.Add(newRock);
                rockCount++;
            }
        }



        private void SyncWarShip()
        {
            if (PurviewMgr.IsMainHost)
            {
                for (int i = 0; i < ships.Length; i++)
                {
                    BroadcastObjPhiStatus(ships[i], false);
                }
            }
            else
            {
                BroadcastObjPhiStatus(ships[controlIndex], false);
            }


        }

        private void BroadcastObjPhiStatus(IGameObj obj, bool collide)
        {
            if (obj is IPhisicalObj)
            {
                if (collide)
                {
                    NonInertiasPhiUpdater phiUpdater = (NonInertiasPhiUpdater)((IPhisicalObj)obj).PhisicalUpdater;
                    SyncCasheWriter.SubmitUserDefineInfo("ObjPhiCollide",
                        obj.ObjInfo.ObjClass, obj, phiUpdater.Pos, phiUpdater.Vel, phiUpdater.Azi, phiUpdater.AngVel);
                }
                else
                {
                    NonInertiasPhiUpdater phiUpdater = (NonInertiasPhiUpdater)((IPhisicalObj)obj).PhisicalUpdater;
                    SyncCasheWriter.SubmitUserDefineInfo("ObjPhi",
                        obj.ObjInfo.ObjClass, obj, phiUpdater.Pos, phiUpdater.Vel, phiUpdater.Azi, phiUpdater.AngVel);
                }
            }
        }

        private Vector2 CalMirrorVel(Vector2 curVel, Vector2 mirrorVertical)
        {
            float mirVecLength = Vector2.Dot(curVel, mirrorVertical);
            Vector2 horizVel = curVel - mirVecLength * mirrorVertical;
            Vector2 newVel = horizVel + Math.Abs(mirVecLength) * mirrorVertical;
            return newVel;
        }

        private void SetGoldNewPos(Gold Sender)
        {
            if (PurviewMgr.IsMainHost)
            {
                while (true)
                {
                    Vector2 pos = RandomHelper.GetRandomVector2(0, 1);
                    pos.X *= mapRect.Width - 200;
                    pos.Y *= mapRect.Height - 200;
                    pos += new Vector2(100, 100);

                    if (CanAddObjAtPos(pos))
                    {
                        Sender.Born(pos);
                        SyncCasheWriter.SubmitUserDefineInfo("GoldBorn", "", Sender, Sender.Pos);
                        break;
                    }
                }
            }
        }

        private bool CanAddObjAtPos(Vector2 pos)
        {
            foreach (WarShip ship in ships)
            {
                if (ship == null)
                    continue;

                if (Math.Abs(ship.Pos.X - pos.X) < AddObjSpace
                    && Math.Abs(ship.Pos.Y - pos.Y) < AddObjSpace)
                    return false;
            }

            foreach (Rock rock in rocks)
            {
                if (Math.Abs(rock.Pos.X - pos.X) < AddObjSpace
                    && Math.Abs(rock.Pos.Y - pos.Y) < AddObjSpace)
                    return false;
            }

            return true;
        }


        #endregion

        #region Initailize

        public StarwarLogic(int controlIndex, string[] playerNames)
        {
            this.controlIndex = controlIndex;

            this.playerNames = playerNames;

            LoadConfig();

            StartTimer();

            InitialCamera();
            InitializeScene();
            InitialBackGround();
            InitailizePurview(controlIndex);

            SyncCasheReader.onCreateObj += new SyncCasheReader.CreateObjInfoHandler(SyncCasheReader_onCreateObj);
            SyncCasheReader.onUserDefineInfo += new SyncCasheReader.UserDefineInfoHandler(SyncCasheReader_onUserDefineInfo);

        }

        private void StartTimer()
        {
            gameTotolTime = SpaceWarConfig.GameTotolTime;
        }

        private void InitailizePurview(int controlIndex)
        {
            if (controlIndex == 0)
            {
                PurviewMgr.IsMainHost = true;
                for (int i = 0; i < ships.Length; i++)
                {
                    if (i != controlIndex)
                        PurviewMgr.RegistSlaveMgObj(ships[i].MgPath);
                }
            }
            else
            {
                PurviewMgr.IsMainHost = false;
                PurviewMgr.RegistSlaveMgObj(ships[controlIndex].MgPath);
            }


        }

        const float phiSyncTime = 0.1f;

        private void InitialBackGround()
        {
            backGround = new Sprite(GameManager.RenderEngine, Path.Combine(Directories.ContentDirectory, "Rules\\SpaceWar\\image\\field_space_001.png"), false);
            backGround.SetParameters(new Vector2(0, 0), new Vector2(0, 0), 1.0f, 0f, Color.White, LayerDepth.BackGround, SpriteBlendMode.AlphaBlend);
        }

        private void LoadConfig()
        {
            SpaceWarConfig.LoadConfig();
        }

        private void InitializeScene()
        {
            sceneMgr = new SceneMgr();

            sceneMgr.AddGroup("", new TypeGroup<WarShip>("warship"));
            sceneMgr.AddGroup("", new TypeGroup<WarShipShell>("shell"));
            sceneMgr.AddGroup("", new TypeGroup<SmartTank.PhiCol.Border>("border"));
            sceneMgr.AddGroup("", new TypeGroup<Gold>("gold"));
            sceneMgr.AddGroup("", new TypeGroup<Rock>("rock"));

            sceneMgr.PhiGroups.Add("warship");
            sceneMgr.PhiGroups.Add("shell");
            sceneMgr.PhiGroups.Add("rock");
            sceneMgr.AddColMulGroups("warship", "shell", "border");
            sceneMgr.AddColMulGroups("warship", "shell", "rock");
            sceneMgr.ColSinGroups.Add("warship");
            sceneMgr.ColSinGroups.Add("rock");

            sceneMgr.AddLapMulGroups("warship", "gold");

            ships = new WarShip[playerNames.Length];
            for (int i = 0; i < playerNames.Length; i++)
            {
                bool openControl = false;
                if (i == controlIndex)
                    openControl = true;

                ships[i] = new WarShip("ship" + i, new Vector2(400 + i * 800, 600), 0, openControl);
                ships[i].OnCollied += new OnCollidedEventHandler(WarShip_OnCollied);
                ships[i].OnOverLap += new OnCollidedEventHandler(Warship_OnOverLap);
                ships[i].OnShoot += new WarShip.WarShipShootEventHandler(WarShip_OnShoot);
                ships[i].OnDead += new WarShip.WarShipDeadEventHandler(Warship_OnDead);
                ships[i].PlayerName = playerNames[i];
                sceneMgr.AddGameObj("warship", ships[i]);
            }

            gold = new Gold("gold", new Vector2(800, 600), 0);
            gold.OnOverLap += new OnCollidedEventHandler(Gold_OnOverLap);
            gold.OnLiveTimeOut += new Gold.GoldLiveTimeOutEventHandler(Gold_OnLiveTimeOut);

            sceneMgr.AddGameObj("border", new SmartTank.PhiCol.Border(mapRect));
            sceneMgr.AddGameObj("gold", gold);

            GameManager.LoadScene(sceneMgr);

            camera.Focus(ships[controlIndex], false);
        }

        private void InitialCamera()
        {
            BaseGame.CoordinMgr.SetScreenViewRect(new Rectangle(0, 0, 800, 600));

            camera = new Camera(1f, new Vector2(400, 300), 0);
            camera.maxScale = 4.5f;
            camera.minScale = 0.5f;
            camera.Enable();
        }

        #endregion

        #region IGameScreen 成员

        void IGameScreen.OnClose()
        {
            base.OnClose();
        }

        void IGameScreen.Render()
        {
            BaseGame.Device.Clear(Color.Black);
            backGround.Draw();
            GameManager.DrawManager.Draw();
            BaseGame.BasicGraphics.DrawRectangle(mapRect, 3, Color.White, LayerDepth.TankBase);
            BaseGame.RenderEngine.FontMgr.DrawInScrnCoord("Time: " + ((int)gameTotolTime).ToString(),
                new Vector2(700, 50), 1.0f, Color.Red, LayerDepth.UI, GameFonts.Lucida);

            DrawScore();
        }

        private void DrawScore()
        {
            for (int i = 0; i < ships.Length; i++)
            {
                //GameManager.RenderEngine.FontMgr.DrawInScrnCoord(" Live: " + ships[i].HP, new Vector2(50 + 120 * i, 500), 0.4f, Color.White, LayerDepth.Text, GameFonts.Comic);
                GameManager.RenderEngine.FontMgr.DrawInScrnCoord(ships[i].PlayerName + " Score: " + ships[i].Score, new Vector2(50 + 120 * i, 550), 0.4f, Color.White, LayerDepth.Text, GameFonts.Comic);
            }
            GameManager.RenderEngine.BasicGrahpics.FillRectangleInScrn(new Rectangle(50, 50, ships[controlIndex].HP / 3, 20), Color.Red, LayerDepth.UI, SpriteBlendMode.AlphaBlend);
        }

        //Vector2 serPos = new Vector2(400, 400);
        //Vector2 serVel = new Vector2(100, 0);

        bool IGameScreen.Update(float second)
        {
            if (isGameOver)
            {
                return true;
            }

            base.Update(second);

            UpdateCamera(second);

            DeleteOutDateShells();

            CreateDelRock(second);

            if (isSendOver)
            {
                GameOver();
                isSendOver = false;
            }

            UpdateTimer(second);

            //SyncWarShip();
            //if (InputHandler.IsKeyDown(Keys.U))
            //{
            //    ((NonInertiasPhiUpdater)ships[0].PhisicalUpdater).SetServerStatue(serPos, serVel, 0, 0, 10);

            //}


            if (InputHandler.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape))
            {
                GameManager.ComponentReset();
                return true;
            }
            else
                return false;
        }

        bool isSendOver = false;

        private void UpdateTimer(float second)
        {
            if (gameTotolTime > 0)
                gameTotolTime -= second;
            if (gameTotolTime <= 0 && PurviewMgr.IsMainHost)
            {
                SyncCasheWriter.SubmitUserDefineInfo("Over", "");
                SendOverRankInfo();
                isSendOver = true;
                //GameOver();
            }
        }

        private void GameOver()
        {
            isGameOver = true;
            int[] scores = new int[ships.Length];
            for (int i = 0; i < ships.Length; i++)
            {
                scores[i] = ships[i].Score;
            }

            GameManager.AddGameScreen(new ScoreScreen(playerNames, scores));
        }

        private void SendOverRankInfo()
        {
            stPkgHead head = new stPkgHead();
            head.iSytle = 80;
            RankInfo[] info = new RankInfo[ships.Length];
            byte[] buffer = new byte[ships.Length * RankInfo.TotolLength];

            for (int i = 0; i < ships.Length; i++)
            {
                info[i].Score = ships[i].Score;
                info[i].Rank = 0;
                info[i].Name = new char[RankInfo.NameLength];

                for (int j = 0; j < ships[i].PlayerName.Length; j++)
                {
                    info[i].Name[j] = ships[i].PlayerName[j];
                }

                byte[] temp = SocketMgr.StructToBytes(info[i]);
                temp.CopyTo(buffer, i * RankInfo.TotolLength);
            }

            MemoryStream stream = new MemoryStream();
            stream.Write(buffer, 0, buffer.Length);
            head.dataSize = buffer.Length;

            SocketMgr.SendCommonPackge(head, stream);
            stream.Close();
        }


        private void CreateDelRock(float second)
        {
            rockTimer += second;
            if (rockTimer > SpaceWarConfig.RockCreateTime)
            {
                rockTimer = 0;

                CreateRock();
            }

            List<Rock> delRocks = new List<Rock>();

            foreach (Rock rock in rocks)
            {
                if (rock.Pos.X < rockDelRect.X
                    || rock.Pos.X > rockDelRect.X + rockDelRect.Width
                    || rock.Pos.Y < rockDelRect.Y
                    || rock.Pos.Y > rockDelRect.Y + rockDelRect.Height)
                {
                    delRocks.Add(rock);
                }
            }

            foreach (Rock rock in delRocks)
            {
                sceneMgr.DelGameObj("rock", rock.Name);
                rocks.Remove(rock);
            }
        }

        private void CreateRock()
        {
            if (PurviewMgr.IsMainHost)
            {
                Vector2 newPos = new Vector2();
                while (true)
                {
                    newPos = RandomHelper.GetRandomVector2(-100, 100);

                    int posType = RandomHelper.GetRandomInt(0, 2);

                    if (posType == 0)
                    {
                        if (newPos.X < 0)
                            newPos.X -= mapRect.X + AddObjSpace;
                        else
                            newPos.X += mapRect.Width + mapRect.X + AddObjSpace;

                        if (newPos.Y < 0)
                            newPos.Y -= mapRect.Y + AddObjSpace;
                        else
                            newPos.Y += mapRect.Y + mapRect.Height + AddObjSpace;
                    }
                    else if (posType == 1)
                    {
                        newPos.X *= mapRect.Width / 200;
                        newPos.X += mapRect.Width / 2 + mapRect.X;

                        if (newPos.Y < 0)
                            newPos.Y -= mapRect.Y + AddObjSpace;
                        else
                            newPos.Y += mapRect.Y + mapRect.Height + AddObjSpace;
                    }
                    else if (posType == 2)
                    {
                        newPos.Y *= mapRect.Height / 200;
                        newPos.Y += mapRect.Y + mapRect.Height / 2;

                        if (newPos.X < 0)
                            newPos.X -= mapRect.X + AddObjSpace;
                        else
                            newPos.X += mapRect.Width + mapRect.X + AddObjSpace;

                    }
                    if (CanAddObjAtPos(newPos))
                        break;

                }
                float speed = RandomHelper.GetRandomFloat(SpaceWarConfig.RockMinSpeed, SpaceWarConfig.RockMaxSpeed);
                Vector2 way = Vector2.Normalize(MapCenterPos - newPos);
                Vector2 delta = RandomHelper.GetRandomVector2(-0.7f, 0.7f);
                Vector2 Vel = Vector2.Normalize(way + delta) * speed;

                float aziVel = RandomHelper.GetRandomFloat(0, SpaceWarConfig.RockMaxAziSpeed);
                float scale = RandomHelper.GetRandomFloat(0.4f, 1.4f);
                int kind = RandomHelper.GetRandomInt(0, ((int)RockTexNo.Max) - 1);

                Rock newRock = new Rock("Rock" + rockCount, newPos, Vel, aziVel, scale, kind);

                newRock.OnCollided += new OnCollidedEventHandler(Rock_OnCollided);
                sceneMgr.AddGameObj("rock", newRock);

                rocks.Add(newRock);
                SyncCasheWriter.SubmitCreateObjMg("rock", typeof(Rock), "Rock" + rockCount, newPos, Vel, aziVel, scale, kind);

                rockCount++;

            }
        }

        private void DeleteOutDateShells()
        {
            if (OutDateShellNames.Count != 0)
            {
                foreach (string name in OutDateShellNames)
                {
                    sceneMgr.DelGameObj("shell", name);
                }
                OutDateShellNames.Clear();
            }
        }

        private void UpdateCamera(float second)
        {
            if (InputHandler.IsKeyDown(Keys.Left))
                camera.Move(new Vector2(-5, 0));
            if (InputHandler.IsKeyDown(Keys.Right))
                camera.Move(new Vector2(5, 0));
            if (InputHandler.IsKeyDown(Keys.Up))
                camera.Move(new Vector2(0, -5));
            if (InputHandler.IsKeyDown(Keys.Down))
                camera.Move(new Vector2(0, 5));
            if (InputHandler.JustPressKey(Keys.V))
                camera.Zoom(-0.2f);
            if (InputHandler.JustPressKey(Keys.B))
                camera.Zoom(0.2f);
            if (InputHandler.IsKeyDown(Keys.T))
                camera.Rota(0.1f);
            if (InputHandler.IsKeyDown(Keys.R))
                camera.Rota(-0.1f);
            camera.Update(second);
        }

        #endregion
    }


    class ScoreScreen : IGameScreen
    {
        //Listbox nameList = new Listbox("listboxName", new Vector2(100, 100), new Point(200, 300), Color.White, Color.Green);
        //Listbox scoreList = new Listbox("listboxName", new Vector2(500, 100), new Point(200, 300), Color.White, Color.Green);
        TextButton btn = new TextButton("btnExit", new Vector2(650, 500), "Exit", 0, Color.Gold);
        string[] names;
        int[] scores;

        bool close = false;

        Color[] colors;
        Texture2D bgTexture;

        public ScoreScreen(string[] names, int[] scores)
        {
            //foreach (string name in names)
            //{
            //    nameList.AddItem(name);
            //}
            //foreach (int score in scores)
            //{
            //    scoreList.AddItem(score.ToString());
            //}
            this.names = names;
            this.scores = scores;

            colors = new Color[6];
            colors[0] = Color.Gold;
            colors[1] = Color.Silver;
            colors[2] = Color.Chocolate;
            colors[3] = Color.DarkSalmon;
            colors[4] = Color.DeepPink;
            colors[5] = Color.DeepSkyBlue;

            bgTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.BgContent, "login"));

            btn.OnClick += new EventHandler(btn_OnClick);
        }

        void btn_OnClick(object sender, EventArgs e)
        {
            close = true;
        }

        #region IGameScreen 成员

        public void OnClose()
        {
        }

        public void Render()
        {
            //nameList.Draw(BaseGame.SpriteMgr.alphaSprite, 1.0f);
            //scoreList.Draw(BaseGame.SpriteMgr.alphaSprite, 1.0f);
            //BaseGame.SpriteMgr.alphaSprite.Draw(bgTexture, new Rectangle(0, 0, 800, 600), null, Color.White, 0, new Vector2(0, 0), SpriteEffects.None, LayerDepth.BackGround);

            BaseGame.RenderEngine.FontMgr.DrawInScrnCoord("得分榜", new Vector2(270, 50), 3.0f, Color.Red, LayerDepth.UI, GameFonts.HDZB);


            for (int i = 0; i < names.Length; i++)
            {
                BaseGame.RenderEngine.FontMgr.DrawInScrnCoord(names[i], new Vector2(200, 200 + i * 30), 1.0f, colors[i], LayerDepth.UI, GameFonts.Comic);
                BaseGame.RenderEngine.FontMgr.DrawInScrnCoord(scores[i].ToString(), new Vector2(550, 200 + i * 30), 1.0f, colors[i], LayerDepth.UI, GameFonts.Comic);
            }
            btn.Draw(BaseGame.SpriteMgr.alphaSprite, 1.0f);

        }

        public bool Update(float second)
        {
            if (close)
                return true;

            btn.Update();

            return false;
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Helpers;
using SmartTank.Rule;
using System.IO;
using System.Reflection;

namespace SmartTank.Helpers.DependInject
{
    static class RuleLoader
    {
        readonly static string ruleDirectory = "Rule";
        readonly static string ruleListPath = "Rule\\List.xml";

        static AssetList list;

        static public void Initial()
        {
            list = AssetList.Load( File.OpenRead( Path.Combine( Directories.GameBaseDirectory, ruleListPath ) ) );
        }

        static public string[] GetRulesList()
        {
            return list.GetTypeList();
        }

        static public IGameRule CreateRuleInstance( int index )
        {
            TypeAssetPath assetPath = list.GetTypeAssetPath( index );
            if (assetPath.typeName.Length > 0)
            {
                IGameRule gameRule = (IGameRule)GetInstance( assetPath.DLLName, assetPath.typeName );
                if (gameRule != null)
                    return gameRule;
                else
                    Log.Write( "Load GameRule error!" );
            }
            return null;
        }

        static public object GetInstance( string assetFullName, string typeName )
        {
            Assembly assembly = null;
            try
            {
                AppDomain.CurrentDomain.AppendPrivatePath( ruleDirectory );
                assembly = Assembly.Load( assetFullName );
                AppDomain.CurrentDomain.ClearPrivatePath();

            }
            catch (Exception)
            {
                Log.Write( "Load Assembly error : " + assetFullName + " load unsucceed!" );
                return null;
            }

            try
            {
                object obj = assembly.CreateInstance( typeName );
                if (obj != null)
                    return obj;
                else
                    Log.Write( "assembly.CreateInstance error!" );
            }
            catch (Exception ex)
            {
                Log.Write( "Load Type error : " + typeName + " create unsucceed!" + ex.Message );
                return null;
            }
            return null;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.DataStructure;
using Microsoft.Xna.Framework;
using System.Collections;
using TankEngine2D.Helpers;

namespace SmartTank.Senses.Memory
{
    public class ConvexHall
    {
        List<BordPoint> convexPoints;

        public ConvexHall ( CircleList<BordPoint> border, float minOptimizeDest )
        {
            BuildConvexHall( border, minOptimizeDest );
        }

        public List<BordPoint> Points
        {
            get { return convexPoints; }
        }

        public void BuildConvexHall ( CircleList<BordPoint> border, float minOptimizeDest )
        {
            #region 获得原始凸包
            if (border.Length < 2)
                return;

            Stack<BordPoint> stack = new Stack<BordPoint>();

            CircleListNode<BordPoint> cur = border.First;
            stack.Push( cur.value );
            cur = cur.next;
            stack.Push( cur.value );
            cur = cur.next;
            for (int i = 2; i < border.Length; i++)
            {
                BordPoint p1 = stack.Pop();

                BordPoint p0 = stack.Peek();

                BordPoint p2 = cur.value;

                if (CountWise( p1, p0, p2 ))
                {
                    stack.Push( p1 );
                    stack.Push( p2 );
                    cur = cur.next;
                }
                else
                {
                    if (stack.Count == 1)
                    {
                        stack.Push( p2 );
                        cur = cur.next;
                    }
                    else
                        i--;
                }
            }

            List<BordPoint> templist = new List<BordPoint>( stack );

            if (templist.Count > 3)
            {
                if (!CountWise( templist[0], templist[1], templist[templist.Count - 1] ))
                {
                    templist.RemoveAt( 0 );
                }
                if (!CountWise( templist[templist.Count - 1], templist[0], templist[templist.Count - 2] ))
                {
                    templist.RemoveAt( templist.Count - 1 );
                }
            }
            else if (templist.Count == 3)
            {
                if (!CountWise( templist[0], templist[1], templist[templist.Count - 1] ))
                {
                    templist.RemoveAt( 0 );
                    BordPoint temp = templist[0];
                    templist[0] = templist[1];
                    templist[1] = temp;
                }
            }

            #endregion

            #region 对凸包进行化简

            if (templist.Count > 3)
            {
                for (int i = 0; i < templist.Count; i++)
                {
                    Vector2 p1 = ConvertHelper.PointToVector2( templist[i].p );
                    Vector2 p2 = ConvertHelper.PointToVector2( templist[(i + 1) % templist.Count].p );
                    Vector2 p3 = ConvertHelper.PointToVector2( templist[(i + 2) % templist.Count].p );
                    Vector2 p4 = ConvertHelper.PointToVector2( templist[(i + 3) % templist.Count].p );

                    if (Vector2.Distance( p2, p3 ) > minOptimizeDest)
                        continue;

                    Vector2 seg1 = p2 - p1;
                    Vector2 seg2 = p4 - p3;

                    float ang = (float)Math.Acos( Vector2.Dot( seg1, seg2 ) / (seg1.Length() * seg2.Length()) );
                    if (ang > MathHelper.PiOver2)
                        continue;

                    Line line1 = new Line( p1, seg1 );
                    Line line2 = new Line( p4, seg2 );

                    Vector2 interPoint;

                    if (!MathTools.InterPoint( line1, line2, out interPoint ))
                        continue;

                    templist[(i + 1) % templist.Count] =
                        new BordPoint( templist[(i + 1) % templist.Count].index, ConvertHelper.Vector2ToPoint( interPoint ) );

                    templist.RemoveAt( (i + 2) % templist.Count );

                    i--;
                }
            }

            #endregion

            convexPoints = templist;
        }

        private bool CountWise ( BordPoint p1, BordPoint p0, BordPoint p2 )
        {
            Vector2 v1 = new Vector2( p1.p.X - p0.p.X, p1.p.Y - p0.p.Y );
            Vector2 v2 = new Vector2( p2.p.X - p1.p.X, p2.p.Y - p1.p.Y );
            float cross = MathTools.Vector2Cross( v1, v2 );
            return cross < 0 || cross == 0 && Vector2.Dot( v1, v2 ) < 0;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Update;
using SmartTank.Draw;
using Microsoft.Xna.Framework;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework.Graphics;

namespace SmartTank.GameObjs
{
    /*
     * 定义了场景物体的一般接口。
     * 
     * */

    public interface IGameObj : IUpdater, IDrawableObj
    {
        string Name { get;}
        GameObjInfo ObjInfo { get;}
        new Vector2 Pos { get;set;}
        float Azi { get;}
    }

    public delegate void OnCollidedEventHandler( IGameObj Sender, CollisionResult result, GameObjInfo objB );
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Text;
using Common.Helpers;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.Xml;
using System.Xml.Serialization;

namespace GameEngine.Graphics
{
    class ChineseWriter
    {
        struct TextKey
        {
            public string text;
            public string fontName;

            public TextKey( string text, string fontName )
            {
                this.text = text;
                this.fontName = fontName;
            }
        }


        RenderEngine engine;

        PrivateFontCollection privateFontCollection;
        System.Drawing.FontFamily[] fontFamilys;
        System.Drawing.Graphics mesureGraphics;

        Dictionary<string, System.Drawing.Font> fonts;

        Dictionary<TextKey, Texture2D> cache = new Dictionary<TextKey, Texture2D>();

        public ChineseWriter( RenderEngine engine )
        {
            this.engine = engine;
            this.fonts = new Dictionary<string, System.Drawing.Font>();
        }

        public bool HasFont( string fontName )
        {
            return fonts.ContainsKey( fontName );
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public void Intitial( FontMgr.FontLoadInfo fontLoadInfo )
        {
            try
            {
                privateFontCollection = new PrivateFontCollection();

                foreach (FontMgr.FontInfo info in fontLoadInfo.UnitCodeFontInfos)
                {
                    privateFontCollection.AddFontFile( info.path );
                }

                fontFamilys = privateFontCollection.Families;

                if (fontFamilys.Length != fontLoadInfo.UnitCodeFontInfos.Count)
                    throw new Exception( "导入的各个字体必须属于不同类别" );

                for (int i = 0; i < fontFamilys.Length; i++)
                {
                    fonts.Add( fontLoadInfo.UnitCodeFontInfos[i].name, new System.Drawing.Font( fontFamilys[i], fontLoadInfo.DefualtEmSize ) );
                }

                System.Drawing.Bitmap tempBitMap = new System.Drawing.Bitmap( 1, 1 );
                mesureGraphics = System.Drawing.Graphics.FromImage( tempBitMap );
            }
            catch (Exception)
            {
                throw new Exception( "读取字体文件出错" );
            }

        }

        /// <summary>
        /// 绘制包含中文字的文字
        /// </summary>
        /// <param name="text">要绘制的文字</param>
        /// <param name="scrnPos">绘制的屏幕位置</param>
        /// <param name="rota">旋转角</param>
        /// <param name="scale">缩放比</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">绘制深度</param>
        /// <param name="fontName">字体名称</param>
        public void WriteText( string text, Vector2 scrnPos, float rota, float scale, Color color, float layerDepth, string fontName )
        {
            Texture2D texture;

            TextKey key = new TextKey( text, fontName );

            if (cache.ContainsKey( key ))
            {
                texture = cache[key];
            }
            else
            {
                texture = BuildTexture( text, fontName );
            }

            engine.SpriteMgr.alphaSprite.Draw( texture, scrnPos, null, color, rota, new Vector2( 0, 0 ), scale, SpriteEffects.None, layerDepth );

        }

        /// <summary>
        /// 建立贴图并添加到缓冲中。
        /// 尽量在第一次绘制之前调用该函数，这样可以避免建立贴图的过程造成游戏的停滞
        /// </summary>
        /// <param name="text">要创建的字符串</param>
        /// <param name="fontName">字体</param>
        /// <returns></returns>
        public Texture2D BuildTexture( string text, string fontName )
        {
            TextKey key = new TextKey( text, fontName );

            if (cache.ContainsKey( key ))
                return null;

            if (!fonts.ContainsKey( fontName ))
            {
                Log.Write( "error fontName used in BuildTexture" );
                return null;
            }

            System.Drawing.Font font = fonts[fontName];

            System.Drawing.SizeF size = mesureGraphics.MeasureString( text, font );
            int texWidth = (int)size.Width;
            int texHeight = (int)size.Height;

            System.Drawing.Bitmap textMap = new System.Drawing.Bitmap( texWidth, texHeight );
            System.Drawing.Graphics curGraphics = System.Drawing.Graphics.FromImage( textMap );
            curGraphics.DrawString( text, font, System.Drawing.Brushes.White, new System.Drawing.PointF() );

            Texture2D texture = new Texture2D( engine.Device, texWidth, texHeight, 1, TextureUsage.None, SurfaceFormat.Color );
            Microsoft.Xna.Framework.Graphics.Color[] data = new Microsoft.Xna.Framework.Graphics.Color[texWidth * texHeight];
            for (int y = 0; y < texHeight; y++)
            {
                for (int x = 0; x < texWidth; x++)
                {
                    data[y * texWidth + x] = ConvertHelper.SysColorToXNAColor( textMap.GetPixel( x, y ) );
                }
            }

            texture.SetData<Microsoft.Xna.Framework.Graphics.Color>( data );

            cache.Add( key, texture );

            curGraphics.Dispose();

            return texture;
        }

        /// <summary>
        /// 返回字符串的长度
        /// </summary>
        /// <param name="text">要测量的字符串</param>
        /// <param name="scale">字符串的缩放率</param>
        /// <param name="fontName">字体</param>
        /// <returns></returns>
        public float MeasureString( string text, float scale, string fontName )
        {
            System.Drawing.Font font = fonts[fontName];
            return mesureGraphics.MeasureString( text, font ).Width;
        }

        /// <summary>
        /// 清除缓冲
        /// </summary>
        public void ClearCache()
        {
            foreach (KeyValuePair<TextKey, Texture2D> pair in cache)
            {
                pair.Value.Dispose();
            }

            cache.Clear();
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.AI;
using SmartTank.AI.AIHelper;
using TankEngine2D.DataStructure;
using TankEngine2D.Graphics;
using SmartTank.GameObjs;
using SmartTank.Senses.Vision;
using SmartTank.GameObjs.Tank.SinTur;

namespace InterRules.Duel
{
    [AIAttribute( "DuelAIModel", "SmartTank Team", "A Model for DuelAI", 2007, 11, 6 )]
    public class DuelAIModel : IDuelAI
    {
        DuelAIOrderServer orderServer;
        AICommonServer commonServer;

        // 可以使用该类提供的高层接口
        AIActionHelper action;

        Rectanglef mapBorder;

        public DuelAIModel ()
        {

        }

        #region IAI 成员

        public IAICommonServer CommonServer
        {
            set
            {
                commonServer = (AICommonServer)value;

                // 可以从CommonServer中获得游戏中与当前坦克无关的一些参数。如：
                mapBorder = commonServer.MapBorder;
            }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = (DuelAIOrderServer)value;
                // 可以添加事件处理
                orderServer.OnCollide += new OnCollidedEventHandlerAI( CollideHandler );

                // 如果使用了AIActionHelper，则需要在此进行初始化。
                action = new AIActionHelper( orderServer );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            // 可以从OrderServer中获得坦克当前的状态，并发出命令。如下：
            Vector2 curPos = orderServer.Pos;

            if (orderServer.FireLeftCDTime <= 0)
                orderServer.Fire();

            orderServer.ForwardSpeed = orderServer.MaxForwardSpeed;

            // 调用orderServer的GetEyeableInfo函数来获得视野中物体（敌对坦克的信息）。
            List<IEyeableInfo> eyeableInfos = orderServer.GetEyeableInfo();
            if (eyeableInfos.Count != 0)
            {
                if (eyeableInfos[0].ObjInfo.ObjClass == "DuelTank" && eyeableInfos[0] is TankSinTur.TankCommonEyeableInfo)
                {
                    // 可获得目标坦克的信息，如下：
                    Vector2 enemyPos = ((TankSinTur.TankCommonEyeableInfo)eyeableInfos[0]).Pos;
                    Vector2 enemyDirection = ((TankSinTur.TankCommonEyeableInfo)eyeableInfos[0]).Direction;

                }
            }


            /* 用AIActionHelper可以使用不少高级的运动指令
             * 
             * 列表如下：
             * RotaToAziOrder           旋转坦克到制定方位角
             * RotaTurretToAziOrder
             * RotaTurretToPosOrder     旋转坦克炮塔直到瞄准制定位置
             * RotaRaderToAziOrder
             * RotaRaderToPosOrder
             * MoveOrder                让坦克向前或向后移动一段距离
             * MoveToPosDirectOrder     直线移动到制定点
             * MoveCircleOrder          沿着一个圆弧的路径走到目标点
             * 
             * 也可以自己从IActionOrder接口继承自己的高级运动指令。
             * */
            action.AddOrder( new OrderRotaRaderToPos( new Vector2( 100, 100 ) ) );
            action.AddOrder( new OrderMoveCircle( new Vector2( 100, 100 ), orderServer.MaxForwardSpeed, orderServer,
                delegate( IActionOrder order )
                {
                    orderServer.Fire();
                }, false ) );

            // 终止一个命令
            action.StopRota();

            // 如果使用AIActionHelper，必须调用他的Update函数
            action.Update( seconds );
        }

        #endregion

        void CollideHandler ( CollisionResult result, GameObjInfo objB )
        {
            // 通过objB的信息确定碰撞物的种类。
            if (objB.ObjClass == "Border")
            {
                // 添加自己的处理函数
            }
            else if (objB.ObjClass == "ShellNormal")
            {
                // 添加自己的处理函数
            }
            else if (objB.ObjClass == "DuelTank")
            {
                // 添加自己的处理函数
            }

        }



        #region IAI 成员


        public void Draw ()
        {
            
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using Common.Helpers;

namespace GameEngine.Draw.BackGround.VergeTile
{
    public class VergeTileData
    {
        #region statics

        static XmlSerializer serializer;

        public static void Save ( Stream stream, VergeTileData data )
        {
            if (serializer == null)
                serializer = new XmlSerializer( typeof( VergeTileData ) );

            try
            {
                serializer.Serialize( stream, data );
            }
            catch (Exception)
            {
                Log.Write( "Save VergeTileData error!" );
            }
            finally
            {
                stream.Close();
            }
        }

        public static VergeTileData Load ( Stream stream )
        {
            if (serializer == null)
                serializer = new XmlSerializer( typeof( VergeTileData ) );

            VergeTileData result = null;
            try
            {
                result = (VergeTileData)serializer.Deserialize( stream );
            }
            catch (Exception)
            {
                Log.Write( "Load VergeTileData error!" );
            }
            finally
            {
                stream.Close();
            }
            return result;
        }

        #endregion

        #region Variables

        public int gridWidth;

        public int gridHeight;

        /// <summary>
        /// 每个顶点处的纹理图索引
        /// sum = (gridWidth + 1) * (gridHeight + 1);
        /// index = x + (gridWidth + 1) * y;
        /// </summary>
        public int[] vertexTexIndexs;

        /// <summary>
        /// 每个格子中的纹理图索引
        /// </summary>
        public int[] gridTexIndexs;

        /// <summary>
        /// 纹理图地址
        /// </summary>
        public string[] texPaths;

        #endregion

        public VergeTileData ()
        {

        }

        public void SetRondomVertexIndex ( int gridWidth, int gridHeight, int usedTexSum )
        {
            vertexTexIndexs = new int[(gridWidth + 1) * (gridHeight + 1)];
            for (int i = 0; i < vertexTexIndexs.Length; i++)
            {
                vertexTexIndexs[i] = RandomHelper.GetRandomInt( 0, usedTexSum );
            }

        }

        public void SetRondomGridIndex ( int gridWidth, int gridHeight )
        {
            gridTexIndexs = new int[gridWidth * gridHeight];
            for (int i = 0; i < gridTexIndexs.Length; i++)
            {
                gridTexIndexs[i] = RandomHelper.GetRandomInt( 0, 17 );
            }
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Graphics;
using TankEngine2D.Helpers;

namespace SmartTank.PhiCol
{

    /// <summary>
    /// 物理更新和冲突管理者
    /// </summary>
    public class PhiColMgr
    {
        const int maxIterDepth = 10;

        #region private type

        struct BinGroup
        {
            public IEnumerable<ICollideObj> group1;
            public IEnumerable<ICollideObj> group2;

            public BinGroup ( IEnumerable<ICollideObj> group1, IEnumerable<ICollideObj> group2 )
            {
                this.group1 = group1;
                this.group2 = group2;
            }
        }

        struct CollisionResultGroup
        {
            public ICollideObj colA;
            public ICollideObj colB;
            public CollisionResult result;

            public CollisionResultGroup ( ICollideObj colA, ICollideObj colB, CollisionResult result )
            {
                this.colA = colA;
                this.colB = colB;
                this.result = result;
            }
        }

        #endregion

        #region Variables

        List<IEnumerable<IPhisicalObj>> PhisicalGroups = new List<IEnumerable<IPhisicalObj>>();

        /*
         * 不允许碰撞物体重叠的组
         * */
        List<IEnumerable<ICollideObj>> ColliderGroups_Single = new List<IEnumerable<ICollideObj>>();
        List<BinGroup> ColliderGroups_Binary = new List<BinGroup>();

        /*
         * 允许碰撞物体重叠的组
         * */
        List<IEnumerable<ICollideObj>> ColliderGroups_CanOverlap_Single = new List<IEnumerable<ICollideObj>>();
        List<BinGroup> ColliderGroups_CanOverlap_Binary = new List<BinGroup>();

        #endregion

        #region Public Methods

        /// <summary>
        /// 添加需要管理成员彼此间的碰撞的组，不允许重叠。
        /// </summary>
        /// <param name="group"></param>
        public void AddCollideGroup ( IEnumerable<ICollideObj> group )
        {
            ColliderGroups_Single.Add( group );
        }

        /// <summary>
        /// 添加需要管理彼此之间的碰撞的两个组。不检查两个组内部成员的碰撞。不允许重叠。
        /// </summary>
        /// <param name="group1"></param>
        /// <param name="group2"></param>
        public void AddCollideGroup ( IEnumerable<ICollideObj> group1, IEnumerable<ICollideObj> group2 )
        {
            ColliderGroups_Binary.Add( new BinGroup( group1, group2 ) );
        }

        /// <summary>
        /// 添加需要管理成员彼此间的碰撞的组，允许重叠。
        /// </summary>
        /// <param name="group"></param>
        public void AddOverlapGroup ( IEnumerable<ICollideObj> group )
        {
            ColliderGroups_CanOverlap_Single.Add( group );
        }

        /// <summary>
        /// 添加需要管理彼此之间的碰撞的两个组。不检查两个组内部成员的碰撞，允许重叠。
        /// </summary>
        /// <param name="group1"></param>
        /// <param name="group2"></param>
        public void AddOverlapGroup ( IEnumerable<ICollideObj> group1, IEnumerable<ICollideObj> group2 )
        {
            ColliderGroups_CanOverlap_Binary.Add( new BinGroup( group1, group2 ) );
        }


        /// <summary>
        /// 清空所有已添加的组。
        /// </summary>
        public void ClearGroups ()
        {
            ColliderGroups_Single.Clear();
            ColliderGroups_Binary.Clear();
            ColliderGroups_CanOverlap_Single.Clear();
            ColliderGroups_CanOverlap_Binary.Clear();
            PhisicalGroups.Clear();
        }

        /// <summary>
        /// 添加物理更新物体组。
        /// </summary>
        /// <param name="phisicals"></param>
        public void AddPhiGroup ( IEnumerable<IPhisicalObj> phisicals )
        {
            PhisicalGroups.Add( phisicals );
        }

        #endregion

        #region Update

        /// <summary>
        /// 更新注册物体的物理状态并执行冲突检测与处理。
        /// </summary>
        /// <param name="seconds">当前帧与上一帧的时间间隔，以秒为单位</param>
        public void Update ( float seconds )
        {
            // 计算每一个物理更新物体的下一个状态。
            foreach (IEnumerable<IPhisicalObj> group in PhisicalGroups)
            {
                foreach (IPhisicalObj phiObj in group)
                {
                    phiObj.PhisicalUpdater.CalNextStatus( seconds );
                }
            }

            // 检查可重叠物体的碰撞情况，如果碰撞，调用处理函数。
            CheckOverlap();

            // 检查下一个状态的碰撞情况,并进行处理。确保新状态中任何物体不碰撞。
            iterDepth = 0;
            HandleCollision( true );

            // 应用物体的新状态。
            foreach (IEnumerable<IPhisicalObj> group in PhisicalGroups)
            {
                foreach (IPhisicalObj phiObj in group)
                {
                    phiObj.PhisicalUpdater.Validated();
                }
            }

        }

        private void CheckOverlap ()
        {
            List<CollisionResultGroup> colResults = new List<CollisionResultGroup>();

            foreach (IEnumerable<ICollideObj> singleGroup in ColliderGroups_CanOverlap_Single)
            {
                ICollideObj[] temp = GetArray( singleGroup );
                for (int i = 0; i < temp.Length - 1; i++)
                {
                    for (int j = i + 1; j < temp.Length; j++)
                    {
                        CollisionResult result = temp[i].ColChecker.CollideMethod.CheckCollision( temp[j].ColChecker.CollideMethod );
                        if (result.IsCollided)
                        {
                            colResults.Add( new CollisionResultGroup( temp[i], temp[j], result ) );
                        }
                    }
                }
            }

            foreach (BinGroup binaryGroup in ColliderGroups_CanOverlap_Binary)
            {
                foreach (ICollideObj colA in binaryGroup.group1)
                {
                    foreach (ICollideObj colB in binaryGroup.group2)
                    {
                        CollisionResult result = colA.ColChecker.CollideMethod.CheckCollision( colB.ColChecker.CollideMethod );
                        if (result.IsCollided)
                        {
                            colResults.Add( new CollisionResultGroup( colA, colB, result ) );
                        }
                    }
                }

            }

            foreach (CollisionResultGroup group in colResults)
            {
                group.colA.ColChecker.HandleOverlap( group.result, group.colB );
                group.colB.ColChecker.HandleOverlap( new CollisionResult( group.result.InterPos, -group.result.NormalVector ), group.colA );
            }

        }

        int iterDepth = 0;
        private void HandleCollision ( bool CallHandleCollision )
        {
            List<CollisionResultGroup> colResults = new List<CollisionResultGroup>();


            List<ICollideObj> Collideds = new List<ICollideObj>();

            #region 处理singleGroups

            foreach (IEnumerable<ICollideObj> singleGroup in ColliderGroups_Single)
            {
                ICollideObj[] temp = GetArray( singleGroup );
                for (int i = 0; i < temp.Length - 1; i++)
                {
                    for (int j = i + 1; j < temp.Length; j++)
                    {
                        CollisionResult result = temp[i].ColChecker.CollideMethod.CheckCollision( temp[j].ColChecker.CollideMethod );
                        if (result.IsCollided)
                        {
                            if (CallHandleCollision)
                            {
                                colResults.Add( new CollisionResultGroup( temp[i], temp[j], result ) );
                                //temp[i].ColChecker.HandleCollision( result, temp[j].ObjInfo );
                                //temp[j].ColChecker.HandleCollision( new CollisionResult( result.InterPos, -result.NormalVector ), temp[i].ObjInfo );
                            }
                            Collideds.Add( temp[i] );
                            Collideds.Add( temp[j] );
                        }
                    }
                }
            }

            #endregion

            #region 处理binaryGroups

            foreach (BinGroup binaryGroup in ColliderGroups_Binary)
            {
                foreach (ICollideObj colA in binaryGroup.group1)
                {
                    foreach (ICollideObj colB in binaryGroup.group2)
                    {
                        CollisionResult result = colA.ColChecker.CollideMethod.CheckCollision( colB.ColChecker.CollideMethod );
                        if (result.IsCollided)
                        {
                            if (CallHandleCollision)
                            {
                                colResults.Add( new CollisionResultGroup( colA, colB, result ) );
                            }
                            Collideds.Add( colA );
                            Collideds.Add( colB );
                        }
                    }
                }

            }
            #endregion

            foreach (CollisionResultGroup group in colResults)
            {
                group.colA.ColChecker.HandleCollision( group.result, group.colB );
                group.colB.ColChecker.HandleCollision( new CollisionResult( group.result.InterPos, -group.result.NormalVector ), group.colA );
            }


            iterDepth++;
            if (iterDepth > maxIterDepth)
            {
                return;
            }

            if (Collideds.Count != 0)
            {
                foreach (ICollideObj col in Collideds)
                {
                    col.ColChecker.ClearNextStatus();
                }
                HandleCollision( false );
            }
        }

        private ICollideObj[] GetArray ( IEnumerable<ICollideObj> group )
        {
            List<ICollideObj> temp = new List<ICollideObj>( 64 );
            IEnumerator<ICollideObj> iter = group.GetEnumerator();
            if (iter.Current != null)
            {
                temp.Add( iter.Current );
            }
            while (iter.MoveNext())
            {
                temp.Add( iter.Current );
            }
            return temp.ToArray();
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Update;
using SmartTank.Draw;

namespace SmartTank.AI
{
    public interface IAI : IUpdater
    {
        IAIOrderServer OrderServer { set;}
        IAICommonServer CommonServer { set;}

        void Draw ();
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace InterRules.Starwar
{
    class SpaceWarConfig
    {
        public static float SpeedMax;
        public static float SpeedAccel;       // 加速度
        public static float SpeedDecay;       // 在无输入状态下每秒降低的速度百分比，实际是积分过程 
        public static float StillSpeedScale; // 硬直状态下移动速度的缩减系数

        public static int IniHP;
        public static float ShootCD;
        public static int HitbyShellDamage;
        public static int HitbyObjExceptShell;
        public static float StillTime;
        public static float WTFTime;
        public static int ScoreByHit;

        public static int ShootEndDest;

        public static int ShellSpeed;
        public static int ShellLiveTime;

        public static int GoldScore;
        public static float GoldLiveTime;

        public static float RockCreateTime;
        public static float RockMinSpeed;
        public static float RockMaxSpeed;
        public static float RockMaxAziSpeed;

        public static float GameTotolTime;

        static public void LoadConfig()
        {
            FileStream confile = File.OpenRead("Content\\Rules\\SpaceWar\\WarShipConfig.txt");
            StreamReader SR = new StreamReader(confile);
            string line = "";
            try
            {
                while (!SR.EndOfStream)
                {
                    line = SR.ReadLine();

                    if (line.StartsWith("SpeedMax=")) SpaceWarConfig.SpeedMax = float.Parse(line.Substring(9));
                    else if (line.StartsWith("SpeedAccel=")) SpaceWarConfig.SpeedAccel = float.Parse(line.Substring(11));
                    else if (line.StartsWith("SpeedDecay=")) SpaceWarConfig.SpeedDecay = float.Parse(line.Substring(11));
                    else if (line.StartsWith("StillSpeedScale=")) SpaceWarConfig.StillSpeedScale = float.Parse(line.Substring(16));
                    else if (line.StartsWith("IniHP=")) SpaceWarConfig.IniHP = int.Parse(line.Substring(6));
                    else if (line.StartsWith("ShootCD=")) SpaceWarConfig.ShootCD = float.Parse(line.Substring(8));
                    else if (line.StartsWith("HitbyShellDamage=")) SpaceWarConfig.HitbyShellDamage = int.Parse(line.Substring(17));
                    else if (line.StartsWith("HitbyObjDamage=")) SpaceWarConfig.HitbyObjExceptShell = int.Parse(line.Substring(15));
                    else if (line.StartsWith("StillTime=")) SpaceWarConfig.StillTime = float.Parse(line.Substring(10));
                    else if (line.StartsWith("WTFTime=")) SpaceWarConfig.WTFTime = float.Parse(line.Substring(8));
                    else if (line.StartsWith("ScoreByHit=")) SpaceWarConfig.ScoreByHit = int.Parse(line.Substring(11));
                    else if (line.StartsWith("ShootEndDest=")) SpaceWarConfig.ShootEndDest = int.Parse(line.Substring(13));
                    else if (line.StartsWith("ShellSpeed=")) SpaceWarConfig.ShellSpeed = int.Parse(line.Substring(11));
                    else if (line.StartsWith("ShellLiveTime=")) SpaceWarConfig.ShellLiveTime = int.Parse(line.Substring(14));
                    else if (line.StartsWith("GoldScore=")) SpaceWarConfig.GoldScore = int.Parse(line.Substring(10));
                    else if (line.StartsWith("GoldLiveTime=")) SpaceWarConfig.GoldLiveTime = float.Parse(line.Substring(13));
                    else if (line.StartsWith("RockCreateTime=")) SpaceWarConfig.RockCreateTime = float.Parse(line.Substring(15));
                    else if (line.StartsWith("RockMinSpeed=")) SpaceWarConfig.RockMinSpeed = float.Parse(line.Substring(13));
                    else if (line.StartsWith("RockMaxSpeed=")) SpaceWarConfig.RockMaxSpeed = float.Parse(line.Substring(13));
                    else if (line.StartsWith("RockMaxAziSpeed=")) SpaceWarConfig.RockMaxAziSpeed = float.Parse(line.Substring(16));
                    else if (line.StartsWith("GameTotolTime=")) SpaceWarConfig.GameTotolTime = float.Parse(line.Substring(14));
                    
                }
            }
            catch (Exception ex)
            {
                throw new Exception("WarShipConfig.txt配置文件格式错误 ： " + line + "  " + ex.ToString());
            }

        }

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;

namespace GameEngine.Graphics
{
    /// <summary>
    /// 精灵绘制的管理者
    /// </summary>
    public class SpriteMgr
    {
        /// <summary>
        /// AlphaSprite
        /// </summary>
        public SpriteBatch alphaSprite;
        /// <summary>
        /// AdditiveSprite
        /// </summary>
        public SpriteBatch additiveSprite;

        GraphicsDevice device;

        internal SpriteMgr ( RenderEngine engine )
        {
            this.device = engine.Device;
            alphaSprite = new SpriteBatch( device );
            additiveSprite = new SpriteBatch( device );
        }

        internal GraphicsDevice Device
        {
            get { return device; }
        }

        internal void HandleDeviceReset ()
        {
            Intial( device );
        }

        private void Intial ( GraphicsDevice device )
        {
            alphaSprite = new SpriteBatch( device );
            additiveSprite = new SpriteBatch( device );
        }

        /// <summary>
        /// alphaSprite.Begin( SpriteBlendMode.AlphaBlend, SpriteSortMode.BackToFront, SaveStateMode.None );
        /// additiveSprite.Begin( SpriteBlendMode.Additive, SpriteSortMode.BackToFront, SaveStateMode.None );
        /// </summary>
        internal void SpriteBatchBegin ()
        {
            alphaSprite.Begin( SpriteBlendMode.AlphaBlend, SpriteSortMode.BackToFront, SaveStateMode.None );
            additiveSprite.Begin( SpriteBlendMode.Additive, SpriteSortMode.BackToFront, SaveStateMode.None );
        }

        /// <summary>
        /// Sprite.alphaSprite.End();
        /// Sprite.additiveSprite.End();
        /// </summary>
        internal void SpriteBatchEnd ()
        {
            alphaSprite.End();
            additiveSprite.End();
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using SmartTank.GameObjs;
using System.Reflection;
using SmartTank.Helpers.DependInject;

namespace SmartTank.net
{
    public static class SyncCasheReader
    {

        static SyncCashe inputCashe;
        static public SyncCashe InputCashe
        {
            get { return inputCashe; }
            set { inputCashe = value; }
        }

        public delegate void CreateObjInfoHandler(IGameObj obj);
        public static event CreateObjInfoHandler onCreateObj;
        public delegate void UserDefineInfoHandler(string infoName, string infoID, object[] args);
        public static event UserDefineInfoHandler onUserDefineInfo;



        internal static void ReadCashe(SmartTank.Scene.ISceneKeeper sceneMgr)
        {
            Monitor.Enter(inputCashe);

            try
            {
                foreach (ObjStatusSyncInfo info in inputCashe.ObjStaInfoList)
                {
                    if ((PurviewMgr.IsMainHost && PurviewMgr.IsSlaveMgObj(info.objMgPath))
                        || (!PurviewMgr.IsMainHost && !PurviewMgr.IsSlaveMgObj(info.objMgPath)))
                    {
                        IGameObj obj = sceneMgr.GetGameObj(info.objMgPath);

                        if (obj == null)
                            continue;

                        Type objType = obj.GetType();
                        objType.GetProperty(info.statusName).SetValue(obj, info.values[0], null); //暂时只处理一个值的情况
                    }
                }

                foreach (ObjEventSyncInfo info in inputCashe.ObjEventInfoList)
                {
                    if (PurviewMgr.IsMainHost && PurviewMgr.IsSlaveMgObj(info.objMgPath))
                    {
                        IGameObj obj = sceneMgr.GetGameObj(info.objMgPath);

                        Type objType = obj.GetType();
                        MethodInfo method = objType.GetMethod("Call" + info.EventName);

                        object[] newParams = new object[info.values.Length];
                        for (int i = 0; i < info.values.Length; i++)
                        {
                            if (info.values[i] is GameObjSyncInfo)
                            {
                                IGameObj gameobj = sceneMgr.GetGameObj(((GameObjSyncInfo)info.values[i]).MgPath);
                                newParams[i] = gameobj;
                            }
                            else
                            {
                                newParams[i] = info.values[i];

                            }
                        }
                        method.Invoke(obj, newParams);

                        //objType.InvokeMember("Call" + info.EventName,  BindingFlags. BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, obj, info.values);
                    }
                }

                if (!PurviewMgr.IsMainHost)
                {
                    foreach (ObjMgSyncInfo info in inputCashe.ObjMgInfoList)
                    {
                        if (info.objMgKind == (int)ObjMgKind.Create)
                        {
                            object[] newArgs = new object[info.args.Length];

                            Type[] argTypes = new Type[info.args.Length];
                            for (int i = 0; i < info.args.Length; i++)
                            {
                                if (info.args[i] == null)
                                {
                                    argTypes[i] = null;
                                }
                                else
                                {
                                    if (info.args[i] is GameObjSyncInfo)
                                    {
                                        IGameObj gameobj = sceneMgr.GetGameObj(((GameObjSyncInfo)info.args[i]).MgPath);
                                        argTypes[i] = gameobj.GetType();
                                        newArgs[i] = gameobj;
                                    }
                                    else
                                    {
                                        argTypes[i] = info.args[i].GetType();
                                        newArgs[i] = info.args[i];
                                    }
                                }
                            }

                            Type newObjType = DIHelper.GetType(info.objType);
                            object newObj = newObjType.GetConstructor(argTypes).Invoke(newArgs);
                            sceneMgr.AddGameObj(info.objPath, (IGameObj)newObj);
                            if (onCreateObj != null)
                                onCreateObj((IGameObj)newObj);
                        }
                        else if (info.objMgKind == (int)ObjMgKind.Delete)
                        {
                            sceneMgr.DelGameObj(info.objPath);
                        }
                    }
                }


                foreach (UserDefineInfo info in inputCashe.UserDefineInfoList)
                {
                    object[] newArgs = new object[info.args.Length];
                    for (int i = 0; i < newArgs.Length; i++)
                    {
                        if (info.args[i] is GameObjSyncInfo)
                        {
                            IGameObj gameobj = sceneMgr.GetGameObj(((GameObjSyncInfo)info.args[i]).MgPath);
                            newArgs[i] = gameobj;
                        }
                        else
                        {
                            newArgs[i] = info.args[i];
                        }
                    }
                    if (onUserDefineInfo != null)
                        onUserDefineInfo(info.infoName, info.infoID, newArgs);
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine("SyncCashReader 解析过程出现异常： " + ex);
            }
            finally
            {
                inputCashe.ObjStaInfoList.Clear();
                inputCashe.ObjEventInfoList.Clear();
                inputCashe.ObjMgInfoList.Clear();
                inputCashe.UserDefineInfoList.Clear();
                Monitor.Exit(inputCashe);
            }
        }
    }
}
<file_sep>//=================================================
// xWinForms
// Copyright ?2007 by <NAME>
// http://psycad007.spaces.live.com/
//=================================================
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Timers;
using System.IO;
using TankEngine2D.Helpers;
using TankEngine2D.Graphics;
using SmartTank.Helpers;

namespace SmartTank.Draw.UI.Controls
{
    public class Textbox : Control
    {
        #region Variables
        public Texture2D[] parts;
        public float width = 30f;


        Color color = Color.White;
        Color textColor = Color.Black;

        Rectangle middlePartRect = Rectangle.Empty;

        bool bHasFocus = false;

        public event EventHandler OnMouseDown;
        public event EventHandler OnKeyPress;

        MouseState ms;
        KeyboardState ks;
        Keys[] textKeys = { Keys.A, Keys.B, Keys.C, Keys.D, Keys.E, Keys.F, Keys.G, Keys.H, Keys.I, Keys.J, Keys.K, Keys.L, Keys.M, Keys.N, Keys.O, Keys.P, Keys.Q, Keys.R, Keys.S, Keys.T, Keys.U, Keys.V, Keys.W, Keys.X, Keys.Y, Keys.Z, Keys.NumPad0, Keys.NumPad1, Keys.NumPad2, Keys.NumPad3, Keys.NumPad4, Keys.NumPad5, Keys.NumPad6, Keys.NumPad7, Keys.NumPad8, Keys.NumPad9, Keys.Space, Keys.Enter };
        Keys[] numericKeys = { Keys.NumPad0, Keys.NumPad1, Keys.NumPad2, Keys.NumPad3, Keys.NumPad4, Keys.NumPad5, Keys.NumPad6, Keys.NumPad7, Keys.NumPad8, Keys.NumPad9, Keys.Enter };
        List<Keys> pressedKeys;
        public bool bNumerical = false;

        Timer keyTimer;

        int cursorPos = 0;
        bool bInputKeyDown = false;
        bool bBackspaceDown = false;
        bool bLeftKey = false;
        bool bRightKey = false;
        bool bDeleteKey = false;
        bool bHomeKey = false;
        bool bEndKey = false;

        Timer cursorTimer;
        bool bCursorVisible = false;

        int characterWidth = 9;

        public Point size = Point.Zero;

        //public Form.Style style = Form.Style.Default;

        int startIndex = 0;
        int endIndex = 0;
        int visibleChar = 0;
        #endregion

        #region Construction
        public Textbox( string name, Vector2 position, float width, string text, bool bNumerical )//, Font font, Form.Style style)        
        {
            this.Type = ControlType.Textbox;
            this.name = name;
            this.position = position;
            this.text = text;
            this.width = width;
            this.bNumerical = bNumerical;

            parts = new Texture2D[3];
            parts[0] = BaseGame.ContentMgr.Load<Texture2D>( Path.Combine( Directories.UIContent, "textbox_left" ) );
            parts[1] = BaseGame.ContentMgr.Load<Texture2D>( Path.Combine( Directories.UIContent, "textbox_middle" ) );
            parts[2] = BaseGame.ContentMgr.Load<Texture2D>( Path.Combine( Directories.UIContent, "textbox_right" ) );

            middlePartRect = new Rectangle( (int)position.X + parts[0].Width, 0, (int)width - parts[0].Width - parts[1].Width, parts[1].Height );

            this.size = new Point( parts[0].Width + middlePartRect.Width + parts[2].Width, parts[0].Height );

            if (width < parts[0].Width + parts[1].Width + parts[2].Width)
                width = parts[0].Width + parts[1].Width + parts[2].Width;

            middlePartRect.Width = (int)width - parts[0].Width - parts[2].Width;
            middlePartRect.X = (int)position.X + parts[0].Width;
            middlePartRect.Y = (int)position.Y;

            visibleChar = middlePartRect.Width / characterWidth + 1;

            OnMouseDown += new EventHandler( Select );
            OnKeyPress += new EventHandler( KeyDown );
            pressedKeys = new List<Keys>();

            cursorTimer = new Timer( 500 );
            cursorTimer.Elapsed += new ElapsedEventHandler( cursorTimer_Tick );

            keyTimer = new Timer( 1000 );
            keyTimer.Elapsed += new ElapsedEventHandler( keyTimer_Tick );
        }
        #endregion

        #region Update
        private void cursorTimer_Tick( Object obj, ElapsedEventArgs e )
        {
            bCursorVisible = !bCursorVisible;
        }

        private void keyTimer_Tick( Object obj, ElapsedEventArgs e )
        {

        }

        public override void Update()// Vector2 formPosition, Vector2 formSize )
        {
            //position = origin + formPosition;
            //middlePartRect.X = (int)position.X + parts[0].Width;
            //middlePartRect.Y = (int)position.Y;

            this.size = new Point( parts[0].Width + middlePartRect.Width + parts[2].Width, parts[0].Height );

            //CheckVisibility( formPosition, formSize );

            if (bVisible)// && !Form.isInUse)
                CheckInput();
        }

        //private void CheckVisibility ( Vector2 formPosition, Vector2 formSize )
        //{
        //    if (position.X + middlePartRect.Width + parts[2].Width > formPosition.X + formSize.X - 15f)
        //        bVisible = false;
        //    else if (position.Y + parts[1].Height > formPosition.Y + formSize.Y - 25f)
        //        bVisible = false;
        //    else
        //        bVisible = true;
        //}

        private void CheckInput()
        {
            ms = Mouse.GetState();

            if (ms.LeftButton == ButtonState.Pressed)
            {
                if (ms.X > position.X && ms.X < position.X + width)
                {
                    if (ms.Y > position.Y && ms.Y < position.Y + parts[0].Height)
                    {
                        if (!bHasFocus)
                        {
                            Select( null, EventArgs.Empty );
                            bCursorVisible = true;
                        }
                    }
                    else if (bHasFocus)
                        Unselect( null, EventArgs.Empty );
                }
                else if (bHasFocus)
                    Unselect( null, EventArgs.Empty );
            }

            if (bHasFocus)
            {
                ks = Keyboard.GetState();

                //Text keys
                bool bFoundKey = false;
                foreach (Keys thisKey in textKeys)
                {
                    if (ks.IsKeyDown( thisKey ))
                    {
                        for (int i = 0; i < pressedKeys.Count; i++)
                        {
                            if (pressedKeys[i] == thisKey)
                                bFoundKey = true;
                        }

                        if (!bFoundKey)
                        {
                            bInputKeyDown = true;
                            OnKeyPress( thisKey, null );
                        }
                    }
                    else
                    {
                        for (int i = 0; i < pressedKeys.Count; i++)
                        {
                            if (thisKey == pressedKeys[i])
                                pressedKeys.RemoveAt( i );
                        }
                    }
                }

                if (!bFoundKey && bInputKeyDown)
                    bInputKeyDown = false;

                //Backspace
                if (ks.IsKeyDown( Keys.Back ))
                {

                    if (!bBackspaceDown)
                    {
                        bBackspaceDown = true;
                        if (cursorPos > 0 && cursorPos < text.Length + 1)
                        {
                            Backspace();
                        }
                    }
                }
                else if (ks.IsKeyUp( Keys.Back ) && bBackspaceDown)
                    bBackspaceDown = false;

                //Delete
                if (ks.IsKeyDown( Keys.Delete ))
                {
                    if (!bDeleteKey)
                    {
                        bDeleteKey = true;
                        if (cursorPos < text.Length)
                            Remove();
                    }
                }
                else if (bDeleteKey)
                    bDeleteKey = false;

                if (ks.IsKeyUp( Keys.Left ))
                {
                    if (!bLeftKey)
                    {
                        bLeftKey = true;
                        if (cursorPos > 0)
                        {
                            cursorPos -= 1;
                            if (cursorPos == startIndex - 1 && startIndex > 0)
                                startIndex -= 1;
                            bCursorVisible = true;
                        }
                    }
                }
                else if (bLeftKey)
                    bLeftKey = false;

                if (ks.IsKeyUp( Keys.Right ))
                {
                    if (!bRightKey)
                    {
                        bRightKey = true;
                        if (cursorPos < text.Length)
                        {
                            cursorPos += 1;
                            if (cursorPos > startIndex + visibleChar)
                                startIndex += 1;
                            bCursorVisible = true;
                        }
                    }
                }
                else if (bRightKey)
                    bRightKey = false;

                if (ks.IsKeyDown( Keys.Home ))
                {
                    if (!bHomeKey)
                    {
                        bHomeKey = true;
                        Home();
                    }
                }
                else if (bHomeKey)
                    bHomeKey = false;

                if (ks.IsKeyDown( Keys.End ))
                {
                    if (!bEndKey)
                    {
                        bEndKey = true;
                        End();
                    }
                }
                else if (bEndKey)
                    bEndKey = false;
            }
        }

        private void Select( Object obj, EventArgs e )
        {
            cursorPos = text.Length;
            bHasFocus = true;
            cursorTimer.Start();
        }

        private void Unselect( Object obj, EventArgs e )
        {
            bHasFocus = false;
            cursorTimer.Stop();
            bCursorVisible = false;
        }

        private void KeyDown( Object obj, EventArgs e )
        {
            if (obj != null)
            {
                bInputKeyDown = true;
                Keys currentKey = (Keys)obj;

                bool bNewKey = true;
                for (int i = 0; i < pressedKeys.Count; i++)
                    if (currentKey == pressedKeys[i])
                        bNewKey = false;

                if (bNewKey)
                {
                    pressedKeys.Add( currentKey );
                    string[] strSplit = new string[2];
                    if (this.cursorPos < this.text.Length + 1)
                    {
                        strSplit[0] = this.text.Substring( 0, this.cursorPos );
                        strSplit[1] = this.text.Substring( this.cursorPos, this.text.Length - this.cursorPos );
                    }

                    if (currentKey == Keys.Space && !bNumerical)
                        Add( " " );
                    else if (currentKey != Keys.Enter)
                    {
                        if (!bNumerical)
                        {
                            bool bNumericKey = false;
                            for (int i = 0; i < numericKeys.Length; i++)
                                if (currentKey == numericKeys[i])
                                    bNumericKey = true;

                            if (bNumericKey)
                                Add( currentKey.ToString().Substring( 6, 1 ) );
                            else if (ks.IsKeyDown( Keys.LeftShift ) || ks.IsKeyDown( Keys.RightShift ))
                                Add( currentKey.ToString() );
                            else
                                Add( currentKey.ToString().ToLower() );
                        }
                        else if (bNumerical)
                        {
                            bool bNumericKey = false;
                            for (int i = 0; i < numericKeys.Length; i++)
                                if (currentKey == numericKeys[i])
                                    bNumericKey = true;

                            if (bNumericKey)
                                Add( currentKey.ToString().Substring( 6, 1 ) );
                        }
                    }
                }
            }
        }

        private void Add( string character )
        {
            if (cursorPos == text.Length)
                text = text + character;
            else
            {
                string[] strSplit = new string[2];
                strSplit[0] = text.Substring( 0, cursorPos );
                strSplit[1] = text.Substring( cursorPos, text.Length - cursorPos );
                text = strSplit[0] + character + strSplit[1];
            }

            cursorPos += 1;

            if (cursorPos > startIndex + visibleChar)
                startIndex += 1;

            //endIndex = cursorPos;
        }

        private void Remove()
        {
            string[] strSplit = new string[2];
            strSplit[0] = text.Substring( 0, cursorPos );
            strSplit[1] = text.Substring( cursorPos + 1, text.Length - cursorPos - 1 );
            text = strSplit[0] + strSplit[1];
        }

        private void Backspace()
        {
            text = text.Remove( cursorPos - 1, 1 );
            cursorPos -= 1;

            if (cursorPos < startIndex + 1)
            {
                startIndex -= visibleChar;
                endIndex = startIndex + 1;
            }
        }

        private void Home()
        {
            cursorPos = 0;
            startIndex = 0;
        }

        private void End()
        {
            cursorPos = text.Length;
            startIndex = cursorPos - visibleChar;
        }
        #endregion

        #region Draw
        public override void Draw( SpriteBatch spriteBatch, float alpha )
        {
            Color dynamicColor = new Color( new Vector4( color.ToVector3().X, color.ToVector3().Y, color.ToVector3().Z, alpha ) );
            Color dynamicTextColor = new Color( new Vector4( textColor.ToVector3().X, textColor.ToVector3().Y, textColor.ToVector3().Z, alpha ) );

            spriteBatch.Draw( parts[0], position, dynamicColor );
            spriteBatch.Draw( parts[1], middlePartRect, dynamicColor );
            spriteBatch.Draw( parts[2], position + new Vector2( parts[0].Width + middlePartRect.Width, 0f ), dynamicColor );

            if (text.Length >= visibleChar)
            {
                endIndex = text.Length - startIndex;
                if (endIndex > visibleChar)
                    endIndex = visibleChar;
            }
            else
            {
                startIndex = 0;
                endIndex = text.Length;
            }

            string visibleText = text.Substring( startIndex, endIndex );
            if (BaseGame.FontMgr.LengthOfString( visibleText, Control.fontScale, Control.fontName ) > width)
                visibleText = text.Substring( startIndex, endIndex - 1 );

            //font.Draw( text.Substring( startIndex, endIndex ), position + new Vector2( 5f, 4f ), 1f, dynamicTextColor, spriteBatch );
            BaseGame.FontMgr.DrawInScrnCoord( text.Substring( startIndex, endIndex ), position + new Vector2( 5f, 4f ), Control.fontScale, dynamicTextColor, 0f, Control.fontName );

            if (bHasFocus)
            {
                if (bCursorVisible)
                {
                    if (cursorPos - startIndex >= 0 && cursorPos - startIndex <= text.Length)
                        //    font.Draw( "|", position + new Vector2( font.Measure( text.Substring( startIndex, cursorPos - startIndex ), 1f ), 3f ), 1f, dynamicTextColor, spriteBatch );
                        BaseGame.FontMgr.DrawInScrnCoord( "|", position + new Vector2( BaseGame.FontMgr.LengthOfString( text.Substring( startIndex, cursorPos - startIndex ), Control.fontScale, Control.fontName ) + 5f, 3f ), 0.7f, dynamicTextColor, 0f, Control.fontName );
                    else
                        //    font.Draw( "|", position + new Vector2( 0f, 3f ), 1f, dynamicTextColor, spriteBatch );
                        BaseGame.FontMgr.DrawInScrnCoord( "|", position + new Vector2( 0f, 3f ), Control.fontScale, dynamicTextColor, 0f, Control.fontName );
                }
            }

        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace MapEditor
{
    class DisplayMgr
    {
        Dictionary<string, ObjDisplay> displays;
        List<ObjClassInfo> objClasses;

        public DisplayMgr ()
        {
        }

        public void Initialize ()
        {

        }

        public void SaveHistoryData ()
        {

        }

        public bool AddDisplay ( Type objClassType, string objDataPath )
        {
            // 需要能自动指定名称。如objData的名称加数字标号。

            return true;
        }

        public bool DelDisplay ( string displayName )
        {
            return true;
        }
        public bool DelDisplay ( int index )
        {
            return true;
        }

        public ObjClassInfo[] GetTypeList ()
        {
            return objClasses.ToArray();
        }

        public int SearchObjClasses ( string DLLPath )
        {
            List<ObjClassInfo> result;
            result = ObjClassSearcher.Search( DLLPath );
            if (result.Count > 0)
                objClasses.AddRange( result );
            return result.Count;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using GameEngine.Graphics;

namespace GameEngine.PhiCol
{
    /// <summary>
    /// 表示可进行冲突检测的物体
    /// </summary>
    public interface ICollideObj
    {
        /// <summary>
        /// 获得冲突检测者
        /// </summary>
        IColChecker ColChecker { get;}
    }

    /// <summary>
    /// 表示冲突检测者。
    /// 他能够通过IColMethod检测冲突，并处理冲突。
    /// 如果碰撞物体可能是一个运动物体，则必须根据下一个状态进行冲突检测。
    /// </summary>
    public interface IColChecker
    {
        /// <summary>
        /// 获得检测冲突的具体方法
        /// </summary>
        IColMethod CollideMethod { get;}

        /// <summary>
        /// 发生不可重叠式碰撞时调用这个函数。
        /// </summary>
        /// <param name="result">冲突结果</param>
        /// <param name="objB">冲突对象</param>
        void HandleCollision ( CollisionResult result, ICollideObj objA, ICollideObj objB );

        /// <summary>
        /// 当物理更新将造成不合理的重叠时必须将下一状态的撤销到与当前状态一样。
        /// </summary>
        void ClearNextStatus ();

        /// <summary>
        /// 发生可重叠式碰撞时会调用该处理函数。
        /// </summary>
        /// <param name="result">冲突结果</param>
        /// <param name="objB">冲突对象</param>
        void HandleOverlap( CollisionResult result, ICollideObj objA, ICollideObj objB );

    }

    /// <summary>
    /// 表示检测冲突的具体方法。
    /// 当前仅支持两种类型的冲突检测：
    ///     精灵与精灵的像素检测方法；
    ///     精灵与边界的检测方法。
    /// </summary>
    public interface IColMethod
    {
        /// <summary>
        /// 检测与另一对象是否冲突
        /// </summary>
        /// <param name="colB"></param>
        /// <returns></returns>
        CollisionResult CheckCollision ( IColMethod colB );

        /// <summary>
        /// 检测与精灵对象是否冲突
        /// </summary>
        /// <param name="spriteChecker"></param>
        /// <returns></returns>
        CollisionResult CheckCollisionWithSprites ( SpriteColMethod spriteChecker );

        /// <summary>
        /// 检测与边界对象是否冲突
        /// </summary>
        /// <param name="Border"></param>
        /// <returns></returns>
        CollisionResult CheckCollisionWithBorder ( BorderColMethod Border );
    }

    public delegate void OnCollidedEventHandler (CollisionResult result,ICollideObj objA, ICollideObj objB);
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.GameObjs;

namespace MapEditor
{
    class ObjDisplay
    {
        string name;
        string objDataPath;
        Type objClassType;

        IGameObj example;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public string ObjDataPath
        {
            get { return objDataPath; }
            set { objDataPath = value; }
        }

        public ObjDisplay ( string name, Type objClassType, string objDataPath )
        {
            this.name = name;
            this.objClassType = objClassType;
            this.objDataPath = objDataPath;

            example = CreateInstance();
        }

        public IGameObj CreateInstance ()
        {
            ConstructorInfo constructer = objClassType.GetConstructor( new Type[] { objDataPath.GetType() } );
            if (constructer == null)
            {
                throw new Exception( "被创建的物体类必须包含只有一个指定GameObjData文件的路径参数的构造函数" );
            }
            else
            {
                return (IGameObj)(constructer.Invoke( new object[] { objDataPath } ));
            }
        }

        public IGameObj CreateInstance ( Vector2 pos )
        {
            IGameObj result = CreateInstance();
            result.Pos = pos;
            return result;
        }

        public void DrawExampleAt ( Vector2 pos )
        {
            example.Pos = pos;
            example.Draw();
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using TankEngine2D.Helpers;
using TankEngine2D.Graphics;
using TankEngine2D.Input;
using TankEngine2D;
using SmartTank.Helpers;
using SmartTank.Draw;

namespace SmartTank
{
    public class BaseGame : Game
    {
        #region Variables

        protected static GraphicsDeviceManager graphics;
        protected static ContentManager content;

        protected static bool showFps = true;
        protected static int Fps = 0;

        protected static GameTime curTime;

        protected static Rectangle clientRec;

        protected static BaseGame curInstance;

        protected static RenderEngine renderEngine;

        #endregion

        #region Properties

        public static GraphicsDevice Device
        {
            get { return graphics.GraphicsDevice; }
        }

        public static ContentManager ContentMgr
        {
            get { return content; }
        }

        public static RenderEngine RenderEngine
        {
            get { return renderEngine; }
            set { renderEngine = value; }
        }

        public static CoordinMgr CoordinMgr
        {
            get
            {
                if (renderEngine != null)
                    return renderEngine.CoordinMgr;
                return null;
            }
        }

        public static FontMgr FontMgr
        {
            get
            {
                if (renderEngine != null)
                    return renderEngine.FontMgr;
                return null;
            }
        }

        public static SpriteMgr SpriteMgr
        {
            get
            {
                if (renderEngine != null)
                    return renderEngine.SpriteMgr;
                return null;
            }
        }

        public static AnimatedMgr AnimatedMgr
        {
            get
            {
                if (renderEngine != null)
                    return renderEngine.AnimatedMgr;
                return null;
            }
        }

        public static BasicGraphics BasicGraphics
        {
            get
            {
                if (renderEngine != null)
                    return renderEngine.BasicGrahpics;
                return null;
            }
        }

        public static float CurTime
        {
            get { return (float)curTime.TotalGameTime.TotalSeconds; }
        }

        public static Rectangle ClientRect
        {
            get { return clientRec; }
        }

        public static bool ShowFPS
        {
            get { return showFps; }
            set { showFps = value; }
        }

        public static bool ShowMouse
        {
            get
            {
                if (curInstance != null)
                    return curInstance.IsMouseVisible;
                else
                    return false;
            }
            set
            {
                if (curInstance != null)
                    curInstance.IsMouseVisible = value;
            }
        }

        public Rectangle ClientRec
        {
            get { return Window.ClientBounds; }
        }

        public int Width
        {
            get { return ClientRec.Width; }
        }

        public int Height
        {
            get { return ClientRec.Height; }
        }

        #endregion

        #region Constructor

        public BaseGame()
        {
            graphics = new GraphicsDeviceManager( this );
            //graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>( graphics_PreparingDeviceSettings );
            clientRec = Window.ClientBounds;
            curInstance = this;
            //graphics.ToggleFullScreen();
        }

        //void graphics_PreparingDeviceSettings( object sender, PreparingDeviceSettingsEventArgs e )
        //{
        //    e.GraphicsDeviceInformation.PresentationParameters.RenderTargetUsage = RenderTargetUsage.PlatformContents;
        //    e.GraphicsDeviceInformation.PresentationParameters.MultiSampleType = MultiSampleType.None;
        //    e.GraphicsDeviceInformation.PresentationParameters.MultiSampleQuality = 0;
        //}

        void HandleDeviceReset( object sender, EventArgs e )
        {
            //Sprite.HandleDeviceReset();
            //FontManager.HandleDeviceReset();
        }

        #endregion

        #region Initialize

        protected override void Initialize()
        {
            content = new ContentManager( Services );
            renderEngine = new RenderEngine( Device, content, "Content\\EngineContent" );
            RandomHelper.GenerateNewRandomGenerator();
            Log.Initialize();
            base.Initialize();
        }
        #endregion

        #region Update

        protected override void Update( GameTime gameTime )
        {
            curTime = gameTime;

            InputHandler.Update();
            if (showFps)
                CalulateFPS( gameTime );

            //waitUpdate = false;

            base.Update( gameTime );
        }

        private void CalulateFPS( GameTime gameTime )
        {
            Fps = (int)((double)1000 / gameTime.ElapsedRealTime.TotalMilliseconds);
        }

        #endregion

        #region Draw

        protected override sealed void Draw( GameTime gameTime )
        {
            try
            {
                Device.Clear( Color.Blue );

                //Quake.Update();

                renderEngine.BeginRender();

                GameDraw( gameTime );

                if (showFps)
                    FontMgr.DrawInScrnCoord( "FPS = " + Fps.ToString(), new Vector2( 30, 15 ), 0.5f, Color.White, 0f, GameFonts.Comic );

                //TextEffect.Draw();

                renderEngine.EndRender();
                base.Draw( gameTime );
            }
            catch (Exception ex)
            {
                Log.Write( ex.Message );
            }
        }

        protected virtual void GameDraw( GameTime gameTime )
        {

        }
        #endregion

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.PhiCol;
using SmartTank.Draw;
using TankEngine2D.DataStructure;
using SmartTank.Shelter;
using SmartTank.Screens;
using SmartTank.Update;
using SmartTank.Senses.Vision;
using SmartTank.Sounds;
using TankEngine2D.Graphics;
using SmartTank.Senses.Memory;
using SmartTank.Effects.SceneEffects;
using SmartTank.Scene;
using SmartTank.Effects.TextEffects;

namespace SmartTank
{
    /*
     * 使用堆栈结构储存游戏屏幕
     * 
     * 一切游戏屏幕（界面，游戏画面）都从IGameScreen继承。
     * 
     * */

    public class GameManager : BaseGame
    {
        #region Variables

        protected static Stack<IGameScreen> gameScreens = new Stack<IGameScreen>();

        protected static PhiColMgr phiColManager;

        protected static ShelterMgr shelterMgr;

        protected static DrawMgr drawManager;

        protected static UpdateMgr updateMgr;

        protected static VisionMgr visionMgr;

        protected static ObjMemoryMgr objMemoryMananger;


        protected static ISceneKeeper curSceneKeeper;


        #endregion

        #region Properties

        public static PhiColMgr PhiColManager
        {
            get { return phiColManager; }
        }

        public static ShelterMgr ShelterMgr
        {
            get { return shelterMgr; }
        }

        public static DrawMgr DrawManager
        {
            get { return drawManager; }
        }

        public static UpdateMgr UpdateMgr
        {
            get { return updateMgr; }
        }

        public static VisionMgr VisionMgr
        {
            get { return visionMgr; }
        }

        public static ObjMemoryMgr ObjMemoryMgr
        {
            get { return objMemoryMananger; }
        }

        public static ISceneKeeper CurSceneKeeper
        {
            get { return curSceneKeeper; }
        }

        #endregion

        #region Initialize



        protected override void Initialize ()
        {
            base.Initialize();

            phiColManager = new PhiColMgr();
            shelterMgr = new ShelterMgr();
            drawManager = new DrawMgr();
            updateMgr = new UpdateMgr();
            visionMgr = new VisionMgr();
            objMemoryMananger = new ObjMemoryMgr();

            Sound.Initial();

            // 在此处将主界面压入堆栈。


            // test

            gameScreens.Push( new RuleSelectScreen() );

            //

        }

        #endregion

        #region Update

        protected override void Update ( GameTime gameTime )
        {
            base.Update( gameTime );

            if (gameScreens.Count == 0)
            {
                Exit();
                return;
            }


            float elapsedSeconds = (float)gameTime.ElapsedGameTime.TotalSeconds;

            GameTimer.UpdateTimers( elapsedSeconds );

            if (gameScreens.Peek().Update( elapsedSeconds ))
            {
                gameScreens.Pop();
            }
        }

        #endregion

        #region Add GameScreen

        public static void AddGameScreen ( IGameScreen gameScreen )
        {
            if (gameScreen != null)
                gameScreens.Push( gameScreen );
        }

        #endregion

        #region Draw

        protected override void GameDraw ( GameTime gameTime )
        {
            if (gameScreens.Count != 0)
                gameScreens.Peek().Render();
        }

        #endregion

        #region LoadScene

        public static void LoadScene ( ISceneKeeper scene )
        {
            phiColManager.ClearGroups();
            ShelterMgr.ClearGroups();
            drawManager.ClearGroups();
            updateMgr.ClearGroups();
            visionMgr.ClearGroups();

            scene.RegistDrawables( drawManager );
            scene.RegistPhiCol( phiColManager );
            scene.RegistShelter( ShelterMgr );
            scene.RegistUpdaters( updateMgr );
            scene.RegistVision( visionMgr );

            curSceneKeeper = scene;
        }

        #endregion

        public static void UpdataComponent ( float seconds )
        {
            GameManager.UpdateMgr.Update( seconds );
            GameManager.PhiColManager.Update( seconds );
            GameManager.ShelterMgr.Update();
            GameManager.VisionMgr.Update();
            GameManager.objMemoryMananger.Update();
            EffectsMgr.Update( seconds );
        }

        public static void ComponentReset ()
        {
            EffectsMgr.Clear();
            Sound.Clear();
            GameTimer.ClearAllTimer();
            TextEffectMgr.Clear();
            GameManager.objMemoryMananger.ClearGroups();
            DrawMgr.SetCondition( null );
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace TankEngine2D.Graphics
{
    /// <summary>
    /// 定义可切帧对象
    /// </summary>
    public interface IAnimated
    {
        /// <summary>
        /// 获取是否已经开始显示
        /// </summary>
        bool IsStart { get;}

        /// <summary>
        /// 获取动画是否已经结束
        /// </summary>
        bool IsEnd { get;}

        /// <summary>
        /// 绘制当前帧，并准备下一帧
        /// </summary>
        void DrawCurFrame ();
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using System.IO;
using Common.Helpers;
using GameEngine.Draw;


namespace GameEngine.Effects.SceneEffects
{
    public class ShellExplode
    {
        ScaleUp scaleUp;

        public static void LoadResources ()
        {

        }

        public ShellExplode ( Vector2 pos, float rota )
        {
            scaleUp = new ScaleUp( Path.Combine( Directories.ContentDirectory, "SceneEffects\\star2" ), new Vector2( 64, 64 ), LayerDepth.EffectLow,
                pos,
                delegate( float curTime,float deltaTime, float lastRadius )
                {
                    if (curTime == 0)
                        return 3f;
                    else
                        return lastRadius + 0.3f;
                },
                delegate( float curTime )
                {
                    return 0;
                }, 20 );
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.GameObjs
{
    [AttributeUsage( AttributeTargets.Class, Inherited = false )]
    class GameObjAttribute : Attribute
    {
        string className;
        string classRemark;
        string programer;
        int year;
        int month;
        int day;

        public string ClassName
        {
            get { return className; }
        }
        public string ClassRemark
        {
            get { return classRemark; }
        }
        public string Programer
        {
            get { return programer; }
        }
        public int Year
        {
            get { return year; }
        }
        public int Month
        {
            get { return month; }
        }
        public int Day
        {
            get { return day; }
        }

        public GameObjAttribute ( string className, string classRemark, string programer, int year, int month, int day )
        {
            this.className = className;
            this.classRemark = classRemark;
            this.programer = programer;
            this.year = year;
            this.month = month;
            this.day = day;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Common.Helpers;
using Microsoft.Xna.Framework.Content;

namespace GameEngine.Effects
{
    /// <summary>
    /// 从一副包含多个子图的图片中建立动画
    /// </summary>
    public class AnimatedSpriteSingle : AnimatedSprite, IDisposable
    {
        /// <summary>
        ///  提前将贴图文件导入到Content当中，以避免读取造成游戏的停滞。
        /// </summary>
        /// <param name="contentMgr">资源管理者</param>
        /// <param name="assetName">资源的名称</param>
        public static void LoadResources( ContentManager contentMgr, string assetName )
        {
            try
            {
                contentMgr.Load<Texture2D>( assetName );
            }
            catch (Exception)
            {
                Log.Write( "导入动画资源错误，请检查图片资源路径: " + assetName );
                throw new Exception( "导入动画资源错误，请检查图片资源路径" );
            }
        }


        #region Fields

        RenderEngine engine;

        Texture2D tex;

        Rectangle[] sourceRectangles;

        bool alreadyLoad = false;

        /// <summary>
        /// 贴图的中心，以贴图坐标表示
        /// </summary>
        public Vector2 Origin;
        
        private  Vector2 pos;
        
        /// <summary>
        /// 逻辑位置
        /// </summary>
        public override Vector2 Pos
        {
            get { return pos; }
        }
        /// <summary>
        /// 逻辑宽度
        /// </summary>
        public float Width;
        /// <summary>
        /// 逻辑高度
        /// </summary>
        public float Height;
        /// <summary>
        /// 方位角
        /// </summary>
        public float Rata;
        /// <summary>
        /// 颜色
        /// </summary>
        public Color Color;
        /// <summary>
        /// 绘制深度
        /// </summary>
        public float LayerDepth;
        /// <summary>
        /// 混合模式
        /// </summary>
        public SpriteBlendMode BlendMode;

        Rectangle mDestiRect;

        int cellWidth;
        int cellHeight;

        #endregion

        /// <summary>
        /// 从一副包含多个子图的图片中建立动画
        /// </summary>
        /// <param name="engine">渲染组件</param>
        public AnimatedSpriteSingle( RenderEngine engine )
        {
            this.engine = engine;
        }

        /// <summary>
        /// 通过素材管道导入图片资源
        /// </summary>
        /// <param name="contentMgr">素材管理者</param>
        /// <param name="assetName">素材名称</param>
        /// <param name="cellWidth">一个子图的宽度</param>
        /// <param name="cellHeight">一个子图的高度</param>
        /// <param name="cellInterval">表示相邻帧之间子图的间隔，只使用能被cellInterval整除的索引的子图</param>
        public void LoadFromContent( ContentManager contentMgr, string assetName, int cellWidth, int cellHeight, int cellInterval )
        {
            if (alreadyLoad)
                throw new Exception( "重复导入动画资源。" );

            alreadyLoad = true;

            try
            {
                tex = contentMgr.Load<Texture2D>( assetName );
            }
            catch (Exception)
            {
                tex = null;
                alreadyLoad = false;

                throw new Exception( "导入动画资源错误，请检查图片资源路径" );
            }

            this.cellWidth = cellWidth;
            this.cellHeight = cellHeight;

            BuildSourceRect( cellInterval );
        }

        /// <summary>
        /// 从文件中导入贴图
        /// </summary>
        /// <param name="filePath">贴图文件路径</param>
        /// <param name="cellWidth">子图宽度</param>
        /// <param name="cellHeight">子图高度</param>
        /// <param name="cellInterval">表示相邻帧之间子图的间隔，只使用能被cellInterval整除的索引的子图</param>
        public void LoadFromFile( string filePath, int cellWidth, int cellHeight, int cellInterval )
        {
            if (alreadyLoad)
                throw new Exception( "重复导入动画资源。" );

            alreadyLoad = true;

            try
            {
                tex = Texture2D.FromFile( engine.Device, filePath );
            }
            catch (Exception)
            {
                tex = null;
                alreadyLoad = false;

                throw new Exception( "导入动画资源错误，请检查图片资源路径" );
            }
        }

        private void BuildSourceRect( int cellInterval )
        {
            int curX = 0;
            int curY = 0;



            List<Rectangle> result = new List<Rectangle>();

            int curCell = 0;

            while (curY + cellHeight <= tex.Height)
            {
                while (curX + cellWidth <= tex.Width)
                {
                    if (curCell % cellInterval == 0)
                        result.Add( new Rectangle( curX, curY, cellWidth, cellHeight ) );

                    curCell++;
                    curX += cellWidth;
                }

                curY += cellHeight;
                curX = 0;
            }

            sourceRectangles = result.ToArray();

            mSumFrame = result.Count;
        }

        /// <summary>
        /// 设置绘制参数
        /// </summary>
        /// <param name="origin">贴图的中心，以贴图坐标表示</param>
        /// <param name="pos">逻辑位置</param>
        /// <param name="width">逻辑宽度</param>
        /// <param name="height">逻辑高度</param>
        /// <param name="rata">方位角</param>
        /// <param name="color">绘制颜色</param>
        /// <param name="layerDepth">绘制深度</param>
        /// <param name="blendMode">混合模式</param>
        public void SetParameters( Vector2 origin, Vector2 pos, float width, float height, float rata, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            Origin = origin;
            this.pos = pos;
            Width = width;
            Height = height;
            Rata = rata;
            Color = color;
            LayerDepth = layerDepth;
            BlendMode = blendMode;
        }

        /// <summary>
        /// 设置绘制参数
        /// </summary>
        /// <param name="origin">贴图的中心，以贴图坐标表示</param>
        /// <param name="pos">逻辑位置</param>
        /// <param name="scale">逻辑大小/原图大小</param>
        /// <param name="rata">方位角</param>
        /// <param name="color">绘制颜色</param>
        /// <param name="layerDepth">绘制深度</param>
        /// <param name="blendMode">混合模式</param>
        public void SetParameters( Vector2 origin, Vector2 pos, float scale, float rata, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            SetParameters( origin, pos, (float)(cellWidth) * scale, (float)(cellHeight) * scale, rata, color, layerDepth, blendMode );
        }

        /// <summary>
        /// 绘制当前帧
        /// </summary>
        protected override void DrawCurFrame()
        {

            CalDestinRect();

            if (BlendMode == SpriteBlendMode.Additive)
            {
                engine.SpriteMgr.additiveSprite.Draw( tex, mDestiRect, sourceRectangles[mCurFrameIndex], Color, Rata, Origin, SpriteEffects.None, LayerDepth );
            }
            else if (BlendMode == SpriteBlendMode.AlphaBlend)
            {
                engine.SpriteMgr.alphaSprite.Draw( tex, mDestiRect, sourceRectangles[mCurFrameIndex], Color, Rata, Origin, SpriteEffects.None, LayerDepth );
            }
        }

        private void CalDestinRect()
        {
            Vector2 scrnPos = engine.CoordinMgr.ScreenPos( new Vector2( pos.X, pos.Y ) );
            mDestiRect.X = (int)scrnPos.X;
            mDestiRect.Y = (int)scrnPos.Y;
            mDestiRect.Width = engine.CoordinMgr.ScrnLength( Width );
            mDestiRect.Height = engine.CoordinMgr.ScrnLength( Height );
        }

        #region IDisposable 成员

        /// <summary>
        /// 释放图片资源
        /// </summary>
        public void Dispose()
        {
            tex.Dispose();
        }

        #endregion


    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace TankEngine2D.DataStructure
{
    /// <summary>
    /// 以浮点格式表示一个矩形
    /// </summary>
    [Serializable]
    public struct Rectanglef
    {
        /// <summary>
        /// 矩形的左上角坐标
        /// </summary>
        public float X, Y;

        /// <summary>
        /// 矩形的宽度和高度
        /// </summary>
        public float Width, Height;

        /// <summary>
        /// 获得矩形的上边沿的Y坐标
        /// </summary>
        public float Top
        {
            get { return Y; }
        }
        /// <summary>
        /// 获得矩形左边沿的X坐标
        /// </summary>
        public float Left
        {
            get { return X; }
        }
        /// <summary>
        /// 获得矩形下边沿的Y坐标
        /// </summary>
        public float Bottom
        {
            get { return Y + Height; }
        }
        /// <summary>
        /// 获得矩形右边沿的X坐标
        /// </summary>
        public float Right
        {
            get { return X + Width; }
        }
        /// <summary>
        /// 获得矩形的左上角顶点
        /// </summary>
        public Vector2 UpLeft
        {
            get { return new Vector2( X, Y ); }
        }
        /// <summary>
        /// 获得矩形的右上角顶点
        /// </summary>
        public Vector2 UpRight
        {
            get { return new Vector2( X + Width, Y ); }
        }
        /// <summary>
        /// 获得矩形的左下角顶点
        /// </summary>
        public Vector2 DownLeft
        {
            get { return new Vector2( X, Y + Height ); }
        }
        /// <summary>
        /// 获得矩形的右下角顶点
        /// </summary>
        public Vector2 DownRight
        {
            get { return new Vector2( X + Width, Y + Height ); }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="x">矩形左上角顶点的X坐标</param>
        /// <param name="y">矩形左上角顶点的Y坐标</param>
        /// <param name="width">矩形的宽度</param>
        /// <param name="height">矩形的高度</param>
        public Rectanglef ( float x, float y, float width, float height )
        {
            this.X = x;
            this.Y = y;
            this.Width = width;
            this.Height = height;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="min">矩形的左上角顶点</param>
        /// <param name="max">矩形的右下角顶点</param>
        public Rectanglef ( Vector2 min, Vector2 max )
        {
            this.X = min.X;
            this.Y = min.Y;
            this.Width = max.X - min.X;
            this.Height = max.Y - min.Y;
        }

        /// <summary>
        /// 判断两个矩形是否有重叠部分
        /// </summary>
        /// <param name="rectB"></param>
        /// <returns></returns>
        public bool Intersects ( Rectanglef rectB )
        {
            if (rectB.X < this.X + this.Width && rectB.X + rectB.Width > this.X &&
                rectB.Y + rectB.Height > this.Y && rectB.Y < this.Y + this.Height ||
                rectB.X + rectB.Width > this.X && rectB.X < this.X + this.Width &&
                rectB.Y + rectB.Height > this.Y && rectB.Y < this.Y + this.Height)
                return true;
            else
                return false;
        }

        /// <summary>
        /// 判断一个点是否在矩形之中
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public bool Contains ( Vector2 point )
        {
            if (X <= point.X && point.X <= X + Width && Y <= point.Y && point.Y <= Y + Height)
                return true;
            else
                return false;
        }
        /// <summary>
        /// 判断两个Rectanglef实例是否相等
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals ( object obj )
        {
            Rectanglef b = (Rectanglef)obj;
            return this.X == b.X && this.Y == b.Y && this.Width == b.Width && this.Height == b.Height;
        }
        /// <summary>
        /// 获得Hash码
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode ()
        {
            return X.GetHashCode();
        }
        /// <summary>
        /// 将信息转换为字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString ()
        {
            return X.ToString() + " " + Y.ToString() + " " + Width.ToString() + " " + Height.ToString();
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.PhiCol;
using SmartTank.Shelter;
using SmartTank.Draw;
using SmartTank.Update;
using SmartTank.Senses.Vision;

namespace SmartTank.Scene
{
    public interface ISceneKeeper
    {
        void RegistPhiCol ( PhiColMgr manager );

        void RegistShelter ( ShelterMgr manager );

        void RegistDrawables ( DrawMgr manager );

        void RegistUpdaters ( UpdateMgr manager );

        void RegistVision ( VisionMgr manager );
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.net
{
    enum PACKAGE_SYTLE
    {
        CHAT = 1,
        DATA = 100,
        EXIT = 21,
        LOGIN_SUCCESS = 11,
        LOGIN_FAIL = 12,
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.PhiCol;
using SmartTank.Shelter;
using SmartTank.Draw;
using SmartTank.Update;
using SmartTank.Senses.Vision;
using SmartTank.GameObjs;

namespace SmartTank.Scene
{
    public interface ISceneKeeper
    {
        void RegistPhiCol ( PhiColMgr manager );

        void RegistShelter ( ShelterMgr manager );

        void RegistDrawables ( DrawMgr manager );

        void RegistUpdaters ( UpdateMgr manager );

        void RegistVision ( VisionMgr manager );

        IGameObj GetGameObj(string objPath);

        bool AddGameObj(string groupPath, IGameObj obj);

        bool DelGameObj(string objPath);
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Senses.Vision;
using Microsoft.Xna.Framework;
using SmartTank.Shelter;

namespace SmartTank.AI
{
    public interface IAIOrderServerSinTur : IAIOrderServer
    {
        Vector2 TurretAxePos { get;}

        float TurretAzi { get;}

        float TurretAimAzi { get;}

        float MaxRotaTurretSpeed { get;}

        float TurnTurretWiseSpeed { get; set;}

        float TurretLength { get;}

        float FireLeftCDTime { get;}

        void Fire ();

        event BorderObjUpdatedEventHandler onBorderObjUpdated;
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Shelter;
using SmartTank.Update;
using SmartTank.PhiCol;
using Microsoft.Xna.Framework;

namespace SmartTank.Senses.Memory
{
    public class ObjMemoryMgr
    {
        #region Type Define
        struct Group
        {
            public IRaderOwner[] raderOwners;
            public ObjMemoryKeeper memory;

            public Group ( IRaderOwner[] raderOwners, ObjMemoryKeeper memory )
            {
                this.raderOwners = raderOwners;
                this.memory = memory;
            }
        }
        #endregion


        List<Group> groups = new List<Group>();

        public void AddGroup ( IRaderOwner[] raderOwners )
        {
            ObjMemoryKeeper memory = new ObjMemoryKeeper();
            groups.Add( new Group( raderOwners, memory ) );
            foreach (IRaderOwner raderOwner in raderOwners)
            {
                raderOwner.Rader.ObjMemoryKeeper = memory;
            }
        }

        public void AddSingle ( IRaderOwner raderOwner )
        {
            ObjMemoryKeeper memory = new ObjMemoryKeeper();
            groups.Add( new Group( new IRaderOwner[] { raderOwner }, memory ) );
            raderOwner.Rader.ObjMemoryKeeper = memory;
        }

        public void ClearGroups ()
        {
            groups.Clear();
        }

        public void Update ()
        {
            foreach (Group group in groups)
            {
                foreach (IRaderOwner raderOwner in group.raderOwners)
                {
                    EyeableBorderObjInfo[] curObjInfo = raderOwner.Rader.EyeableBorderObjInfos;

                    // 查找是否有消失的物体
                    List<IHasBorderObj> disappearedObjs = new List<IHasBorderObj>();
                    List<EyeableBorderObjInfo> disappearedObjInfos = new List<EyeableBorderObjInfo>();


                    foreach (KeyValuePair<IHasBorderObj, EyeableBorderObjInfo> pair in group.memory.MemoryObjs)
                    {
                        if (pair.Value.IsDisappeared)
                            continue;

                        // 是否回到了原来看到该物体的位置
                        bool back = false;
                        foreach (Vector2 keyPoint in pair.Value.EyeableInfo.CurKeyPoints)
                        {
                            if (raderOwner.Rader.PointInRader( keyPoint ))
                            {
                                back = true;
                                break;
                            }
                        }

                        if (back)
                        {
                            // 现在是否看到了该物体
                            bool find = false;
                            foreach (EyeableBorderObjInfo objInfo in curObjInfo)
                            {
                                if (objInfo.Obj == pair.Key)
                                {
                                    find = true;
                                    break;
                                }
                            }
                            if (!find)
                            {
                                disappearedObjs.Add( pair.Key );
                                disappearedObjInfos.Add( pair.Value );
                            }
                        }
                    }

                    group.memory.HandlerObjDisappear( disappearedObjs );

                    // 得到边界有更新的物体
                    List<EyeableBorderObjInfo> updatedObjInfo = new List<EyeableBorderObjInfo>();

                    // 更新物体信息
                    foreach (EyeableBorderObjInfo info in curObjInfo)
                    {
                        if (group.memory.ApplyEyeableBorderObjInfo( info ))
                        {
                            // 当物体边界有更新时添加到更新物体中
                            updatedObjInfo.Add( info );
                        }
                    }

                    // 发现物体消失时也判定物体有更新
                    foreach (EyeableBorderObjInfo info in disappearedObjInfos)
                    {
                        updatedObjInfo.Add( info );
                    }

                    // 通知物体获得了更新的消息
                    if (updatedObjInfo.Count != 0)
                    {
                        raderOwner.BorderObjUpdated( updatedObjInfo.ToArray() );
                    }
                }
            }
        }

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.IO;
using SmartTank.Rule;
using SmartTank.Screens;
using SmartTank.AI;
using SmartTank.GameObjs.Tank.SinTur;
using SmartTank.Effects.SceneEffects;
using SmartTank.GameObjs;
using SmartTank.Draw.UI.Controls;
using SmartTank.Helpers.DependInject;
using TankEngine2D.DataStructure;
using SmartTank.Scene;
using SmartTank.Draw;
using SmartTank.Draw.BackGround.VergeTile;
using SmartTank.GameObjs.Tank;
using TankEngine2D.Graphics;
using SmartTank;
using InterRules.ShootTheBall;
using TankEngine2D.Input;
using SmartTank.GameObjs.Shell;
using SmartTank.Helpers;
using TankEngine2D.Helpers;
using SmartTank.Senses.Vision;
using SmartTank.Update;
using SmartTank.Effects.TextEffects;
using SmartTank.Sounds;
using System.Windows.Forms;
using SmartTank.Effects;

namespace InterRules.Duel
{

    [RuleAttribute( "Duel", "两个坦克在空旷的场景中搏斗（平台的第二个规则）", "SmartTank编写组", 2007, 11, 2 )]
    public class DuelRule : IGameRule
    {
        #region Variables

        Combo AIListForTank1;
        Combo AIListForTank2;

        TextButton btn;

        int selectIndexTank1;
        int selectIndexTank2;

        AILoader aiLoader;

        #endregion

        #region IGameRule 成员

        public string RuleName
        {
            get { return "Duel"; }
        }

        public string RuleIntroduction
        {
            get { return "两个坦克在空旷的场景中搏斗（平台的第二个规则）"; }
        }

        #endregion

        public DuelRule()
        {
            BaseGame.ShowMouse = true;

            AIListForTank1 = new Combo( "AIListForTank1", new Vector2( 100, 100 ), 250 );
            AIListForTank2 = new Combo( "AIListForTank1", new Vector2( 100, 300 ), 250 );

            AIListForTank1.OnChangeSelection += new EventHandler( AIListForTank1_OnChangeSelection );
            AIListForTank2.OnChangeSelection += new EventHandler( AIListForTank2_OnChangeSelection );

            aiLoader = new AILoader();
            aiLoader.AddInterAI( typeof( DuelerNoFirst ) );
            aiLoader.AddInterAI( typeof( ManualControl ) );
            aiLoader.AddInterAI( typeof( DuelAIModel ) );
            aiLoader.AddInterAI( typeof( AutoShootAI ) );
            aiLoader.InitialCompatibleAIs( typeof( IDuelAIOrderServer ), typeof( AICommonServer ) );
            foreach (string name in aiLoader.GetAIList())
            {
                AIListForTank1.AddItem( name );
                AIListForTank2.AddItem( name );
            }
            btn = new TextButton( "OkBtn", new Vector2( 700, 500 ), "Begin", 0, Color.Yellow );
            btn.OnClick += new EventHandler( btn_OnPress );

            LoadResouce();
        }

        private void LoadResouce()
        {
            ShellExplode.LoadResources();
            Explode.LoadResources();
        }

        void btn_OnPress( object sender, EventArgs e )
        {
            GameManager.AddGameScreen( new DuelGameScreen( aiLoader.GetAIInstance( selectIndexTank1 ), aiLoader.GetAIInstance( selectIndexTank2 ) ) );
        }

        void AIListForTank1_OnChangeSelection( object sender, EventArgs e )
        {
            selectIndexTank1 = AIListForTank1.currentIndex;
        }

        void AIListForTank2_OnChangeSelection( object sender, EventArgs e )
        {
            selectIndexTank2 = AIListForTank2.currentIndex;
        }

        #region IGameScreen 成员

        public void Render()
        {
            BaseGame.Device.Clear( Color.LawnGreen );

            AIListForTank1.Draw( BaseGame.SpriteMgr.alphaSprite, 1 );
            AIListForTank2.Draw( BaseGame.SpriteMgr.alphaSprite, 1 );
            btn.Draw( BaseGame.SpriteMgr.alphaSprite, 1 );
        }

        public bool Update( float second )
        {


            AIListForTank1.Update();
            AIListForTank2.Update();
            btn.Update();

            if (InputHandler.JustPressKey( Microsoft.Xna.Framework.Input.Keys.Escape ))
                return true;

            return false;
        }

       
        public void OnClose()
        {
        }

        #endregion
    }

    class DuelGameScreen : IGameScreen
    {
        #region Constants
        readonly Rectangle scrnViewRect = new Rectangle( 30, 30, 740, 540 );
        readonly Rectanglef mapRect = new Rectanglef( 0, 0, 300, 220 );
        readonly float tankRaderLength = 90;
        readonly float tankMaxForwardSpd = 60;
        readonly float tankMaxBackwardSpd = 50;
        readonly float shellSpeed = 100;
        #endregion

        #region Variables

        SceneMgr sceneMgr;
        Camera camera;

        VergeTileGround vergeGround;

        DuelTank tank1;
        DuelTank tank2;

        AICommonServer commonServer;

        bool gameStart = false;
        bool gameOver = false;

        #endregion

        #region Construction

        public DuelGameScreen( IAI TankAI1, IAI TankAI2 )
        {
            BaseGame.CoordinMgr.SetScreenViewRect( scrnViewRect );

            camera = new Camera( 2.6f, new Vector2( 150, 112 ), 0 );
            camera.maxScale = 4.5f;
            camera.minScale = 2f;
            camera.Enable();

            InitialBackGround();

            sceneMgr = new SceneMgr();
            SceneInitial();
            GameManager.LoadScene( sceneMgr );

            RuleInitial();

            AIInitial( TankAI1, TankAI2 );

            InitialDrawMgr( TankAI1, TankAI2 );

            InitialStartTimer();
        }

        private void AIInitial( IAI tankAI1, IAI tankAI2 )
        {
            commonServer = new AICommonServer( mapRect );

            tankAI1.CommonServer = commonServer;
            tankAI1.OrderServer = tank1;
            tank1.SetTankAI( tankAI1 );

            tankAI2.CommonServer = commonServer;
            tankAI2.OrderServer = tank2;
            tank2.SetTankAI( tankAI2 );

            //GameManager.ObjMemoryMgr.AddSingle( tank1 );
            //GameManager.ObjMemoryMgr.AddSingle( tank2 );
        }

        private void InitialDrawMgr( IAI tankAI1, IAI tankAI2 )
        {
            if (tankAI1 is ManualControl)
            {
                DrawMgr.SetCondition(
                    delegate( IDrawableObj obj )
                    {
                        if (tank1.IsDead)
                            return true;

                        if (tank1.Rader.PointInRader( obj.Pos ) || obj == tank1 ||
                            ((obj is ShellNormal) && ((ShellNormal)obj).Firer == tank1))
                            return true;
                        else
                            return false;
                    } );
            }
            if (tankAI2 is ManualControl)
            {
                DrawMgr.SetCondition(
                    delegate( IDrawableObj obj )
                    {
                        if (tank2.IsDead)
                            return true;

                        if (tank2.Rader.PointInRader( obj.Pos ) || obj == tank2 ||
                            ((obj is ShellNormal) && ((ShellNormal)obj).Firer == tank2))
                            return true;
                        else
                            return false;
                    } );
            }
        }

        private void InitialBackGround()
        {
            VergeTileData data = new VergeTileData();
            data.gridWidth = 30;
            data.gridHeight = 22;
            data.SetRondomVertexIndex( 30, 22, 4 );
            data.SetRondomGridIndex( 30, 22 );
            data.texPaths = new string[]
            {
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_Dirt.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_DirtRough.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_DirtGrass.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_GrassDark.tga"),
            };
            vergeGround = new VergeTileGround( data, scrnViewRect, mapRect );
        }

        private void SceneInitial()
        {
            tank1 = new DuelTank( "tank1", TankSinTur.M60TexPath, TankSinTur.M60Data, new Vector2( mapRect.X + 150 + RandomHelper.GetRandomFloat( -40, 40 ),
                mapRect.Y + 60 + RandomHelper.GetRandomFloat( -10, 10 ) ),
                MathHelper.Pi + RandomHelper.GetRandomFloat( -MathHelper.PiOver4, MathHelper.PiOver4 ),
                "Tank1", tankRaderLength, tankMaxForwardSpd, tankMaxBackwardSpd, 10 );
            tank2 = new DuelTank( "tank2", TankSinTur.M1A2TexPath, TankSinTur.M1A2Data, new Vector2( mapRect.X + 150 + RandomHelper.GetRandomFloat( -40, 40 ),
                mapRect.Y + 160 + RandomHelper.GetRandomFloat( -10, 10 ) ),
                RandomHelper.GetRandomFloat( -MathHelper.PiOver4, MathHelper.PiOver4 ),
                "Tank2", tankRaderLength, tankMaxForwardSpd, tankMaxBackwardSpd, 10 );

            tank1.ShellSpeed = shellSpeed;
            tank2.ShellSpeed = shellSpeed;

            camera.Focus( tank1, true );

            sceneMgr.AddGroup( "", new TypeGroup<DuelTank>( "tank" ) );
            sceneMgr.AddGroup( "", new TypeGroup<SmartTank.PhiCol.Border>( "border" ) );
            sceneMgr.AddGroup( "", new TypeGroup<ShellNormal>( "shell" ) );
            sceneMgr.PhiGroups.Add( "tank" );
            sceneMgr.PhiGroups.Add( "shell" );
            sceneMgr.AddColMulGroups( "tank", "border", "shell" );
            sceneMgr.ShelterGroups.Add( new SceneMgr.MulPair( "tank", new List<string>() ) );
            sceneMgr.VisionGroups.Add( new SceneMgr.MulPair( "tank", new List<string>( new string[] { "tank" } ) ) );

            sceneMgr.AddGameObj( "tank", tank1 );
            sceneMgr.AddGameObj( "tank", tank2 );
            sceneMgr.AddGameObj( "border", new SmartTank.PhiCol.Border( mapRect ) );
        }

        private void InitialStartTimer()
        {
            new GameTimer( 1,
                delegate()
                {
                    TextEffectMgr.AddRiseFadeInScrnCoordin( "3", new Vector2( 400, 300 ), 3, Color.Red, LayerDepth.Text, GameFonts.Lucida, 200, 1.4f );
                } );

            new GameTimer( 2,
                delegate()
                {
                    TextEffectMgr.AddRiseFadeInScrnCoordin( "2", new Vector2( 400, 300 ), 3, Color.Red, LayerDepth.Text, GameFonts.Lucida, 200, 1.4f );
                } );

            new GameTimer( 3,
                delegate()
                {
                    TextEffectMgr.AddRiseFadeInScrnCoordin( "1", new Vector2( 400, 300 ), 3, Color.Red, LayerDepth.Text, GameFonts.Lucida, 200, 1.4f );
                } );

            new GameTimer( 4,
                delegate()
                {
                    TextEffectMgr.AddRiseFadeInScrnCoordin( "Start!", new Vector2( 400, 300 ), 3, Color.Red, LayerDepth.Text, GameFonts.Lucida, 200, 1.4f );

                } );
            new GameTimer( 5,
                delegate()
                {
                    gameStart = true;
                } );
        }

        private void RuleInitial()
        {
            tank1.onShoot += new Tank.ShootEventHandler( tank_onShoot );
            tank2.onShoot += new Tank.ShootEventHandler( tank_onShoot );

            tank1.onCollide += new OnCollidedEventHandler( tank_onCollide );
            tank2.onCollide += new OnCollidedEventHandler( tank_onCollide );
        }


        #endregion

        #region Rules

        int shellSum = 0;
        void tank_onShoot( Tank sender, Vector2 turretEnd, float azi )
        {
            ShellNormal shell = new ShellNormal( "shell" + shellSum.ToString(), sender, turretEnd, azi, shellSpeed );
            shell.onCollided += new OnCollidedEventHandler( shell_onCollided );
            shellSum++;
            sceneMgr.AddGameObj( "shell", shell );
            Sound.PlayCue( "CANNON1" );
        }

        void tank_onCollide( IGameObj Sender, CollisionResult result, GameObjInfo objB )
        {
            if (objB.ObjClass == "ShellNormal")
            {
                if (Sender == tank1)
                {
                    tank1.Live--;
                    // 在此添加效果
                    tank1.smoke.Concen += 0.2f;

                    if (tank1.Live <= 0 && !tank1.IsDead)
                    {
                        new Explode( tank1.Pos, 0 );

                        tank1.Dead();

                        new GameTimer( 3,
                            delegate()
                            {
                                MessageBox.Show( "Tank2胜利！" );
                                gameOver = true;
                            } );

                    }
                }
                else if (Sender == tank2)
                {
                    tank2.Live--;

                    tank2.smoke.Concen += 0.2f;
                    // 在此添加效果
                    if (tank2.Live <= 0 && !tank2.IsDead)
                    {
                        new Explode( tank2.Pos, 0 );

                        tank2.Dead();

                        new GameTimer( 3,
                            delegate()
                            {
                                MessageBox.Show( "Tank1胜利！" );
                                gameOver = true;
                            } );
                    }
                }
            }
        }

        void shell_onCollided( IGameObj Sender, CollisionResult result, GameObjInfo objB )
        {
            sceneMgr.DelGameObj( "shell", Sender.Name );
            new ShellExplodeBeta( Sender.Pos, ((ShellNormal)Sender).Azi );

            Quake.BeginQuake( 10, 50 );
            Sound.PlayCue( "EXPLO1" );

        }

        #endregion

        #region IGameScreen 成员

        public bool Update( float seconds )
        {
            if (InputHandler.JustPressKey( Microsoft.Xna.Framework.Input.Keys.Escape ))
            {
                GameManager.ComponentReset();
                return true;
            }

            if (!gameStart)
                return false;

            GameManager.UpdataComponent( seconds );

            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.Left ))
                camera.Move( new Vector2( -5, 0 ) );
            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.Right ))
                camera.Move( new Vector2( 5, 0 ) );
            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.Up ))
                camera.Move( new Vector2( 0, -5 ) );
            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.Down ))
                camera.Move( new Vector2( 0, 5 ) );
            if (InputHandler.JustPressKey( Microsoft.Xna.Framework.Input.Keys.V ))
                camera.Zoom( -0.2f );
            if (InputHandler.JustPressKey( Microsoft.Xna.Framework.Input.Keys.B ))
                camera.Zoom( 0.2f );
            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.T ))
                camera.Rota( 0.1f );
            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.R ))
                camera.Rota( -0.1f );

            camera.Update( seconds );

            if (gameOver)
            {
                GameManager.ComponentReset();
                return true;
            }

            return false;
        }

        public void Render()
        {
            vergeGround.Draw();

            GameManager.DrawManager.Draw();

            BaseGame.BasicGraphics.DrawRectangle( mapRect, 3, Color.Red, 0f );
            BaseGame.BasicGraphics.DrawRectangleInScrn( scrnViewRect, 3, Color.Green, 0f );

            //foreach (Vector2 visiPoint in tank1.KeyPoints)
            //{
            //    BasicGraphics.DrawPoint( Vector2.Transform( visiPoint, tank1.TransMatrix ), 0.4f, Color.Blue, 0f );
            //}

            //foreach (Vector2 visiPoint in tank2.KeyPoints)
            //{
            //    BasicGraphics.DrawPoint( Vector2.Transform( visiPoint, tank2.TransMatrix ), 0.4f, Color.Blue, 0f );
            //}

        }

        #endregion

        #region IGameScreen 成员

        public void OnClose()
        {
            
        }

        #endregion
    }

    #region class Define

    public interface IDuelAIOrderServer : IAIOrderServerSinTur
    {
        float Live { get;}
    }

    /// <summary>
    /// 写本规则的AI，请继承该接口。
    /// </summary>
    [IAIAttribute( typeof( IDuelAIOrderServer ), typeof( IAICommonServer ) )]
    public interface IDuelAI : IAISinTur
    {

    }


    class DuelTank : TankSinTur, IDuelAIOrderServer
    {
        float live;

        public SmokeGenerater smoke;

        public DuelTank( string name, string texPath, GameObjData skinData , Vector2 pos, float Azi , string tankName,
            float tankRaderLength, float tankMaxForwardSpd, float tankMaxBackwardSpd ,
            float live )
            : base( name, new GameObjInfo( "DuelTank", tankName ) , texPath , skinData ,
                tankRaderLength , MathHelper.Pi * 0.15f , Color.Yellow ,
                tankMaxForwardSpd , tankMaxBackwardSpd , MathHelper.PiOver4 , MathHelper.PiOver4 , MathHelper.Pi , 0.8f , pos , Azi )
        {
            this.live = live;
            smoke = new SmokeGenerater( 0, 30, Vector2.Zero, 0.3f, 0, false, this );

            this.GetEyeableInfoHandler = TankSinTur.GetCommonEyeInfoFun;
        }

        public override void Update( float seconds )
        {
            base.Update( seconds );
            smoke.Update( seconds );
        }

        public override void Draw()
        {
            base.Draw();
            smoke.Draw();
        }

        #region DuelAIOrderServer 成员

        public float Live
        {
            get { return live; }
            set { live = value; }
        }

        #endregion
    }

    #endregion
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.Update;
using TankEngine2D.Helpers;
using TankEngine2D.DataStructure;

namespace SmartTank.AI.AIHelper
{
    public class AIActionHelper : IUpdater
    {
        #region Type Def
        class EmptyActionOrder : IActionOrder
        {
            #region IActionOrder 成员

            public ActionRights NeedRights
            {
                get { return 0; }
            }

            public IAIOrderServer OrderServer
            {
                set { ; }
            }

            public bool IsEnd
            {
                get { return false; }
            }

            public void Stop ()
            {
            }

            #endregion

            #region IUpdater 成员

            public void Update ( float seconds )
            {

            }

            #endregion
        }
        #endregion

        #region Variables

        IAIOrderServer orderServer;

        IActionOrder RotaRightOwner = new EmptyActionOrder();
        IActionOrder RotaTurretRightOwner = new EmptyActionOrder();
        IActionOrder RotaRaderRightOwner = new EmptyActionOrder();
        IActionOrder MoveRightOwner = new EmptyActionOrder();

        List<IActionOrder> curOrder = new List<IActionOrder>();

        #endregion

        #region Construction

        public AIActionHelper ( IAIOrderServer orderServer )
        {
            this.orderServer = orderServer;
        }

        #endregion

        #region AddOrder

        public void AddOrder ( IActionOrder order )
        {
            ActionRights needRights = order.NeedRights;
            if ((needRights & ActionRights.Rota) == ActionRights.Rota)
            {
                RotaRightOwner.Stop();
                DeleteAllRightOfOrder( RotaRightOwner );
                RotaRightOwner = order;
            }
            if ((needRights & ActionRights.RotaTurret) == ActionRights.RotaTurret)
            {
                RotaTurretRightOwner.Stop();
                DeleteAllRightOfOrder( RotaTurretRightOwner );
                RotaTurretRightOwner = order;
            }
            if ((needRights & ActionRights.RotaRader) == ActionRights.RotaRader)
            {
                RotaRaderRightOwner.Stop();
                DeleteAllRightOfOrder( RotaRaderRightOwner );
                RotaRaderRightOwner = order;
            }
            if ((needRights & ActionRights.Move) == ActionRights.Move)
            {
                MoveRightOwner.Stop();
                DeleteAllRightOfOrder( MoveRightOwner );
                MoveRightOwner = order;
            }

            order.OrderServer = orderServer;
            curOrder.Add( order );
        }

        private void DeleteAllRightOfOrder ( IActionOrder order )
        {
            if (RotaRightOwner == order)
            {
                RotaRightOwner = new EmptyActionOrder();
                orderServer.TurnRightSpeed = 0;
            }
            if (RotaTurretRightOwner == order)
            {
                RotaTurretRightOwner = new EmptyActionOrder();
                ((IAIOrderServerSinTur)orderServer).TurnTurretWiseSpeed = 0;
            }
            if (RotaRaderRightOwner == order)
            {
                RotaRaderRightOwner = new EmptyActionOrder();
                orderServer.TurnRaderWiseSpeed = 0;
            }
            if (MoveRightOwner == order)
            {
                MoveRightOwner = new EmptyActionOrder();
                orderServer.ForwardSpeed = 0;
            }

            curOrder.Remove( order );
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            List<IActionOrder> deleteOrder = new List<IActionOrder>();
            for (int i = 0; i < curOrder.Count; i++)
            {
                curOrder[i].Update( seconds );
                if (curOrder[i].IsEnd)
                    deleteOrder.Add( curOrder[i] );
            }
            foreach (IActionOrder order in deleteOrder)
            {
                DeleteAllRightOfOrder( order );
            }
        }

        #endregion

        #region StopOrder

        public void StopRota ()
        {
            RotaRightOwner.Stop();
            //orderServer.TurnRightSpeed = 0;
            DeleteAllRightOfOrder( RotaRightOwner );
        }

        public void StopRotaTurret ()
        {
            RotaTurretRightOwner.Stop();
            //orderServer.TurnTurretWiseSpeed = 0;
            DeleteAllRightOfOrder( RotaTurretRightOwner );
        }

        public void StopRotaRader ()
        {
            RotaRaderRightOwner.Stop();
            //orderServer.TurnRaderWiseSpeed = 0;
            DeleteAllRightOfOrder( RotaRaderRightOwner );
        }

        public void StopMove ()
        {
            MoveRightOwner.Stop();
            //orderServer.ForwardSpeed = 0;
            DeleteAllRightOfOrder( MoveRightOwner );
        }

        #endregion
    }

    [Flags]
    public enum ActionRights
    {
        Rota = 0x01,
        RotaTurret = 0x02,
        RotaRader = 0x04,
        Move = 0x08,
    }

    public delegate void ActionFinishHandler ( IActionOrder order );

    public interface IActionOrder : IUpdater
    {
        ActionRights NeedRights { get;}
        IAIOrderServer OrderServer { set;}
        bool IsEnd { get;}
        void Stop ();
    }

    #region OrderRotaToAzi
    /// <summary>
    /// 使坦克转向目标方向
    /// </summary>
    public class OrderRotaToAzi : IActionOrder
    {
        float aimAzi;
        bool wiseClock;
        float angSpeed = 0;
        bool isEnd = false;
        ActionFinishHandler finishHandler;
        bool stopCallFinish = false;

        IAIOrderServer orderServer;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimAzi">目标方位角</param>
        public OrderRotaToAzi ( float aimAzi )
        {
            this.aimAzi = aimAzi;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimAzi">目标方位角</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        public OrderRotaToAzi ( float aimAzi, float angSpeed )
        {
            this.aimAzi = aimAzi;
            this.angSpeed = Math.Abs( angSpeed );
        }

        /// <summary>
        /// 允许指定结束后调用处理函数的构造函数。
        /// </summary>
        /// <param name="aimAzi">目标方位角</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        /// <param name="finishHandler">命令结束后的处理函数</param>
        /// <param name="stopCallFinish">指定当命令被终止时是否调用结束处理函数</param>
        public OrderRotaToAzi ( float aimAzi, float angSpeed, ActionFinishHandler finishHandler, bool stopCallFinish )
        {
            this.aimAzi = aimAzi;
            this.angSpeed = Math.Abs( angSpeed );
            this.finishHandler = finishHandler;
            this.stopCallFinish = stopCallFinish;
        }

        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.Rota; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                this.orderServer = value;
                if (MathTools.FloatEqualZero( angSpeed, 0.001f ))
                    angSpeed = orderServer.MaxRotaSpeed;
                else
                    angSpeed = Math.Min( orderServer.MaxRotaSpeed, angSpeed );

                float DeltaAng = MathTools.AngTransInPI( aimAzi - orderServer.Azi );
                if (DeltaAng > 0)
                    wiseClock = true;
                else
                    wiseClock = false;
                orderServer.TurnRightSpeed = angSpeed * Math.Sign( DeltaAng );
            }
        }

        public bool IsEnd
        {
            get { return isEnd; }
        }

        public void Stop ()
        {
            if (stopCallFinish && finishHandler != null)
            {
                finishHandler( this );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            float DeltaAng = MathTools.AngTransInPI( aimAzi - orderServer.Azi );
            if (wiseClock ? DeltaAng > 0 : DeltaAng < 0)
            {

                if (Math.Abs( DeltaAng ) < angSpeed * seconds)
                {
                    orderServer.TurnRightSpeed = 0.5f * angSpeed * (wiseClock ? 1 : -1);
                }

            }
            else
            {
                isEnd = true;
                if (finishHandler != null)
                {
                    finishHandler( this );
                }
            }
        }

        #endregion
    }
    #endregion

    #region OrderRotaTurretToAzi
    /// <summary>
    /// 使炮塔指向目标方位。需要IAIOrderServerSinTur
    /// </summary>
    public class OrderRotaTurretToAzi : IActionOrder
    {
        float aimAzi;
        bool wiseClock;
        float angSpeed = 0;
        bool isEnd = false;
        ActionFinishHandler finishHandler;
        bool stopCallFinish = false;

        IAIOrderServerSinTur orderServer;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimAzi">目标方位角</param>
        public OrderRotaTurretToAzi ( float aimAzi )
        {
            this.aimAzi = aimAzi;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimAzi">目标方位角</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        public OrderRotaTurretToAzi ( float aimAzi, float angSpeed )
        {
            this.aimAzi = aimAzi;
            this.angSpeed = Math.Abs( angSpeed );
        }

        /// <summary>
        /// 允许指定结束后调用处理函数的构造函数。
        /// </summary>
        /// <param name="aimAzi">目标方位角</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        /// <param name="finishHandler">命令结束后的处理函数</param>
        /// <param name="stopCallFinish">指定当命令被终止时是否调用结束处理函数</param>
        public OrderRotaTurretToAzi ( float aimAzi, float angSpeed, ActionFinishHandler finishHandler, bool stopCallFinish )
        {
            this.aimAzi = aimAzi;
            this.angSpeed = Math.Abs( angSpeed );
            this.finishHandler = finishHandler;
            this.stopCallFinish = stopCallFinish;
        }

        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.RotaTurret; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                this.orderServer = (IAIOrderServerSinTur)value;
                if (MathTools.FloatEqualZero( angSpeed, 0.001f ))
                    angSpeed = orderServer.MaxRotaTurretSpeed;
                else
                    angSpeed = Math.Min( orderServer.MaxRotaTurretSpeed, angSpeed );

                float DeltaAng = MathTools.AngTransInPI( aimAzi - orderServer.TurretAimAzi );
                if (DeltaAng > 0)
                    wiseClock = true;
                else
                    wiseClock = false;
                orderServer.TurnTurretWiseSpeed = angSpeed * Math.Sign( DeltaAng );
            }
        }

        public bool IsEnd
        {
            get { return isEnd; }
        }

        public void Stop ()
        {
            if (stopCallFinish && finishHandler != null)
            {
                finishHandler( this );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            float DeltaAng = MathTools.AngTransInPI( aimAzi - orderServer.TurretAimAzi );
            if (wiseClock ? DeltaAng > 0 : DeltaAng < 0)
            {

                if (Math.Abs( DeltaAng ) < angSpeed * seconds)
                {
                    orderServer.TurnTurretWiseSpeed = 0.5f * angSpeed * (wiseClock ? 1 : -1);
                }

            }
            else
            {
                isEnd = true;
                if (finishHandler != null)
                {
                    finishHandler( this );
                }
            }
        }

        #endregion
    }
    #endregion

    #region OrderRotaTurretToPos
    /// <summary>
    /// 转动炮塔，使指向目标位置。需要IAIOrderServerSinTur
    /// </summary>
    public class OrderRotaTurretToPos : IActionOrder
    {
        Vector2 aimPos;
        bool wiseClock;
        float angSpeed = 0;
        bool isEnd = false;
        ActionFinishHandler finishHandler;
        bool stopCallFinish = false;

        IAIOrderServerSinTur orderServer;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimPos">目标位置</param>
        public OrderRotaTurretToPos ( Vector2 aimPos )
        {
            this.aimPos = aimPos;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimAzi">目标位置</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        public OrderRotaTurretToPos ( Vector2 aimPos, float angSpeed )
        {
            this.aimPos = aimPos;
            this.angSpeed = Math.Abs( angSpeed );
        }

        /// <summary>
        /// 允许指定结束后调用处理函数的构造函数。
        /// </summary>
        /// <param name="aimAzi">目标位置</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        /// <param name="finishHandler">命令结束后的处理函数</param>
        /// <param name="stopCallFinish">指定当命令被终止时是否调用结束处理函数</param>
        public OrderRotaTurretToPos ( Vector2 aimPos, float angSpeed, ActionFinishHandler finishHandler, bool stopCallFinish )
        {
            this.aimPos = aimPos;
            this.angSpeed = Math.Abs( angSpeed );
            this.finishHandler = finishHandler;
            this.stopCallFinish = stopCallFinish;
        }

        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.RotaTurret; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                this.orderServer = (IAIOrderServerSinTur)value;
                if (MathTools.FloatEqualZero( angSpeed, 0.001f ))
                    angSpeed = orderServer.MaxRotaTurretSpeed;
                else
                    angSpeed = Math.Min( orderServer.MaxRotaTurretSpeed, angSpeed );

                float aimAzi = MathTools.AziFromRefPos( aimPos - orderServer.TurretAxePos );
                float DeltaAng = MathTools.AngTransInPI( aimAzi - orderServer.TurretAimAzi );
                if (DeltaAng > 0)
                    wiseClock = true;
                else
                    wiseClock = false;
                orderServer.TurnTurretWiseSpeed = angSpeed * Math.Sign( DeltaAng );
            }
        }

        public bool IsEnd
        {
            get { return isEnd; }
        }

        public void Stop ()
        {
            if (stopCallFinish && finishHandler != null)
            {
                finishHandler( this );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            float aimAzi = MathTools.AziFromRefPos( aimPos - orderServer.TurretAxePos );
            float DeltaAng = MathTools.AngTransInPI( aimAzi - orderServer.TurretAimAzi );
            if (wiseClock ? DeltaAng > 0 : DeltaAng < 0)
            {

                if (Math.Abs( DeltaAng ) < angSpeed * seconds)
                {
                    orderServer.TurnTurretWiseSpeed = 0.5f * angSpeed * (wiseClock ? 1 : -1);
                }

            }
            else
            {
                isEnd = true;
                if (finishHandler != null)
                {
                    finishHandler( this );
                }
            }
        }

        #endregion
    }
    #endregion

    #region OrderRotaRaderToAng
    /// <summary>
    /// 转动雷达，使其指向相对车身的角度
    /// </summary>
    public class OrderRotaRaderToAng : IActionOrder
    {
        float aimAng;
        bool wiseClock;
        float angSpeed = 0;
        bool isEnd = false;
        ActionFinishHandler finishHandler;
        bool stopCallFinish = false;

        IAIOrderServer orderServer;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimAzi">目标角</param>
        public OrderRotaRaderToAng ( float aimAng )
        {
            this.aimAng = aimAng;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimAzi">目标角</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        public OrderRotaRaderToAng ( float aimAng, float angSpeed )
        {
            this.aimAng = aimAng;
            this.angSpeed = Math.Abs( angSpeed );
        }

        /// <summary>
        /// 允许指定结束后调用处理函数的构造函数。
        /// </summary>
        /// <param name="aimAzi">目标角</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        /// <param name="finishHandler">命令结束后的处理函数</param>
        /// <param name="stopCallFinish">指定当命令被终止时是否调用结束处理函数</param>
        public OrderRotaRaderToAng ( float aimAng, float angSpeed, ActionFinishHandler finishHandler, bool stopCallFinish )
        {
            this.aimAng = aimAng;
            this.angSpeed = Math.Abs( angSpeed );
            this.finishHandler = finishHandler;
            this.stopCallFinish = stopCallFinish;
        }

        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.RotaRader; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                this.orderServer = value;
                if (MathTools.FloatEqualZero( angSpeed, 0.001f ))
                    angSpeed = orderServer.MaxRotaRaderSpeed;
                else
                    angSpeed = Math.Min( orderServer.MaxRotaRaderSpeed, angSpeed );

                float DeltaAng = MathTools.AngTransInPI( aimAng - orderServer.RaderAzi );
                if (DeltaAng > 0)
                    wiseClock = true;
                else
                    wiseClock = false;
                orderServer.TurnRaderWiseSpeed = angSpeed * Math.Sign( DeltaAng );
            }
        }

        public bool IsEnd
        {
            get { return isEnd; }
        }

        public void Stop ()
        {
            if (stopCallFinish && finishHandler != null)
            {
                finishHandler( this );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            float DeltaAng = MathTools.AngTransInPI( aimAng - orderServer.RaderAzi );
            if (wiseClock ? DeltaAng > 0 : DeltaAng < 0)
            {

                if (Math.Abs( DeltaAng ) < angSpeed * seconds)
                {
                    orderServer.TurnRaderWiseSpeed = 0.5f * angSpeed * (wiseClock ? 1 : -1);
                }

            }
            else
            {
                isEnd = true;
                if (finishHandler != null)
                {
                    finishHandler( this );
                }
            }
        }

        #endregion
    }
    #endregion

    #region OrderRotaRaderToAzi
    /// <summary>
    /// 转动雷达到指定方位
    /// </summary>
    public class OrderRotaRaderToAzi : IActionOrder
    {
        float aimAzi;
        bool wiseClock;
        float angSpeed = 0;
        bool isEnd = false;
        ActionFinishHandler finishHandler;
        bool stopCallFinish = false;

        IAIOrderServer orderServer;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimAzi">目标方位角</param>
        public OrderRotaRaderToAzi ( float aimAzi )
        {
            this.aimAzi = aimAzi;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimAzi">目标方位角</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        public OrderRotaRaderToAzi ( float aimAzi, float angSpeed )
        {
            this.aimAzi = aimAzi;
            this.angSpeed = Math.Abs( angSpeed );
        }

        /// <summary>
        /// 允许指定结束后调用处理函数的构造函数。
        /// </summary>
        /// <param name="aimAzi">目标方位角</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        /// <param name="finishHandler">命令结束后的处理函数</param>
        /// <param name="stopCallFinish">指定当命令被终止时是否调用结束处理函数</param>
        public OrderRotaRaderToAzi ( float aimAzi, float angSpeed, ActionFinishHandler finishHandler, bool stopCallFinish )
        {
            this.aimAzi = aimAzi;
            this.angSpeed = Math.Abs( angSpeed );
            this.finishHandler = finishHandler;
            this.stopCallFinish = stopCallFinish;
        }

        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.RotaRader; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                this.orderServer = value;
                if (MathTools.FloatEqualZero( angSpeed, 0.001f ))
                    angSpeed = orderServer.MaxRotaRaderSpeed;
                else
                    angSpeed = Math.Min( orderServer.MaxRotaRaderSpeed, angSpeed );

                float DeltaAng = MathTools.AngTransInPI( aimAzi - orderServer.RaderAimAzi );
                if (DeltaAng > 0)
                    wiseClock = true;
                else
                    wiseClock = false;
                orderServer.TurnRaderWiseSpeed = angSpeed * Math.Sign( DeltaAng );
            }
        }

        public bool IsEnd
        {
            get { return isEnd; }
        }

        public void Stop ()
        {
            if (stopCallFinish && finishHandler != null)
            {
                finishHandler( this );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            float DeltaAng = MathTools.AngTransInPI( aimAzi - orderServer.RaderAimAzi );
            if (wiseClock ? DeltaAng > 0 : DeltaAng < 0)
            {

                if (Math.Abs( DeltaAng ) < angSpeed * seconds)
                {
                    orderServer.TurnRaderWiseSpeed = 0.5f * angSpeed * (wiseClock ? 1 : -1);
                }

            }
            else
            {
                isEnd = true;
                if (finishHandler != null)
                {
                    finishHandler( this );
                }
            }
        }

        #endregion
    }
    #endregion

    #region OrderRotaRaderToPos
    /// <summary>
    /// 转动雷达，使指向目标位置
    /// </summary>
    public class OrderRotaRaderToPos : IActionOrder
    {
        Vector2 aimPos;
        bool wiseClock;
        float angSpeed = 0;
        bool isEnd = false;
        ActionFinishHandler finishHandler;
        bool stopCallFinish = false;

        IAIOrderServer orderServer;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimAzi">目标位置</param>
        public OrderRotaRaderToPos ( Vector2 aimPos )
        {
            this.aimPos = aimPos;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aimAzi">目标位置</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        public OrderRotaRaderToPos ( Vector2 aimPos, float angSpeed )
        {
            this.aimPos = aimPos;
            this.angSpeed = Math.Abs( angSpeed );
        }

        /// <summary>
        /// 允许指定结束后调用处理函数的构造函数。
        /// </summary>
        /// <param name="aimAzi">目标位置</param>
        /// <param name="angSpeed">转向速度。如果是0，则使用最大旋转角速度</param>
        /// <param name="finishHandler">命令结束后的处理函数</param>
        /// <param name="stopCallFinish">指定当命令被终止时是否调用结束处理函数</param>
        public OrderRotaRaderToPos ( Vector2 aimPos, float angSpeed, ActionFinishHandler finishHandler, bool stopCallFinish )
        {
            this.aimPos = aimPos;
            this.angSpeed = Math.Abs( angSpeed );
            this.finishHandler = finishHandler;
            this.stopCallFinish = stopCallFinish;
        }

        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.RotaRader; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                this.orderServer = value;
                if (MathTools.FloatEqualZero( angSpeed, 0.001f ))
                    angSpeed = orderServer.MaxRotaRaderSpeed;
                else
                    angSpeed = Math.Min( orderServer.MaxRotaRaderSpeed, angSpeed );

                float aimAzi = MathTools.AziFromRefPos( aimPos - orderServer.Pos );
                float DeltaAng = MathTools.AngTransInPI( aimAzi - orderServer.RaderAimAzi );
                if (DeltaAng > 0)
                    wiseClock = true;
                else
                    wiseClock = false;
                orderServer.TurnRaderWiseSpeed = angSpeed * Math.Sign( DeltaAng );
            }
        }

        public bool IsEnd
        {
            get { return isEnd; }
        }

        public void Stop ()
        {
            if (stopCallFinish && finishHandler != null)
            {
                finishHandler( this );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            float aimAzi = MathTools.AziFromRefPos( aimPos - orderServer.Pos );
            float DeltaAng = MathTools.AngTransInPI( aimAzi - orderServer.RaderAimAzi );
            if (wiseClock ? DeltaAng > 0 : DeltaAng < 0)
            {

                if (Math.Abs( DeltaAng ) < angSpeed * seconds)
                {
                    orderServer.TurnRaderWiseSpeed = 0.5f * angSpeed * (wiseClock ? 1 : -1);
                }

            }
            else
            {
                isEnd = true;
                if (finishHandler != null)
                {
                    finishHandler( this );
                }
            }
        }

        #endregion
    }
    #endregion

    #region OrderMove
    /// <summary>
    /// 前进或后退
    /// </summary>
    public class OrderMove : IActionOrder
    {
        float length;
        float movedLength = 0;
        float speed = 0;
        bool isEnd = false;
        ActionFinishHandler finishHandler;
        bool stopCallFinish = false;

        IAIOrderServer orderServer;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="length">距离。大于0表示前进，小于0表示后退</param>
        public OrderMove ( float length )
        {
            this.length = length;
        }

        /// <summary>
        /// 允许设置移动速度
        /// </summary>
        /// <param name="length">距离。大于0表示前进，小于0表示后退</param>
        /// <param name="speed">移动速度。无论前进或后退都输入正数。输入零表示最大速度</param>
        public OrderMove ( float length, float speed )
        {
            this.length = length;
            this.speed = speed;
        }

        /// <summary>
        /// 允许指定结束后调用处理函数的构造函数。
        /// </summary>
        /// <param name="length">距离。大于0表示前进，小于0表示后退</param>
        /// <param name="speed">移动速度。无论前进或后退都输入正数。输入零表示最大速度</param>
        /// <param name="finishHandler">命令结束后的处理函数</param>
        /// <param name="stopCallFinish">指定当命令被终止时是否调用结束处理函数</param>
        public OrderMove ( float length, float speed, ActionFinishHandler finishHandler, bool stopCallFinish )
        {
            this.length = length;
            this.speed = Math.Abs( speed );
            this.finishHandler = finishHandler;
            this.stopCallFinish = stopCallFinish;
        }

        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.Move; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = value;

                if (length > 0)
                {
                    if (speed == 0)
                    {
                        speed = orderServer.MaxForwardSpeed;
                    }

                    speed = Math.Min( orderServer.MaxForwardSpeed, speed );
                    orderServer.ForwardSpeed = speed;
                }
                else
                {
                    if (speed == 0)
                    {
                        speed = orderServer.MaxBackwardSpeed;
                    }
                    speed = Math.Min( orderServer.MaxBackwardSpeed, speed );
                    orderServer.ForwardSpeed = -speed;
                }
            }
        }

        public bool IsEnd
        {
            get { return isEnd; }
        }

        public void Stop ()
        {
            if (stopCallFinish && finishHandler != null)
            {
                finishHandler( this );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            if (movedLength < Math.Abs( length ))
            {
                if (Math.Abs( length ) - movedLength < speed * seconds)
                {
                    orderServer.ForwardSpeed = speed * 0.5f;
                    movedLength += speed * 0.5f * seconds;
                }
                else
                    movedLength += speed * seconds;
            }
            else
            {
                isEnd = true;
                if (finishHandler != null)
                {
                    finishHandler( this );
                }
            }
        }

        #endregion
    }
    #endregion

    #region OrderMoveToPosDirect
    /// <summary>
    /// 走直线到指定地点
    /// </summary>
    public class OrderMoveToPosDirect : IActionOrder
    {
        IAIOrderServer orderServer;

        Vector2 aimPos;

        float rotaVel;
        float forwardVel;

        bool isEnd = false;
        IActionOrder curOrder;

        ActionFinishHandler finishHandler;
        bool stopCallFinish = false;

        public OrderMoveToPosDirect ( Vector2 aimPos )
        {
            this.aimPos = aimPos;
        }

        public OrderMoveToPosDirect ( Vector2 aimPos, float rotaVel, float forwardVel )
        {
            this.aimPos = aimPos;
            this.rotaVel = rotaVel;
            this.forwardVel = forwardVel;
        }

        public OrderMoveToPosDirect ( Vector2 aimPos, float rotaVel, float forwardVel, ActionFinishHandler finishHandler, bool stopCallFinish )
        {
            this.aimPos = aimPos;
            this.rotaVel = rotaVel;
            this.forwardVel = forwardVel;
            this.finishHandler = finishHandler;
            this.stopCallFinish = stopCallFinish;
        }

        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.Move | ActionRights.Rota; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = value;
                if (rotaVel == 0)
                    rotaVel = orderServer.MaxRotaSpeed;
                else rotaVel = Math.Min( orderServer.MaxRotaSpeed, Math.Abs( rotaVel ) );
                curOrder = new OrderRotaToAzi( MathTools.AziFromRefPos( aimPos - orderServer.Pos ), rotaVel );
                curOrder.OrderServer = orderServer;

                if (forwardVel == 0)
                    forwardVel = orderServer.MaxForwardSpeed;
                else
                    forwardVel = Math.Min( orderServer.MaxForwardSpeed, Math.Abs( forwardVel ) );
            }
        }

        public bool IsEnd
        {
            get { return isEnd; }
        }

        public void Stop ()
        {
            if (stopCallFinish && finishHandler != null)
            {
                finishHandler( this );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            if (curOrder.IsEnd)
            {
                if (curOrder is OrderRotaToAzi)
                {
                    orderServer.TurnRightSpeed = 0;
                    curOrder = new OrderMove( Vector2.Distance( aimPos, orderServer.Pos ), forwardVel );
                    curOrder.OrderServer = orderServer;
                }
                else
                {
                    isEnd = true;
                    if (finishHandler != null)
                    {
                        finishHandler( this );
                    }
                }
            }
            curOrder.Update( seconds );
        }

        #endregion
    }
    #endregion

    #region OrderMoveToPosSmooth
    /// <summary>
    /// 光滑地移动到目标点。
    /// 与OrderMoveToPosDirect命令的不同之处在于，当目标方向与当前方向的夹角在某个阀值之内时，将在转弯的同时向前移动。
    /// 这使该命令能够适用于可能会不间歇地调用的场合。
    /// </summary>
    public class OrderMoveToPosSmooth : IActionOrder
    {
        const float fixFactor = 0.9f;

        IAIOrderServer orderServer;

        bool isEnd = false;

        ActionFinishHandler finishHandler;
        bool stopCallFinish = false;

        Vector2 aimPos;
        float smoothAng = MathHelper.PiOver2;

        float vel;
        float rotaVel;

        bool turnWise;

        bool rotaWForward = false;

        /// <summary>
        /// 移动到目标点。
        /// 与OrderMoveToPosDirect命令的不同之处在于，当目标方向与当前方向的夹角在某个阀值之内时，将在转弯的同时向前移动。
        /// </summary>
        /// <param name="aimPos">目标点</param>
        /// <param name="smoothAng">允许在转弯的同时向前移动的最大角度</param>
        /// <param name="vel">向前移动的速度。如果为0，将取最大速度</param>
        /// <param name="rotaVel">旋转的速度。如果为0，将取最大速度</param>
        /// <param name="finishHandler">命令结束后的处理函数</param>
        /// <param name="stopCallFinish">指定当命令被终止时是否调用结束处理函数</param>
        public OrderMoveToPosSmooth ( Vector2 aimPos, float smoothAng, float vel, float rotaVel, ActionFinishHandler finishHandler, bool stopCallFinish )
        {
            this.aimPos = aimPos;
            this.finishHandler = finishHandler;
            this.stopCallFinish = stopCallFinish;
            this.vel = Math.Abs( vel );
            this.rotaVel = Math.Abs( rotaVel );
            this.smoothAng = smoothAng;
        }


        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.Rota | ActionRights.Move; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                this.orderServer = value;

                if (vel == 0)
                    vel = orderServer.MaxForwardSpeed;
                if (rotaVel == 0)
                    rotaVel = orderServer.MaxRotaSpeed;

                Vector2 curPos = orderServer.Pos;
                Vector2 refPos = aimPos - curPos;
                float aimAzi = MathTools.AziFromRefPos( refPos );
                float curAzi = orderServer.Azi;
                float deltaAzi = MathTools.AngTransInPI( aimAzi - curAzi );
                if (deltaAzi > 0)
                    turnWise = true;
                else
                    turnWise = false;

                orderServer.TurnRightSpeed = Math.Sign( deltaAzi ) * rotaVel;

                if (Math.Abs( deltaAzi ) < smoothAng)
                {
                    Line refLine = new Line( curPos, orderServer.Direction );
                    Line vertice = MathTools.VerticeLine( refLine, curPos );
                    Line midVert = MathTools.MidVerLine( curPos, aimPos );
                    Vector2 interPoint;

                    bool canFor = false;
                    if (MathTools.InterPoint( vertice, midVert, out interPoint ))
                    {
                        float radius = Vector2.Distance( interPoint, curPos );

                        if (radius * fixFactor > vel / rotaVel)
                            canFor = true;
                    }
                    else
                    {
                        canFor = true;
                    }

                    if (canFor)
                    {
                        rotaWForward = true;
                        orderServer.ForwardSpeed = vel;
                    }
                }
            }
        }

        public bool IsEnd
        {
            get { return isEnd; }
        }

        public void Stop ()
        {
            if (stopCallFinish && finishHandler != null)
            {
                finishHandler( this );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            Vector2 curPos = orderServer.Pos;
            Vector2 refPos = aimPos - curPos;
            float aimAzi = MathTools.AziFromRefPos( refPos );
            float curAzi = orderServer.Azi;
            float deltaAzi = MathTools.AngTransInPI( aimAzi - curAzi );

            if (turnWise && deltaAzi < 0)
                orderServer.TurnRightSpeed = 0;
            else if (!turnWise && deltaAzi > 0)
                orderServer.TurnRightSpeed = 0;

            if (!rotaWForward && Math.Abs( deltaAzi ) < smoothAng)
            {
                Line refLine = new Line( curPos, orderServer.Direction );
                Line vertice = MathTools.VerticeLine( refLine, curPos );
                Line midVert = MathTools.MidVerLine( curPos, aimPos );
                Vector2 interPoint;

                bool canFor = false;
                if (MathTools.InterPoint( vertice, midVert, out interPoint ))
                {
                    float radius = Vector2.Distance( interPoint, curPos );
                    if (radius * fixFactor > vel / rotaVel)
                        canFor = true;
                }
                else
                {
                    canFor = true;
                }

                if (canFor)
                {
                    rotaWForward = true;
                    orderServer.ForwardSpeed = vel;
                }
            }

            if (!rotaWForward && orderServer.TurnRightSpeed == 0)
            {
                orderServer.ForwardSpeed = vel;
            }

            if (orderServer.TurnRightSpeed == 0 && Math.Abs( MathTools.AngTransInPI( curAzi - aimAzi ) ) > MathHelper.PiOver4)
            {
                isEnd = true;
                orderServer.TurnRightSpeed = 0;
                orderServer.ForwardSpeed = 0;

                if (finishHandler != null)
                {
                    finishHandler( this );
                }
            }
        }

        #endregion
    }
    #endregion

    #region OrderMoveCircle
    public class OrderMoveCircle : IActionOrder
    {
        float length;
        float rotaVel;
        float moveVel;

        OrderMove moveOrder;

        bool isEnd = false;
        IAIOrderServer orderServer;

        ActionFinishHandler finishHandler;
        bool stopCallFinish = false;

        public OrderMoveCircle ( float length, float rotaVel, float moveVel )
        {
            this.length = length;
            this.rotaVel = rotaVel;
            this.moveVel = moveVel;
        }

        public OrderMoveCircle ( float length, float rotaVel, float moveVel, ActionFinishHandler finishHandler, bool stopCallFinish )
        {
            this.length = length;
            this.rotaVel = rotaVel;
            this.moveVel = moveVel;
            this.finishHandler = finishHandler;
            this.stopCallFinish = stopCallFinish;
        }

        public OrderMoveCircle ( Vector2 aimPos, float moveVel, IAIOrderServer orderServer )
        {
            this.orderServer = orderServer;
            moveVel = Math.Min( Math.Max( -orderServer.MaxBackwardSpeed, moveVel ), orderServer.MaxForwardSpeed );
            Vector2 direction = orderServer.Direction;
            Line curVertice = MathTools.VerticeLine( new Line( orderServer.Pos, direction ), orderServer.Pos );
            Line midVertice = MathTools.MidVerLine( orderServer.Pos, aimPos );
            Vector2 center;
            if (!MathTools.InterPoint( curVertice, midVertice, out center ))
            {
                this.moveVel = moveVel;
                this.rotaVel = 0;
                float forward = Vector2.Dot( direction, aimPos - orderServer.Pos );
                this.length = Vector2.Distance( aimPos, orderServer.Pos ) * Math.Sign( forward );
            }
            else
            {
                float radius = Vector2.Distance( center, orderServer.Pos );

                float turnRight = MathTools.Vector2Cross( direction, aimPos - orderServer.Pos );

                if (orderServer.MaxRotaSpeed * radius < Math.Abs( moveVel ))
                {
                    this.moveVel = orderServer.MaxRotaSpeed * radius;
                    this.rotaVel = orderServer.MaxRotaSpeed * Math.Sign( turnRight );

                }
                else
                {
                    this.moveVel = moveVel;
                    this.rotaVel = moveVel / radius * Math.Sign( turnRight );
                }
                float ang = MathTools.AngBetweenVectors( orderServer.Pos - center, aimPos - center );
                bool inFront = Vector2.Dot( direction, aimPos - orderServer.Pos ) >= 0;
                if (moveVel > 0)
                {
                    if (inFront)
                    {
                        this.length = ang * radius;
                    }
                    else
                    {
                        this.length = (2 * MathHelper.Pi - ang) * radius;
                    }
                }
                else
                {
                    if (inFront)
                    {
                        this.length = -(2 * MathHelper.Pi - ang) * radius;
                    }
                    else
                    {
                        this.length = -ang * radius;
                    }
                }
            }
        }

        public OrderMoveCircle ( Vector2 aimPos, float moveVel, IAIOrderServer orderServer, ActionFinishHandler finishHandler, bool stopCallFinish )
        {
            this.orderServer = orderServer;
            moveVel = Math.Min( Math.Max( -orderServer.MaxBackwardSpeed, moveVel ), orderServer.MaxForwardSpeed );
            Vector2 direction = orderServer.Direction;
            Line curVertice = MathTools.VerticeLine( new Line( orderServer.Pos, direction ), orderServer.Pos );
            Line midVertice = MathTools.MidVerLine( orderServer.Pos, aimPos );
            Vector2 center;
            if (!MathTools.InterPoint( curVertice, midVertice, out center ))
            {
                this.moveVel = moveVel;
                this.rotaVel = 0;
                float forward = Vector2.Dot( direction, aimPos - orderServer.Pos );
                this.length = Vector2.Distance( aimPos, orderServer.Pos ) * Math.Sign( forward );
            }
            else
            {
                float radius = Vector2.Distance( center, orderServer.Pos );

                float turnRight = MathTools.Vector2Cross( direction, aimPos - orderServer.Pos );

                if (orderServer.MaxRotaSpeed * radius < Math.Abs( moveVel ))
                {
                    this.moveVel = orderServer.MaxRotaSpeed * radius;
                    this.rotaVel = orderServer.MaxRotaSpeed * Math.Sign( turnRight );

                }
                else
                {
                    this.moveVel = moveVel;
                    this.rotaVel = moveVel / radius * Math.Sign( turnRight );
                }
                float ang = MathTools.AngBetweenVectors( orderServer.Pos - center, aimPos - center );
                bool inFront = Vector2.Dot( direction, aimPos - orderServer.Pos ) >= 0;
                if (moveVel > 0)
                {
                    if (inFront)
                    {
                        this.length = ang * radius;
                    }
                    else
                    {
                        this.length = (2 * MathHelper.Pi - ang) * radius;
                    }
                }
                else
                {
                    if (inFront)
                    {
                        this.length = -(2 * MathHelper.Pi - ang) * radius;
                    }
                    else
                    {
                        this.length = -ang * radius;
                    }
                }
            }

            this.finishHandler = finishHandler;
            this.stopCallFinish = stopCallFinish;
        }

        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.Move | ActionRights.Rota; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = value;
                moveOrder = new OrderMove( length, moveVel,
                    delegate( IActionOrder action )
                    {
                        isEnd = true;
                    }, false );
                moveOrder.OrderServer = orderServer;
                orderServer.TurnRightSpeed = rotaVel;
            }
        }

        public bool IsEnd
        {
            get { return isEnd; }
        }

        public void Stop ()
        {
            if (stopCallFinish && finishHandler != null)
            {
                finishHandler( this );
            }
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            moveOrder.Update( seconds );
            if (isEnd)
            {
                if (finishHandler != null)
                {
                    finishHandler( this );
                }
            }
        }

        #endregion
    }
    #endregion

    #region OrderScanRader
    /// <summary>
    /// 雷达以坦克方向为基准在一定夹角范围内来回扫描
    /// </summary>
    public class OrderScanRader : IActionOrder
    {
        float rotaAngLeft;
        float rotaAngRight;
        float rotaSpeed;

        bool startAtRight;

        IAIOrderServer orderServer;

        AIActionHelper action;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="rotaAng">最大扫描角</param>
        /// <param name="rotaSpeed">扫描速度,如果为零，则为最大旋转速度</param>
        /// <param name="startAtRight">是否先向右扫描</param>
        public OrderScanRader ( float rotaAng, float rotaSpeed, bool startAtRight )
        {
            this.rotaAngLeft = rotaAng;
            this.rotaAngRight = rotaAng;
            this.rotaSpeed = rotaSpeed;
            this.startAtRight = startAtRight;
        }

        public OrderScanRader ( float rotaAngRight, float rotaAngLeft, float rotaSpeed, bool startAtRight )
        {
            this.rotaAngRight = rotaAngRight;
            this.rotaAngLeft = rotaAngLeft;
            this.rotaSpeed = rotaSpeed;
            this.startAtRight = startAtRight;
        }

        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.RotaRader; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = value;
                action = new AIActionHelper( orderServer );

                if (rotaSpeed == 0)
                    rotaSpeed = orderServer.MaxRotaRaderSpeed;

                if (startAtRight)
                    TurnRight( null );
                else
                    TurnLeft( null );
            }
        }

        private void TurnRight ( IActionOrder order )
        {
            action.AddOrder( new OrderRotaRaderToAng( rotaAngRight, rotaSpeed, TurnLeft, false ) );
        }

        private void TurnLeft ( IActionOrder order )
        {
            action.AddOrder( new OrderRotaRaderToAng( -rotaAngLeft, rotaSpeed, TurnRight, false ) );
        }

        public bool IsEnd
        {
            get { return false; }
        }

        public void Stop ()
        {

        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            action.Update( seconds );
        }

        #endregion
    }
    #endregion

    #region OrderScanRaderAzi
    /// <summary>
    /// 雷达在一定方位角范围内来回扫描
    /// </summary>
    public class OrderScanRaderAzi : IActionOrder
    {
        float rotaAziLeft;
        float rotaAziRight;
        float rotaSpeed;

        bool startAtRight;

        IAIOrderServer orderServer;

        AIActionHelper action;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="rotaAzi">最大扫描角</param>
        /// <param name="rotaSpeed">扫描速度,如果为零，则为最大旋转速度</param>
        /// <param name="startAtRight">是否先向右扫描</param>
        public OrderScanRaderAzi ( float rotaAzi, float rotaSpeed, bool startAtRight )
        {
            this.rotaAziLeft = rotaAzi;
            this.rotaAziRight = rotaAzi;
            this.rotaSpeed = rotaSpeed;
            this.startAtRight = startAtRight;
        }

        public OrderScanRaderAzi ( float rotaAziRight, float rotaAziLeft, float rotaSpeed, bool startAtRight )
        {
            this.rotaAziRight = rotaAziRight;
            this.rotaAziLeft = rotaAziLeft;
            this.rotaSpeed = rotaSpeed;
            this.startAtRight = startAtRight;
        }

        #region IActionOrder 成员

        public ActionRights NeedRights
        {
            get { return ActionRights.RotaRader; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = value;
                action = new AIActionHelper( orderServer );

                if (rotaSpeed == 0)
                    rotaSpeed = orderServer.MaxRotaRaderSpeed;

                if (startAtRight)
                    TurnRight( null );
                else
                    TurnLeft( null );
            }
        }

        private void TurnRight ( IActionOrder order )
        {
            action.AddOrder( new OrderRotaRaderToAzi( rotaAziRight, rotaSpeed, TurnLeft, false ) );
        }

        private void TurnLeft ( IActionOrder order )
        {
            action.AddOrder( new OrderRotaRaderToAzi( rotaAziLeft, rotaSpeed, TurnRight, false ) );
        }

        public bool IsEnd
        {
            get { return false; }
        }

        public void Stop ()
        {

        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            action.Update( seconds );
        }

        #endregion
    }
    #endregion
}

<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using System.Collections;
using Common.Helpers;
using Common.DataStructure;

namespace GameEngine.Senses.Memory
{
    public class ConvexHall
    {
        List<VisiBordPoint> convexPoints;

        public ConvexHall ( CircleList<VisiBordPoint> border, float minOptimizeDest )
        {
            BuildConvexHall( border, minOptimizeDest );
        }

        public List<VisiBordPoint> Points
        {
            get { return convexPoints; }
        }

        public void BuildConvexHall ( CircleList<VisiBordPoint> border, float minOptimizeDest )
        {
            #region 获得原始凸包
            if (border.Length < 2)
                return;

            Stack<VisiBordPoint> stack = new Stack<VisiBordPoint>();

            CircleListNode<VisiBordPoint> cur = border.First;
            stack.Push( cur.value );
            cur = cur.next;
            stack.Push( cur.value );
            cur = cur.next;
            for (int i = 2; i < border.Length; i++)
            {
                VisiBordPoint p1 = stack.Pop();

                VisiBordPoint p0 = stack.Peek();

                VisiBordPoint p2 = cur.value;

                if (CountWise( p1, p0, p2 ))
                {
                    stack.Push( p1 );
                    stack.Push( p2 );
                    cur = cur.next;
                }
                else
                {
                    if (stack.Count == 1)
                    {
                        stack.Push( p2 );
                        cur = cur.next;
                    }
                    else
                        i--;
                }
            }

            List<VisiBordPoint> templist = new List<VisiBordPoint>( stack );

            if (templist.Count > 3)
            {
                if (!CountWise( templist[0], templist[1], templist[templist.Count - 1] ))
                {
                    templist.RemoveAt( 0 );
                }
                if (!CountWise( templist[templist.Count - 1], templist[0], templist[templist.Count - 2] ))
                {
                    templist.RemoveAt( templist.Count - 1 );
                }
            }
            else if (templist.Count == 3)
            {
                if (!CountWise( templist[0], templist[1], templist[templist.Count - 1] ))
                {
                    templist.RemoveAt( 0 );
                    VisiBordPoint temp = templist[0];
                    templist[0] = templist[1];
                    templist[1] = temp;
                }
            }

            #endregion

            #region 对凸包进行化简

            if (templist.Count > 3)
            {
                for (int i = 0; i < templist.Count; i++)
                {
                    Vector2 p1 = ConvertHelper.PointToVector2( templist[i].p );
                    Vector2 p2 = ConvertHelper.PointToVector2( templist[(i + 1) % templist.Count].p );
                    Vector2 p3 = ConvertHelper.PointToVector2( templist[(i + 2) % templist.Count].p );
                    Vector2 p4 = ConvertHelper.PointToVector2( templist[(i + 3) % templist.Count].p );

                    if (Vector2.Distance( p2, p3 ) > minOptimizeDest)
                        continue;

                    Vector2 seg1 = p2 - p1;
                    Vector2 seg2 = p4 - p3;

                    float ang = (float)Math.Acos( Vector2.Dot( seg1, seg2 ) / (seg1.Length() * seg2.Length()) );
                    if (ang > MathHelper.PiOver2)
                        continue;

                    Line line1 = new Line( p1, seg1 );
                    Line line2 = new Line( p4, seg2 );

                    Vector2 interPoint;

                    if (!MathTools.InterPoint( line1, line2, out interPoint ))
                        continue;

                    templist[(i + 1) % templist.Count] =
                        new VisiBordPoint( templist[(i + 1) % templist.Count].index, ConvertHelper.Vector2ToPoint( interPoint ) );

                    templist.RemoveAt( (i + 2) % templist.Count );

                    i--;
                }
            }

            #endregion

            convexPoints = templist;
        }

        private bool CountWise ( VisiBordPoint p1, VisiBordPoint p0, VisiBordPoint p2 )
        {
            Vector2 v1 = new Vector2( p1.p.X - p0.p.X, p1.p.Y - p0.p.Y );
            Vector2 v2 = new Vector2( p2.p.X - p1.p.X, p2.p.Y - p1.p.Y );
            float cross = MathTools.Vector2Cross( v1, v2 );
            return cross < 0 || cross == 0 && Vector2.Dot( v1, v2 ) < 0;
        }
    }
}
<file_sep>#include "GameProtocol.h"
#include "mythread.h"

long GameProtocal::m_recvPackNum = 0;
extern pthread_mutex_t DD_ClientMgr_Mutex[MAXCLIENT]; 
extern int  g_MaxRoommate;

GameProtocal::GameProtocal()
{
    outLog.open("log.txt");
}

GameProtocal::~GameProtocal()
{
    outLog.close();
}


/************************************************************************/
/* 发给其他人
/************************************************************************/ 
bool GameProtocal::SendToOthers(MySocket* pSockClient, Packet &pack)
{
    MySocket *pSock;
    int realSize = pack.length + HEADSIZE;

    //outLog.write((char*)&pack, realSize);
    //char buffLog[PACKSIZE];
    /**/int nClient = pManager->GetNum();
    for ( int i = 0; i < nClient; i++)
    {
        if ( pSockClient == (pSock = pManager->GetClient(i) ) )
        {
            continue;
        }
        if ( false == pSock->SendPacket(pack, realSize) )
        {
            pManager->DelClient(pSockClient);
        }
    } 
    
    return true;
}
/************************************************************************/
/* 发给all
/************************************************************************/ 
bool GameProtocal::SendToAll(MySocket* pSockClient, Packet &pack)
{
    MySocket *pSock;
    int realSize = pack.length + HEADSIZE;

    for ( int i = 0; i < pManager->GetNum(); i++)
    {
        pSock = pManager->GetClient(i);
        if ( false == pSock->SendPacket(pack, realSize) )
        {
            pManager->DelClient( pSock );
        }
    } 
    return true;
}

/************************************************************************/
/* 发给某人
/************************************************************************/ 
bool GameProtocal::SendToOne(MySocket* pSockClient, Packet &pack)
{
    int realSize = pack.length + HEADSIZE;

    if ( false == pSockClient->SendPacket(pack, realSize) )
    {
        pManager->DelClient( pSockClient );
    }
    return true;
}
/************************************************************************/
/* 直接发送包头
/************************************************************************/ 
bool GameProtocal::SendHead(MySocket* pSockClient, PacketHead &packHead)
{
    if (false == pSockClient->SendPacketHead(packHead) )
    {
        pManager->DelClient(pSockClient);
    }
    return true;
}
/************************************************************************/
/*  用户登录 
/************************************************************************/      
bool GameProtocal::UserLogin(MySocket *pSockClient, Packet &pack)
{
    char buffPass[21];
    PacketHead packHead;
    packHead.length = 0;

    UserLoginPack sLogin;
    memcpy(&sLogin, (char*)&pack+HEADSIZE, sizeof(UserLoginPack));
    
    cout << pSockClient->GetIP() << "尝试登录:" << sLogin.Name << ":" 
        << sLogin.Password;
    /* 查询是否重复登录 */
    for ( int i = 0; i < pManager->GetNum(); i++)
    {
        MySocket *p = pManager->GetClient(i);
        if ( p == pSockClient )
            continue;
        if ( 0 == strcmp(pManager->GetClient(i)->m_name, sLogin.Name) )
        {
            cout << " --- 拒绝重登录." << endl;
            packHead.iStyle = LOGIN_FAIL;
            SendHead(pSockClient, packHead);
            return false;
        }
    }

    /* 查询数据库 */
    if ( -1 == m_SQL.GetUserPassword(sLogin.Name, buffPass) 
       || 0 != strcmp(buffPass, sLogin.Password))
    {
        // Wrong user name or password.
        cout << " --- 失败." << endl;
        packHead.iStyle = LOGIN_FAIL;
        SendHead(pSockClient, packHead);
    }
    else
    { 
        // Login success
        cout << " --- OK." << endl;
        pSockClient->BindName(sLogin.Name);
        pSockClient->m_rank = m_SQL.GetUserRank(sLogin.Name);
        pSockClient->m_score = m_SQL.GetUserScore(sLogin.Name);
        packHead.iStyle = LOGIN_SUCCESS;
        SendHead(pSockClient, packHead);
        return false;
    }

    return true;
}
/************************************************************************/
/*  用户离开<...>
/************************************************************************/
bool GameProtocal::UserExit(MySocket *pSockClient)
{
    PacketHead head;
    head.iStyle = USER_EXIT;
    head.length = 0;
    SendHead(pSockClient, head);
    pManager->DelClient(pSockClient);     
    return true;
}
/************************************************************************/
/*  用户注册 
/************************************************************************/      
bool GameProtocal::UserRegist(MySocket *pSockClient, Packet &pack)
{
    return true;
}
/************************************************************************/
/*  用户排行榜
/************************************************************************/ 
bool GameProtocal::ListRank(MySocket *pSockClient, Packet &pack)
{
    int realSize, realPlayers, rankBegin;
    RankInfo  riOut[NUM_OF_RANK]; 

    memcpy(&rankBegin, (char*)&pack.length+HEADSIZE, sizeof(int));
    realPlayers = m_SQL.GetRankList(rankBegin, rankBegin+NUM_OF_RANK, riOut);
    
    pack.length = realPlayers*sizeof(RankInfo);
    realSize = pack.length + HEADSIZE;

    //cout << setw(20) << "Name" << setw(10) << "Rank" << setw(10) << "Score" << endl;
    for ( int i = 0;   i < realPlayers;   i++)
    {
        /* 复制排行榜 */
        memcpy( (char*)&pack + HEADSIZE + i*sizeof(RankInfo) ,
                &riOut[i], sizeof(RankInfo));
        //cout << setw(20) << riOut[i].Name << setw(10)  
        //    << riOut[i].Rank << setw(10) << riOut[i].Score << endl;
    }
    if ( false == pSockClient->SendPacket(pack, realSize) )
        pManager->DelClient(pSockClient);

    cout << "刷新排行榜成功." << endl;
    return true;
}
/************************************************************************/
/*  用户列表
/************************************************************************/ 
bool GameProtocal::ListUser(MySocket *pSockClient, Packet &pack)
{   
    int realSize, realPlayers;
    UserInfo  riOut[MAXROOMMATE]; 
    realPlayers = pManager->m_room->GetPlayers();

    pack.iStyle = ROOM_LISTUSER; 
    pack.length = realPlayers*sizeof(UserInfo);


    realSize = pack.length + HEADSIZE;
    pManager->m_room->GetPlayesInfo(riOut);

    //cout << setw(-20)  << "玩家名" << setw(10) << "总分"<< endl;

    for ( int i = 0;   i < realPlayers; i++)
    {
        /* 复制房间人员信息 */
        memcpy( (char*)&pack + HEADSIZE + i*sizeof(UserInfo) ,
            &riOut[i], sizeof(UserInfo));
        //cout << setw(-20) << riOut[i].Name ;
        /*if ( riOut[i].ID == 1){
            cout << "(房主)" ;
        }
        cout << setw(10) << riOut[i].Score <<  endl;*/
    }
    if ( false == pSockClient->SendPacket(pack, realSize) )
        pManager->DelClient(pSockClient);

    return true;
}

/************************************************************************/
/* list房间 
/************************************************************************/
bool GameProtocal::ListRoom(MySocket *pSockClient, Packet &pack)
{
    int numOfRoom = pManager->m_numOfRoom;
    if ( 0 == numOfRoom )
    {
        pack.length = 0;
        pSockClient->SendPacket(pack, HEADSIZE);
        //cout << "刷新房间,房间数目:" << numOfRoom << endl;
    }
    else
    {
        RoomInfo ri;
        pack.length = sizeof(RoomInfo);
        int realSize = HEADSIZE + sizeof(RoomInfo);
        pManager->m_room->GetRoomInfo(ri);
        memcpy((char*)&pack+HEADSIZE, &ri, sizeof(RoomInfo));
        pSockClient->SendPacket(pack, realSize);
        //cout << "刷新房间,房间数目:" << numOfRoom << endl;
    }
    return true;
}


/************************************************************************/
/*  创建房间    */
/************************************************************************/
bool GameProtocal::CreateRoom(MySocket *pSockClient, Packet &pack)
{
    PacketHead head;
    int numOfRoom = pManager->m_numOfRoom;
    head.length = 0;
    if ( 0 == numOfRoom )
    {            
        cout << "【" << pSockClient->m_name << "】创建了房间." << endl;
        pManager->m_room->CreateRoom(pSockClient);
        head.iStyle = CREATE_SUCCESS;
        pManager->m_numOfRoom = 1;
    }
    else
    { 
        head.iStyle = CREATE_FAIL;
        cout << "【" << pSockClient->m_name << "】创建房间失败." << endl;
    }
    SendHead(pSockClient, head);
    return true;
}
/************************************************************************/
/*  进入房间    */
/************************************************************************/
bool GameProtocal::EnterRoom(MySocket *pSockClient, Packet &pack)
{
    PacketHead head;
    RoomInfo ri;
    pManager->m_room->GetRoomInfo(ri);

    head.length = 0;
    if ( g_MaxRoommate == ri.players || 0==pManager->m_numOfRoom || ri.bBegin)
    {
        head.iStyle = JOIN_FAIL;
        cout << "【" << pSockClient->m_name << "】进入房间失败." << endl;
        SendHead(pSockClient, head);
    }
    else
    { 
        cout << "【" << pSockClient->m_name << "】进入房间成功." << endl;

        pManager->m_room->EnterRoom(pSockClient);
        head.iStyle = JOIN_SUCCESS;
        SendHead(pSockClient, head);

        // 刷新房间信息
        Packet pack;
        for ( int i = 0; i < pManager->m_room->GetPlayers(); i++)
        {
            ListUser(pManager->m_room->GetPlayer(i), pack);
        }
    }
    return true;
}
/************************************************************************/
/*  离开房间    */
/************************************************************************/
bool GameProtocal::ExitRoom(MySocket *pSockClient, Packet &pack)
{
    pack.iStyle = ROOM_LISTUSER;
    if ( true == pManager->m_room->RemovePlayer(pSockClient) )
    {
        if ( pManager->m_room->GetPlayers() == 0)
        {
            pManager->m_numOfRoom--;
        }
        // 刷新房间信息
        for ( int i = 0; i < pManager->m_room->GetPlayers(); i++)
        {
            ListUser(pManager->m_room->GetPlayer(i), pack);
        }
    }
    else
    {
        cout << "你牛B,没进房你也能退房." << endl;
    }

    return true;
}
/************************************************************************/
/*  用户自己信息    */
/************************************************************************/
bool GameProtocal::MyInfo(MySocket *pSockClient, Packet &pack)
{
    int realSize;
    UserInfo  riOut; 
    pack.length = sizeof(UserInfo);
    realSize = pack.length + HEADSIZE;
    pSockClient->GetUserInfo(riOut);
    
    cout << "个人信息" << endl;
    if ( riOut.ID == 1){
        cout << "(房主)" ;
    }
    cout << riOut.Name << " : 总分"<<riOut.Rank << 
        ",排名第 " << riOut.Rank << " 名." << endl;
    /* 复制信息 */
    memcpy( (char*)&pack + HEADSIZE,  &riOut, sizeof(UserInfo));
    

    if ( false == pSockClient->SendPacket(pack, realSize) )
        pManager->DelClient(pSockClient);
    return true;
}
/************************************************************************/
/*  游戏开始  */
/************************************************************************/
bool GameProtocal::GameGo(MySocket *pSockClient, Packet &pack)
{
    pack.length = 0;
    if ( pManager->m_room->GetPlayers() > 1)
    {
        pManager->m_room->SetRoomState(true);
        cout << "游戏开始." << endl;
        pack.iStyle = GAME_GO;
    }
    else
    {
        cout << "1个人玩个毛." << endl;
        pack.iStyle = GAME_START_FAIL;
    }
    // 发送给房间里的所有人
    pManager->m_room->SendToAll(pack);
    return true;
}
/************************************************************************/
/*  保存游戏结果到数据库  */
/************************************************************************/
bool GameProtocal::SaveGameResult(MySocket *pSockClient, Packet &pack)
{
    int realPlayers = pack.length/sizeof(RankInfo);
    RankInfo ri[MAXROOMMATE];
    memcpy(ri, (char*)&pack + HEADSIZE, pack.length);
    for (int i = 0; i < realPlayers; i++)
    {
        // 增加得分
        int newScore = m_SQL.GetUserScore(ri[i].Name) + ri[i].Score;
        cout << ri[i].Name << " 得分: " << ri[i].Score << endl;
        if ( -1 ==  m_SQL.SetUserScore(ri[i].Name, newScore) )
            cout << "修改 " << ri[i].Name << " 失败." << endl;
    }
    pManager->m_room->SetRoomState(false);
    return true;
}

/************************************************************************/
/*  保存游戏结果到数据库  */
/************************************************************************/
bool GameProtocal::SendGameData(MySocket *pSockClient, Packet &pack)
{
    pManager->m_room->SendToOthers(pSockClient, pack);
    return true;
}








<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace SmartTank.GameObjs.Tank
{
    public class TurretLinker
    {
        Vector2 refAxesToOri;
        float scale;
        Vector2 tankOriInLogic;
        Vector2 turretAxesInLogic;

        /// <summary>
        /// 新建一个TurretLinker对象
        /// </summary>
        /// <param name="turretAxesInPix"></param>
        /// <param name="tankOriInPix"></param>
        /// <param name="scale">逻辑尺寸/原图尺寸</param>
        public TurretLinker ( Vector2 turretAxesInPix, Vector2 tankOriInPix, float scale )
        {
            this.scale = scale;
            this.tankOriInLogic = tankOriInPix * scale;
            this.turretAxesInLogic = turretAxesInPix * scale;
            refAxesToOri = turretAxesInLogic - tankOriInLogic;
        }

        public Vector2 GetTexturePos ( Vector2 basePos, float baseRota )
        {
            return basePos + Vector2.Transform( refAxesToOri, Matrix.CreateRotationZ( baseRota ) );
        }

        public void SetTurretAxes ( Vector2 turretAxesInPix )
        {
            Vector2 turretAxesInLogic = turretAxesInPix * scale;
            refAxesToOri = turretAxesInLogic - tankOriInLogic;
        }
    }
}
<file_sep>﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
using SmartTank.Helpers.DependInject;
using SmartTank.Rule;
using SmartTank.AI;

namespace AssetRegister
{
    public partial class AssetRegister : Form
    {
        readonly string rulesPath = "Rule";
        readonly string rulesListPath = "Rule\\List.xml";

        readonly string AIPath = "AIs";
        readonly string AIListPath = "AIs\\List.xml";

        AssetList rulelist;
        AssetList AIlist;

        public AssetRegister ()
        {
            InitializeComponent();
            InitialRuleList();
            InitialAIList();
        }

        private void InitialRuleList ()
        {
            Directory.SetCurrentDirectory( Application.StartupPath );
            if (!Directory.Exists( rulesPath ))
            {
                Directory.CreateDirectory( rulesPath );
            }
            rulelist = AssetList.Load( File.Open( rulesListPath, FileMode.OpenOrCreate ) );

            if (rulelist == null) rulelist = new AssetList();

            ListViewItem myItem = new ListViewItem();
            listViewRule.Items.Clear();
            foreach (AssetItem item in rulelist.list)
            {
                foreach (NameAndTypeName item1 in item.names)
                {
                    myItem = listViewRule.Items.Add( item.DLLName );
                    myItem.SubItems.Add( item1.name );
                    myItem.SubItems.Add( item1.typeNames );
                }
            }
        }

        private void InitialAIList ()
        {
            Directory.SetCurrentDirectory( Application.StartupPath );
            if (!Directory.Exists( AIPath ))
            {
                Directory.CreateDirectory( AIPath );
            }
            AIlist = AssetList.Load( File.Open( AIListPath, FileMode.OpenOrCreate ) );
            if (AIlist == null) AIlist = new AssetList();

            ListViewItem myItem = new ListViewItem();
            listViewAI.Items.Clear();
            foreach (AssetItem item in AIlist.list)
            {
                foreach (NameAndTypeName item1 in item.names)
                {
                    myItem = listViewAI.Items.Add( item.DLLName );
                    myItem.SubItems.Add( item1.name );
                    myItem.SubItems.Add( item1.typeNames );
                }
            }
        }

        #region AddRule

        private void OpenRuleDLLFileDialog_FileOk ( object sender, CancelEventArgs e )
        {
            List<AssetItem> rulesList = new List<AssetItem>();

            List<string> vaildDLL = new List<string>();

            int countVaildClass = 0;

            foreach (string fileName in OpenRuleDLLFileDialog.FileNames)
            {
                Assembly assembly = DIHelper.GetAssembly( fileName );

                AssetItem curItem;
                bool findGameRule = false;
                curItem = new AssetItem();
                curItem.DLLName = assembly.FullName;// Path.GetFileName( fileName );
                List<NameAndTypeName> names = new List<NameAndTypeName>();
                try
                {
                    foreach (Type type in assembly.GetTypes())
                    {
                        foreach (Type infer in type.GetInterfaces())
                        {
                            if (infer.Name == "IGameRule")
                            {
                                object[] attributes = type.GetCustomAttributes( typeof( RuleAttribute ), false );
                                foreach (object attri in attributes)
                                {
                                    if (attri is RuleAttribute)
                                    {
                                        findGameRule = true;
                                        string ruleName = ((RuleAttribute)attri).Name;
                                        names.Add( new NameAndTypeName( ruleName, type.FullName ) );
                                        countVaildClass++;
                                        break;
                                    }
                                }
                                if (findGameRule)
                                    break;
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    findGameRule = false;
                }
                if (findGameRule)
                {
                    curItem.names = names.ToArray();
                    rulesList.Add( curItem );
                    vaildDLL.Add( fileName );
                }
            }

            if (rulesList.Count != 0)
            {
                Directory.SetCurrentDirectory( Application.StartupPath );
                if (!Directory.Exists( rulesPath ))
                {
                    Directory.CreateDirectory( rulesPath );
                }
                AssetList list = AssetList.Load( File.Open( rulesListPath, FileMode.OpenOrCreate ) );
                if (list == null)
                    list = new AssetList();


                foreach (AssetItem item in rulesList)
                {
                    int index = list.IndexOf( item.DLLName );
                    if (index != -1)
                        list.list[index] = item;
                    else
                        list.list.Add( item );
                }
                AssetList.Save( File.Open( rulesListPath, FileMode.OpenOrCreate ), list );

                foreach (string DLLPath in vaildDLL)
                {
                    string copyPath = Path.Combine( rulesPath, Path.GetFileName( DLLPath ) );
                    if (!Path.GetFullPath( copyPath ).Equals( DLLPath ))
                    {
                        if (File.Exists( copyPath ))
                        {
                            DialogResult result = MessageBox.Show( Path.GetFileName( DLLPath ) + "已存在于" + rulesPath + "中。是否覆盖？", "文件已存在", MessageBoxButtons.YesNo );
                            if (result == DialogResult.Yes)
                            {
                                File.Copy( DLLPath, copyPath, true );
                            }
                        }
                        else
                            File.Copy( DLLPath, copyPath );
                    }
                }
                MessageBox.Show( "添加规则程序集成功！共添加" + vaildDLL.Count + "个有效程序集，" + countVaildClass + "个有效规则类", "成功" );
            }
            else
                MessageBox.Show( "未找到有效规则程序集！", "失败" );

            InitialRuleList();
        }

        private void AddRuleBtn_Click ( object sender, EventArgs e )
        {
            OpenRuleDLLFileDialog.ShowDialog();
        }

        #endregion

        private void DelRuleBtn_Click ( object sender, EventArgs e )
        {
            if (listViewRule.SelectedItems.Count == 0)
            {
                MessageBox.Show( "请在左边选择一个要删除的条目！", "提示窗口",
                MessageBoxButtons.OK, MessageBoxIcon.Information );
                return;
            }
            foreach (AssetItem aa in rulelist.list)
            {
                foreach (NameAndTypeName bb in aa.names)
                {
                    foreach (ListViewItem listitem in listViewRule.SelectedItems)
                    {
                        this.Text += bb.name;
                        if (aa.DLLName == listitem.SubItems[0].Text && bb.name == listitem.SubItems[1].Text
                              && bb.typeNames == listitem.SubItems[2].Text)
                        {
                            rulelist.list.Remove( aa );
                            File.Delete( rulesListPath );
                            AssetList.Save( File.Open( rulesListPath, FileMode.OpenOrCreate ), rulelist );
                            InitialRuleList();
                            return;
                        }
                    }
                }
            }

        }



        private void AddAIBtn_Click ( object sender, EventArgs e )
        {
            OpenAIDLLFileDialog.ShowDialog();
        }

        private void OpenAIDLLFileDialog_FileOk ( object sender, CancelEventArgs e )
        {
            List<AssetItem> AIList = new List<AssetItem>();

            List<string> vaildDLL = new List<string>();

            int countVaildClass = 0;

            foreach (string fileName in OpenAIDLLFileDialog.FileNames)
            {
                Assembly assembly = DIHelper.GetAssembly( fileName );

                AssetItem curItem;
                bool findGameAI = false;
                curItem = new AssetItem();
                curItem.DLLName = Path.GetFileName( fileName );
                List<NameAndTypeName> names = new List<NameAndTypeName>();
                try
                {
                    Directory.SetCurrentDirectory( Application.StartupPath );
                    AppDomain.CurrentDomain.AppendPrivatePath( "Rules" );
                    foreach (Type type in assembly.GetTypes())
                    {
                        foreach (Type infer in type.GetInterfaces())
                        {
                            if (infer.Name == "IAI")
                            {
                                object[] attributes = type.GetCustomAttributes( typeof( AIAttribute ), false );
                                foreach (object attri in attributes)
                                {
                                    if (attri is AIAttribute)
                                    {
                                        findGameAI = true;
                                        string AIName = ((AIAttribute)attri).Name;
                                        names.Add( new NameAndTypeName( AIName, type.FullName ) );
                                        countVaildClass++;
                                        break;
                                    }
                                }
                                if (findGameAI)
                                    break;
                            }
                        }
                    }
                    AppDomain.CurrentDomain.ClearPrivatePath();
                }
                catch (Exception ex)
                {
                    findGameAI = false;
                }
                if (findGameAI)
                {
                    curItem.names = names.ToArray();
                    AIList.Add( curItem );
                    vaildDLL.Add( fileName );
                }
            }

            if (AIList.Count != 0)
            {
                Directory.SetCurrentDirectory( Application.StartupPath );
                if (!Directory.Exists( AIPath ))
                {
                    Directory.CreateDirectory( AIPath );
                }
                AssetList list = AssetList.Load( File.Open( AIListPath, FileMode.OpenOrCreate ) );
                if (list == null)
                    list = new AssetList();


                foreach (AssetItem item in AIList)
                {
                    int index = list.IndexOf( item.DLLName );
                    if (index != -1)
                        list.list[index] = item;
                    else
                        list.list.Add( item );
                }
                AssetList.Save( File.Open( AIListPath, FileMode.OpenOrCreate ), list );

                foreach (string DLLPath in vaildDLL)
                {
                    string copyPath = Path.Combine( AIPath, Path.GetFileName( DLLPath ) );
                    if (!Path.GetFullPath( copyPath ).Equals( DLLPath ))
                    {
                        if (File.Exists( copyPath ))
                        {
                            DialogResult result = MessageBox.Show( Path.GetFileName( DLLPath ) + "已存在于" + rulesPath + "中。是否覆盖？", "文件已存在", MessageBoxButtons.YesNo );
                            if (result == DialogResult.Yes)
                            {
                                File.Copy( DLLPath, copyPath, true );
                            }
                        }
                        else
                            File.Copy( DLLPath, copyPath );
                    }
                }
                MessageBox.Show( "添加规则程序集成功！共添加" + vaildDLL.Count + "个有效程序集，" + countVaildClass + "个有效规则类", "成功" );
            }
            else
                MessageBox.Show( "未找到有效规则程序集！", "失败" );

            InitialAIList();
        }

        private void DelAIBtn_Click ( object sender, EventArgs e )
        {
            if (listViewAI.SelectedItems.Count == 0)
            {
                MessageBox.Show( "请在左边选择一个要删除的条目！", "提示窗口",
                MessageBoxButtons.OK, MessageBoxIcon.Information );
                return;
            }
            foreach (AssetItem aa in AIlist.list)
            {
                foreach (NameAndTypeName bb in aa.names)
                {
                    foreach (ListViewItem listitem in listViewAI.SelectedItems)
                    {
                        this.Text += bb.name;
                        if (aa.DLLName == listitem.SubItems[0].Text && bb.name == listitem.SubItems[1].Text
                              && bb.typeNames == listitem.SubItems[2].Text)
                        {
                            AIlist.list.Remove( aa );
                            File.Delete( AIListPath );
                            AssetList.Save( File.Open( AIListPath, FileMode.OpenOrCreate ), AIlist );
                            InitialAIList();
                            return;
                        }
                    }
                }
            }
        }


    }
}<file_sep>//=================================================
// xWinForms
// Copyright ?2007 by <NAME>
// http://psycad007.spaces.live.com/
//=================================================
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SmartTank.Draw.UI.Controls
{
    public class Progressbar : Control
    {
        #region Variables
        Texture2D border;
        Texture2D progressBar;
        public int width = 200;

        int numberOfBlocks = 20;
        int blockWidth = 10;

        private Rectangle sourceRect = Rectangle.Empty;
        private Rectangle destRect = Rectangle.Empty;

        public Vector4 color;

        public Style style;
        public enum Style
        {
            Continuous,
            Blocks
        }
        #endregion

        #region Construction
        public Progressbar ( string name, Vector2 position, Color color, int width, int value, bool bContinuous )
        {
            Type = ControlType.ProgressBar;
            this.name = name;
            //this.origin = position;
            this.position = position;
            this.width = width;
            this.value = value;
            this.color = color.ToVector4();

            if (bContinuous)
                style = Style.Continuous;
            else
                style = Style.Blocks;

            numberOfBlocks = width / blockWidth + 1;
            max = 100;

            CreateTextures();
        }

        private void CreateTextures ()
        {
            border = new Texture2D( BaseGame.Device, width, 18, 1, Control.resourceUsage, SurfaceFormat.Color );
            progressBar = new Texture2D( BaseGame.Device, width - 8, border.Height - 8, 1, Control.resourceUsage, SurfaceFormat.Color );

            sourceRect = new Rectangle( 0, 0, progressBar.Width, progressBar.Height );
            destRect = new Rectangle( 0, 0, progressBar.Width, progressBar.Height );

            Color[] borderPixel = new Color[border.Width * border.Height];
            Color[] progressBarPixel = new Color[progressBar.Width * progressBar.Height];

            for (int y = 0; y < border.Height; y++)
            {
                for (int x = 0; x < border.Width; x++)
                {
                    if (x < 3 || y < 3 || x > border.Width - 3 || y > border.Height - 3)
                    {
                        if (x == 0 || y == 0 || x == border.Width - 1 || y == border.Height - 1)
                            borderPixel[x + y * border.Width] = Color.Black;
                        if (x == 1 || y == 1 || x == border.Width - 2 || y == border.Height - 2)
                            borderPixel[x + y * border.Width] = Color.LightGray;
                        if (x == 2 || y == 2 || x == border.Width - 3 || y == border.Height - 3)
                            borderPixel[x + y * border.Width] = Color.Gray;
                    }
                    else
                        borderPixel[x + y * border.Width] = new Color( new Vector4( 0.8f, 0.8f, 0.8f, 1f ) );
                }
            }

            for (int y = 0; y < progressBar.Height; y++)
            {
                for (int x = 0; x < progressBar.Width; x++)
                {
                    bool bInvisiblePixel = false;

                    if (style == Style.Blocks)
                    {
                        int xPos = x % (int)(progressBar.Width / (float)numberOfBlocks);
                        if (xPos == 0 || xPos == 1)
                            bInvisiblePixel = true;
                    }

                    if (!bInvisiblePixel)
                    {
                        float gradient = 0.7f - y * 0.065f;
                        Color pixelColor = new Color( new Vector4( color.X * gradient, color.Y * gradient, color.Z * gradient, 1f ) );
                        progressBarPixel[x + y * progressBar.Width] = pixelColor;
                    }
                }
            }

            border.SetData<Color>( borderPixel );
            progressBar.SetData<Color>( progressBarPixel );
        }
        #endregion

        #region Update
        public override void Update ()// Vector2 formPosition, Vector2 formSize )
        {
            //base.Update( formPosition, formSize );

            if (value < 0)
                value = 0;
            if (value > 100)
                value = 100;

            int rectWidth = (int)(progressBar.Width * ((float)value / (float)max));

            //Console.WriteLine(rectWidth);

            if (style == Style.Continuous)
            {
                destRect.Width = rectWidth;
                sourceRect.Width = destRect.Width;
            }
            else
            {
                int totalBlocks = (int)(numberOfBlocks * ((float)value / (float)max));

                int blockWidth = 0;
                if (totalBlocks > 0)
                    blockWidth = (int)(progressBar.Width / (numberOfBlocks));

                destRect.Width = blockWidth * totalBlocks;
                sourceRect.Width = destRect.Width;
            }

            destRect.X = (int)position.X + 4;
            destRect.Y = (int)position.Y + 4;

            //CheckVisibility( formPosition, formSize );
        }

        //private void CheckVisibility ( Vector2 formPosition, Vector2 formSize )
        //{
        //    if (position.X + border.Width > formPosition.X + formSize.X - 15f)
        //        bVisible = false;
        //    else if (position.Y + border.Height > formPosition.Y + formSize.Y - 25f)
        //        bVisible = false;
        //    else
        //        bVisible = true;
        //} 
        #endregion

        #region Draw
        public override void Draw ( SpriteBatch spriteBatch, float alpha )
        {
            Color dynamicColor = new Color( new Vector4( 1f, 1f, 1f, alpha ) );
            spriteBatch.Draw( border, position, dynamicColor );
            spriteBatch.Draw( progressBar, destRect, sourceRect, dynamicColor );
        } 
        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using GameEngine.Senses.Vision;
using Common.DataStructure;
using Common.Helpers;

namespace GameEngine.Senses.Memory
{
    public struct NaviPoint
    {
        EyeableBorderObjInfo objInfo;
        int index;
        Vector2 pos;

        public EyeableBorderObjInfo ObjInfo
        {
            get { return objInfo; }
        }

        public int Index
        {
            get { return index; }
        }

        public Vector2 Pos
        {
            get { return pos; }
        }

        public NaviPoint ( EyeableBorderObjInfo objInfo, int index, Vector2 pos )
        {
            this.objInfo = objInfo;
            this.index = index;
            this.pos = pos;
        }
    }

    public class GuardConvex
    {
        public GraphPoint<NaviPoint>[] points;

        public GraphPoint<NaviPoint> this[int i]
        {
            get { return points[i]; }
        }

        public int Length
        {
            get { return points.Length; }
        }

        public GuardConvex ( GraphPoint<NaviPoint>[] points )
        {
            this.points = points;
        }

        public bool PointInConvex ( Vector2 p )
        {
            if (points.Length < 3)
                return false;

            float sign = 0;
            bool first = true;
            for (int i = 0; i < points.Length; i++)
            {
                GraphPoint<NaviPoint> cur = points[i];
                GraphPoint<NaviPoint> next = points[(i + 1) % points.Length];

                float cross = MathTools.Vector2Cross( p - cur.value.Pos, next.value.Pos - p );

                if (first)
                {
                    sign = cross;
                    first = false;
                }
                else
                {
                    if (Math.Sign( sign ) != Math.Sign( cross ))
                    {
                        return false;
                    }
                }
            }
            return true;
        }
    }

    public class NavigateMap
    {
        GraphPoint<NaviPoint>[] naviGraph;

        List<Segment> guardLines;

        List<Segment> borderLines;

        List<GuardConvex> convexs;

        public GraphPoint<NaviPoint>[] Map
        {
            get { return naviGraph; }
        }

        public List<Segment> GuardLines
        {
            get { return guardLines; }
        }

        public List<Segment> BorderLines
        {
            get { return borderLines; }
        }

        public List<GuardConvex> Convexs
        {
            get { return convexs; }
        }

        public NavigateMap ( EyeableBorderObjInfo[] objInfos, Rectanglef mapBorder, float spaceForTank )
        {
            BuildMap( objInfos, mapBorder, spaceForTank );
        }

        public void BuildMap ( EyeableBorderObjInfo[] objInfos, Rectanglef mapBorder, float spaceForTank )
        {

            #region 对每一个BorderObj生成逻辑坐标上的凸包点集，并向外扩展

            borderLines = new List<Segment>();

            convexs = new List<GuardConvex>();
            foreach (EyeableBorderObjInfo obj in objInfos)
            {
                if (obj.ConvexHall == null || obj.IsDisappeared || obj.ConvexHall.Points == null)
                    continue;

                Matrix matrix = obj.EyeableInfo.CurTransMatrix;

                GraphPoint<NaviPoint>[] convexHall;

                List<VisiBordPoint> bordPoints = obj.ConvexHall.Points;
                if (bordPoints.Count > 2)
                {
                    List<GraphPoint<NaviPoint>> list = new List<GraphPoint<NaviPoint>>();
                    for (int i = 0; i < bordPoints.Count; i++)
                    {
                        Vector2 lastPos = Vector2.Transform( ConvertHelper.PointToVector2( bordPoints[i - 1 < 0 ? bordPoints.Count - 1 : i - 1].p ), matrix );
                        Vector2 curPos = Vector2.Transform( ConvertHelper.PointToVector2( bordPoints[i].p ), matrix );
                        Vector2 nextPos = Vector2.Transform( ConvertHelper.PointToVector2( bordPoints[(i + 1) % bordPoints.Count].p ), matrix );

                        Vector2 v1 = curPos - lastPos;
                        Vector2 v2 = curPos - nextPos;
                        float ang = MathTools.AngBetweenVectors( v1, v2 );
                        if (ang >= MathHelper.PiOver2)
                        {
                            float halfDes = (float)(spaceForTank / Math.Sin( ang ));
                            Vector2 delta = halfDes * Vector2.Normalize( v1 ) + halfDes * Vector2.Normalize( v2 );
                            list.Add( new GraphPoint<NaviPoint>(
                                new NaviPoint( obj, bordPoints[i].index, curPos + delta ), new List<GraphPath<NaviPoint>>() ) );
                        }
                        else
                        {
                            v1.Normalize();
                            v2.Normalize();
                            Vector2 cenV = Vector2.Normalize( v1 + v2 );
                            Vector2 vertiV = new Vector2( cenV.Y, -cenV.X );
                            float ang2 = MathHelper.PiOver4 - 0.25f * ang;
                            float vertiL = (float)(spaceForTank * Math.Tan( ang2 ));

                            list.Add( new GraphPoint<NaviPoint>(
                                new NaviPoint( obj, bordPoints[i].index, curPos + spaceForTank * cenV + vertiL * vertiV ),
                                new List<GraphPath<NaviPoint>>() ) );
                            list.Add( new GraphPoint<NaviPoint>(
                                new NaviPoint( obj, bordPoints[i].index, curPos + spaceForTank * cenV - vertiL * vertiV ),
                                new List<GraphPath<NaviPoint>>() ) );
                        }

                        // 添加borderLine
                        borderLines.Add( new Segment( curPos, nextPos ) );
                    }
                    convexHall = list.ToArray();
                    convexs.Add( new GuardConvex( convexHall ) );
                }
                else if (bordPoints.Count == 2)
                {
                    convexHall = new GraphPoint<NaviPoint>[4];
                    Vector2 startPos = Vector2.Transform( ConvertHelper.PointToVector2( bordPoints[0].p ), matrix );
                    Vector2 endPos = Vector2.Transform( ConvertHelper.PointToVector2( bordPoints[1].p ), matrix );
                    Vector2 dir = endPos - startPos;
                    dir.Normalize();
                    Vector2 normal = new Vector2( dir.Y, -dir.X );
                    convexHall[0] = new GraphPoint<NaviPoint>(
                        new NaviPoint( obj, bordPoints[0].index, startPos - dir * spaceForTank ), new List<GraphPath<NaviPoint>>() );
                    convexHall[1] = new GraphPoint<NaviPoint>(
                        new NaviPoint( obj, bordPoints[0].index, startPos + spaceForTank * normal ), new List<GraphPath<NaviPoint>>() );
                    convexHall[2] = new GraphPoint<NaviPoint>(
                        new NaviPoint( obj, bordPoints[1].index, endPos + spaceForTank * normal ), new List<GraphPath<NaviPoint>>() );
                    convexHall[3] = new GraphPoint<NaviPoint>(
                        new NaviPoint( obj, bordPoints[1].index, endPos + dir * spaceForTank ), new List<GraphPath<NaviPoint>>() );

                    //if (float.IsNaN( convexHall[0].value.Pos.X ) || float.IsNaN( convexHall[1].value.Pos.X ))
                    //{

                    //}

                    // 添加borderLine
                    borderLines.Add( new Segment( startPos, endPos ) );

                    convexs.Add( new GuardConvex( convexHall ) );
                }

            }

            #endregion

            #region 得到警戒线

            guardLines = new List<Segment>();

            foreach (GuardConvex convex in convexs)
            {
                for (int i = 0; i < convex.points.Length; i++)
                {
                    guardLines.Add( new Segment( convex[i].value.Pos, convex[(i + 1) % convex.Length].value.Pos ) );

                    //if (float.IsNaN( convex[i].value.Pos.X ))
                    //{

                    //}
                }
            }

            mapBorder = new Rectanglef( mapBorder.X + spaceForTank, mapBorder.Y + spaceForTank,
                mapBorder.Width - 2 * spaceForTank, mapBorder.Height - 2 * spaceForTank );

            guardLines.Add( new Segment( mapBorder.UpLeft, mapBorder.UpRight ) );
            guardLines.Add( new Segment( mapBorder.UpRight, mapBorder.DownRight ) );
            guardLines.Add( new Segment( mapBorder.DownRight, mapBorder.DownLeft ) );
            guardLines.Add( new Segment( mapBorder.DownLeft, mapBorder.UpLeft ) );

            #endregion

            #region 检查凸包内部连线是否和警戒线相交,如不相交则连接该连线并计算权值

            foreach (GuardConvex convex in convexs)
            {
                for (int i = 0; i < convex.Length; i++)
                {
                    // 检查连线是否超出边界
                    if (!mapBorder.Contains( convex[i].value.Pos ))
                        continue;

                    Segment link = new Segment( convex[i].value.Pos, convex[(i + 1) % convex.Length].value.Pos );


                    bool isCross = false;
                    foreach (Segment guardLine in guardLines)
                    {
                        if (link.Equals( guardLine ))
                            continue;

                        if (Segment.IsCross( link, guardLine ))
                        {
                            isCross = true;
                            break;
                        }
                    }

                    if (!isCross)
                    {
                        float weight = Vector2.Distance( convex[i].value.Pos, convex[(i + 1) % convex.Length].value.Pos );
                        //if (float.IsNaN( weight ))
                        //{

                        //}
                        GraphPoint<NaviPoint>.Link( convex[i], convex[(i + 1) % convex.Length], weight );
                    }
                }
            }

            #endregion

            #region 检查凸包之间连线是否与警戒线以及边界线相交，如不相交则连接并计算权值

            for (int i = 0; i < convexs.Count - 1; i++)
            {
                for (int j = i + 1; j < convexs.Count; j++)
                {
                    foreach (GraphPoint<NaviPoint> p1 in convexs[i].points)
                    {
                        // 检查连线是否超出边界
                        if (!mapBorder.Contains( p1.value.Pos ))
                            continue;

                        foreach (GraphPoint<NaviPoint> p2 in convexs[j].points)
                        {
                            Segment link = new Segment( p1.value.Pos, p2.value.Pos );

                            bool isCross = false;
                            foreach (Segment guardLine in guardLines)
                            {
                                if (Segment.IsCross( link, guardLine ))
                                {
                                    isCross = true;
                                    break;
                                }
                            }
                            if (!isCross)
                            {
                                foreach (Segment borderLine in borderLines)
                                {
                                    if (Segment.IsCross( link, borderLine ))
                                    {
                                        isCross = true;
                                        break;
                                    }
                                }
                            }

                            if (!isCross)
                            {
                                float weight = Vector2.Distance( p1.value.Pos, p2.value.Pos );
                                //if (float.IsNaN( weight ))
                                //{

                                //}
                                GraphPoint<NaviPoint>.Link( p1, p2, weight );
                            }
                        }
                    }
                }
            }

            #endregion

            #region 整理导航图

            List<GraphPoint<NaviPoint>> points = new List<GraphPoint<NaviPoint>>();

            foreach (GuardConvex convex in convexs)
            {
                foreach (GraphPoint<NaviPoint> p in convex.points)
                {
                    points.Add( p );
                }
            }

            naviGraph = points.ToArray();

            #endregion
        }

        /// <summary>
        /// 检查点是否在生成的警戒线凸包之中
        /// </summary>
        /// <param name="p">要检查的点</param>
        /// <param name="convex">如果点处于某个凸包之中，返回这个凸包，否则为null</param>
        /// <returns></returns>
        public bool PointInConvexs ( Vector2 p, out GuardConvex convex )
        {
            foreach (GuardConvex conve in convexs)
            {
                if (conve.PointInConvex( p ))
                {
                    convex = conve;
                    return true;
                }
            }
            convex = null;
            return false;
        }

        /// <summary>
        /// 检查点是否在生成的警戒线凸包之中
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public bool PointInConvexs ( Vector2 p )
        {
            GuardConvex temp;
            return PointInConvexs( p, out temp );
        }

        #region 使用A*算法计算路径

        class NodeAStar
        {
            public GraphPoint<NaviPoint> point;
            public NodeAStar father;

            public float G;
            public float H;
            public float F;

            public NodeAStar ( GraphPoint<NaviPoint> point, NodeAStar father )
            {
                this.point = point;
                this.father = father;
                this.G = 0;
                this.H = 0;
                this.F = 0;
            }
        }

        /// <summary>
        /// 使用A*算法依据当前信息计算一条最短的路径。
        /// 注意，如果目标点在警戒线以内，会返回一条并非如你期望的路径。
        /// 所以请自行实现目标点无法到达时的处理逻辑。
        /// </summary>
        /// <param name="curPos"></param>
        /// <param name="aimPos"></param>
        /// <returns></returns>
        public NaviPoint[] CalPathUseAStar ( Vector2 curPos, Vector2 aimPos )
        {

            #region 复制导航图
            GraphPoint<NaviPoint>[] map = new GraphPoint<NaviPoint>[Map.Length + 2];
            GraphPoint<NaviPoint>[] temp = GraphPoint<NaviPoint>.DepthCopy( Map );
            for (int i = 0; i < temp.Length; i++)
            {
                map[i] = temp[i];
            }
            #endregion

            #region 将当前点和目标点加入到导航图中
            int prePointSum = temp.Length;
            GraphPoint<NaviPoint> curNaviPoint = new GraphPoint<NaviPoint>( new NaviPoint( null, -1, curPos ), new List<GraphPath<NaviPoint>>() );
            GraphPoint<NaviPoint> aimNaviPoint = new GraphPoint<NaviPoint>( new NaviPoint( null, -1, aimPos ), new List<GraphPath<NaviPoint>>() );
            AddCurPosToNaviMap( map, curNaviPoint, prePointSum, GuardLines, BorderLines );
            AddAimPosToNaviMap( map, aimNaviPoint, curNaviPoint, prePointSum, GuardLines, BorderLines );

            #endregion

            #region 计算最短路径，使用A*算法

            List<NodeAStar> open = new List<NodeAStar>();
            List<NodeAStar> close = new List<NodeAStar>();
            open.Add( new NodeAStar( curNaviPoint, null ) );

            NodeAStar cur = null;
            while (open.Count != 0)
            {
                cur = open[open.Count - 1];

                if (cur.point == aimNaviPoint)
                    break;

                open.RemoveAt( open.Count - 1 );
                close.Add( cur );

                foreach (GraphPath<NaviPoint> path in cur.point.neighbors)
                {
                    if (Contains( close, path.neighbor ))
                    {
                        continue;
                    }
                    else
                    {
                        NodeAStar inOpenNode;
                        if (Contains( open, path.neighbor, out inOpenNode ))
                        {
                            float G = cur.G + path.weight;
                            if (inOpenNode.G > G)
                            {
                                inOpenNode.G = G;
                                inOpenNode.F = G + inOpenNode.H;
                            }
                        }
                        else
                        {
                            NodeAStar childNode = new NodeAStar( path.neighbor, cur );
                            childNode.G = cur.G + path.weight;
                            childNode.H = Vector2.Distance( aimPos, childNode.point.value.Pos );
                            childNode.F = childNode.G + childNode.H;
                            SortInsert( open, childNode );
                        }
                    }
                }
            }

            //if (cur == null)
            //    return null;

            Stack<NodeAStar> cahe = new Stack<NodeAStar>();
            while (cur.father != null)
            {
                cahe.Push( cur );
                cur = cur.father;
            }

            NaviPoint[] result = new NaviPoint[cahe.Count];

            int j = 0;
            foreach (NodeAStar node in cahe)
            {
                result[j] = node.point.value;
                j++;
            }

            return result;

            #endregion
        }

        private void SortInsert ( List<NodeAStar> open, NodeAStar childNode )
        {
            int i = 0;
            while (i < open.Count && open[i].F > childNode.F)
            {
                i++;
            }
            if (i == open.Count)
                open.Add( childNode );
            else
                open.Insert( i, childNode );
        }

        private bool Contains ( List<NodeAStar> list, GraphPoint<NaviPoint> graphPoint, out NodeAStar findNode )
        {
            if ((findNode = list.Find( new Predicate<NodeAStar>(
                delegate( NodeAStar node )
                {
                    if (node.point == graphPoint)
                        return true;
                    else
                        return false;
                } ) )) == null)
                return false;
            else
                return true;
        }

        private bool Contains ( List<NodeAStar> list, GraphPoint<NaviPoint> graphPoint )
        {
            if (list.Find( new Predicate<NodeAStar>(
                delegate( NodeAStar node )
                {
                    if (node.point == graphPoint)
                        return true;
                    else
                        return false;
                } ) ) == null)
                return false;
            else
                return true;
        }

        private void AddCurPosToNaviMap ( GraphPoint<NaviPoint>[] map, GraphPoint<NaviPoint> curNaviP,
            int prePointSum, List<Segment> guardLines, List<Segment> borderLines )
        {
            map[prePointSum] = curNaviP;
            for (int i = 0; i < prePointSum; i++)
            {
                Segment seg = new Segment( curNaviP.value.Pos, map[i].value.Pos );

                bool cross = false;
                foreach (Segment guardLine in guardLines)
                {
                    if (Segment.IsCross( guardLine, seg ))
                    {
                        cross = true;
                        break;
                    }
                }

                if (!cross)
                {
                    foreach (Segment borderLine in borderLines)
                    {
                        if (Segment.IsCross( borderLine, seg ))
                        {
                            cross = true;
                            break;
                        }

                    }
                }

                if (!cross)
                {
                    float weight = Vector2.Distance( curNaviP.value.Pos, map[i].value.Pos );
                    GraphPoint<NaviPoint>.Link( map[i], curNaviP, weight );
                }
            }
        }

        private void AddAimPosToNaviMap ( GraphPoint<NaviPoint>[] map, GraphPoint<NaviPoint> aimNaviP, GraphPoint<NaviPoint> curNaviP,
            int prePointSum, List<Segment> guardLines, List<Segment> borderLines )
        {
            map[prePointSum + 1] = aimNaviP;
            for (int i = 0; i < prePointSum; i++)
            {
                Segment seg = new Segment( aimNaviP.value.Pos, map[i].value.Pos );

                bool cross = false;
                foreach (Segment guardLine in guardLines)
                {
                    if (Segment.IsCross( guardLine, seg ))
                    {
                        cross = true;
                        break;
                    }
                }

                if (!cross)
                {
                    foreach (Segment borderLine in borderLines)
                    {
                        if (Segment.IsCross( borderLine, seg ))
                        {
                            cross = true;
                            break;
                        }

                    }
                }

                if (!cross)
                {
                    float weight = Vector2.Distance( aimNaviP.value.Pos, map[i].value.Pos );
                    GraphPoint<NaviPoint>.Link( map[i], aimNaviP, weight );
                }
            }

            Segment curToAim = new Segment( curNaviP.value.Pos, aimNaviP.value.Pos );

            bool link = true;
            foreach (Segment guardLine in guardLines)
            {
                if (Segment.IsCross( guardLine, curToAim ))
                {
                    if (MathTools.Vector2Cross( guardLine.endPoint - guardLine.startPoint, curNaviP.value.Pos - guardLine.endPoint ) < 0)
                    {
                        link = false;
                        break;
                    }
                }
            }

            if (link)
            {
                foreach (Segment borderLine in borderLines)
                {
                    if (Segment.IsCross( borderLine, curToAim ))
                    {
                        link = false;
                        break;
                    }

                }
            }

            if (link)
            {
                float weight = Vector2.Distance( curNaviP.value.Pos, aimNaviP.value.Pos );
                GraphPoint<NaviPoint>.Link( curNaviP, aimNaviP, weight );
            }
        } 

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.GameObjs;
using TankEngine2D.DataStructure;

namespace SmartTank.Draw
{
    /*
     * 实现了场景物体的跟踪。
     * 
     * 视域的缩放动画等效果。
     * 
     * 
     * */
    public class Camera 
    {
        static Camera curCamera;
        static public event EventHandler onCameraScaled;

        static public Camera CurCamera
        {
            get
            {
                return curCamera;
            }
        }

        const float defaultMinScale = 0.8f;
        const float defaultMaxScale = 6f;

        float scale;
        Vector2 centerPos;

        bool enabled = false;

        IGameObj focusObj;
        bool focusing = false;
        bool focusAzi = false;

        public float minScale = defaultMinScale;
        public float maxScale = defaultMaxScale;

        float rota;

        //public Rectanglef LogicViewRect
        //{
        //    get
        //    {
        //        return Coordin.LogicRect;
        //    }
        //}


        public Vector2 CenterPos
        {
            get { return centerPos; }
            set
            {
                centerPos = value;
                SubmitChange();
            }
        }

        public float Scale
        {
            get { return scale; }
            set
            {
                scale = value;
                scale = Math.Min( Math.Max( minScale, scale ), maxScale );
                if (curCamera == this && onCameraScaled != null)
                    onCameraScaled( this, EventArgs.Empty );
                SubmitChange();
            }
        }

        public float Azi
        {
            get { return rota; }
            set
            {
                rota = value;
                SubmitChange();
            }
        }

        public Camera ( float scale, Vector2 centerPos, float rota )
        {
            this.scale = scale;
            this.centerPos = centerPos;
            this.rota = rota;
        }

        public void Enable ()
        {
            if (curCamera != null)
                curCamera.Disable();
            curCamera = this;
            enabled = true;
            SubmitChange();
        }

        private void SubmitChange ()
        {
            BaseGame.CoordinMgr.SetCamera( scale, centerPos, rota );
        }

        public void Disable ()
        {
            enabled = false;
        }

        public void Move ( Vector2 deltaVector )
        {
            centerPos += Vector2.Transform( deltaVector, BaseGame.CoordinMgr.RotaMatrixFromScrnToLogic );
            SubmitChange();
        }

        /// <summary>
        /// 缩放镜头
        /// </summary>
        /// <param name="rate">正数表示放大百分比，负数表示缩小百分比</param>
        public void Zoom ( float rate )
        {
            scale *= (1 + rate);
            scale = Math.Min( Math.Max( minScale, scale ), maxScale );
            SubmitChange();
            if (curCamera == this && onCameraScaled != null)
                onCameraScaled( this, EventArgs.Empty );
        }

        /// <summary>
        /// 旋转镜头
        /// </summary>
        /// <param name="ang"></param>
        public void Rota ( float ang )
        {
            rota += ang;
            SubmitChange();
        }

        public void Focus ( IGameObj obj, bool focusAzi )
        {
            focusing = true;
            focusObj = obj;
            this.focusAzi = focusAzi;
        }

        public void FocusCancel ()
        {
            focusing = false;
        }

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            if (!enabled)
                return;

            if (focusing)
            {
                centerPos = centerPos * 0.95f + focusObj.Pos * 0.05f;
                if (focusAzi)
                    rota = rota * 0.95f + focusObj.Azi * 0.05f;
                SubmitChange();
            }

        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Rule;
using SmartTank.Screens;
using SmartTank.net;
using SmartTank.GameObjs;
using SmartTank.PhiCol;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TankEngine2D.Graphics;
using SmartTank;
using SmartTank.Draw;
using TankEngine2D.Helpers;
using TankEngine2D.Input;
using Microsoft.Xna.Framework.Input;
using SmartTank.Scene;
using System.IO;
using SmartTank.Helpers;
using SmartTank.GameObjs.Shell;
using TankEngine2D.DataStructure;
using SmartTank.Effects.SceneEffects;
using SmartTank.Effects;
using SmartTank.Sounds;
using SmartTank.Draw.UI.Controls;
using System.Runtime.InteropServices;

namespace InterRules.Starwar
{
    class Rank : IGameScreen
    {
        [StructLayoutAttribute(LayoutKind.Sequential, Size = 32, CharSet = CharSet.Ansi, Pack = 1)]
        struct RankInfo
        {
            public const int size = 32;

            public int rank;
            public int score;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
            public char[] name;
        }

        [StructLayoutAttribute(LayoutKind.Sequential, Size = 56, CharSet = CharSet.Ansi, Pack = 1)]
        struct UserInfo
        {
            public const int size = 56;

            public int state;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)]
            public char[] name;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 23)]
            public char[] pass;
            public int score;
            public int rank;
        }

        struct RankIF
        { 
            public int rank;
            public string name;
            public int score;
        }
        RankIF myInfo;
        Texture2D bgTexture, rkTexture, piTexture, hdTexture;
        List<string> devHeads;

        Rectangle bgRect;

        SpriteBatch spriteBatch;

        Listbox roomList;
        Listbox rankList;

        Byte[] rankBuffer = new byte[400];

        TextButton btnOK;

        List<RankIF> rankItems;
        Vector2 rankPos;

        bool bOK, bLoaded;

        int selectIndexRank = -1;
        int selectIndexRoom = -1;


        public Rank()
        {
            devHeads = new List<string>();
            devHeads.Add("asokawu");
            devHeads.Add("ddli");
            devHeads.Add("jehutyhu");
            devHeads.Add("zashchen");
            devHeads.Add("orrischen");
            devHeads.Add("johntan");
            devHeads.Add("seekyao");
            
            BaseGame.ShowMouse = true;


            rankPos = new Vector2(50, 120);

            roomList = new Listbox("roomlist", new Vector2(550, 120), new Point(200, 150), Color.White, Color.Black);
            rankList = new Listbox("ranklist", rankPos, new Point(450, 350), Color.White, Color.Green);
            bgTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.BgContent, "bg"));
            rkTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.UIContent, "ranklist"));
            piTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.UIContent, "yourinfo"));
            bgRect = new Rectangle(0, 0, 800, 600);
            btnOK = new TextButton("OKBtn", new Vector2(550, 370), "OK", 0, Color.Gold);
            btnOK.OnClick += new EventHandler(btnOK_OnPress);
            rankList.OnChangeSelection += new EventHandler(rankList_OnChangeSelection);
            roomList.OnChangeSelection += new EventHandler(roomList_OnChangeSelection);
            SocketMgr.OnReceivePkg += new SocketMgr.ReceivePkgEventHandler(OnReceivePack);



            stPkgHead head = new stPkgHead();
            //head.iSytle = //包头类型还没初始化
            byte[] rankcode = new byte[4];
            rankcode[0] = 1;
            rankcode[1] = 0;
            rankcode[2] = 0;
            rankcode[3] = 0;

            MemoryStream Stream = new MemoryStream();
            Stream.Write(rankcode, 0, 4);
            head.dataSize = 4;
            head.iSytle = 50;
            SocketMgr.SendCommonPackge(head, Stream);
            Stream.Close();


            stPkgHead head2 = new stPkgHead();
            MemoryStream Stream2 = new MemoryStream();
            head2.dataSize = 0;
            head2.iSytle = 40;
            SocketMgr.SendCommonPackge(head2, Stream2);
            Stream2.Close();

            head = new stPkgHead();
            //head.iSytle = //包头类型还没初始化
            rankcode = new byte[4];
            rankcode[0] = 1;
            rankcode[1] = 0;
            rankcode[2] = 0;
            rankcode[3] = 0;

            Stream = new MemoryStream();
            Stream.Write(rankcode, 0, 4);
            head.dataSize = 4;
            head.iSytle = 50;
            SocketMgr.SendCommonPackge(head, Stream);
            Stream.Close();

            bOK = false;
            rankItems = new List<RankIF>();
            bLoaded = false;
            // 连接到服务器
            //SocketMgr.ConnectToServer();
        }
        
        void OnReceivePack(stPkgHead head, byte[] data)
        {
            byte[] tmpData;

            tmpData = new Byte[head.dataSize];
            
            if (head.iSytle == 50)
            {
                RankInfo ri;
                RankIF tmpItem;
                string str;
                rankItems.Clear();



                for (int i = 0; i < head.dataSize; i += 32)
                {
                    str = "";
                    for (int k = 0; k < 32; k++)
                    {
                        tmpData[k] = data[i + k];
                    }
                    ri = (RankInfo)SocketMgr.BytesToStuct(tmpData, typeof(RankInfo));
                    for (int j = 0; ri.name[j] != '\0'; ++j)
                    {
                        str += ri.name[j];
                    }
                    tmpItem.rank = ri.rank;
                    tmpItem.score = ri.score;
                    tmpItem.name = str;
                    rankItems.Add(tmpItem);

                }
            }
            else if (head.iSytle == 40)
            {
                
                UserInfo player;
                string str;
                str = "";
                //data.Read(roomBuffer, 0, 32);

                player = (UserInfo)SocketMgr.BytesToStuct(data, typeof(UserInfo));

                for (int j = 0; player.name[j] != '\0'; ++j)
                {
                    str += player.name[j];
                }
                
                myInfo.name = str;
                myInfo.rank = player.rank;
                myInfo.score = player.score;

                if (devHeads.Contains(myInfo.name))
                    hdTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.UIContent, myInfo.name));
                else
                    hdTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.UIContent, "head"));
                bLoaded = true;
            }
        }
        
        void roomList_OnChangeSelection(object sender, EventArgs e)
        {
            selectIndexRoom = roomList.selectedIndex;
        }

        void rankList_OnChangeSelection(object sender, EventArgs e)
        {
            selectIndexRank = rankList.selectedIndex;
        }

        void btnOK_OnPress(object sender, EventArgs e)
        {
            bOK = true;
            SocketMgr.OnReceivePkg -= OnReceivePack;
        }

        #region IGameScreen 成员

        public bool Update(float second)
        {

            btnOK.Update();
            
            roomList.Update();

            if (InputHandler.IsKeyDown(Keys.Escape))
                return true;

            return bOK;

        }

        public void Render()
        {

            BaseGame.Device.Clear(Color.LightSkyBlue);
            spriteBatch = (SpriteBatch)BaseGame.SpriteMgr.alphaSprite;
            spriteBatch.Draw(bgTexture, Vector2.Zero, bgRect, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, LayerDepth.BackGround);
            spriteBatch.Draw(rkTexture, new Vector2(50, 102), new Rectangle(0, 0, 75, 18), Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0f);
            spriteBatch.Draw(piTexture, new Vector2(550, 102), new Rectangle(0, 0, 137, 18), Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0f);
            roomList.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            rankList.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            BaseGame.FontMgr.DrawInScrnCoord("Rank", rankPos + new Vector2(8f, 4f), Control.fontScale, Color.Black, 0f, Control.fontName);
            BaseGame.FontMgr.DrawInScrnCoord("Name", rankPos + new Vector2(100f, 4f), Control.fontScale, Color.Black, 0f, Control.fontName);
            BaseGame.FontMgr.DrawInScrnCoord("Score", rankPos + new Vector2(250f, 4f), Control.fontScale, Color.Black, 0f, Control.fontName);

            for (int i = 0; i < rankItems.Count; i++)
            {
                BaseGame.FontMgr.DrawInScrnCoord(rankItems[i].rank.ToString(), rankPos + new Vector2(10f, 20f + 15 * i), Control.fontScale, Color.Green, 0f, Control.fontName);
                BaseGame.FontMgr.DrawInScrnCoord(rankItems[i].name, rankPos + new Vector2(102f, 20f + 15 * i), Control.fontScale, Color.Green, 0f, Control.fontName);
                BaseGame.FontMgr.DrawInScrnCoord(rankItems[i].score.ToString(), rankPos + new Vector2(252f, 20f + 15 * i), Control.fontScale, Color.Green, 0f, Control.fontName);
            }
            if (bLoaded)
            {
                spriteBatch.Draw(hdTexture, new Vector2(560, 128), new Rectangle(0, 0, 70, 70), Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, LayerDepth.UI - 0.1f);
                BaseGame.FontMgr.DrawInScrnCoord("Name: " + myInfo.name, new Vector2(560, 200), Control.fontScale, Color.Black, 0f, Control.fontName);
                BaseGame.FontMgr.DrawInScrnCoord("Score: " + myInfo.score, new Vector2(560, 215), Control.fontScale, Color.Black, 0f, Control.fontName);
                BaseGame.FontMgr.DrawInScrnCoord("Rank:  " + myInfo.rank, new Vector2(560, 230), Control.fontScale, Color.Black, 0f, Control.fontName);
            }
            btnOK.Draw(BaseGame.SpriteMgr.alphaSprite, 1);




        }

        public void OnClose()
        {
            SocketMgr.OnReceivePkg -= OnReceivePack;
        }

        #endregion
    }





}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using GameEngine.Shelter;
using GameEngine.PhiCol;
using GameEngine.Senses.Vision;
using Common.DataStructure;

namespace GameEngine.Senses.Memory
{
    /// <summary>
    /// 如果要在生成导航图的时候考虑该物体，返回true，否则返回false。
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public delegate bool NaviMapConsiderObj ( EyeableBorderObjInfo obj );

    public class ObjMemoryKeeper
    {
        Dictionary<IHasBorderObj, EyeableBorderObjInfo> memoryObjs;

        //NavigateMap naviMap;

        public ObjMemoryKeeper ()
        {
            memoryObjs = new Dictionary<IHasBorderObj, EyeableBorderObjInfo>();
        }

        public EyeableBorderObjInfo[] GetEyeableBorderObjInfos ()
        {
            EyeableBorderObjInfo[] result = new EyeableBorderObjInfo[memoryObjs.Values.Count];
            memoryObjs.Values.CopyTo( result, 0 );
            return result;
        }

        public NavigateMap CalNavigationMap ( NaviMapConsiderObj selectFun, Rectanglef mapBorder, float spaceForTank )
        {
            List<EyeableBorderObjInfo> eyeableInfos = new List<EyeableBorderObjInfo>();

            foreach (KeyValuePair<IHasBorderObj, EyeableBorderObjInfo> pair in memoryObjs)
            {
                if (selectFun( pair.Value ))
                {
                    eyeableInfos.Add( pair.Value );
                }
            }

            return new NavigateMap( eyeableInfos.ToArray(), mapBorder, spaceForTank );
        }

        //public NavigateMap NavigateMap
        //{
        //    get { return naviMap; }
        //}

        internal bool ApplyEyeableBorderObjInfo ( EyeableBorderObjInfo objInfo )
        {
            bool objUpdated = false;
            if (memoryObjs.ContainsKey( objInfo.Obj ))
            {
                if (memoryObjs[objInfo.Obj].Combine( objInfo ))
                    objUpdated = true;
            }
            else
            {
                memoryObjs.Add( objInfo.Obj, objInfo );
                objUpdated = true;
            }

            return objUpdated;
        }

        internal Dictionary<IHasBorderObj, EyeableBorderObjInfo> MemoryObjs
        {
            get { return memoryObjs; }
        }

        internal void HandlerObjDisappear ( List<IHasBorderObj> disappearObjs )
        {
            foreach (IHasBorderObj obj in disappearObjs)
            {
                memoryObjs[obj].SetIsDisappeared( true );
            }
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using SmartTank.GameObjs;

namespace SmartTank.net
{
    /* 场景物体更新同步包缓冲区
     * 包括场景物体的状态更新信息
     * 场景物体的事件通知
     * 场景物体的创建与删除信息（只有主机发送）
     * */
    struct ObjStatusSyncInfo
    {
        public string objMgPath;
        public string statusName;
        public object[] values;
    };

    struct ObjEventSyncInfo
    {
        public string objMgPath;
        public string EventName;
        public object[] values;
    };

    struct ObjMgSyncInfo
    {
        public string objPath;
        public string objType;
        public int objMgKind;
        public object[] args;
    };

    struct UserDefineInfo
    {
        public string infoName;
        public string infoID;
        public object[] args;
    }

    struct GameObjSyncInfo
    {
        public string MgPath;

        public GameObjSyncInfo(string mgPath)
        {
            this.MgPath = mgPath;
        }
    };


    public class SyncCashe
    {
        List<ObjStatusSyncInfo> objStaInfoList = new List<ObjStatusSyncInfo>();
        List<ObjEventSyncInfo> objEventInfoList = new List<ObjEventSyncInfo>();
        List<ObjMgSyncInfo> objMgInfoList = new List<ObjMgSyncInfo>();
        List<UserDefineInfo> userDefineInfoList = new List<UserDefineInfo>();
        internal List<ObjStatusSyncInfo> ObjStaInfoList
        {
            get { return objStaInfoList; }
        }
        internal List<ObjEventSyncInfo> ObjEventInfoList
        {
            get { return objEventInfoList; }
        }
        internal List<ObjMgSyncInfo> ObjMgInfoList
        {
            get { return objMgInfoList; }
        }
        internal List<UserDefineInfo> UserDefineInfoList
        {
            get { return userDefineInfoList; }
        }

        public bool IsCasheEmpty
        {
            get
            {
                return objStaInfoList.Count == 0
                    && objEventInfoList.Count == 0
                    && objMgInfoList.Count == 0
                    && userDefineInfoList.Count == 0;
            }
        }

        internal void AddObjStatusSyncInfo(string objMgPath, string statueName, object[] values)
        {
            ObjStatusSyncInfo newStatus;
            newStatus.objMgPath = objMgPath;
            newStatus.statusName = statueName;
            newStatus.values = values;
            objStaInfoList.Add(newStatus);
        }

        internal void AddObjEventSyncInfo(string objMgPath, string EventName, object[] values)
        {
            ObjEventSyncInfo newEvent;
            newEvent.objMgPath = objMgPath;
            newEvent.EventName = EventName;
            newEvent.values = ConvertObjArg(values);
            objEventInfoList.Add(newEvent);
        }

        internal void AddObjMgCreateSyncInfo(string objPath, Type objType, object[] args)
        {
            ObjMgSyncInfo newObjMg;
            newObjMg.objPath = objPath;
            newObjMg.objType = objType.ToString();
            newObjMg.objMgKind = (int)ObjMgKind.Create;

            object[] newparams = ConvertObjArg(args);

            newObjMg.args = newparams;
            objMgInfoList.Add(newObjMg);
        }



        internal void AddObjMgDeleteSyncInfo(string objPath)
        {
            ObjMgSyncInfo newObjMg;
            newObjMg.objPath = objPath;
            newObjMg.objMgKind = (int)ObjMgKind.Delete;
            newObjMg.objType = null;
            newObjMg.args = new object[0];
            objMgInfoList.Add(newObjMg);
        }

        internal void AddUserDefineInfo(string infoName, string infoID, params object[] args)
        {
            UserDefineInfo info;
            info.infoName = infoName;
            info.infoID = infoID;
            info.args = ConvertObjArg(args);
            userDefineInfoList.Add(info);
        }

        internal void SendPackage()
        {
            if (!IsCasheEmpty)
            {
                SocketMgr.SendGameLogicPackge(this);
                ClearAllList();
            }
        }

        private void ClearAllList()
        {
            objStaInfoList.Clear();
            objEventInfoList.Clear();
            objMgInfoList.Clear();
            userDefineInfoList.Clear();
        }


        private static object[] ConvertObjArg(object[] args)
        {
            object[] newparams = new object[args.Length];

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] is IGameObj)
                {
                    newparams[i] = new GameObjSyncInfo(((IGameObj)args[i]).MgPath);
                }
                else
                {
                    newparams[i] = args[i];
                }

            }
            return newparams;
        }





    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using TankEngine2D.DataStructure;

namespace SmartTank.AI
{
    public class AICommonServer : IAICommonServer
    {
        Rectanglef mapBorder;

        public AICommonServer ( Rectanglef mapBorder )
        {
            this.mapBorder = mapBorder;
        }

        #region IAICommonServer ³ΙΤ±

        public Rectanglef MapBorder
        {
            get { return mapBorder; }
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.GameObjs;
using SmartTank.PhiCol;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework;
using SmartTank.GameObjs.Item;
using SmartTank;
using SmartTank.Helpers;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.Draw;

namespace InterRules.Starwar
{
    class Gold : ItemStatic
    {
        public delegate void GoldLiveTimeOutEventHandler(Gold sender);
        public event GoldLiveTimeOutEventHandler OnLiveTimeOut;

        AnimatedSpriteSeries animate;
        float liveTimer = 0;

        public Gold(string name, Vector2 pos, float azi)
        {
            this.name = name;
            this.objInfo = new GameObjInfo("Gold", "");
            this.pos = pos;
            this.azi = azi;

            LoadResource(pos, azi);
            SetCollidSprite();
        }

        private void SetCollidSprite()
        {
            this.sprite = new Sprite(BaseGame.RenderEngine, Path.Combine(Directories.ContentDirectory, "Rules\\SpaceWar\\image\\field_coin_001.png"), true);
            sprite.SetParameters(new Vector2(32, 32), pos, 1, 0, Color.White, LayerDepth.GroundObj, SpriteBlendMode.AlphaBlend);
            this.colMethod = new SpriteColMethod(new Sprite[] { sprite });
        }

        private void LoadResource(Vector2 pos, float azi)
        {
            animate = new AnimatedSpriteSeries(BaseGame.RenderEngine);
            animate.LoadSeriesFromFiles(BaseGame.RenderEngine, Path.Combine(Directories.ContentDirectory, "Rules\\SpaceWar\\image"), "field_coin_00", ".png", 1, 5, false);
            animate.SetSpritesParameters(new Vector2(32, 32), pos, 1, azi, Color.White, LayerDepth.GroundObj, SpriteBlendMode.AlphaBlend);
            GameManager.AnimatedMgr.Add(animate);
            animate.Interval = 10;
            animate.Start();

        }

        public void Dead()
        {
            animate.Stop();
        }

        public override void Update(float seconds)
        {
            liveTimer += seconds;
            if (liveTimer > SpaceWarConfig.GoldLiveTime)
            {
                if (OnLiveTimeOut != null)
                    OnLiveTimeOut(this);
                liveTimer = 0;
            }
        }

        public override void Draw()
        {

        }

        internal void Born(Vector2 pos)
        {
            this.pos = pos;
            animate.SetSpritesParameters(new Vector2(32, 32), pos, 1, azi, Color.White, LayerDepth.GroundObj, SpriteBlendMode.AlphaBlend);
            sprite.Pos = pos;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.IO;
using SmartTank.PhiCol;
using SmartTank.Shelter;
using SmartTank.Senses.Vision;
using TankEngine2D.Graphics;
using TankEngine2D.DataStructure;
using SmartTank.Draw;

namespace SmartTank.GameObjs.Item
{
    public class ItemCommon : IGameObj, IPhisicalObj, ICollideObj, IShelterObj, IEyeableObj
    {
        #region Variables

        public event OnCollidedEventHandler OnCollided;
        public event OnCollidedEventHandler OnOverlap;

        string name;

        GameObjInfo objInfo;

        NonInertiasColUpdater phiUpdater;

        Sprite sprite;

        Vector2[] keyPoints;

        public string Name
        {
            get { return name; }
        }

        public float Scale
        {
            get { return sprite.Scale; }
            set { sprite.Scale = value; }
        }

        public Vector2 Vel
        {
            get { return phiUpdater.Vel; }
            set { phiUpdater.Vel = value; }
        }

        public Vector2 Pos
        {
            get { return phiUpdater.Pos; }
            set { phiUpdater.Pos = value; }
        }

        public float Azi
        {
            get { return phiUpdater.Azi; }
            set { phiUpdater.Azi = value; }
        }



        #endregion

        public ItemCommon( string name, string objClass, string script,
            string texPath, Vector2 texOrigin, float scale, Vector2[] keyPoints,
            Vector2 pos, float azi, Vector2 vel, float rotaVel )
        {
            this.name = name;
            objInfo = new GameObjInfo( objClass, script );
            sprite = new Sprite( BaseGame.RenderEngine, texPath, true );
            sprite.SetParameters( texOrigin, pos, scale, azi, Color.White, LayerDepth.GroundObj, SpriteBlendMode.AlphaBlend );
            sprite.UpdateTransformBounding();
            this.keyPoints = keyPoints;
            phiUpdater = new NonInertiasColUpdater( objInfo, pos, vel, azi, rotaVel, new Sprite[] { sprite } );

            phiUpdater.OnCollied += new OnCollidedEventHandler( phiUpdater_OnCollied );
            phiUpdater.OnOverlap += new OnCollidedEventHandler( phiUpdater_OnOverlap );
        }

        public ItemCommon( string name, string objClass, string script, string dataPath, GameObjData data, float scale, Vector2 pos, float azi, Vector2 vel, float rotaVel )
            : this( name, objClass, script, Path.Combine( dataPath, data.baseNode.texPaths[0] ),
            data.baseNode.structKeyPoints[0], scale, data.baseNode.visiKeyPoints.ToArray(),
            pos, azi, vel, rotaVel )
        {

        }

        public void LoadResource( TankEngine2D.RenderEngine renderEngine )
        {

        }

        void phiUpdater_OnOverlap( IGameObj sender, CollisionResult result, GameObjInfo objB )
        {
            if (OnOverlap != null)
                OnOverlap( this, result, objB );
        }

        void phiUpdater_OnCollied( IGameObj sender, CollisionResult result, GameObjInfo objB )
        {
            if (OnCollided != null)
                OnCollided( this, result, objB );
        }


        #region IGameObj 成员

        public GameObjInfo ObjInfo
        {
            get { return objInfo; }
        }

        #endregion

        #region IUpdater 成员

        public void Update( float seconds )
        {
            sprite.UpdateTransformBounding();
        }

        #endregion

        #region IDrawableObj 成员

        public void Draw()
        {
            sprite.Pos = phiUpdater.Pos;
            sprite.Rata = phiUpdater.Azi;
            sprite.Draw();
        }

        #endregion

        #region IPhisicalObj 成员

        public IPhisicalUpdater PhisicalUpdater
        {
            get { return phiUpdater; }
        }

        #endregion

        #region ICollideObj 成员


        public IColChecker ColChecker
        {
            get { return phiUpdater; }
        }

        #endregion

        #region IShelterObj 成员

        public CircleList<BorderPoint> BorderData
        {
            get { return sprite.BorderData; }
        }

        public Microsoft.Xna.Framework.Matrix WorldTrans
        {
            get { return sprite.Transform; }
        }

        public Rectanglef BoundingBox
        {
            get { return sprite.BoundRect; }
        }

        #endregion

        #region IEyeableObj 成员

        public Vector2[] KeyPoints
        {
            get { return keyPoints; }
        }

        public Matrix TransMatrix
        {
            get { return sprite.Transform; }
        }

        GetEyeableInfoHandler getEyeableInfoHandler;

        public GetEyeableInfoHandler GetEyeableInfoHandler
        {
            get
            {
                return getEyeableInfoHandler;
            }
            set
            {
                getEyeableInfoHandler = value;
            }
        }

        #endregion


        #region IGameObj 成员



        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using TankEngine2D.Helpers;

namespace TankEngine2D.DataStructure
{
    /*
     * 一个能够具有多重身份的链式容器。
     * 
     * 如果其中的元素继承于某个接口（或父类），就能获取该链表的一个可以以该接口（或父类）进行迭代的副本。
     * 
     * 当原链表中元素有所改动时，副本和原链表始终保持一致。
     * 
     * */

    /// <summary>
    /// 多重身份链表的节点
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [Serializable]
    [Obsolete]
    public class MultiLinkedListNode<T> where T : class
    {
        static readonly public MultiLinkedListNode<T> empty = new MultiLinkedListNode<T>();

        /// <summary>
        /// 空构造函数
        /// </summary>
        public MultiLinkedListNode ()
        {
        }
        /// <summary>
        /// 设置节点中的值
        /// </summary>
        /// <param name="value"></param>
        public MultiLinkedListNode ( T value )
        {
            this.value = value;
        }

        /// <summary>
        /// 节点的值
        /// </summary>
        public T value;

        /// <summary>
        /// 该节点的前一个节点
        /// </summary>
        public MultiLinkedListNode<T> pre;

        /// <summary>
        /// 该节点的后一个节点
        /// </summary>
        public MultiLinkedListNode<T> next;
    }

    /// <summary>
    /// 一个能够具有多重身份的链式容器。
    /// 如果其中的元素继承于某个接口（或父类），就能获取该链表的一个可以以该接口（或父类）进行迭代的副本。
    /// 当原链表中元素有所改动时，副本和原链表始终保持一致。
    /// 该容器同时保管一个Hash表。以使查找效率更高，但也使容器中不能有节点值相同的节点。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [Serializable]
    [Obsolete("由于设计的一些不合理之处，该数据结构废弃，请使用新的MultiList类提供相似功能")]
    public class MultiLinkedList<T> : IEnumerable<T> where T : class
    {
        #region Emunerator
        private class MultiLinkedListEnumerator : IEnumerator<T>
        {
            public MultiLinkedListNode<T> curNode;
            MultiLinkedListNode<T> first;

            int EnumeLength = 0;

            public MultiLinkedListEnumerator ( MultiLinkedList<T> list )
            {
                this.first = list.First;
                EnumeLength = list.length;
            }

            #region IEnumerator<T> 成员

            public T Current
            {
                get { return curNode != null ? curNode.value : null; }
            }

            #endregion

            #region IDisposable 成员

            public void Dispose ()
            {

            }

            #endregion

            #region IEnumerator 成员

            object IEnumerator.Current
            {
                get { return curNode; }
            }

            public bool MoveNext ()
            {
                if (--EnumeLength < 0) return false;

                if (curNode == null)
                {
                    curNode = first;
                    return true;
                }
                else if (curNode.next != null)
                {
                    curNode = curNode.next;
                    return true;
                }
                else
                    return false;
            }

            public void Reset ()
            {
                curNode = first;
            }

            #endregion
        }
        #endregion

        #region Variables

        MultiLinkedListNode<T> head;
        MultiLinkedListNode<T> last;
        int length;

        /// <summary>
        /// 为了使移除元素更高效而添加这个Hash表
        /// </summary>
        Dictionary<T, MultiLinkedListNode<T>> ValueNodeTable;

        #endregion

        #region Properties

        MultiLinkedListNode<T> First
        {
            get { return head.next; }
        }

        MultiLinkedListNode<T> Last
        {
            get { return last; }
        }

        #endregion

        #region Construction

        /// <summary>
        /// 构建一个空链表
        /// </summary>
        public MultiLinkedList ()
        {
            head = new MultiLinkedListNode<T>();
            last = head;
            ValueNodeTable = new Dictionary<T, MultiLinkedListNode<T>>();
        }

        #endregion

        #region Methods

        /// <summary>
        /// 在链表的末尾加入一个新的节点
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public bool AddLast ( MultiLinkedListNode<T> node )
        {
            try
            {
                ValueNodeTable.Add( node.value, node );
                length++;

                last.next = node;
                node.pre = last;
                last = node;
            }
            catch (ArgumentException)
            {
                Log.Write( "MultiLinkedList : AddLast : ArgumentException : 当前键已存在." );
                return false;
            }
            return true;
        }

        /// <summary>
        /// 在链表的末尾加入一个新的节点
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool AddLast ( T value )
        {

            MultiLinkedListNode<T> node = new MultiLinkedListNode<T>( value );
            return AddLast( node );
        }

        /// <summary>
        /// 移除链表中的节点
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public bool Remove ( MultiLinkedListNode<T> node )
        {
            if (node != null && node.pre != null)
            {
                node.pre.next = node.next;
                if (node.next != null)
                    node.next.pre = node.pre;
                if (last == node)
                    last = node.pre;
                ValueNodeTable.Remove( node.value );
                length--;
                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// 查找链表中是否含有值为value的节点，如果有，则删除该节点。若没有，在日志上记录。
        /// 查找过程使用Hash表。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Remove ( T value )
        {
            try
            {
                MultiLinkedListNode<T> node = ValueNodeTable[value];
                if (node != null)
                {
                    return Remove( node );
                }
            }
            catch (KeyNotFoundException)
            {
                Log.Write( "MultiLinkedList: Remove : keyNotFoundException" );
            }
            return false;
        }

        /// <summary>
        /// 对每个元素执行一次操作
        /// </summary>
        /// <param name="func"></param>
        public void ForEach ( ForEachFunc<T> func )
        {
            MultiLinkedListEnumerator iter = new MultiLinkedListEnumerator( this );
            while (iter.MoveNext())
            {
                func( ref iter.curNode.value );
            }
        }

        /// <summary>
        /// 用遍历的方法获得节点在链表中的位置。
        /// 如果节点不在链表中，返回-1
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public int IndexOf ( MultiLinkedListNode<T> node )
        {
            MultiLinkedListEnumerator iter = new MultiLinkedListEnumerator( this );

            int result = -1;
            while (iter.MoveNext())
            {
                result++;
                if (iter.curNode == node)
                    return result;
            }
            return -1;
        }

        /// <summary>
        /// 将链表中的值转换到一个数组中。
        /// </summary>
        /// <returns></returns>
        public T[] ToArray ()
        {
            T[] result = new T[this.length];

            int i = 0;
            foreach (T value in this)
            {
                result[i] = value;
                i++;
            }

            return result;
        }

        /// <summary>
        /// 获得该链表的一个副本，该副本是一个链表值的接口（或父类）的可迭代对象，并始终与原链表保持一致。
        /// </summary>
        /// <typeparam name="CopyType">副本迭代的类型，必须是链表中值的接口或父类</typeparam>
        /// <returns></returns>
        public IEnumerable<CopyType> GetConvertList<CopyType> () where CopyType : class
        {
            Type copyType = typeof( CopyType );
            Type valueType = typeof( T );
            if (copyType.IsInterface)
            {
                if (valueType.GetInterface( copyType.Name ) == null)
                    throw new Exception( "Can not convert ValueType to CopyType!" );
            }
            else
            {
                if (!typeof( T ).IsSubclassOf( typeof( CopyType ) ))
                    throw new Exception( "Can not convert ValueType to CopyType!" );
            }


            IEnumerable<CopyType> copy = new MultiListCopy<CopyType, T>( this );
            return copy;
        }

        #endregion

        #region IEnumerable<T> 成员

        /// <summary>
        /// 获得链表的迭代器
        /// </summary>
        /// <returns></returns>
        public IEnumerator<T> GetEnumerator ()
        {
            return new MultiLinkedListEnumerator( this );
        }

        #endregion

        #region IEnumerable 成员

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
        {
            return GetEnumerator();
        }

        #endregion
    }

    /// <summary>
    /// 多重身份链表的副本
    /// </summary>
    /// <typeparam name="CopyType"></typeparam>
    /// <typeparam name="T"></typeparam>
    [Serializable]
    public class MultiListCopy<CopyType, T> : IEnumerable<CopyType>
        where T : class
        where CopyType : class
    {
        MultiLinkedList<T> list;

        /// <summary>
        /// 用原链表来创造该副本
        /// </summary>
        /// <param name="list"></param>
        public MultiListCopy ( MultiLinkedList<T> list )
        {
            this.list = list;
        }

        #region IEnumerable<CopyType> 成员

        /// <summary>
        /// 获得迭代器
        /// </summary>
        /// <returns></returns>
        public IEnumerator<CopyType> GetEnumerator ()
        {
            foreach (T obj in list)
            {
                yield return obj as CopyType;
            }
        }

        #endregion

        #region IEnumerable 成员

        IEnumerator IEnumerable.GetEnumerator ()
        {
            return GetEnumerator();
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace MapEditor
{
    static class ObjClassSearcher
    {
        public static List<ObjClassInfo> Search ( string DLLPath )
        {
            return null;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.PhiCol;

namespace SmartTank.GameObjs.Tank
{
    public interface ITankController : IPhisicalUpdater, IColChecker
    {

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using TankEngine2D.DataStructure;

namespace SmartTank.AI
{
    public interface IAICommonServer
    {
        Rectanglef MapBorder { get;}
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace GameEngine.Draw.BackGround
{
    interface IBackGround
    {
        void Draw ();
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.GameObjs
{
    [Serializable]
    public class GameObjInfo
    {
        public readonly string ObjClass;
        public readonly string Script;

        public GameObjInfo( string objClass, string script )
        {
            this.ObjClass = objClass;
            this.Script = script;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using TankEngine2D.Helpers;
using System.IO;

namespace SmartTank.Helpers.DependInject
{

    public static class DIHelper
    {

        /// <summary>
        /// 使用Assembly>.LoadFile函数获取程序集。
        /// </summary>
        /// <param name="assetFullName"></param>
        /// <returns></returns>
        static public Assembly GetAssembly ( string assetPath )
        {
            Assembly assembly = null;

            try
            {
                assembly = Assembly.LoadFile( Path.Combine( System.Environment.CurrentDirectory, assetPath ) );
            }
            catch (Exception)
            {
                Log.Write( "Load Assembly error : " + assetPath + " load unsucceed!" );
                return null;
            }

            return assembly;
        }

        static public object GetInstance ( Type type )
        {
            return Activator.CreateInstance( type );
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using GameEngine.Effects.Particles;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Common.Helpers;
using System.IO;
using GameEngine.Draw;


namespace GameEngine.Effects.SceneEffects
{
    public class SmokeGenerater : IManagedEffect
    {
        readonly string texAsset = Path.Combine( Directories.ContentDirectory, "SceneEffects\\CloudSingle" );
        readonly Vector2 texOrigin = new Vector2( 32, 32 );
        readonly float startRadius = 10;


        bool isEnd = false;

        ParticleSystem particleSystem;

        float duaration;
        float curSystemTime = -1;

        float concen;

        public float Concen
        {
            get { return concen; }
            set { concen = value; }
        }

        public SmokeGenerater( float duaration, float partiDuara, Vector2 pos, Vector2 dir, float speed, float concen, bool managered )
        {
            this.duaration = duaration;
            this.concen = concen;

            Texture2D tex = BaseGame.ContentMgr.Load<Texture2D>( texAsset );
            particleSystem = new ParticleSystem( duaration, partiDuara, pos, tex, texOrigin, null, LayerDepth.EffectLow + 0.01f,
                delegate( float curTime, ref float timer )
                {
                    if (this.concen == 0)
                        return 0;
                    else if (this.concen > 1)
                        return (int)(this.concen);
                    else if (curTime % (int)(1 / this.concen) == 0)
                        return 1;
                    else
                        return 0;
                },
                delegate( float curTime,float deltaTime, Vector2 lastPos, Vector2 curDir, int No )
                {
                    if (curTime == 0)
                        return Vector2.Zero + RandomHelper.GetRandomVector2( -1, 1 );

                    else
                        return lastPos + curDir * speed;
                },
                delegate( float curTime, float deltaTime,Vector2 lastDir, int No )
                {
                    if (curTime == 0)
                        return dir + RandomHelper.GetRandomVector2( -0.3f, 0.3f );

                    else
                        return lastDir;
                },
                delegate( float curTime, float deltaTime, float lastRadius, int No )
                {
                    return startRadius * (1 + 0.1f * curTime);
                },
                delegate( float curTime, float deltaTime, Color lastColor, int No )
                {
                    return new Color( 160, 160, 160, Math.Max( (byte)0, (byte)(255 * (partiDuara - curTime) / partiDuara) ) );
                } );

            if (managered)
                EffectsMgr.AddManagedEffect( this );
        }       

        public SmokeGenerater( float duaration, float partiDuara, Vector2 dir, float speed, float concen, bool managered)
            : this( duaration, partiDuara, Vector2.Zero, dir, speed, concen, managered )
        {
        }

        #region IManagedEffect 成员

        public bool IsEnd
        {
            get { return isEnd; }
        }

        #endregion

        #region IUpdater 成员

        public void Update( float seconds )
        {
            curSystemTime++;
            if (duaration != 0 && curSystemTime > duaration)
            {
                isEnd = true;
                return;
            }
            particleSystem.Update(seconds);
        }

        #endregion

        #region IDrawableObj 成员

        public void Draw()
        {
            particleSystem.Draw();
        }

        #endregion

        #region IDrawableObj 成员


        public Vector2 Pos
        {
            get { return particleSystem.Pos; }
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace GameEngine.Effects
{
    /// <summary>
    /// 可切帧对象的基类
    /// </summary>
    public abstract class AnimatedSprite: IManagedEffect
    {

        #region Variables

        /// <summary>
        /// 当动画结束时引发这个事件
        /// </summary>
        public event EventHandler OnStop;

        /// <summary>
        /// 切帧频率
        /// </summary>
        public float Interval = 1;

        /// <summary>
        /// 动画的帧总数
        /// </summary>
        protected int mSumFrame;

        /// <summary>
        /// 当前的帧索引，从0开始
        /// </summary>
        protected int mCurFrameIndex;

        float timer = 0;

        bool started = false;

        bool end = false;

        int mShowedFrame;

        int mSumShowFrame = 0;

        bool mShowOnce = false;

        #endregion

        /// <summary>
        /// 动画是否已经开始显示
        /// </summary>
        public bool IsStart
        {
            get { return started; }
        }

        /// <summary>
        /// 动画是否已经结束
        /// </summary>
        public bool IsEnd
        {
            get { return end; }
        }

        #region Start

        /// <summary>
        /// 从索引0开始连续播放动画。
        /// </summary>
        public void Start ()
        {
            Start( 0 );
        }

        /// <summary>
        /// 开始连续播放动画，制定开始的帧索引
        /// </summary>
        /// <param name="startFrame">开始处的帧索引</param>
        public void Start ( int startFrame )
        {
            Start( startFrame, 0, false );
        }

        /// <summary>
        /// Start to Show the Cartoon on Screen,
        /// it will start at the startFrame index,
        /// and after passing sumShowFrame's number of frames, it will a stop automatically, and call OnStop Event.
        /// 开始播放动画，制定播放开始的索引和一共显示多少帧，并制定是否只播放一次
        /// </summary>
        /// <param name="startFrame">开始处的帧索引</param>
        /// <param name="sumShowFrame">总共显示的帧数</param>
        /// <param name="showOnce">是否只显示一次</param>
        public void Start ( int startFrame, int sumShowFrame, bool showOnce )
        {
            started = true;
            mCurFrameIndex = Math.Max( 0, Math.Min( mSumFrame, startFrame ) );
            mSumShowFrame = sumShowFrame;
            mShowedFrame = 0;
            mShowOnce = showOnce;
        }

        #endregion

        #region StopShow

        private void Stop()
        {
            mShowedFrame = 0;
            mCurFrameIndex = 0;
            started = false;
            if (OnStop != null)
                OnStop(this, null);
        }

        #endregion

        #region Draw Current Frame

        /// <summary>
        /// 绘制当前帧，由继承类重载后实现
        /// </summary>
        protected virtual void DrawCurFrame()
        {

        }

        #endregion



        #region IManagedEffect 成员


        public void Update(float seconds)
        {
            timer += seconds;
            if (timer >= Interval)
            {
                timer = 0;
                NextFrame();
            }
        }

        private void NextFrame()
        {
            if (mSumShowFrame != 0)
            {
                mShowedFrame++;
                if (mShowedFrame >= mSumShowFrame)
                {
                    Stop();
                    end = true;
                }
            }
            mCurFrameIndex++;
            if (mCurFrameIndex >= mSumFrame)
            {
                if (mShowOnce)
                {
                    Stop();
                    end = true;
                }
                else
                {
                    mCurFrameIndex -= mSumFrame;
                }
            }
        }

        #endregion

        #region IDrawableObj 成员

        public void Draw()
        {
            DrawCurFrame();
        }

        public abstract Microsoft.Xna.Framework.Vector2 Pos{ get; }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.IO;
using TankEngine2D.Helpers;
using SmartTank.Helpers;
using SmartTank.Draw;

namespace SmartTank.Effects.SceneEffects
{
    public class Explode
    {
        AnimatedSpriteSingle animatefire;
        AnimatedSpriteSingle animateBright;

        public static void LoadResources()
        {
            AnimatedSpriteSingle.LoadResources( BaseGame.ContentMgr, Path.Combine( Directories.ContentDirectory, "SceneEffects\\fire" ) );
            AnimatedSpriteSingle.LoadResources( BaseGame.ContentMgr, Path.Combine( Directories.ContentDirectory, "SceneEffects\\bright" ) );
        }

        public Explode( Vector2 pos, float rata )
        {
            animatefire = new AnimatedSpriteSingle( BaseGame.RenderEngine );
            animatefire.LoadFromContent( BaseGame.ContentMgr, Path.Combine( Directories.ContentDirectory, "SceneEffects\\fire" ), 32, 32, 2 );
            animatefire.SetParameters( new Vector2( 16, 16 ), pos, 2f, rata, Color.White, LayerDepth.EffectLow, SpriteBlendMode.AlphaBlend );
            animatefire.Start( 0, 64, true );

            animateBright = new AnimatedSpriteSingle( BaseGame.RenderEngine );
            animateBright.LoadFromContent( BaseGame.ContentMgr, Path.Combine( Directories.ContentDirectory, "SceneEffects\\bright" ), 32, 32, 2 );
            animateBright.SetParameters( new Vector2( 16, 16 ), pos, 2f, rata, Color.White, LayerDepth.EffectLow, SpriteBlendMode.AlphaBlend );
            animateBright.Start( 0, 64, true );
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using GameEngine.Graphics;
using Common.DataStructure;
using Common.Helpers;
using GameEngine.Senses.Memory;

namespace GameEngine.Shelter
{

    public class RaderDepthMap
    {
        #region Constants

        readonly float scale;

        //readonly int minSize = 10;

        #endregion

        #region Variables

        float[] depthMap;

        /*
         * 需要为TankAI提供当前遮挡它的物体信息。
         * 
         * 故加入此成员。
         * 
         * */
        IShelterObj[] objMap;


        /// <summary>
        /// 缓存物体的可见边界。
        /// </summary>
        VisiBordPoint[] objBordIndexMap;


        IShelterObj[] curShelters;

        ObjVisiBorder[] curObjVisiBorders;

        Texture2D mapTex;

        #endregion

        #region Properties

        public int Size
        {
            get { return depthMap.Length; }
        }

        public float this[float l]
        {
            get
            {
                int index = IndexOf( l );
                if (index < 0 || index >= Size)
                    return 1;
                else
                    return depthMap[index];
            }
            set
            {
                int index = IndexOf( l );
                if (index < 0 || index >= Size)
                    return;
                else
                    depthMap[index] = value;
            }
        }

        public float[] DepthMap
        {
            get { return depthMap; }
        }

        #endregion

        #region Construction

        public RaderDepthMap( int gridSum )
        {
            depthMap = new float[gridSum];
            scale = (float)gridSum / 2f;
            ClearMap( 1 );

            objMap = new IShelterObj[gridSum];
            objBordIndexMap = new VisiBordPoint[gridSum];

            mapTex = new Texture2D( BaseGame.Device, ShelterMgr.gridSum, 1, 1, TextureUsage.None, SurfaceFormat.Alpha8 );
        }

        public void ClearMap( float value )
        {
            for (int i = 0; i < depthMap.Length; i++)
            {
                depthMap[i] = value;
            }
        }

        #endregion

        #region Methods

        public void ApplyShelterObj( Rader rader, IShelterObj obj )
        {
            Matrix worldMatrix = obj.WorldTrans;

            CircleList<BorderPoint> border = obj.BorderData;
            CircleListNode<BorderPoint> lastB = border.First.pre;
            Vector2 pInRader = rader.TranslateToRaderSpace( Vector2.Transform( ConvertHelper.PointToVector2( lastB.value.p ), worldMatrix ) );
            int lastIndex = IndexOf( pInRader.X );
            float lastDepth = pInRader.Y;

            CircleListNode<BorderPoint> cur = border.First;
            for (int i = 0; i < border.Length; i++)
            {
                pInRader = rader.TranslateToRaderSpace( Vector2.Transform( ConvertHelper.PointToVector2( cur.value.p ), worldMatrix ) );
                int curIndex = IndexOf( pInRader.X );
                float curDepth = pInRader.Y;
                if (pInRader.X >= -1.1f && pInRader.X <= 1.3f)
                {
                    //this[pInRader.X] = Math.Min( this[pInRader.X], pInRader.Y );
                    SetValueAtIndex( curIndex, pInRader.Y, obj, i, cur.value.p );

                    if (curIndex - lastIndex > 1)
                    {
                        int overIndex = lastIndex + 1;
                        while (overIndex != curIndex)
                        {
                            float lerp = MathHelper.Lerp( lastDepth, curDepth, (curIndex - overIndex) / (curIndex - lastIndex) );
                            SetValueAtIndex( overIndex, lerp, obj, i, cur.value.p );
                            overIndex++;
                        }
                    }
                    else if (curIndex - lastIndex < -1)
                    {
                        int overIndex = lastIndex - 1;
                        while (overIndex != curIndex)
                        {
                            float lerp = MathHelper.Lerp( lastDepth, curDepth, (curIndex - overIndex) / (curIndex - lastIndex) );
                            SetValueAtIndex( overIndex, lerp, obj, i, cur.value.p );
                            overIndex--;
                        }
                    }
                }
                lastIndex = curIndex;
                lastDepth = curDepth;

                cur = cur.next;
            }
        }

        public Texture2D GetMapTexture()
        {
            byte[] data = new byte[depthMap.Length];
            for (int i = 0; i < depthMap.Length; i++)
            {
                data[i] = (byte)(depthMap[i] * 255);
            }
            BaseGame.Device.Textures[0] = null;
            mapTex.SetData<byte>( data );
            return mapTex;
        }

        public IShelterObj[] GetShelters()
        {
            return curShelters;
        }

        public ObjVisiBorder[] GetSheltersVisiBorder()
        {
            return curObjVisiBorders;
        }

        public void CalSheltersVisiBorder()
        {
            Dictionary<IShelterObj, List<VisiBordPoint>> temp = new Dictionary<IShelterObj, List<VisiBordPoint>>();

            int index = 0;
            foreach (IShelterObj obj in objMap)
            {
                if (obj != null)
                {
                    if (!temp.ContainsKey( obj ))
                    {
                        temp.Add( obj, new List<VisiBordPoint>() );
                    }
                    temp[obj].Add( objBordIndexMap[index] );
                }
                index++;
            }

            curObjVisiBorders = new ObjVisiBorder[temp.Count];

            curShelters = new IShelterObj[temp.Count];

            int i = 0;
            foreach (KeyValuePair<IShelterObj, List<VisiBordPoint>> pair in temp)
            {
                pair.Value.Sort(
                    delegate( VisiBordPoint p1, VisiBordPoint p2 )
                    {
                        if (p1.index < p2.index)
                            return -1;
                        else if (p1.index == p2.index)
                            return 0;
                        else
                            return 1;
                    } );

                CircleList<VisiBordPoint> points = new CircleList<VisiBordPoint>();

                foreach (VisiBordPoint p in pair.Value)
                {
                    if (points.Last == null || points.Last.value.index != p.index)
                        points.AddLast( p );
                }

                curObjVisiBorders[i] = new ObjVisiBorder( (IHasBorderObj)pair.Key, points );
                curShelters[i] = pair.Key;

                i++;
            }
        }

        #endregion

        #region Private Functions

        private int IndexOf( float x )
        {
            return (int)((x + 1) * scale);
        }

        private void SetValueAtIndex( int index, float value, IShelterObj obj, int bordIndex, Point bordp )
        {
            if (index < 0 || index >= depthMap.Length)
                return;

            if (value < depthMap[index])
            {
                depthMap[index] = value;
                objMap[index] = obj;
                objBordIndexMap[index] = new VisiBordPoint( bordIndex, bordp );
            }
        }

        #endregion
    }

}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using TankEngine2D.DataStructure;
using Microsoft.Xna.Framework.Graphics;
using TankEngine2D.Helpers;
using TankEngine2D.Graphics;
using SmartTank.GameObjs;
using SmartTank.Draw;
using SmartTank.Senses.Vision;
using SmartTank.Senses.Memory;

namespace SmartTank.Shelter
{
    /* 封装一个扇形的雷达。
     * 
     * 用GPU来完成遮挡检测和雷达图形的绘制。
     * 
     * 
     * 雷达空间(Rader Space)指以扇形中线为r轴，顺时针为正方向建立的级坐标系。（r，l）
     * 
     * 其中扇形弧边两端点的坐标分别为（1，1）和（1，-1）。
     * 
     * 将在此空间中完成深度数据和遮挡的计算。
     * 
     * */

    public class Rader : IDrawableObj
    {
        #region Constants

        public static readonly float smallMapScale = (float)ShelterMgr.texSizeSmall / (float)ShelterMgr.texSize;

        #endregion

        #region Variables

        /// <summary>
        /// 夹角的一半
        /// </summary>
        float ang;

        /// <summary>
        /// 半径
        /// </summary>
        float r;

        /// <summary>
        /// 圆心位置
        /// </summary>
        Vector2 pos;

        /// <summary>
        /// 中线的方位角
        /// </summary>
        float azi;

        /// <summary>
        /// 
        /// </summary>
        Rectanglef bouBox;

        /// <summary>
        /// 雷达的颜色
        /// </summary>
        Color color;

        /// <summary>
        /// 旋转矩阵，在计算贴图时使用。
        /// </summary>
        Matrix rotaMatrix;

        Texture2D texture;

        Texture2D texSmall;

        Color[] textureData;

        internal RaderDepthMap depthMap;

        internal RenderTarget2D target;
        internal RenderTarget2D targetSmall;

        int leftWaitframe = 0;

        // 当前的遮挡物
        IShelterObj[] shelterObjs = new IShelterObj[0];

        ObjVisiBorder[] shelterVisiBorders = new ObjVisiBorder[0];

        EyeableBorderObjInfo[] eyeableBorderObjInfos = new EyeableBorderObjInfo[0];

        List<IEyeableInfo> curEyeableInfo = new List<IEyeableInfo>();

        ObjMemoryKeeper objMemoryKeeper;

        #endregion

        #region Properties

        public Vector2 Pos
        {
            get { return pos; }
            set
            {
                pos = value;
            }
        }

        public float X
        {
            get { return pos.X; }
            set
            {
                pos.X = value;
            }
        }

        public float Y
        {
            get { return pos.Y; }
            set
            {
                pos.Y = value;
            }
        }

        public float Azi
        {
            get { return azi; }
            set
            {
                azi = value;
            }
        }

        /// <summary>
        /// 夹角的一半
        /// </summary>
        public float Ang
        {
            get { return ang; }
            set { ang = value; }
        }

        /// <summary>
        /// 半径
        /// </summary>
        public float R
        {
            get { return r; }
            set { r = value; }
        }

        public Rectanglef BoundBox
        {
            get { return bouBox; }
        }

        /// <summary>
        /// 中线单位向量
        /// 使用该属性会进行三角函数求值，不要频繁调用。
        /// </summary>
        public Vector2 N
        {
            get
            {
                return new Vector2( (float)Math.Sin( azi ), -(float)Math.Cos( azi ) );
            }
        }

        /// <summary>
        /// 左边界单位向量
        /// 使用该属性会进行三角函数求值，不要频繁调用。
        /// </summary>
        public Vector2 B
        {
            get
            {
                return new Vector2( (float)Math.Sin( azi - ang ), -(float)Math.Cos( azi - ang ) );
            }
        }

        /// <summary>
        /// 右边界单位向量
        /// 使用该属性会进行三角函数求值，不要频繁调用。
        /// </summary>
        public Vector2 U
        {
            get
            {
                return new Vector2( (float)Math.Sin( azi + ang ), -(float)Math.Cos( azi + ang ) );
            }
        }

        /// <summary>
        /// 左边界点
        /// 使用该属性会进行三角函数求值，不要频繁调用。
        /// </summary>
        public Vector2 LeftP
        {
            get
            {
                return pos + B * r;
            }

        }

        /// <summary>
        /// 右边界点
        /// 使用该属性会进行三角函数求值，不要频繁调用。
        /// </summary>
        public Vector2 RightP
        {
            get
            {
                return pos + U * r;
            }
        }

        /// <summary>
        /// 雷达的颜色
        /// </summary>
        public Color RaderColor
        {
            get { return color; }
        }

        /// <summary>
        /// 旋转矩阵，在计算贴图时使用。
        /// 在每一帧使用前，需要调用UpdateMatrix函数。
        /// </summary>
        internal Matrix RotaMatrix
        {
            get { return rotaMatrix; }
        }

        /// <summary>
        /// 获得当前遮挡雷达的物体
        /// </summary>
        public IShelterObj[] ShelterObjs
        {
            get { return shelterObjs; }
            set { shelterObjs = value; }
        }

        /// <summary>
        /// 获取当前可见遮挡物体的可见边界信息
        /// </summary>
        internal ObjVisiBorder[] ShelterVisiBorders
        {
            get { return shelterVisiBorders; }
            set { shelterVisiBorders = value; }
        }

        //public ObjVisiBorder[] NonShelterVisiBorders
        //{
        //    get { return nonShelterVisiBorders; }
        //    set { nonShelterVisiBorders = value; }
        //}

        internal EyeableBorderObjInfo[] EyeableBorderObjInfos
        {
            get { return eyeableBorderObjInfos; }
            set { eyeableBorderObjInfos = value; }
        }

        public List<IEyeableInfo> CurEyeableObjs
        {
            get { return curEyeableInfo; }
            set { curEyeableInfo = value; }
        }

        /// <summary>
        /// 当前视野中的深度图，索引按顺时针方向增大。
        /// 值为1表示当前方向无遮挡。
        /// </summary>
        public float[] DepthMap
        {
            get { return depthMap.DepthMap; }
        }

        /// <summary>
        /// 获得曾经见过物体的边界信息。
        /// 可在ObjMemoryMgr中将多个RaderOwner注册为物体边界信息共享组。
        /// </summary>
        public ObjMemoryKeeper ObjMemoryKeeper
        {
            get { return objMemoryKeeper; }
            set { objMemoryKeeper = value; }
        }

        #endregion

        #region Construction

        public Rader ( float ang, float r, Vector2 pos, float azi, Color color )
        {
            this.pos = pos;
            this.azi = azi;
            this.r = r;
            this.ang = ang;
            this.color = color;

            this.depthMap = new RaderDepthMap( ShelterMgr.gridSum );

            int texSize = ShelterMgr.texSize;
            int texSizeSmall = ShelterMgr.texSizeSmall;

            target = new RenderTarget2D( BaseGame.Device, texSize, texSize, 1, BaseGame.Device.PresentationParameters.BackBufferFormat );
            targetSmall = new RenderTarget2D( BaseGame.Device, texSizeSmall, texSizeSmall, 1, BaseGame.Device.PresentationParameters.BackBufferFormat );

            Camera.onCameraScaled += new EventHandler( Camera_onCameraScaled );
        }

        /// <summary>
        /// 防止摄像机缩放改变的时候原雷达图案依然被绘制。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Camera_onCameraScaled ( object sender, EventArgs e )
        {
            leftWaitframe = 1;
        }

        #endregion

        #region Update

        public void Update ()
        {
            UpdateBoundRect();
            UpdateMatrix();
        }

        #endregion

        #region If Obj in RaderRect

        private void UpdateBoundRect ()
        {
            float len = r / (float)Math.Cos( ang );
            Vector2 CenterP = pos + N * len;
            Vector2 min = Vector2.Min( Vector2.Min( Vector2.Min( pos, LeftP ), RightP ), CenterP );
            Vector2 max = Vector2.Max( Vector2.Max( Vector2.Max( pos, LeftP ), RightP ), CenterP );

            bouBox = new Rectanglef( min.X, min.Y, max.X - min.X, max.Y - min.Y );
        }

        /// <summary>
        /// 在调用该函数之前，确保当前帧内调用过UpdateBoundRect()函数。
        /// </summary>
        /// <param name="objBoundBox"></param>
        /// <returns></returns>
        public bool InRaderRect ( Rectanglef objBoundBox )
        {
            return bouBox.Intersects( objBoundBox );
        }

        #endregion

        #region Translations

        private void UpdateMatrix ()
        {
            rotaMatrix = Matrix.CreateRotationZ( -azi + BaseGame.CoordinMgr.Rota );
        }

        internal Vector2 TranslateToRaderSpace ( Vector2 pInWorld )
        {
            Vector2 result;
            Vector2 V = pInWorld - pos;

            float aziP;
            if (V.Y == 0)
            {
                if (V.X == 0)
                    return Vector2.Zero;
                else if (V.X > 0)
                    aziP = MathHelper.PiOver2;
                else
                    aziP = -MathHelper.PiOver2;
            }
            else if (V.Y < 0)
            {
                aziP = -(float)Math.Atan( V.X / V.Y );
            }
            else
            {
                aziP = MathHelper.Pi - (float)Math.Atan( V.X / V.Y );
            }
            result.X = MathTools.AngTransInPI( aziP - azi ) / ang;
            result.Y = V.Length() / r;

            return result;
        }

        #endregion

        #region Draw

        internal void UpdateTexture()
        {
            texture = target.GetTexture();
            texSmall = targetSmall.GetTexture();
            UpdateTexData();

            depthMap.CalSheltersVisiBorder();
            this.ShelterObjs = depthMap.GetShelters();
            this.ShelterVisiBorders = depthMap.GetSheltersVisiBorder();

        }

        public void Draw ()
        {
            if (leftWaitframe != 0)
            {
                leftWaitframe--;
                return;
            }
            if (texture != null)
            {
                BaseGame.SpriteMgr.alphaSprite.Draw( texture, BaseGame.CoordinMgr.ScreenPos( pos ), null,
                    Color.White, 0, new Vector2( 0.5f * ShelterMgr.texSize, 0.5f * ShelterMgr.texSize ), BaseGame.CoordinMgr.ScrnLengthf( r + r ) / (float)ShelterMgr.texSize, SpriteEffects.None, LayerDepth.TankRader );
            }
        }

        #endregion

        #region Dectection

        private void UpdateTexData ()
        {
            if (texSmall != null)
            {
                try
                {
                    textureData = new Color[texSmall.Width * texSmall.Height];
                    texSmall.GetData<Color>( textureData );
                }
                catch (Exception)
                {

                }
            }
        }

        /*
         * 使用一个尺寸较小的略图判断物体是否在雷达中。
         * 
         * */
        public bool PointInRader ( Vector2 point )
        {
            if (textureData == null)
                return false;

            if (texture == null)
                return false;

            if (!bouBox.Contains( point ))
                return false;

            Vector2 texPos = (Vector2.Transform( (point - pos), Matrix.CreateRotationZ( -BaseGame.CoordinMgr.Rota ) ) + new Vector2( r, r )) * (float)(texture.Width) * smallMapScale * 0.5f / r;

            if (texPos.X < 0 || texPos.X >= texSmall.Width || texPos.Y < 0 || texPos.Y >= texSmall.Height)
                return false;

            int index = (int)(texPos.X) + texSmall.Width * (int)(texPos.Y);
            if (textureData[index].A > 0)
                return true;
            else
                return false;
        }

        #endregion



        
    }

}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.AI
{

    [AttributeUsage( AttributeTargets.Class, Inherited = false )]
    public class AIAttribute : Attribute
    {
        public string Name;
        public string Programer;
        public string Script;
        public DateTime Time;

        public AIAttribute (string name, string programer, string script, int year, int mouth, int day )
        {
            this.Name = name;
            this.Programer = programer;
            this.Script = script;
            this.Time = new DateTime( year, mouth, day );
        }

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Common.Helpers;

namespace GameEngine.Effects.TextEffects
{
    /// <summary>
    /// 实现一个不断上升并不断变得透明的文字特效
    /// </summary>
    class FadeUpEffect : ITextEffect
    {

        #region Variables


        string text;

        Vector2 pos;

        float scale;

        Color color;

        float layerDepth;

        string fontType;

        float sumFrame;
        float frameRePlatforms;

        float step;

        bool ended = false;

        bool inLogic = false;

        float curDest = 0;

        /// <summary>
        /// 
        /// </summary>
        public bool Ended
        {
            get { return ended; }
        }
        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="text">文字内容</param>
        /// <param name="pos">显示的屏幕位置</param>
        /// <param name="Scale">大小</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">绘制深度</param>
        /// <param name="fontType">字体</param>
        /// <param name="existedFrame">保持在屏幕中的时间循环次数</param>
        /// <param name="step">每次时间循环中，上升的高度，以像素为单位</param>
        public FadeUpEffect( string text, bool inLogic, Vector2 pos, float scale, Color color, float layerDepth, string fontType, float existFrame, float step )
        {
            if (scale <= 0 || existFrame <= 1)
                throw new Exception( "scale and existFrame cann't be below Zero!" );

            this.text = text;
            this.inLogic = inLogic;
            this.pos = pos;
            this.scale = scale;
            this.color = color;
            this.layerDepth = layerDepth;
            this.fontType = fontType;
            this.sumFrame = existFrame;
            this.frameRePlatforms = existFrame;
            this.step = step;
        }

        #region Draw

        /// <summary>
        /// 绘制并更新自己
        /// </summary>
        public void Draw()
        {
            if (frameRePlatforms <= 0)
            {
                ended = true;
                return;
            }
            else
            {
                frameRePlatforms--;
                curDest += step;
                color = ColorHelper.ApplyAlphaToColor( color, CalAlpha() );
                if (inLogic)
                    BaseGame.FontMgr.DrawInScrnCoord( text, BaseGame.CoordinMgr.ScreenPos( pos ) - new Vector2( 0, curDest ), scale, color, layerDepth, fontType );
                else
                    BaseGame.FontMgr.DrawInScrnCoord( text, pos - new Vector2( 0, curDest ), scale, color, layerDepth, fontType );
            }
        }

        #endregion

        float CalAlpha()
        {
            if (frameRePlatforms > 0.5f * sumFrame)
                return 1f;
            else
                return (frameRePlatforms - (int)(0.5f * sumFrame)) / (0.5f * sumFrame) + 1;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.GameObjs.Tank.SinTur
{
    public class TankLimitSinTur
    {
        public float MaxForwardSpeed;
        public float MaxBackwardSpeed;
        public float MaxTurnAngleSpeed;
        public float MaxTurretAngleSpeed;
        public float MaxRaderAngleSpeed;

        public TankLimitSinTur ( float maxForwardSpeed, float maxBackwardSpeed, float maxTurnAngleSpeed, float maxTurretAngleSpeed, float maxRaderAngleSpeed )
        {
            this.MaxForwardSpeed = maxForwardSpeed;
            this.MaxBackwardSpeed = maxBackwardSpeed;
            this.MaxTurnAngleSpeed = maxTurnAngleSpeed;
            this.MaxTurretAngleSpeed = maxTurretAngleSpeed;
            this.MaxRaderAngleSpeed = maxRaderAngleSpeed;
        }

        public float LimitSpeed ( float speed )
        {
            return Math.Min( MaxForwardSpeed, Math.Max( -MaxBackwardSpeed, speed ) );
        }

        public float LimitAngleSpeed ( float angleSpeed )
        {
            return Math.Min( MaxTurnAngleSpeed, Math.Max( -MaxTurnAngleSpeed, angleSpeed ) );
        }

        public float LimitTurretAngleSpeed ( float turretAngleSpeed )
        {
            return Math.Min( MaxTurretAngleSpeed, Math.Max( -MaxTurretAngleSpeed, turretAngleSpeed ) );
        }

        internal float LimitRaderAngleSpeed ( float raderAngleSpeed )
        {
            return Math.Min( MaxRaderAngleSpeed, Math.Max( -MaxRaderAngleSpeed, raderAngleSpeed ) );
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace GameObjEditor
{
    public partial class PictureBoxGird : PictureBox
    {
        #region Variables

        Bitmap bitmap;

        float scale;
        PointF texFocusPos;

        public event PaintEventHandler LastPaint;

        #endregion

        #region Properties

        public int TexWidth
        {
            get { return bitmap.Width; }
        }

        public int TexHeight
        {
            get { return bitmap.Height; }
        }

        public PointF ScrnCenter
        {
            get { return new PointF( 0.5f * Width, 0.5f * Height ); }
        }

        public float Scale
        {
            get { return scale; }
            set { scale = value; }
        }

        public PointF TexFocusPos
        {
            get { return texFocusPos; }
            set { texFocusPos = value; }
        }

        #endregion

        public PictureBoxGird ()
        {
            InitializeComponent();
        }

        #region Load/Clear Piciture

        public void LoadPicture ( Bitmap bitmap )
        {
            if (bitmap == null)
                return;

            this.bitmap = bitmap;

            ResetScrn();
        }

        private void ResetScrn ()
        {
            float scaleW = ((float)Width) / (float)(bitmap.Width + 2);
            float scaleH = ((float)Height) / (float)(bitmap.Height + 2);

            scale = Math.Min( scaleW, scaleH );
            texFocusPos = new PointF( 0.5f * TexWidth, 0.5f * TexHeight );
        }

        public void ClearPicture ()
        {
            this.bitmap = null;
        }

        public Bitmap CurBitMap
        {
            get { return bitmap; }
        }

        #endregion

        #region Coordin

        public RectangleF RectAtPos ( int x, int y )
        {
            PointF scrnCenter = ScrnCenter;
            PointF upLeft = new PointF( (x - texFocusPos.X) * scale + scrnCenter.X, (y - texFocusPos.Y) * scale + scrnCenter.Y );
            return new RectangleF( upLeft, new SizeF( scale, scale ) );
        }

        public PointF ScrnPos ( int x, int y )
        {
            PointF scrnCenter = ScrnCenter;
            return new PointF( (x - texFocusPos.X) * scale + scrnCenter.X, (y - texFocusPos.Y) * scale + scrnCenter.Y );
        }

        public PointF ScrnPos ( float x, float y )
        {
            PointF scrnCenter = ScrnCenter;
            return new PointF( (x - texFocusPos.X) * scale + scrnCenter.X, (y - texFocusPos.Y) * scale + scrnCenter.Y );
        }

        public PointF TexPos ( float scrnX, float scrnY )
        {
            PointF scrnCenter = ScrnCenter;
            return new PointF( (scrnX - scrnCenter.X) / scale + texFocusPos.X, (scrnY - scrnCenter.Y) / scale + texFocusPos.Y );
        }

        #endregion

        #region Paint

        bool alphaMode = false;

        public bool AlphaMode
        {
            get { return alphaMode; }
            set { alphaMode = value; }
        }

        public void ToggleAlphaMode ()
        {
            alphaMode = !alphaMode;
            this.Invalidate();
        }

        protected override void OnPaint ( PaintEventArgs pe )
        {
            base.OnPaint( pe );
            if (bitmap != null)
            {
                DrawBitMap( pe.Graphics );
                DrawGrid( pe.Graphics );
            }
            if (LastPaint != null)
                LastPaint( this, pe );
        }

        private void DrawBitMap ( Graphics graphics )
        {

            PointF minTexPos = TexPos( 0, 0 );
            PointF maxTexPos = TexPos( Width, Height );

            float width = maxTexPos.X - minTexPos.X;

            if (width > 60)
            {
                graphics.DrawImage( bitmap, new RectangleF( ScrnPos( 0, 0 ), new SizeF( TexWidth * scale, TexHeight * scale ) ) );
            }
            else
            {
                if (alphaMode)
                {
                    for (int y = Math.Max( 0, (int)minTexPos.Y ); y <= Math.Min( bitmap.Height - 1, maxTexPos.Y ); y++)
                    {
                        for (int x = Math.Max( 0, (int)minTexPos.X ); x <= Math.Min( bitmap.Width - 1, maxTexPos.X ); x++)
                        {
                            Color color = bitmap.GetPixel( x, y );
                            graphics.FillRectangle( new SolidBrush( Color.FromArgb( color.A, 255 - color.A, 255 - color.A, 255 - color.A ) ), RectAtPos( x, y ) );
                        }
                    }
                }
                else
                {
                    for (int y = Math.Max( 0, (int)minTexPos.Y ); y <= Math.Min( bitmap.Height - 1, maxTexPos.Y ); y++)
                    {
                        for (int x = Math.Max( 0, (int)minTexPos.X ); x <= Math.Min( bitmap.Width - 1, maxTexPos.X ); x++)
                        {
                            Color color = bitmap.GetPixel( x, y );
                            graphics.FillRectangle( new SolidBrush( color ), RectAtPos( x, y ) );
                        }
                    }
                }
            }

        }

        private void DrawGrid ( Graphics graphics )
        {
            int interval = (int)(Height / (scale * 100));
            interval = Math.Max( 1, interval );

            float width = scale * (bitmap.Width + 2);
            float height = scale * (bitmap.Height + 2);

            for (int i = -1; i <= bitmap.Width + 1; i += interval)
            {
                graphics.DrawLine( Pens.Brown, ScrnPos( i, -1 ), ScrnPos( i, TexHeight + 1 ) );
            }
            for (int i = -1; i <= bitmap.Height + 1; i += interval)
            {
                graphics.DrawLine( Pens.Brown, ScrnPos( -1, i ), ScrnPos( TexWidth + 1, i ) );
            }
        }

        #endregion

        #region MouseControl

        PointF mouseDownPos;
        bool mouseDown = false;
        PointF preFocusPos;
        float preScale;

        enum CoodinChange
        {
            None,
            Move,
            Zoom,
        }
        CoodinChange coordinChange;

        float moveFactor = 1f;

        public bool Controlling
        {
            get { return coordinChange != CoodinChange.None; }
        }

        [Description( "指定平移的鼠标灵敏度" ), Category( "控制" )]
        public float MoveFactor
        {
            get { return moveFactor; }
            set { moveFactor = value; }
        }

        float zoomFactor = 1f;

        [Description( "指定缩放的鼠标灵敏度" ), Category( "控制" )]
        public float ZoomFactor
        {
            get { return zoomFactor; }
            set { zoomFactor = value; }
        }

        float zoomWheelFactor = 1f;

        [Description( "指定缩放的鼠标滑轮灵敏度" ), Category( "控制" )]
        public float ZoomWheelFactor
        {
            get { return zoomWheelFactor; }
            set { zoomWheelFactor = value; }
        }

        protected override void OnMouseEnter ( EventArgs e )
        {
            base.OnMouseEnter( e );
            this.Focus();
        }

        protected override void OnMouseDown ( MouseEventArgs e )
        {
            base.OnMouseDown( e );
            mouseDownPos = new PointF( e.X, e.Y );
            preFocusPos = TexFocusPos;
            preScale = Scale;
            mouseDown = true;
        }

        protected override void OnMouseMove ( MouseEventArgs e )
        {
            base.OnMouseMove( e );

            if (mouseDown)
            {
                PointF curMousePos = new PointF( e.X, e.Y );
                if (coordinChange == CoodinChange.Move)
                {
                    texFocusPos = new PointF( preFocusPos.X + (curMousePos.X - mouseDownPos.X) * moveFactor * 0.2f, preFocusPos.Y + (curMousePos.Y - mouseDownPos.Y) * moveFactor * 0.2f );
                }
                else if (coordinChange == CoodinChange.Zoom)
                {
                    float delta = (curMousePos.Y - mouseDownPos.Y) * 0.01f * zoomFactor;
                    delta = Math.Max( -0.9f, delta );
                    scale = preScale * (1 + delta);
                }
                else
                    return;

                this.Invalidate();
            }
        }

        protected override void OnMouseUp ( MouseEventArgs e )
        {
            base.OnMouseUp( e );

            mouseDown = false;
        }

        protected override void OnKeyDown ( KeyEventArgs e )
        {
            base.OnKeyDown( e );

            if (e.Control || e.KeyCode == Keys.Z)
            {
                if (e.Control)
                    coordinChange = CoodinChange.Move;
                else if (e.KeyCode == Keys.Z)
                    coordinChange = CoodinChange.Zoom;
            }
            else if (e.Shift)
            {
                ResetScrn();
                this.Invalidate();
            }
            else if (e.KeyData == Keys.A)
            {
                ToggleAlphaMode();
            }
        }

        protected override void OnKeyUp ( KeyEventArgs e )
        {
            base.OnKeyUp( e );

            coordinChange = CoodinChange.None;
        }

        protected override void OnLostFocus ( EventArgs e )
        {
            base.OnLostFocus( e );
            coordinChange = CoodinChange.None;
        }

        protected override void OnMouseWheel ( MouseEventArgs e )
        {
            base.OnMouseWheel( e );
            float delta = Math.Max( -0.9f, Math.Min( 9f, (float)(e.Delta) * 0.002f * zoomWheelFactor ) );
            scale = scale * (1 + delta);
            this.Invalidate();
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using GameEngine.Senses.Vision;
using GameEngine.Senses.Memory;

namespace GameEngine.Shelter
{
    public delegate void BorderObjUpdatedEventHandler ( EyeableBorderObjInfo[] borderObjInfos );

    public interface IRaderOwner
    {
        Rader Rader { get;}
        void BorderObjUpdated ( EyeableBorderObjInfo[] borderObjInfo );
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Senses.Vision;
using SmartTank.PhiCol;
using Microsoft.Xna.Framework;
using SmartTank.Shelter;

namespace SmartTank.Senses.Memory
{
    public class EyeableBorderObjInfo
    {
        IEyeableInfo eyeableInfo;
        ObjVisiBorder border;
        bool isDisappeared = false;

        ConvexHall convexHall;

        public EyeableBorderObjInfo ( IEyeableInfo eyeableInfo, ObjVisiBorder border )
        {
            this.eyeableInfo = eyeableInfo;
            this.border = border;
        }

        public ObjVisiBorder Border
        {
            get { return border; }
        }

        public IEyeableInfo EyeableInfo
        {
            get { return eyeableInfo; }
        }

        public bool IsDisappeared
        {
            get { return isDisappeared; }
        }

        public void UpdateConvexHall ( float minOptimizeDest )
        {
            Vector2 transV = Vector2.Transform( Vector2.UnitX, eyeableInfo.CurTransMatrix );
            Vector2 transZero = Vector2.Transform( Vector2.Zero, eyeableInfo.CurTransMatrix );
            float scale = (transV - transZero).Length();
            float minOptimizeDestInTexSpace = minOptimizeDest / scale;

            if (convexHall == null)
                convexHall = new ConvexHall( border.VisiBorder, minOptimizeDestInTexSpace );
            else
                convexHall.BuildConvexHall( border.VisiBorder, minOptimizeDestInTexSpace );
        }

        public ConvexHall ConvexHall
        {
            get { return convexHall; }
        }

        internal IHasBorderObj Obj
        {
            get { return border.Obj; }
        }

        internal bool Combine ( EyeableBorderObjInfo borderObjInfo )
        {
            bool objUpdated = false;

            if (borderObjInfo.eyeableInfo.Pos != this.eyeableInfo.Pos)
                objUpdated = true;

            this.eyeableInfo = borderObjInfo.eyeableInfo;
            if (this.border.Combine( borderObjInfo.border.VisiBorder ))
                objUpdated = true;

            isDisappeared = false;

            return objUpdated;
        }

        internal void SetIsDisappeared ( bool isDisappeared )
        {
            this.isDisappeared = isDisappeared;
        }


    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Graphics;
using TankEngine2D.Helpers;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.Helpers;
using SmartTank.Draw;

namespace SmartTank.Effects.SceneEffects
{
    public class ShellExplode
    {
        AnimatedSpriteSeries shellTexs;

        public static void LoadResources()
        {
            AnimatedSpriteSeries.LoadResource( BaseGame.ContentMgr,
                Path.Combine( Directories.ContentDirectory, "SceneEffects\\ShellExplode\\MulEffect" ),
                0, 32 );
        }

        private static AnimatedSpriteSeries CreateTexs()
        {
            AnimatedSpriteSeries result = new AnimatedSpriteSeries( BaseGame.RenderEngine );
            result.LoadSeriesFormContent( BaseGame.RenderEngine, BaseGame.ContentMgr, Path.Combine( Directories.ContentDirectory, "SceneEffects\\ShellExplode\\MulEffect" ),
                0, 32, false );

            return result;
        }

        public ShellExplode( Vector2 pos, float rota )
        {
            shellTexs = CreateTexs();
            shellTexs.SetSpritesParameters( new Vector2( 49, 49 ), pos, 30, 30, rota + MathHelper.PiOver2, Color.White, LayerDepth.Shell, SpriteBlendMode.AlphaBlend );
            shellTexs.Interval = 1;
            shellTexs.Start( 0, 32, true );
        }

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using GameEngine.Graphics;

using GameEngine.Effects.TextEffects;
using GameEngine.Draw;

namespace GameEngine.Effects
{
    public class EffectsMgr
    {
        static List<IManagedEffect> managedEffects = new List<IManagedEffect>();

        public static void AddManagedEffect ( IManagedEffect effect )
        {
            managedEffects.Add( effect );
        }

        public static void Update ( float seconds )
        {
            for (int i = 0; i < managedEffects.Count; i++)
            {
                managedEffects[i].Update( seconds );
                if (managedEffects[i].IsEnd)
                {
                    managedEffects.Remove( managedEffects[i] );
                    i--;
                }
            }
        }

        internal static void Draw ( DrawCondition condition )
        {
            TextEffectMgr.Draw();

            foreach (IManagedEffect effect in managedEffects)
            {
                if (condition != null)
                {
                    if (condition( effect ))
                        effect.Draw();
                }
                else
                    effect.Draw();
            }
        }

        internal static void Clear ()
        {
            managedEffects.Clear();
        }


    }
}
<file_sep>//=================================================
// xWinForms
// Copyright ?2007 by <NAME>
// http://psycad007.spaces.live.com/
//=================================================
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.IO;
using Common.Helpers;
using GameEngine.Graphics;
using GameEngine.Input;
using GameEngine.Draw;

namespace GameEngine.UI
{
    public class TextButton : Control
    {
        #region Variables
        Point fontSize = new Point( 8, 15 );

        Texture2D buttonTexture;
        Rectangle[] sourceRect = new Rectangle[3];
        Rectangle[] destRect = new Rectangle[3];

        Rectangle buttonArea = Rectangle.Empty;

        public event EventHandler OnClick;
        private void onPress( object obj, EventArgs e ) { }

        bool bMouseOver = false;
        bool bPressed = false;

        public Color color = Color.White;
        public int width = 0;

        #endregion

        #region Construction

        public TextButton( string name, Vector2 position, string text, Nullable<int> width, /*Font font,*/ Color color )//, Style style)
        {
            this.Type = ControlType.TextButton;
            this.name = name;
            this.position = position;
            this.text = text;
            //this.font = font;
            this.color = color;
            if (width.HasValue)
                this.width = width.Value;
            OnClick += new EventHandler( onPress );

            Init();//style );
        }

        #endregion

        #region Initial
        private void Init( /*Style style*/ )
        {
            buttonTexture = BaseGame.ContentMgr.Load<Texture2D>( Path.Combine( Directories.UIContent, "button" ) );

            sourceRect[0] = new Rectangle( 0, 0, (int)(buttonTexture.Width * 0.1f), buttonTexture.Height );
            sourceRect[1] = new Rectangle( (int)(buttonTexture.Width * 0.1f), 0, buttonTexture.Width - (int)(buttonTexture.Width * 0.2f), buttonTexture.Height );
            sourceRect[2] = new Rectangle( buttonTexture.Width - (int)(buttonTexture.Width * 0.1f), 0, (int)(buttonTexture.Width * 0.1f), buttonTexture.Height );

            destRect[0] = sourceRect[0];
            destRect[1] = sourceRect[1];
            destRect[2] = sourceRect[2];

            if (width == 0)
                destRect[1].Width = text.Length * fontSize.X + 10;
            else if (width > destRect[0].Width + destRect[1].Width + destRect[2].Width)
                destRect[1].Width = width - (destRect[0].Width + destRect[2].Width);

            buttonArea.Width = destRect[0].Width + destRect[1].Width + destRect[2].Width;
            buttonArea.Height = destRect[0].Height;
        }
        #endregion

        #region Update
        public override void Update()//Vector2 formPosition, Vector2 formSize )
        {
            //base.Update( formPosition, formSize );

            destRect[0].X = (int)position.X;
            destRect[0].Y = (int)position.Y;

            destRect[1].X = (int)position.X + destRect[0].Width;
            destRect[1].Y = (int)position.Y;

            destRect[2].X = (int)position.X + destRect[0].Width + destRect[1].Width;
            destRect[2].Y = (int)position.Y;

            if (benable)
                CheckMouseState();

            //CheckVisibility( formPosition, formSize );
        }

        private void CheckMouseState()
        {

            buttonArea.X = (int)position.X;
            buttonArea.Y = (int)position.Y;

            if (buttonArea.Contains( InputHandler.CurMousePos ))
            {
                bMouseOver = true;
                if (InputHandler.MouseJustReleaseLeft)
                {
                    if (!bPressed)
                    {
                        bPressed = true;
                        OnClick( this, EventArgs.Empty );
                    }
                }
                else if (bPressed)
                    bPressed = false;
            }
            else if (bMouseOver)
                bMouseOver = false;

        }

        //private void CheckVisibility ( Vector2 formPosition, Vector2 formSize )
        //{
        //    if (position.X + buttonArea.Width > formPosition.X + formSize.X - 15f)
        //        bVisible = false;
        //    else if (position.Y + buttonArea.Height > formPosition.Y + formSize.Y - 25f)
        //        bVisible = false;
        //    else
        //        bVisible = true;
        //} 
        #endregion

        #region Draw

        public override void Draw( SpriteBatch spriteBatch, float alpha )
        {
            Color dynamicColor = Color.White;

            if (!bMouseOver && !bPressed)
                dynamicColor = new Color( new Vector4( color.ToVector3().X * 0.95f, color.ToVector3().Y * 0.95f, color.ToVector3().Z * 0.95f, alpha ) );
            else if (bPressed)
                dynamicColor = new Color( new Vector4( color.ToVector3().X * 0.9f, color.ToVector3().Y * 0.9f, color.ToVector3().Z * 0.9f, alpha ) );
            else if (bMouseOver)
                dynamicColor = new Color( new Vector4( color.ToVector3().X * 1.5f, color.ToVector3().Y * 1.5f, color.ToVector3().Z * 1.5f, alpha ) );

            spriteBatch.Draw( buttonTexture, destRect[0], sourceRect[0], dynamicColor, 0, Vector2.Zero, SpriteEffects.None, LayerDepth.UI );
            spriteBatch.Draw( buttonTexture, destRect[1], sourceRect[1], dynamicColor, 0, Vector2.Zero, SpriteEffects.None, LayerDepth.UI );
            spriteBatch.Draw( buttonTexture, destRect[2], sourceRect[2], dynamicColor, 0, Vector2.Zero, SpriteEffects.None, LayerDepth.UI );

            Color dynamicTextColor = new Color( new Vector4( 0f, 0f, 0f, alpha ) );

            int spacing = (destRect[1].Width - text.Length * fontSize.X) / 2;
            BaseGame.FontMgr.DrawInScrnCoord( text, new Vector2( destRect[0].X + destRect[0].Width + spacing, destRect[0].Y + 3f ), Control.fontScale, dynamicTextColor, LayerDepth.Text, Control.fontName );
        }
        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;

namespace TankEngine2D.Helpers
{
    /// <summary>
    /// Log will create automatically a log file and write
    /// log/error/debug info for simple runtime error checking, very useful
    /// for minor errors, such as finding not files.
    /// The application can still continue working, but this log provides
    /// an easy support to find out what files are missing (in this example).
    /// </summary>
    public static class Log
    {
        #region Variables
        /// <summary>
        /// Writer
        /// </summary>
        private static StreamWriter writer = null;

        /// <summary>
        /// Log filename
        /// </summary>
        private const string LogFilename = "Log.txt";
        #endregion

        static bool initialized = false;

        #region Static constructor to create log file
        /// <summary>
        /// Static constructor
        /// </summary>
        public static void Initialize ()
        {
            if (initialized && writer != null)
                return;

            initialized = true;

            try
            {
                // Open file
                FileStream file = File.Open( LogFilename, FileMode.OpenOrCreate | FileMode.Append, FileAccess.Write );
                //old: new FileStream(
                //    LogFilename, FileMode.OpenOrCreate,
                //    FileAccess.Write, FileShare.ReadWrite);

                // Associate writer with that, when writing to a new file,
                // make sure UTF-8 sign is written, else don't write it again!
                if (file.Length == 0)
                    writer = new StreamWriter( file,
                        System.Text.Encoding.UTF8 );
                else
                    writer = new StreamWriter( file );

                // Go to end of file
                writer.BaseStream.Seek( 0, SeekOrigin.End );

                // Enable auto flush (always be up to date when reading!)
                writer.AutoFlush = true;

                // Add some info about this session
                writer.WriteLine( "" );
                writer.WriteLine( "/// Session started at: " + DateTime.Now.ToString() );
                writer.WriteLine( "/// TankEngine2D" );
                writer.WriteLine( "" );
            }
            catch (IOException)
            {
                // Ignore any file exceptions, if file is not
                // createable (e.g. on a CD-Rom) it doesn't matter.
                initialized = false;
            }
            catch (UnauthorizedAccessException)
            {
                // Ignore any file exceptions, if file is not
                // createable (e.g. on a CD-Rom) it doesn't matter.
                initialized = false;
            }
        }
        #endregion

        #region Write log entry
        /// <summary>
        /// Writes a LogType and info/error message string to the Log file
        /// </summary>
        static public void Write ( string message )
        {
            // Can't continue without valid writer
            if (writer == null)
                return;

            try
            {
                DateTime ct = DateTime.Now;
                string s = "[" + ct.Hour.ToString( "00" ) + ":" +
                    ct.Minute.ToString( "00" ) + ":" +
                    ct.Second.ToString( "00" ) + "] " +
                    message;
                writer.WriteLine( s );

#if DEBUG
                // In debug mode write that message to the console as well!
                System.Console.WriteLine( s );
#endif
            }
            catch (IOException)
            {
                // Ignore any file exceptions, if file is not
                // createable (e.g. on a CD-Rom) it doesn't matter.
            }
            catch (UnauthorizedAccessException)
            {
                // Ignore any file exceptions, if file is not
                // createable (e.g. on a CD-Rom) it doesn't matter.
            }
        }
        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.GameObjs;
using SmartTank.PhiCol;
using SmartTank.Shelter;
using TankEngine2D.DataStructure;
using SmartTank.Senses.Vision;

namespace SmartTank.Scene
{
    public abstract class TypeGroup : Group
    {
        public TypeGroup ( string groupName )
            : base( groupName )
        {
        }

        public abstract bool AddObj ( IGameObj obj );
        public abstract bool DelObj ( string name );
        public abstract bool DelObj ( IGameObj obj );
        public abstract IGameObj GetObj ( string name );

        public abstract IEnumerable<CopyType> GetEnumerableCopy<CopyType> () where CopyType : class;
    }

    public class TypeGroup<T> : TypeGroup
        where T : class, IGameObj
    {
        protected MultiList<T> objs;

        protected bool asPhi = false;
        protected bool asCol = false;
        protected bool asShe = false;
        protected bool asRaderOwner = false;
        protected bool asEyeable = false;

        public MultiList<T> Objs
        {
            get { return objs; }
        }

        public TypeGroup ( string name )
            : base( name )
        {
            this.objs = new MultiList<T>();

            Type type = typeof( T );
            foreach (Type intfce in type.GetInterfaces())
            {
                if (intfce == typeof( IPhisicalObj ))
                    this.asPhi = true;
                if (intfce == typeof( ICollideObj ))
                    this.asCol = true;
                if (intfce == typeof( IShelterObj ))
                    this.asShe = true;
                if (intfce == typeof( IRaderOwner ))
                    this.asRaderOwner = true;
                if (intfce == typeof( IEyeableObj ))
                    this.asEyeable = true;
            }
        }

        public bool AddObj ( T obj )
        {
            return objs.Add( obj.Name, obj );
        }

        public override bool DelObj ( string objName )
        {
            return objs.Remove( objName );
        }

        public override bool DelObj ( IGameObj obj )
        {
            return DelObj( obj.Name );
        }

        public override bool AddObj ( IGameObj obj )
        {
            return AddObj( (T)obj );
        }

        public override IGameObj GetObj ( string name )
        {
            return objs[name];
        }

        public override IEnumerable<CopyType> GetEnumerableCopy<CopyType> ()
        {
            return objs.GetCopy<CopyType>();
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace Common.DataStructure
{
    /// <summary>
    /// 表示有权无向图的路径
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public struct GraphPath<T>
    {
        /// <summary>
        /// 与当前节点通过该路径相连的节点
        /// </summary>
        public GraphPoint<T> neighbor;

        /// <summary>
        /// 路径上的权值
        /// </summary>
        public float weight;

        /// <summary>
        ///
        /// </summary>
        /// <param name="neighbor">与当前节点通过该路径相连的节点</param>
        /// <param name="weight">路径上的权值</param>
        public GraphPath ( GraphPoint<T> neighbor, float weight )
        {
            this.neighbor = neighbor;
            this.weight = weight;
        }
    }

    /// <summary>
    /// 有权无向图中的节点
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class GraphPoint<T>
    {
        /// <summary>
        /// 复制一幅图。复制图的节点，但不复制节点中的值。
        /// </summary>
        /// <param name="graph"></param>
        /// <returns></returns>
        static public GraphPoint<T>[] DepthCopy ( GraphPoint<T>[] graph )
        {
            GraphPoint<T>[] result = new GraphPoint<T>[graph.Length];

            Dictionary<GraphPoint<T>, int> indexCahe = new Dictionary<GraphPoint<T>, int>();

            for (int i = 0; i < graph.Length; i++)
            {
                result[i] = new GraphPoint<T>( graph[i].value, new List<GraphPath<T>>() );
                indexCahe.Add( graph[i], i );
            }

            for (int i = 0; i < graph.Length; i++)
            {
                foreach (GraphPath<T> path in graph[i].neighbors)
                {
                    Link( result[indexCahe[path.neighbor]], result[i], path.weight );
                }
            }

            return result;
        }

        /// <summary>
        /// 节点中的值
        /// </summary>
        public T value;

        /// <summary>
        /// 通向相连节点的路径的列表
        /// </summary>
        public List<GraphPath<T>> neighbors;

        /// <summary>
        /// 空构造函数
        /// </summary>
        public GraphPoint ()
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value">节点中的值</param>
        /// <param name="neighbors">通向相连节点的路径的列表</param>
        public GraphPoint ( T value, List<GraphPath<T>> neighbors )
        {
            this.value = value;
            this.neighbors = neighbors;
        }

        /// <summary>
        /// 连接两个有权无向图节的节点
        /// </summary>
        /// <param name="p1">节点1</param>
        /// <param name="p2">节点2</param>
        /// <param name="weight">路径上的权重值</param>
        public static void Link ( GraphPoint<T> p1, GraphPoint<T> p2, float weight )
        {
            p1.neighbors.Add( new GraphPath<T>( p2, weight ) );
            p2.neighbors.Add( new GraphPath<T>( p1, weight ) );
        }
    }


}
<file_sep>#ifndef _MYTHREAD_H_
#define _MYTHREAD_H_

#include "mysocket.h"
#include "ClientManager.h"


#ifdef WIN32 
    #define THREADHEAD int
#else
    #define THREADHEAD void *
#endif

THREADHEAD   ThreadClient(void* pparam);
THREADHEAD   ThreadSend  (void* pparam);
bool  DoServercommand(ClientManager *pManager, char* msg);

/* 线程参数 */
typedef struct _ThreadParam_Target
{
    MySocket *sock;     // 服务器套接字
    ClientManager *mgr; // 用户管理器
}ThreadParam, *PThreadParam;




#endif






<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace SmartTank.PhiCol
{
    public interface ISyncable
    {
        void SetServerStatue(Vector2 serPos, Vector2 serVel, float serAzi, float serAziVel, float syncTime, bool velChangeIme);
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.GameObjs.Item;
using Microsoft.Xna.Framework;
using System.IO;
using SmartTank.Helpers;
using SmartTank.net;

namespace InterRules.Starwar
{
    enum RockTexNo
    {
        oo1,
        ooo1,
        oo2,
        ooo2,
        oo3,
        ooo3,
        Max,
    }

    class Rock : ItemCommon
    {
        static string[] texPaths = {
            "field_map_001.png","field_map_0001.png",
            "field_map_002.png","field_map_0002.png",
            "field_map_003.png","field_map_0003.png",
            "field_map_004.png","field_map_0004.png"};
        static Vector2[] texOrigin = {
            new Vector2(150,120),new Vector2(37,32),
            new Vector2(75,60),new Vector2(60,45),
            new Vector2(74,63),new Vector2(60,32),
            new Vector2(60,45),new Vector2(50,47)};


        public Rock(string name, Vector2 startPos, Vector2 vel, float aziVel, float scale, int texNo)
            : base(name, "Rock", "",
            Path.Combine(Directories.ContentDirectory, "Rules\\SpaceWar\\image\\" + texPaths[texNo]),
            texOrigin[texNo], scale,new Vector2[0], startPos, 0, vel, aziVel)
        {
        }

        public override void Update(float seconds)
        {
            base.Update(seconds);
            SyncCasheWriter.SubmitNewStatus(this.MgPath, "Pos", SyncImportant.HighFrequency, Pos);
            SyncCasheWriter.SubmitNewStatus(this.MgPath, "Vel", SyncImportant.HighFrequency, Vel);
            SyncCasheWriter.SubmitNewStatus(this.MgPath, "Azi", SyncImportant.HighFrequency, Azi);
        }
        
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xna.Framework.Graphics;
using System.IO;
using SmartTank.GameObjs;
using TankEngine2D.Graphics;
using SmartTank.Helpers;

namespace GameObjEditor
{
    public partial class GameObjEditor : Form
    {
        #region TypeDef

        class TreeNodeObj : TreeNode
        {
            public GameObjData obj;

            public GameObjData GameObj
            {
                get { return obj; }
            }

            public TreeNodeObj ( string objName )
                : base( objName )
            {
                obj = new GameObjData( objName );
                TreeNodeNode baseNode = new TreeNodeNode( "Base" );
                TreeNodeNode.AddToChilds( this, baseNode );
                obj.creater = "your name";
                obj.year = DateTime.Today.Year;
                obj.month = DateTime.Today.Month;
                obj.day = DateTime.Today.Day;
            }

            public TreeNodeObj ( GameObjData data, string path )
                : base( data.name )
            {
                obj = data;
                TreeNodeNode baseNode = new TreeNodeNode( data.baseNode, path );
                TreeNodeNode.AddToChilds( this, baseNode, false );
            }

            public void Rename ( string newName )
            {
                if (newName == string.Empty)
                    return;

                Text = newName;
                obj.name = newName;
            }

            public TreeNodeNode BaseNode
            {
                get
                {
                    if (Nodes.Count == 1)
                        return (TreeNodeNode)this.Nodes[0];
                    else
                        return null;
                }
            }
        }

        class TreeNodeNode : TreeNode, IEnumerable<TreeNodeNode>
        {
            static public void AddToChilds ( TreeNode parent, TreeNodeNode child )
            {
                AddToChilds( parent, child, true );
            }

            static public void AddToChilds ( TreeNode parent, TreeNodeNode child, bool addDataNodeChild )
            {
                if (parent is TreeNodeObj)
                {
                    if (((TreeNodeObj)parent).BaseNode == null)
                    {
                        if (addDataNodeChild)
                            ((TreeNodeObj)parent).GameObj.baseNode = child.dateNode;
                        parent.Nodes.Add( child );
                    }
                }
                else if (parent is TreeNodeNode)
                {
                    if (addDataNodeChild)
                    {
                        ((TreeNodeNode)parent).dateNode.childNodes.Add( child.dateNode );
                        child.dateNode.parent = ((TreeNodeNode)parent).dateNode;
                    }
                    parent.Nodes.Add( child );
                }
            }

            static public void RemoveChild ( TreeNodeNode parent, TreeNodeNode child )
            {
                parent.Nodes.Remove( child );
                parent.dateNode.childNodes.Remove( child.dateNode );
            }

            GameObjDataNode dateNode;

            List<string> texNames;

            List<Texture2D> textures;
            List<Bitmap> bitmaps;

            int curTexIndex = -1;
            int curVisiPointIndex = -1;
            int curStructPointIndex = -1;

            public TreeNodeNode ( string text )
                : base( text )
            {
                textures = new List<Texture2D>();
                bitmaps = new List<Bitmap>();
                texNames = new List<string>();
                borderMaps = new List<SpriteBorder.BorderMap>();
                dateNode = new GameObjDataNode( text );
            }

            public TreeNodeNode ( GameObjDataNode dateNode, string path )
                : this( dateNode.nodeName )
            {
                this.dateNode = dateNode;

                foreach (string texName in dateNode.texPaths)
                {
                    AddTex( Path.Combine( path, texName ), GameObjEditor.device, false );
                }

                foreach (GameObjDataNode child in dateNode.childNodes)
                {
                    TreeNodeNode childNode = new TreeNodeNode( child, path );
                    AddToChilds( this, childNode, false );
                }

            }

            public void Rename ( string newName )
            {
                if (newName == string.Empty)
                    return;

                Text = newName;
                dateNode.nodeName = newName;
            }

            public List<string> TexNames
            {
                get
                {
                    return texNames;
                }
            }

            public List<Microsoft.Xna.Framework.Vector2> VisiPoints
            {
                get { return dateNode.visiKeyPoints; }
            }

            public List<Microsoft.Xna.Framework.Vector2> StructPoints
            {
                get { return dateNode.structKeyPoints; }
            }

            public List<Texture2D> Textures
            {
                get { return textures; }
            }

            public int CurTexIndex
            {
                get { return curTexIndex; }
                set { curTexIndex = value; }
            }

            public int CurVisiPointIndex
            {
                get { return curVisiPointIndex; }
                set { curVisiPointIndex = value; }
            }

            public int CurStructPointIndex
            {
                get { return curStructPointIndex; }
                set { curStructPointIndex = value; }
            }

            public Texture2D CurXNATex
            {
                get
                {
                    if (curTexIndex >= 0 && curTexIndex < bitmaps.Count)
                        return textures[curTexIndex];
                    else
                        return null;
                }
            }

            public Bitmap CurBitMap
            {
                get
                {
                    if (curTexIndex >= 0 && curTexIndex < bitmaps.Count)
                        return bitmaps[curTexIndex];
                    else
                        return null;
                }
            }

            public SpriteBorder.BorderMap CurBorderMap
            {
                get
                {
                    if (curTexIndex >= 0 && curTexIndex < bitmaps.Count)
                        return borderMaps[curTexIndex];
                    else
                        return null;
                }
            }

            public TreeNodeObj TreeNodeObj
            {
                get
                {
                    TreeNode obj = this;
                    while (obj.Parent != null)
                    {
                        obj = obj.Parent;
                        if (obj is TreeNodeObj)
                            return (TreeNodeObj)obj;
                    }
                    return null;
                }
            }

            public List<SpriteBorder.BorderMap> borderMaps;

            public void AddTex ( string filePath, GraphicsDevice device, bool addDataNodeTexPath )
            {
                textures.Add( Texture2D.FromFile( device, filePath ) );
                bitmaps.Add( new Bitmap( filePath ) );
                texNames.Add( Path.GetFileName( filePath ) );
                borderMaps.Add( null );
                if (addDataNodeTexPath)
                    dateNode.texPaths.Add( Path.GetFileName( filePath ) );
                curTexIndex = textures.Count - 1;
            }

            public void DelTex ( int index )
            {
                if (index < 0 || index >= textures.Count)
                    return;

                textures.RemoveAt( index );
                bitmaps.RemoveAt( index );
                texNames.RemoveAt( index );
                borderMaps.RemoveAt( index );
                dateNode.texPaths.RemoveAt( index );
                curTexIndex--;
            }

            public void SetBorderMap ( SpriteBorder.BorderMap borderMap )
            {
                borderMaps[curTexIndex] = borderMap;
            }

            public void UpTex ( int index )
            {
                if (index <= 0 || index >= textures.Count)
                    return;

                Texture2D tempTex = textures[index];
                textures[index] = textures[index - 1];
                textures[index - 1] = tempTex;

                Bitmap tempBitmap = bitmaps[index];
                bitmaps[index] = bitmaps[index - 1];
                bitmaps[index - 1] = tempBitmap;

                string tempName = texNames[index];
                texNames[index] = texNames[index - 1];
                texNames[index - 1] = tempName;

                string tempPath = dateNode.texPaths[index];
                dateNode.texPaths[index] = dateNode.texPaths[index - 1];
                dateNode.texPaths[index - 1] = tempPath;

                curTexIndex--;
            }

            public void downTex ( int index )
            {
                if (index < 0 || index >= textures.Count - 1)
                    return;

                Texture2D tempTex = textures[index];
                textures[index] = textures[index + 1];
                textures[index + 1] = tempTex;

                Bitmap tempBitmap = bitmaps[index];
                bitmaps[index] = bitmaps[index + 1];
                bitmaps[index + 1] = tempBitmap;

                string tempName = texNames[index];
                texNames[index] = texNames[index + 1];
                texNames[index + 1] = tempName;

                string tempPath = dateNode.texPaths[index];
                dateNode.texPaths[index] = dateNode.texPaths[index + 1];
                dateNode.texPaths[index + 1] = tempPath;

                curTexIndex++;
            }

            public void AddVisiPoint ( float x, float y )
            {
                dateNode.visiKeyPoints.Add( new Microsoft.Xna.Framework.Vector2( x, y ) );

                curVisiPointIndex = dateNode.visiKeyPoints.Count - 1;
            }

            public void DelVisiPoint ()
            {
                if (curVisiPointIndex < 0 || curVisiPointIndex >= dateNode.visiKeyPoints.Count)
                    return;

                dateNode.visiKeyPoints.RemoveAt( curVisiPointIndex );

                curVisiPointIndex--;
            }

            public void UpVisiPoint ()
            {
                if (curVisiPointIndex <= 0 || curVisiPointIndex >= dateNode.visiKeyPoints.Count)
                    return;

                Microsoft.Xna.Framework.Vector2 temp = dateNode.visiKeyPoints[curVisiPointIndex];
                dateNode.visiKeyPoints[curVisiPointIndex] = dateNode.visiKeyPoints[curVisiPointIndex - 1];
                dateNode.visiKeyPoints[curVisiPointIndex - 1] = temp;

                curVisiPointIndex--;
            }

            public void DownVisiPoint ()
            {
                if (curVisiPointIndex < 0 || curVisiPointIndex >= dateNode.visiKeyPoints.Count - 1)
                    return;

                Microsoft.Xna.Framework.Vector2 temp = dateNode.visiKeyPoints[curVisiPointIndex];
                dateNode.visiKeyPoints[curVisiPointIndex] = dateNode.visiKeyPoints[curVisiPointIndex + 1];
                dateNode.visiKeyPoints[curVisiPointIndex + 1] = temp;

                curVisiPointIndex++;
            }

            public void AddStructPoint ( float x, float y )
            {
                dateNode.structKeyPoints.Add( new Microsoft.Xna.Framework.Vector2( x, y ) );

                curStructPointIndex = dateNode.structKeyPoints.Count - 1;
            }

            public void DelStructiPoint ()
            {
                if (curStructPointIndex < 0 || curStructPointIndex >= dateNode.structKeyPoints.Count)
                    return;

                dateNode.structKeyPoints.RemoveAt( curStructPointIndex );

                curStructPointIndex--;
            }

            public void UpStructPoint ()
            {
                if (curStructPointIndex <= 0 || curStructPointIndex >= dateNode.structKeyPoints.Count)
                    return;

                Microsoft.Xna.Framework.Vector2 temp = dateNode.structKeyPoints[curStructPointIndex];
                dateNode.structKeyPoints[curStructPointIndex] = dateNode.structKeyPoints[curStructPointIndex - 1];
                dateNode.structKeyPoints[curStructPointIndex - 1] = temp;

                curStructPointIndex--;
            }

            public void DownStructPoint ()
            {
                if (curStructPointIndex < 0 || curStructPointIndex >= dateNode.structKeyPoints.Count - 1)
                    return;

                Microsoft.Xna.Framework.Vector2 temp = dateNode.structKeyPoints[curStructPointIndex];
                dateNode.structKeyPoints[curStructPointIndex] = dateNode.structKeyPoints[curStructPointIndex + 1];
                dateNode.structKeyPoints[curStructPointIndex + 1] = temp;

                curStructPointIndex++;
            }

            public List<int> IntDatas
            {
                get { return dateNode.intDatas; }
            }

            public List<float> FloatDatas
            {
                get { return dateNode.floatDatas; }
            }

            public void AddIntData ( int value )
            {
                dateNode.intDatas.Add( value );
            }

            public void AddFloatData ( float value )
            {
                dateNode.floatDatas.Add( value );
            }

            public void DelIntData ( int index )
            {
                if (dateNode.intDatas.Count > index)
                {
                    dateNode.intDatas.RemoveAt( index );
                }
            }

            public void DelFloatData ( int index )
            {
                if (dateNode.floatDatas.Count > index)
                {
                    dateNode.floatDatas.RemoveAt( index );
                }
            }

            #region IEnumerable<TreeNodeEnum> 成员

            public IEnumerator<TreeNodeNode> GetEnumerator ()
            {
                yield return this;

                foreach (TreeNode childNode in Nodes)
                {
                    if (!(childNode is TreeNodeNode))
                        throw new Exception( "childNode isn't a TreeNodeEnum." );

                    foreach (TreeNodeNode downNode in (TreeNodeNode)childNode)
                    {
                        yield return downNode;
                    }
                }
            }

            #endregion

            #region IEnumerable 成员

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
            {
                return GetEnumerator();
            }

            #endregion
        }

        #endregion

        #region Variables

        ContextMenuStrip treeMenuStrip;
        ContextMenuStrip texListMenuStrip;
        ContextMenuStrip pictureMenuStrip;
        ContextMenuStrip pointMenuStrip;
        ContextMenuStrip dataMenuStrip;


        TreeNode CurTreeNode
        {
            get { return treeView.SelectedNode; }
            set { treeView.SelectedNode = value; }
        }

        TreeNodeNode CurNodeNode
        {
            get
            {
                if (CurTreeNode != null && CurTreeNode is TreeNodeNode)
                {
                    return (TreeNodeNode)CurTreeNode;
                }
                else
                    return null;
            }
        }

        TreeNodeObj CurTreeObj
        {
            get
            {
                if (CurTreeNode != null)
                {
                    if (CurTreeNode is TreeNodeObj)
                    {
                        return (TreeNodeObj)CurTreeNode;
                    }
                    else
                    {
                        return ((TreeNodeNode)CurTreeNode).TreeNodeObj;
                    }
                }
                else
                    return null;
            }
        }

        static GraphicsDevice device;

        int CurTexIndex
        {
            get
            {
                if (CurTreeNode != null && CurTreeNode is TreeNodeNode)
                    return ((TreeNodeNode)CurTreeNode).CurTexIndex;
                else
                    return -1;
            }
            set
            {
                if (CurTreeNode != null && CurTreeNode is TreeNodeNode)
                    ((TreeNodeNode)CurTreeNode).CurTexIndex = value;
            }
        }

        Texture2D CurXNATex
        {
            get
            {
                if (CurTreeNode != null && CurTreeNode is TreeNodeNode)
                {
                    return ((TreeNodeNode)CurTreeNode).CurXNATex;
                }
                else
                    return null;
            }
        }

        Bitmap CurBitMap
        {
            get
            {
                if (CurTreeNode != null && CurTreeNode is TreeNodeNode)
                    return ((TreeNodeNode)CurTreeNode).CurBitMap;
                else
                    return null;
            }
        }

        SpriteBorder.BorderMap CurBorderMap
        {
            get
            {
                if (CurXNATex != null)
                    return ((TreeNodeNode)CurTreeNode).CurBorderMap;
                else
                    return null;
            }
        }

        enum TabState
        {
            Texture,
            VisiPoint,
            StructPoint,
            IntData,
            FloatData,
        }

        TabState CurTabState
        {
            get
            {
                if (tabControl1.SelectedTab == texTab)
                {
                    return TabState.Texture;
                }
                else if (tabControl1.SelectedTab == visiPointTab)
                {
                    return TabState.VisiPoint;
                }
                else if (tabControl1.SelectedTab == structPointTab)
                {
                    return TabState.StructPoint;
                }
                else if (tabControl1.SelectedTab == intDataTab)
                {
                    return TabState.IntData;
                }
                else
                {
                    return TabState.FloatData;
                }
            }
        }


        Bitmap visiPointMap;
        Bitmap structPointMap;

        #endregion

        public GameObjEditor ()
        {
            visiPointMap = new Bitmap( "Content\\pointBlue.png" );
            structPointMap = new Bitmap( "Content\\pointRed.png" );

            InitializeComponent();
            InitialTreeViewContentMenu();
            InitialTexContentMenu();
            InitialGraphicsDevice();
            InitialTexContentMenu();
            InitialPictureBoxContentMenu();
            InitialPointContentMenu();

            InitialDataListContentMenu();

            pictureBox.LastPaint += new PaintEventHandler( pictureBox_LastPaint );

        }

        private void InitialGraphicsDevice ()
        {
            PresentationParameters pp = new PresentationParameters();
            pp.BackBufferCount = 1;
            pp.IsFullScreen = false;
            pp.SwapEffect = SwapEffect.Discard;
            pp.BackBufferWidth = this.Width;
            pp.BackBufferHeight = this.Height;

            pp.AutoDepthStencilFormat = DepthFormat.Depth24Stencil8;
            pp.EnableAutoDepthStencil = true;
            pp.PresentationInterval = PresentInterval.Default;
            pp.BackBufferFormat = SurfaceFormat.Unknown;
            pp.MultiSampleType = MultiSampleType.None;

            device = new GraphicsDevice( GraphicsAdapter.DefaultAdapter,
                DeviceType.Hardware, this.Handle,
                pp );
        }

        private void UpdateComponent ()
        {
            UpdateTreeContentMenu();
            UpdateTexPathList();
            UpdateTexListContentMenu();
            UpdateMenu();
            UpdatePictureBox();
            UpdatePictureMenuStrip();
            UpdateVisiList();
            UpdateStructList();
            UpdatePointContentMenu();
            UpdateStatusBar();
            UpdateDataList();
        }

        private void tabControl1_SelectedIndexChanged ( object sender, EventArgs e )
        {
            UpdateComponent();
        }

        #region TreeViewContentMenu

        void InitialTreeViewContentMenu ()
        {
            treeMenuStrip = new ContextMenuStrip();

            ToolStripMenuItem addNewObjLabel = new ToolStripMenuItem();
            addNewObjLabel.Name = "添加新物体";
            addNewObjLabel.Text = "添加新物体";
            ToolStripMenuItem delObjLabel = new ToolStripMenuItem();
            delObjLabel.Name = "删除物体";
            delObjLabel.Text = "删除物体";
            ToolStripMenuItem addChildLabel = new ToolStripMenuItem();
            addChildLabel.Name = "添加子节点";
            addChildLabel.Text = "添加子节点";
            ToolStripMenuItem delNodeLabel = new ToolStripMenuItem();
            delNodeLabel.Name = "删除节点";
            delNodeLabel.Text = "删除节点";
            ToolStripMenuItem renameLabel = new ToolStripMenuItem();
            renameLabel.Name = "重命名";
            renameLabel.Text = "重命名";

            treeMenuStrip.Items.AddRange( new ToolStripMenuItem[] { addNewObjLabel, delObjLabel, addChildLabel, delNodeLabel, renameLabel } );

            treeView.ContextMenuStrip = treeMenuStrip;

            addNewObjLabel.Click += new EventHandler( addNewObjLabel_Click );
            delObjLabel.Click += new EventHandler( delObjLabel_Click );
            addChildLabel.Click += new EventHandler( addChildLabel_Click );
            delNodeLabel.Click += new EventHandler( delNodeLabel_Click );
            renameLabel.Click += new EventHandler( renameLabel_Click );

            AddNewObj();

        }

        void addNewObjLabel_Click ( object sender, EventArgs e )
        {
            AddNewObj();
            UpdateComponent();
        }

        void delObjLabel_Click ( object sender, EventArgs e )
        {
            DialogResult result = MessageBox.Show( "这将删除当前正在编辑的场景物体，是否继续？", "确定删除", MessageBoxButtons.YesNo );
            if (result == DialogResult.No)
                return;
            DelObj();
            UpdateComponent();
        }

        void addChildLabel_Click ( object sender, EventArgs e )
        {
            AddNode();
            UpdateComponent();
        }

        void delNodeLabel_Click ( object sender, EventArgs e )
        {
            DialogResult result = MessageBox.Show( "这将删除当前的节点，是否继续？", "确定删除", MessageBoxButtons.YesNo );
            if (result == DialogResult.No)
                return;
            DelNode();
            UpdateComponent();
        }

        void renameLabel_Click ( object sender, EventArgs e )
        {
            Rename rename = new Rename();
            rename.NameText = CurTreeNode.Text;
            rename.ShowDialog();

            if (CurTreeNode is TreeNodeObj)
            {
                ((TreeNodeObj)CurTreeNode).Rename( rename.NameText );
            }
            else if (CurTreeNode is TreeNodeNode)
            {
                ((TreeNodeNode)CurTreeNode).Rename( rename.NameText );
            }
            UpdateComponent();
        }

        private void treeView_AfterSelect ( object sender, TreeViewEventArgs e )
        {
            UpdateComponent();
        }

        private void treeView_MouseClick ( object sender, MouseEventArgs e )
        {
            TreeNode node = treeView.GetNodeAt( e.X, e.Y );
            CurTreeNode = node;
            UpdateComponent();
        }


        private void UpdateTreeContentMenu ()
        {
            treeMenuStrip.Items["删除物体"].Enabled = true;
            treeMenuStrip.Items["添加子节点"].Enabled = true;
            treeMenuStrip.Items["删除节点"].Enabled = true;
            treeMenuStrip.Items["重命名"].Enabled = true;

            if (CurTreeNode == null)
            {
                treeMenuStrip.Items["删除物体"].Enabled = false;
                treeMenuStrip.Items["添加子节点"].Enabled = false;
                treeMenuStrip.Items["删除节点"].Enabled = false;
                treeMenuStrip.Items["重命名"].Enabled = false;
            }
            else if (CurTreeNode is TreeNodeObj)
            {
                treeMenuStrip.Items["添加子节点"].Enabled = false;
                treeMenuStrip.Items["删除节点"].Enabled = false;
            }
            else if (CurTreeNode is TreeNodeNode && CurTreeNode.Parent is TreeNodeObj)
            {
                treeMenuStrip.Items["删除节点"].Enabled = false;
            }
        }

        void AddNewObj ()
        {
            TreeNodeObj newObjNode = new TreeNodeObj( "NewGameObj" );
            treeView.Nodes.Add( newObjNode );
            newObjNode.Expand();
            CurTreeNode = newObjNode.Nodes[0];
        }

        void DelObj ()
        {
            if (CurTreeNode is TreeNodeObj)
            {
                treeView.Nodes.Remove( CurTreeNode );
            }
            else if (CurTreeNode is TreeNodeNode)
            {
                treeView.Nodes.Remove( ((TreeNodeNode)CurTreeNode).TreeNodeObj );
            }
        }

        void AddNode ()
        {
            if (CurTreeNode == null)
                return;

            TreeNodeNode newTreeNode = new TreeNodeNode( "newNode" );
            TreeNodeNode.AddToChilds( CurTreeNode, newTreeNode );
            CurTreeNode = newTreeNode;
        }

        void DelNode ()
        {
            if (CurTreeNode == null)
                return;

            if (CurTreeNode is TreeNodeNode && CurTreeNode.Parent is TreeNodeNode)
            {
                TreeNodeNode.RemoveChild( (TreeNodeNode)CurTreeNode.Parent, (TreeNodeNode)CurTreeNode );
            }
        }

        #endregion

        #region TexListContentMenu

        void InitialTexContentMenu ()
        {
            texListMenuStrip = new ContextMenuStrip();

            ToolStripMenuItem importTexLabel = new ToolStripMenuItem();
            importTexLabel.Name = "导入贴图";
            importTexLabel.Text = "导入贴图";
            ToolStripMenuItem delTexLabel = new ToolStripMenuItem();
            delTexLabel.Name = "移除贴图";
            delTexLabel.Text = "移除贴图";
            ToolStripMenuItem upTexLabel = new ToolStripMenuItem();
            upTexLabel.Name = "上移";
            upTexLabel.Text = "上移";
            ToolStripMenuItem downTexLabel = new ToolStripMenuItem();
            downTexLabel.Name = "下移";
            downTexLabel.Text = "下移";
            ToolStripMenuItem checkBorderLabel = new ToolStripMenuItem();
            checkBorderLabel.Name = "提取边界";
            checkBorderLabel.Text = "提取边界";

            texListMenuStrip.Items.AddRange( new ToolStripItem[] { importTexLabel, delTexLabel, upTexLabel, downTexLabel, checkBorderLabel } );

            importTexLabel.Click += new EventHandler( importTexLabel_Click );
            delTexLabel.Click += new EventHandler( delTexLabel_Click );
            upTexLabel.Click += new EventHandler( upTexLabel_Click );
            downTexLabel.Click += new EventHandler( downTexLabel_Click );
            checkBorderLabel.Click += new EventHandler( checkBorderLabel_Click );

            listViewTex.ContextMenuStrip = texListMenuStrip;
        }

        void importTexLabel_Click ( object sender, EventArgs e )
        {
            LoadTex();
            UpdateComponent();
            pictureBox.Invalidate();
        }

        void delTexLabel_Click ( object sender, EventArgs e )
        {
            DelTex();
            UpdateComponent();
            pictureBox.Invalidate();
        }

        void upTexLabel_Click ( object sender, EventArgs e )
        {
            UpTex();
            UpdateComponent();
            pictureBox.Invalidate();
        }

        void downTexLabel_Click ( object sender, EventArgs e )
        {
            DownTex();
            UpdateComponent();
            pictureBox.Invalidate();
        }

        void checkBorderLabel_Click ( object sender, EventArgs e )
        {
            if (CheckBorder())
                MessageBox.Show( "生成边界成功！" );
            else
                MessageBox.Show( "生成边界失败！" );
            pictureBox.Invalidate();
        }

        void UpdateTexPathList ()
        {
            listViewTex.Items.Clear();

            if (CurTreeNode == null || CurTreeNode is TreeNodeObj)
                return;

            int i = 0;
            foreach (string texName in ((TreeNodeNode)CurTreeNode).TexNames)
            {
                ListViewItem item = listViewTex.Items.Add( i.ToString() );
                item.SubItems.Add( texName );
                i++;
            }

            if (CurTexIndex != -1 && CurTexIndex < listViewTex.Items.Count)
                listViewTex.Items[CurTexIndex].Selected = true;
        }

        private void listViewTex_MouseClick ( object sender, MouseEventArgs e )
        {
            CurTexIndex = listViewTex.GetItemAt( e.X, e.Y ).Index;
            UpdateComponent();
        }

        void UpdateTexListContentMenu ()
        {
            texListMenuStrip.Items["移除贴图"].Enabled = true;
            texListMenuStrip.Items["上移"].Enabled = true;
            texListMenuStrip.Items["下移"].Enabled = true;
            texListMenuStrip.Items["提取边界"].Enabled = true;


            if (CurTexIndex == -1)
            {
                texListMenuStrip.Items["移除贴图"].Enabled = false;
                texListMenuStrip.Items["上移"].Enabled = false;
                texListMenuStrip.Items["下移"].Enabled = false;
                texListMenuStrip.Items["提取边界"].Enabled = false;
            }
            if (CurTexIndex == 0)
            {
                texListMenuStrip.Items["上移"].Enabled = false;
            }
            if (CurTexIndex == listViewTex.Items.Count - 1)
            {
                texListMenuStrip.Items["下移"].Enabled = false;
            }
        }

        void LoadTex ()
        {
            if (CurTreeNode != null && CurTreeNode is TreeNodeNode)
                openTexDialog.ShowDialog();
        }

        private void openTexDialog_FileOk ( object sender, CancelEventArgs e )
        {
            string texPath = openTexDialog.FileName;
            ((TreeNodeNode)CurTreeNode).AddTex( texPath, device, true );
            UpdateComponent();
        }

        void DelTex ()
        {
            if (CurTexIndex != -1 && CurTreeNode is TreeNodeNode)
            {
                ((TreeNodeNode)CurTreeNode).DelTex( CurTexIndex );
            }
        }

        void UpTex ()
        {
            if (CurTexIndex > 0 && CurTreeNode is TreeNodeNode)
            {
                ((TreeNodeNode)CurTreeNode).UpTex( CurTexIndex );
            }
        }

        void DownTex ()
        {
            if (CurTexIndex >= 0 && CurTreeNode is TreeNodeNode)
            {
                ((TreeNodeNode)CurTreeNode).downTex( CurTexIndex );
            }
        }

        #endregion

        #region CheckBorder

        Point errorPoint;
        bool showError = false;

        bool CheckBorder ()
        {
            if (CurXNATex != null)
            {
                bool success = true; ;
                try
                {
                    SpriteBorder.BorderMap borderMap;
                    Sprite.CheckBorder( CurXNATex, out borderMap );
                    ((TreeNodeNode)CurTreeNode).SetBorderMap( borderMap );
                }
                catch (BorderBulidException e)
                {
                    ((TreeNodeNode)CurTreeNode).SetBorderMap( e.borderMap );
                    success = false;
                    errorPoint = new Point( e.curPoint.X, e.curPoint.Y );
                    pictureBox.TexFocusPos = errorPoint;
                    pictureBox.Invalidate();
                }
                showError = !success;

                return success;
            }
            return false;
        }

        #endregion

        #region PointContentMenu

        void InitialPointContentMenu ()
        {
            pointMenuStrip = new ContextMenuStrip();

            ToolStripMenuItem delPoint = new ToolStripMenuItem();
            delPoint.Name = "删除关键点";
            delPoint.Text = "删除关键点";
            ToolStripMenuItem upPoint = new ToolStripMenuItem();
            upPoint.Name = "上升";
            upPoint.Text = "上升";
            ToolStripMenuItem downPoint = new ToolStripMenuItem();
            downPoint.Name = "下降";
            downPoint.Text = "下降";

            delPoint.Click += new EventHandler( delPoint_Click );
            upPoint.Click += new EventHandler( upPoint_Click );
            downPoint.Click += new EventHandler( downPoint_Click );

            pointMenuStrip.Items.AddRange( new ToolStripItem[] { delPoint, upPoint, downPoint } );

            listViewVisi.ContextMenuStrip = pointMenuStrip;
            listViewStruct.ContextMenuStrip = pointMenuStrip;
        }

        void UpdatePointContentMenu ()
        {
            pointMenuStrip.Items["删除关键点"].Enabled = true;
            pointMenuStrip.Items["上升"].Enabled = true;
            pointMenuStrip.Items["下降"].Enabled = true;

            if (CurTreeNode == null || CurTreeNode is TreeNodeObj)
            {
                pointMenuStrip.Items["删除关键点"].Enabled = false;
                pointMenuStrip.Items["上升"].Enabled = false;
                pointMenuStrip.Items["下降"].Enabled = false;
            }
            else
            {
                if (CurTabState == TabState.VisiPoint)
                {
                    int index = ((TreeNodeNode)CurTreeNode).CurVisiPointIndex;
                    int count = ((TreeNodeNode)CurTreeNode).VisiPoints.Count;
                    if (index < 0 || index >= count)
                    {
                        pointMenuStrip.Items["删除关键点"].Enabled = false;
                        pointMenuStrip.Items["上升"].Enabled = false;
                        pointMenuStrip.Items["下降"].Enabled = false;
                    }

                    if (index <= 0)
                    {
                        pointMenuStrip.Items["上升"].Enabled = false;
                    }
                    if (index >= count - 1)
                    {
                        pointMenuStrip.Items["下降"].Enabled = false;
                    }

                }
                else if (CurTabState == TabState.StructPoint)
                {
                    int index = ((TreeNodeNode)CurTreeNode).CurStructPointIndex;
                    int count = ((TreeNodeNode)CurTreeNode).StructPoints.Count;

                    if (index < 0 || index >= count)
                    {
                        pointMenuStrip.Items["删除关键点"].Enabled = false;
                        pointMenuStrip.Items["上升"].Enabled = false;
                        pointMenuStrip.Items["下降"].Enabled = false;
                    }

                    if (index <= 0)
                    {
                        pointMenuStrip.Items["上升"].Enabled = false;
                    }
                    if (index >= count - 1)
                    {
                        pointMenuStrip.Items["下降"].Enabled = false;
                    }
                }
            }
        }

        void delPoint_Click ( object sender, EventArgs e )
        {
            if (CurTreeNode == null)
                return;

            if (CurTabState == TabState.VisiPoint)
            {
                ((TreeNodeNode)CurTreeNode).DelVisiPoint();
            }
            else if (CurTabState == TabState.StructPoint)
            {
                ((TreeNodeNode)CurTreeNode).DelStructiPoint();
            }
            UpdateComponent();
        }

        void upPoint_Click ( object sender, EventArgs e )
        {
            if (CurTreeNode == null)
                return;

            if (CurTabState == TabState.VisiPoint)
            {
                ((TreeNodeNode)CurTreeNode).UpVisiPoint();
            }
            else if (CurTabState == TabState.StructPoint)
            {
                ((TreeNodeNode)CurTreeNode).UpStructPoint();
            }
            UpdateComponent();
        }

        void downPoint_Click ( object sender, EventArgs e )
        {
            if (CurTreeNode == null)
                return;

            if (CurTabState == TabState.VisiPoint)
            {
                ((TreeNodeNode)CurTreeNode).DownVisiPoint();
            }
            else if (CurTabState == TabState.StructPoint)
            {
                ((TreeNodeNode)CurTreeNode).DownStructPoint();
            }
            UpdateComponent();
        }

        void UpdateVisiList ()
        {
            if (CurTreeNode != null && CurTreeNode is TreeNodeNode)
            {
                listViewVisi.Items.Clear();
                int i = 0;
                foreach (Microsoft.Xna.Framework.Vector2 pos in ((TreeNodeNode)CurTreeNode).VisiPoints)
                {
                    ListViewItem item = new ListViewItem( i.ToString() );
                    listViewVisi.Items.Add( item );
                    item.SubItems.Add( "( " + pos.X + ", " + pos.Y + " )" );
                    i++;
                }
                int selectIndex = ((TreeNodeNode)CurTreeNode).CurVisiPointIndex;
                if (selectIndex >= 0 && selectIndex < i)
                    listViewVisi.Items[selectIndex].Selected = true;
            }
            else
            {
                listViewVisi.Items.Clear();
            }
        }

        void UpdateStructList ()
        {
            if (CurTreeNode != null && CurTreeNode is TreeNodeNode)
            {
                listViewStruct.Items.Clear();
                int i = 0;
                foreach (Microsoft.Xna.Framework.Vector2 pos in ((TreeNodeNode)CurTreeNode).StructPoints)
                {
                    ListViewItem item = new ListViewItem( i.ToString() );
                    listViewStruct.Items.Add( item );
                    item.SubItems.Add( "( " + pos.X + ", " + pos.Y + " )" );
                    i++;
                }

                int selectIndex = ((TreeNodeNode)CurTreeNode).CurStructPointIndex;
                if (selectIndex >= 0 && selectIndex < i)
                    listViewStruct.Items[selectIndex].Selected = true;
            }
            else
            {
                listViewStruct.Items.Clear();
            }
        }

        private void listViewVisi_MouseClick ( object sender, MouseEventArgs e )
        {
            ((TreeNodeNode)CurTreeNode).CurVisiPointIndex = listViewVisi.GetItemAt( e.X, e.Y ).Index;
            UpdateComponent();
        }

        private void listViewStruct_MouseClick ( object sender, MouseEventArgs e )
        {
            ((TreeNodeNode)CurTreeNode).CurStructPointIndex = listViewStruct.GetItemAt( e.X, e.Y ).Index;
            UpdateComponent();
        }

        #endregion

        #region Menu

        private void UpdateMenu ()
        {
            menuStrip.Items["texToolStripMenuItem"].Enabled = true;
            saveToolStripMenuItem.Enabled = true;

            if (CurTreeNode == null || !(CurTreeNode is TreeNodeNode))
            {
                menuStrip.Items["texToolStripMenuItem"].Enabled = false;
            }

            if (CurTreeNode == null)
            {
                saveToolStripMenuItem.Enabled = false;
            }
        }

        private void ImportToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            LoadTex();
            pictureBox.Invalidate();
        }

        private void ExitToolStripMenuItem_Click ( object sender, EventArgs e )
        {

        }

        private void SaveToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            Save();
        }

        private void OpenToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            Open();
        }

        private void BorderToolStripMenuItem_Click ( object sender, EventArgs e )
        {

        }

        void Save ()
        {
            TreeNodeObj curObj;
            if (CurTreeNode is TreeNodeObj)
            {
                curObj = (TreeNodeObj)CurTreeNode;
            }
            else
            {
                curObj = ((TreeNodeNode)CurTreeNode).TreeNodeObj;
            }

            if (curObj.BaseNode == null)
                return;

            EnterYourName enterName = new EnterYourName( "保存" + curObj.obj.name + "场景物体中，请输入您的名字以便储存。" );

            enterName.ShowDialog();
            if (enterName.SelectYes)
            {
                curObj.obj.creater = enterName.CreatorName;



                string savePath = Path.Combine( Directories.GameObjsDirectory, curObj.obj.creater );

                if (!Directory.Exists( savePath ))
                {
                    Directory.CreateDirectory( savePath );
                }

                savePath = Path.Combine( savePath, curObj.obj.name );

                if (!Directory.Exists( savePath ))
                {
                    Directory.CreateDirectory( savePath );
                }

                foreach (TreeNodeNode node in curObj.BaseNode)
                {
                    int i = 0;
                    foreach (Texture2D texture in node.Textures)
                    {
                        string saveFile = Path.Combine( savePath, node.TexNames[i] );
                        if (File.Exists( saveFile ))
                        {
                            DialogResult result = MessageBox.Show( "贴图文件已存在，是否覆盖？", "文件已存在", MessageBoxButtons.YesNo );
                            if (result == DialogResult.No)
                                return;
                            else
                                File.Delete( saveFile );
                        }
                        texture.Save( Path.Combine( savePath, node.TexNames[i] ), ImageFileFormat.Png );
                        i++;
                    }
                }

                string filePath = Path.Combine( savePath, curObj.obj.name + ".xml" );
                if (File.Exists( filePath ))
                {
                    DialogResult result = MessageBox.Show( "XML文件已存在，是否覆盖？", "文件已存在", MessageBoxButtons.YesNo );
                    if (result == DialogResult.No)
                        return;
                    else
                        File.Delete( filePath );
                }

                FileStream stream = File.Create( filePath );

                GameObjData.Save( stream, curObj.obj );
            }
        }

        void Open ()
        {
            openGameObjDialog.ShowDialog();
        }

        private void openGameObjDialog_FileOk ( object sender, CancelEventArgs e )
        {
            try
            {
                FileStream stream = File.OpenRead( openGameObjDialog.FileName );
                GameObjData newObj = GameObjData.Load( stream );

                string path = Path.GetDirectoryName( openGameObjDialog.FileName );
                TreeNodeObj newObjNode = new TreeNodeObj( newObj, path );
                treeView.Nodes.Add( newObjNode );
                newObjNode.Expand();
                CurTreeNode = newObjNode.Nodes[0];
            }
            catch (Exception)
            {
            }
        }

        #endregion

        #region PictureBox

        bool editMode = false;

        private void UpdatePictureBox ()
        {
            if (CurBitMap != null && pictureBox.CurBitMap != CurBitMap)
                pictureBox.LoadPicture( CurBitMap );

            if (CurTexIndex == -1)
                pictureBox.ClearPicture();

            pictureBox.Invalidate();
        }

        private void pictureBox_Paint ( object sender, PaintEventArgs e )
        {
            if (CurBorderMap != null)
            {
                SpriteBorder.BorderMap borderMap = CurBorderMap;

                for (int y = -2; y < borderMap.Height - 2; y++)
                {
                    for (int x = -2; x < borderMap.Width - 2; x++)
                    {
                        if (borderMap[x, y])
                        {
                            e.Graphics.FillRectangle( new SolidBrush( System.Drawing.Color.Green ), pictureBox.RectAtPos( x, y ) );
                        }
                    }
                }
                if (showError)
                    e.Graphics.FillRectangle( new SolidBrush( System.Drawing.Color.Red ), pictureBox.RectAtPos( errorPoint.X, errorPoint.Y ) );
            }
        }

        void pictureBox_LastPaint ( object sender, PaintEventArgs e )
        {
            if (CurTreeNode != null && CurTreeNode is TreeNodeNode)
            {

                List<Microsoft.Xna.Framework.Vector2> visiPoints = ((TreeNodeNode)CurTreeNode).VisiPoints;
                PointF[] visiPos = new PointF[visiPoints.Count];
                for (int i = 0; i < visiPos.Length; i++)
                {
                    visiPos[i] = pictureBox.ScrnPos( visiPoints[i].X, visiPoints[i].Y );
                }

                List<Microsoft.Xna.Framework.Vector2> structPoints = ((TreeNodeNode)CurTreeNode).StructPoints;
                PointF[] structPos = new PointF[structPoints.Count];
                for (int i = 0; i < structPos.Length; i++)
                {
                    structPos[i] = pictureBox.ScrnPos( structPoints[i].X, structPoints[i].Y );
                }

                if (visiPos.Length > 0)
                {
                    foreach (PointF point in visiPos)
                    {
                        e.Graphics.DrawImage( visiPointMap, new PointF( point.X - 20, point.Y - 20 ) );
                    }
                }

                if (structPos.Length > 0)
                {
                    foreach (PointF point in structPos)
                    {
                        e.Graphics.DrawImage( structPointMap, new PointF( point.X - 20, point.Y - 20 ) );
                    }
                }
            }
        }

        void InitialPictureBoxContentMenu ()
        {
            pictureMenuStrip = new ContextMenuStrip();

            ToolStripMenuItem checkBorder = new ToolStripMenuItem();
            checkBorder.Name = "提取边界";
            checkBorder.Text = "提取边界";
            ToolStripMenuItem alphaMode = new ToolStripMenuItem();
            alphaMode.Name = "Alpha模式";
            alphaMode.Text = "切换到Alpha模式";
            ToolStripMenuItem editMode = new ToolStripMenuItem();
            editMode.Name = "编辑模式";
            editMode.Text = "切换到编辑模式";
            ToolStripMenuItem pen = new ToolStripMenuItem();
            pen.Name = "画笔";
            pen.Text = "切换到透明画笔";
            pen.Visible = false;

            checkBorder.Click += new EventHandler( checkBorder_Click );
            alphaMode.Click += new EventHandler( alphaMode_Click );
            editMode.Click += new EventHandler( editMode_Click );
            pen.Click += new EventHandler( pen_Click );

            pictureMenuStrip.Items.AddRange( new ToolStripItem[] { checkBorder, alphaMode, pen, editMode } );
            pictureBox.ContextMenuStrip = pictureMenuStrip;
        }

        PenKind penKind = PenKind.black;
        enum PenKind
        {
            trans,
            half,
            black,
        }

        void pen_Click ( object sender, EventArgs e )
        {
            penKind = (PenKind)((((int)penKind) + 1) % 3);

            UpdateComponent();
        }

        void UpdatePictureMenuStrip ()
        {

            if (CurBitMap == null)
            {
                pictureMenuStrip.Items["编辑模式"].Enabled = false;
                pictureMenuStrip.Items["提取边界"].Enabled = false;
                pictureMenuStrip.Items["Alpha模式"].Enabled = false;
                pictureMenuStrip.Items["画笔"].Visible = false;
                pictureMenuStrip.Items["编辑模式"].Text = "切换到编辑模式";
                editMode = false;
            }
            else
            {
                pictureMenuStrip.Items["提取边界"].Enabled = true;
                pictureMenuStrip.Items["Alpha模式"].Enabled = true;
                pictureMenuStrip.Items["编辑模式"].Enabled = true;
            }

            if (CurTabState == TabState.Texture)
            {
                pictureMenuStrip.Items["提取边界"].Visible = true;
            }
            else if (CurTabState == TabState.VisiPoint)
            {
                pictureMenuStrip.Items["提取边界"].Visible = false;
                pictureMenuStrip.Items["画笔"].Visible = false;
            }
            else if (CurTabState == TabState.StructPoint)
            {
                pictureMenuStrip.Items["提取边界"].Visible = false;
                pictureMenuStrip.Items["画笔"].Visible = false;
            }

            if (editMode)
            {
                if (CurTabState == TabState.Texture)
                {
                    pictureMenuStrip.Items["画笔"].Visible = true;

                    if (penKind == PenKind.trans)
                    {
                        pictureMenuStrip.Items["画笔"].Text = "切换到半透明画笔";
                    }
                    else if (penKind == PenKind.half)
                    {
                        pictureMenuStrip.Items["画笔"].Text = "切换到黑色画笔";
                    }
                    else if (penKind == PenKind.black)
                    {
                        pictureMenuStrip.Items["画笔"].Text = "切换到透明画笔";
                    }


                }
                pictureMenuStrip.Items["编辑模式"].Text = "取消编辑模式";


            }
            else
            {
                pictureMenuStrip.Items["画笔"].Visible = false;
                pictureMenuStrip.Items["编辑模式"].Text = "切换到编辑模式";
            }

            if (pictureBox.AlphaMode)
            {
                pictureMenuStrip.Items["Alpha模式"].Text = "取消Alpha模式";
            }
            else
            {
                pictureMenuStrip.Items["Alpha模式"].Text = "切换到Alpha模式";
            }
        }

        void checkBorder_Click ( object sender, EventArgs e )
        {
            if (CheckBorder())
                MessageBox.Show( "生成边界成功！" );
            else
                MessageBox.Show( "生成边界失败！" );
            pictureBox.Invalidate();
        }

        void alphaMode_Click ( object sender, EventArgs e )
        {
            pictureBox.AlphaMode = !pictureBox.AlphaMode;
            UpdateComponent();
        }

        void editMode_Click ( object sender, EventArgs e )
        {
            editMode = !editMode;
            UpdateComponent();
        }

        private void pictureBox_MouseClick ( object sender, MouseEventArgs e )
        {
            if (editMode && !pictureBox.Controlling)
            {
                PointF texPos = pictureBox.TexPos( e.X, e.Y );
                if (CurTabState == TabState.Texture)
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        if (penKind == PenKind.black)
                            SetAlpha( (int)texPos.X, (int)texPos.Y, 255 );
                        else if (penKind == PenKind.trans)
                            SetAlpha( (int)texPos.X, (int)texPos.Y, 0 );
                        else if (penKind == PenKind.half)
                            SetAlpha( (int)texPos.X, (int)texPos.Y, SpriteBorder.minBlockAlpha );
                    }
                }
            }
        }

        private void pictureBox_MouseDoubleClick ( object sender, MouseEventArgs e )
        {
            if (editMode && !pictureBox.Controlling)
            {
                PointF texPos = pictureBox.TexPos( e.X, e.Y );

                if (CurTabState == TabState.VisiPoint)
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        ((TreeNodeNode)CurTreeNode).AddVisiPoint( texPos.X, texPos.Y );
                    }
                }
                else if (CurTabState == TabState.StructPoint)
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        ((TreeNodeNode)CurTreeNode).AddStructPoint( texPos.X, texPos.Y );
                    }
                }
            }
            pictureBox.Invalidate();
            UpdateVisiList();
            UpdateStructList();
        }

        private void pictureBox_MouseMove ( object sender, MouseEventArgs e )
        {
            if (pictureBox.CurBitMap != null)
            {
                PointF curMousePos = pictureBox.TexPos( e.X, e.Y );
                statusStrip.Items["toolStripStatusMousePos"].Text = "当前鼠标位置：" + curMousePos.ToString();
            }
        }

        void SetAlpha ( int x, int y, byte alpha )
        {
            if (CurBitMap != null && CurXNATex != null &&
                x >= 0 && x < CurBitMap.Width &&
                y >= 0 && y < CurBitMap.Height)
            {
                System.Drawing.Color preColor = CurBitMap.GetPixel( x, y );
                CurBitMap.SetPixel( x, y, System.Drawing.Color.FromArgb( alpha, preColor ) );

                Microsoft.Xna.Framework.Graphics.Color[] data = new Microsoft.Xna.Framework.Graphics.Color[CurXNATex.Width * CurXNATex.Height];
                CurXNATex.GetData<Microsoft.Xna.Framework.Graphics.Color>( data );
                Microsoft.Xna.Framework.Graphics.Color preXNAColor = data[y * CurXNATex.Width + x];
                data[y * CurXNATex.Width + x] = new Microsoft.Xna.Framework.Graphics.Color( preXNAColor.R, preXNAColor.G, preXNAColor.B, alpha );
                CurXNATex.SetData<Microsoft.Xna.Framework.Graphics.Color>( data );
                pictureBox.Invalidate();
            }
        }

        #endregion

        #region StatusBar

        void UpdateStatusBar ()
        {
            if (CurTreeObj != null)
            {
                statusStrip.Items["toolStripStatusBaseInfo"].Text = CurTreeObj.obj.name + " / " + CurTreeObj.obj.creater + " / " + CurTreeObj.obj.year + ":" + CurTreeObj.obj.month + ":" + CurTreeObj.obj.day;
                if (editMode)
                {
                    statusStrip.Items["toolStripStatusLabelEdit"].Text = "编辑模式";
                    statusStrip.Items["toolStripStatusLabelEditState"].Visible = true;
                    if (CurTabState == TabState.Texture)
                    {
                        if (penKind == PenKind.black)
                            statusStrip.Items["toolStripStatusLabelEditState"].Text = "黑色画笔";
                        else if (penKind == PenKind.half)
                            statusStrip.Items["toolStripStatusLabelEditState"].Text = "半透明画笔";
                        else
                            statusStrip.Items["toolStripStatusLabelEditState"].Text = "透明画笔";



                    }
                    else if (CurTabState == TabState.VisiPoint)
                    {
                        statusStrip.Items["toolStripStatusLabelEditState"].Text = "双击添加可视关键点";
                    }
                    else if (CurTabState == TabState.StructPoint)
                    {
                        statusStrip.Items["toolStripStatusLabelEditState"].Text = "双击添加结构关键点";
                    }
                }
                else
                {
                    statusStrip.Items["toolStripStatusLabelEdit"].Text = "查看模式";
                    statusStrip.Items["toolStripStatusLabelEditState"].Visible = false;
                }

                if (pictureBox.AlphaMode)
                {
                    statusStrip.Items["toolStripStatusAlpha"].Text = "Alpha模式";
                }
                else
                {
                    statusStrip.Items["toolStripStatusAlpha"].Text = "颜色模式";
                }
            }


        }

        #endregion

        #region IntList

        private void InitialDataListContentMenu ()
        {
            dataMenuStrip = new ContextMenuStrip();

            ToolStripMenuItem addData = new ToolStripMenuItem();
            addData.Name = "添加新数据";
            addData.Text = "添加新数据";

            ToolStripMenuItem delData = new ToolStripMenuItem();
            delData.Name = "删除数据";
            delData.Text = "删除数据";

            addData.Click += new EventHandler( addData_Click );
            delData.Click += new EventHandler( delData_Click );

            dataMenuStrip.Items.AddRange( new ToolStripItem[] { addData, delData } );

            listViewInt.ContextMenuStrip = dataMenuStrip;
            listViewFloat.ContextMenuStrip = dataMenuStrip;
        }

        void delData_Click ( object sender, EventArgs e )
        {
            if (CurTabState == TabState.IntData)
            {
                if (listViewInt.SelectedIndices.Count > 0 && CurNodeNode != null)
                {
                    int delIndex = listViewInt.SelectedIndices[0];
                    CurNodeNode.DelIntData( delIndex );
                }
            }
            else if (CurTabState == TabState.FloatData)
            {
                if (listViewFloat.SelectedIndices.Count > 0 && CurNodeNode != null)
                {
                    int delIndex = listViewFloat.SelectedIndices[0];
                    CurNodeNode.DelFloatData( delIndex );
                }
            }
            UpdateComponent();
        }

        void addData_Click ( object sender, EventArgs e )
        {
            if (CurTabState == TabState.IntData)
            {
                if (CurNodeNode != null)
                {
                    EnterNumber enter = new EnterNumber();
                    enter.ShowDialog();
                    int value = new int();
                    try
                    {
                        value = int.Parse( enter.NumberText );
                    }
                    catch (Exception)
                    {
                        MessageBox.Show( "输入格式错误！" );
                        return;
                    }
                    CurNodeNode.AddIntData( value );
                }
            }
            else if (CurTabState == TabState.FloatData)
            {
                if (CurNodeNode != null)
                {
                    EnterNumber enter = new EnterNumber();
                    enter.ShowDialog();
                    float value = new float();
                    try
                    {
                        value = float.Parse( enter.NumberText );
                    }
                    catch (Exception)
                    {
                        MessageBox.Show( "输入格式错误！" );
                        return;
                    }
                    CurNodeNode.AddFloatData( value );
                }
            }
            UpdateComponent();
        }

        void UpdateDataList ()
        {
            listViewInt.Items.Clear();

            if (CurNodeNode != null)
            {
                int index = 0;
                foreach (int i in CurNodeNode.IntDatas)
                {
                    ListViewItem newItem = new ListViewItem( index.ToString() );
                    newItem.SubItems.Add( i.ToString() );
                    listViewInt.Items.Add( newItem );
                    index++;
                }
            }

            listViewFloat.Items.Clear();

            if (CurNodeNode != null)
            {
                int index = 0;
                foreach (float f in CurNodeNode.FloatDatas)
                {
                    ListViewItem newItem = new ListViewItem( index.ToString() );
                    newItem.SubItems.Add( f.ToString() );
                    listViewFloat.Items.Add( newItem );
                    index++;
                }
            }

        }

        #endregion

    }
}<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace GameEngine.Effects.Particles
{
    class PointSource : ParticleSystem
    {
        bool isOpen = true;

        public bool IsOpen
        {
            get { return isOpen; }
            set { isOpen = value; }
        }

        Vector2 curDir;

        public Vector2 CurDir
        {
            get { return curDir; }
            set { curDir = value; }
        }

        public PointSource( Vector2 pos, Vector2 direct, float vel, float partiDura, float CreateRate, bool isOpen,
            Texture2D tex, Vector2 texOrign, Nullable<Rectangle> sourceRect, float layerDepth )
        {
            this.BasePos = pos;
            this.CurDir = direct;
            this.
        }

        public PointSource( Vector2 pos, Vector2 direct, float vel, float partiDura, float CreateRate, bool isOpen,
            Texture2D tex, Vector2 texOrign, Nullable<Rectangle> sourceRect, float layerDepth )
            : base( 0, partiDura, pos, tex, texOrign, sourceRect, layerDepth,
            delegate( float curTime, ref float timer )
            {
                if (CreateRate != 0)
                {
                    if (timer > 1 / CreateRate)
                    {
                        float sumInFloat = timer * CreateRate;
                        int createSum = (int)sumInFloat;
                        timer -= (float)createSum / CreateRate;
                        return createSum;
                    }
                }
                return 0;
            },
            delegate( float curPartiTime, float deltaTime, Vector2 lastPos, Vector2 dir, int No )
            {
                if (curPartiTime == 0)
                    return Vector2.Zero;
                return deltaTime * dir + lastPos;
            },
            this.DirFunction,
            delegate( float curPartiTime, float deltaTime, float lastRadius, int No )
            {
                return lastRadius;
            },
            delegate( float curPartiTime, float deltaTime, Color lastColor, int No )
            {
                return Color.White;
            } )
        {
            this.isOpen = isOpen;
        }

        protected override void CreateNewParticle( float seconds )
        {
            if (this.isOpen)
                base.CreateNewParticle( seconds );
        }

        protected virtual Vector2 DirFunction( float curPartiTime, float deltaTime, Vector2 lastDir, int No )
        {
            if (curPartiTime == 0)
                return curDir;
            else
                return lastDir;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Helpers;
using SmartTank.AI;
using System.IO;
using System.Reflection;

namespace SmartTank.Helpers.DependInject
{
    public class AILoader
    {
        readonly static string AIDirectory = "AIs";
        readonly static string AIListPath = "AIs\\List.xml";

        AssetList list;

        List<Type> interList;

        List<Type> compatibleAIs;
        List<string> compatibleAINames;

        public AILoader ()
        {
            Directory.SetCurrentDirectory( System.Environment.CurrentDirectory );
            if (!Directory.Exists( AIDirectory ))
            {
                Directory.CreateDirectory( AIDirectory );
            }
            if (File.Exists( AIListPath ))
            {
                list = AssetList.Load( File.Open( AIListPath, FileMode.OpenOrCreate ) );
            }
            interList = new List<Type>();
            compatibleAIs = new List<Type>();
            compatibleAINames = new List<string>();

        }

        public void InitialCompatibleAIs ( Type OrderServerType, Type CommonServerType )
        {
            foreach (Type type in interList)
            {
                if (!IsTankAI( type ))
                    continue;

                if (IsCompatibleAI( type, OrderServerType, CommonServerType ))
                {
                    object[] attributes = type.GetCustomAttributes( false );
                    foreach (object attri in attributes)
                    {
                        if (attri is AIAttribute)
                        {
                            string name = ((AIAttribute)attri).Name;
                            compatibleAINames.Add( name );
                            compatibleAIs.Add( type );
                            break;
                        }
                    }
                }
            }

            if (list != null)
            {
                foreach (AssetItem item in list.list)
                {
                    Directory.SetCurrentDirectory( System.Environment.CurrentDirectory );
                    //Assembly assembly = DIHelper.GetAssembly( Path.Combine( AIDirectory, item.DLLName ) );
                    Assembly assembly = GetAssembly( Path.Combine( AIDirectory, item.DLLName ) );
                    foreach (Type type in assembly.GetTypes())
                    {

                        if (!IsTankAI( type ))
                            continue;

                        if (IsCompatibleAI( type, OrderServerType, CommonServerType ))
                        {
                            object[] attributes = type.GetCustomAttributes( false );
                            foreach (object attri in attributes)
                            {
                                if (attri is AIAttribute)
                                {
                                    string name = ((AIAttribute)attri).Name;
                                    compatibleAINames.Add( name );
                                    compatibleAIs.Add( type );
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        public void AddInterAI ( Type AIType )
        {
            interList.Add( AIType );
        }

        public string[] GetAIList ()
        {
            return compatibleAINames.ToArray();
        }

        public IAI GetAIInstance ( int index )
        {
            if (index < 0 || index > compatibleAIs.Count)
                return null;
            return (IAI)DIHelper.GetInstance( compatibleAIs[index] );
        }

        public bool IsTankAI ( Type type )
        {
            foreach (Type interfa in type.GetInterfaces())
            {
                if (interfa.Equals( typeof( IAI ) ))
                {
                    return true;
                }
            }
            return false;
        }

        private bool IsCompatibleAI ( Type type, Type OrderServerType, Type CommonServerType )
        {
            Type maxIAI = MaxIAI( type );

            object[] attributes = maxIAI.GetCustomAttributes( false );
            foreach (object attri in attributes)
            {
                if (attri is IAIAttribute)
                {
                    bool orderServerCompatible = IsChildType( OrderServerType, ((IAIAttribute)attri).OrderServerType ) ||
                        OrderServerType == ((IAIAttribute)attri).OrderServerType;
                    bool commonServerCompatible = IsChildType( CommonServerType, ((IAIAttribute)attri).CommonServerType ) ||
                        CommonServerType == ((IAIAttribute)attri).CommonServerType;
                    if (orderServerCompatible && commonServerCompatible)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        private Type MaxIAI ( Type AIClasstype )
        {
            List<Type> IAIs = new List<Type>();
            foreach (Type interfa in AIClasstype.GetInterfaces())
            {
                if (IsChildType( interfa, typeof( IAI ) ))
                {
                    IAIs.Add( interfa );
                }
            }

            Type maxIAI = typeof( IAI );
            foreach (Type type in IAIs)
            {
                if (IsChildType( type, maxIAI ))
                    maxIAI = type;
            }

            return maxIAI;
        }

        private bool IsChildType ( Type type, Type childType )
        {
            foreach (Type interfa in type.GetInterfaces())
            {
                if (interfa.Equals( childType ))
                {
                    return true;
                }
            }
            return false;
        }

        static public Assembly GetAssembly ( string assetFullName )
        {
            Assembly assembly = null;
            try
            {
                assembly = Assembly.LoadFile( Path.Combine( System.Environment.CurrentDirectory, assetFullName ) );
            }
            catch (Exception)
            {
                Log.Write( "Load Assembly error : " + assetFullName + " load unsucceed!" );
                return null;
            }

            return assembly;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using GameEngine.Graphics;

namespace GameEngine.Effects
{
    /// <summary>
    /// 从多幅图中建立动画的动画类
    /// </summary>
    public class AnimatedSpriteSeries : AnimatedSprite, IDisposable
    {
        Vector2 pos;

        /// <summary>
        /// 提前将贴图文件导入到Content当中，以避免读取造成游戏的停滞。
        /// 资源名由固定的头名字和名字后的阿拉伯数字索引组成
        /// </summary>
        /// <param name="contentMgr">资源管理者</param>
        /// <param name="assetHead">资源的路径以及头名字</param>
        /// <param name="firstNo">索引开始的数字</param>
        /// <param name="sumFrame">系列贴图文件的数量</param>
        static public void LoadResource( ContentManager contentMgr, string assetHead, int firstNo, int sumFrame )
        {
            try
            {
                for (int i = 0; i < sumFrame; i++)
                {
                    contentMgr.Load<Texture2D>( assetHead + (firstNo + i) );
                }
            }
            catch (Exception)
            {
                throw new Exception( "导入动画资源错误，请检查图片资源是否完整" );
            }
        }

        #region Variables

        Sprite[] mSprites;

        bool alreadyLoad = false;

        /// <summary>
        /// 获取当前帧的Sprite对象
        /// </summary>
        public Sprite CurSprite
        {
            get { return mSprites[mCurFrameIndex]; }
        }

        /// <summary>
        /// 获取动画每一帧的Sprite对象
        /// </summary>
        public Sprite[] Sprites
        {
            get { return mSprites; }
        }

        #endregion

        /// <summary>
        /// 从多幅图中建立动画的动画类
        /// </summary>
        /// <param name="engine">渲染组件</param>
        public AnimatedSpriteSeries ( RenderEngine engine )
        {

        }

        #region Load Textures

        /// <summary>
        /// 从文件中导入系列贴图资源。
        /// 资源名由固定的头名字和名字后的阿拉伯数字索引组成。
        /// </summary>
        /// <param name="engine">渲染组件</param>
        /// <param name="path">贴图资源的路径</param>
        /// <param name="fileHeadName">头名字</param>
        /// <param name="extension">扩展名</param>
        /// <param name="firstNo">第一个数字索引</param>
        /// <param name="sumFrame">索引总数</param>
        /// <param name="supportInterDect">是否添加冲突检测的支持</param>
        public void LoadSeriesFromFiles ( RenderEngine engine, string path, string fileHeadName, string extension, int firstNo, int sumFrame, bool supportInterDect )
        {
            if (alreadyLoad)
                throw new Exception( "重复导入动画资源。" );

            alreadyLoad = true;

            mSprites = new Sprite[sumFrame];
            try
            {
                for (int i = 0; i < sumFrame; i++)
                {
                    mSprites[i] = new Sprite( engine );
                    mSprites[i].LoadTextureFromFile( Path.Combine( path, fileHeadName + (i + firstNo) + extension ), supportInterDect );
                }
            }
            catch (Exception)
            {
                mSprites = null;
                alreadyLoad = false;

                throw new Exception( "导入动画资源错误，请检查图片资源是否完整" );
            }

            mSumFrame = sumFrame;
            mCurFrameIndex = 0;
        }

        /// <summary>
        /// 使用素材管道导入贴图文件。
        /// 资源名由固定的头名字和名字后的阿拉伯数字索引组成
        /// </summary>
        /// <param name="engine">渲染组件</param>
        /// <param name="contentMgr">素材管理者</param>
        /// <param name="assetHead">资源的路径以及头名字</param>
        /// <param name="firstNo">索引开始的数字</param>
        /// <param name="sumFrame">系列贴图文件的数量</param>
        /// <param name="supportInterDect">是否提供冲突检测的支持</param>
        public void LoadSeriesFormContent ( RenderEngine engine, ContentManager contentMgr, string assetHead, int firstNo, int sumFrame, bool supportInterDect )
        {
            if (alreadyLoad)
                throw new Exception( "重复导入动画资源。" );

            alreadyLoad = true;

            mSprites = new Sprite[sumFrame];

            try
            {
                for (int i = 0; i < sumFrame; i++)
                {
                    mSprites[i] = new Sprite( engine );
                    mSprites[i].LoadTextureFromContent( contentMgr, assetHead + (firstNo + i), supportInterDect );
                }
            }
            catch (Exception)
            {
                mSprites = null;
                alreadyLoad = false;

                throw new Exception( "导入动画资源错误，请检查图片资源是否完整" );
            }

            mSumFrame = sumFrame;
            mCurFrameIndex = 0;
        }

        #endregion

        #region Dispose

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose ()
        {
            foreach (Sprite sprite in mSprites)
            {
                sprite.Dispose();
            }
        }

        #endregion

        #region Set Sprites Parameters

        /// <summary>
        /// 
        /// </summary>
        /// <param name="origin"></param>
        /// <param name="pos"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="rata"></param>
        /// <param name="color"></param>
        /// <param name="layerDepth"></param>
        /// <param name="blendMode"></param>
        public void SetSpritesParameters ( Vector2 origin, Vector2 pos, float width, float height, float rata, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            this.pos = pos;
            foreach (Sprite sprite in mSprites)
            {
                sprite.SetParameters( origin, pos, width, height, rata, color, layerDepth, blendMode );
            }
        }

        /// <summary>
        /// 设置所有Sprite的参数
        /// </summary>
        /// <param name="origin">贴图的中心，以贴图坐标表示</param>
        /// <param name="pos">逻辑位置</param>
        /// <param name="scale">贴图的缩放比（= 逻辑长度/贴图长度）</param>
        /// <param name="rata">逻辑方位角</param>
        /// <param name="color">绘制颜色</param>
        /// <param name="layerDepth">深度，1为最低层，0为最表层</param>
        /// <param name="blendMode">采用的混合模式</param>
        public void SetSpritesParameters ( Vector2 origin, Vector2 pos, float scale, float rata, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            foreach (Sprite sprite in mSprites)
            {
                sprite.SetParameters( origin, pos, scale, rata, color, layerDepth, blendMode );
            }
        }

        #endregion

        #region Draw Current Frame

        /// <summary>
        /// 绘制当前的贴图
        /// </summary>
        protected override void DrawCurFrame()
        {
            CurSprite.Draw();
        }

        #endregion



        public override Vector2 Pos
        {
            get { return pos; }
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Rule;
using SmartTank.Screens;
using SmartTank.net;
using SmartTank.GameObjs;
using SmartTank.PhiCol;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TankEngine2D.Graphics;
using SmartTank;
using SmartTank.Draw;
using TankEngine2D.Helpers;
using TankEngine2D.Input;
using Microsoft.Xna.Framework.Input;
using SmartTank.Scene;
using System.IO;
using SmartTank.Helpers;
using SmartTank.GameObjs.Shell;
using TankEngine2D.DataStructure;
using SmartTank.Effects.SceneEffects;
using SmartTank.Effects;
using SmartTank.Sounds;
using SmartTank.Draw.UI.Controls;
using System.Runtime.InteropServices;

namespace InterRules.Starwar
{
    class Room : IGameScreen
    {
        [StructLayoutAttribute(LayoutKind.Sequential, Size = 32, CharSet = CharSet.Ansi, Pack = 1)]
        struct RankInfo
        {
            public const int size = 32;

            public int rank;
            public int score;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
            public char[] name;
        }

        Texture2D bgTexture;

        Rectangle bgRect;

        SpriteBatch spriteBatch;

        Listbox roomList;
        Listbox rankList;

        Byte[] rankBuffer = new byte[400];

        TextButton btnCreate, btnEnter, btnRank;

        int selectIndexRank = -1;
        int selectIndexRoom = -1;

        public Room()
        {
            BaseGame.ShowMouse = true;

            roomList = new Listbox("roomlist", new Vector2(30, 100), new Point(200, 350), Color.WhiteSmoke, Color.Green);

            rankList = new Listbox("ranklist", new Vector2(300, 100), new Point(450, 350), Color.WhiteSmoke, Color.Green);

            roomList.AddItem("Room 1");

            bgTexture = BaseGame.ContentMgr.Load<Texture2D>(Path.Combine(Directories.BgContent, "login"));

            bgRect = new Rectangle(0, 0, 800, 600);



            btnCreate = new TextButton("CreateBtn", new Vector2(130, 460), "Create", 0, Color.Gold);
            btnEnter = new TextButton("EnterBtn", new Vector2(50, 460), "Enter", 0, Color.Gold);
            btnRank = new TextButton("RankBtn", new Vector2(650, 460), "Rank List", 0, Color.Gold);

            btnCreate.OnClick += new EventHandler(btnCreate_OnPress);
            btnEnter.OnClick += new EventHandler(btnEnter_OnPress);
            btnRank.OnClick += new EventHandler(btnRank_OnPress);

            rankList.OnChangeSelection += new EventHandler(rankList_OnChangeSelection);
            roomList.OnChangeSelection += new EventHandler(roomList_OnChangeSelection);

            SocketMgr.OnReceivePkg += new SocketMgr.ReceivePkgEventHandler(OnReceivePack);

            /*

            stPkgHead head = new stPkgHead();
            //head.iSytle = //包头类型还没初始化


            MemoryStream Stream = new MemoryStream();
            Stream.Write(new byte[1], 0, 1);
            head.dataSize = 1;
            head.iSytle = 50;
            SocketMgr.SendCommonPackge(head, Stream);
            Stream.Close();
            */
            // 连接到服务器
            //SocketMgr.ConnectToServer();
        }
        
        void OnReceivePack(stPkgHead head, MemoryStream data)
        {
            if (head.iSytle == 50)
            {
                RankInfo ri;
                string str;

                for (int i = 0; i < head.dataSize; i += 32)
                {
   
                    str = "";
                    data.Read(rankBuffer, 0, 32);

                    ri = (RankInfo)SocketMgr.BytesToStuct(rankBuffer, typeof(RankInfo));

                    for (int j = 0; ri.name[j] != '\0'; ++j)
                    {
                        str += ri.name[j];
                    }


                    rankList.AddItem(ri.rank + "        " + str + "              " + ri.score);

                }
            }
        }
        
        void roomList_OnChangeSelection(object sender, EventArgs e)
        {
            selectIndexRoom = roomList.selectedIndex;
        }

        void rankList_OnChangeSelection(object sender, EventArgs e)
        {
            selectIndexRank = rankList.selectedIndex;
        }

        void btnCreate_OnPress(object sender, EventArgs e)
        {
            
        }

        void btnEnter_OnPress(object sender, EventArgs e)
        {

        }

        void btnRank_OnPress(object sender, EventArgs e)
        {

        }

        #region IGameScreen 成员

        public bool Update(float second)
        {

            btnCreate.Update();
            btnEnter.Update();
            btnRank.Update();
            
            roomList.Update();
            rankList.Update();

            if (InputHandler.IsKeyDown(Keys.F1))
                GameManager.AddGameScreen(new StarwarLogic(0));
            else if (InputHandler.IsKeyDown(Keys.F2))
                GameManager.AddGameScreen(new StarwarLogic(1));
            else if (InputHandler.IsKeyDown(Keys.PageDown))
            {
                SocketMgr.OnReceivePkg -= OnReceivePack;
                GameManager.AddGameScreen(new Rank());
            }

            if (InputHandler.IsKeyDown(Keys.Escape))
                return true;

            return false;
        }

        public void Render()
        {
            BaseGame.Device.Clear(Color.LightSkyBlue);
            spriteBatch = (SpriteBatch)BaseGame.SpriteMgr.alphaSprite;
            spriteBatch.Draw(bgTexture, Vector2.Zero, bgRect, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, LayerDepth.BackGround);
            roomList.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            rankList.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            btnEnter.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            btnCreate.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            btnRank.Draw(BaseGame.SpriteMgr.alphaSprite, 1);
            
        }

        public void OnClose()
        {

        }

        #endregion
    }





}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Scene;
using TankEngine2D.Graphics;
using SmartTank.AI;
using SmartTank.GameObjs.Tank;
using SmartTank.GameObjs.Shell;
using SmartTank.GameObjs.Item;
using System.IO;
using TankEngine2D.Helpers;
using SmartTank.GameObjs;
using SmartTank.Draw;
using TankEngine2D.Input;
using TankEngine2D.DataStructure;
using SmartTank.Draw.BackGround.VergeTile;
using SmartTank.Shelter;
using SmartTank.Screens;
using SmartTank.Senses.Vision;
using SmartTank.Rule;
using SmartTank.Effects.SceneEffects;
using Microsoft.Xna.Framework;
using SmartTank.GameObjs.Tank.SinTur;
using SmartTank;
using SmartTank.Helpers;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.Effects.TextEffects;

namespace InterRules.ShootTheBall
{
    /*
     * 一个Demo，便于测试各种效果。
     * 
     * 已添加的效果：
     *      
     *      炮塔后座。
     * 
     *      物体间相互作用。
     * 
     *      地形表面。
     * 
     * 有待完成的效果：
     * 
     *      炮口火焰。
     * 
     *      坦克换肤。
     * 
     *      履带印痕。
     * 
     *      界面制作。
     * 
     * */
    [RuleAttribute( "ShootTheBall", "坦克炮轰一个运动的球。（平台的第一个规则，帮助我们进行了大量的测试!）", "SmartTank编写组", 2007, 10, 30 )]
    class ShootTheBallRule : IGameRule
    {
        readonly float shellSpeed = 150;

        public string RuleName
        {
            get { return "ShootTheBall"; }
        }

        public string RuleIntroduction
        {
            get { return "坦克炮轰一个运动的球。（平台的第一个规则，帮助我们进行了大量的测试!）"; }
        }

        #region Variables

        readonly Rectangle scrnViewRect = new Rectangle( 30, 30, 750, 550 );

        readonly Rectanglef mapSize = new Rectanglef( 0, 0, 200, 150 );

        //SceneKeeperCommon scene;
        SceneMgr sceneMgr;

        TankSinTur tank;
        //TankSinTur tankPlayer;

        Camera camera;

        //SimpleTileGround simpleGround;

        VergeTileGround vergeGround;

        int Score = 0;
        int shootSum = 0;
        int hitSum = 0;

        bool firstHit = true;
        bool showFirstHit = false;

        bool firstScore = true;
        bool showFirstScore = false;

        bool firstHitTank = true;
        bool showFirstHitTank = false;

        bool showNiceShoot = true;
        int NiceShootSum = 0;

        #endregion

        #region Construction

        public ShootTheBallRule()
        {
            //BaseGame.ShowMouse = true;

            BaseGame.CoordinMgr.SetScreenViewRect( scrnViewRect );

            camera = new Camera( 4, new Vector2( 100, 75 ), 0 );
            camera.maxScale = 4;
            camera.Enable();

            InintialBackGround();

            //scene = new SceneKeeperCommon();
            sceneMgr = new SceneMgr();
            SceneInitial();
            GameManager.LoadScene( sceneMgr );

            LoadResource();
        }

        private void LoadResource()
        {
            BaseGame.FontMgr.BuildTexture( "哦，这个家伙变小了！", GameFonts.HDZB );
            BaseGame.FontMgr.BuildTexture( "当这个物体消失时，你会获得100分！", GameFonts.HDZB );
            BaseGame.FontMgr.BuildTexture( "不过这个物体也会开始运动。", GameFonts.HDZB );
        }

        private void InintialBackGround()
        {
            VergeTileData data2 = new VergeTileData();
            data2.gridWidth = 20;
            data2.gridHeight = 15;
            //data2.vertexTexIndexs = new int[]
            //{
            //    0,0,0,1,1,1,1,2,2,2,3,
            //    0,0,1,2,1,1,1,2,2,3,3,
            //    0,1,3,3,3,3,1,2,2,3,3,
            //    0,1,3,3,3,1,2,2,3,3,3,
            //    0,1,1,2,3,1,2,2,3,3,3,
            //    1,1,1,2,2,2,2,2,2,3,2,
            //    1,1,1,1,2,2,2,3,3,2,2,
            //    1,1,2,2,2,1,2,2,3,3,2,
            //    1,1,1,2,2,2,2,3,3,2,2,
            //    1,1,2,1,2,3,2,3,3,2,2,
            //    1,1,2,2,2,2,2,3,2,2,2,

            //};
            data2.SetRondomVertexIndex( 20, 15, 4 );
            data2.SetRondomGridIndex( 20, 15 );
            data2.texPaths = new string[]
            {
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_Dirt.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_DirtRough.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_DirtGrass.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_GrassDark.tga"),

                //"Cave_Dirt.tga",
                //"Cave_LavaCracks.tga",
                //"Cave_Brick.tga",
                //"Cave_RedStones.tga",
                //"Cave_SquareTiles.tga",
                //"Cave_Lava.tga",
                //"Cave_GreyStones.tga",

                //"Lordw_Dirt.tga",
                //"Lordw_DirtRough.tga",
                //"Lordw_Grass.tga",
                //"Lordw_SnowGrass.tga",
                //"Lordw_Rock.tga",
                //"Lordw_Snow.tga",
                
                //"North_dirt.tga",
                //"North_dirtdark.tga",
                //"North_Grass.tga",
                //"North_ice.tga",
                //"North_rock.tga",
                //"North_Snow.tga",
                //"North_SnowRock.tga",

                //"Village_Dirt.tga",
                //"Village_DirtRough.tga",
                //"Village_GrassShort.tga",
                //"Village_Crops.tga",

            };

            vergeGround = new VergeTileGround( data2, scrnViewRect, mapSize );
        }

        private void SceneInitial()
        {
            tank = new TankSinTur( "tank", new GameObjInfo( "Tank", "Player" ), TankSinTur.M60TexPath, TankSinTur.M60Data,
                170, MathHelper.PiOver4, Color.Yellow,
                0f, 80, 60, 0.6f * MathHelper.Pi, 0.5f * MathHelper.Pi, MathHelper.Pi, 2f,
                new Vector2( 100, 50 ), 0, 0 );

            AutoShootAI autoShoot = new AutoShootAI();
            autoShoot.OrderServer = tank;
            ManualControl manualControl = new ManualControl();
            manualControl.OrderServer = tank;
            //tank.SetTankAI( manualControl );
            tank.SetTankAI( autoShoot );
            tank.onShoot += new Tank.ShootEventHandler( Tank_onShoot );
            tank.ShellSpeed = shellSpeed;

            //ItemCommon item = new ItemCommon( "item", "Scorpion", Path.Combine( Directories.ContentDirectory, "GameObjs\\scorpion" ), new Vector2( 128, 128 ), 0.031f, new Vector2[] { new Vector2( 128, 128 ) },
            //    new Vector2( 150, 50 ), 0f, Vector2.Zero, 0 );
            Ball ball = new Ball( "ball", 0.031f, new Vector2( 150, 50 ), 0, Vector2.Zero, 0 );
            ball.OnCollided += new OnCollidedEventHandler( item_OnCollided );

            smoke = new SmokeGenerater( 0, 50, Vector2.Zero, 0.3f, 0f, true, ball );

            sceneMgr.AddGroup( string.Empty, new TypeGroup<TankSinTur>( "tank" ) );
            sceneMgr.AddGroup( string.Empty, new TypeGroup<Ball>( "ball" ) );
            sceneMgr.AddGroup( string.Empty, new TypeGroup<SmartTank.PhiCol.Border>( "border" ) );
            sceneMgr.AddGroup( string.Empty, new TypeGroup<ShellNormal>( "shell" ) );

            sceneMgr.PhiGroups.Add( "tank" );
            sceneMgr.PhiGroups.Add( "ball" );
            sceneMgr.PhiGroups.Add( "shell" );

            sceneMgr.ColPairGroups.Add( new SceneMgr.Pair( "tank", "ball" ) );
            sceneMgr.ColPairGroups.Add( new SceneMgr.Pair( "tank", "border" ) );
            sceneMgr.ColPairGroups.Add( new SceneMgr.Pair( "ball", "border" ) );
            sceneMgr.ColPairGroups.Add( new SceneMgr.Pair( "shell", "border" ) );
            sceneMgr.ColPairGroups.Add( new SceneMgr.Pair( "shell", "ball" ) );

            sceneMgr.ShelterGroups.Add( new SceneMgr.MulPair( "tank", new List<string>() ) );
            sceneMgr.VisionGroups.Add( new SceneMgr.MulPair( "tank", new List<string>( new string[] { "ball" } ) ) );

            sceneMgr.AddGameObj( "tank", tank );
            sceneMgr.AddGameObj( "ball", ball );
            sceneMgr.AddGameObj( "border", new SmartTank.PhiCol.Border( mapSize ) );


            //camera.Focus( tank );
        }

        #endregion

        #region IGameScreen 成员

        public bool Update( float seconds )
        {
            GameManager.UpdataComponent( seconds );

            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.Left ))
                camera.Move( new Vector2( -5, 0 ) );
            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.Right ))
                camera.Move( new Vector2( 5, 0 ) );
            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.Up ))
                camera.Move( new Vector2( 0, -5 ) );
            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.Down ))
                camera.Move( new Vector2( 0, 5 ) );
            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.V ))
                camera.Zoom( -0.2f );
            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.B ))
                camera.Zoom( 0.2f );

            camera.Update( seconds );

            if (InputHandler.IsKeyDown( Microsoft.Xna.Framework.Input.Keys.Escape ))
            {
                GameManager.ComponentReset();
                return true;
            }
            else
                return false;
        }

        bool firstDraw = true;
        public void Render()
        {
            //simpleGround.Draw( camera.LogicViewRect );
            vergeGround.Draw();

            GameManager.DrawManager.Draw();

            BaseGame.BasicGraphics.DrawRectangle( mapSize, 3, Color.Red, 0f );
            BaseGame.BasicGraphics.DrawRectangleInScrn( scrnViewRect, 3, Color.Green, 0f );

            BaseGame.BasicGraphics.DrawPoint( BaseGame.CoordinMgr.LogicPos( ConvertHelper.PointToVector2( InputHandler.CurMousePos ) ), 3f, Color.Red, LayerDepth.Mouse );

            if (firstDraw)
            {
                //TextEffectMgr.AddRiseFade( "Use 'AWSD' to Move the Tank, 'JK' to Rotate the Turret,", new Vector2( 40, 150 ), 1.2f, Color.Red, LayerDepth.Text, FontType.Comic, 500, 0.2f );
                //TextEffectMgr.AddRiseFade( "and press Space To Shoot!", new Vector2( 40, 160 ), 1.2f, Color.Red, LayerDepth.Text, FontType.Comic, 500, 0.2f );

                firstDraw = false;
            }

            if (showFirstHit)
            {
                TextEffectMgr.AddRiseFade( "哦，这个家伙变小了！", new Vector2( 50, 70 ), 1.4f, Color.Red, LayerDepth.Text, GameFonts.HDZB, 300, 0.2f );
                showFirstHit = false;
            }

            if (showFirstScore)
            {
                TextEffectMgr.AddRiseFade( "当这个物体消失时，你会获得100分！", new Vector2( 20, 70 ), 1.4f, Color.Red, LayerDepth.Text, GameFonts.HDZB, 300, 0.2f );
                TextEffectMgr.AddRiseFade( "不过这个物体也会开始运动。", new Vector2( 20, 80 ), 1.4f, Color.Red, LayerDepth.Text, GameFonts.HDZB, 300, 0.2f );

                showFirstScore = false;
            }

            if (showFirstHitTank)
            {
                //TextEffect.AddRiseFade( "Oh, the Object hit you, it grows bigger!", new Vector2( 30, 150 ), 1.1f, Color.Red, LayerDepth.Text, FontType.Comic, 300, 0.2f );
                showFirstHitTank = false;
            }

            if (showNiceShoot)
            {
                if (NiceShootSum >= 30)
                    TextEffectMgr.AddRiseFade( "GOD LIKE!", tank.Pos, 1.1f, Color.Black, LayerDepth.Text, GameFonts.Comic, 200, 1f );
                else if (NiceShootSum >= 17)
                    TextEffectMgr.AddRiseFade( "Master Shoot!", tank.Pos, 1.1f, Color.Pink, LayerDepth.Text, GameFonts.Comic, 200, 1f );
                else if (NiceShootSum >= 4)
                    TextEffectMgr.AddRiseFade( "Nice Shoot!", tank.Pos, 1.1f, Color.GreenYellow, LayerDepth.Text, GameFonts.Comic, 200, 1f );

                showNiceShoot = false;
            }

            if (tank.Rader.PointInRader( InputHandler.GetCurMousePosInLogic( BaseGame.RenderEngine ) ))
            {
                BaseGame.FontMgr.DrawInScrnCoord( "mouse In Rader!", ConvertHelper.PointToVector2( InputHandler.CurMousePos ), 0.6f, Color.Yellow, LayerDepth.Text, GameFonts.Lucida );
            }

            if (tank.Rader.ShelterObjs.Length != 0)
            {
                foreach (IShelterObj obj in tank.Rader.ShelterObjs)
                {
                    BaseGame.FontMgr.Draw( "I am Sheltered by " + (obj as IGameObj).Name + " Pos: " + ((IGameObj)obj).Pos.ToString(), tank.Pos, 0.6f, Color.Yellow, LayerDepth.Text, GameFonts.Lucida );
                }
            }


            BaseGame.FontMgr.DrawInScrnCoord( "You Score : " + Score.ToString(), new Vector2( 500, 40 ), 0.6f, Color.Yellow, LayerDepth.Text, GameFonts.Comic );
            BaseGame.FontMgr.DrawInScrnCoord( "Shoot Sum : " + shootSum.ToString(), new Vector2( 500, 60 ), 0.6f, Color.Yellow, LayerDepth.Text, GameFonts.Comic );
            BaseGame.FontMgr.DrawInScrnCoord( "hit Sum   : " + hitSum.ToString(), new Vector2( 500, 80 ), 0.6f, Color.Yellow, LayerDepth.Text, GameFonts.Comic );
            float hitRate = shootSum != 0 ? (float)hitSum * 100 / (float)shootSum : 0;
            BaseGame.FontMgr.DrawInScrnCoord( "hit rate  : " + hitRate.ToString() + "%", new Vector2( 500, 100 ), 0.6f, Color.Yellow, LayerDepth.Text, GameFonts.Comic );


        }

        #endregion

        #region Rules

        SmokeGenerater smoke;

        bool speedy = false;



        //float lastCollideWithBorderTime = -1;
        void item_OnCollided( IGameObj Sender, CollisionResult result, GameObjInfo objB )
        {

            if (objB.ObjClass == "Border")
            {
                ((ItemCommon)Sender).Vel = -2 * Vector2.Dot( ((ItemCommon)Sender).Vel, result.NormalVector ) * result.NormalVector + ((ItemCommon)Sender).Vel;

                //float curTime = GameManager.CurTime;
                //if (lastCollideWithBorderTime != -1 && curTime - lastCollideWithBorderTime < 0.05f)
                //    ((ItemCommon)Sender).Scale -= 0.1f * 0.25f;

                //lastCollideWithBorderTime = curTime;
            }
            else if (objB.ObjClass == "Tank")
            {
                //((ItemCommon)Sender).Scale += 0.1f * 0.25f;
                //((ItemCommon)Sender).Pos += result.NormalVector * 10f;
                ((ItemCommon)Sender).Vel = ((ItemCommon)Sender).Vel.Length() * result.NormalVector;


                if (firstHitTank)
                {
                    showFirstHitTank = true;
                    firstHitTank = false;
                }
            }
            else if (objB.ObjClass == "ShellNormal")
            {
                smoke.Concen += 0.3f;

                if (((ItemCommon)Sender).Scale < 0.5f * 0.031f)
                {
                    //scene.RemoveGameObj( Sender, true, false, false, false, SceneKeeperCommon.GameObjLayer.HighBulge );
                    sceneMgr.DelGameObj( "shell", Sender.Name );
                    Score += 100;

                    hitSum++;

                    AddNewItem( Sender );

                    if (firstScore)
                    {
                        showFirstScore = true;
                        firstScore = false;
                    }

                    smoke.Concen = 0;
                }
                else
                {
                    ((ItemCommon)Sender).Scale -= 0.15f * 0.031f;
                    ((ItemCommon)Sender).Vel = -result.NormalVector * ((ItemCommon)Sender).Vel.Length();
                    hitSum++;
                }

                if (firstHit)
                {
                    showFirstHit = true;
                    firstHit = false;
                }

                NiceShootSum += 2;
                showNiceShoot = true;

                if (NiceShootSum >= 30 && !speedy)
                {
                    TextEffectMgr.AddRiseFade( "You Got A Speedy Turret!", tank.Pos, 2f, Color.Purple, LayerDepth.Text, GameFonts.Lucida, 300, 0.2f );
                    tank.FireCDTime = 2f;
                    speedy = true;
                }
            }

        }

        private void AddNewItem( IGameObj Sender )
        {
            Vector2 pos;
            do
            {
                pos = RandomHelper.GetRandomVector2( 10, 140 );
            }
            while (Vector2.Distance( pos, tank.Pos ) < 30);

            Vector2 vel = RandomHelper.GetRandomVector2( Score / 10, Score / 5 );
            ((ItemCommon)Sender).Pos = pos;
            ((ItemCommon)Sender).Vel = vel;
            ((ItemCommon)Sender).Azi = RandomHelper.GetRandomFloat( 0, 10 );
            ((ItemCommon)Sender).Scale = 0.031f;
            //scene.AddGameObj( Sender, true, false, false, SceneKeeperCommon.GameObjLayer.HighBulge );
            sceneMgr.AddGameObj( "ball", Sender );
        }

        int shellCount = 0;

        void Tank_onShoot( Tank sender, Vector2 turretEnd, float azi )
        {
            ShellNormal newShell = new ShellNormal( "shell" + shellCount.ToString(), sender, turretEnd, azi, shellSpeed );
            newShell.onCollided += new OnCollidedEventHandler( Shell_onCollided );
            newShell.onOverlap += new OnCollidedEventHandler( Shell_onOverlap );
            //scene.AddGameObj( newShell, true, false, false, SceneKeeperCommon.GameObjLayer.lowFlying );
            sceneMgr.AddGameObj( "shell", newShell );
            shootSum++;
            //camera.Focus( newShell );
        }

        void Shell_onOverlap( IGameObj Sender, CollisionResult result, GameObjInfo objB )
        {
            if (objB.ObjClass == "Border")
                NiceShootSum = Math.Max( 0, NiceShootSum - 10 );
            //camera.Focus( tank );
        }

        void Shell_onCollided( IGameObj Sender, CollisionResult result, GameObjInfo objB )
        {
            //scene.RemoveGameObj( Sender, true, false, false, false, SceneKeeperCommon.GameObjLayer.lowFlying );
            sceneMgr.DelGameObj( "shell", Sender.Name );

            //camera.Focus( tank );
            //if (objB.Name == "Border")
            //{
            //    NiceShootSum = Math.Max( 0, NiceShootSum - 1 );
            //}
        }



        #endregion


    }

    class ItemEyeableInfo : IEyeableInfo
    {
        EyeableInfo eyeableInfo;
        Vector2 vel;

        public Vector2 Pos
        {
            get { return eyeableInfo.Pos; }
        }

        public Vector2 Vel
        {
            get { return vel; }
        }

        public ItemEyeableInfo( ItemCommon item )
        {
            this.eyeableInfo = new EyeableInfo( item );
            this.vel = item.Vel;
        }

        #region IEyeableInfo 成员

        public GameObjInfo ObjInfo
        {
            get { return eyeableInfo.ObjInfo; }
        }

        public Vector2[] CurKeyPoints
        {
            get { return eyeableInfo.CurKeyPoints; }
        }

        public Matrix CurTransMatrix
        {
            get { return eyeableInfo.CurTransMatrix; }
        }

        #endregion
    }

    class Ball : ItemCommon
    {
        public Ball( string name, float scale, Vector2 pos, float azi, Vector2 vel, float rotaVel )
            : base( name, "item" , "Scorpion" , Path.Combine( Directories.GameObjsDirectory, "Internal\\Ball" ) ,
            GameObjData.Load( File.OpenRead( Path.Combine( Directories.GameObjsDirectory, "Internal\\Ball\\Ball.xml" ) ) ) ,
            scale , pos , azi , vel , rotaVel )
        {
            this.GetEyeableInfoHandler = new GetEyeableInfoHandler( GetItemInfo );
        }

        IEyeableInfo GetItemInfo( IRaderOwner raderOwner, IEyeableObj item )
        {
            return (IEyeableInfo)(new ItemEyeableInfo( (ItemCommon)item ));
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.IO;
using InterRules.ShootTheBall;
using SmartTank.Rule;
using SmartTank.Screens;
using SmartTank.Draw.UI.Controls;
using SmartTank.Helpers.DependInject;
using TankEngine2D.DataStructure;
using SmartTank.Draw;
using SmartTank.Draw.BackGround.VergeTile;
using SmartTank.Scene;
using SmartTank.AI;
using SmartTank.GameObjs.Tank.SinTur;
using SmartTank.GameObjs.Item;
using SmartTank.Draw.UI;
using SmartTank;
using TankEngine2D.Input;
using SmartTank.Update;
using SmartTank.Effects.TextEffects;
using SmartTank.GameObjs;
using SmartTank.Helpers;
using SmartTank.Senses.Vision;
using TankEngine2D.Graphics;

namespace InterRules.FindPath
{
    [RuleAttribute( "FindPath", "测试AI的寻路能力", "SmartTank编写组", 2007, 11, 20 )]
    public class FindPathRule : IGameRule
    {
        #region Variables

        Combo aiList;

        TextButton btn;

        int selectIndex;

        AILoader aiLoader;

        #endregion

        #region IGameRule 成员

        public string RuleIntroduction
        {
            get { return "测试AI的寻路能力"; }
        }

        public string RuleName
        {
            get { return "FindPath"; }
        }

        #endregion

        public FindPathRule()
        {
            BaseGame.ShowMouse = true;

            aiList = new Combo( "AIList", new Vector2( 200, 200 ), 300 );

            aiList.OnChangeSelection += new EventHandler( AIList_OnChangeSelection );

            aiLoader = new AILoader();
            aiLoader.AddInterAI( typeof( PathFinderThird ) );
            aiLoader.AddInterAI( typeof( PathFinderSecond ) );
            aiLoader.AddInterAI( typeof( ManualControl ) );
            aiLoader.AddInterAI( typeof( PathFinderFirst ) );
            aiLoader.InitialCompatibleAIs( typeof( IAIOrderServerSinTur ), typeof( AICommonServer ) );
            foreach (string name in aiLoader.GetAIList())
            {
                aiList.AddItem( name );
            }
            btn = new TextButton( "OkBtn", new Vector2( 700, 500 ), "Begin", 0, Color.Blue );
            btn.OnClick += new EventHandler( btn_OnClick );
        }

        void btn_OnClick( object sender, EventArgs e )
        {
            GameManager.AddGameScreen( new FindPathGameScreen( aiLoader.GetAIInstance( selectIndex ) ) );
        }

        void AIList_OnChangeSelection( object sender, EventArgs e )
        {
            selectIndex = aiList.currentIndex;
        }

        #region IGameScreen 成员

        public void Render()
        {
            BaseGame.Device.Clear( Color.BurlyWood );
            aiList.Draw( BaseGame.SpriteMgr.alphaSprite, 1f );
            btn.Draw( BaseGame.SpriteMgr.alphaSprite, 1f );
        }

        public bool Update( float second )
        {
            aiList.Update();
            btn.Update();

            if (InputHandler.JustPressKey( Microsoft.Xna.Framework.Input.Keys.Escape ))
                return true;
            return false;
        }

        #endregion
    }

    class FindPathGameScreen : IGameScreen
    {
        static readonly Rectanglef mapSize = new Rectanglef( 0, 0, 1000, 1000 );
        static readonly Rectangle scrnRect = new Rectangle( 0, 0, BaseGame.ClientRect.Width, BaseGame.ClientRect.Height );

        static readonly Vector2 cameraStartPos = new Vector2( 50, 50 );

        const float tankRaderDepth = 100;
        const float tankRaderAng = MathHelper.PiOver4;
        const float tankMaxForwardSpd = 50;
        const float tankMaxBackwardSpd = 30;
        const float tankMaxRotaSpd = 0.3f * MathHelper.Pi;
        const float tankMaxRotaTurretSpd = 0.6f * MathHelper.Pi;
        const float tankMaxRotaRaderSpd = MathHelper.Pi;
        static readonly Vector2 tankStartPos = new Vector2( 20, 20 );
        const float tankStartAzi = 0;

        Camera camera;
        Compass compass;
        VergeTileGround backGround;

        SceneMgr sceneMgr;


        AICommonServer commonServer;

        TankSinTur tank;

        ObstacleCommon wall1;
        ObstacleCommon wall2;
        ObstacleCommon wall3;

        Ball ball;

        public FindPathGameScreen( IAI tankAI )
        {
            BaseGame.CoordinMgr.SetScreenViewRect( scrnRect );
            camera = new Camera( 2, cameraStartPos, 0f );
            compass = new Compass( new Vector2( 740, 540 ) );
            camera.Enable();

            InitialBackGround();

            InitialScene();

            InitialAI( tankAI );

            camera.Focus( tank, true );

            GameTimer timer = new GameTimer( 5,
                delegate()
                {
                    TextEffectMgr.AddRiseFadeInScrnCoordin( "test FadeUp in Scrn!", new Vector2( 100, 100 ), 1f, Color.Black, LayerDepth.Text, GameFonts.Lucida, 300, 0.5f );
                    TextEffectMgr.AddRiseFade( "test FadeUp in Login!", new Vector2( 100, 100 ), 1f, Color.White, LayerDepth.Text, GameFonts.Lucida, 300, 0.5f );
                } );
        }

        private void InitialAI( IAI tankAI )
        {
            commonServer = new AICommonServer( mapSize );
            tank.SetTankAI( tankAI );
            tankAI.OrderServer = tank;
            tankAI.CommonServer = commonServer;

            GameManager.ObjMemoryMgr.AddSingle( tank );
        }

        private void InitialScene()
        {
            sceneMgr = new SceneMgr();

            tank = new TankSinTur( "tank", new GameObjInfo( "Tank", string.Empty ),
                TankSinTur.M60TexPath, TankSinTur.M60Data,
                tankRaderDepth, tankRaderAng, Color.Wheat,
                tankMaxForwardSpd, tankMaxBackwardSpd, tankMaxRotaSpd, tankMaxRotaTurretSpd, tankMaxRotaRaderSpd,
                0.3f, tankStartPos, tankStartAzi );

            wall1 = new ObstacleCommon( "wall1", new GameObjInfo( "wall", string.Empty ), new Vector2( 100, 50 ), 0,
                Path.Combine( Directories.ContentDirectory, "GameObjs\\wall" ),
                new Vector2( 90, 15 ), 1f, Color.White, LayerDepth.GroundObj, new Vector2[] { new Vector2( 90, 15 ) } );
            wall1.GetEyeableInfoHandler = EyeableInfo.GetEyeableInfoHandler;

            wall2 = new ObstacleCommon( "wall2", new GameObjInfo( "wall", string.Empty ), new Vector2( 250, 150 ), MathHelper.PiOver2,
                            Path.Combine( Directories.ContentDirectory, "GameObjs\\wall" ),
                            new Vector2( 90, 15 ), 1f, Color.White, LayerDepth.GroundObj, new Vector2[] { new Vector2( 90, 15 ) } );
            wall2.GetEyeableInfoHandler = EyeableInfo.GetEyeableInfoHandler;

            wall3 = new ObstacleCommon( "wall3", new GameObjInfo( "wall", string.Empty ), new Vector2( 100, 100 ), 0,
                Path.Combine( Directories.ContentDirectory, "GameObjs\\wall" ),
                new Vector2( 90, 15 ), 1f, Color.White, LayerDepth.GroundObj, new Vector2[] { new Vector2( 90, 15 ) } );
            wall3.GetEyeableInfoHandler = EyeableInfo.GetEyeableInfoHandler;


            ball = new Ball( "ball", 0.3f, new Vector2( 300, 250 ), 0, new Vector2( 5, 5 ), 0 );

            sceneMgr.AddGroup( "", new TypeGroup<TankSinTur>( "tank" ) );
            sceneMgr.AddGroup( "", new Group( "obstacle" ) );
            sceneMgr.AddGroup( "obstacle", new TypeGroup<ObstacleCommon>( "wall" ) );
            sceneMgr.AddGroup( "obstacle", new TypeGroup<Ball>( "ball" ) );
            sceneMgr.AddGroup( "obstacle", new TypeGroup<SmartTank.PhiCol.Border>( "border" ) );
            sceneMgr.AddColMulGroups( "tank", "obstacle" );
            sceneMgr.PhiGroups.AddRange( new string[] { "tank", "obstacle\\ball" } );
            sceneMgr.AddShelterMulGroups( "tank", "obstacle\\wall" );
            sceneMgr.VisionGroups.Add( new SceneMgr.MulPair( "tank", new List<string>( new string[] { "obstacle\\ball", "obstacle\\wall" } ) ) );

            sceneMgr.AddGameObj( "tank", tank );
            sceneMgr.AddGameObj( "obstacle\\wall", wall1, wall2, wall3 );
            sceneMgr.AddGameObj( "obstacle\\ball", ball );
            sceneMgr.AddGameObj( "obstacle\\border", new SmartTank.PhiCol.Border( mapSize ) );
            
            GameManager.LoadScene( sceneMgr );
        }

        private void InitialBackGround()
        {
            VergeTileData data = new VergeTileData();
            data.gridWidth = 50;
            data.gridHeight = 50;
            data.SetRondomVertexIndex( 50, 50, 4 );
            data.SetRondomGridIndex( 50, 50 );
            data.texPaths = new string[]
            {
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_Dirt.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_DirtRough.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_DirtGrass.tga"),
                Path.Combine(Directories.ContentDirectory,"BackGround\\Lords_GrassDark.tga"),
            };
            backGround = new VergeTileGround( data, scrnRect, mapSize );
        }


        #region IGameScreen 成员

        public void Render()
        {
            BaseGame.Device.Clear( Color.Blue );

            backGround.Draw();

            //BasicGraphics.DrawRectangle( wall.BoundingBox, 3f, Color.Red, 0f );

            //BasicGraphics.DrawRectangle( mapSize, 3f, Color.Red, 0f );
            foreach (Vector2 keyPoint in ball.KeyPoints)
            {
                BaseGame.BasicGraphics.DrawPoint( Vector2.Transform( keyPoint, ball.TransMatrix ), 1f, Color.Black, 0f );
            }
            BaseGame.BasicGraphics.DrawPoint( Vector2.Transform( wall1.KeyPoints[0], wall1.TransMatrix ), 1f, Color.Black, 0f );
            BaseGame.BasicGraphics.DrawPoint( Vector2.Transform( wall2.KeyPoints[0], wall2.TransMatrix ), 1f, Color.Black, 0f );
            BaseGame.BasicGraphics.DrawPoint( Vector2.Transform( wall3.KeyPoints[0], wall3.TransMatrix ), 1f, Color.Black, 0f );


            GameManager.DrawManager.Draw();
            compass.Draw();

        }

        public bool Update( float second )
        {
            camera.Update( second );
            compass.Update();

            GameManager.UpdataComponent( second );

            if (InputHandler.JustPressKey( Microsoft.Xna.Framework.Input.Keys.Escape ))
                return true;
            return false;
        }

        #endregion
    }
}
<file_sep>#ifndef _HEAD_H_
#define _HEAD_H_

#include "config.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <time.h>
#include "assert.h"
using namespace std;

#pragma warning( disable:  4996)
#pragma warning( disable:  4267)
#pragma warning( disable:  4244)

struct MyTimer //Timer结构体，用来保存一个定时器的信息
{    
    int total_time;  //每隔total_time秒
    int left_time;   //还剩left_time秒
    int func;        //该定时器超时，要执行的代码的标志
};

#ifdef WIN32
    typedef int socklen_t; 
    typedef int ssize_t; 
    #define MSG_NOSIGNAL 0 // send最后参数:linux最好设为MSG_NOSIGNAL否则在发送出错后可能会导致程序退出
    #include <winsock2.h>  
    #include <windows.h>
    #define GetMyError       GetLastError()
    #define pthread_mutex_t  CRITICAL_SECTION
    #define LockThreadBegin  EnterCriticalSection(&DD_ClientMgr_Mutex[nID]);
    #define LockThreadEnd    LeaveCriticalSection(&DD_ClientMgr_Mutex[nID]);
#else
    typedef int SOCKET; 
    typedef unsigned char BYTE; 
    typedef unsigned long DWORD; 
    #define FALSE 0 
    #define SOCKET_ERROR (-1) 

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/time.h>
    #include <stdio.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <pthread.h>         
    #include <errno.h>           // 错误处理
    #include <signal.h>          // 信号机制
    #define GetMyError       errno
    #define LockThreadBegin  pthread_mutex_lock(&DD_ClientMgr_Mutex[nID]);
    #define LockThreadEnd  pthread_mutex_unlock(&DD_ClientMgr_Mutex[nID]);
#endif





#endif



 

<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using TankEngine2D.Helpers;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using Microsoft.Xna.Framework;
using System.Runtime.InteropServices;

namespace SmartTank.net
{
    struct SocketConfig
    {
        public string ServerIP;
        public int ServerPort;
    };


    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct stPkgHead
    {
        static public int Size = 8;
        //static public int MaxDataSize = 1028;
        //static public int TotolSize
        //{
        //    get { return Size + MaxDataSize; }
        //}


        public int iSytle;
        public int dataSize;

        //[MarshalAs(UnmanagedType.ByValStr, SizeConst = 1024)]
        //public string data;
        //int数组，SizeConst表示数组的个数，在转换成
        //byte数组前必须先初始化数组，再使用，初始化
        //的数组长度必须和SizeConst一致，例test = new int[6];
        //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        //public int[] test;

    }



    static public class SocketMgr
    {
        public delegate void ReceivePkgEventHandler(stPkgHead head, byte[] readData);
        public static event ReceivePkgEventHandler OnReceivePkg;

        static SocketConfig config;
        static TcpClient client;
        //static Socket sckt;
        static Thread thread;
        static SyncCashe sInputCashe;


        /// <summary>
        /// 初始化，读配置文件
        /// </summary>
        public static void Initial()
        {
            ReadConfig();
            InitialTypeTable();
        }

        static public void SetInputCahes(SyncCashe inputCashe)
        {
            sInputCashe = inputCashe;
        }

        static void ReadConfig()
        {
            try
            {
                FileStream stream = new FileStream("SocketConfig.txt", FileMode.Open);
                StreamReader reader = new StreamReader(stream);
                string line = reader.ReadLine();
                while (line != null)
                {
                    if (line.Contains("ServerIP=")) config.ServerIP = line.Remove(0, 9);
                    else if (line.Contains("ServerPort=")) config.ServerPort = int.Parse(line.Remove(0, 11));
                    line = reader.ReadLine();
                }
                reader.Close();
                stream.Close();
            }
            catch (Exception ex)
            {
                Log.Write("net.SocketMgr ReadConfig error!" + ex.ToString());
            }
        }

        static public bool ConnectToServer()
        {
            if (client != null && client.Connected == true)
                return true;

            try
            {
                IPAddress IPAdd = IPAddress.Parse(config.ServerIP);
                IPEndPoint endPoint = new IPEndPoint(IPAdd, config.ServerPort);
                //sckt = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                //sckt.Connect(endPoint);
                //if (sckt.Connected)
                //    return true;
                //else
                //    return false;
                client = new TcpClient();

                client.Connect(endPoint);
                if (client.Connected)
                    return true;
                else
                    return false;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return false;
            }
        }

        static public void SendGameLogicPackge(SyncCashe cash)
        {
            try
            {
                if (client.Connected)
                {
                    Stream netStream = client.GetStream();

                    if (netStream.CanWrite)
                    {

                        // Head
                        stPkgHead head = new stPkgHead();
                        head.iSytle = (int)PACKAGE_SYTLE.DATA;

                        MemoryStream MStream = new MemoryStream();
                        //StreamWriter SW = new StreamWriter(MStream);
                        BinaryWriter BW = new BinaryWriter(MStream);


                        // 状态同步数据
                        BW.Write(cash.ObjStaInfoList.Count);

                        
                        //SW.WriteLine(cash.ObjStaInfoList.Count);
                        foreach (ObjStatusSyncInfo info in cash.ObjStaInfoList)
                        {
                            //SW.WriteLine(info.objMgPath);
                            BW.Write(info.objMgPath);
                            BW.Write(info.statusName);
                            BW.Write(info.values.Length);
                            foreach (object obj in info.values)
                            {
                                WriteObjToStream(BW, obj);
                            }
                        }

                        // 事件同步数据
                        BW.Write(cash.ObjEventInfoList.Count);
                        foreach (ObjEventSyncInfo info in cash.ObjEventInfoList)
                        {
                            BW.Write(info.objMgPath);
                            BW.Write(info.EventName);
                            BW.Write(info.values.Length);
                            foreach (object obj in info.values)
                            {
                                WriteObjToStream(BW, obj);
                            }
                        }

                        // 物体管理同步数据
                        BW.Write(cash.ObjMgInfoList.Count);
                        foreach (ObjMgSyncInfo info in cash.ObjMgInfoList)
                        {
                            BW.Write(info.objPath);
                            BW.Write(info.objMgKind);
                            BW.Write(info.objType);
                            BW.Write(info.args.Length);
                            foreach (object obj in info.args)
                            {
                                WriteObjToStream(BW, obj);
                            }
                        }

                        // 用户自定义数据
                        BW.Write(cash.UserDefineInfoList.Count);
                        foreach (UserDefineInfo info in cash.UserDefineInfoList)
                        {
                            BW.Write(info.infoName);
                            BW.Write(info.infoID);
                            BW.Write(info.args.Length);
                            foreach (object obj in info.args)
                            {
                                WriteObjToStream(BW, obj);
                            }
                        }

                        BW.Flush();
                        int dataLength = (int)MStream.Length;
                        //int dataLength = (int)SW.BaseStream.Length;

                        byte[] temp = new byte[dataLength];
                        MStream.Position = 0;
                        MStream.Read(temp, 0, dataLength);

                        head.dataSize = temp.Length;


                        netStream.Write(StructToBytes(head), 0, stPkgHead.Size);
                        netStream.Write(temp, 0, head.dataSize);

                        // 释放资源
                        BW.Close();
                        MStream.Close();

                        Console.WriteLine("Send " + head.iSytle + " " + head.dataSize);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return;
            }

        }

        static public void SendCommonPackge(stPkgHead head, MemoryStream data)
        {
            if (head.dataSize != 0 && (data == null || head.dataSize != data.Length))
                throw new Exception("发送的包头有误");

            try
            {
                if (client != null && client.Connected)
                {
                    Stream netStream = client.GetStream();

                    if (netStream.CanWrite)
                    {
                        netStream.Write(StructToBytes(head), 0, stPkgHead.Size);
                        if (data != null)
                            data.WriteTo(netStream);

                        Console.WriteLine("Send " + head.iSytle + " " + head.dataSize);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return;
            }
        }

        static public void ReceivePackge()
        {
            
            try
            {
                while (true)
                {
                    if (client.Connected)
                    {
                        byte[] buffer = new byte[stPkgHead.Size];
                        Stream netStream = client.GetStream();

                        if (netStream.CanRead)
                        {
                            // 这里要确保每次读一个整包
                            netStream.Read(buffer, 0, stPkgHead.Size);
                            stPkgHead pkg = (stPkgHead)BytesToStuct(buffer, typeof(stPkgHead));

                            Console.WriteLine("ReceiveDataPkg:");
                            Console.WriteLine("Sytle : " + pkg.iSytle);
                            Console.WriteLine("Size : " + pkg.dataSize);

                            int recvLength = 0;
                            byte[] readData = new byte[pkg.dataSize];
                            while (recvLength < pkg.dataSize)
                            {
                                recvLength += netStream.Read(readData, recvLength, pkg.dataSize - recvLength);
                            }
                            if (recvLength != pkg.dataSize)
                            {
                                throw new Exception("危险：收到包的长度不等于实际包长");
                            }

                            // 退出信号
                            if (pkg.iSytle == (int)PACKAGE_SYTLE.EXIT)
                            {
                                Console.WriteLine("read close info");
                                break;
                            }

                            // 数据
                            else if (pkg.iSytle == (int)PACKAGE_SYTLE.DATA)
                            {

                                //byte[] readData = new byte[pkg.dataSize];
                                //netStream.Read(readData, 0, pkg.dataSize);
                                SyncCashe cashe = sInputCashe;

                                MemoryStream memStream = new MemoryStream(readData);

                                //StreamReader SR = new StreamReader(memStream);
                                BinaryReader BR = new BinaryReader(memStream);
                                try
                                {
                                    //string temp = ""; 

                                    // 物体状态同步数据
                                    //temp = SR.ReadLine();
                                    int StaCount = BR.ReadInt32();//int.Parse(temp);


                                    for (int i = 0; i < StaCount; i++)
                                    {
                                        ObjStatusSyncInfo info = new ObjStatusSyncInfo();

                                        //temp = SR.ReadLine();
                                        //Console.WriteLine("ObjName:" + temp);
                                        info.objMgPath = BR.ReadString();//temp;


                                        //temp = SR.ReadLine();
                                        //Console.WriteLine("StatusName: " + temp);
                                        info.statusName = BR.ReadString();//temp;


                                        //temp = SR.ReadLine();
                                        //Console.WriteLine("ValueCount: " + temp);
                                        int valueCount = BR.ReadInt32(); //int.Parse(temp);


                                        info.values = new object[valueCount];
                                        for (int j = 0; j < valueCount; j++)
                                        {
                                            info.values[j] = ReadObjFromStream(BR);
                                        }

                                        // 添加Info到缓冲区
                                        Monitor.Enter(cashe);
                                        cashe.ObjStaInfoList.Add(info);
                                        Monitor.Exit(cashe);

                                        //Console.WriteLine("Read Pkg Success!");
                                    }

                                    // 事件同步数据
                                    //temp = SR.ReadLine();
                                    int EventCount = BR.ReadInt32(); //int.Parse(temp);
                                    for (int i = 0; i < EventCount; i++)
                                    {
                                        ObjEventSyncInfo info = new ObjEventSyncInfo();

                                        //temp = SR.ReadLine();
                                        info.objMgPath = BR.ReadString();//temp;


                                        //temp = SR.ReadLine();
                                        info.EventName = BR.ReadString();// temp;


                                        //temp = SR.ReadLine();
                                        int valueCount = BR.ReadInt32();// int.Parse(temp);

                                        info.values = new object[valueCount];
                                        for (int j = 0; j < valueCount; j++)
                                        {
                                            info.values[j] = ReadObjFromStream(BR);
                                        }

                                        // 添加Info到缓冲区
                                        Monitor.Enter(cashe);
                                        cashe.ObjEventInfoList.Add(info);
                                        Monitor.Exit(cashe);

                                    }

                                    // 物体管理同步数据

                                    //temp = SR.ReadLine();
                                    int ObjMgCount = BR.ReadInt32(); //int.Parse(temp);
                                    for (int i = 0; i < ObjMgCount; i++)
                                    {
                                        ObjMgSyncInfo info = new ObjMgSyncInfo();

                                        //temp = SR.ReadLine();
                                        info.objPath = BR.ReadString();//temp;


                                        //temp = SR.ReadLine();
                                        info.objMgKind = BR.ReadInt32(); //int.Parse(temp);


                                        //temp = SR.ReadLine();
                                        info.objType = BR.ReadString();//temp;

                                        //temp = SR.ReadLine();
                                        int valueCount = BR.ReadInt32();// int.Parse(temp);

                                        info.args = new object[valueCount];
                                        for (int j = 0; j < valueCount; j++)
                                        {
                                            info.args[j] = ReadObjFromStream(BR);
                                        }

                                        // 添加Info到缓冲区
                                        Monitor.Enter(cashe);
                                        cashe.ObjMgInfoList.Add(info);
                                        Monitor.Exit(cashe);

                                    }

                                    // 用户自定义数据
                                    //temp = BR.ReadLine();
                                    int UserDefinCount = BR.ReadInt32();// int.Parse(temp);
                                    for (int i = 0; i < UserDefinCount; i++)
                                    {
                                        UserDefineInfo info = new UserDefineInfo();

                                        //temp = SR.ReadLine();
                                        info.infoName = BR.ReadString();// temp;
                                        //temp = SR.ReadLine();
                                        info.infoID = BR.ReadString();//temp;

                                        //temp = SR.ReadLine();
                                        int valueCount = BR.ReadInt32();//int.Parse(temp);

                                        info.args = new object[valueCount];
                                        for (int j = 0; j < valueCount; j++)
                                        {
                                            info.args[j] = ReadObjFromStream(BR);
                                        }
                                        Monitor.Enter(cashe);
                                        cashe.UserDefineInfoList.Add(info);
                                        Monitor.Exit(cashe);
                                    }

                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine(ex);
                                }
                                finally
                                {
                                    memStream.Close();
                                    ////需要清空当前包中剩余内容
                                    //int left = stPakage.TotolSize / sizeof(char) - (int)SR.BaseStream.Position;
                                    //char[] temp = new char[left];
                                    //SR.Read(temp, 0, left);
                                }
                            }
                            else
                            {
                                if (pkg.dataSize < 1024 * 10 && pkg.dataSize >= 0)
                                {
                                    byte[] temp = new byte[pkg.dataSize];
                                    readData.CopyTo(temp, 0);
                                    if (OnReceivePkg != null)
                                        OnReceivePkg(pkg, temp);

                                }
                                else
                                {
                                    Log.Write("包头有问题: type: " + pkg.iSytle + " , size: " + pkg.dataSize);
                                    Console.WriteLine("包头有问题: type: " + pkg.iSytle + " , size: " + pkg.dataSize);
                                    //throw new Exception("包头有问题啊，我日");
                                    // 包头很可能有问题
                                }
                            }
                        }
                    }
                }
            }
            catch (SocketException ex)
            {
                Console.WriteLine(ex.ToString());
            }
            finally
            {
                client.Close();
                client = null;
            }
        }



        static public void StartReceiveThread()
        {
            if (client != null && client.Connected && thread == null)
            {
                thread = new Thread(ReceivePackge);
                thread.Start();
            }
        }

        static public bool Close()
        {
            if (client != null && client.Connected)
            {
                stPkgHead pkg = new stPkgHead();
                pkg.iSytle = (int)PACKAGE_SYTLE.EXIT;
                client.GetStream().Write(StructToBytes(pkg), 0, stPkgHead.Size);
                thread = null;
            }
            return true;
        }

        static Dictionary<string,UInt16> TypeIndexTable = new Dictionary<string,ushort>();

        static void InitialTypeTable()
        {
            TypeIndexTable.Clear();
            TypeIndexTable.Add("null", 0);            
            TypeIndexTable.Add("Microsoft.Xna.Framework.Vector2", 1);
            TypeIndexTable.Add("SmartTank.net.GameObjSyncInfo", 2);
            TypeIndexTable.Add("TankEngine2D.Graphics.CollisionResult", 3);
            TypeIndexTable.Add("SmartTank.GameObjs.GameObjInfo", 4);
            TypeIndexTable.Add("System.Boolean", 5);
            TypeIndexTable.Add("System.Int32", 6);
            TypeIndexTable.Add("System.String", 7);
            TypeIndexTable.Add("System.Single", 8);
            
        }

        private static void WriteObjToStream(BinaryWriter BW, object obj)
        {
            if (obj == null)
            {
                BW.Write(TypeIndexTable["null"]);
                return;
            }

            //BW.Write(obj.GetType().ToString());
            BW.Write(TypeIndexTable[obj.GetType().ToString()]);
            switch (obj.GetType().ToString())
            {
                case "Microsoft.Xna.Framework.Vector2":
                    BW.Write(((Microsoft.Xna.Framework.Vector2)obj).X);
                    BW.Write(((Microsoft.Xna.Framework.Vector2)obj).Y);
                    break;
                case "SmartTank.net.GameObjSyncInfo":
                    BW.Write(((GameObjSyncInfo)obj).MgPath);
                    break;
                case "TankEngine2D.Graphics.CollisionResult":
                    TankEngine2D.Graphics.CollisionResult result = obj as TankEngine2D.Graphics.CollisionResult;
                    WriteObjToStream(BW, result.InterPos);
                    WriteObjToStream(BW, result.NormalVector);
                    WriteObjToStream(BW, result.IsCollided);
                    break;
                case "SmartTank.GameObjs.GameObjInfo":
                    SmartTank.GameObjs.GameObjInfo objInfo = obj as SmartTank.GameObjs.GameObjInfo;
                    BW.Write(objInfo.ObjClass);
                    BW.Write(objInfo.Script);
                    break;
                case "System.Boolean":
                    BW.Write((bool)obj);
                    break;
                case "System.Int32":
                    BW.Write((Int32)obj);
                    break;
                case "System.String":
                    BW.Write((String)obj);
                    break;
                case "System.Single":
                    BW.Write((Single)obj);
                    break;

                default:
                    throw new Exception("某种类型的数据没有发送");
                    break;
            }
        }

        private static object ReadObjFromStream(BinaryReader BR)
        {
            //string temp;

            //temp = BR.ReadString();
            //Console.WriteLine("TypeName: " + temp);
            UInt16 typeIndex = BR.ReadUInt16();

            if (typeIndex == TypeIndexTable["null"])
                return null;

            switch (typeIndex)
            {
                case 7://TypeIndexTable["System.String"]:
                    return BR.ReadString();
                case 8://TypeIndexTable["System.Single"]:
                    return BR.ReadSingle();//float.Parse(temp);
                case 1://TypeIndexTable["Microsoft.Xna.Framework.Vector2"]:
                    //temp = SR.ReadLine();
                    float x = BR.ReadSingle();// float.Parse(temp);
                    //temp = SR.ReadLine();
                    float y = BR.ReadSingle();// float.Parse(temp);
                    return new Microsoft.Xna.Framework.Vector2(x, y);
                case 2://TypeIndexTable["SmartTank.net.GameObjSyncInfo"]:
                    //temp = ;//SR.ReadLine();
                    return new GameObjSyncInfo(BR.ReadString());
                case 3://TypeIndexTable["TankEngine2D.Graphics.CollisionResult"]:
                    Vector2 InterPos = (Vector2)ReadObjFromStream(BR);
                    Vector2 NormalVector = (Vector2)ReadObjFromStream(BR);
                    bool IsCollided = (bool)ReadObjFromStream(BR);
                    return new TankEngine2D.Graphics.CollisionResult(IsCollided, InterPos, NormalVector);
                case 5://TypeIndexTable["System.Boolean"]:
                    //temp = SR.ReadLine();
                    return BR.ReadBoolean();//bool.Parse(temp);
                case 6://TypeIndexTable["System.Int32"]:
                    //temp = SR.ReadLine();
                    return BR.ReadInt32();// int.Parse(temp);
                case 4://TypeIndexTable["SmartTank.GameObjs.GameObjInfo"]:
                    string objClass = BR.ReadString();
                    string script = BR.ReadString();
                    return new SmartTank.GameObjs.GameObjInfo(objClass, script);
                default:
                    Console.WriteLine(typeIndex);
                    throw new Exception("某个格式的数据没有被解析");
            }
        }


        /// <summary>
        /// 结构体转byte数组
        /// </summaryss
        /// <param name="structObj">要转换的结构体</param>
        /// <returns>转换后的byte数组</returns>
        static public byte[] StructToBytes(object structObj)
        {
            //得到结构体的大小
            int size = Marshal.SizeOf(structObj);
            //创建byte数组
            byte[] bytes = new byte[size];
            //分配结构体大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体拷到分配好的内存空间
            Marshal.StructureToPtr(structObj, structPtr, false);
            //从内存空间拷到byte数组
            Marshal.Copy(structPtr, bytes, 0, size);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            //返回byte数组
            return bytes;
        }

        /// <summary>
        /// byte数组转结构体
        /// </summary>
        /// <param name="bytes">byte数组</param>
        /// <param name="type">结构体类型</param>
        /// <returns>转换后的结构体</returns>
        public static object BytesToStuct(byte[] bytes, Type type)
        {
            //得到结构体的大小
            int size = Marshal.SizeOf(type);
            //byte数组长度小于结构体的大小
            if (size > bytes.Length)
            {
                //返回空
                return null;
            }
            //分配结构体大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将byte数组拷到分配好的内存空间
            Marshal.Copy(bytes, 0, structPtr, size);
            //将内存空间转换为目标结构体
            object obj = Marshal.PtrToStructure(structPtr, type);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            //返回结构体
            return obj;
        }


    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Rule;
using SmartTank.Scene;
using SmartTank.GameObjs.Tank.SinTur;

namespace InterRules.TestNewSceneMgrRule
{
    class TestSceneMgrRule : IGameRule
    {
        SceneMgr sceneMgr;

        public TestSceneMgrRule ()
        {
            sceneMgr = new SceneMgr();

            //TankSinTur tank1 = sceneMgr.GetGameObj( @"Tank\tank1" );
            //TankSinTur tank2 = sceneMgr.GetGameObj( @"Tank\tank2" );

            //tank1.
            
        }

        #region IGameRule ³ΙΤ±

        public string RuleIntroduction
        {
            get { return "this class is to test SceneMgr."; }
        }

        public string RuleName
        {
            get { return "TestSceneMgrRule"; }
        }

        #endregion

        #region IGameScreen ³ΙΤ±

        public void Render ()
        {
            
        }

        public bool Update ( float second )
        {
            return true;
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using TankEngine2D.Helpers;

namespace SmartTank.Helpers.DependInject
{
    public struct NameAndTypeName
    {
        public string name;
        public string typeNames;

        public NameAndTypeName ( string name, string typeNames )
        {
            this.name = name;
            this.typeNames = typeNames;
        }
    }

    public struct AssetItem
    {
        public string DLLName;
        public NameAndTypeName[] names;

        public AssetItem ( string DLLName, NameAndTypeName[] names )
        {
            this.DLLName = DLLName;
            this.names = names;
        }
    }

    public struct TypeAssetPath
    {
        public string DLLName;
        public string typeName;
        public string name;

        public TypeAssetPath ( string DLLName, string typeName, string name )
        {
            this.DLLName = DLLName;
            this.typeName = typeName;
            this.name = name;
        }
    }

    public class AssetList
    {
        #region Type Def


        #endregion

        #region statics
        static XmlSerializer serializer;

        static public void Save ( Stream stream, AssetList data )
        {
            if (serializer == null)
                serializer = new XmlSerializer( typeof( AssetList ) );

            try
            {
                serializer.Serialize( stream, data );
            }
            catch (Exception)
            {
                Log.Write( "Save AssetList error!" );
            }
            finally
            {
                stream.Close();
            }
        }

        static public AssetList Load ( Stream stream )
        {
            if (serializer == null)
            {
                serializer = new XmlSerializer( typeof( AssetList ) );
            }
            AssetList result = null;
            try
            {
                result = (AssetList)serializer.Deserialize( stream );
            }
            catch (Exception)
            {
                Log.Write( "Load AssetList error!" );
            }
            finally
            {
                stream.Close();
            }
            return result;
        }
        #endregion

        public List<AssetItem> list = new List<AssetItem>();

        List<TypeAssetPath> pathList;

        public AssetList ()
        {

        }

        public string[] GetTypeList ()
        {
            if (pathList == null)
            {
                InitialPathList();
            }

            List<string> result = new List<string>();
            foreach (TypeAssetPath assetPath in pathList)
            {
                result.Add( assetPath.name );
            }
            return result.ToArray();
        }

        public TypeAssetPath GetTypeAssetPath ( int index )
        {
            if (pathList == null)
                InitialPathList();

            if (index >= pathList.Count || index < 0)
                return new TypeAssetPath();

            return pathList[index];
        }

        public int IndexOf ( string DLLName )
        {
            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].DLLName.Equals( DLLName ))
                {
                    return i;
                }
            }
            return -1;
        }

        private void InitialPathList ()
        {
            pathList = new List<TypeAssetPath>();
            foreach (AssetItem item in list)
            {
                foreach (NameAndTypeName names in item.names)
                {
                    pathList.Add( new TypeAssetPath( item.DLLName, names.typeNames, names.name ) );
                }
            }
        }
    }
}
<file_sep>#ifndef _CONFIG_H_
#define _CONFIG_H_

/* 服务器基本配置 */
#define IP "192.168.35.225"     // 服务器IP地址
#define MYPORT 9999             // 服务器端口号
#define MYSQL_USERNAME "root"   // 服务器MySql数据库用户名
#ifdef WIN32
    #define MYSQL_PASS "<PASSWORD>"
#else
    #define MYSQL_PASS NULL     // 公司服务器MySql密码为空
#endif

#define MAXCLIENT 100       // 总玩家上限
#define PACKSIZE 10240      // 单次收包上限
#define MAXROOMMATE 2       // 房间人数上限
#define NUM_OF_RANK 10      // 排行榜一页

/* 协议配置 : 登录部分 */
#define LOGIN           10    // 登录包标志
#define LOGIN_SUCCESS   11    // 登录成功反馈
#define LOGIN_FAIL      12    // 登录失败反馈
#define USER_REGIST     15    // 注册帐号
#define USER_DELETE     16    // 删除帐号

/* 协议配置 : 游戏部分 */
#define HEART_BEAT   0  // 心跳包
#define CHAT         1  // 聊天消息包(系统消息包)
#define USER_EXIT 21    // 退出应答包

#define ROOM_CREATE    30    // 创建房间
#define ROOM_JOIN      31    // 加入房间
#define ROOM_DESTROY   32    // 销毁房间
#define ROOM_LIST      33    // 列举房间信息
#define ROOM_LISTUSER  34    // 列举房间所有用户信息
#define CREATE_SUCCESS 35    // 创建房间成功
#define CREATE_FAIL    36    // 创建房间失败
#define JOIN_SUCCESS   37    // 加入房间成功
#define JOIN_FAIL      38    // 加入房间失败
#define ROOM_EXIT      39    // 房间有人退出

#define USER_INFO 40    // 查询自己的帐号信息
#define USER_RANK 50    // 列举排行榜信息(M-N)

#define GAME_GO           70    // 游戏正式开始
#define GAME_START_FAIL   71    // 开始请求失败
#define GAME_OVER         72    // 开始请求失败
#define GAME_RESULT       80    // 游戏结果保存
#define USER_DATA         100   // 游戏数据：正常游戏时的数据交换

typedef struct _PacketHead_Target
{
    int  iStyle ;        // 数据包类型
    int  length;         // 包体长度(不包括包头!)
}PacketHead, *PPacketHead;

// 变长数据包: 前8个字节为包头，后面可任意填充数据
typedef struct _Packet_Target
{
    int iStyle;          // 数据包类型
    int length;          // 包体长度(不包括包头!)
    char data[PACKSIZE]; // msg
}Packet, *PPacket;

#define SIZEOFPACKET sizeof(Packet)
#define HEADSIZE sizeof(PacketHead)

/* 用户数据库 */

// 用户登录用此包
struct UserLoginPack{
    char Name[21];
    char Password[21];
}; 

// 用户数据库信息
struct UserInfo {
    int ID;
    char Name[21];
    char Password[21];
    int Score;
    int Rank;
};

// 排行榜数据信息
struct RankInfo {
    int Rank;      // 排名
    int Score;     // 得分
    char Name[21]; // 用户名
};

// 房间数据信息 
struct RoomInfo {
    int nID;        // 房间号
    int players;    // 该房间有几个人
    int bBegin;     // 表示该房间游戏是否开始，0:没开始可以加入,1:已经开始禁止进入 
    char Name[21];  // 房间名字
};




#endif









<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Senses.Vision;
using Microsoft.Xna.Framework;
using SmartTank.PhiCol;
using TankEngine2D.Graphics;
using SmartTank.Senses.Memory;
using TankEngine2D.DataStructure;
using SmartTank.GameObjs;

namespace SmartTank.AI
{
    public delegate void OnCollidedEventHandlerAI ( CollisionResult result, GameObjInfo objB );

    public interface IAIOrderServer
    {
        /// <summary>
        /// 获得可见物体的信息
        /// </summary>
        /// <returns></returns>
        List<IEyeableInfo> GetEyeableInfo ();

        /// <summary>
        /// 获得坦克的当前位置
        /// </summary>
        Vector2 Pos { get;}

        /// <summary>
        /// 获得坦克当前的方位角
        /// </summary>
        float Azi { get;}

        /// <summary>
        /// 获得坦克当前朝向的单位向量
        /// </summary>
        Vector2 Direction { get;}

        /// <summary>
        /// 获得坦克前进的极限速度
        /// </summary>
        float MaxForwardSpeed { get;}

        /// <summary>
        /// 获得坦克后退的极限速度
        /// </summary>
        float MaxBackwardSpeed { get;}

        /// <summary>
        /// 获得坦克的极限旋转速度
        /// </summary>
        float MaxRotaSpeed { get;}

        /// <summary>
        /// 获得坦克当前的前进速度，如果值为负，表示坦克正在后退
        /// </summary>
        float ForwardSpeed { get; set;}

        /// <summary>
        /// 获得坦克当前的旋转角速度。弧度单位，顺时针旋转为正。
        /// </summary>
        float TurnRightSpeed { get; set;}

        /// <summary>
        /// 获得坦克雷达的半径
        /// </summary>
        float RaderRadius { get;}

        /// <summary>
        /// 获得坦克张角的一半
        /// </summary>
        float RaderAng { get;}

        /// <summary>
        /// 获得坦克雷达当前相对于坦克的方向
        /// </summary>
        float RaderAzi { get;}

        /// <summary>
        /// 获得坦克雷达当前的方位角
        /// </summary>
        float RaderAimAzi { get;}

        /// <summary>
        /// 获得坦克雷达的旋转极限速度
        /// </summary>
        float MaxRotaRaderSpeed { get;}

        /// <summary>
        /// 获得当前坦克雷达的旋转速度，顺时针方向为正
        /// </summary>
        float TurnRaderWiseSpeed { get; set;}

        /// <summary>
        /// 获得该坦克发出炮弹的速度
        /// </summary>
        float ShellSpeed { get;}

        /// <summary>
        /// 获得坦克的宽度
        /// </summary>
        float TankWidth { get;}

        /// <summary>
        /// 获得坦克的长度
        /// </summary>
        float TankLength { get;}

        /// <summary>
        /// 获得当前坦克可见的有边界的物体
        /// </summary>
        EyeableBorderObjInfo[] EyeableBorderObjInfos { get;}

        /// <summary>
        /// 计算导航图
        /// </summary>
        /// <param name="selectFun">定义在生成导航图的时候考虑哪些有边界物体的函数</param>
        /// <param name="mapBorder">地图的边界</param>
        /// <param name="spaceForTank">离碰撞物的边界多远的距离上标记警戒线</param>
        /// <returns></returns>
        NavigateMap CalNavigateMap ( NaviMapConsiderObj selectFun, Rectanglef mapBorder, float spaceForTank );

        /// <summary>
        /// 当坦克发生碰撞时
        /// </summary>
        event OnCollidedEventHandlerAI OnCollide;

        /// <summary>
        /// 当坦克发生重叠时
        /// </summary>
        event OnCollidedEventHandlerAI OnOverLap;
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using TankEngine2D.Helpers;
using System.IO;

namespace SmartTank.Helpers.DependInject
{

    public static class DIHelper
    {

        /// <summary>
        /// 使用Assembly>.LoadFile函数获取程序集。
        /// </summary>
        /// <param name="assetFullName"></param>
        /// <returns></returns>
        static public Assembly GetAssembly ( string assetPath )
        {
            Assembly assembly = null;

            try
            {
                assembly = Assembly.LoadFile( Path.Combine( System.Environment.CurrentDirectory, assetPath ) );
            }
            catch (Exception)
            {
                Log.Write( "Load Assembly error : " + assetPath + " load unsucceed!" );
                return null;
            }

            return assembly;
        }

        static public object GetInstance ( Type type )
        {
            return Activator.CreateInstance( type );
        }

        internal static Type GetType(string typepath)
        {
            string[] path = typepath.Split('.');
            if (path[0] == "SmartTank")
            {
                Assembly assembly = Assembly.Load("SmartTank, Version=1.0.0.0, Culture=neutral, PublicKeyToToken=null");
                return assembly.GetType(typepath);
            }
            if (path[0] == "InterRules")
            {
                Assembly assembly = Assembly.Load("InterRules, Version=1.0.0.0, Culture=neutral, PublicKeyToToken=null");
                return assembly.GetType(typepath);
            }
            return null;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Graphics;
using SmartTank.Draw;
using SmartTank.PhiCol;
using Microsoft.Xna.Framework;
using SmartTank.AI;
using TankEngine2D.DataStructure;

namespace SmartTank.GameObjs.Tank
{
    public abstract class Tank : IGameObj, ICollideObj, IPhisicalObj
    {
        #region EventHandlers

        /*
         * 坦克类将设计场景交互方面的事件交给游戏规则类来处理。
         * 
         * 这样能消除坦克类和具体游戏规则的耦合，提高坦克类的重用性。
         * 
         * 更多的事件有待添加。
         * 
         * */

        public delegate void ShootEventHandler( Tank sender, Vector2 turretEnd, float azi );

        #endregion

        #region Variables

        protected string name;

        protected GameObjInfo objInfo;

        //protected ITankSkin skin;

        protected IColChecker colChecker;

        protected IPhisicalUpdater phisicalUpdater;

        protected IAI tankAI;

        protected bool isDead;

        #endregion

        #region Properties

        public bool IsDead
        {
            get { return isDead; }
        }
        #endregion

        #region IGameObj 成员

        public virtual GameObjInfo ObjInfo
        {
            get { return objInfo; }
        }

        public abstract Vector2 Pos { get;set;}

        public abstract float Azi { get;set;}

        #endregion

        #region IUpdater 成员

        public virtual void Update( float seconds )
        {
            if (!isDead && tankAI != null)
                tankAI.Update( seconds );
        }

        #endregion

        #region IDrawable 成员

        public virtual void Draw()
        {
            tankAI.Draw();
        }

        #endregion

        #region ICollideObj 成员


        public IColChecker ColChecker
        {
            get { return colChecker; }
        }

        #endregion

        #region IPhisicalObj 成员

        public IPhisicalUpdater PhisicalUpdater
        {
            get { return phisicalUpdater; }
        }

        #endregion

        #region SetTankAI

        public void SetTankAI( IAI tankAI )
        {
            if (tankAI == null)
                throw new NullReferenceException( "tankAI is null!" );
            this.tankAI = tankAI;
        }

        #endregion

        #region Dead

        public virtual void Dead()
        {
            isDead = true;
        }

        #endregion

        #region IHasBorderObj 成员

        public abstract CircleList<BorderPoint> BorderData
        {
            get;
        }


        public abstract Matrix WorldTrans
        {
            get;
        }

        public abstract Rectanglef BoundingBox
        {
            get;
        }

        #endregion



        #region IGameObj 成员

        public string Name
        {
            get { return name; }
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.Draw;
using Microsoft.Xna.Framework.Graphics;
using System.IO;
using SmartTank.Shelter;
using SmartTank.AI;
using SmartTank.Senses.Vision;
using TankEngine2D.DataStructure;
using TankEngine2D.Graphics;
using SmartTank.Senses.Memory;
using TankEngine2D.Helpers;
using SmartTank.Helpers;
using SmartTank.net;

namespace SmartTank.GameObjs.Tank.SinTur
{
    public class TankSinTur : Tank, IRaderOwner, IAIOrderServerSinTur, IEyeableObj
    {
        #region Statics

        static public string M1A2TexPath = Path.Combine(Directories.GameObjsDirectory, "Internal\\M1A2");
        static public GameObjData M1A2Data = GameObjData.Load(File.OpenRead(Path.Combine(M1A2TexPath, "M1A2.xml")));

        static public string M60TexPath = Path.Combine(Directories.GameObjsDirectory, "Internal\\M60");
        static public GameObjData M60Data = GameObjData.Load(File.OpenRead(Path.Combine(M60TexPath, "M60.xml")));

        static public string TigerTexPath = Path.Combine(Directories.GameObjsDirectory, "Internal\\Tiger");
        static public GameObjData TigerData = GameObjData.Load(File.OpenRead(Path.Combine(TigerTexPath, "Tiger.xml")));

        #endregion

        #region Events

        public event ShootEventHandler onShoot;

        public event OnCollidedEventHandler onCollide;

        public event OnCollidedEventHandler onOverLap;

        public event BorderObjUpdatedEventHandler onBorderObjUpdated;

        #endregion

        #region Variables

        TankContrSinTur controller;

        TankSkinSinTur skin;

        Rader rader;

        float shellSpeed;

        #endregion

        #region Properties

        public float FireCDTime
        {
            get { return controller.fireCDTime; }
            set
            {
                controller.fireCDTime = Math.Max(0, value);
            }
        }

        public override Vector2 Pos
        {
            get { return controller.Pos; }
            set { controller.Pos = value; }
        }

        public Vector2 TurretAxePos
        {
            get { return skin.Sprites[1].Pos; }
        }

        public override float Azi
        {
            get { return controller.Azi; }
            set { controller.Azi = value; }
        }

        public Vector2 Direction
        {
            get { return MathTools.NormalVectorFromAzi(Azi); }
        }

        public float TurretAimAzi
        {
            get { return controller.Azi + controller.turretAzi; }
        }

        public float TurretAzi
        {
            get { return controller.turretAzi; }
            set { controller.turretAzi = value; }
        }

        public float RaderRadius
        {
            get
            {
                return rader.R;
            }
        }

        public float RaderAng
        {
            get
            {
                return rader.Ang;
            }
        }

        public float RaderAzi
        {
            get { return controller.raderAzi; }
            set { controller.raderAzi = value; }
        }

        public float RaderAimAzi
        {
            get { return controller.Azi + controller.raderAzi; }
        }

        public float MaxForwardSpeed
        {
            get { return controller.limit.MaxForwardSpeed; }
        }

        public float MaxBackwardSpeed
        {
            get { return controller.limit.MaxBackwardSpeed; }
        }

        public float MaxRotaSpeed
        {
            get { return controller.limit.MaxTurnAngleSpeed; }
        }

        public float MaxRotaTurretSpeed
        {
            get { return controller.limit.MaxTurretAngleSpeed; }
        }

        public float MaxRotaRaderSpeed
        {
            get { return controller.limit.MaxRaderAngleSpeed; }
        }

        public float ShellSpeed
        {
            get { return shellSpeed; }
            set { shellSpeed = value; }
        }

        public float TurretLength
        {
            get { return skin.TurretLength; }
        }

        public override CircleList<BorderPoint> BorderData
        {
            get { return skin.Sprites[0].BorderData; }
        }

        public override Matrix WorldTrans
        {
            get { return skin.Sprites[0].Transform; }
        }

        public override Rectanglef BoundingBox
        {
            get { return skin.Sprites[0].BoundRect; }
        }

        #endregion

        #region Consturction

        public TankSinTur(string name, GameObjInfo objInfo, string texPath, GameObjData skinData,
            float raderLength, float raderAng, Color raderColor,
            float maxForwardSpeed, float maxBackwardSpeed, float maxRotaSpeed,
            float maxTurretRotaSpeed, float maxRaderRotaSpeed, float fireCDTime,
            Vector2 pos, float baseAzi)
            : this(name, objInfo, texPath, skinData,
            raderLength, raderAng, raderColor, 0, maxForwardSpeed, maxBackwardSpeed, maxRotaSpeed, maxTurretRotaSpeed,
            maxRaderRotaSpeed, fireCDTime, pos, 0, 0)
        {
        }

        public TankSinTur(string name, GameObjInfo objInfo, string texPath, GameObjData skinData,
            float raderLength, float raderAng, Color raderColor, float raderAzi,
            float maxForwardSpeed, float maxBackwardSpeed, float maxRotaSpeed,
            float maxTurretRotaSpeed, float maxRaderRotaSpeed, float fireCDTime,
            Vector2 pos, float baseRota, float turretRota)
        {
            this.name = name;
            this.objInfo = objInfo;
            this.skin = new TankSkinSinTur(new TankSkinSinTurData(texPath, skinData));
            skin.Initial(pos, baseRota, turretRota);
            controller = new TankContrSinTur(objInfo, new Sprite[] { skin.Sprites[0] } , pos, baseRota, maxForwardSpeed, maxBackwardSpeed, maxRotaSpeed, maxTurretRotaSpeed, maxRaderRotaSpeed, Math.Max(0, fireCDTime));
            colChecker = controller;
            phisicalUpdater = controller;
            controller.onShoot += new EventHandler(controller_onShoot);
            controller.OnCollied += new OnCollidedEventHandler(controller_OnCollied);
            controller.OnOverlap += new OnCollidedEventHandler(controller_OnOverlap);
            controller.posAziChanged += new SmartTank.PhiCol.NonInertiasPhiUpdater.PosAziChangedEventHandler(controller_OnPosAziChanged);
            rader = new Rader(raderAng, raderLength, pos, raderAzi + baseRota, raderColor);
        }

        private void controller_OnPosAziChanged()
        {
            SyncCasheWriter.SubmitNewStatus(this.MgPath, "Pos", SyncImportant.MidFrequency, this.Pos);
            SyncCasheWriter.SubmitNewStatus(this.MgPath, "Azi", SyncImportant.MidFrequency, this.Azi);
        }

        #endregion

        #region Update

        public override void Update(float seconds)
        {
            base.Update(seconds);
            controller.Update(seconds);
            skin.Update(seconds);

            SyncCasheWriter.SubmitNewStatus(this.MgPath, "TurnTurretWiseSpeed", SyncImportant.MidFrequency, this.TurnTurretWiseSpeed);
            SyncCasheWriter.SubmitNewStatus(this.MgPath, "TurnRaderWiseSpeed", SyncImportant.MidFrequency, this.TurnRaderWiseSpeed);
            SyncCasheWriter.SubmitNewStatus(this.MgPath, "TurretAzi", SyncImportant.MidFrequency, this.TurretAzi);
            SyncCasheWriter.SubmitNewStatus(this.MgPath, "RaderAzi", SyncImportant.MidFrequency, this.RaderAzi);
        }


        #endregion

        #region Dead
        public override void Dead()
        {
            base.Dead();
            controller.Enable = false;
        }
        #endregion

        #region Draw

        public override void Draw()
        {
            skin.ResetSprites(controller.Pos, controller.Azi, controller.turretAzi);
            skin.Draw();

            if (!isDead)
            {
                rader.Pos = Pos;
                rader.Azi = controller.raderAzi + controller.Azi;
                rader.Draw();
            }

            base.Draw();
        }

        #endregion

        #region EventHandler

        void controller_onShoot(object sender, EventArgs e)
        {
            if (onShoot != null)
                InfoRePath.CallEvent(this.MgPath, "onShoot", onShoot, this, skin.GetTurretEndPos(controller.Pos, controller.Azi, controller.turretAzi), controller.Azi + controller.turretAzi);

            skin.BeginRecoil();
        }

        /// <summary>
        /// 为了让远端的事件传递过来，必须添加 “Call”+ 事件名的函数
        /// 将来最好用元数据机制实现
        /// </summary>
        /// <param name="args"></param>
        public void CallonShoot(Tank tank, Vector2 turretEnd, float azi)
        {
            if (onShoot != null)
                onShoot(tank, turretEnd, azi);
        }

        void controller_OnOverlap(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (onOverLap != null)
                //onOverLap(this, result, objB);
                InfoRePath.CallEvent(this.MgPath, "onOverLap", onOverLap, this, result, objB);

            if (OnOverLap != null)
                //OnOverLap(result, objB);
                InfoRePath.CallEvent(this.MgPath, "OnOverLap", OnOverLap,  result, objB);
        }

        void controller_OnCollied(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (onCollide != null)
                //onCollide(this, result, objB);
                InfoRePath.CallEvent(this.MgPath, "onCollide", onCollide,  this, result, objB);

            if (OnCollide != null)
                //OnCollide(result, objB);
                InfoRePath.CallEvent(this.MgPath, "OnCollide", OnCollide, result, objB);
        }

        #endregion

        #region IRaderOwner 成员

        public Rader Rader
        {
            get { return rader; }
        }

        public List<IEyeableInfo> CurEyeableObjs
        {
            set
            {
                rader.CurEyeableObjs = value;
            }
        }

        public void BorderObjUpdated(EyeableBorderObjInfo[] borderObjInfo)
        {
            if (onBorderObjUpdated != null)
                onBorderObjUpdated(borderObjInfo);
        }

        #endregion

        #region IAIOrderServerSinTur 成员

        public List<IEyeableInfo> GetEyeableInfo()
        {
            return rader.CurEyeableObjs;
        }

        public float ForwardSpeed
        {
            get
            {
                return controller.ForwardSpeed;
            }
            set
            {
                controller.ForwardSpeed = value;
                SyncCasheWriter.SubmitNewStatus(this.MgPath, "ForwardSpeed", SyncImportant.MidFrequency, value);
            }
        }

        public float TurnRightSpeed
        {
            get
            {
                return controller.TurnRightSpeed;
            }
            set
            {
                controller.TurnRightSpeed = value;
                SyncCasheWriter.SubmitNewStatus(this.MgPath, "TurnRightSpeed", SyncImportant.MidFrequency, value);
            }
        }

        public float TurnTurretWiseSpeed
        {
            get
            {
                return controller.TurnTurretWiseSpeed;
            }
            set
            {
                controller.TurnTurretWiseSpeed = value;
                SyncCasheWriter.SubmitNewStatus(this.MgPath, "TurnTurretWiseSpeed", SyncImportant.MidFrequency, value);
            }
        }

        public float FireLeftCDTime
        {
            get { return controller.FireLeftCDTime; }
        }

        public float TurnRaderWiseSpeed
        {
            get
            {
                return controller.TurnRaderWiseSpeed;
            }
            set
            {
                controller.TurnRaderWiseSpeed = value;
                SyncCasheWriter.SubmitNewStatus(this.MgPath, "TurnRaderWiseSpeed", SyncImportant.MidFrequency, value);
            }
        }

        public void Fire()
        {
            controller.Fire();
        }

        public float TankWidth
        {
            get { return skin.TankWidth; }
        }

        public float TankLength
        {
            get { return skin.TankLength; }
        }

        public event OnCollidedEventHandlerAI OnCollide;

        public event OnCollidedEventHandlerAI OnOverLap;

        public EyeableBorderObjInfo[] EyeableBorderObjInfos
        {
            get { return rader.ObjMemoryKeeper.GetEyeableBorderObjInfos(); }
        }

        public NavigateMap CalNavigateMap(NaviMapConsiderObj selectFun, Rectanglef mapBorder, float spaceForTank)
        {
            return rader.ObjMemoryKeeper.CalNavigationMap(selectFun, mapBorder, spaceForTank);
        }

        #endregion

        #region IEyeableObj 成员

        static public IEyeableInfo GetCommonEyeInfoFun(IRaderOwner raderOwner, IEyeableObj tank)
        {
            return new TankCommonEyeableInfo((TankSinTur)tank);
        }

        public class TankCommonEyeableInfo : IEyeableInfo
        {
            EyeableInfo eyeableInfo;

            Vector2 vel;
            float azi;
            Vector2 direction;
            float turretAimAzi;

            public Vector2 Pos
            {
                get { return eyeableInfo.Pos; }
            }

            public Vector2 Vel
            {
                get { return vel; }
            }

            public float Azi
            {
                get { return azi; }
            }

            public Vector2 Direction
            {
                get { return direction; }
            }

            public float TurretAimAzi
            {
                get { return turretAimAzi; }
            }

            public TankCommonEyeableInfo(TankSinTur tank)
            {
                this.eyeableInfo = new EyeableInfo(tank);

                this.azi = tank.Azi;
                this.vel = tank.Direction * tank.ForwardSpeed;
                this.direction = tank.Direction;
                this.turretAimAzi = tank.TurretAimAzi;
            }

            #region IEyeableInfo 成员

            public GameObjInfo ObjInfo
            {
                get { return eyeableInfo.ObjInfo; }
            }

            public Vector2[] CurKeyPoints
            {
                get { return eyeableInfo.CurKeyPoints; }
            }

            public Matrix CurTransMatrix
            {
                get { return eyeableInfo.CurTransMatrix; }
            }

            #endregion
        }

        public Vector2[] KeyPoints
        {
            get { return skin.VisiKeyPoints; }
        }

        public Matrix TransMatrix
        {
            get { return skin.Sprites[0].Transform; }
        }

        GetEyeableInfoHandler getEyeableInfoHandler;

        public GetEyeableInfoHandler GetEyeableInfoHandler
        {
            get
            {
                return getEyeableInfoHandler;
            }
            set
            {
                getEyeableInfoHandler = value;
            }
        }

        #endregion




    }
}
<file_sep>//=================================================
// xWinForms
// Copyright ?2007 by <NAME>
// http://psycad007.spaces.live.com/
//=================================================
// edit by wufei_spring
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Common.Helpers;
using System.IO;
using GameEngine.Graphics;
using GameEngine.Draw;


namespace GameEngine.UI
{
    public class Combo : Control
    {
        #region Variables
        public List<string> Items;
        public int width;

        Texture2D[] listboxParts;
        Rectangle listboxRect;

        Texture2D listBackground;
        Texture2D selectionArea;

        Color color = Color.White;
        Color textColor = Color.Black;
        Color listColor = Color.Snow;

        Button listBoxButton;

        int charHeight = 15;

        State state = State.Closed;
        public enum State
        {
            Opened,
            Closed
        }

        MouseState ms;


        public event EventHandler OnChangeSelection;
        private void Combo_onChangeSelection ( Object obj, EventArgs e ) { Close(); }

        public int currentIndex = -1;

        #endregion

        #region Construction
        public Combo ( string name, Vector2 position, int width )//, Font font, Form.Style style)
        {
            this.Type = ControlType.Combo;
            this.width = width;
            this.position = position;
            this.name = name;
            //this.font = font;
            //this.style = style;
            Init();//this.style);

            OnChangeSelection += new EventHandler( Combo_onChangeSelection );

            Items = new List<string>();
        }

        #endregion

        #region Initial
        private void Init ()
        {
            listboxParts = new Texture2D[4];
            listboxParts[0] = BaseGame.ContentMgr.Load<Texture2D>( Path.Combine( Directories.UIContent, "textbox_left" ) );
            listboxParts[1] = BaseGame.ContentMgr.Load<Texture2D>( Path.Combine( Directories.UIContent, "textbox_middle" ) );
            listboxParts[2] = BaseGame.ContentMgr.Load<Texture2D>( Path.Combine( Directories.UIContent, "textbox_right" ) );
            listboxRect = new Rectangle( 0, 0, (width - listboxParts[0].Width) - listboxParts[1].Width, listboxParts[0].Height );

            listBoxButton = new Button( "bt_Combo", "combo_button", position + new Vector2( listboxParts[0].Width + listboxParts[1].Width + listboxParts[2].Width, 0f ), Color.White );
            listBoxButton.OnMousePress += new EventHandler( listBoxButton_onMousePress );
        }
        #endregion

        #region Items Methods
        public void AddItem ( string item )
        {
            Items.Add( item );
            if (Items.Count == 1)
                selectedItem = Items[0];
        }

        public void RemoveItem ( string item )
        {
            Items.Remove( item );
        }

        public void RemoveItem ( int index )
        {
            Items.RemoveAt( index );
        }

        public void Sort ()
        {
            Items.Sort();
        }

        public void Clear ()
        {
            Items.Clear();
        }

        public bool Contains ( string item )
        {
            return Items.Contains( item );
        }

        private void SelectItem ( int index )
        {
            if (currentIndex == index)
                return;

            currentIndex = index;
            selectedItem = Items[index];
            OnChangeSelection( this, EventArgs.Empty );
        }
        #endregion

        #region Create Textures
        public void CreateTextures ()
        {
            int listHeight = Items.Count * charHeight + 8;
            listBackground = new Texture2D( BaseGame.Device, listboxParts[0].Width + listboxRect.Width + listboxParts[2].Width, listHeight, 1, Control.resourceUsage, SurfaceFormat.Color );

            Color[] pixels = new Color[listBackground.Width * listBackground.Height];
            for (int y = 0; y < listBackground.Height; y++)
            {
                for (int x = 0; x < listBackground.Width; x++)
                {
                    if (x < 3 || y < 3 || x > listBackground.Width - 3 || y > listBackground.Height - 3)
                    {
                        if (x == 0 || y == 0 || x == listBackground.Width - 1 || y == listBackground.Height - 1)
                            pixels[x + y * listBackground.Width] = Color.Black;
                        if (x == 1 || y == 1 || x == listBackground.Width - 2 || y == listBackground.Height - 2)
                            pixels[x + y * listBackground.Width] = Color.LightGray;
                        if (x == 2 || y == 2 || x == listBackground.Width - 3 || y == listBackground.Height - 3)
                            pixels[x + y * listBackground.Width] = Color.Gray;
                    }
                    else
                    {
                        float cX = listColor.ToVector3().X;
                        float cY = listColor.ToVector3().Y;
                        float cZ = listColor.ToVector3().Z;

                        cX *= 1.0f - ((float)y / (float)listBackground.Height) * 0.4f;
                        cY *= 1.0f - ((float)y / (float)listBackground.Height) * 0.4f;
                        cZ *= 1.0f - ((float)y / (float)listBackground.Height) * 0.4f;

                        pixels[x + y * listBackground.Width] = new Color( new Vector4( cX, cY, cZ, listColor.ToVector4().W ) );
                    }

                    float currentX = pixels[x + y * listBackground.Width].ToVector3().X;
                    float currentY = pixels[x + y * listBackground.Width].ToVector3().Y;
                    float currentZ = pixels[x + y * listBackground.Width].ToVector3().Z;

                    pixels[x + y * listBackground.Width] = new Color( new Vector4( currentX, currentY, currentZ, 0.85f ) );
                }
            }

            listBackground.SetData<Color>( pixels );

            selectionArea = new Texture2D( BaseGame.Device, listBackground.Width - 8, charHeight, 1, Control.resourceUsage, SurfaceFormat.Color );
            pixels = new Color[selectionArea.Width * selectionArea.Height];
            for (int y = 0; y < selectionArea.Height; y++)
            {
                for (int x = 0; x < selectionArea.Width; x++)
                {
                    pixels[x + y * selectionArea.Width] = new Color( new Vector4( 0f, 0f, 0f, 0.3f ) );
                }
            }

            selectionArea.SetData<Color>( pixels );
        }
        #endregion

        #region Update
        private void listBoxButton_onMousePress ( Object obj, EventArgs e )
        {
            //Console.WriteLine("listBoxButton_OnMousePress");
            if (state == State.Closed)
                Open();
            else if (state == State.Opened)
                Close();
        }

        public void Open ()
        {
            CreateTextures();
            state = State.Opened;
        }

        public void Close ()
        {
            state = State.Closed;
        }

        public override void Update ()// Vector2 formPosition, Vector2 formSize )
        {
            if (selectedItem == string.Empty && Items.Count > 0)
                selectedItem = Items[0];

            //position = formPosition + origin;
            listboxRect.X = (int)position.X + listboxParts[0].Width;
            listboxRect.Y = (int)position.Y;

            listBoxButton.MoveTo( position + new Vector2( listboxParts[0].Width + listboxRect.Width + listboxParts[2].Width, 0f ) );

            listBoxButton.Update();

            //CheckVisibility( formPosition, formSize );

            if (state == State.Opened)//&& !Form.isInUse)
                CheckSelection();
        }

        //private void CheckVisibility ( Vector2 formPosition, Vector2 formSize )
        //{
        //    if (position.X + listboxRect.Width + listboxParts[2].Width + listBoxButton.size.X > formPosition.X + formSize.X - 15f)
        //        bVisible = false;
        //    else if (position.Y + listboxParts[1].Height > formPosition.Y + formSize.Y - 25f)
        //        bVisible = false;
        //    else
        //        bVisible = true;
        //}

        private void CheckSelection ()
        {
            ms = Mouse.GetState();

            if (ms.LeftButton == ButtonState.Pressed)
            {
                for (int i = 0; i < Items.Count; i++)
                {
                    if (bIsOverItem( i ))
                        SelectItem( i );
                }
            }
        }

        private bool bIsOverItem ( int i )
        {
            Vector2 itemPosition = position + new Vector2( 4f, listboxParts[0].Height + 4f );

            if (ms.X > itemPosition.X && ms.X < itemPosition.X + listBackground.Width - 8f)
            {
                if (ms.Y > itemPosition.Y + (charHeight * i) && ms.Y < itemPosition.Y + +(charHeight * (i + 1)))
                {
                    return true;
                }
                else
                    return false;
            }
            else
                return false;
        }

        #endregion

        #region Draw
        public override void Draw ( SpriteBatch spriteBatch, float alpha )
        {
            //Text Area
            Color dynamicColor = new Color( new Vector4( color.ToVector3(), alpha ) );
            spriteBatch.Draw( listboxParts[0], position, null, dynamicColor, 0, Vector2.Zero, 1f, SpriteEffects.None, LayerDepth.UI );
            spriteBatch.Draw( listboxParts[1], listboxRect, null, dynamicColor, 0, Vector2.Zero, SpriteEffects.None, LayerDepth.UI );
            spriteBatch.Draw( listboxParts[2], position + new Vector2( listboxParts[0].Width + listboxRect.Width, 0f ), dynamicColor );
            listBoxButton.Draw( spriteBatch, alpha );

            //Text
            Color dynamicTextColor = new Color( new Vector4( textColor.ToVector3(), alpha ) );
            BaseGame.FontMgr.DrawInScrnCoord( selectedItem, position + new Vector2( 5f, 2f ), Control.fontScale, dynamicTextColor, LayerDepth.Text, Control.fontName );

            //Listbox
            if (state == State.Opened)
            {
                Vector2 listPosition = position + new Vector2( 0f, listboxParts[0].Height );

                //Background
                Color dynamicListboxColor = new Color( new Vector4( listColor.ToVector3(), alpha ) );
                spriteBatch.Draw( listBackground, listPosition, null, dynamicListboxColor, 0, Vector2.Zero, 1, SpriteEffects.None, LayerDepth.UI );

                //Items
                for (int i = 0; i < Items.Count; i++)
                {
                    BaseGame.FontMgr.DrawInScrnCoord( Items[i], listPosition + new Vector2( 4f, 4f ) + new Vector2( 0f, charHeight * i ), Control.fontScale, dynamicTextColor, LayerDepth.Text, Control.fontName );

                    //Selection Area
                    if (ms.LeftButton == ButtonState.Released)
                    {
                        if (bIsOverItem( i ))
                        {
                            Color dynamicAreaColor = new Color( new Vector4( Vector3.One, alpha ) );
                            spriteBatch.Draw( selectionArea, listPosition + new Vector2( 4f, 4f ) + new Vector2( 0f, charHeight * i ), null, dynamicAreaColor, 0, Vector2.Zero, 1, SpriteEffects.None, LayerDepth.UI );
                        }
                    }
                }
            }

        }
        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.GameObjs.Shell;
using SmartTank.PhiCol;
using TankEngine2D.Helpers;
using SmartTank.GameObjs;
using Microsoft.Xna.Framework;
using TankEngine2D.Graphics;
using SmartTank.Helpers;
using SmartTank.net;

namespace InterRules.Starwar
{
    class WarShipShell : ShellNormal
    {
        public delegate void ShellOutDateEventHandler(WarShipShell sender, IGameObj shooter);
        public event ShellOutDateEventHandler OnOutDate;

        protected float liveTimer = -SpaceWarConfig.ShellLiveTime;

        public Vector2 Vel
        {
            get { return ((NonInertiasPhiUpdater)PhisicalUpdater).Vel; }
            set { ((NonInertiasPhiUpdater)PhisicalUpdater).Vel = value; }
        }

        public WarShipShell(string name, IGameObj firer, Vector2 startPos, float startAzi)
            : base(name, firer, startPos, startAzi, SpaceWarConfig.ShellSpeed, 
            Directories.ContentDirectory + "\\Rules\\SpaceWar\\image\\field_bullet_001.png", false, new Vector2(4, 4), 1f)
        {
            this.objInfo = new GameObjInfo("WarShipShell", "");
        }

        public override void Update(float seconds)
        {
            liveTimer += seconds;
            if (liveTimer > 0)
            {
                if (OnOutDate != null)
                    OnOutDate(this, Firer);
            }
            SyncCasheWriter.SubmitNewStatus(this.MgPath, "Pos", SyncImportant.HighFrequency, this.Pos);
            SyncCasheWriter.SubmitNewStatus(this.MgPath, "Vel", SyncImportant.HighFrequency, this.Vel);

        }



        internal void MirrorPath(CollisionResult result)
        {
            Vector2 curVel = ((NonInertiasPhiUpdater)this.PhisicalUpdater).Vel;
            float mirVecLength = Vector2.Dot(curVel, result.NormalVector);
            Vector2 horizVel = curVel - mirVecLength * result.NormalVector;
            Vector2 newVel = horizVel + Math.Abs(mirVecLength) * result.NormalVector;
            ((NonInertiasPhiUpdater)this.PhisicalUpdater).Vel = newVel;
            ((NonInertiasPhiUpdater)this.PhisicalUpdater).Azi = MathTools.AziFromRefPos(newVel);

        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Update;
using SmartTank.Draw;

namespace SmartTank.Effects.SceneEffects
{
    public interface IManagedEffect : IUpdater, IDrawableObj
    {
        bool IsEnd { get; }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.GameObjs;
using SmartTank.PhiCol;

namespace SmartTank.PhiCol
{
    public class NonInertiasPhiUpdater : IPhisicalUpdater
    {
        GameObjInfo objInfo;

        public Vector2 Vel;
        public Vector2 Pos;

        public float AngVel;
        public float Azi;

        protected Vector2 nextPos;
        protected float nextAzi;

        public NonInertiasPhiUpdater ( GameObjInfo objInfo )
        {
            this.objInfo = objInfo;
        }

        public NonInertiasPhiUpdater ( GameObjInfo objInfo, Vector2 pos, Vector2 vel, float azi, float angVel )
        {
            this.objInfo = objInfo;
            this.Pos = pos;
            this.Vel = vel;
            this.Azi = azi;
            this.AngVel = angVel;
            this.nextPos = pos;
            this.nextAzi = azi;
        }

        #region IPhisicalUpdater ³ΙΤ±

        public virtual void CalNextStatus ( float seconds )
        {
            nextPos = Pos + Vel * seconds;
            nextAzi = Azi + AngVel * seconds;
        }

        public virtual void Validated ()
        {
            Pos = nextPos;
            Azi = nextAzi;
        }

        public GameObjInfo ObjInfo
        {
            get { return objInfo; }
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.IO;
using TankEngine2D.Helpers;
using System.Xml.Serialization;
using Microsoft.Xna.Framework.Content;

namespace TankEngine2D.Graphics
{
    /// <summary>
    /// 提供字符的绘制功能。
    /// </summary>
    public class FontMgr
    {
        /// <summary>
        /// 表示字体的名称与导入路径
        /// </summary>
        public struct FontInfo
        {
            /// <summary>
            /// 字体的名称
            /// </summary>
            public string name;
            /// <summary>
            /// 导入路径
            /// </summary>
            public string path;
            /// <summary>
            /// 表示字体的名称与导入路径
            /// </summary>
            /// <param name="name">字体的名称</param>
            /// <param name="path">导入路径</param>
            public FontInfo ( string name, string path )
            {
                this.name = name;
                this.path = path;
            }
        }
        /// <summary>
        /// 表示字体的导入信息
        /// </summary>
        public class FontLoadInfo
        {
            /// <summary>
            /// 从文件中读取字体的导入信息
            /// </summary>
            /// <param name="filePath"></param>
            /// <returns></returns>
            static public FontLoadInfo Load ( string filePath )
            {
                try
                {
                    XmlSerializer serializer = new XmlSerializer( typeof( FontLoadInfo ) );
                    FileStream stream = File.Open( filePath, FileMode.Open );
                    return (FontLoadInfo)(serializer.Deserialize( stream ));
                }
                catch (Exception e)
                {
                    if (e is FileNotFoundException)
                    {
                        FontLoadInfo model = new FontLoadInfo();
                        model.ASCIIFontInfos.Add( new FontInfo( "fontName2", "fontAssetPath : 请填入XNA专用字体信息文件路径" ) );
                        model.UnitCodeFontInfos.Add( new FontInfo( "fontName1", "TrueTypeFontPath : 请填入TrueType字体文件路径" ) );
                        Save( filePath, model );
                        Log.Write( "没找到字体导入配置文件，自动生成配置文件模板" );
                    }

                    throw;
                }
            }
            /// <summary>
            /// 将字体的导入信息储存到文件中
            /// </summary>
            /// <param name="filePath"></param>
            /// <param name="info"></param>
            static public void Save ( string filePath, FontLoadInfo info )
            {
                try
                {
                    XmlSerializer serializer = new XmlSerializer( typeof( FontLoadInfo ) );
                    serializer.Serialize( File.Open( filePath, FileMode.Create ), info );
                }
                catch (Exception)
                {
                    throw;
                }
            }

            /// <summary>
            /// 字体默认大小（Scale = 1)时的磅值
            /// </summary>
            public float DefualtEmSize;
            /// <summary>
            /// TrueType字体文件的导入信息
            /// </summary>
            public List<FontInfo> UnitCodeFontInfos;
            /// <summary>
            /// XNA素材管道专用字体文件的导入信息
            /// </summary>
            public List<FontInfo> ASCIIFontInfos;

            /// <summary>
            /// 表示字体的导入信息
            /// </summary>
            public FontLoadInfo ()
            {
                this.UnitCodeFontInfos = new List<FontInfo>();
                this.ASCIIFontInfos = new List<FontInfo>();
                DefualtEmSize = fontDrawEmSize;
            }
        }

        const string configFilePath = "font.cfg";
        const float fontDrawEmSize = 20;


        #region Varibles

        RenderEngine engine;
        ChineseWriter chineseWriter;

        Dictionary<string, SpriteFont> fonts;

        #endregion

        /// <summary>
        /// 提供字符的绘制功能
        /// </summary>
        /// <param name="engine">渲染组件</param>
        /// <param name="contentMgr">素材管理者</param>
        public FontMgr ( RenderEngine engine, ContentManager contentMgr )
        {
            this.engine = engine;
            chineseWriter = new ChineseWriter( engine );
            fonts = new Dictionary<string, SpriteFont>();

            LoadFonts( contentMgr );
        }

        private void LoadFonts ( ContentManager contentMgr )
        {
            FontLoadInfo fontLoadInfo = FontLoadInfo.Load( configFilePath );
            chineseWriter.Intitial( fontLoadInfo );

            if (contentMgr == null)
                return;

            try
            {
                foreach (FontInfo info in fontLoadInfo.ASCIIFontInfos)
                {
                    fonts.Add( info.name, contentMgr.Load<SpriteFont>( info.path ) );
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 建立贴图并添加到缓冲中。
        /// 请在第一次绘制之前调用该函数，这样可以避免建立贴图的过程造成游戏的停滞
        /// </summary>
        /// <param name="text">要创建的字符串</param>
        /// <param name="fontName">字体</param>
        public void BuildTexture( string text, string fontName )
        {
            chineseWriter.BuildTexture( text, fontName );
        }

        #region Draw Functions

        /// <summary>
        /// 在逻辑坐标中绘制一段文字。
        /// 注意，如果文字内容中包含中文，必须选用中文字体
        /// </summary>
        /// <param name="text">文字内容</param>
        /// <param name="pos">文字起始处在逻辑坐标中的位置</param>
        /// <param name="scale">文字的大小</param>
        /// <param name="color">颜色</param>
        /// <param name="rota">顺时针旋转弧度</param>
        /// <param name="layerDepth">深度，0为最表层，1为最深层</param>
        /// <param name="fontName">字体</param>
        public void Draw ( string text, Vector2 pos, float scale, float rota, Color color, float layerDepth, string fontName )
        {
            DrawInScrnCoord( text, engine.CoordinMgr.ScreenPos( pos ), scale, rota - engine.CoordinMgr.Rota, color, layerDepth, fontName );
        }

        /// <summary>
        /// 在逻辑坐标中绘制一段文字。
        /// 注意，如果文字内容中包含中文，必须选用中文字体
        /// </summary>
        /// <param name="text">文字内容</param>
        /// <param name="pos">文字起始处在逻辑坐标中的位置</param>
        /// <param name="scale">文字的大小</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0为最表层，1为最深层</param>
        /// <param name="fontName">字体</param>
        public void Draw ( string text, Vector2 pos, float scale, Color color, float layerDepth, string fontName )
        {
            Draw( text, pos, scale, 0, color, layerDepth, fontName );
        }

        /// <summary>
        /// 在屏幕坐标中绘制一段文字
        /// 注意，如果文字内容中包含中文，必须选用中文字体
        /// </summary>
        /// <param name="text">文字内容</param>
        /// <param name="pos">文字起始处在屏幕坐标中的位置</param>
        /// <param name="scale">文字的大小</param>
        /// <param name="rota">旋转角</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0为最表层，1为最深层</param>
        /// <param name="fontName">字体</param>
        public void DrawInScrnCoord ( string text, Vector2 pos, float scale, float rota, Color color, float layerDepth, string fontName )
        {
            if (fonts.ContainsKey( fontName ))
            {
                try
                {
                    engine.SpriteMgr.alphaSprite.DrawString( fonts[fontName], text, pos, color, rota, Vector2.Zero, scale, SpriteEffects.None, layerDepth );
                }
                catch (Exception)
                {
                    Log.Write( "尝试使用非UnitCode字体绘制UnitCode字符:  " + text );
                }
            }
            else if (chineseWriter.HasFont( fontName ))
                chineseWriter.WriteText( text, pos, rota, scale, color, layerDepth, fontName );
            else
                Log.Write( "未找到指定的字体，请检查字体导入配置文件:  " + fontName );
        }

        /// <summary>
        /// 在屏幕坐标中绘制一段文字
        /// 注意，如果文字内容中包含中文，必须选用中文字体
        /// </summary>
        /// <param name="text">文字内容</param>
        /// <param name="pos">文字起始处在屏幕坐标中的位置</param>
        /// <param name="scale">文字的大小</param>
        /// <param name="color">颜色</param>
        /// <param name="layerDepth">深度，0为最表层，1为最深层</param>
        /// <param name="fontName">字体</param>
        public void DrawInScrnCoord ( string text, Vector2 pos, float scale, Color color, float layerDepth, string fontName )
        {
            DrawInScrnCoord( text, pos, scale, 0f, color, layerDepth, fontName );
        }

        #endregion

        #region LengthOfString

        /// <summary>
        /// 获取一段文字在屏幕坐标上的长度
        /// 注意，如果文字内容中包含中文，必须选用中文字体
        /// </summary>
        /// <param name="text">文字的内容</param>
        /// <param name="scale">文字的大小</param>
        /// <param name="fontName">字体</param>
        /// <returns></returns>
        public float LengthOfString ( string text, float scale, string fontName )
        {

            if (fonts.ContainsKey( fontName ))
            {
                try
                {
                    return fonts[fontName].MeasureString( text ).X * scale;
                }
                catch (Exception)
                {
                    Log.Write( "用不支持中文的字体获取包含中文字符的字符串的长度： " + text );
                    return -1;
                }
            }
            else if (chineseWriter.HasFont( fontName ))
                return chineseWriter.MeasureString( text, scale, fontName );
            else
            {
                Log.Write( "未找到指定的字体，请检查字体导入配置文件:  " + fontName );
                return -1;
            }

        }
        #endregion
    }

}

<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.Rule;
using SmartTank.Effects.SceneEffects;
using SmartTank.Screens;
using System.Threading;
using SmartTank.Scene;
using TankEngine2D.Input;

namespace SmartTank.net
{
    public class RuleSupNet : IGameScreen
    {
        SyncCashe inputCashe;
        SyncCashe outputCashe;

        protected SceneMgr sceneMgr;

        public RuleSupNet()
        {
            inputCashe = new SyncCashe();
            outputCashe = new SyncCashe();
            SyncCasheWriter.OutPutCashe = outputCashe;
            SyncCasheReader.InputCashe = inputCashe;

            //temp 
            PurviewMgr.IsMainHost = true;

            // SocketMgr 的管理交给UI控制
            //SocketMgr.Initial(); 
            SocketMgr.SetInputCahes(inputCashe);
            //SocketMgr.ConnectToServer();

            //SocketMgr.StartReceiveThread();

        }

        #region IGameScreen 成员

        public virtual bool Update(float second)
        {
            if (PurviewMgr.IsMainHost)
            {
                /* 1.更新场景物体
                 * 2.处理消息缓冲区
                 * 3.更新其他组件
                 * 4.广播同步消息
                 * */
                GameManager.UpdateMgr.Update(second);

                // 处理消息缓冲区
                SyncCasheReader.ReadCashe(sceneMgr);

                GameManager.UpdataComponent(second);

                // 广播同步消息
                outputCashe.SendPackage();
                SyncCasheWriter.Update(second);

            }
            else
            {
                /* 1.处理同步消息缓冲区
                 * 1.更新场景物体  其中会添加需要发送的同步消息
                 * 2.更新其他组件
                 * 3.发送同步消息
                 * */
                GameManager.UpdateMgr.Update(second);
                GameManager.UpdataComponent(second);
                // 处理消息缓冲区
                SyncCasheReader.ReadCashe(sceneMgr);
                // 发送同步消息
                outputCashe.SendPackage();
                SyncCasheWriter.Update(second);
            }

            return false;
        }

        public virtual void Render()
        {

        }

        public void OnClose()
        {
            //SocketMgr.Close();
            PurviewMgr.Close();
            
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace GameEngine.Draw
{
    static public class GameFonts
    {
        public static string Comic = "Comic";
        public static string Lucida = "Lucida";
        public static string HDZB = "HDZB";
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace MapEditor
{
    class ObjClassInfo
    {
        public readonly string className;
        public readonly string classRemark;
        public readonly Type classType;

        public ObjClassInfo ( string className, string classRemark, Type classType )
        {
            this.className = className;
            this.classRemark = classRemark;
            this.classType = classType;
        }
    }
}
<file_sep>//=================================================
// xWinForms
// Copyright ?2007 by <NAME>
// http://psycad007.spaces.live.com/
//=================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace GameEngine.UI
{
    public class ControlCollection
    {
        #region Properties
        public List<Control> controls;

        public Control this[string name]
        {
            get { return getElement( name ); }
        }
        public Control this[int index]
        {
            get { return controls[index]; }
        }

        public int Count
        {
            get { return controls.Count; }
        } 
        #endregion

        #region Construction
        public ControlCollection ()
        {
            controls = new List<Control>();
        } 
        #endregion

        #region Element Methods
        public void Add ( Control element ) { this.controls.Add( element ); }
        public void Remove ( Control element ) { this.controls.Remove( element ); }
        public Control getElement ( string name )
        {
            return this.controls.Find( delegate( Control returnElement ) { return returnElement.name == name; } );
        } 
        #endregion

        #region Update

        #region Old Code
        //public void Update ( Vector2 formPosition, Vector2 formSize )
        //{
        //    foreach (Control thisControl in controls)
        //    {
        //        if (thisControl != null)
        //            thisControl.Update( formPosition, formSize );
        //    }
        //} 
        #endregion

        public void Update ()
        {
            foreach (Control control in controls)
            {
                control.Update();
            }
        }

        #endregion

        #region Draw
        public void Draw ( SpriteBatch windowBatch, float alpha )
        {
            foreach (Control thisControl in controls)
            {
                if (thisControl != null && thisControl.bvisible)
                    thisControl.Draw( windowBatch, alpha );
            }
        }     
        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using GameEngine.PhiCol;
using GameEngine.Graphics;
using Microsoft.Xna.Framework;

namespace GameEngine.PhiCol
{
    public class NonInertiasColUpdater : NonInertiasPhiUpdater, IColChecker
    {
        Sprite[] collideSprites;
        SpriteColMethod colMethod;

        public NonInertiasColUpdater( Sprite[] collideSprites )
            : base()
        {
            this.collideSprites = collideSprites;
            colMethod = new SpriteColMethod( collideSprites );
        }

        public NonInertiasColUpdater( Vector2 pos, Vector2 vel, float azi, float angVel, Sprite[] collideSprites )
            : base(pos, vel, azi, angVel )
        {
            this.collideSprites = collideSprites;
            colMethod = new SpriteColMethod( collideSprites );
        }

        #region IColChecker ³ΙΤ±

        public virtual void HandleCollision( CollisionResult result,ICollideObj objA, ICollideObj objB )
        {
            Pos += result.NormalVector * BaseGame.CoordinMgr.LogicLength( 0.5f );

            if (OnCollied != null)
                OnCollied( result, objA, objB );
        }

        public virtual void HandleOverlap( CollisionResult result, ICollideObj objA, ICollideObj objB )
        {
            if (OnOverlap != null)
                OnOverlap( result, objA, objB );
        }

        public virtual void ClearNextStatus()
        {
            nextPos = Pos;
            nextAzi = Azi;
        }

        public IColMethod CollideMethod
        {
            get
            {
                foreach (Sprite sprite in collideSprites)
                {
                    sprite.Pos = nextPos;
                    sprite.Rata = nextAzi;
                }
                return colMethod;
            }
        }

        #endregion

        #region Event

        public event OnCollidedEventHandler OnCollied;

        public event OnCollidedEventHandler OnOverlap;

        #endregion




    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace GameObjEditor
{
    public partial class EnterYourName : Form
    {
        bool selectYes;

        public EnterYourName (string labelText)
        {
            InitializeComponent();
            label1.Text = labelText;
        }

        public string CreatorName
        {
            get { return textBox1.Text; }
        }

        public bool SelectYes
        {
            get { return selectYes; }
        }

        private void Enter_Click ( object sender, EventArgs e )
        {
            selectYes = true;
            this.Close();
        }

        private void Cancel_Click ( object sender, EventArgs e )
        {
            selectYes = false;
            this.Close();
        }


    }
}<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.GameObjs;
using SmartTank.PhiCol;

namespace SmartTank.PhiCol
{
    public class NonInertiasPhiUpdater : IPhisicalUpdater, ISyncable
    {
        public delegate void PosAziChangedEventHandler();
        public event PosAziChangedEventHandler posAziChanged;

        GameObjInfo objInfo;

        public Vector2 Vel;
        public Vector2 Pos;

        public float AngVel;
        public float Azi;

        protected Vector2 nextPos;
        protected float nextAzi;

        public Vector2 serPos;
        public Vector2 serVel;
        public float serAzi;
        public float serAziVel;

        protected Vector2 localPos;
        protected Vector2 localVel;
        protected float localAzi;
        protected float localAziVel;

        protected float syncTotolTime = 0;
        protected bool startSync = false;
        protected bool syncing = false;
        protected float syncCurTime = 0;
        protected float mount = 0;


        public NonInertiasPhiUpdater(GameObjInfo objInfo)
        {
            this.objInfo = objInfo;
        }

        public NonInertiasPhiUpdater(GameObjInfo objInfo, Vector2 pos, Vector2 vel, float azi, float angVel)
        {
            this.objInfo = objInfo;
            this.Pos = pos;
            this.Vel = vel;
            this.Azi = azi;
            this.AngVel = angVel;
            this.nextPos = pos;
            this.nextAzi = azi;
        }

        #region IPhisicalUpdater ³ΙΤ±

        public virtual void CalNextStatus(float seconds)
        {
            if (startSync)
            {
                syncCurTime = 0;
                localPos = Pos;
                localVel = Vel;
                localAzi = Azi;
                localAziVel = AngVel;
                mount = 0;
                startSync = false;
            }

            if (syncing)
            {
                syncCurTime += seconds;

                float tScale = syncCurTime / syncTotolTime;

                float V0 = localVel.Length();
                float V1 = serVel.Length();

                float M = (V0 + V1) * syncTotolTime / 2;
                if (M != 0)
                {
                    float curV = MathHelper.Lerp(V0, V1, tScale);
                    float w = (V0 + curV) * syncCurTime / 2;
                    float mount = w / M;
                    if (mount > 1)
                    {
                        int x = 0;
                    }
                    nextPos = Vector2.Hermite(localPos, localVel, serPos, serVel, mount);
                }
                else
                {
                    nextPos = (serPos - localPos) * tScale + localPos;
                }

                float MAzi = (localAziVel + serAziVel) * syncCurTime / 2;
                if (MAzi != 0)
                {
                    float curAziVel = MathHelper.Lerp(localAziVel, serAziVel, tScale);
                    float wAzi = (localAziVel + curAziVel) * syncCurTime / 2;
                    float mountAzi = wAzi / MAzi;
                    nextAzi = MathHelper.Hermite(localAzi, localAziVel, serAzi, serAziVel, mountAzi);
                }
                else
                {
                    nextAzi = MathHelper.Lerp(localAzi, serAziVel, tScale);
                }

                if (syncCurTime > syncTotolTime)
                {
                    syncing = false;
                    Vel = serVel;
                    AngVel = serAziVel;
                }
            }
            else
            {
                nextPos = Pos + Vel * seconds;
                nextAzi = Azi + AngVel * seconds;
            }
        }

        public virtual void Validated()
        {
            Pos = nextPos;
            Azi = nextAzi;
            if (posAziChanged != null)
                posAziChanged();
        }

        public GameObjInfo ObjInfo
        {
            get { return objInfo; }
        }

        #endregion

        #region ISyncable ³ΙΤ±

        public void SetServerStatue(Vector2 serPos, Vector2 serVel, float serAzi, float serAziVel, float syncTime, bool velChangeIme)
        {
            if (syncTime == 0)
                return;

            if (velChangeIme)
            {
                this.Vel = serVel;
                this.Pos = serPos;
            }
            this.serPos = serPos + serVel * syncTime;
            this.serVel = serVel;
            this.serAzi = serAzi + serAziVel * syncTime;
            this.serAziVel = serAziVel;
            this.syncTotolTime = syncTime;
            this.startSync = true;
            this.syncing = true;
        }

        #endregion

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.DataStructure;
using Microsoft.Xna.Framework;

namespace SmartTank.Draw.BackGround
{
    interface IBackGround
    {
        void Draw ();
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using GameEngine.Draw;


namespace GameEngine.Effects
{
    public interface IManagedEffect:IDrawableObj
    {
        bool IsEnd { get; }

        void Update( float seconds );
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.PhiCol;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework;
using TankEngine2D.Helpers;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.Scene;
using SmartTank.GameObjs;
using TankEngine2D.DataStructure;
using SmartTank.Helpers;
using SmartTank.Draw;
using SmartTank.net;

namespace SmartTank.GameObjs.Shell
{
    public class ShellNormal : IGameObj, ICollideObj, IPhisicalObj
    {
        public event OnCollidedEventHandler onCollided;
        public event OnCollidedEventHandler onOverlap;

        string name;

        protected GameObjInfo objInfo = new GameObjInfo("ShellNormal", string.Empty);

        IGameObj firer;

        Sprite sprite;

        NonInertiasColUpdater phiUpdater;

        public float Azi
        {
            get { return sprite.Rata; }
        }

        public IGameObj Firer
        {
            get { return firer; }
        }

        public ShellNormal(string name, IGameObj firer, Vector2 startPos, float startAzi, float speed, string texPath, bool fromContent, Vector2 texOrignPos, float texScale)
        {
            this.name = name;
            this.firer = firer;

            if (fromContent)
            {
                sprite = new Sprite(BaseGame.RenderEngine, BaseGame.ContentMgr, texPath, true);
            }
            else
            {
                sprite = new Sprite(BaseGame.RenderEngine, texPath, true);
            }
            sprite.SetParameters(texOrignPos, startPos, texScale, startAzi, Color.White, LayerDepth.Shell, SpriteBlendMode.AlphaBlend);
            phiUpdater = new NonInertiasColUpdater(ObjInfo, startPos, MathTools.NormalVectorFromAzi(startAzi) * speed, startAzi, 0f, new Sprite[] { sprite });
            phiUpdater.OnOverlap += new OnCollidedEventHandler(phiUpdater_OnOverlap);
            phiUpdater.OnCollied += new OnCollidedEventHandler(phiUpdater_OnCollied);
        }

        public ShellNormal(string name, IGameObj firer, Vector2 startPos, float startAzi, float speed)
            : this(name, firer, startPos, startAzi, speed, "GameObjs\\ShellNormal", true, new Vector2(5, 0), 0.08f)
        {
        }

        void phiUpdater_OnCollied(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (onCollided != null)
                //onCollided( this, result, objB );
                InfoRePath.CallEvent(this.MgPath, "onCollided", onCollided, this, result, objB);
        }

        void phiUpdater_OnOverlap(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (onOverlap != null)
                //onOverlap( this, result, objB );
                InfoRePath.CallEvent(this.MgPath, "onOverlap", onOverlap, this, result, objB);
        }


        #region IGameObj 成员

        public GameObjInfo ObjInfo
        {
            get { return objInfo; }
        }
        public Vector2 Pos
        {
            get { return phiUpdater.Pos; }
            set { phiUpdater.Pos = value; }
        }

        #endregion

        #region IUpdater 成员

        public virtual void Update(float seconds)
        {

        }

        #endregion

        #region IDrawable 成员

        public void Draw()
        {
            sprite.Pos = phiUpdater.Pos;
            sprite.Draw();
        }

        #endregion

        #region ICollideObj 成员


        public IColChecker ColChecker
        {
            get { return phiUpdater; }
        }

        #endregion

        #region IPhisicalObj 成员

        public IPhisicalUpdater PhisicalUpdater
        {
            get { return phiUpdater; }
        }

        #endregion

        #region IHasBorderObj 成员

        public CircleList<BorderPoint> BorderData
        {
            get { return sprite.BorderData; }
        }

        public Matrix WorldTrans
        {
            get { return sprite.Transform; }
        }

        public Rectanglef BoundingBox
        {
            get { return sprite.BoundRect; }
        }

        #endregion

        #region IGameObj 成员

        public string Name
        {
            get { return name; }
        }

        #endregion

        #region IGameObj 成员

        string mgPath;
        public string MgPath
        {
            get
            {
                return mgPath;
            }
            set
            {
                mgPath = value;
            }
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.net
{
    public enum SyncImportant
    {
        Immediate,
        HighFrequency,
        MidFrequency,
        LowFrequency,
    };

    public enum ObjMgKind
    {
        Create,
        Delete,
    }

    static public class SyncCasheWriter
    {
        const float highSpace = 0.05f;
        const float midSpace = 0.1f;
        const float lowSpace = 1.0f;

        static public SyncCashe outPutCashe;
        static public SyncCashe OutPutCashe
        {
            get { return outPutCashe; }
            set { outPutCashe = value; }
        }

        static private Dictionary<string, float> Timer = new Dictionary<string, float>();

        // 此函数由场景物体类调用，因此函数中要判断主从关系，发包频率
        static public void SubmitNewStatus(string objMgPath, string statueName, SyncImportant improtant, params object[] values)
        {

            if (improtant == SyncImportant.Immediate)
            {
                PushNewStatus(objMgPath, statueName, values);
            }
            else
            {
                string key = objMgPath + statueName;
                if (Timer.ContainsKey(key))
                {
                    float leftTime = Timer[key];
                    switch (improtant)
                    {
                        case SyncImportant.HighFrequency:
                            if (leftTime > 0)
                            {
                                PushNewStatus(objMgPath, statueName, values);
                                Timer[key] = -highSpace;
                            }
                            break;
                        case SyncImportant.MidFrequency:
                            if (leftTime > 0)
                            {
                                PushNewStatus(objMgPath, statueName, values);
                                Timer[key] = -midSpace;
                            }
                            break;
                        case SyncImportant.LowFrequency:
                            if (leftTime > 0)
                            {
                                PushNewStatus(objMgPath, statueName, values);
                                Timer[key] = -lowSpace;
                            }
                            break;
                        default:
                            break;
                    }
                }
                else
                {
                    switch (improtant)
                    {
                        case SyncImportant.HighFrequency:
                            Timer.Add(key, -highSpace);
                            break;
                        case SyncImportant.MidFrequency:
                            Timer.Add(key, -midSpace);
                            break;
                        case SyncImportant.LowFrequency:
                            Timer.Add(key, -lowSpace);
                            break;
                        default:
                            break;
                    }
                }
            }

        }

        static public void SubmitNewEvent(string objMgPath, string EventName, params object[] values)
        {
            if (!PurviewMgr.IsMainHost && PurviewMgr.IsSlaveMgObj(objMgPath))
            {
                outPutCashe.AddObjEventSyncInfo(objMgPath, EventName, values);
            }
        }

        static public void SubmitCreateObjMg(string objPath, Type objType, params object[] createParams)
        {
            if (PurviewMgr.IsMainHost)
            {
                outPutCashe.AddObjMgCreateSyncInfo(objPath, objType, createParams);
            }
        }

        static public void SubmitDeleteObjMg(string objPath)
        {
            if (PurviewMgr.IsMainHost)
            {
                outPutCashe.AddObjMgDeleteSyncInfo(objPath);
            }
        }

        static public void SubmitUserDefineInfo(string infoName, string infoID, params object[] args)
        {
            outPutCashe.AddUserDefineInfo(infoName, infoID, args);
        }

        static void PushNewStatus(string objMgPath, string statueName, object[] values)
        {
            outPutCashe.AddObjStatusSyncInfo(objMgPath, statueName, values);
        }

        static public void Update(float seconds)
        {
            string[] Keys = new string[Timer.Count];
            Timer.Keys.CopyTo(Keys, 0);
            for (int i = 0; i < Timer.Count; i++)
            {
                Timer[Keys[i]] += seconds;
            }
        }

    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using GameEngine.PhiCol;
using GameEngine.Shelter;
using Common.DataStructure;

namespace GameEngine.Senses.Memory
{
    public struct VisiBordPoint
    {
        public int index;
        public Point p;

        public VisiBordPoint ( int index, Point p )
        {
            this.index = index;
            this.p = p;
        }
    }

    public class ObjVisiBorder
    {
        IHasBorderObj obj;
        CircleList<VisiBordPoint> visiBorder;

        internal IHasBorderObj Obj
        {
            get { return obj; }
        }

        public CircleList<VisiBordPoint> VisiBorder
        {
            get { return visiBorder; }
        }


        public ObjVisiBorder ( IHasBorderObj obj, CircleList<VisiBordPoint> visiBorder )
        {
            this.obj = obj;
            this.visiBorder = visiBorder;
            this.visiBorder.LinkLastAndFirst();
        }

        //public ObjVisiBorder ( IGameObj obj )
        //{
        //    this.obj = obj;
        //    this.visiBorder = new CircleList<BordPoint>();
        //}

        internal bool Combine ( CircleList<VisiBordPoint> borderB )
        {
            CircleListNode<VisiBordPoint> curA = this.visiBorder.First;

            int iA = 0;
            bool borderUpdated = false;

            if (curA.value.index > borderB.First.value.index)
            {
                this.visiBorder.AddFirst( borderB.First.value );
                curA = this.visiBorder.First;
                borderUpdated = true;
            }

            bool objborderChanged = false;

            foreach (VisiBordPoint pB in borderB)
            {
                while (curA.value.index < pB.index && iA < this.visiBorder.Length)
                {
                    curA = curA.next;
                    iA++;
                }
                if (curA.value.index == pB.index)
                {
                    if (curA.value.p != pB.p)
                    {
                        objborderChanged = true;
                        break;
                    }
                }
                else
                {
                    borderUpdated = true;
                    this.visiBorder.InsertAfter( pB, curA.pre );
                    curA = curA.pre;
                }
            }

            if (objborderChanged)
            {
                this.visiBorder = borderB;
            }

            #region Check Code
            //CircleListNode<BordPoint> checkCur = this.visiBorder.First;

            //int lastIndex = -1;

            //for (int i = 0; i < this.visiBorder.Length; i++)
            //{
            //    if (checkCur.value.index <= lastIndex)
            //    {
            //        Console.WriteLine( "this.visiBorder :" );
            //        this.ShowInfo();
            //        Console.WriteLine();
            //        Console.WriteLine( "borderB :" );
            //        foreach (BordPoint p in borderB)
            //        {
            //            Console.WriteLine( p.index );
            //        }

            //        throw new Exception();
            //    }

            //    lastIndex = checkCur.value.index;
            //    checkCur = checkCur.next;
            //}
            #endregion

            return borderUpdated;
        }

        internal void ShowInfo ()
        {
            CircleListNode<VisiBordPoint> checkCur = this.visiBorder.First;
            for (int i = 0; i < this.visiBorder.Length; i++)
            {
                Console.WriteLine( checkCur.value.index );
                checkCur = checkCur.next;
            }
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Common.Helpers;

namespace Common.DataStructure
{
    /// <summary>
    /// 表示一条线段
    /// </summary>
    public struct Segment
    {
        /// <summary>
        /// 线段的起始端点
        /// </summary>
        public Vector2 startPoint;
        /// <summary>
        /// 线段的终止端点
        /// </summary>
        public Vector2 endPoint;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="startPoint">线段的起始端点</param>
        /// <param name="endPoint">线段的终止端点</param>
        public Segment ( Vector2 startPoint, Vector2 endPoint )
        {
            this.startPoint = startPoint;
            this.endPoint = endPoint;
        }

        /// <summary>
        /// 判断两Segmet实例是否相等，以重载
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals ( object obj )
        {
            Segment b = (Segment)obj;
            if (this.startPoint == b.startPoint && this.endPoint == b.endPoint ||
                this.startPoint == b.endPoint && this.endPoint == b.startPoint)
                return true;
            else
                return false;
        }

        /// <summary>
        /// 获得Hash值
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode ()
        {
            return startPoint.GetHashCode();
        }

        /// <summary>
        /// 将信息转换为字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString ()
        {
            return startPoint.ToString() + " " + endPoint.ToString();
        }

        /// <summary>
        /// 判断两条线段是否相交
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        static public bool IsCross ( Segment a, Segment b )
        {
            return Math.Max( a.startPoint.X, a.endPoint.X ) >= Math.Min( b.startPoint.X, b.endPoint.X ) &&
                   Math.Max( b.startPoint.X, b.endPoint.X ) >= Math.Min( a.startPoint.X, a.endPoint.X ) &&
                   Math.Max( a.startPoint.Y, a.endPoint.Y ) >= Math.Min( b.startPoint.Y, b.endPoint.Y ) &&
                   Math.Max( b.startPoint.Y, b.endPoint.Y ) >= Math.Min( a.startPoint.Y, a.endPoint.Y ) &&
                   MathTools.Vector2Cross( a.endPoint - b.startPoint, a.startPoint - a.endPoint ) *
                   MathTools.Vector2Cross( b.endPoint - a.endPoint, a.startPoint - b.endPoint ) > 0 &&
                   MathTools.Vector2Cross( b.endPoint - a.startPoint, b.startPoint - b.endPoint ) *
                   MathTools.Vector2Cross( a.endPoint - b.endPoint, b.startPoint - a.endPoint ) > 0;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using SmartTank.AI;
using SmartTank.AI.AIHelper;
using TankEngine2D.Input;
using TankEngine2D.Helpers;
using SmartTank;
using SmartTank.Senses.Memory;
using SmartTank.Scene;

namespace InterRules.FindPath
{
    /// <summary>
    /// 拥有一个很简陋的寻路逻辑的AI。
    /// </summary>
    [AIAttribute( "PathFinder No.1", "SmartTank编写组", "测试AI的寻路能力", 2007, 11, 21 )]
    class PathFinderFirst : IAISinTur
    {
        IAIOrderServerSinTur orderServer;

        AICommonServer commonServer;

        AIActionHelper action;

        #region IAI 成员

        public IAICommonServer CommonServer
        {
            set { commonServer = (AICommonServer)value; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = (IAIOrderServerSinTur)value;
                action = new AIActionHelper( orderServer );
            }
        }

        #endregion

        Vector2 aimPos;

        bool waitOrder = true;

        //float tempAzi;

        bool rotaing = false;

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            Vector2 curPos = orderServer.Pos;

            if (InputHandler.MouseJustPressRight)
            {
                aimPos = InputHandler.GetCurMousePosInLogic( BaseGame.RenderEngine );
                float aimAzi = MathTools.AziFromRefPos( aimPos - curPos );
                action.StopMove();
                action.StopRota();

                rotaing = true;
                action.AddOrder( new OrderRotaToAzi( aimAzi, 0,
                    delegate( IActionOrder order )
                    {
                        rotaing = false;
                        SearchPath();
                    }, false ) );

                waitOrder = false;
            }

            if (waitOrder)
                return;

            if (!rotaing)
                SearchPath();

            if (Vector2.Distance( curPos, aimPos ) < 1)
            {
                action.StopMove();
                action.StopRota();
                waitOrder = true;
            }


            action.Update( seconds );
        }

        private void SearchPath ()
        {
            Vector2 curPos = orderServer.Pos;
            float curAzi = MathTools.AngTransInPI( orderServer.Azi );
            float aimAzi = MathTools.AziFromRefPos( aimPos - curPos );

            bool aimObstruct = false;
            bool curObstruct = false;
            bool crossPi = false;
            bool crossZero = false;
            float minAziMinus = 0;
            float maxAziMinus = -MathHelper.Pi;
            float minAziPlus = MathHelper.Pi;
            float maxAziPlus = 0;

            foreach (EyeableBorderObjInfo borderObjInfo in orderServer.EyeableBorderObjInfos)
            {
                //if (!((SceneCommonObjInfo)borderObjInfo.EyeableInfo.ObjInfo.SceneInfo).isTankObstacle)
                //    continue;

                if (InputHandler.JustPressKey( Microsoft.Xna.Framework.Input.Keys.B ))
                    //borderObjInfo.UpdateConvexHall();

                    foreach (BordPoint bordP in borderObjInfo.Border.VisiBorder)
                    {


                        Vector2 logicP = Vector2.Transform( ConvertHelper.PointToVector2( bordP.p ), borderObjInfo.EyeableInfo.CurTransMatrix );
                        float azi = MathTools.AziFromRefPos( logicP - curPos );

                        if (azi < 0)
                        {
                            minAziMinus = Math.Min( minAziMinus, azi );
                            maxAziMinus = Math.Max( maxAziMinus, azi );
                        }
                        else
                        {
                            minAziPlus = Math.Min( minAziPlus, azi );
                            maxAziPlus = Math.Max( maxAziPlus, azi );
                        }

                        if (MathTools.FloatEqualZero( MathTools.AngTransInPI( azi - MathHelper.Pi ), 0.1f ))
                        {
                            crossPi = true;
                        }

                        if (MathTools.FloatEqualZero( azi, 0.1f ))
                        {
                            crossZero = true;
                        }

                        if (MathTools.FloatEqual( azi, aimAzi, 0.1f ) && Vector2.Distance( logicP, curPos ) < Vector2.Distance( aimPos, curPos ))
                        {
                            aimObstruct = true;
                        }

                        if (MathTools.FloatEqual( curAzi, azi, 0.1f ) && Vector2.Distance( logicP, curPos ) < Vector2.Distance( aimPos, curPos ))
                        {
                            curObstruct = true;
                        }
                    }
            }

            if (!aimObstruct)
            {
                if (!MathTools.FloatEqual( curAzi, aimAzi, 0.1f ))
                    action.AddOrder( new OrderMoveToPosDirect( aimPos ) );
                else
                    orderServer.ForwardSpeed = orderServer.MaxForwardSpeed;
            }
            else if (!curObstruct)
            {
                orderServer.ForwardSpeed = orderServer.MaxForwardSpeed;
            }
            else
            {
                orderServer.ForwardSpeed = 0;

                float aziEage1 = 0;
                float aziEage2 = 0;

                if (!crossZero && !crossPi)
                {
                    if (minAziMinus == 0)
                    {
                        aziEage1 = minAziPlus;
                        aziEage2 = maxAziPlus;
                    }
                    else
                    {
                        aziEage1 = minAziMinus;
                        aziEage2 = maxAziMinus;
                    }
                }
                else if (crossZero)
                {
                    aziEage1 = minAziMinus;
                    aziEage2 = maxAziPlus;
                }
                else if (crossPi)
                {
                    aziEage1 = minAziPlus;
                    aziEage2 = maxAziMinus;
                }
                else
                {

                }

                float curAimAzi = 0;

                if (Math.Abs( MathTools.AngTransInPI( curAzi - aziEage1 ) ) < Math.Abs( MathTools.AngTransInPI( curAzi - aziEage2 ) ))
                {
                    curAimAzi = aziEage1 - 0.1f;
                }
                else
                {
                    curAimAzi = aziEage2 + 0.1f;
                }

                rotaing = true;
                action.AddOrder( new OrderRotaToAzi( curAimAzi, 0,
                    delegate( IActionOrder order )
                    {
                        rotaing = false;
                        orderServer.ForwardSpeed = orderServer.MaxForwardSpeed;
                    }, false ) );
            }
        }

        #endregion

        #region IAI 成员


        public void Draw ()
        {

        }

        #endregion
    }
}
<file_sep>#include "ClientManager.h"

extern pthread_mutex_t DD_ClientMgr_Mutex[MAXCLIENT];
extern int g_MyPort;
extern int g_MaxRoommate;
extern char g_mySqlUserlName[21];
extern char g_mySqlUserlPass[21];


ClientManager::ClientManager()
{

    // 预分配
    /**/for ( int i = 0; i < MAXCLIENT; i++)
    {
        MySocket* pSock = new MySocket;
        pSock->m_ID = -1;
        pSock->m_socket = -1;
        m_pEmpty.push_back( pSock );
    }
    m_numOfRoom = 0;
    m_room = new MyRoom;
    m_room->SetManager(this);
    //SetTimer(5);
}

ClientManager::~ClientManager()
{
    vector<MySocket*>::iterator it = m_pClient.begin();
    vector<MySocket*>::iterator itEnd = m_pClient.end();
    for(; it != itEnd; it++)
    {
        delete (*it);
        *it = NULL;
        itEnd = m_pClient.end();
    }
    /**/it = m_pEmpty.begin();
    itEnd = m_pEmpty.end();
    for(; it != itEnd; it++)
    {
        delete (*it);
        *it = NULL;
        itEnd = m_pEmpty.end();
    }
    delete m_room;
    m_room = NULL;
}

//////////////////////////////////////////////////////////////////////////
// 记录服务器.返回socket指针
MySocket *ClientManager::AddServer( MySocket *psock)
{
    //#ifdef WIN32 
    //EnterCriticalSection(&DD_ClientMgr_Mutex);
    //#else
    //pthread_mutex_lock(&DD_ClientMgr_Mutex);
    //#endif

    if ( NULL == psock)
    {
        perror("AddServer");
    }
    m_pServer = psock;

//#ifdef WIN32 
//    LeaveCriticalSection(&DD_ClientMgr_Mutex);
//#else
//    pthread_mutex_unlock(&DD_ClientMgr_Mutex);
//#endif
    return m_pServer;
}


//////////////////////////////////////////////////////////////////////////
// 新用户加入
MySocket *ClientManager::AddClient( MySocket *psock)
{
    cout << "AddClient --- ";
    int p = m_pEmpty.size();
    if ( p > 0 )
    {
        psock->m_ID = GetNum();
        int nID = psock->m_ID;
        LockThreadBegin

        MySocket *newSock = m_pEmpty[p-1];
        memcpy(newSock,psock,sizeof(MySocket));
        m_pClient.push_back( newSock );
        m_pClient.back()->m_isLiving = true;
        m_pEmpty.pop_back();

        LockThreadEnd
        cout << "Success." << endl;
        return  newSock;
    }
    else
    {
        cout << "达到服务器人数上限.." << endl;
        return NULL;
    }
    //LockThreadEnd
    
}

//////////////////////////////////////////////////////////////////////////
// 得到某用户.返回socket指针
MySocket *ClientManager::GetClient( int iID)
{
    if ( iID<0 || iID>GetNum())
    {
        perror("AddServer");
    }
    return m_pClient[iID];
}
MySocket *ClientManager::GetSafeClient( int iID)
{
    if ( iID<0 || iID>GetNum())
    {
        perror("AddServer");
    }
    return m_pClient[iID];
}
//////////////////////////////////////////////////////////////////////////
// 删除用户
bool ClientManager::DelClient( MySocket *psock)
{
    if (NULL == psock)
        return true;
   int nID = psock->m_ID;
    LockThreadBegin
    vector<MySocket*>::iterator it = m_pClient.begin();
    for(; it != m_pClient.end(); it++)
    {
        // Close客户套接字
        if ( psock->m_ID == (*it)->m_ID)
        {  
            m_pEmpty.push_back( *it );
            m_pClient.erase(it);
            cout << psock->GetIP() << "离开游戏.当前客户数:" << GetNum() << endl;
            m_room->RemovePlayer(psock);
            if( m_room->GetPlayers() == 0)
                m_numOfRoom = 0;
            psock->Close();
            // cout << "Delete socket success." << endl;
            break;
        }
    }
    LockThreadEnd

    return true;
}

/************************************************************************/
/* 删除用户                                                                     */
/************************************************************************/
bool ClientManager::DelClientAll( )
{
    for (int i = 0; i < (int)m_pClient.size(); i++)
    {
        DelClient(m_pClient[i]);
    }
    return true;
}
/************************************************************************/
/* 定时器                                                                     */
/************************************************************************/
void ClientManager::SetTimer(int t )
{
#ifdef WIN32

    //::SetTimer(NULL, nID, 10000, HeartBeatFun);
#else
    struct itimerval itv, oldtv;
    itv.it_interval.tv_sec = t;
    itv.it_interval.tv_usec = 0;
    itv.it_value.tv_sec = t;
    itv.it_value.tv_usec = 0;

    setitimer(ITIMER_REAL, &itv, &oldtv);
#endif

}

void ClientManager::HeartBeatFun(MySocket *psock)
{
    psock->m_isLiving = true;
    cout << psock->m_name << " is Living..." << endl;
}




<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Common.DataStructure;

namespace Common.Helpers
{
    /// <summary>
    /// 提供数学上的计算辅助
    /// </summary>
    public static class MathTools
    {
        /// <summary>
        /// 将弧度值换算到PI和-PI之间
        /// </summary>
        /// <param name="ang"></param>
        /// <returns></returns>
        public static float AngTransInPI ( float ang )
        {
            float pi2 = 2 * MathHelper.Pi;
            while (ang > MathHelper.Pi)
            {
                ang -= pi2;
            }
            while (ang < -MathHelper.Pi)
            {
                ang += pi2;
            }
            return ang;
        }

        /// <summary>
        /// 由方向角计算出该方向的单位向量，包含三角函数。
        /// </summary>
        /// <param name="azi"></param>
        /// <returns></returns>
        public static Vector2 NormalVectorFromAzi ( float azi )
        {
            return new Vector2( (float)Math.Sin( azi ), -(float)Math.Cos( azi ) );
        }

        /// <summary>
        /// 转化为最靠近的整数
        /// </summary>
        /// <param name="f"></param>
        /// <returns></returns>
        public static int Round ( float f )
        {
            return (int)Math.Round( f, MidpointRounding.AwayFromZero );
        }

        /// <summary>
        /// 比较两浮点值是否相等
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="error">允许的误差</param>
        /// <returns></returns>
        public static bool FloatEqual ( float a, float b, float error )
        {
            if (Math.Abs( a - b ) < error)
                return true;
            else
                return false;
        }

        /// <summary>
        /// 检查浮点值是否为零
        /// </summary>
        /// <param name="a"></param>
        /// <param name="error">允许的误差</param>
        /// <returns></returns>
        public static bool FloatEqualZero ( float a, float error )
        {
            if (Math.Abs( a ) < error)
                return true;
            else
                return false;
        }

        /// <summary>
        /// 计算相对向量的方位
        /// </summary>
        /// <param name="refPos"></param>
        /// <returns></returns>
        public static float AziFromRefPos ( Vector2 refPos )
        {
            float result = new float();
            if (refPos.Y == 0)
            {
                if (refPos.X >= 0)
                    result = MathHelper.PiOver2;
                else
                    result = -MathHelper.PiOver2;
            }
            else if (refPos.Y < 0)
            {
                result = (float)Math.Atan( -refPos.X / refPos.Y );
            }
            else
            {
                result = (float)Math.PI + (float)Math.Atan( -refPos.X / refPos.Y );
            }
            result = AngTransInPI( result );
            return result;
        }

        /// <summary>
        /// 计算两点的中垂线
        /// </summary>
        /// <param name="point1"></param>
        /// <param name="point2"></param>
        /// <returns></returns>
        public static Line MidVerLine ( Vector2 point1, Vector2 point2 )
        {
            return new Line( 0.5f * (point1 + point2), Vector2.Normalize( new Vector2( -point2.Y + point1.Y, point2.X - point1.X ) ) );
        }

        /// <summary>
        /// 计算通过定点并与指定直线垂直的直线
        /// </summary>
        /// <param name="line"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static Line VerticeLine ( Line line, Vector2 point )
        {
            return new Line( point, Vector2.Normalize( new Vector2( -line.direction.Y, line.direction.X ) ) );
        }

        /// <summary>
        /// 计算两直线的交点，当两直线存在交点时返回true
        /// </summary>
        /// <param name="line1"></param>
        /// <param name="line2"></param>
        /// <param name="result"></param>
        /// <returns>当两直线存在交点时返回true</returns>
        public static bool InterPoint ( Line line1, Line line2, out Vector2 result )
        {
            if (Vector2.Normalize( line1.direction ) == Vector2.Normalize( line2.direction ) ||
                Vector2.Normalize( line1.direction ) == -Vector2.Normalize( line2.direction ))
            {
                result = Vector2.Zero;
                return false;
            }
            else
            {
                float k = ((line2.pos.X - line1.pos.X) * line2.direction.Y - (line2.pos.Y - line1.pos.Y) * line2.direction.X) /
                    (line1.direction.X * line2.direction.Y - line1.direction.Y * line2.direction.X);
                result = line1.pos + line1.direction * k;
                return true;
            }
        }

        /// <summary>
        /// 计算两向量间的夹角，以弧度为单位
        /// </summary>
        /// <param name="vec1"></param>
        /// <param name="vec2"></param>
        /// <returns></returns>
        public static float AngBetweenVectors ( Vector2 vec1, Vector2 vec2 )
        {
            return (float)Math.Acos( Vector2.Dot( vec1, vec2 ) / (vec1.Length() * vec2.Length()) );
        }

        /// <summary>
        /// 两二维向量的叉积，大于零表示两向量呈顺时针弯折
        /// </summary>
        /// <param name="vec1"></param>
        /// <param name="vec2"></param>
        /// <returns></returns>
        public static float Vector2Cross ( Vector2 vec1, Vector2 vec2 )
        {
            return vec1.X * vec2.Y - vec2.X * vec1.Y;
        }

        /// <summary>
        /// 获得入射向量经镜面反射后的反射向量
        /// </summary>
        /// <param name="incident">入射向量</param>
        /// <param name="mirrorNormal">镜面法向量</param>
        /// <returns></returns>
        public static Vector2 ReflectVector ( Vector2 incident, Vector2 mirrorNormal )
        {
            mirrorNormal.Normalize();
            return incident - 2 * Vector2.Dot( incident, mirrorNormal ) * mirrorNormal;
        }

        /// <summary>
        /// 从多个点中获得最小包围矩形
        /// </summary>
        /// <param name="containPoints"></param>
        /// <returns></returns>
        public static Rectanglef BoundBox ( params Vector2[] containPoints )
        {
            Vector2 minPoint = containPoints[0];
            Vector2 maxPoint = containPoints[0];
            for (int i = 1; i < containPoints.Length; i++)
            {
                minPoint = Vector2.Min( minPoint, containPoints[i] );
                maxPoint = Vector2.Max( maxPoint, containPoints[i] );
            }

            return new Rectanglef( minPoint, maxPoint );
        }
    }
}
<file_sep>
using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.GameObjs;
using TankEngine2D.Helpers;

namespace SmartTank.net
{
    static public class InfoRePath
    {


        static public void CallEvent(string objMgPath, string eventName, MulticastDelegate delgt, params object[] eventParams)
        {
            try
            {
                delgt.DynamicInvoke(eventParams);
                if (!PurviewMgr.IsMainHost)
                {
                    object[] newparams = new object[eventParams.Length];

                    for (int i = 0; i < eventParams.Length; i++)
                    {
                        if (eventParams[i] is IGameObj)
                        {
                            newparams[i] = new GameObjSyncInfo(((IGameObj)eventParams[i]).MgPath);
                        }
                        else
                        {
                            newparams[i] = eventParams[i];
                        }

                    }

                    // 通过网络协议传递给主机
                    SyncCasheWriter.SubmitNewEvent(objMgPath, eventName, newparams);
                }
            }
            catch (Exception ex)
            {
                Log.Write(ex.ToString());
            }
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.GameObjs;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework;
using SmartTank.PhiCol;
using System.IO;
using SmartTank;
using SmartTank.Draw;
using Microsoft.Xna.Framework.Graphics;
using TankEngine2D.Input;
using TankEngine2D.Helpers;
using Microsoft.Xna.Framework.Input;
using SmartTank.net;
using SmartTank.Helpers;

namespace InterRules.Starwar
{
    class WarShip : IGameObj, ICollideObj, IPhisicalObj
    {

        public WarShip(string name,Vector2 pos, float azi, bool openControl)
        {
            this.name = name;
            this.objInfo = new GameObjInfo("WarShip", name);
            this.openControl = openControl;
            InitializeTex(pos, azi);
            InitializePhisical(pos, azi);
            this.Pos = pos;
            this.Azi = azi;
            this.OnDead += new WarShipDeadEventHandler(WarShip_OnDead);
        }

        void WarShip_OnDead(WarShip sender)
        {
            destoryAnimate.SetSpritesParameters(new Vector2(48, 48), this.Pos, 1f, this.Azi, Color.White, LayerDepth.TankBase, SpriteBlendMode.AlphaBlend);
            destoryAnimate.Interval = 5;
            destoryAnimate.Start(0, 6, true);
            GameManager.AnimatedMgr.Add(destoryAnimate);
        }

        #region Logic

        public readonly float cRootTwoDivideTwo = (float)(Math.Sqrt(2) * 0.5f);

        //protected Vector2 curSpeed = new Vector2(0, 0);

        protected int curHP = SpaceWarConfig.IniHP;
        protected bool isDead = false;

        /* 计时器在小于0时有效计时状态
         * */
        protected float stillTimer = 0;
        protected float wtfTimer = 0;
        protected float shootTimer = 0;
        protected int score = 0;

        string playerName;

        public string PlayerName
        {
            get { return playerName; }
            set { playerName = value; }
        }

        public int Score
        {
            get { return score; }
            set 
            {
                score = value;
            }
        }

        public Vector2 Vel
        {
            get { return phisicalUpdater.Vel; }
            set { phisicalUpdater.Vel = value; }
        }

        public int HP
        {
            get { return curHP; }
            set { curHP = value; }
        }


        public delegate void WarShipShootEventHandler(WarShip firer, Vector2 endPoint, float azi);
        public delegate void WarShipDeadEventHandler(WarShip sender);

        public event WarShipShootEventHandler OnShoot;
        public event WarShipDeadEventHandler OnDead;

        protected bool Shoot(float ShootAzi)
        {
            if (shootTimer >= 0)
            {
                if (OnShoot != null)
                    InfoRePath.CallEvent(this.mgPath, "OnShoot", OnShoot, this, Pos + MathTools.NormalVectorFromAzi(ShootAzi) * SpaceWarConfig.ShootEndDest, ShootAzi);
                shootTimer -= SpaceWarConfig.ShootCD;
                return true;
            }
            return false;
        }

        public void CallOnShoot(WarShip firer, Vector2 endPoint, float azi)
        {
            if (OnShoot != null)
                OnShoot(this, Pos + MathTools.NormalVectorFromAzi(azi) * SpaceWarConfig.ShootEndDest, azi);
        }

        internal void Born(Vector2 newPos)
        {
            BeginWTF();
            this.Pos = newPos;
            this.Vel = Vector2.Zero;
            isDead = false;
            this.HP = SpaceWarConfig.IniHP;
        }

        public void BeginStill()
        {
            stillTimer = -SpaceWarConfig.StillTime;
        }

        public void BeginWTF()
        {
            wtfTimer = -SpaceWarConfig.WTFTime;
        }

        public void HitByShell()
        {
            LooseHP(SpaceWarConfig.HitbyShellDamage);
        }

        public void HitByObjExceptShell()
        {
            LooseHP(SpaceWarConfig.HitbyObjExceptShell);
        }

        private void LooseHP(int Damage)
        {
            this.curHP -= Damage;

            if (curHP <= 0)
            {
                isDead = true;
                if (OnDead != null)
                    OnDead(this);
            }
        }

        public void Dead()
        {
            this.isDead = true;
            if (OnDead != null)
                OnDead(this);
        }

        private void HandlerControl(float seconds)
        {
            if (!isDead && openControl)
            {
                float maxSpeed = SpaceWarConfig.SpeedMax;
                float accel = SpaceWarConfig.SpeedAccel;
                if (stillTimer < 0)
                {
                    // 硬直状态
                    // maxSpeed *= cStillSpeedScale; 
                    accel *= SpaceWarConfig.StillSpeedScale;
                }

                #region  获取键盘输入

                bool Up = InputHandler.IsKeyDown(Keys.W);
                bool Left = InputHandler.IsKeyDown(Keys.A);
                bool Down = InputHandler.IsKeyDown(Keys.S);
                bool Right = InputHandler.IsKeyDown(Keys.D);

                Vector2 deltaSpeed = new Vector2();
                bool noInput = false;

                // 左上
                if (Up && Left && !Right && !Down)
                {
                    deltaSpeed.X = -cRootTwoDivideTwo;
                    deltaSpeed.Y = -cRootTwoDivideTwo;
                }
                // 右上
                else if (Up && Right && !Left && !Down)
                {
                    deltaSpeed.X = cRootTwoDivideTwo;
                    deltaSpeed.Y = -cRootTwoDivideTwo;
                }
                // 右下
                else if (Down && Right && !Up && !Left)
                {
                    deltaSpeed.X = cRootTwoDivideTwo;
                    deltaSpeed.Y = cRootTwoDivideTwo;
                }
                // 左下
                else if (Down && Left && !Up && !Right)
                {
                    deltaSpeed.X = -cRootTwoDivideTwo;
                    deltaSpeed.Y = cRootTwoDivideTwo;
                }
                // 上
                else if (Up && !Down)
                {
                    deltaSpeed.X = 0;
                    deltaSpeed.Y = -1.0f;
                }
                // 下
                else if (Down && !Up)
                {
                    deltaSpeed.X = 0;
                    deltaSpeed.Y = 1.0f;
                }
                // 左
                else if (Left && !Right)
                {
                    deltaSpeed.X = -1.0f;
                    deltaSpeed.Y = 0;
                }
                // 右
                else if (Right && !Left)
                {
                    deltaSpeed.X = 1.0f;
                    deltaSpeed.Y = 0;
                }
                else
                {
                    noInput = true;
                }

                #endregion

                #region 获得鼠标状态

                if (InputHandler.LastMouseLeftDown)
                {
                    Vector2 mousePos = InputHandler.GetCurMousePosInLogic(BaseGame.RenderEngine);
                    float shootAzi = MathTools.AziFromRefPos(mousePos - this.Pos);

                    this.Shoot(shootAzi);
                }

                #endregion


                if (!noInput)
                {
                    phisicalUpdater.Azi = MathTools.AziFromRefPos(Vel);
                    deltaSpeed *= seconds * accel;
                    Vel += deltaSpeed;
                    float SpeedAbs = Vel.Length();
                    if (SpeedAbs > maxSpeed)
                    {
                        Vel *= maxSpeed / SpeedAbs;
                    }
                }
                else // 衰减
                {
                    // 假设时间间隔是均匀的，并且间隔很小。
                    if (SpaceWarConfig.SpeedDecay * seconds < 1)
                    {
                        Vel *= (1 - SpaceWarConfig.SpeedDecay * seconds);
                    }
                }
                phisicalUpdater.Vel = Vel;
            }
        }

        #endregion

        #region IPhisicalObj 成员

        public event OnCollidedEventHandler OnCollied;
        public event OnCollidedEventHandler OnOverLap;


        private void InitializePhisical(Vector2 pos, float azi)
        {
            phisicalUpdater = new NonInertiasColUpdater(objInfo, new Sprite[] { normalSprite });
            phisicalUpdater.OnCollied += new OnCollidedEventHandler(phisicalUpdater_OnCollied);
            phisicalUpdater.OnOverlap += new OnCollidedEventHandler(phisicalUpdater_OnOverlap);
        }

        public void CallOnOverlap(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (OnOverLap != null)
                OnOverLap(Sender, result, objB);
        }

        public void CallOnCollied(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (OnCollied != null)
                OnCollied(Sender, result, objB);
        }

        void phisicalUpdater_OnOverlap(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (OnOverLap != null)
                InfoRePath.CallEvent(this.mgPath, "OnOverlap", OnOverLap, this, result, objB);
        }

        void phisicalUpdater_OnCollied(IGameObj Sender, CollisionResult result, GameObjInfo objB)
        {
            if (OnCollied != null)
                InfoRePath.CallEvent(this.mgPath, "OnCollied", OnCollied, this, result, objB);
        }


        protected NonInertiasColUpdater phisicalUpdater;

        public IPhisicalUpdater PhisicalUpdater
        {
            get { return phisicalUpdater; }
        }

        #endregion

        #region ICollideObj 成员

        public IColChecker ColChecker
        {
            get { return phisicalUpdater; }
        }

        #endregion

        #region IGameObj 成员

        public float Azi
        {
            get { return phisicalUpdater.Azi; }
            set { phisicalUpdater.Azi = value; }
        }

        protected string mgPath;
        public string MgPath
        {
            get
            {
                return mgPath;
            }
            set
            {
                mgPath = value;
            }
        }

        protected string name;
        public string Name
        {
            get { return name; }
        }

        protected GameObjInfo objInfo;
        public GameObjInfo ObjInfo
        {
            get { return objInfo; }
        }

        public Microsoft.Xna.Framework.Vector2 Pos
        {
            get
            {
                return phisicalUpdater.Pos;
            }
            set
            {
                phisicalUpdater.Pos = value;
            }
        }

        #endregion

        #region IUpdater 成员

        protected bool openControl;
        public void Update(float seconds)
        {
            if (openControl)
                HandlerControl(seconds);

            UpdateTimers(seconds);

            UpdateSprite();

            CommitSyncInfo();
        }

        private void CommitSyncInfo()
        {
            SyncCasheWriter.SubmitNewStatus(this.mgPath, "Pos", SyncImportant.HighFrequency, this.Pos);
            SyncCasheWriter.SubmitNewStatus(this.mgPath, "Vel", SyncImportant.HighFrequency, this.Vel);
            SyncCasheWriter.SubmitNewStatus(this.mgPath, "Azi", SyncImportant.HighFrequency, this.Azi);
        }

        private void UpdateSprite()
        {
            hitingSprite.Pos = this.Pos;
            hitingSprite.Rata = this.Azi;
        }

        private void UpdateTimers(float seconds)
        {
            if (shootTimer < 0)
                shootTimer += seconds;
            if (wtfTimer < 0)
                wtfTimer += seconds;
            if (stillTimer < 0)
                stillTimer += seconds;

        }


        #endregion

        #region IDrawableObj 成员


        Sprite normalSprite;
        Sprite hitingSprite;

        AnimatedSpriteSeries destoryAnimate;

        private void InitializeTex(Vector2 pos, float azi)
        {
            normalSprite = new Sprite(BaseGame.RenderEngine);
            normalSprite.LoadTextureFromFile(Path.Combine(Directories.ContentDirectory, "Rules\\SpaceWar\\image\\field_spaceship_001.png"), true);
            normalSprite.SetParameters(new Vector2(16, 16), pos, 1f, azi, Color.White, LayerDepth.TankBase, SpriteBlendMode.AlphaBlend);

            hitingSprite = new Sprite(BaseGame.RenderEngine);
            hitingSprite.LoadTextureFromFile(Path.Combine(Directories.ContentDirectory, "Rules\\SpaceWar\\image\\field_spaceship_002.png"), true);
            hitingSprite.SetParameters(new Vector2(16, 16), pos, 1f, azi, Color.White, LayerDepth.TankBase, SpriteBlendMode.AlphaBlend);

            destoryAnimate = new AnimatedSpriteSeries(BaseGame.RenderEngine);
            destoryAnimate.LoadSeriesFromFiles(BaseGame.RenderEngine, Path.Combine(Directories.ContentDirectory, "Rules\\SpaceWar\\image"), "field_burst_00", ".png", 1, 6, false);
        }

        public void Draw()
        {
            if (isDead)
            {

            }
            else if (stillTimer >= 0)
            {
                normalSprite.Draw();
            }
            else
            {
                hitingSprite.Draw();
            }
        }

        #endregion


    }
}
<file_sep>#include "mysocket.h"

#ifdef WIN32
    extern CRITICAL_SECTION DD_ClientMgr_Mutex[MAXCLIENT];  
#else
    extern int errno;
    extern pthread_mutex_t DD_ClientMgr_Mutex[MAXCLIENT];  
#endif
int MySocket::m_sinSize = sizeof(struct sockaddr_in);
extern MySocket sockSrv;
extern int g_MyPort;
extern int g_MaxRoommate;
extern char g_mySqlUserlName[21];
extern char g_mySqlUserlPass[21];
//////////////////////////////////////////////////////////////////////////
MySocket::MySocket()
{
    m_socket = SOCKET_ERROR;
    memset(&m_addr, 0, m_sinSize);
    m_ID = -1;
    m_bHost = false;
    m_bInRoom = false;
}

//////////////////////////////////////////////////////////////////////////
// 析构并且关闭
MySocket::~MySocket()
{
    Close();
}
//////////////////////////////////////////////////////////////////////////
// 绑定套接字
void MySocket::Bind(int port)
{   
    // 创建套接字
    if ( ( m_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("socket");
        exit(1);
    }

    m_addr.sin_family = AF_INET;
    m_addr.sin_port   = htons(port);
    m_addr.sin_addr.s_addr   =  htonl(INADDR_ANY);
    memset(&m_addr.sin_zero, 0, 8);

    // bind套接字
    if ( bind( m_socket, (sockaddr*)(&m_addr), sizeof(sockaddr) ) == -1)
    {
        int errsv = errno;
        cout << errsv << endl;
        cin >> errsv;
        perror("Bind");
        exit(1);
    }

}
//////////////////////////////////////////////////////////////////////////
// 监听
void MySocket::Listen()
{
    // listen
    linger ling;
    ling.l_onoff=0;   ling.l_linger=1;
    ///*******************Xiangbin Modified this**************************/
    if(0 != setsockopt(m_socket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling)))
    {
        return ;
    }
    if ( listen( m_socket, MAXCLIENT ) == -1)
    {
        perror("listen");
        exit(1);
    }
}
//////////////////////////////////////////////////////////////////////////
// 接受套接字
int MySocket::Accept(MySocket *pSockConn)
{
    int sockConn;
    sockaddr_in addrClient;
    int len = sizeof(sockaddr);
    
    if ( -1 == ( sockConn = accept(m_socket, (sockaddr*)&addrClient,(socklen_t*)&len) ) )
    {
        perror("accept");
        return -1;
    }
    else
    {
        pSockConn->m_socket = sockConn;
        memcpy(&pSockConn->m_addr, &addrClient, MySocket::m_sinSize);
        sprintf(pSockConn->m_sIP,"%s", inet_ntoa((in_addr)addrClient.sin_addr));    
        return sockConn;
    }
}
//////////////////////////////////////////////////////////////////////////
// 连接 
bool MySocket::Connect( char* chIP, long port)
{
    m_addr.sin_family = AF_INET;
    m_addr.sin_port   = htons(MYPORT);
    m_addr.sin_addr.s_addr   =  (inet_addr(IP));
    memset(&m_addr.sin_zero, 0, 8);
    int err = connect( m_socket, (struct sockaddr*)(&m_addr), m_sinSize) ;
    
    if ( err == -1)
    {
        perror("connect"); 
        return false;
    }
    else
    {
        return true;
    }
    
}
//////////////////////////////////////////////////////////////////////////
// 发送
bool MySocket::Send( char* msg, long leng)
{
    if ( send( m_socket, msg, leng, 0) == -1)
    {
        perror("Send");
        return false;
    }
    else
    {
        return true;
    }
}
/************************************************************************/
/* 发送数据包                           
/************************************************************************/
bool MySocket::SendPacket( Packet& pack, int realSize)        
{     
    /* 加锁转发 */
    int nID = m_ID;
    LockThreadBegin
    if ( -1 == send( m_socket, (char*)&pack, realSize, MSG_NOSIGNAL) )
    {   
        LockThreadEnd
        cout << errno << ":SendPacket." << endl;
        return false;
    }
    LockThreadEnd
    return true;
}
/************************************************************************/
/* 发送数据包头                           
/************************************************************************/
bool MySocket::SendPacketHead( PacketHead& packHead) 
{
    /* 加锁转发 */
    int nID = m_ID;
    LockThreadBegin
    if ( -1 == send( m_socket, (char*)&packHead, HEADSIZE, MSG_NOSIGNAL) )
    {
        cout << errno << ":SendPacketHead." << endl;
        LockThreadEnd
        return false;
    }
    LockThreadEnd
    return true;
}
bool MySocket::SendPacketChat( char *msg, long leng)
{
    //char sChatHead[300];
    //char sIP[16];
    //char sPort[8]; 
    //pSockClient->GetIP(sIP);
    //pSockClient->GetPort(sPort);
    //sprintf(sChatHead, "%s:%s 说:%s ", sIP, sPort, pack.data);
    //strcpy( pack.data, sChatHead);
    //cout << sChatHead << endl;

   /* Packet packOut;
    packOut.iStyle = CHAT;
    packOut.length = sizeof(Packet);
    memset(packOut.data, 0, PACKSIZE);
    strcpy(packOut.data, msg);
    if ( -1 == send( m_socket, (char*)&packOut, sizeof(Packet), MSG_NOSIGNAL) )
    {
        perror("SendPacket");
        cout << "Oh, 狗日的掉线了." << endl;
        return false;
    }*/

    return true;
}
/************************************************************************/
/* 接收数据包                           
/************************************************************************/
bool MySocket::RecvPacket( PacketHead& packHead, Packet& pack )
{
    if ( packHead.length == 0)
        return true;

    int nRecvBytes = 0;
    int ret;
    memcpy(&pack, &packHead, HEADSIZE);
    while ( nRecvBytes < packHead.length)
    {
        if ( -1 == ( ret = recv(m_socket, (char*)(&pack)+HEADSIZE+nRecvBytes,
            packHead.length-nRecvBytes, MSG_NOSIGNAL) ) ) 
        {   // 失败，删除该客户
            return false;
        }
        nRecvBytes += ret;
    }
    return ( nRecvBytes == packHead.length );
}

//////////////////////////////////////////////////////////////////////////
// 关闭套接字
void MySocket::Close()
{
    // 清理工作
#ifdef WIN32 
    closesocket(m_socket);  
#else
    close(m_socket);
#endif

}
//////////////////////////////////////////////////////////////////////////
// 返回IP地址
char* MySocket::GetIP()
{
    return m_sIP;
}
//////////////////////////////////////////////////////////////////////////
// 返回端口号
long MySocket::GetPort()
{
    return (long)m_addr.sin_port;
}
bool MySocket::GetUserInfo(UserInfo &ui)
{
    ui.ID = m_bHost;
    strcpy(ui.Name, m_name);
    ui.Score = m_score;
    ui.Rank  = m_rank;
    memset(ui.Password, 0, 21);
    return true;
}
// 返回端口号(字符串形式)
char* MySocket::GetPort(char *outPort)
{
    if( !outPort )
    {
        perror("outBuff is NULL");
        exit(1);
    }
    sprintf( outPort,"%d", m_addr.sin_port );    
    return outPort;
}



//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 初始化套接字
void StartSocket()
{
#ifdef WIN32
    //初始化协议
    WSADATA wsaData;
    int err;    
    err = WSAStartup( MAKEWORD(2,2), &wsaData );
    if ( err != 0 ) {
        cout << "ERROR = " << err << endl;
        return;
	}
    for ( int i=0; i<MAXCLIENT; i++)
    { 
        InitializeCriticalSection(&DD_ClientMgr_Mutex[i]);
    }
#else
    for ( int i=0; i<MAXCLIENT; i++)
    { 
        pthread_mutex_init(&DD_ClientMgr_Mutex[i], NULL);
    }
    {
        // 断开的管道和非正常关闭socket有关 不进行信号处理
        signal(SIGHUP     ,SIG_IGN   );       /*   hangup,   generated   when   terminal   disconnects   */   
        signal(SIGINT     ,SIG_IGN   );       /*   interrupt,   generated   from   terminal   special   char   */   
        signal(SIGQUIT   ,SIG_IGN   );       /*   (*)   quit,   generated   from   terminal   special   char   */   
        signal(SIGILL     ,SIG_IGN   );       /*   (*)   illegal   instruction   (not   reset   when   caught)*/   
        signal(SIGTRAP   ,SIG_IGN   );       /*   (*)   trace   trap   (not   reset   when   caught)   */   
        signal(SIGABRT   ,SIG_IGN   );       /*   (*)   abort   process   */   
#ifdef   D_AIX   
        signal(SIGEMT     ,SIG_IGN   );       /*   EMT   intruction   */   
#endif   
        signal(SIGFPE     ,SIG_IGN   );       /*   (*)   floating   point   exception   */   
        signal(SIGKILL   ,SIG_IGN   );       /*   kill   (cannot   be   caught   or   ignored)   */   
        signal(SIGBUS     ,SIG_IGN   );       /*   (*)   bus   error   (specification   exception)   */   
        signal(SIGSEGV   ,SIG_IGN   );       /*   (*)   segmentation   violation   */   
        signal(SIGSYS     ,SIG_IGN   );       /*   (*)   bad   argument   to   system   call   */   
        signal(SIGPIPE   ,SIG_IGN   );       /*   write   on   a   pipe   with   no   one   to   read   it   */   
        //signal(SIGALRM   ,HeartBeatFun );       /*   alarm   clock   timeout   */   
        //signal(SIGTERM   ,stopproc   );     /*   software   termination   signal   */   
        signal(SIGURG     ,SIG_IGN   );       /*   (+)   urgent   contition   on   I/O   channel   */   
        signal(SIGSTOP   ,SIG_IGN   );       /*   (@)   stop   (cannot   be   caught   or   ignored)   */   
        signal(SIGTSTP   ,SIG_IGN   );       /*   (@)   interactive   stop   */   
        signal(SIGCONT   ,SIG_IGN   );       /*   (!)   continue   (cannot   be   caught   or   ignored)   */   
        signal(SIGCHLD   ,SIG_IGN);         /*   (+)   sent   to   parent   on   child   stop   or   exit   */   
        signal(SIGTTIN   ,SIG_IGN);         /*   (@)   background   read   attempted   from   control   terminal*/   
        signal(SIGTTOU   ,SIG_IGN);         /*   (@)   background   write   attempted   to   control   terminal   */   
        signal(SIGIO       ,SIG_IGN);         /*   (+)   I/O   possible,   or   completed   */   
        signal(SIGXCPU   ,SIG_IGN);         /*   cpu   time   limit   exceeded   (see   setrlimit())   */   
        signal(SIGXFSZ   ,SIG_IGN);         /*   file   size   limit   exceeded   (see   setrlimit())   */   

#ifdef   D_AIX   
        signal(SIGMSG     ,SIG_IGN);         /*   input   data   is   in   the   ring   buffer   */   
#endif   

        signal(SIGWINCH,SIG_IGN);         /*   (+)   window   size   changed   */   
        signal(SIGPWR     ,SIG_IGN);         /*   (+)   power-fail   restart   */   
        //signal(SIGUSR1   ,stopproc);       /*   user   defined   signal   1   */   
        //signal(SIGUSR2   ,stopproc);       /*   user   defined   signal   2   */   
        signal(SIGPROF   ,SIG_IGN);         /*   profiling   time   alarm   (see   setitimer)   */   

#ifdef   D_AIX   
        signal(SIGDANGER,SIG_IGN);       /*   system   crash   imminent;   free   up   some   page   space   */   
#endif   

        signal(SIGVTALRM,SIG_IGN);       /*   virtual   time   alarm   (see   setitimer)   */   

#ifdef   D_AIX   
        signal(SIGMIGRATE,SIG_IGN);     /*   migrate   process   */   
        signal(SIGPRE     ,SIG_IGN);         /*   programming   exception   */   
        signal(SIGVIRT   ,SIG_IGN);         /*   AIX   virtual   time   alarm   */     
        signal(SIGALRM1,SIG_IGN);         /*   m:n   condition   variables   -   RESERVED   -   DON'T   USE   */   
        signal(SIGWAITING,SIG_IGN);     /*   m:n   scheduling   -   RESERVED   -   DON'T   USE   */   
        signal(SIGCPUFAIL   ,SIG_IGN);   /*   Predictive   De-configuration   of   Processors   -   */   
        signal(SIGKAP,SIG_IGN);             /*   keep   alive   poll   from   native   keyboard   */   
        signal(SIGRETRACT,SIG_IGN);     /*   monitor   mode   should   be   relinguished   */   
        signal(SIGSOUND     ,SIG_IGN);     /*   sound   control   has   completed   */   
        signal(SIGSAK         ,SIG_IGN);     /*   secure   attention   key   */   
#endif   
    }
#endif
}
//////////////////////////////////////////////////////////////////////////
void DestroySocket()
{
#ifdef WIN32
    WSACleanup();
    for ( int i=0; i<MAXCLIENT; i++)
    {
        DeleteCriticalSection(&DD_ClientMgr_Mutex[i]);
    }
#else
    for ( int i=0; i<MAXCLIENT; i++)
    {
        pthread_mutex_destroy(&DD_ClientMgr_Mutex[i]);
    }
#endif
}





<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.IO;
using TankEngine2D.Helpers;
using TankEngine2D.DataStructure;
using Microsoft.Xna.Framework.Content;

namespace TankEngine2D.Graphics
{
    /// <summary>
    /// this is the class which manages all the sprite items in the gameScene.
    /// it can draw itself according to the position, rotation, scale, ect as you like.
    /// it's also able to detect collision between two sprite using pix-detection method.
    /// Notice: sourceRectangle is't supported, so you cann't load a picture with several items in it.
    /// 这个类管理游戏画面中的所有精灵。
    /// 它保存绘制的地点，旋转角，缩放比等参数，并能够按照这些参数绘制自身。
    /// 并且它具有判断两精灵是否重叠，以及该精灵是否出界的方法。使用的是像素检测的方法。
    /// 注意，该类并不支持sourceRectangle。所以不能用它导入一个拥有多个子图的图片。
    /// </summary>
    public class Sprite : IDisposable
    {
        #region Statics

        /// <summary>
        /// 一个计算冲突法向量时用到的参数，表示计算法向量时将取冲突处附近的多少点进行效果的平均
        /// </summary>
        public static readonly int DefaultAverageSum = 5;

        #endregion

        #region Variables

        RenderEngine engine;

        Texture2D mTexture;

        /*
         * 逻辑上的位置和大小
         * */
        /// <summary>
        /// 贴图的中心，以贴图坐标表示
        /// </summary>
        public Vector2 Origin;

        /// <summary>
        /// 逻辑位置
        /// </summary>
        public Vector2 Pos;

        /// <summary>
        /// 逻辑宽度
        /// </summary>
        public float Width;

        /// <summary>
        /// 逻辑高度
        /// </summary>
        public float Height;
        //public float Scale;

        /// <summary>
        /// 逻辑方位角
        /// </summary>
        public float Rata;

        /// <summary>
        /// 绘制颜色
        /// </summary>
        public Color Color;

        /// <summary>
        /// 深度，1为最低层，0为最表层。
        /// </summary>
        public float LayerDepth;

        /// <summary>
        /// 采用的混合模式
        /// </summary>
        public SpriteBlendMode BlendMode;

        Rectanglef mBounding;
        /// <summary>
        /// 获得包围盒，以逻辑坐标。
        /// 该属性中进行了除法运算。
        /// </summary>
        public Rectanglef BoundRect
        {
            get
            {
                //Vector2 logicPos = Coordin.LogicPos( new Vector2( mBounding.X, mBounding.Y ) );
                //return new Rectanglef( logicPos.X, logicPos.Y, Coordin.LogicLength( mBounding.Width ), Coordin.LogicLength( mBounding.Height ) );
                return mBounding;
            }
        }

        Matrix mTransform;
        /// <summary>
        /// 世界转换矩阵
        /// 每一帧需要先调用UpdateTransformBounding函数。
        /// </summary>
        public Matrix Transform
        {
            get { return mTransform; }
        }

        Rectangle mDestiRect;

        bool[] mTextureData;

        SpriteBorder mBorder;

        /// <summary>
        /// 计算遮挡所需原数据
        /// </summary>
        public CircleList<BorderPoint> BorderData
        {
            get { return mBorder.BorderCircle; }
        }

        bool mloaded = false;

        bool mSupportIntersectDect = false;

        int mAverageSum = DefaultAverageSum;

        /// <summary>
        /// 获得或设置贴图的缩放比（= 逻辑长度/贴图长度）
        /// </summary>
        public float Scale
        {
            get
            {
                return Width / (float)mTexture.Width;
            }
            set
            {
                Width = (float)mTexture.Width * Math.Max( 0, value );
                Height = (float)mTexture.Height * Math.Max( 0, value );
                CalDestinRect();
            }
        }

        #endregion

        #region Constructions

        /// <summary>
        /// 构造未导入贴图的Sprite对象
        /// </summary>
        public Sprite ( RenderEngine engine )
        {
            this.engine = engine;
            Rata = 0f;
            Color = Color.White;
            LayerDepth = 0f;
        }

        /// <summary>
        /// 构造Sprite对象并导入贴图
        /// </summary>
        /// <param name="engine">渲染组件</param>
        /// <param name="texturePath">贴图路径</param>
        /// <param name="SupportIntersectDect"></param>
        public Sprite ( RenderEngine engine, string texturePath, bool SupportIntersectDect )
            : this( engine )
        {
            LoadTextureFromFile( texturePath, SupportIntersectDect );
        }

        /// <summary>
        /// 构造Sprite对象并导入贴图
        /// </summary>
        /// <param name="engine">渲染组件</param>
        /// <param name="contentMgr">素材管理者</param>
        /// <param name="assetPath">素材路径</param>
        /// <param name="SupportIntersectDect">是否添加冲突检测支持</param>
        public Sprite ( RenderEngine engine, ContentManager contentMgr, string assetPath, bool SupportIntersectDect )
            : this( engine )
        {
            LoadTextureFromContent( contentMgr, assetPath, SupportIntersectDect );
        }

        #endregion

        #region LoadTexture Functions

        /// <summary>
        /// 检查贴图的是否能建立边界，如果建立边界失败，将抛出异常。成功时则返回所建的边界。
        /// 在检测贴图是否能被正常的建立边界的情况下使用。
        /// </summary>
        /// <param name="tex"></param>
        /// <param name="borderMap">建立边界成功时返回结果</param>
        public static void CheckBorder ( Texture2D tex, out SpriteBorder.BorderMap borderMap )
        {
            SpriteBorder border = new SpriteBorder( tex, out borderMap );
        }

        /// <summary>
        /// Load Texture From File
        /// 从文件中导入贴图。
        /// </summary>
        /// <param name="texturePath">the texture Directory and File Name, without GameBaseDirectory Path.
        /// 贴图文件的相对于游戏运行文件的路径</param>
        /// <param name="SupportIntersectDect">true to add intersect dectection support.
        /// 为true时，为贴图添加冲突检测的支持</param>
        public void LoadTextureFromFile ( string texturePath, bool SupportIntersectDect )
        {
            mloaded = true;
            try
            {
                mTexture = Texture2D.FromFile( engine.Device, texturePath );
                if (SupportIntersectDect)
                {
                    AddIntersectSupport();
                }
            }
            catch (Exception)
            {
                mloaded = false;
                mTexture = null;
                mTextureData = null;
                //mTextureBoundData = null;
                throw new Exception( "导入贴图文件失败！" );
            }
        }

        /// <summary>
        /// Load Texture From Content
        /// 从素材管道中导入贴图
        /// </summary>
        /// <param name="contentMgr">素材管理者</param>
        /// <param name="assetName">the assetName.素材路径</param>
        /// <param name="SupportIntersectDect">true to add intersect Dectection support.
        /// 为true时为贴图添加冲突检测的支持</param>
        public void LoadTextureFromContent ( ContentManager contentMgr, string assetName, bool SupportIntersectDect )
        {
            mloaded = true;
            try
            {
                mTexture = contentMgr.Load<Texture2D>( assetName );
                if (SupportIntersectDect)
                {
                    AddIntersectSupport();
                }
            }
            catch (Exception)
            {
                mloaded = false;
                mTexture = null;
                mTextureData = null;
                //mTextureBoundData = null;
                throw new Exception( "导入贴图文件失败！" );
            }
        }

        /// <summary>
        /// Load Texture From File, support Intersect dectect,
        /// the AverageSum is use to modify the default averageSum,
        /// which is used in calulate the Normal vector,
        /// biger the number is, more border points will be added to the result of Normal Vector. 
        /// 从文件中导入贴图，并添加冲突检测的支持
        /// </summary>
        /// <param name="texturePath">贴图文件的相对于游戏运行文件的路径</param>
        /// <param name="AverageSum">使用该传入值作为AverageSum。
        /// 这是一个计算碰撞法向量时用到的参数，表示计算法向量时将取碰撞处附近的多少点进行效果的平均</param>
        public void LoadTextureFromFile ( string texturePath, int AverageSum )
        {
            mAverageSum = AverageSum;
            LoadTextureFromFile( texturePath, true );
        }

        /// <summary>
        /// Load Texture From Content, support Intersect dectect,
        /// the AverageSum is use to modify the default averageSum,
        /// which is used in calulate the Normal vector,
        /// biger the number is, more border points will be added to the result of Normal Vector. 
        /// 从素材管道中导入贴图，并添加冲突检测的支持
        /// </summary>
        /// <param name="contentMgr">素材管理者</param>
        /// <param name="assetName">素材路径</param>
        /// <param name="AverageSum">使用该传入值作为AverageSum。
        /// 这是一个计算碰撞法向量时用到的参数，表示计算法向量时将取碰撞处附近的多少点进行效果的平均</param>
        public void LoadTextureFromContent ( ContentManager contentMgr, string assetName, int AverageSum )
        {
            mAverageSum = AverageSum;
            LoadTextureFromContent( contentMgr, assetName, true );
        }

        /// <summary>
        /// 为Sprite对象添加冲突检测的支持
        /// </summary>
        public void AddIntersectSupport ()
        {
            mSupportIntersectDect = true;

            Color[] textureData = new Color[mTexture.Width * mTexture.Height];
            mTextureData = new bool[mTexture.Width * mTexture.Height];
            mTexture.GetData( textureData );
            for (int i = 0; i < textureData.Length; i++)
            {
                if (textureData[i].A >= SpriteBorder.minBlockAlpha)
                    mTextureData[i] = true;
                else
                    mTextureData[i] = false;
            }
            mBorder = new SpriteBorder( mTexture );
        }
        #endregion

        #region Set Parameters
        /// <summary>
        /// 设置该精灵的绘制参数
        /// </summary>
        /// <param name="origin">贴图的中心，以贴图坐标表示</param>
        /// <param name="pos">逻辑位置</param>
        /// <param name="width">逻辑宽度</param>
        /// <param name="height">逻辑高度</param>
        /// <param name="rata">逻辑方位角</param>
        /// <param name="color">绘制颜色</param>
        /// <param name="layerDepth">深度，1为最低层，0为最表层</param>
        /// <param name="blendMode">采用的混合模式</param>
        public void SetParameters ( Vector2 origin, Vector2 pos, float width, float height, float rata, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            Origin = origin;
            Pos = pos;
            Width = width;
            Height = height;
            Rata = rata;
            Color = color;
            LayerDepth = layerDepth;
            BlendMode = blendMode;
        }
        /// <summary>
        /// 设置该精灵的绘制参数
        /// </summary>
        /// <param name="origin">贴图的中心，以贴图坐标表示</param>
        /// <param name="pos">逻辑位置</param>
        /// <param name="scale">贴图的缩放比（= 逻辑长度/贴图长度）</param>
        /// <param name="rata">逻辑方位角</param>
        /// <param name="color">绘制颜色</param>
        /// <param name="layerDepth">深度，1为最低层，0为最表层</param>
        /// <param name="blendMode">采用的混合模式</param>
        public void SetParameters ( Vector2 origin, Vector2 pos, float scale, float rata, Color color, float layerDepth, SpriteBlendMode blendMode )
        {
            SetParameters( origin, pos, (float)(mTexture.Width) * scale, (float)(mTexture.Height) * scale, rata, color, layerDepth, blendMode );
        }
        #endregion

        #region Update Transform Matrix and Bounding Rectangle

        /// <summary>
        /// 更新精灵的转换矩阵和包围盒
        /// </summary>
        public void UpdateTransformBounding ()
        {
            CalDestinRect();

            mTransform =
                Matrix.CreateTranslation( new Vector3( -Origin, 0f ) ) *
                Matrix.CreateScale( new Vector3( Width / (float)mTexture.Width, Height / (float)mTexture.Height, 1 ) ) *
                Matrix.CreateRotationZ( Rata ) *
                Matrix.CreateTranslation( new Vector3( Pos, 0f ) );

            mBounding = CalculateBoundingRectangle( new Rectangle( 0, 0, mTexture.Width, mTexture.Height ), mTransform );
        }
        #endregion

        #region Calculate Destination Rectangle

        private void CalDestinRect ()
        {
            Vector2 scrnPos = engine.CoordinMgr.ScreenPos( new Vector2( Pos.X, Pos.Y ) );
            mDestiRect.X = (int)scrnPos.X;
            mDestiRect.Y = (int)scrnPos.Y;
            mDestiRect.Width = engine.CoordinMgr.ScrnLength( Width );
            mDestiRect.Height = engine.CoordinMgr.ScrnLength( Height );
        }

        #endregion

        #region Draw Functions

        /// <summary>
        /// 绘制该精灵
        /// </summary>
        public void Draw ()
        {
            if (!mloaded) return;

            CalDestinRect();

            if (BlendMode == SpriteBlendMode.Additive)
            {
                engine.SpriteMgr.additiveSprite.Draw( mTexture, mDestiRect, null, Color, Rata - engine.CoordinMgr.Rota, Origin, SpriteEffects.None, LayerDepth );
            }
            else if (BlendMode == SpriteBlendMode.AlphaBlend)
            {
                engine.SpriteMgr.alphaSprite.Draw( mTexture, mDestiRect, null, Color, Rata - engine.CoordinMgr.Rota, Origin, SpriteEffects.None, LayerDepth );
            }
        }
        #endregion

        #region Intersect Detect Functions

        /// <summary>
        /// Determines if there is overlap of the non-transparent pixels between two
        /// sprites.
        /// 检查两个精灵是否发生碰撞
        /// </summary>
        /// <returns>True if non-transparent pixels overlap; false otherwise</returns>
        public static CollisionResult IntersectPixels ( Sprite spriteA, Sprite spriteB )
        {
            if (!spriteA.mSupportIntersectDect || !spriteB.mSupportIntersectDect)
                throw new Exception( "At lest one of the two sprite doesn't support IntersectDect!" );

            spriteA.UpdateTransformBounding();
            spriteB.UpdateTransformBounding();

            CollisionResult result = new CollisionResult();

            if (!spriteA.mBounding.Intersects( spriteB.mBounding ))
            {
                result.IsCollided = false;
                return result;
            }

            int widthA = spriteA.mTexture.Width;
            int heightA = spriteA.mTexture.Height;
            int widthB = spriteB.mTexture.Width;
            int heightB = spriteB.mTexture.Height;

            // Calculate a matrix which transforms from A's local space into
            // world space and then into B's local space
            Matrix transformAToB = spriteA.mTransform * Matrix.Invert( spriteB.mTransform );

            // When a point moves in A's local space, it moves in B's local space with a
            // fixed direction and distance proportional to the movement in A.
            // This algorithm steps through A one pixel at a time along A's X and Y axes
            // Calculate the analogous steps in B:
            Vector2 stepX = Vector2.TransformNormal( Vector2.UnitX, transformAToB );
            Vector2 stepY = Vector2.TransformNormal( Vector2.UnitY, transformAToB );

            // Calculate the top left corner of A in B's local space
            // This variable will be reused to keep track of the start of each row
            Vector2 oriPosInB = Vector2.Transform( Vector2.Zero, transformAToB );

            CircleList<BorderPoint> list = spriteA.mBorder.BorderCircle;
            CircleListNode<BorderPoint> cur = list.First;

            bool justStart = true;
            bool find = false;

            CircleListNode<BorderPoint> firstNode = cur;
            int length = 0;

            #region 找出第一个相交点和该连续相交线的长度
            for (int i = 0; i < list.Length; i++)
            {
                Point bordPointA = cur.value.p;

                if (SpriteBBlockAtPos( spriteB, oriPosInB, stepX, stepY, bordPointA ))
                {
                    if (!justStart)
                    {
                        if (!find)
                        {
                            find = true;
                            firstNode = cur;
                        }
                        else
                        {
                            length++;
                        }
                    }
                    else
                    {
                        CircleListNode<BorderPoint> temp = cur.pre;
                        while (SpriteBBlockAtPos( spriteB, oriPosInB, stepX, stepY, temp.value.p ) && temp != cur)
                        {
                            temp = temp.pre;
                        }
                        cur = temp;
                        i--;
                        justStart = false;
                    }
                }
                else
                {
                    justStart = false;

                    if (find)
                    {
                        break;
                    }
                }

                cur = cur.next;
            }
            #endregion

            if (find)
            {
                cur = firstNode;

                for (int i = 0; i < Math.Round( (float)length / 2 ); i++)
                {
                    cur = cur.next;
                }

                Point bordPointA = cur.value.p;
                result.IsCollided = true;
                Vector2 InterPos = Vector2.Transform( new Vector2( bordPointA.X, bordPointA.Y ), spriteA.mTransform );
                result.NormalVector = Vector2.Transform( spriteA.mBorder.GetNormalVector( cur, spriteA.mAverageSum ), spriteA.mTransform )
                    - Vector2.Transform( Vector2.Zero, spriteA.mTransform );
                result.NormalVector.Normalize();
                result.InterPos = InterPos;
                return result;
            }


            // No intersection found
            result.IsCollided = false;
            return result;
        }

        /// <summary>
        /// 检测是否在边界矩形外
        /// </summary>
        /// <param name="BorderRect"></param>
        /// <returns></returns>
        public CollisionResult CheckOutBorder ( Rectanglef BorderRect )
        {
            if (!this.mSupportIntersectDect)
                throw new Exception( "the sprite doesn't support IntersectDect!" );

            UpdateTransformBounding();

            CollisionResult result = new CollisionResult();
            Rectanglef screenRect = BorderRect;


            if (!this.mBounding.Intersects( screenRect ))
            {
                result.IsCollided = false;
                return result;
            }

            int widthA = this.mTexture.Width;
            int heightA = this.mTexture.Height;

            // Calculate a matrix which transforms from A's local space into
            // world space
            Matrix transformAToWorld = mTransform;

            Vector2 stepX = Vector2.TransformNormal( Vector2.UnitX, transformAToWorld );
            Vector2 stepY = Vector2.TransformNormal( Vector2.UnitY, transformAToWorld );

            Vector2 oriPosInWorld = Vector2.Transform( Vector2.Zero, transformAToWorld );


            CircleList<BorderPoint> list = mBorder.BorderCircle;
            CircleListNode<BorderPoint> cur = list.First;

            bool justStart = true;
            bool find = false;

            CircleListNode<BorderPoint> firstNode = cur;
            int length = 0;

            #region 找出第一个相交点和该连续相交线的长度
            for (int i = 0; i < list.Length; i++)
            {
                Point bordPointA = cur.value.p;

                if (PointOutBorder( oriPosInWorld, stepX, stepY, bordPointA, screenRect ))
                {
                    if (!justStart)
                    {
                        if (!find)
                        {
                            find = true;
                            firstNode = cur;
                        }
                        else
                        {
                            length++;
                        }
                    }
                    else
                    {
                        CircleListNode<BorderPoint> temp = cur.pre;

                        int leftLength = list.Length;
                        while (PointOutBorder( oriPosInWorld, stepX, stepY, temp.value.p, screenRect ) && leftLength >= 0)
                        {
                            temp = temp.pre;
                            leftLength--;
                        }
                        cur = temp;
                        i--;
                        justStart = false;
                    }
                }
                else
                {
                    justStart = false;

                    if (find)
                    {
                        break;
                    }
                }

                cur = cur.next;
            }
            #endregion

            if (find)
            {
                cur = firstNode;

                for (int i = 0; i < Math.Round( (float)length / 2 ); i++)
                {
                    cur = cur.next;
                }

                Point bordPointA = cur.value.p;
                result.IsCollided = true;
                Vector2 InterPos = Vector2.Transform( new Vector2( bordPointA.X, bordPointA.Y ), mTransform );
                result.NormalVector = Vector2.Transform( mBorder.GetNormalVector( cur, mAverageSum ), mTransform )
                    - Vector2.Transform( Vector2.Zero, mTransform );
                result.NormalVector.Normalize();
                result.InterPos = InterPos;
                return result;
            }


            // No intersection found
            result.IsCollided = false;
            return result;
        }

        private bool PointOutBorder ( Vector2 oriPosInWorld, Vector2 stepX, Vector2 stepY, Point bordPointA, Rectanglef screenRect )
        {
            Vector2 PInWorld = oriPosInWorld + bordPointA.X * stepX + bordPointA.Y * stepY;

            int xW = (int)(PInWorld.X);
            int yW = (int)(PInWorld.Y);

            if (screenRect.Contains( new Vector2( xW, yW ) ))
                return false;
            else
                return true;
        }

        private static bool SpriteBBlockAtPos ( Sprite spriteB, Vector2 oriPosInB, Vector2 stepX, Vector2 stepY, Point bordPointA )
        {
            Vector2 bPInB = oriPosInB + bordPointA.X * stepX + bordPointA.Y * stepY;

            int xB = (int)(bPInB.X);
            int yB = (int)(bPInB.Y);

            if (xB < 0 || xB >= spriteB.mTexture.Width || yB < 0 || yB >= spriteB.mTexture.Height)
                return false;
            else
                return spriteB.mTextureData[xB + yB * spriteB.mTexture.Width];
        }

        /// <summary>
        /// Calculates an axis aligned rectangle which fully contains an arbitrarily
        /// transformed axis aligned rectangle.
        /// </summary>
        /// <param name="rectangle">Original bounding rectangle.</param>
        /// <param name="transform">World transform of the rectangle.</param>
        /// <returns>A new rectangle which contains the trasnformed rectangle.</returns>
        private static Rectanglef CalculateBoundingRectangle ( Rectangle rectangle, Matrix transform )
        {
            // Get all four corners in local space
            Vector2 leftTop = new Vector2( rectangle.Left, rectangle.Top );
            Vector2 rightTop = new Vector2( rectangle.Right, rectangle.Top );
            Vector2 leftBottom = new Vector2( rectangle.Left, rectangle.Bottom );
            Vector2 rightBottom = new Vector2( rectangle.Right, rectangle.Bottom );

            // Transform all four corners into work space
            Vector2.Transform( ref leftTop, ref transform, out leftTop );
            Vector2.Transform( ref rightTop, ref transform, out rightTop );
            Vector2.Transform( ref leftBottom, ref transform, out leftBottom );
            Vector2.Transform( ref rightBottom, ref transform, out rightBottom );

            // Find the minimum and maximum extents of the rectangle in world space
            Vector2 min = Vector2.Min( Vector2.Min( leftTop, rightTop ),
                                      Vector2.Min( leftBottom, rightBottom ) );
            Vector2 max = Vector2.Max( Vector2.Max( leftTop, rightTop ),
                                      Vector2.Max( leftBottom, rightBottom ) );

            // Return that as a rectangle
            return new Rectanglef( min.X, min.Y, (max.X - min.X), (max.Y - min.Y) );
        }

        #endregion

        #region Dispose

        /// <summary>
        /// 清理资源
        /// </summary>
        public void Dispose ()
        {
            if (mTexture != null)
                mTexture.Dispose();
            mTexture = null;
            mTextureData = null;
            //mTextureBoundData = null;
            mloaded = false;
        }

        #endregion
    }


}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using TankEngine2D.Helpers;

namespace SmartTank.Effects
{
    /// <summary>
    /// 实现了振动特效
    /// </summary>
    public static class Quake
    {
        #region Variables
        static bool sStarted = false;

        static float sStrength;

        static int sSumFrame;
        static int sRePlatformsFrame;

        static float sAx;
        static float sAy;
        static float sVx;
        static float sVy;
        static float sStrX;
        static float sStrY;
        static float sDeltaX;
        static float sDeltaY;

        static float sAtten;
        static float sCurRate;
        static float sCrest;

        static Rectangle orignScrnRect;
        #endregion

        #region Begin Quake

        /// <summary>
        /// 开始振动
        /// </summary>
        /// <param name="strengh">振动强度</param>
        /// <param name="sumFrame">振动持续的帧数</param>
        static public void BeginQuake ( float strengh, int sumFrame )
        {
            if (sumFrame <= 0)
                throw new Exception( "the value of sumFrame should biger than 0!" );

            strengh = Math.Abs( strengh );

            if (sStarted)
            {
                BaseGame.CoordinMgr.SetScreenViewRect( orignScrnRect );
            }

            sStarted = true;
            sStrength = strengh;
            sCurRate = 1f;

            sSumFrame = sumFrame;
            sRePlatformsFrame = sumFrame;
            orignScrnRect = BaseGame.CoordinMgr.ScrnViewRect;

            sStrX = strengh * RandomHelper.GetRandomFloat( -1f, 1f );
            sStrY = strengh * RandomHelper.GetRandomFloat( -1f, 1f );

            sAx = strengh * RandomHelper.GetRandomFloat( -0.7f, 0.7f );
            sAy = strengh * RandomHelper.GetRandomFloat( -0.7f, 0.7f );

            sVx = strengh * RandomHelper.GetRandomFloat( -0.7f, 0.7f );
            sVy = strengh * RandomHelper.GetRandomFloat( -0.7f, 0.7f );

            sAtten = 6 / (float)sumFrame;
            sCrest = 1;
        }
        #endregion

        #region Stop Quake

        /// <summary>
        /// 停止振动
        /// </summary>
        static public void StopQuake ()
        {
            sStarted = false;
            BaseGame.CoordinMgr.SetScreenViewRect( orignScrnRect );
        } 
        #endregion

        #region Update

        /// <summary>
        /// 更新，已经由BaseGame类管理。
        /// </summary>
        static internal void Update ()
        {
            if (sStarted)
            {
                if (sRePlatformsFrame <= 0)
                {
                    sStarted = false;
                    BaseGame.CoordinMgr.SetScreenViewRect( orignScrnRect );
                    return;
                }
                else
                {
                    Next();
                    Rectangle curScrnViewRect =
                        new Rectangle( orignScrnRect.X + (int)sDeltaX,
                                        orignScrnRect.Y + (int)sDeltaY,
                                        orignScrnRect.Width,
                                        orignScrnRect.Height );

                    BaseGame.CoordinMgr.SetScreenViewRect( curScrnViewRect );
                    sRePlatformsFrame--;
                }
            }


        } 
        #endregion

        #region private Functions
        static void Next ()
        {
            sAx = -sStrX ;
            sVx += sAx;
            sStrX += sVx;

            sAy = -sStrY;
            sVy += sAy;
            sStrY += sVy;

            sCurRate -= sAtten;
            if (sCurRate < 0.2)
            {
                sCrest -= 0.167f;
                if (sCrest < 0) sCrest = 0;
                sCurRate = sCrest;
            }

            sDeltaX = sStrX * sCurRate;
            sDeltaY = sStrY * sCurRate;

        } 
        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using System.Xml.Serialization;
using System.IO;
using TankEngine2D.Helpers;
using System.Collections;
using System.Xml;

namespace SmartTank.GameObjs
{
    public class GameObjDataNode : IEnumerable<GameObjDataNode>
    {
        public string nodeName;
        public List<string> texPaths;
        public List<Vector2> visiKeyPoints;
        public List<Vector2> structKeyPoints;

        // 暂时只添加这两类数据格式
        public List<int> intDatas;
        public List<float> floatDatas;

        public GameObjDataNode parent;
        public List<GameObjDataNode> childNodes;

        public GameObjDataNode()
        {
            texPaths = new List<string>();
            visiKeyPoints = new List<Vector2>();
            structKeyPoints = new List<Vector2>();
            childNodes = new List<GameObjDataNode>();

            intDatas = new List<int>();
            floatDatas = new List<float>();
        }

        public GameObjDataNode( string nodeName )
            : this( nodeName, null )
        {
        }

        public GameObjDataNode( string nodeName, GameObjDataNode parent )
            : this()
        {
            this.nodeName = nodeName;
            this.parent = parent;
        }

        #region IEnumerable<GameObjDataNode> 成员

        /// <summary>
        /// 采用前序遍历
        /// </summary>
        /// <returns></returns>
        public IEnumerator<GameObjDataNode> GetEnumerator()
        {
            yield return this;

            if (childNodes != null)
            {
                foreach (GameObjDataNode childNode in childNodes)
                {
                    foreach (GameObjDataNode node in childNode)
                    {
                        yield return node;
                    }
                }
            }
        }



        #endregion

        #region IEnumerable 成员

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion

        public void WriteToXML( XmlWriter writer )
        {
            writer.WriteStartElement( "GameObjDataNode" );

            writer.WriteElementString( "NodeName", nodeName );

            writer.WriteStartElement( "TexPaths" );
            writer.WriteElementString( "count", texPaths.Count.ToString() );
            foreach (string texPath in texPaths)
            {
                writer.WriteElementString( "string", texPath );
            }
            writer.WriteEndElement();

            writer.WriteStartElement( "VisiKeyPoints" );
            writer.WriteElementString( "count", visiKeyPoints.Count.ToString() );
            foreach (Vector2 visiPoint in visiKeyPoints)
            {
                writer.WriteStartElement( "Vector2" );
                writer.WriteElementString( "X", visiPoint.X.ToString() );
                writer.WriteElementString( "Y", visiPoint.Y.ToString() );
                writer.WriteEndElement();
            }
            writer.WriteEndElement();

            writer.WriteStartElement( "StructKeyPoints" );
            writer.WriteElementString( "count", structKeyPoints.Count.ToString() );
            foreach (Vector2 structPoint in structKeyPoints)
            {
                writer.WriteStartElement( "Vector2" );
                writer.WriteElementString( "X", structPoint.X.ToString() );
                writer.WriteElementString( "Y", structPoint.Y.ToString() );
                writer.WriteEndElement();
            }
            writer.WriteEndElement();

            writer.WriteStartElement( "intDatas" );
            writer.WriteElementString( "count", intDatas.Count.ToString() );
            foreach (int i in intDatas)
            {
                writer.WriteElementString( "int", i.ToString() );
            }
            writer.WriteEndElement();

            writer.WriteStartElement( "floatDatas" );
            writer.WriteElementString( "count", floatDatas.Count.ToString() );
            foreach (float f in floatDatas)
            {
                writer.WriteElementString( "float", f.ToString() );
            }
            writer.WriteEndElement();

            writer.WriteStartElement( "Childs" );
            writer.WriteElementString( "count", childNodes.Count.ToString() );
            foreach (GameObjDataNode child in childNodes)
            {
                child.WriteToXML( writer );
            }
            writer.WriteEndElement();

            writer.WriteEndElement();
        }

        static public GameObjDataNode ReadFromXML( XmlReader reader )
        {
            GameObjDataNode result = new GameObjDataNode();

            reader.ReadStartElement( "GameObjDataNode" );

            result.nodeName = reader.ReadElementString( "NodeName" );

            reader.ReadStartElement( "TexPaths" );
            int countTex = int.Parse( reader.ReadElementString( "count" ) );
            for (int i = 0; i < countTex; i++)
            {
                result.texPaths.Add( reader.ReadElementString( "string" ) );
            }
            reader.ReadEndElement();

            reader.ReadStartElement( "VisiKeyPoints" );
            int countVisi = int.Parse( reader.ReadElementString( "count" ) );
            for (int i = 0; i < countVisi; i++)
            {
                reader.ReadStartElement( "Vector2" );
                float x = float.Parse( reader.ReadElementString( "X" ) );
                float y = float.Parse( reader.ReadElementString( "Y" ) );
                reader.ReadEndElement();

                result.visiKeyPoints.Add( new Vector2( x, y ) );
            }
            reader.ReadEndElement();

            reader.ReadStartElement( "StructKeyPoints" );
            int countStruct = int.Parse( reader.ReadElementString( "count" ) );
            for (int i = 0; i < countStruct; i++)
            {
                reader.ReadStartElement( "Vector2" );
                float x = float.Parse( reader.ReadElementString( "X" ) );
                float y = float.Parse( reader.ReadElementString( "Y" ) );
                reader.ReadEndElement();

                result.structKeyPoints.Add( new Vector2( x, y ) );
            }
            reader.ReadEndElement();

            reader.ReadStartElement( "intDatas" );
            int countInt = int.Parse( reader.ReadElementString( "count" ) );
            for (int i = 0; i < countInt; i++)
            {
                result.intDatas.Add( int.Parse( reader.ReadElementString( "int" ) ) );
            }
            reader.ReadEndElement();

            reader.ReadStartElement( "floatDatas" );
            int countFloat = int.Parse( reader.ReadElementString( "count" ) );
            for (int i = 0; i < countFloat; i++)
            {
                result.floatDatas.Add( float.Parse( reader.ReadElementString( "float" ) ) );
            }
            reader.ReadEndElement();

            reader.ReadStartElement( "Childs" );
            int countChild = int.Parse( reader.ReadElementString( "count" ) );
            for (int i = 0; i < countChild; i++)
            {
                result.childNodes.Add( GameObjDataNode.ReadFromXML( reader ) );
            }
            reader.ReadEndElement();

            reader.ReadEndElement();

            return result;
        }
    }

    public class GameObjData
    {
        #region statics

        static public void Save( Stream stream, GameObjData data )
        {
            try
            {
                XmlWriterSettings setting = new XmlWriterSettings();
                setting.Indent = true;
                XmlWriter writer = XmlWriter.Create( stream, setting );

                writer.WriteStartElement( "GameObjData" );
                writer.WriteElementString( "Name", data.name );
                writer.WriteElementString( "Creater", data.creater );
                writer.WriteElementString( "Year", data.year.ToString() );
                writer.WriteElementString( "Month", data.month.ToString() );
                writer.WriteElementString( "Day", data.day.ToString() );

                data.baseNode.WriteToXML( writer );

                writer.WriteEndElement();

                writer.Flush();
            }
            catch (Exception e)
            {
                Log.Write( "Save GameObjData error!" + e.Message );
            }
            finally
            {
                stream.Close();
            }
        }

        static public GameObjData Load( Stream stream )
        {
            GameObjData result = new GameObjData();

            try
            {
                XmlReader reader = XmlReader.Create( stream );

                reader.ReadStartElement( "GameObjData" );
                result.name = reader.ReadElementString( "Name" );
                result.creater = reader.ReadElementString( "Creater" );
                result.year = int.Parse( reader.ReadElementString( "Year" ) );
                result.month = int.Parse( reader.ReadElementString( "Month" ) );
                result.day = int.Parse( reader.ReadElementString( "Day" ) );

                result.baseNode = GameObjDataNode.ReadFromXML( reader );

                reader.ReadEndElement();
            }
            catch (Exception)
            {
                Log.Write( "Load GameObjData error!" );
            }
            finally
            {
                stream.Close();
            }

            return result;
        }

        #endregion

        public string name;
        public string creater;
        public int year;
        public int month;
        public int day;

        public GameObjDataNode baseNode;

        public GameObjDataNode this[int index]
        {
            get
            {
                int i = 0;
                foreach (GameObjDataNode node in baseNode)
                {
                    if (i == index)
                        return node;
                    i++;
                }
                return null;
            }
        }

        public GameObjData()
        {

        }

        public GameObjData( string objName )
        {
            this.name = objName;
            //this.baseNode = new GameObjDataNode( "Base", null );
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Audio;
using TankEngine2D.Helpers;
using System.IO;
using SmartTank.Helpers;

namespace SmartTank.Sounds
{
    public static class Sound
    {
        static AudioEngine audioEngine;
        
        static WaveBank waveBank;
        
        static SoundBank soundBank;

        public static void Initial()
        {
            try
            {
                string dir = Directories.SoundDirectory;
                audioEngine = new AudioEngine( Path.Combine( dir, "SmartTank1.xgs" ) );
                waveBank = new WaveBank( audioEngine, Path.Combine( dir, "Wave Bank.xwb" ) );

                if (waveBank != null)
                {
                    soundBank = new SoundBank( audioEngine,
                        Path.Combine( dir, "Sound Bank.xsb" ) );
                }
                
            }
            catch (NoAudioHardwareException ex)
            {
                Log.Write( "Failed to create sound class: " + ex.ToString() );
            }
        }


        public static void PlayCue ( string cueName )
        {
            soundBank.PlayCue( cueName );
        }

        internal static void Clear ()
        {
            audioEngine.GetCategory( "Default" ).Stop( AudioStopOptions.Immediate );
        }
    }
}
<file_sep>    using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.Draw
{
    /*
     *  当前一些绘制物的深度
     *
     *
     *  场景物体：			深度
     *
     *  文字				0.1
     *
     *  界面				0.15
     *  
     *  炮弹				0.4
     *
     *  地面物体			0.5~0.65
     * 
	 *  坦克			    0.6~0.65
     *
     *  坦克雷达			0.9
     *
     *  地面				0.95
     * 
     * */


    public static class LayerDepth
    {
        public static readonly float Mouse = 0.05f;

        public static readonly float Text = 0.1f;

        public static readonly float UI = 0.15f;

        public static readonly float EffectLow = 0.3f;

        public static readonly float Shell = 0.4f;

        public static readonly float TankTurret = 0.6f;

        public static readonly float TankBase = 0.65f;

        public static readonly float GroundObj = 0.66f;

        public static readonly float TankRader = 0.9f;

        public static readonly float BackGround = 0.95f;


    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.AI
{
    /*
     * 设置该属性的目的在于使低层AI可以用作高层AI
     * 
     * 但同时保证这样的使用局限在这样一种情况下：
     * 
     * 高层AI使用的OrderServer类是从低层AI使用的OrderServer类中继承而来的。
     * 
     * */

    [AttributeUsage( AttributeTargets.Interface, Inherited = false )]
    public class IAIAttribute : Attribute
    {
        public Type OrderServerType;
        public Type CommonServerType;

        public IAIAttribute ( Type orderServerType, Type commonServerType )
        {
            this.OrderServerType = orderServerType;
            this.CommonServerType = commonServerType;
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using SmartTank.PhiCol;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework;
using TankEngine2D.Helpers;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.Scene;
using SmartTank.GameObjs;
using TankEngine2D.DataStructure;
using SmartTank.Helpers;
using SmartTank.Draw;

namespace SmartTank.GameObjs.Shell
{
    public class ShellNormal : IGameObj, ICollideObj, IPhisicalObj
    {
        readonly string texPath = "GameObjs\\ShellNormal";

        public event OnCollidedEventHandler onCollided;
        public event OnCollidedEventHandler onOverlap;

        string name;

        GameObjInfo objInfo = new GameObjInfo( "ShellNormal", string.Empty );

        IGameObj firer;

        Sprite sprite;

        NonInertiasColUpdater phiUpdater;

        public float Azi
        {
            get { return sprite.Rata; }
        }

        public IGameObj Firer
        {
            get { return firer; }
        }

        public ShellNormal( string name, IGameObj firer, Vector2 startPos, float startAzi, float speed )
        {
            this.name = name;
            this.firer = firer;
            sprite = new Sprite( BaseGame.RenderEngine, BaseGame.ContentMgr, Path.Combine( Directories.ContentDirectory, texPath ), true );
            sprite.SetParameters( new Vector2( 5, 0 ), startPos, 0.08f, startAzi, Color.White, LayerDepth.Shell, SpriteBlendMode.AlphaBlend );
            phiUpdater = new NonInertiasColUpdater( ObjInfo, startPos, MathTools.NormalVectorFromAzi( startAzi ) * speed, startAzi, 0f, new Sprite[] { sprite } );
            phiUpdater.OnOverlap += new OnCollidedEventHandler( phiUpdater_OnOverlap );
            phiUpdater.OnCollied += new OnCollidedEventHandler( phiUpdater_OnCollied );
        }

        void phiUpdater_OnCollied( IGameObj Sender, CollisionResult result, GameObjInfo objB )
        {
            if (onCollided != null)
                onCollided( this, result, objB );
        }

        void phiUpdater_OnOverlap( IGameObj Sender, CollisionResult result, GameObjInfo objB )
        {
            //if (objB.ObjClass == "Border")
            //{
            //    ((SceneKeeperCommon)(GameManager.CurSceneKeeper)).RemoveGameObj( this, true, false, false, false, SceneKeeperCommon.GameObjLayer.lowFlying );
            //}

            if (onOverlap != null)
                onOverlap( this, result, objB );
        }


        #region IGameObj 成员

        public GameObjInfo ObjInfo
        {
            get { return objInfo; }
        }
        public Vector2 Pos
        {
            get { return phiUpdater.Pos; }
            set { phiUpdater.Pos = value; }
        }

        #endregion

        #region IUpdater 成员

        public void Update( float seconds )
        {

        }

        #endregion

        #region IDrawable 成员

        public void Draw()
        {
            sprite.Pos = phiUpdater.Pos;
            sprite.Draw();
        }

        #endregion

        #region ICollideObj 成员


        public IColChecker ColChecker
        {
            get { return phiUpdater; }
        }

        #endregion

        #region IPhisicalObj 成员

        public IPhisicalUpdater PhisicalUpdater
        {
            get { return phiUpdater; }
        }

        #endregion

        #region IHasBorderObj 成员

        public CircleList<BorderPoint> BorderData
        {
            get { return sprite.BorderData; }
        }

        public Matrix WorldTrans
        {
            get { return sprite.Transform; }
        }

        public Rectanglef BoundingBox
        {
            get { return sprite.BoundRect; }
        }

        #endregion

        #region IGameObj 成员

        public string Name
        {
            get { return name; }
        }

        #endregion
    }
}
<file_sep>//=================================================
// xWinForms
// Copyright ?2007 by <NAME>
// http://psycad007.spaces.live.com/
//=================================================
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TankEngine2D.Graphics;
namespace SmartTank.Draw.UI.Controls
{
    public class Label : Control
    {

        public Color color = Color.Black;
        public float scale = 1f;

        public Label( string name, Vector2 position, string text, Color color, float scale )//, Font font)
        {
            this.Type = ControlType.Label;
            this.name = name;
            this.position = position;
            this.text = text;
            this.scale = scale;
            this.color = new Color( new Vector4( color.ToVector3(), 1f ) );
        }

        #region Old Code
        //public override void Update(Vector2 formPosition, Vector2 formSize)
        //{
        //    base.Update(formPosition, formSize);
        //    CheckVisibility(formPosition, formSize);
        //} 
        #endregion

        private void CheckVisibility( Vector2 formPosition, Vector2 formSize )
        {
            if (position.X + name.Length * 9f > formPosition.X + formSize.X - 15f)
                bVisible = false;
            else if (position.Y + 15f > formPosition.Y + formSize.Y - 25f)
                bVisible = false;
            else
                bVisible = true;
        }

        public override void Draw( SpriteBatch spriteBatch, float alpha )
        {
            Color dynamicColor = new Color( new Vector4( color.ToVector3(), alpha ) );
            //font.Draw(text, position, scale, dynamicColor, spriteBatch);
            BaseGame.FontMgr.DrawInScrnCoord( text, position, scale, dynamicColor, 0f, fontName );
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using SmartTank.AI;
using SmartTank.AI.AIHelper;
using SmartTank.Senses.Memory;
using SmartTank.Shelter;
using TankEngine2D.Input;
using SmartTank;
using SmartTank.Scene;
using SmartTank.Senses.Vision;
using TankEngine2D.DataStructure;
using TankEngine2D.Graphics;
using SmartTank.Draw;

namespace InterRules.FindPath
{
    [AIAttribute( "PathFinder No.2", "SmartTank编写组", "测试AI的寻路能力", 2007, 11, 23 )]
    class PathFinderSecond : IAISinTur
    {
        IAIOrderServerSinTur orderServer;

        AICommonServer commonServer;

        AIActionHelper action;

        NavigateMap naviMap;

        bool seeItem = false;
        bool itemDisappeared = false;

        #region IAI 成员

        public IAICommonServer CommonServer
        {
            set { commonServer = (AICommonServer)value; }
        }

        public IAIOrderServer OrderServer
        {
            set
            {
                orderServer = (IAIOrderServerSinTur)value;
                action = new AIActionHelper( orderServer );
                orderServer.onBorderObjUpdated += new BorderObjUpdatedEventHandler( orderServer_onBorderObjUpdated );
            }
        }

        void orderServer_onBorderObjUpdated ( EyeableBorderObjInfo[] borderObjInfos )
        {
        }

        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            if (InputHandler.IsKeyDown( Keys.W ))
            {
                orderServer.ForwardSpeed = 1000;
            }
            else if (InputHandler.IsKeyDown( Keys.S ))
            {
                orderServer.ForwardSpeed = -1000;
            }
            else
            {
                orderServer.ForwardSpeed = 0;
            }

            if (InputHandler.IsKeyDown( Keys.D ))
            {
                orderServer.TurnRightSpeed = 20;
            }
            else if (InputHandler.IsKeyDown( Keys.A ))
            {
                orderServer.TurnRightSpeed = -20;
            }
            else
            {
                orderServer.TurnRightSpeed = 0;
            }


            if (InputHandler.MouseJustPressRight)
            {
                action.AddOrder( new OrderRotaRaderToPos( InputHandler.GetCurMousePosInLogic( BaseGame.RenderEngine ) ) );
            }

            action.AddOrder( new OrderRotaTurretToPos( InputHandler.GetCurMousePosInLogic( BaseGame.RenderEngine ) ) );


            //if (InputHandler.JustPressKey( Keys.C ))
            //{
            foreach (EyeableBorderObjInfo borderObj in orderServer.EyeableBorderObjInfos)
            {
                borderObj.UpdateConvexHall( 10 );
            }
            //}

            //if (InputHandler.JustPressKey( Keys.N ))
            //{

            naviMap = orderServer.CalNavigateMap(
                delegate( EyeableBorderObjInfo obj )
                {
                    //if (((SceneCommonObjInfo)(obj.EyeableInfo.ObjInfo.SceneInfo)).isTankObstacle)
                        return true;
                    //else
                        //return false;
                }, commonServer.MapBorder, 5 );
            //}

            action.Update( seconds );

            itemDisappeared = false;
            foreach (EyeableBorderObjInfo borderObjInfo in orderServer.EyeableBorderObjInfos)
            {
                if (borderObjInfo.EyeableInfo.ObjInfo.ObjClass == "Item")
                {
                    if (borderObjInfo.IsDisappeared)
                        itemDisappeared = true;
                }
            }

            seeItem = false;
            foreach (IEyeableInfo eyeableInfo in orderServer.GetEyeableInfo())
            {
                if (eyeableInfo.ObjInfo.ObjClass == "Item")
                {
                    seeItem = true;
                }
            }
        }

        #endregion

        #region IAI 成员


        public void Draw ()
        {
            if (naviMap != null)
            {
                foreach (GraphPoint<NaviPoint> naviPoint in naviMap.Map)
                {
                    BaseGame.BasicGraphics.DrawPoint( naviPoint.value.Pos, 1f, Color.Yellow, 0.1f );

                    foreach (GraphPath<NaviPoint> path in naviPoint.neighbors)
                    {
                        BaseGame.BasicGraphics.DrawLine( naviPoint.value.Pos, path.neighbor.value.Pos, 3f, Color.Yellow, 0.1f );
                        BaseGame.FontMgr.Draw( path.weight.ToString(), 0.5f * (naviPoint.value.Pos + path.neighbor.value.Pos), 0.5f, Color.Black, 0f, GameFonts.Comic );
                    }
                }

                foreach (Segment guardLine in naviMap.GuardLines)
                {
                    BaseGame.BasicGraphics.DrawLine( guardLine.startPoint, guardLine.endPoint, 3f, Color.Red, 0f, SpriteBlendMode.AlphaBlend );
                }
            }

            if (seeItem)
                BaseGame.FontMgr.Draw( "I see Item!", orderServer.Pos, 1f, Color.Black, 0f, GameFonts.Lucida );

            if (itemDisappeared)
                BaseGame.FontMgr.Draw( "Item Disappeared!", orderServer.Pos - new Vector2( 0, 10 ), 1f, Color.Black, 0f, GameFonts.Lucida );
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.GameObjs;

namespace MapEditor
{
    public partial class ProperityEditer : DataGridView
    {
        #region TypeDefine

        class Element
        {
            public string name;
            public object value;
            public Type valueType;

            public string Name
            {
                get { return name; }
                set { name = value; }
            }

            public object Value
            {
                get { return value; }
                set { this.value = value; }
            }

            public Element ( string name, object value )
            {
                this.name = name;
                this.value = value;
                this.valueType = value.GetType();
            }
        }

        class ProperityList
        {
            IGameObj obj;
            List<Element> list;

            public List<Element> List
            {
                get { return list; }
            }

            public ProperityList ( IGameObj obj )
            {
                this.obj = obj;
                list = new List<Element>();

                UpdateList();
            }

            public void UpdateList ()
            {
                Type type = obj.GetType();

                list = new List<Element>();
                foreach (PropertyInfo info in type.GetProperties())
                {
                    if (info.GetCustomAttributes( typeof( EditableProperty ), false ).Length != 0)
                    {
                        list.Add( new Element( info.Name, info.GetValue( obj, null ) ) );
                    }
                }
            }

            public void UpdateData ()
            {
                foreach (Element ele in list)
                {
                    PropertyInfo info = obj.GetType().GetProperty( ele.name );
                    info.SetValue( obj, ConvertData( ele.valueType, ele.value ), null );
                }
            }

            private object ConvertData ( Type type, object value )
            {
                try
                {
                    if (value is string)
                    {
                        string sValue = (string)value;
                        if (type.Name == "Vector2")
                        {
                            string[] values;
                            values = sValue.Split( ':', 'Y', ':', '}' );
                            Vector2 result = new Vector2( float.Parse( values[1] ), float.Parse( values[3] ) );
                            return result;
                        }
                        else if (type.Name == "Color")
                        {
                            string[] values;
                            values = sValue.Split( ':', 'G', ':', 'B', ':', 'A', ':', '}' );
                            Color result = new Color( byte.Parse( values[1] ), byte.Parse( values[3] ), byte.Parse( values[5] ), byte.Parse( values[7] ) );
                            return result;
                        }
                        else if (type.Name == "Single")
                        {
                            return float.Parse( sValue );
                        }
                    }
                    else
                        return Convert.ChangeType( value, type );

                    throw new Exception();
                }
                catch (Exception)
                {
                    // 在此添加异常处理
                    throw;
                }
            }

            public Type GetTypeAt ( int index )
            {
                return list[index].valueType;
            }
        }

        #endregion

        IGameObj obj;
        ProperityList properityList;

        public ProperityEditer ()
        {
            InitializeComponent();
            InitializeDataGridView();
        }

        private void InitializeDataGridView ()
        {
            // 在此设定外观
        }

        public void SetObj ( IGameObj obj )
        {
            this.obj = obj;
            this.properityList = new ProperityList( obj );

            this.DataSource = properityList.List;
        }

        public void ClearObj ()
        {
            this.obj = null;
            this.properityList = null;
        }

        protected override void OnCellBeginEdit ( DataGridViewCellCancelEventArgs e )
        {
            base.OnCellBeginEdit( e );

            if (properityList != null)
            {
                Type type = properityList.GetTypeAt( e.RowIndex );

                // 在此添加对不同类型变量的格外处理过程
            }
        }

        protected override void OnCellValueChanged ( DataGridViewCellEventArgs e )
        {
            base.OnCellValueChanged( e );

            if (properityList != null)
            {
                properityList.UpdateData();
                properityList.UpdateList();
            }
        }
    }
}
<file_sep>#include "Team5_DB.h"
#include <cstdio>
#include <cstring>

int Team5_DB::Connect()
{
	mysql = mysql_init(NULL);
	if (!mysql_real_connect(mysql, NULL, "root", NULL, NULL, 0, NULL, 0))
	{
		return -1;	
	}
	if (mysql_select_db(mysql, "mmogfps_5"))
	{
		return -1;
	}
	return 0;
}

void Team5_DB::Disconnect()
{
	mysql_close(mysql);
	mysql_library_end();
}

int Team5_DB::Reset()
{
	mysql_query(mysql, "DROP TABLE UserData");
	if (mysql_query(mysql, "CREATE TABLE UserData (ID BIGINT(12) NOT NULL AUTO_INCREMENT PRIMARY KEY, Name char(50) unique, Password char(50), Score int) ENGINE=INNODB AUTO_INCREMENT = 0"))
	{
		printf("Reset Error\n");
		return -1;
	}
	return 0;
}

int Team5_DB::AddUserItem(char *Name, char *Password, int StartScore)
{
	sprintf(buffer, "INSERT INTO UserData (Name, Password, Score) VALUES ('%s', '%s', %d)", Name, Password, StartScore);
	if (mysql_query(mysql, buffer))
	{
		printf("AddUserItem Error\n");
		return -1;
	}
	return 0;
}

int Team5_DB::DeleteUserItem(char *Name)
{
	sprintf(buffer, "DELETE FROM UserData WHERE Name = '%s'", Name);
	if (mysql_query(mysql, buffer))
	{
		printf("DeleteUserItem Error\n");
		return -1;
	}
	return 0;
}

int Team5_DB::SetUserName(char *Name, char *NewName)
{
	sprintf(buffer, "UPDATE UserData SET Name = '%s' WHERE Name = '%s'", NewName, Name);
	if (mysql_query(mysql, buffer))
	{
		printf("SetUserName Error\n");
		return -1;
	}
	return 0;
}

int Team5_DB::SetUserPassword(char *Name, char *NewPassword)
{
	sprintf(buffer, "UPDATE UserData SET Password = '%s' WHERE Name = '%s'", NewPassword, Name);
	if (mysql_query(mysql, buffer))
	{
		printf("SetUserPassword Error\n");
		return -1;
	}
	return 0;
}

int Team5_DB::SetUserScore(char *Name, int Score)
{
	sprintf(buffer, "UPDATE UserData SET Score = %d WHERE Name = '%s'", Score, Name);
	if (mysql_query(mysql, buffer))
	{
		printf("SetUserScore Error\n");
		return -1;
	}
	return 0;
}

int Team5_DB::GetUserPassword(char *Name, char *RetPassword)
{
	sprintf(buffer, "select Password from UserData where Name = '%s'", Name);
	if (mysql_query(mysql, buffer))
	{
		printf("User is not exist...\n");
		return -1;
	}

	result = mysql_use_result(mysql);
	if (!result)
	{
		printf("GetUserPassword Error\n");
		return -1;
	}

	row = mysql_fetch_row(result) ;
	if (!row)
	{
		printf("GetUserPassword Error\n");
		return -1;
	}

	strcpy(RetPassword, row[0]);
	mysql_free_result(result);
	return 0;
}

int Team5_DB::GetUserScore(char *Name)
{
	int score;

	sprintf(buffer, "select Score from UserData where Name = '%s'", Name);
	if (mysql_query(mysql, buffer))
	{
		printf("User is not exist...\n");
		return -1;
	}

	result = mysql_use_result(mysql);
	if (!result)
	{
		printf("GetUserScore Error\n");
		return -1;
	}

	row = mysql_fetch_row(result) ;
	if (!row)
	{
		printf("GetUserScore Error\n");
		return -1;
	}

	score = atoi(row[0]);
	mysql_free_result(result);
	return score;
}

int Team5_DB::GetUserID(char *Name)
{
	int id;

	sprintf(buffer, "select ID from UserData where Name = '%s'", Name);
	if (mysql_query(mysql, buffer))
	{
		printf("User is not exist...\n");
		return -1;
	}

	result = mysql_use_result(mysql);
	if (!result)
	{
		printf("GetUserID Error\n");
		return -1;
	}

	row = mysql_fetch_row(result) ;
	if (!row)
	{
		printf("GetUserID Error\n");
		return -1;
	}

	id = atoi(row[0]);
	mysql_free_result(result);
	return id;
}

int Team5_DB::GetUserCount()
{
	int count;

	if (mysql_query(mysql, "SELECT COUNT(*) FROM UserData"))
	{
		printf("GetUserCount Error\n");
		return -1;
	}

	result = mysql_use_result(mysql);
	if (!result)
	{
		printf("GetUserCount Error\n");
		return -1;
	}

	row = mysql_fetch_row(result) ;
	if (!row)
	{
		printf("GetUserCount Error\n");
		return -1;
	}

	count = atoi(row[0]);
	mysql_free_result(result);
	return count;
}

int Team5_DB::GetRankList(int m, int n, RankInfo *RetPage)
{
	int count = 0;

	sprintf(buffer, "SELECT Name, Score FROM UserData ORDER BY Score DESC limit %d,%d", m, n);
	if (mysql_query(mysql, buffer))
	{
		printf("GetRankList Error\n");
		return -1;
	}

	result = mysql_use_result(mysql);
	if (!result)
	{
		printf("GetRankList Error\n");
		return -1;
	}

	row = mysql_fetch_row(result);

	for (int r = m + count + 1; row != NULL; ++count, ++r)
	{
		strcpy(RetPage[count].Name, (char *)row[0]);
		RetPage[count].Score = atoi(row[1]);
		if (count != 0 && RetPage[count].Score == RetPage[count - 1].Score)
		{
			RetPage[count].Rank = RetPage[count - 1].Rank;
		}
		else
		{
			RetPage[count].Rank = r;
		}
		row = mysql_fetch_row(result);
	}

	mysql_free_result(result);
	return count;
}

int Team5_DB::GetUserList(int m, int n, UserInfo *RetPage)
{
	int count = 0;

	sprintf(buffer, "SELECT ID, Name, Password, Score FROM UserData");
	if (mysql_query(mysql, buffer))
	{
		printf("GetUserList Error\n");
		return -1;
	}

	result = mysql_use_result(mysql);
	if (!result)
	{
		printf("GetUserList Error\n");
		return -1;
	}

	row = mysql_fetch_row(result);

	for (; row != NULL; ++count)
	{
		RetPage[count].ID = atoi(row[0]);
		strcpy(RetPage[count].Name, (char *)row[1]);
		strcpy(RetPage[count].Password, (char *)row[2]);
		RetPage[count].Score = atoi(row[3]);
		row = mysql_fetch_row(result);
	}

	mysql_free_result(result);

	for (int i = 0; i < count; i++)
	{
		RetPage[i].Rank = GetUserRank(RetPage[i].Name);
		if (RetPage[i].Rank < 0)
		{
			printf("GetUserList Error\n");
			return -1;
		}
	}

	return count;
}

int Team5_DB::GetUserRank(char *Name)
{
	int Rank;

	sprintf(buffer, "select count(*) from UserData where Score > (select Score from UserData where Name = '%s')", Name);

	if (mysql_query(mysql, buffer))
	{
		printf("GetUserRank Error\n");
		return -1;
	}

	result = mysql_use_result(mysql);
	if (!result)
	{
		printf("GetUserRank Error\n");
		return -1;
	}

	row = mysql_fetch_row(result) ;
	if (!row)
	{
		printf("GetUserRank Error\n");
		return -1;
	}

	Rank = atoi(row[0]) + 1;
	mysql_free_result(result);
	return Rank;
}

int Team5_DB::GetUserInfo(char *Name, UserInfo &RetInfo)
{
	RetInfo.ID = GetUserID(Name);
	if (RetInfo.ID < 0)
	{
		printf("GetUserInfo Error\n");
		return -1;
	}
	strcpy(RetInfo.Name, Name);
	if (GetUserPassword(Name, RetInfo.Password))
	{
		printf("GetUserInfo Error\n");
		return -1;
	}
	RetInfo.Score = GetUserScore(Name);
	if (RetInfo.Score < 0)
	{
		printf("GetUserInfo Error\n");
		return -1;
	}
	RetInfo.Rank = GetUserRank(Name);
	if (RetInfo.Rank < 0)
	{
		printf("GetUserInfo Error\n");
		return -1;
	}

	return 0;
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Common.DataStructure;
using GameEngine.Graphics;

namespace GameEngine.Shelter
{
    public interface IHasBorderObj
    {
        CircleList<BorderPoint> BorderData { get;}
        
        /// <summary>
        /// 暂时定义为贴图坐标到屏幕坐标的转换，当改写Coordin类以后修该为贴图坐标到逻辑坐标的转换。
        /// </summary>
        Matrix WorldTrans { get;}

        Rectanglef BoundingBox { get;}
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using TankEngine2D.Graphics;
using Microsoft.Xna.Framework;
using SmartTank.PhiCol;
using SmartTank.Update;
using SmartTank.Scene;
using SmartTank.GameObjs.Shell;
using TankEngine2D.Helpers;

namespace SmartTank.GameObjs.Tank.SinTur
{
    public class TankContrSinTur : NonInertiasColUpdater, ITankController, IUpdater
    {
        #region Events

        public event EventHandler onShoot;

        #endregion

        #region Variables

        public TankLimitSinTur limit;

        Sprite[] collideSprites;

        #region Additional StateParameter

        public float forwardVel;

        public float turretAzi;
        public float turretAngVel;

        public float raderAzi;
        public float raderAngVel;

        public float fireCDTime;
        public float fireLeftCDTime = 0;
        public bool fireOnNextSpare;



        #endregion

        bool enable = true;

        #endregion

        #region Properties

        Vector2 ForwardVector
        {
            get
            {
                return new Vector2( (float)Math.Sin( Azi ), -(float)Math.Cos( Azi ) );
            }
        }

        public bool Enable
        {
            get { return enable; }
            set
            {
                enable = value;
                this.Vel = Vector2.Zero;
                this.AngVel = 0;
                this.forwardVel = 0;
                this.turretAngVel = 0;
                this.raderAngVel = 0;
            }
        }

        #endregion

        #region Construction

        public TankContrSinTur ( GameObjInfo objInfo,
            Sprite[] collideSprites,
            Vector2 initialPos, float initialRota,
            float maxForwardSpeed, float maxBackwardSpeed, float maxTurnAngleSpeed,
            float maxTurretAngleSpeed, float maxRaderAngleSpeed,
            float fireCDTime )
            : base( objInfo, initialPos, Vector2.Zero, initialRota, 0f, collideSprites )
        {
            this.collideSprites = collideSprites;
            limit = new TankLimitSinTur( maxForwardSpeed, maxBackwardSpeed, maxTurnAngleSpeed, maxTurretAngleSpeed, maxRaderAngleSpeed );
            this.fireCDTime = fireCDTime;
        }

        #endregion

        #region IAIOrderServerSinTur 成员

        public float ForwardSpeed
        {
            get
            {
                return forwardVel;
            }
            set
            {
                forwardVel = limit.LimitSpeed( value );
            }
        }

        public float TurnRightSpeed
        {
            get
            {
                return AngVel;
            }
            set
            {
                AngVel = limit.LimitAngleSpeed( value );
            }
        }

        public float TurnTurretWiseSpeed
        {
            get
            {
                return turretAngVel;
            }
            set
            {
                turretAngVel = limit.LimitTurretAngleSpeed( value );
            }
        }

        public float FireLeftCDTime
        {
            get { return fireLeftCDTime; }
        }

        public float TurnRaderWiseSpeed
        {
            get
            {
                return raderAngVel;
            }
            set
            {
                raderAngVel = limit.LimitRaderAngleSpeed( value );
            }
        }

        public void Fire ()
        {
            // 接收到开火命令后，如果不在冷却中，就开火
            if (fireLeftCDTime <= 0)
                Shoot();
        }

        //public List<Platform.Senses.Vision.IEyeableInfo> GetEyeableInfo ()
        //{
        //    throw new Exception( "The method or operation is not implemented." );
        //}



        #endregion

        #region IUpdater 成员

        public void Update ( float seconds )
        {
            if (!enable) 
                return;

            turretAzi += turretAngVel * seconds;
            raderAzi += raderAngVel * seconds;
            fireLeftCDTime = Math.Max( 0, fireLeftCDTime - seconds );

            if (fireOnNextSpare && fireLeftCDTime == 0 )
            {
                fireOnNextSpare = false;
                Shoot();
            }
        }

        #endregion

        #region Override Functions

        public override void ClearNextStatus ()
        {
            base.ClearNextStatus();
        }

        public override void CalNextStatus ( float seconds )
        {
            if (!enable)
                return;

            Vel = forwardVel * ForwardVector;
            base.CalNextStatus( seconds );
        }

        public override void Validated ()
        {
            if (!enable)
                return;

            base.Validated();
        }

        #endregion

        private void Shoot ()
        {
            if (onShoot != null)
                onShoot( this, EventArgs.Empty );
            fireLeftCDTime = fireCDTime;
        }

    }
}
<file_sep>/*
#pragma comment(lib, "D:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\opt\\libmysql.lib")
#pragma comment(lib, "D:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\opt\\mysqlclient.lib")
#pragma comment(lib, "D:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\opt\\mysys.lib")
#pragma comment(lib, "D:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\opt\\regex.lib")
#pragma comment(lib, "D:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\opt\\strings.lib")
#pragma comment(lib, "D:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\opt\\zlib.lib")
#include <windows.h>
*/
#include <cstdlib>
#include <mysql.h>

struct RankInfo {
	int Rank;
	char Name[21];
	int Score;
};

struct UserInfo {
	int ID;
	char Name[21];
	char Password[21];
	int Score;
	int Rank;
};

class Team5_DB {
private:
	MYSQL *mysql;
	MYSQL_RES *result;
	MYSQL_ROW row;
	char buffer[256];
public:
	//功  能: 连接数据库
	//返回值: 0 -------------正常结束
	//        -1 ------------异常
	int Connect();

	//功  能: 断开与数据库的连接
	void Disconnect();

	//功  能: 添加一条用户信息
	//参  数: Name ----------用户名
	//        Password-------密码
	//        StartScore-----初始积分
	//返回值: 0 -------------正常结束
	//        -1 ------------异常
	int AddUserItem(char *Name, char *Password, int StartScore);

	//功  能: 删除一条用户信息
	//参  数: Name ----------用户名
	//返回值: 0 -------------正常结束
	//        -1 ------------异常
	int DeleteUserItem(char *Name);

	//功  能: 更改用户名
	//参  数: Name ----------用户名
	//        NewName--------新用户名
	//返回值: 0 -------------正常结束
	//        -1 ------------异常
	int SetUserName(char *Name, char *NewName);

	//功  能: 更改用户密码
	//参  数: Name ----------用户名
	//        NewPassword----新密码
	//返回值: 0 -------------正常结束
	//        -1 ------------异常
	int SetUserPassword(char *Name, char *NewPassword);

	//功  能: 更改用户积分
	//参  数: Name ----------用户名
	//        Score----------积分
	//返回值: 0 -------------正常结束
	//        -1 ------------异常
	int SetUserScore(char *Name, int Score);

	//功  能: 获得用户ID
	//参  数: Name ----------用户名
	//返回值: >=0 -----------用户ID
	//        -1 ------------异常
	int GetUserID(char *Name);

	//功  能: 获得用户密码
	//参  数: Name ----------用户名
	//        RetPassword----返回的密码写入 RetPassword 所指向的空间
	//返回值: 0 -------------正常结束
	//        -1 ------------异常
	int GetUserPassword(char *Name, char *RetPassword);

	//功  能: 获得用户积分
	//参  数: Name ----------用户名
	//返回值: >=0 -----------用户的积分
	//        -1 ------------异常
	int GetUserScore(char *Name);

	//功  能: 获得用户排名
	//参  数: Name ----------用户名
	//返回值: >=0 -----------用户的排名
	//        -1 ------------异常
	int GetUserRank(char *Name);

	//功  能: 获得用户完整信息
	//参  数: Name ----------用户名
	//        RetInfo -------返回的用户信息写入 RetInfo 中
	//返回值: 0 -------------正常结束
	//        -1 ------------异常
	int GetUserInfo(char *Name, UserInfo &RetInfo);

	//功  能: 获得用户总数
	//参  数: Name ----------用户名
	//返回值: >=0 -----------用户总数
	//        -1 ------------异常
	int GetUserCount();

	//功  能: 获得积分排名列表
	//参  数: m -------------从第 m + 1 名开始
	//        n ------------- n 个用户
	//        RetPage -------将排名在 [m + 1, m + n] 区间内的 RankInfo 写入 RetPage
	//返回值: >=0 -----------实际获得的 RankInfo 数量
	//        -1 ------------异常
	int GetRankList(int m, int n, RankInfo *RetPage);
	

	//功  能: 获得用户数据列表（按注册先后顺序）
	//参  数: m -------------从第 m + 1 个开始
	//        n ------------- n 个用户
	//        RetPage -------将注册顺序在 [m + 1, m + n] 区间内的 UserInfo 写入 RetPage
	//返回值: >=0 -----------实际获得的 UserInfo 数量
	//        -1 ------------异常
	int GetUserList(int m, int n, UserInfo *RetPage);

	//功  能: 数据库复位
	//返回值: 0 -------------正常结束
	//        -1 ------------异常
	int Reset();
};
<file_sep>/************************************************************
FileName: ClientManager.cpp
Author:   DD.Li     Version :   1.0       Date:2009-2-26
Description:     // 管理，维护用户套接字  
***********************************************************/
#ifndef _CLIENTMANAGER_H_
#define _CLIENTMANAGER_H_

#include "head.h"
#include "mysocket.h"
#include "GameProtocol.h"
#include "ClientManager.h"
#include "MyRoom.h"
#include <vector>
using namespace std;

class MyRoom;

class ClientManager
{
public:
    ClientManager();
    ~ClientManager();
    int  GetClient();
    MySocket *AddServer( MySocket *psock);  // 记录服务器.返回socket指针
    MySocket *AddClient( MySocket *psock);  // 新用户加入.返回socket指针
    MySocket *GetClient( int iID);          // 得到某用户.返回socket指针
    MySocket *GetSafeClient(int iID);       // garbage
    void SetTimer(int nID);                 // 设置定时器
    bool DelClient( MySocket *psock);       // 删除用户
    bool DelClientAll();                    // 删除all

	GameProtocal* GetProtocal(){				 // 取得协议分析器
		return m_protocol;
	};
	void AttachProtocal( GameProtocal* pProtocal){// 添加协议
		m_protocol = pProtocal;
	}
    int GetNum(){       //  返回客户总数
        return (int)m_pClient.size();
    }
    void HeartBeatFun(MySocket *psock);

	GameProtocal *m_protocol;		// 协议分析器
    MyRoom *m_room;                 // Rooms
    int m_numOfRoom;                // number of Rooms
    MyTimer myTimer[MAXCLIENT];    //定义Timer类型的数组，用来保存所有的定时器
protected:
    vector<MySocket*> m_pClient;   // 客户池<已有>
    vector<MySocket*> m_pEmpty;    // 客户池<可用>
    MySocket *m_pServer;           // 服务器
};






#endif









<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using GameEngine.PhiCol;

namespace GameEngine.PhiCol
{
    public class NonInertiasPhiUpdater : IPhisicalUpdater
    {
        public Vector2 Vel;
        public Vector2 Pos;

        public float AngVel;
        public float Azi;

        protected Vector2 nextPos;
        protected float nextAzi;

        public NonInertiasPhiUpdater ()
        {
        }

        public NonInertiasPhiUpdater (Vector2 pos, Vector2 vel, float azi, float angVel )
        {
            this.Pos = pos;
            this.Vel = vel;
            this.Azi = azi;
            this.AngVel = angVel;
            this.nextPos = pos;
            this.nextAzi = azi;
        }

        #region IPhisicalUpdater ³ΙΤ±

        public virtual void CalNextStatus ( float seconds )
        {
            nextPos = Pos + Vel * seconds;
            nextAzi = Azi + AngVel * seconds;
        }

        public virtual void Validated ()
        {
            Pos = nextPos;
            Azi = nextAzi;
        }

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using WeifenLuo.WinFormsUI.Docking;
using Microsoft.Xna.Framework.Graphics;
using SmartTank.Scene;
using System.IO;

namespace MapEditor
{
    public partial class MapEditor : Form
    {
        ObjPropertyPanel objPropertyPanel;
        GroupPanel groupPanel;
        ObjDisplayPanel objDisplayPanel;
        BackGroundPanel backGroundPanel;

        MainScreen mainScreen;
        SpriteBatch mainScrnBatch;
        GraphicsDevice mainDevice;

        GraphicsDevice displayDevice;
        SpriteBatch displayBatch;

        SceneMgr curScene;

        public MapEditor()
        {
            InitializeComponent();
            InitializeChildForm();
            InitializeMainScrn();
            InitializeDisplayScrn();
        }

        private void InitializeChildForm()
        {
            objPropertyPanel = new ObjPropertyPanel();
            groupPanel = new GroupPanel();
            objDisplayPanel = new ObjDisplayPanel();
            backGroundPanel = new BackGroundPanel();

            objPropertyPanel.Show( dockPanel, DockState.DockRightAutoHide );
            groupPanel.Show( dockPanel, DockState.DockLeftAutoHide );
            objDisplayPanel.Show( dockPanel, DockState.DockLeftAutoHide );
            backGroundPanel.Show( dockPanel, DockState.DockRightAutoHide );

        }

        private void toolStripButtonShowGroupPanel_Click( object sender, EventArgs e )
        {
            groupPanel.Show( dockPanel, DockState.DockLeftAutoHide );
        }

        private void toolStripButtonShowBackGroundPanel_Click( object sender, EventArgs e )
        {
            backGroundPanel.Show( dockPanel, DockState.DockRightAutoHide );
        }

        private void toolStripButtonShowObjCreatePanel_Click( object sender, EventArgs e )
        {
            objDisplayPanel.Show( dockPanel, DockState.DockLeftAutoHide );
        }

        private void toolStripButtonShowObjPropertyPanel_Click( object sender, EventArgs e )
        {
            objPropertyPanel.Show( dockPanel, DockState.DockRightAutoHide );
        }

        #region MainScrn

        private void InitializeMainScrn()
        {
            mainScreen = new MainScreen();

            PresentationParameters pp = new PresentationParameters();
            pp.BackBufferCount = 1;
            pp.IsFullScreen = false;
            pp.SwapEffect = SwapEffect.Discard;
            pp.BackBufferWidth = mainScreen.canvas.Width;
            pp.BackBufferHeight = mainScreen.canvas.Height;

            pp.AutoDepthStencilFormat = DepthFormat.Depth24Stencil8;
            pp.EnableAutoDepthStencil = true;
            pp.PresentationInterval = PresentInterval.Default;
            pp.BackBufferFormat = SurfaceFormat.Unknown;
            pp.MultiSampleType = MultiSampleType.None;

            mainDevice = new GraphicsDevice( GraphicsAdapter.DefaultAdapter,
                DeviceType.Hardware, this.mainScreen.canvas.Handle,
                pp );

            mainScreen.canvas.SizeChanged += new EventHandler( mainScreen_canvas_SizeChanged );
            mainScreen.canvas.Paint += new EventHandler( mainScreen_canvas_Paint );

            mainDevice.Reset();

            mainScreen.Show( dockPanel, DockState.Document );

            mainScrnBatch = new SpriteBatch( mainDevice );

            //BasicGraphics.Initial( mainDevice );
        }

        void mainScreen_canvas_Paint( object sender, EventArgs e )
        {
            mainDevice.Clear( Microsoft.Xna.Framework.Graphics.Color.Blue );

            //Coordin.SetScreenViewRect( new Microsoft.Xna.Framework.Rectangle( 0, 0, mainScreen.canvas.Width, mainScreen.canvas.Height ) );
            //Coordin.SetCamera( 1, new Microsoft.Xna.Framework.Vector2( 100, 100 ), 0 );

            //Sprite.alphaSprite = mainScrnBatch;
            //mainScrnBatch.Begin();

            //BasicGraphics.DrawLine( new Microsoft.Xna.Framework.Vector2( 100, 100 ), new Microsoft.Xna.Framework.Vector2( 0, 0 ), 3, Microsoft.Xna.Framework.Graphics.Color.Red, 0f );

            //mainScrnBatch.End();
            mainDevice.Present();
        }

        void mainScreen_canvas_SizeChanged( object sender, EventArgs e )
        {
            MainDeviceReset();
        }

        private void MainDeviceReset()
        {
            if (this.WindowState == FormWindowState.Minimized ||
                this.mainScreen.canvas.Width == 0 ||
                this.mainScreen.canvas.Height == 0)
                return;
            mainDevice.PresentationParameters.BackBufferWidth = this.mainScreen.canvas.Width;
            mainDevice.PresentationParameters.BackBufferHeight = this.mainScreen.canvas.Height;
            mainDevice.Reset();
        }

        #endregion

        #region DisplayScrn

        private void InitializeDisplayScrn()
        {
            PresentationParameters pp = new PresentationParameters();
            pp.BackBufferCount = 1;
            pp.IsFullScreen = false;
            pp.SwapEffect = SwapEffect.Discard;
            pp.BackBufferWidth = objDisplayPanel.canvas.Width;
            pp.BackBufferHeight = objDisplayPanel.canvas.Height;

            pp.AutoDepthStencilFormat = DepthFormat.Depth24Stencil8;
            pp.EnableAutoDepthStencil = true;
            pp.PresentationInterval = PresentInterval.Default;
            pp.BackBufferFormat = SurfaceFormat.Unknown;
            pp.MultiSampleType = MultiSampleType.None;

            displayDevice = new GraphicsDevice( GraphicsAdapter.DefaultAdapter,
                DeviceType.Hardware, objDisplayPanel.canvas.Handle,
                pp );

            objDisplayPanel.canvas.SizeChanged += new EventHandler( objDisplay_canvas_SizeChanged );
            objDisplayPanel.canvas.Paint += new EventHandler( objDisplayPanel_canvas_Paint );

            displayBatch = new SpriteBatch( displayDevice );
        }

        void objDisplayPanel_canvas_Paint( object sender, EventArgs e )
        {
            displayDevice.Clear( Microsoft.Xna.Framework.Graphics.Color.YellowGreen );

            //Sprite.alphaSprite = displayBatch;
            //displayBatch.Begin();

            //BasicGraphics.DrawLineInScrn( new Microsoft.Xna.Framework.Vector2( 0, 0 ), new Microsoft.Xna.Framework.Vector2( 50, 100 ), 3, Microsoft.Xna.Framework.Graphics.Color.White, 0f );

            //displayBatch.End();
            displayDevice.Present();
        }

        void objDisplay_canvas_SizeChanged( object sender, EventArgs e )
        {
            DisplayDeviceReset();
        }

        private void DisplayDeviceReset()
        {
            if (this.WindowState == FormWindowState.Minimized ||
                this.objDisplayPanel.canvas.Width == 0 ||
                this.objDisplayPanel.canvas.Height == 0)
                return;

            displayDevice.PresentationParameters.BackBufferWidth = this.objDisplayPanel.canvas.Width;
            displayDevice.PresentationParameters.BackBufferHeight = this.objDisplayPanel.canvas.Height;
            displayDevice.Reset();
        }


        #endregion

        private void MenuItemNewScene_Click( object sender, EventArgs e )
        {
            //if (curScene != null) // ر¯ختتا·ٌ±£´و
            curScene = new SceneMgr();
        }

        private void MenuItemOpenScene_Click( object sender, EventArgs e )
        {
            DialogResult result = openSceneDialog.ShowDialog( this );
            if (result == DialogResult.OK)
            {
                curScene = SceneMgr.Load( openSceneDialog.FileName );
            }
        }

        private void MenuItemSaveScene_Click( object sender, EventArgs e )
        {
            if (curScene == null)
                return;

            DialogResult result = saveSceneDialog.ShowDialog( this );
            if (result == DialogResult.OK)
            {
                Stream file = File.Create( saveSceneDialog.FileName );
                SceneMgr.Save( file, curScene );
            }
        }



    }
}<file_sep>using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace GameEngine.Effects.Particles
{
    public delegate Vector2 PosGroupFunc( float curPartiTime,float deltaTime, Vector2 lastPos, Vector2 dir, int No );

    public delegate Vector2 DirGroupFunc( float curPartiTime, float deltaTime, Vector2 lastDir, int No );

    public delegate float RadiusGroupFunc( float curPartiTime, float deltaTime, float lastRadius, int No );

    public delegate Color ColorGroupFunc( float curPartiTime, float deltaTime, Color lastColor, int No );

    public delegate int CreateSumFunc( float curTime, ref float timer );


    public class ParticleSystem: IManagedEffect
    {
        #region Variables

        Texture2D tex;

        Vector2 texOrigin;

        Nullable<Rectangle> sourceRect;

        float layerDepth;

        public CreateSumFunc createSumFunc;

        public PosGroupFunc posGroupFunc;

        public DirGroupFunc dirGroupFunc;

        public RadiusGroupFunc radiusGroupFunc;

        public ColorGroupFunc colorGroupFunc;

        List<Particle> particles;

        float curTime = -1;

        float duration;
        float partiDura;

        Vector2 basePos;

        bool isEnd = false;

        protected float createTimer = 0;

        #endregion

        public Vector2 BasePos
        {
            get { return basePos; }
            set { basePos = value; }
        }

        public ParticleSystem()
        {
        }

        public ParticleSystem( float duration, float partiDuration, Vector2 basePos,
            Texture2D tex, Vector2 texOrigin, Nullable<Rectangle> sourceRect, float layerDepth,
            CreateSumFunc createSumFunc, PosGroupFunc posGroupFunc, DirGroupFunc dirGroupFunc,
            RadiusGroupFunc radiusGroupFunc, ColorGroupFunc colorGroupFunc )
        {
            this.tex = tex;
            this.texOrigin = texOrigin;
            this.sourceRect = sourceRect;
            this.layerDepth = layerDepth;
            this.createSumFunc = createSumFunc;
            this.posGroupFunc = posGroupFunc;
            this.dirGroupFunc = dirGroupFunc;
            this.radiusGroupFunc = radiusGroupFunc;
            this.colorGroupFunc = colorGroupFunc;

            this.duration = duration;
            this.partiDura = partiDuration;
            this.basePos = basePos;

            this.particles = new List<Particle>();

        }

        #region Update

        public void Update(float seconds)
        {
            curTime += seconds;
            if (duration != 0 && curTime > duration)
            {
                isEnd = true;
            }

            CreateNewParticle(seconds);

            UpdateParticles(seconds);
        }

        protected virtual void UpdateParticles( float seconds )
        {
            foreach (Particle particle in particles)
            {
                particle.Update(seconds);
            }
        }

        protected virtual void CreateNewParticle(float seconds)
        {
            createTimer += seconds;
            int createSum = createSumFunc( curTime, ref  createTimer);
            int preCount = particles.Count;

            for (int i = 0; i < createSum; i++)
            {
                particles.Add( new Particle( partiDura, basePos, layerDepth,
                    delegate( float curParticleTime,float deltaTime, Vector2 lastPos, Vector2 dir )
                    {
                        return posGroupFunc( curParticleTime,deltaTime, lastPos, dir, preCount + i );
                    },
                    delegate( float curParticleTime, float deltaTime, Vector2 lastDir )
                    {
                        return dirGroupFunc( curParticleTime, deltaTime, lastDir, preCount + i );
                    },
                    delegate( float curParticleTime, float deltaTime, float lastRadius )
                    {
                        return radiusGroupFunc( curParticleTime, deltaTime, lastRadius, preCount + i );
                    },
                    tex, texOrigin, sourceRect,
                    delegate( float curParticleTime, float deltaTime, Color lastColor )
                    {
                        return colorGroupFunc( curParticleTime, deltaTime, lastColor, preCount + i );
                    } ) );
            }
        }

        #endregion

        #region IDrawableObj 成员

        public void Draw()
        {
            foreach (Particle parti in particles)
            {
                parti.Draw();
            }
        }

        #endregion

        #region IDrawableObj 成员


        public Vector2 Pos
        {
            get { return BasePos; }
        }

        #endregion

        #region IManagedEffect 成员

        public bool IsEnd
        {
            get { return isEnd; }
        }

       

        #endregion
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Text;

namespace SmartTank.Screens
{
    public interface IGameScreen
    {
        /// <summary>
        /// 当需要退出该屏幕时返回true
        /// </summary>
        /// <param name="second"></param>
        /// <returns></returns>
        bool Update ( float second );

        void Render ();

        /// <summary>
        /// 当从该规则中退出前该方法被调用
        /// </summary>
        void OnClose();
    }
}
