?? marsdoc.cpp
字號(hào):
// MarsDoc.cpp : implementation of the CMarsDoc class
//
// 本程序是《瘋狂的火星蟲(chóng)—面向?qū)ο鬆顟B(tài)機(jī)實(shí)踐指南》的演示程序
//
// 版權(quán)所有 (C) 2004 王詠武
// http://www.contextfree.net/wangyw/
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <math.h>
#include "Mars.h"
#include "MarsDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMarsDoc
IMPLEMENT_DYNCREATE(CMarsDoc, CDocument)
BEGIN_MESSAGE_MAP(CMarsDoc, CDocument)
//{{AFX_MSG_MAP(CMarsDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMarsDoc construction/destruction
CMarsDoc::CMarsDoc()
{
// TODO: add one-time construction code here
srand(GetTickCount());
}
CMarsDoc::~CMarsDoc()
{
for (int i = 0; i < m_Bugs.size(); i ++)
delete m_Bugs[i].m_pBug;
}
BOOL CMarsDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
// 初始創(chuàng)建10個(gè)火星蟲(chóng)
for (int i = 0; i < 10; i ++)
AddNewBug();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMarsDoc serialization
void CMarsDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
int size = m_Bugs.size();
ar << size;
for (int i = 0; i < size; i ++)
{
m_Bugs[i].Serialize(ar);
}
}
else
{
// TODO: add loading code here
int size;
ar >> size;
int i;
// 從文件裝載時(shí),先刪除原來(lái)的火星蟲(chóng)
for (i = 0; i < m_Bugs.size(); i ++)
{
m_Bugs[i].m_pBug->Invalidate();
delete m_Bugs[i].m_pBug;
}
m_Bugs.erase(m_Bugs.begin(), m_Bugs.end());
for (i = 0; i < size; i ++)
{
SBugInfo bug_info(new CMarsBug(0, 0, 0));
bug_info.Serialize(ar);
m_Bugs.push_back(bug_info);
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CMarsDoc diagnostics
#ifdef _DEBUG
void CMarsDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CMarsDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMarsDoc commands
void CMarsDoc::OnDraw(CDC* pDC)
{
for (int i = 0; i < m_Bugs.size(); i ++)
m_Bugs[i].m_pBug->OnDraw(pDC);
}
void CMarsDoc::OnTimer()
{
vector<SBugInfo>::iterator it;
for (it = m_Bugs.begin(); it < m_Bugs.end(); it ++)
if (it->m_bRemove)
{
it->m_pBug->Invalidate();
delete it->m_pBug;
m_Bugs.erase(it);
break;
}
// 根據(jù)距離確定給每個(gè)火星蟲(chóng)發(fā)送的消息
for (int i = 0; i < m_Bugs.size(); i ++)
for (int j = i + 1; j < m_Bugs.size(); j ++)
{
int distance = GetDistance(m_Bugs[i].m_pBug, m_Bugs[j].m_pBug);
if (distance < m_Bugs[i].m_iDistance)
{
if (distance <= CMarsBug::DISTANCE_CAN_ATTACK)
m_Bugs[i].m_Event = CMarsBug::EVENT_CAN_ATTACK;
else if (distance <= CMarsBug::DISTANCE_CAN_SEE)
m_Bugs[i].m_Event = CMarsBug::EVENT_CAN_SEE;
else
m_Bugs[i].m_Event = CMarsBug::EVENT_IDLE;
m_Bugs[i].m_iDistance = distance;
m_Bugs[i].m_pEnemy = m_Bugs[j].m_pBug;
}
if (distance < m_Bugs[j].m_iDistance)
{
if (distance <= CMarsBug::DISTANCE_CAN_ATTACK)
m_Bugs[j].m_Event = CMarsBug::EVENT_CAN_ATTACK;
else if (distance <= CMarsBug::DISTANCE_CAN_SEE)
m_Bugs[j].m_Event = CMarsBug::EVENT_CAN_SEE;
else
m_Bugs[j].m_Event = CMarsBug::EVENT_IDLE;
m_Bugs[j].m_iDistance = distance;
m_Bugs[j].m_pEnemy = m_Bugs[i].m_pBug;
}
}
for (int k = 0; k < m_Bugs.size(); k ++)
{
m_Bugs[k].m_pBug->Invalidate();
m_Bugs[k].m_pBug->SendEvent(m_Bugs[k].m_Event, 0, (DWORD)m_Bugs[k].m_pEnemy);
m_Bugs[k].m_pBug->Invalidate();
m_Bugs[k].Init();
}
}
void CMarsDoc::Escape(CMarsBug * pBug, CMarsBug * pBugFrom)
{
int distance = GetDistance(pBug, pBugFrom);
int x = pBug->GetX();
int xFrom = pBugFrom->GetX();
if (distance)
x -= (xFrom - x) * CMarsBug::ESCAPE_STEP / distance;
else
x -= CMarsBug::ESCAPE_STEP;
int y = pBug->GetY();
int yFrom = pBugFrom->GetY();
if (distance)
y -= (yFrom - y) * CMarsBug::ESCAPE_STEP / distance;
else
y -= CMarsBug::ESCAPE_STEP;
BorderCheck(x, y);
pBug->SetX(x);
pBug->SetY(y);
}
void CMarsDoc::Chase(CMarsBug * pBug, CMarsBug * pBugFrom)
{
int distance = GetDistance(pBug, pBugFrom);
int x = pBug->GetX();
int xFrom = pBugFrom->GetX();
if (distance)
x += (xFrom - x) * CMarsBug::CHASE_STEP / distance;
int y = pBug->GetY();
int yFrom = pBugFrom->GetY();
if (distance)
y += (yFrom - y) * CMarsBug::CHASE_STEP / distance;
BorderCheck(x, y);
pBug->SetX(x);
pBug->SetY(y);
}
void CMarsDoc::Walk(CMarsBug * pBug)
{
int x = pBug->GetX();
x += rand() * CMarsBug::WALK_STEP / RAND_MAX - CMarsBug::WALK_STEP / 2;
int y = pBug->GetY();
y += rand() * CMarsBug::WALK_STEP / RAND_MAX - CMarsBug::WALK_STEP / 2;
BorderCheck(x, y);
pBug->SetX(x);
pBug->SetY(y);
}
int CMarsDoc::GetDistance(CMarsBug *pBug1, CMarsBug *pBug2)
{
double cx = pBug1->GetX() - pBug2->GetX();
double cy = pBug1->GetY() - pBug2->GetY();
return sqrt(cx * cx + cy * cy);
}
void CMarsDoc::AddNewBug()
{
int x = rand() * m_iWidth / RAND_MAX;
int y = rand() * m_iHeight / RAND_MAX;
m_Bugs.push_back(SBugInfo(new CMarsBug(x, y,
RGB(rand() * 255 / RAND_MAX, rand() * 255 / RAND_MAX, rand() * 255 / RAND_MAX))));
}
void CMarsDoc::Remove(CMarsBug * pBug)
{
vector<SBugInfo>::iterator i;
for (i = m_Bugs.begin(); i < m_Bugs.end(); i ++)
if (i->m_pBug == pBug)
{
i->m_bRemove = TRUE;
break;
}
}
void CMarsDoc::Spawn(int x, int y)
{
m_Bugs.push_back(SBugInfo(new CMarsBug(x, y, RGB(rand() * 255 / RAND_MAX, rand() * 255 / RAND_MAX, rand() * 255 / RAND_MAX))));
}
void CMarsDoc::BorderCheck(int & x, int & y)
{
if (x < CMarsBug::RADIUS)
x = CMarsBug::RADIUS;
else if (x > m_iWidth - CMarsBug::RADIUS)
x = m_iWidth - CMarsBug::RADIUS;
if (y < CMarsBug::RADIUS)
y = CMarsBug::RADIUS;
else if (y > m_iHeight - CMarsBug::RADIUS)
y = m_iHeight - CMarsBug::RADIUS;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -