C语言项目实战—坦克大战

闲暇时间写的一个坦克大战,有些功能还没完善,但是给新手参考学习还是不错的。先看看效果图:

 

 

看看各部分代码吧

一、场景管理

1、背景

#include "stdafx.h"



CBackGround::CBackGround(TSTRING name)
{
CPicture*_pPic= CResManager::GetInstance()->GetPicture(name);
	if (_pPic==nullptr)
	{
		assert (_T("pic is null"));
	}
	m_nShowWidth = _pPic->GetWidth();
	m_nShowHeight = _pPic->GetHeight();
	Texture = CResManager::GetInstance()->GetPicture(name)->GetTexture();
	m_sDesPos = { 0.0f,0.0f,0.0f };
}

CBackGround::~CBackGround()
{
}

void CBackGround::Render()
{
	m_pSprite->Begin(D3DXSPRITE_ALPHABLEND);

	if (m_sDesPos.y >= 0)
		m_pSprite->Draw(Texture, NULL, NULL, &D3DXVECTOR3(0, m_sDesPos.y - m_nShowHeight, 0), 0xffffffff);
	m_pSprite->Draw(Texture, NULL, NULL, &D3DXVECTOR3(0, m_sDesPos.y, 0), 0xffffffff);
	
	m_pSprite->End();
}

void CBackGround::Update()
{
	if (m_sDesPos.y < m_nWindowHeight)
		m_sDesPos.y += 1;
	else
		m_sDesPos.y = m_nWindowHeight-m_nShowHeight;
}

2、场景

#include "stdafx.h"



CScene::CScene()
{
}


CScene::~CScene()
{
}

3、开始场景

#include "stdafx.h"


CBeginScene::CBeginScene()
{
	background = new CBackGround(_T("ditu.png"));//开始页面的背景
	m_begin = new CUIButton(250,200,_T("OK.png"), _T("OK1.png"), _T("OK2.png"));//开始按键
	m_over = new CUIButton(250,260,_T("T.png"), _T("T1.png"), _T("T2.png"));//退出按键
}

CBeginScene::~CBeginScene()
{
	if (background)
		delete background;
	if (m_begin)
		delete m_begin;
	if (m_over)
		delete m_over;

}

void CBeginScene::Update()
{
	m_begin->Wndpfoc();//调消息处理函数
	m_over->Wndpfoc();//调消息处理函数
	if (m_begin->IsButtonDown())
	{
		CSceneManager::GetInstance()->SetCurSceneName(_T("gamescene"));//切换场景
		CSceneManager::GetInstance()->RemoveScene(_T("beginscene")); 
	}
	else if(m_over->IsButtonDown())
	{
		PostQuitMessage(0);    //退出游戏
	}
	
}


void CBeginScene::Render()
{	
	background->Render();
	m_begin->Draw();
	m_over->Draw();
}

void  CBeginScene::ClickButton()
{
	/*CSceneManager::GetInstance()->SetCurSceneName(_T("menuscene"));
	CSceneManager::GetInstance()->RemoveScene(_T("beginscene"));*/
}



4、游戏场景

4.1、地图

#include "stdafx.h"



Map::Map()
{
}


Map::~Map()
{
}

void Map::Init(TSTRING _name)
{
	m_Grass.Init(_T("map1.png"));//草
	m_Water.Init(_T("map2.png"));//水
	m_Brick.Init(_T("map3.png"));//砖
	m_Lron.Init(_T("map.png"));  //铁
	m_Boss.Init(_T("Dea1.png"));//Boss
	FILE* fp;
#ifdef UNICODE
	char*file = CUtility::CU_U2A(_name.c_str());       //从xml文件中读取图片内容
#else
	const char*file = fileName.c_str();
#endif
	fopen_s(&fp, file, "r");//找到文件名
	if (0 == fp)            //是否为空
		return;
	fscanf_s(fp, "(%d,%d)\r\n", &m_Xmap, &m_Ymap);//取出行列
	if (m_Xmap != 0 && m_Ymap != 0)               //判断行列不等于零
	{
		//开二维数组的堆
		m_map = new int*[m_Ymap];        //先new行数
		for (int i = 0; i < m_Ymap; ++i)//开始去循环去new 列数
		{
			m_map[i] = new int[m_Xmap];
		}
		//读取地图数据
		for (int i = 0; i < m_Ymap; ++i) //循环读取TXT数据
		{
			for (int j = 0; j < m_Xmap; ++j)
			{
				fscanf_s(fp, "%d,", &m_map[i][j]);
			}
			fscanf_s(fp, "\r\n");
		}
		fclose(fp);	//关闭文件
	}
}

