游戏制作第四棒——坦克大战

这次制作的游戏是我第一次使用MFC没有任何辅助情况下制作的,制作过程遇到过诸多困难,主要是SetTimer定时器的应用出问题。这个版本的坦克大战有许多bug,因为没有数据库所以只能由一个地图。与之前用java写的坦克大战比起来,这次的制作更加困难,这也验证了为什么MFC会被淘汰,而java能很挺立。一下是主要代码,只贴上部分的代码
坦克类:
#pragma once
#include"Shot.h"
#include<vector>
class AllTank
{
private:
int x;
int y;
int direct;
int spend;
int color;
public:
AllTank(void);
AllTank(int xx,int yy,int d,int sp,int c)
{
x=xx;
y=yy;
direct=d;
spend=sp;
color=c;
}
~AllTank(void);
public:
//得到和设置坦克的位置

virtual int GetX()const
{
return x;
}

virtual int GetY()const
{
return y;
}

virtual void SetX(int X)
{
x=X;
}

virtual void SetY(int Y)
{
y=Y;
}

//得到 改变其他属性
virtual int GetDirect()const
{
return direct;
}

virtual void SetDirect(int d)
{
direct=d;
}

virtual int GetColor()const
{
return color;
}

virtual void SetCorlor(int c)
{
color=c;
}
virtual int GetSpend()const
{
return spend;
}
};

class MyTank:public AllTank
{
public:
bool Is_Live;

//定义子弹
std::vector<Shot> st;

MyTank(int xx,int yy,int d,int sp,int c):AllTank(xx,yy,d,sp,c)
{
Is_Live=true;
}

//得到和设置坦克的位置

int GetX()const
{
return AllTank::GetX();
}

int GetY()const
{
return AllTank::GetY();
}

void SetX(int X)
{
 AllTank::SetX(X);
}

void SetY(int Y)
{
 AllTank::SetY(Y);
}

//得到 改变其他属性
int GetDirect()const
{
return AllTank::GetDirect();
}

void SetDirect(int d)
{
AllTank::SetDirect(d);
}

int GetColor()const
{
return AllTank::GetColor();
}

void SetCorlor(int c)
{
AllTank::SetCorlor(c);
}
int GetSpend()const
{
return AllTank::GetSpend();
}
};

class EnemyTank:public AllTank
{
public:
//定义是否活着
bool Is_Live;

//定义子弹
std::vector<Shot> st;

EnemyTank(int xx,int yy,int d,int sp,int c):AllTank(xx,yy,d,sp,c)
{
Is_Live=true;
}
//得到和设置坦克的位置

int GetX()const
{
return AllTank::GetX();
}
int GetY()const
{
return AllTank::GetY();
}

void SetX(int X)
{
 AllTank::SetX(X);
}
void SetY(int Y)
{
 AllTank::SetY(Y);
}

//得到 改变其他属性
int GetDirect()const
{
return AllTank::GetDirect();
}
void SetDirect(int d)
{
AllTank::SetDirect(d);
}

int GetColor()const
{
return AllTank::GetColor();
}
void SetCorlor(int c)
{
AllTank::SetCorlor(c);
}
int GetSpend()const
{
return AllTank::GetSpend();
}
};
#include "stdafx.h"
#include "AllTank.h"


AllTank::AllTank(void)
{
x=y=direct=spend=color=0;
}


AllTank::~AllTank(void)
{

}

//子弹类
#pragma once
class Shot
{
private:
int x;
int y;
int direct;
int spend;
public:
bool Is_Live;
Shot(void);
Shot(int xx,int yy,int di,int sp)
{
Is_Live=true;
x=xx;
y=yy;
direct=di;
spend=sp;
}
~Shot(void);

//获得位置方向等
int GetX()const
{
return x;
}
void SetX(int xx)
{
x=xx;
}
int GetY()const
{
return y;
}
void SetY(int yy)
{
y=yy;
}
int GetDirect()const
{
return direct;
}
int GetSpend()const
{
return spend;
}
};

