Страница 6 из 6 Листинг 1 Программная модель стрелка extern LArc RiflemanTBL[]; class CRifleman : public LFsaAppl { public: int GetNumber(); void SetNumber(int n); void SetLink(CRifleman *pFsaLeft, CRifleman *pFsaRigtht); CRifleman *pFsaRightMan; CRifleman *pFsaLeftMan; CRifleman(); CRifleman(int n, CWnd* pW, LArc *pTBL=RiflemanTBL); virtual ~CRifleman(); bool operator==(const CRifleman &var) const; bool operator<(const CRifleman &var) const; bool operator!=(const CRifleman &var) const; bool operator>(const CRifleman &var) const; protected: CWnd* pParentWnd; CFireApp *pApp; // указатель на объект // основного класса программы int x1(); // Is fire? int x2(); // Is ready? int x3(); // Number is equal to zero? Shot! int x4(); // void y1(); // To place number. void y2(); // To reduce number by unit. void y3(); // Gunshot void y4(); // void y5(); // int nNumber; int nSaveNumber; int nLengthQueue; // Length of queue. int nCurrentQueue; // }; typedef vector<CRifleman*> TIArrayRifleman; typedef vector<CRifleman*>: :iterator TIIteratorRifleman; extern LArc RiflemanTBL[]; CRifleman::CRifleman():LFsaAppl() { } CRifleman::CRifleman(int n, CWnd* pW, LArc* pTBL): LFsaAppl(pTBL) { pParentWnd = pW; pFsaRightMan = NULL; pFsaLeftMan = NULL; nNumber = n; nLengthQueue = 5; nCurrentQueue = nLengthQueue; if (pParentWnd) { pApp = (CFireApp*)AfxGetApp(); FLoad(pApp->pNetFsa,1); } } bool CRifleman::operator==(const CRifleman &var) const { if (nNumber==var.nNumber) return true; else return false; } void CRifleman::SetLink(CRifleman * pFsaLeft, CRifleman * pFsaRigtht) { pFsaRightMan = pFsaRigtht; pFsaLeftMan = pFsaLeft; } LArc RiflemanTBL[] = { LArc("Сон", "Огонь", "x1", "y1"), LArc("Огонь", "Готов", "x2", "y2"), LArc("Готов", "Готов", "x3", "y2"), LArc("Готов", "Выстрел", "^x3", "y3y4"), LArc("Выстрел", "Выстрел", "x4", "y3y5"), LArc("Выстрел", "Сон", "^x4", "-"), LArc() }; int CRifleman::x1() { if (!pFsaLeftMan) return false; return string((pFsaLeftMan)- >FGetState()) == "Огонь"; } int CRifleman::x2() { if (!pFsaRightMan) return true; else return string((pFsaRightMan)- >FGetState()) == "Готов"; } int CRifleman::x3() { return nNumber; } int CRifleman::x4() { return nCurrentQueue; } void CRifleman::y1() { int n = pFsaLeftMan->GetNumber(); SetNumber(n+1); } void CRifleman::y2() { nNumber-; } void CRifleman::y3() { } void CRifleman::y4() { nCurrentQueue = nLengthQueue; } // формирование задержки между выстрелами void CRifleman::y5() { CFDelay *pCFDelay; pCFDelay = new CFDelay(200); pCFDelay->FCall(this); nCurrentQueue-; } Листинг 2 Модель командира class COfficer : public CRifleman { public: COfficer(); virtual ~COfficer(); void SetCommand(); protected: CFireApp *pApp; // int x1(); // Is fire? void y1(); bool bCommandFire; }; extern LArc OfficerTBL[]; COfficer::COfficer():CRifleman (0,NULL,OfficerTBL) { bCommandFire = false; pApp = (CFireApp*)AfxGetApp(); // FLoad(pApp->pNetFsa,1); // подключить объект к КА-сети } COfficer::~COfficer() { } LArc OfficerTBL[] = { LArc("Сон", "Огонь", "x1", "y1"), LArc("Огонь", "Сон", "-", "-"), LArc() }; int COfficer::x1() { return bCommandFire; } void COfficer::y1() { bCommandFire = false; } void COfficer::SetCommand() { bCommandFire = true; } Листинг 3 Модель пули extern LArc BulletTBL[]; class CBullet : public TBounce { public: void SetAddrMan (LFsaAppl *pFsaAppl); CBullet(); CBullet(CWnd* pW, int nNum, CSize sz=CSize(10,10), LArc *pTBL=BulletTBL); virtual ~CBullet(); void SetCenter(int x, int y); void SetMove(int cx, int cy); protected: int x1(); int x2(); int x3(); void y4(); protected: LFsaAppl *pFsaShot; }; typedef vector<CBullet*> TIArrayBullet; typedef vector<CBullet*>: :iterator TIIteratorBullet; CBullet::CBullet(CWnd* pW, int nNum, CSize sz, LArc *pTBL) :TBounce(pW, nNum, sz, pTBL) { pFsaShot = NULL; } CBullet::CBullet():TBounce() { pFsaShot = NULL; } CBullet::~CBullet() { } void CBullet::SetAddrMan(LFsaAppl * pFsaAppl) { pFsaShot = pFsaAppl; } // LArc BulletTBL[] = { LArc("st","b1", "x1", "y4"), LArc("b1","b1", "^x2", "y1"), LArc("b1","st", "x2", "y4"), LArc() }; int CBullet::x1() { if (!pFsaShot) return false; return string((pFsaShot)- >FGetState()) == "выстрел"; } int CBullet::x2() { return m_ptCenter.y + m_sizeRadius.cy >= rcClient.bottom; } int CBullet::x3() { return nNumBounce; } void CBullet::y4() { SetCenter(0,10); } void CBullet::SetCenter(int x, int y) { if (y) m_ptCenter.y = y; if (x) m_ptCenter.x = x; } void CBullet::SetMove(int cx, int cy) { m_sizeMove.cx = cx; m_sizeMove.cy = cy; } Листинг 4 Модель цепи стрелков class CChainShot { public: CChainShot(CWnd *pW); virtual ~CChainShot(); void SetLink(); void SetCommand(); void OnSize(int cx, int cy); CRifleman* GetAddrRifleman(int n); CBullet* GetAddrBullet(int n); protected: CWnd *pWnd; COfficer *pCOfficer; TIArrayRifleman IArrayRifleman; TIArrayBullet IArrayBullet; }; CChainShot::CChainShot(CWnd *pW) { pWnd = pW; pCOfficer = new COfficer(); for (int i=1; i<=4; i++) { IArrayRifleman.push_back(new CRifleman(i,pWnd)); IArrayBullet.push_back(new CBullet(pWnd,i)); } SetLink(); } CChainShot::~CChainShot() { if (pCOfficer) delete pCOfficer; TIIteratorRifleman iterRifleman = IArrayRifleman.begin(); while (iterRifleman != IArrayRifleman.end()) delete *iterRifleman++; IArrayRifleman.erase(IArrayRifleman.begin(), IArrayRifleman.end()); TIIteratorBullet iterBullet = IArrayBullet .begin(); while (iterBullet!=IArrayBullet.end()) delete *iterBullet++; IArrayBullet.erase(IArrayBullet.begin() ,IArrayBullet.end()); } void CChainShot::SetCommand() { if (pCOfficer) pCOfficer->SetCommand(); } CRifleman* CChainShot::GetAddrRifleman(int n) { CRifleman* currentRifleman=NULL; CRifleman vs(n, NULL); TIIteratorRifleman iterRifleman = IArrayRifleman.begin(); while (iterRifleman != IArrayRifleman.end()) { currentRifleman= *iterRifleman++; if (*currentRifleman==vs) break; } return currentRifleman; } CBullet* CChainShot::GetAddrBullet(int n) { CBullet* currentBullet=NULL; CBullet vs(NULL, n); if (!IArrayBullet.empty()) { TIIteratorBullet iterBullet = IArrayBullet .begin(); while (iterBullet != IArrayBullet.end()) { currentBullet= *iterBullet++; if (*currentBullet==vs) break; } } return currentBullet; } void CChainShot::SetLink() { LFsaAppl *currentRifleman; TIIteratorRifleman iterRifleman = IArrayRifleman.begin(); int n =1; CRifleman *pFsaLeft = NULL; CRifleman *pFsaRight = NULL; while (iterRifleman != IArrayRifleman.end()) { if (n==1) { currentRifleman= *iterRifleman++; ((CRifleman*)currentRifleman)- >SetNumber(n); n++; pFsaLeft = pCOfficer; pFsaRight= *iterRifleman++; ((CRifleman*)pFsaRight)->SetNumber(n); n++; ((CRifleman*)currentRifleman)-> SetLink(pFsaLeft, pFsaRight); } else { pFsaLeft = currentRifleman; if (iterRifleman != IArrayRifleman.end()) { currentRifleman = pFsaRight; pFsaRight= *iterRifleman++; ((CRifleman*)pFsaRight)->SetNumber(n); n++; ((CRifleman*)currentRifleman)-> SetLink(pFsaLeft, pFsaRight); } } } pFsaLeft = currentRifleman; currentRifleman = pFsaRight; pFsaRight= NULL; ((CRifleman*)currentRifleman)- >SetLink(pFsaLeft, pFsaRight); TIIteratorBullet iterBullet = IArrayBullet.begin(); while (iterBullet != IArrayBullet.end()) { CBullet* currentBullet= *iterBullet++; CRifleman* pRf=GetAddrRifleman (currentBullet->GetNum()); currentBullet->SetAddrMan(pRf); } } void CChainShot::OnSize(int cx, int cy) { int n=1; CBullet* currentBullet; TIIteratorBullet iterBullet = IArrayBullet.begin(); while (iterBullet != IArrayBullet.end()) { currentBullet= *iterBullet++; currentBullet->Size(CSize(cx/n,cy/n)); currentBullet->SetCenter(400/n-20,10); currentBullet->SetMove(0,1); // currentBullet->SizeBounce(CSize(20,20)); n++; } } Листинг 5 Объект окна-отображения void CFireView::OnFire() { pChainShot->SetCommand(); } int CFireView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; pChainShot = new CChainShot(this); CFireApp *pApp = (CFireApp*)AfxGetApp(); // pApp->pNetFsa->go_task(); // запуск КА-объекта return 0; } void CFireView::OnSize(UINT nType, int cx, int cy) { pChainShot->OnSize(cx, cy); CView::OnSize(nType, cx, cy); } void CFireView::OnFast() { CFireApp *pApp = (CFireApp*)AfxGetApp(); pApp->lCountTime=0; } void CFireView::OnSlow() { CFireApp *pApp = (CFireApp*)AfxGetApp(); pApp->lCountTime=1000; } Листинг 6 Действие y3 модели стрелка void CRifleman::y3() { CRect r; pParentWnd->GetClientRect(r); CSize cz = r.Size(); int x1, y1; x1=cz.cx/nSaveNumber; y1= cz.cy/nSaveNumber; CBullet *currentBullet = new CBullet(pParentWnd, 0); // задание начального положения пули и ее размеров currentBullet->SetCenter(x1-50,10); currentBullet->SetMove(0,3);// интервал между пулями // currentBullet->SetMove(nCurrentQueue,3); // стрельба // веером currentBullet->SizeBounce(CSize(2,5)); // передача адреса стрелка новой пуле currentBullet->SetAddrMan(this); // currentBullet->FCall(this); } Листинг 7 Таблица переходов "автоматной" пули LArc BulletTBL[] = { LArc("st","b1", "x1x3", "y4"), LArc("st","b1", "^x3", "y4"), LArc("b1","b1", "^x2", "y1"), LArc("b1","st", "x2x3", "y4"), LArc("b1","00", "x2^x3","-"), LArc() }; |