void Map::Render()
{
	for (size_t i = 0; i < m_Ymap; i++)//循环行
	{
		for (size_t j = 0; j < m_Xmap; j++)//循环列
		{
			D3DXVECTOR3 _desPos = { FLOAT(j * 28), FLOAT(i * 28), 0 };//画的像素大小
			
			switch (m_map[i][j])
			{
			case Grass: //草的地图块
			{
				m_Grass.SetDesPos(_desPos);
				m_Grass.Render();
			}
			break;
			case water:
			{
				m_Water.SetDesPos(_desPos);
				m_Water.Render();
			}
			break;
			case Brick://砖的地图块
			{
				m_Brick.SetDesPos(_desPos);
				m_Brick.Render();
			}
			break;
			case Lron://铁的地图块
			{
				m_Lron.SetDesPos(_desPos);
				m_Lron.Render();
			}
			break;
			case Boss:
			{
				m_Boss.SetDesPos(_desPos);
				m_Boss.Render();
			}
			break;
			default:
				break;
			}
		}
	}
}

4.2、敌机

#include "stdafx.h"



CEnemy::CEnemy(TSTRING n_name,TSTRING _name, TSTRING _name1, TSTRING _name2, TSTRING _name3, FLOAT _x, FLOAT _y)
{
	m_nDir = DOWN;
	m_Tname = n_name;     //坦克路径
	m_Enmeyname = _name; //动画上
	m_Enmeyname1 = _name1;//动画下
	m_Enmeyname2 = _name2;//动画左
	m_Enmeyname3 = _name3;//动画右
	m_x = _x;  //初始位置
	m_y = _y; //初始位置
	SetDesPos({ m_x,m_y,0 });                //敌机初始位置
	m_speed = 3;                             //移动速度
	m_fbullte = false;                       //开始不发子弹
	vector<TSTRING>animationName;            //动画容器
	animationName.push_back(m_Enmeyname);    //往上动画
	animationName.push_back(m_Enmeyname1);   //往下动画
	animationName.push_back(m_Enmeyname2);   //往左动画
	animationName.push_back(m_Enmeyname3);   //往右动画
	Init(animationName);
	RECT _rec = CResManager::GetInstance()->GetAnimationFrame(m_Tname)->GetRect();
	SetShowWidth(_rec.right - _rec.left); //显示在屏幕上的宽
	SetShowHeight(_rec.bottom - _rec.top);//显示在屏幕上的高
	SetCenter({ 0.0f,0.0f,0 });//设置锚点
	SetCollideRect(_rec);
}


CEnemy::~CEnemy()
{
}

VOID CEnemy::PlayerDir()
{

	srand(time(0));
	int m_time = rand() % 4 + 1;
	switch (m_time)
	{
	case 1:
	{
		m_nDir = UP;
		bIsMoving = TRUE;
	}
	break;

	case  2:

	{
		m_nDir = DOWN;
		bIsMoving = TRUE;
	}
	break;
	case 3:
	{
		m_nDir = LEFT;
		bIsMoving = TRUE;
	}
	break;
	case 4:
	{
		m_nDir = RIGHT;

		bIsMoving = TRUE;
	}
	break;
	default:
		break;
	}
	
	


	
}

void CEnemy::Move()
{
	
		switch (m_nDir)
		{
			
		case UP:
		{
			if (m_curAnimation != m_Enmeyname)
			{
				SetCurAnimation(m_Enmeyname);
			}
			m_sSpeed = { 0,-1 * m_speed,0 };
			
		}
		break;
		case DOWN:
		{
			if (m_curAnimation != m_Enmeyname1)
			{
				SetCurAnimation(m_Enmeyname1);
			}
				m_sSpeed = { 0,m_speed,0 };        //移动速度;
		}
		break;
		case LEFT:
		{
			if (m_curAnimation != m_Enmeyname2)
			{
				SetCurAnimation(m_Enmeyname2);
			}
			
			m_sSpeed = { -1 * m_speed,0,0 };
		}
		break;
		case RIGHT:
		{
			if (m_curAnimation != m_Enmeyname3)
			{
				SetCurAnimation(m_Enmeyname3);
			}
			
				m_sSpeed = { m_speed, 0,0 };
		
		}
		break;
		/*default:
			break;*/
		}
		Collision();
	if (bIsMoving)
	{
		m_sDesPos += m_sSpeed;
		Update();
	}
	else if (m_nDir == NONE)
	{

		Update();
	}
}