#include "stdafx.h"
#include "Shot.h"


Shot::Shot(void)
{
Is_Live=true;
}


Shot::~Shot(void)
{
}

//地图类
#pragma once

#define WindowWith 800
#define WindowHeight 700
enum SORT{Blank,Brink,Grass,Iron};
class Map
{
public:
int map[WindowHeight/50+10][WindowWith/50+1];
public:
Map(void);
~Map(void);

void InitMap();
};

#include "stdafx.h"
#include "Map.h"


Map::Map(void)
{
}


Map::~Map(void)
{
}

void Map::InitMap()
{
for(int i=0;i<=12;i++)
for(int j=0;j<=16;j++)
map[i][j]=Blank;
//我方坦克的家
map[11][8]=Brink;
map[11][9]=Brink;
map[11][10]=Brink;

map[12][8]=Brink;
map[12][10]=Brink;

//其他障碍物

//铁块
map[3][1]=Iron;
map[3][2]=Iron;
map[3][3]=Iron;

map[3][7]=Iron;
map[3][8]=Iron;
map[3][9]=Iron;
map[3][10]=Iron;

map[3][14]=Iron;
map[3][15]=Iron;
map[3][16]=Iron;

//草地
map[4][1]=Grass;
map[4][2]=Grass;
map[4][3]=Grass;
map[5][1]=Grass;
map[5][2]=Grass;
map[5][3]=Grass;
map[4][14]=Grass;
map[4][15]=Grass;
map[4][16]=Grass;
map[5][14]=Grass;
map[5][15]=Grass;
map[5][16]=Grass;

for(int i=8;i<=9;i++)
{
for(int j=1;j<=3;j++)
{
map[i][j]=Grass;
}
}
for(int i=8;i<=9;i++)
{
for(int j=14;j<=16;j++)
{
map[i][j]=Grass;
}
}

//砖块
map[6][1]=Brink;
map[6][2]=Brink;
map[6][3]=Brink;
map[7][1]=Brink;
map[7][2]=Brink;
map[7][3]=Brink;

map[6][14]=Brink;
map[6][15]=Brink;
map[6][16]=Brink;
map[7][14]=Brink;
map[7][15]=Brink;
map[7][16]=Brink;

for(int i=6;i<=11;i++)
{
map[4][i]=Brink;
map[7][i]=Brink;
}
for(int i=5;i<=6;i++)
{
map[i][6]=Brink;
map[i][11]=Brink;
}
}  

视图类,主要的代码都在这里

// TankView.h : CTankView 类的接口
//

#pragma once
#include"AllTank.h"
#include"Map.h"
#include"Shot.h"
#include<vector>

#define WindowWith 800
#define WindowHeight 700

#define ALL 0
#define ID_ENEMY 1
#define ID_SHOT 2

class CTankView : public CView
{
protected: // 仅从序列化创建
CTankView();
DECLARE_DYNCREATE(CTankView)

// 特性
public:
CTankDoc* GetDocument() const;

// 操作
public:
//画坦克
void DrawMyTank(MyTank*& mytank,CDC* pDC);
void DrawEnemyTank(std::vector<EnemyTank>& enemytank,CDC* pDC);
//画地图
void DrawMap(Map m,CDC* pDC);
//画子弹
void DrawShot(std::vector<Shot>& st,CDC* pDC);

void ChangeEP();
void ChangeDirect();

//改变子弹的位置
void ChangeShotP(std::vector<Shot>& st);

//判断敌人是否被打中如果被打中则将其属性Is_Live给赋值为false
void HitEnemy(EnemyTank &ey);

//判断我是否死掉
void HitMe();

//判断地图是否可走
bool Is_Ok();
bool E_Is_Ok(EnemyTank enemy);
//判断是否可以转动
bool Is_Turn(int now_d,int d);

public:
//定义坦克

MyTank *hero;
std::vector<EnemyTank> ey;

//定义地图
Map MyMap;

// 重写
public:
virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// 实现
public:
virtual ~CTankView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnDestroy();
};

