闲暇时间写的一个坦克大战,有些功能还没完善,但是给新手参考学习还是不错的。先看看效果图:
看看各部分代码吧
一、场景管理
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();
}