VOID CEnemy::Collision()
{
	//临时变量
	int dir = m_nDir;           //方向
	int speed = m_speed;        //速度
	int playerX = m_sDesPos.x; //x坐标位置
	int playerY = m_sDesPos.y;//y坐标位置
	switch (m_nDir)
	{
	case UP:
		playerY -= speed;
		break;
	case DOWN:
		playerY += speed;
		break;
	case LEFT:
		playerX -= speed;
		break;
	case RIGHT:
		playerX += speed;
		break;
	}
	//当前位置加上移动向量
	//temp_pos += v;
	//用下一时刻位置图片所占的格子去判断碰撞
	//临时变量
	int playerWidth = GetShowWidth();   //玩家宽
	int playerHeight = GetShowHeight(); //玩家高
	int startRow = (playerY + 2) / 28;               //行的开始点
	int endRow = (playerY + playerHeight - 2) / 28;//行的结尾点
	int startCol = (playerX + 2) / 28;               //列的开始点
	int endCol = (playerX + playerWidth - 2) / 28;    //列的结尾点
	switch (m_nDir)
	{
	case  UP:
	{
		for (int i = startCol; i <= endCol; i++)
			if (m_map1->m_map[startRow][i] > Grass)
			{
				bIsMoving = false;
				break;
			}
		/*else
		{
		if (m_map1->m_map[(INT)playerY / 28 - 1][(INT)playerX / 28] == Grass)
		{
		if (m_map1->m_map[startRow][i] == Grass)
		{
		bIsMoving = false;
		break;
		}
		}
		}*/

	}
	break;
	case RIGHT:
	{

		for (int i = startRow; i <= endRow; i++)
			if (m_map1->m_map[i][endCol] > Grass)
			{
				bIsMoving = false;
				break;
			}
		/*else
		{
		if (m_map1->m_map[(INT)playerY / 28][(INT)playerX / 28 + 1] == Grass)
		{
		if (m_map1->m_map[startRow][i] == Grass)
		{
		bIsMoving = false;
		break;
		}
		}
		}
		*/
	}
	break;
	case DOWN:
	{

		for (int i = startCol; i <= endCol; i++)
			if (m_map1->m_map[endRow][i] > Grass)
			{
				bIsMoving = false;
				break;
			}
		/*else
		{
		if (m_map1->m_map[(INT)playerY / 28 - 1][(INT)playerX / 28] == Grass)
		{
		if (m_map1->m_map[startRow][i] == Grass)
		{
		bIsMoving = false;
		break;
		}
		}
		}*/

	}
	break;
	case LEFT:
	{

		for (int i = startRow; i <= endRow; i++)
			if (m_map1->m_map[i][startCol] > Grass)
			{
				bIsMoving = false;
				break;
			}
		/*else
		{
		if (m_map1->m_map[(INT)playerY / 28][(INT)playerX / 28-1] == Grass)
		{
		if (m_map1->m_map[startRow][i] == Grass)
		{
		bIsMoving = false;
		break;
		}
		}
		}*/

	}
	break;

	default:
		break;
	}
}

4.3、技能

#include "stdafx.h"



CProps::CProps()
{
	m_mTank.Init(_T("pro.png"));
	CResManager::GetInstance()->GetAnimation(_T("pro.png"))->m_fTime = 0.2;
	m_mLron.Init(_T("pro2.png"));
	CResManager::GetInstance()->GetAnimation(_T("pro2.png"))->m_fTime = 0.2;
	m_mzhadan.Init(_T("pro3.png"));
	CResManager::GetInstance()->GetAnimation(_T("pro3.png"))->m_fTime = 0.2;
	m_fTemp = 0;
	m_t = 0.1;
}


CProps::~CProps()
{
}

VOID CProps::RenderTAank(INT _x, INT _y)
{
	if (m_fTemp >= 2 || m_fTemp <= -2)
	{
		m_t *= -1;
	}
	m_fTemp = m_fTemp + m_t;
	m_mTank.SetDesPos({ (FLOAT)_x * 28,(FLOAT)_y * 28 + m_fTemp,0 });
	m_mTank.Update();
	m_mTank.UpdateMAatrix();
	m_mTank.Render();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值