#ifndef _DEBUG  // TankView.cpp 中的调试版本
inline CTankDoc* CTankView::GetDocument() const
   { return reinterpret_cast<CTankDoc*>(m_pDocument); }
#endif


// TankView.cpp : CTankView 类的实现
//

#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "Tank.h"
#endif

#include "TankDoc.h"
#include "TankView.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CTankView

IMPLEMENT_DYNCREATE(CTankView, CView)

BEGIN_MESSAGE_MAP(CTankView, CView)
// 标准打印命令
ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
ON_WM_KEYUP()
ON_WM_KEYDOWN()
ON_WM_CHAR()
ON_WM_TIMER()
ON_WM_DESTROY()
END_MESSAGE_MAP()

// CTankView 构造/析构

CTankView::CTankView()
{
// TODO: 在此处添加构造代码

//创建一个我的坦克
hero=new MyTank(300,560,0,5,0);
//创建四个敌人的坦克
for(int i=0;i<4;i++)
{
EnemyTank e(i*240+25,30,2,5,1);
ey.push_back(e);
}

//初始化题图
MyMap.InitMap();

}

CTankView::~CTankView()
{
}

BOOL CTankView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
//  CREATESTRUCT cs 来修改窗口类或样式

return CView::PreCreateWindow(cs);
}

// CTankView 绘制

//判断我是否被击中
void CTankView::HitMe()
{
int my_x=hero->GetX();
int my_y=hero->GetY();
int d=hero->GetDirect();

for(int i=0;i<ey.size();i++)
{
if(ey[i].Is_Live==false)
continue;

for(int j=0;j<ey[i].st.size();j++)
{
if(ey[i].st[j].Is_Live==false)
continue;
int s_x=ey[i].st[j].GetX();
int s_y=ey[i].st[j].GetY();

switch(d)
{
case 0:
case 2:
if(s_x>my_x-20&&s_x<my_x+20&&s_y>my_y-30&&s_y<my_y+30)
hero->Is_Live=false;
break;
case 1:
case 3:
if(s_x>my_x-30&&s_x<my_x+30&&s_y>my_y-20&&s_y<my_y+20)
hero->Is_Live=false;
break;
}
}
}
}

//画我的坦克
void CTankView::DrawMyTank(MyTank*& mytank,CDC* pDC)
{
HitMe();

if(hero->Is_Live==false)
MessageBox(_T("游戏结束"),_T("逗逼你输了!"));

int d=mytank->GetDirect();
int c=mytank->GetColor();

int x=mytank->GetX();
int y=mytank->GetY();

COLORREF *color=NULL;
switch(c)
{
case 0:
color=new COLORREF(RGB(0,255,0));
break;
case 1:
color=new COLORREF(RGB(0,0,255));
}
switch(d)
{
//上
case 0:
//左轮子
pDC->FillSolidRect(x-20,y-30,10,60,*color);
//中间
pDC->FillSolidRect(x-10,y-20,20,40,*color);
//右轮子
pDC->FillSolidRect(x+10,y-30,10,60,*color);
//中间的架子
pDC->FillSolidRect(x-6,y-16,12,32,RGB(255,0,0));
//炮筒
pDC->FillSolidRect(x-1,y-30,2,30,RGB(0,0,255));
break;
//左
case 1:
//左轮子
pDC->FillSolidRect(x-30,y-20,60,10,*color);
//中间
pDC->FillSolidRect(x-20,y-10,40,20,*color);
//右轮子
pDC->FillSolidRect(x-30,y+10,60,10,*color);
//中间的架子
pDC->FillSolidRect(x-16,y-6,32,12,RGB(255,0,0));
//炮筒
pDC->FillSolidRect(x,y-1,30,2,RGB(0,0,255));
break;
//下
case 2:
//左轮子
pDC->FillSolidRect(x-20,y-30,10,60,*color);
//中间
pDC->FillSolidRect(x-10,y-20,20,40,*color);
//右轮子
pDC->FillSolidRect(x+10,y-30,10,60,*color);
//中间的架子
pDC->FillSolidRect(x-6,y-16,12,32,RGB(255,0,0));
//炮筒
pDC->FillSolidRect(x-1,y,2,30,RGB(0,0,255));
break;
//右
case 3:
//左轮子
pDC->FillSolidRect(x-30,y-20,60,10,*color);
//中间
pDC->FillSolidRect(x-20,y-10,40,20,*color);
//右轮子
pDC->FillSolidRect(x-30,y+10,60,10,*color);
//中间的架子
pDC->FillSolidRect(x-16,y-6,32,12,RGB(255,0,0));
//炮筒
pDC->FillSolidRect(x-30,y-1,30,2,RGB(0,0,255));
break;
}
}

//画敌人的坦克
void CTankView::DrawEnemyTank(std::vector<EnemyTank>& enemytank,CDC* pDC)
{

for(int i=0;i<enemytank.size();i++)
{
if(enemytank[i].Is_Live!=true)
continue;

int c=enemytank[i].GetColor();
COLORREF *color=NULL;
switch(c)
{
case 0:
color=new COLORREF(RGB(0,255,0));
break;
case 1:
color=new COLORREF(RGB(0,0,255));
}
int d=enemytank[i].GetDirect();
int x=enemytank[i].GetX();
int y=enemytank[i].GetY();
switch(d)
{
//上
case 0:
//左轮子
pDC->FillSolidRect(x-20,y-30,10,60,*color);
//中间
pDC->FillSolidRect(x-10,y-20,20,40,*color);
//右轮子
pDC->FillSolidRect(x+10,y-30,10,60,*color);
//中间的架子
pDC->FillSolidRect(x-6,y-16,12,32,RGB(255,0,0));
//炮筒
pDC->FillSolidRect(x-1,y-30,2,30,RGB(0,255,0));
break;
//左
case 1:
//左轮子
pDC->FillSolidRect(x-30,y-20,60,10,*color);
//中间
pDC->FillSolidRect(x-20,y-10,40,20,*color);
//右轮子
pDC->FillSolidRect(x-30,y+10,60,10,*color);
//中间的架子
pDC->FillSolidRect(x-16,y-6,32,12,RGB(255,0,0));
//炮筒
pDC->FillSolidRect(x,y-1,30,2,RGB(0,255,0));
break;
//下
case 2:
//左轮子
pDC->FillSolidRect(x-20,y-30,10,60,*color);
//中间
pDC->FillSolidRect(x-10,y-20,20,40,*color);
//右轮子
pDC->FillSolidRect(x+10,y-30,10,60,*color);
//中间的架子
pDC->FillSolidRect(x-6,y-16,12,32,RGB(255,0,0));
//炮筒
pDC->FillSolidRect(x-1,y,2,30,RGB(0,255,0));
break;
//右
case 3:
//左轮子
pDC->FillSolidRect(x-30,y-20,60,10,*color);
//中间
pDC->FillSolidRect(x-20,y-10,40,20,*color);
//右轮子
pDC->FillSolidRect(x-30,y+10,60,10,*color);
//中间的架子
pDC->FillSolidRect(x-16,y-6,32,12,RGB(255,0,0));
//炮筒
pDC->FillSolidRect(x-30,y-1,30,2,RGB(0,255,0));
break;
}
}
}

//画地图
void CTankView::DrawMap(Map m,CDC* pDC)
{
for(int i=1;i<=10;i++)
{
for(int j=1;j<=16;j++)
{
switch(m.map[i][j])
{
case Brink:
pDC->FillSolidRect((j-1)*50,(i-1)*50,50,50,RGB(100,100,100));
break;
case Grass:
pDC->FillSolidRect((j-1)*50,(i-1)*50,50,50,RGB(0,200,0));
break;
case Iron:
pDC->FillSolidRect((j-1)*50,(i-1)*50,50,50,RGB(255,255,255));
}
}
}
for(int i=11;i<=12;i++)
{
for(int j=1;j<=16;j++)
{
if(m.map[i][j]==Brink)
{
if(i==11&&j==9)
pDC->FillSolidRect((j-1)*50-25,(i-1)*50,50+25,25,RGB(100,100,100));
pDC->FillSolidRect((j-1)*50,(i-1)*50,25,50,RGB(100,100,100));
}
}
}
}

//画子弹
void CTankView::DrawShot(std::vector<Shot>& st,CDC* pDC)
{
for(int i=0;i<st.size();i++)
{
if(st[i].Is_Live==false)
continue;
pDC->FillSolidRect(st[i].GetX()-1,st[i].GetY()-1,2,2,RGB(255,0,0));
}
}

BOOL is_create=FALSE;
void CTankView::OnDraw(CDC* pDC)
{
CTankDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: 在此处为本机数据添加绘制代码

if(!is_create)
{
//设置全部画面的定时器

SetTimer(ALL,800,NULL);

//设置敌人坦克的定时器

srand((unsigned)time(NULL));
SetTimer(ID_ENEMY,100,NULL);

//设置子弹的定时器
SetTimer(ID_SHOT,100,NULL);

is_create=TRUE;
}

CRect rect;
GetClientRect(&rect);
pDC->FillSolidRect(rect,RGB(0,0,0));

//绘制我的坦克

DrawMyTank(hero,pDC);
DrawEnemyTank(ey,pDC);
DrawMap(MyMap,pDC);
//画我的子弹
DrawShot(hero->st,pDC);
//画敌人的子弹
for(int i=0;i<ey.size();i++)
{
if(ey[i].Is_Live==false)
continue;
DrawShot(ey[i].st,pDC);
}
}


// CTankView 打印

BOOL CTankView::OnPreparePrinting(CPrintInfo* pInfo)
{
// 默认准备
return DoPreparePrinting(pInfo);
}

void CTankView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加额外的打印前进行的初始化过程
}

void CTankView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加打印后进行的清理过程
}


// CTankView 诊断

#ifdef _DEBUG
void CTankView::AssertValid() const
{
CView::AssertValid();
}

void CTankView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}

CTankDoc* CTankView::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTankDoc)));
return (CTankDoc*)m_pDocument;
}
#endif //_DEBUG


// CTankView 消息处理程序


void CTankView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值


CView::OnKeyUp(nChar, nRepCnt, nFlags);
}

bool CTankView::Is_Ok()
{
int x=hero->GetX();
int y=hero->GetY();
int t=hero->GetSpend();
int d=hero->GetDirect();
switch(d)
{
case 0:
if(MyMap.map[(y-t-30)/50+1][x/50+1]==Iron||MyMap.map[(y-t-30)/50+1][x/50+1]==Brink)
return false;
break;
case 1:
if(MyMap.map[y/50+1][(x+t+30)/50+1]==Iron||MyMap.map[y/50+1][(x+t+30)/50+1]==Brink)
return false;
break;
case 2:
if(MyMap.map[(y+t+30)/50+1][x/50+1]==Iron||MyMap.map[(y+t+30)/50+1][x/50+1]==Brink)
return false;
break;
case 3:
if(MyMap.map[y/50+1][(x-t-30)/50+1]==Iron||MyMap.map[y/50+1][(x-t-30)/50+1]==Brink)
return false;
break;
}
return true;
}

bool CTankView::Is_Turn(int now_d,int d)
{
if(now_d==d)
return true;
else if(now_d+d==2||now_d+d==4)
return true;
int x=hero->GetX();
int y=hero->GetY();
int tx=0,ty=0;
switch(d)
{
case 0:
case 2:
tx=x/50;
ty=(y-30)/50;
if(MyMap.map[ty][tx]!=Blank||MyMap.map[y][tx]!=Grass)
return false;
ty=(y+30)/50;
if(MyMap.map[ty][tx]!=Blank||MyMap.map[y][tx]!=Grass)
return false;
break;
case 1:
case 3:
ty=y/50;
tx=(x-30)/50;
if(MyMap.map[ty][tx]!=Blank||MyMap.map[y][tx]!=Grass)
return false;
tx=(x+30)/50;
if(MyMap.map[ty][tx]!=Blank||MyMap.map[y][tx]!=Grass)
return false;
break;
}
return true;
}

void CTankView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(GetAsyncKeyState(VK_DOWN))
{
hero->SetDirect(2);
if(!Is_Ok())
return ;
int y=hero->GetY();
if(y+30+110<WindowHeight)
hero->SetY(y+hero->GetSpend());
}
else if(GetAsyncKeyState(VK_UP))
{
hero->SetDirect(0);
if(!Is_Ok())
return ;
int y=hero->GetY();
if(y>30)
hero->SetY(y-hero->GetSpend());
}
else if(GetAsyncKeyState(VK_LEFT))
{
hero->SetDirect(3);
if(!Is_Ok())
return ;
int x=hero->GetX();
if(x>30)
hero->SetX(x-hero->GetSpend());
}
else if(GetAsyncKeyState(VK_RIGHT))
{
hero->SetDirect(1);
if(!Is_Ok())
return ;
int x=hero->GetX();
if(x+30+20<WindowWith)
hero->SetX(x+hero->GetSpend());
}
else if(GetAsyncKeyState(VK_NUMPAD1))
{
Shot s(hero->GetX(),hero->GetY(),hero->GetDirect(),10);//<<---子弹的速度
int nSize=hero->st.size();
int Shot_count=0;
for(int i=0;i<nSize;i++)
{
if(hero->st[i].Is_Live==true)
Shot_count++;
}
if(Shot_count>4)
return ;
hero->st.push_back(s);
}
CDC *pDC=GetDC();
OnDraw(pDC);

CView::OnKeyDown(nChar, nRepCnt, nFlags);
}


void CTankView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

CView::OnChar(nChar, nRepCnt, nFlags);
}

//判断敌人是否被打中如果被打中则将其属性Is_Live给赋值为false
void CTankView::HitEnemy(EnemyTank &ey)
{
int nSize=hero->st.size();
for(int i=0;i<nSize;i++)
{
if(ey.Is_Live==false)
return ;

int sx=hero->st[i].GetX();
int sy=hero->st[i].GetY();

int e_x=ey.GetX();
int e_y=ey.GetY();

int d=ey.GetDirect();

switch(d)
{
case 0:
case 2:
if(sx>e_x-20&&sx<e_x+20&&sy>e_y-30&&sy<e_y+30)
ey.Is_Live=false;
break;
case 1:
case 3:
if(sx>e_x-30&&sx<e_x+30&&sy>e_y-20&&sy<e_y+20)
ey.Is_Live=false;
}
}
}

//判断敌人是否可走
bool CTankView::E_Is_Ok(EnemyTank enemy)
{
int x=enemy.GetX();
int y=enemy.GetY();
int t=enemy.GetSpend();
int d=enemy.GetDirect();
switch(d)
{
case 0:
if(MyMap.map[(y-t-30)/50+1][x/50+1]==Iron||MyMap.map[(y-t-30)/50+1][x/50+1]==Brink)
return false;
break;
case 1:
if(MyMap.map[y/50+1][(x+t+30)/50+1]==Iron||MyMap.map[y/50+1][(x+t+30)/50+1]==Brink)
return false;
break;
case 2:
if(MyMap.map[(y+t+30)/50+1][x/50+1]==Iron||MyMap.map[(y+t+30)/50+1][x/50+1]==Brink)
return false;
break;
case 3:
if(MyMap.map[y/50+1][(x-t-30)/50+1]==Iron||MyMap.map[y/50+1][(x-t-30)/50+1]==Brink)
return false;
break;
}
return true;
}

//改变敌人坦克的位置
void CTankView::ChangeEP()
{
int X,Y;
for(int i=0;i<ey.size();i++)
{
//判断敌人是否被打中
HitEnemy(ey[i]);

//判断敌人是否死掉
if(ey[i].Is_Live==false)
continue;

//判断敌人是否可走
if(!E_Is_Ok(ey[i]))
continue;

int d=ey[i].GetDirect();
switch(d)
{
case 0:
Y=ey[i].GetY();
if(Y>30)
ey[i].SetY(Y-ey[i].GetSpend());
break;
case 1:
X=ey[i].GetX();
if(X+30+20<WindowWith)
ey[i].SetX(X+ey[i].GetSpend());
break;
case 2:
Y=ey[i].GetY();
if(Y+30+110<WindowHeight)
ey[i].SetY(Y+ey[i].GetSpend());
break;
case 3:
X=ey[i].GetX();
if(X>30)
ey[i].SetX(X-ey[i].GetSpend());
break;
}
}
}
int T=0;
void CTankView::ChangeDirect()
{
T++;
for(int i=0;i<ey.size();i++)
{
if(ey[i].Is_Live==false)
continue;

//让敌人也发射子弹

//限定敌人子弹数量
//这段代码有问题
/*
int Shot_count=0;
for(int i=0;i<ey[i].st.size();i++)
{
if(ey[i].st[i].Is_Live==true)
Shot_count++;
}
if(Shot_count>4)
continue;
*/
if(T%3!=0)
continue;
Shot s(ey[i].GetX(),ey[i].GetY(),ey[i].GetDirect(),10);
ey[i].st.push_back(s);

int d=rand()%4;
ey[i].SetDirect(d);
}
}

//改变子弹的位置
void CTankView::ChangeShotP(std::vector<Shot>& st)
{
int X=0,Y=0;
for(int i=0;i<st.size();i++)
{
if(st[i].Is_Live!=true)
continue;
int d=st[i].GetDirect();
switch(d)
{
case 0:
Y=st[i].GetY();
if(Y>30)
st[i].SetY(Y-st[i].GetSpend());
else
st[i].Is_Live=false;
break;
case 1:
X=st[i].GetX();
if(X+30+20<WindowWith)
st[i].SetX(X+st[i].GetSpend());
else
st[i].Is_Live=false;
break;
case 2:
Y=st[i].GetY();
if(Y+30+110<WindowHeight)
st[i].SetY(Y+st[i].GetSpend());
else
st[i].Is_Live=false;
break;
case 3:
X=st[i].GetX();
if(X>30)
st[i].SetX(X-st[i].GetSpend());
else
st[i].Is_Live=false;
break;
}
}
}

void CTankView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

if(hero->Is_Live==false)
{
OnDestroy();
return ;
}

CDC* pDC=GetDC();
switch(nIDEvent)
{
case ALL:
ChangeDirect();
OnDraw(pDC);
break;
case ID_ENEMY:
//改变敌人坦克的位置
ChangeEP();
OnDraw(pDC);
break;
case ID_SHOT:
//改变子弹的位置
ChangeShotP(hero->st);
for(int i=0;i<ey.size();i++)
{
if(ey[i].Is_Live==false)
continue;
ChangeShotP(ey[i].st);
}
OnDraw(pDC);
break;
}
CView::OnTimer(nIDEvent);
}


void CTankView::OnDestroy()
{
CView::OnDestroy();

KillTimer(ALL);
KillTimer(ID_ENEMY);
KillTimer(ID_SHOT);

// TODO: 在此处添加消息处理程序代码
}
其他部分的代码我就不贴了,基本建立工程就能生成 

你可能感兴趣的:(游戏制作第四棒——坦克大战)