MFC与坦克大战系列(奇迹冬瓜)---chapter3(坦克属性定义与坦克的平滑移动)

MFC实现坦克大战(附完整源码) 阅读详情

今天我们继续坦克大战系列。我将沿用chapter2的代码继续为大家讲解。由于计划的修订第三节先完成我方坦克的移动。主要的操作流程如下:

(一)首先打开上一节的代码,然后在资源解决方案中头文件和主文件的地方添加程序要自己定义的坦克的类和方法。

主要操作位右键头文件->头文件->新建项->.h文件 命名为Thing

在Thing.h里面添加的代码如下 附图。

#include "stdafx.h"
#include "Resource.h"

#if !defined(_Thing_H_)
#define _Thing_H_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class Tank
{
public:
	int HP;          //黄色坦克为我方坦克 HP 0-5 初始为3  绿色为敌方坦克 HP 0-3 初始为3  红色坦克为敌方坦克 HP 0-5 初始为5
	int Direct;      //坦克有四个方向行走 分别为 up-1 right-2 down-3 left-4
	int Speed;       //坦克有行走速度 我方坦克(黄)-初始速度为10 敌方坦克红色初始为10 绿色初始为20
	int Attribute;   //坦克有被击中没有的属性 初始为1 当HP为0时 attribute为0
	int IsPlayer;    //1是我方坦克 2是敌军坦克
	int Mark;        //标记坦克数量(加上我方坦克最大数量为9) 0-我方坦克 1-8地方坦克
	CPoint Site;     //坦克有自己的位置
	CBitmap Image;   //坦克有自己本身的图像
	HBITMAP HImage;  //坦克有自己的加载图像格式
	bool move;

	Tank(){};        //重写构造函数
	///~Tank(){};
	Tank(Tank &tank){}
	 //析构函数
public:
	bool InitTank(int H,int Dir,int Spe,int Attr,int IsP,int Ma,CPoint Si);  //初始化坦克非图像计算的值
	bool LoadImage();   //初始化坦克图像计算的值
	bool Collision(CPoint *tank,int n);   //碰撞检测
	void ChaseMode(CPoint player); //追逐模式
	void RandomMode();//随机模式
	
};

class Bullet
{
public:
	int Direct;          //子弹有方向 为坦克初始化时候的方向
	int Attribute;       //子弹有属性 1为子弹显示 0为子弹消失
	CPoint Site;         //子弹有位置 根据发射坦克位置来初始化
	int Speed;           //子弹有速度 速度为10
	int IsPlayer;        //通过确定是否玩家发射子弹来确认子弹属性
	CBitmap BImage;      //用于子弹加载位图
	HBITMAP HBImage;     //用于装换位图格式

	Bullet(){};
	Bullet(Bullet &bullet){};
	
public:
	bool InitBullet(int Dir,int Attr,int Spe,int IsP,CPoint Si);
	bool LoadImage();
	int Collision(CPoint *tank,int n);
	bool InitAgain(CPoint p,int Dir);
	bool BulletMove();
};

class Props
{
public:
	int Attribute;            //道具属性1为出现 0为消失
	int Mark;                 //道具标识 0为停止时间 1为传送任意位置 2为坦克加血 3为无敌 4为坦克全减1血
	int IsPlayer;             //判断是否玩家吃到道具
	CBitmap PImage;           //用于道具加载位图
	HBITMAP HPImage;          //用于装换位图格式
	CPoint Site;

	Props(){};
	Props(Props &props){};
	
public:
	bool InitProps(int Attr,int Ma,int IsP,CPoint Si);
	bool LoadImage();
	void GetSite(CPoint *tank,int n);
};

#endif // !defined(_Thing_H_)


 

当然 我们今天用到的只有坦克的类和方法。我写类的变量和方法的时候已经做了详细的注释相信大家都看的懂。

接下来在源文件中添加

右键单击源文件-〉添加-〉新建项-〉.cpp文件 命名为Thing

在里面添加实现的方法

在添加方法前我先导入两幅坦克的图片进去四个方向。一个我方坦克。一个敌方坦克。我用RGB(200,200,200)的tank背景。为了更好的透明处理

图片如下 像素240*60

再次声明两幅tank是网上的素材进行2次ps。只做学习之用。不做任何其它用途。

然后将两幅图片进行导入(两幅都是.bmp格式。资源导入的方法在第二节就已经进行了详细的说明。请大家参考chapter2的背景导入那儿)

然后在resources.h里面可以看到两幅图片的ID

 接着可以在我们建好的thing.cpp文件中添加以下代码。代码里面只有这一节用会用到的两个方法。

#include "stdafx.h"
#include "Resource.h"
#include "Thing.h"
#include<math.h>
#include<time.h>
#include<stdlib.h>

bool Tank::InitTank(int H,int Dir,int Sp,int Attr,int IsP,int Ma,CPoint Si)
{
	HP=H;
	Direct=Dir;
	Speed=Sp;
	Attribute=Attr;
	IsPlayer=IsP;
	Mark=Ma;
	Site=Si;
	move=false;
	return true;
}

bool Tank::LoadImage()
{
	1==IsPlayer?Image.LoadBitmap(IDB_BITMAP8):Image.LoadBitmap(IDB_BITMAP11);
	HImage=HBITMAP(Image);
	return true;
}


 

当然类里面的方法没添加完。我只添加这一节我们会用到的方法。第一个是初始化tank的各项属性。第二个是加载关联的图像。

在TankGame1Dlg.h中添加红色部分。我们要引用自己写的类及方法。也就是接口函数。

接下来我们要在这里面添加几行代码

红色部分为相较于上一节进行的增加和改动。并且用红色字体进行了说明。

在TankGame1Dlg.cpp里面添加如下

DWORD WINAPI InitTank(LPVOID lpParam)
{
	CTankGame1Dlg *c=(CTankGame1Dlg*)lpParam;

	CPoint p;
	p.x=0,p.y=650;
	c->Player.InitTank(3,1,8,1,1,0,p);
	c->Player.LoadImage();

	
	c->KeyDown=false;
	c->KeyLeft=false;
	c->KeyUp=false;
	c->KeyRight=false;
	c->control=true;
	c->controlend=true;
	return TRUE;
}

BOOL CTankGame1Dlg::PreTranslateMessage(MSG* pMsg)
{
	bool Judge=false;
	if (pMsg-> message == WM_KEYDOWN)
	{

		if(pMsg-> wParam== VK_UP)
		{
			KeyUp=true;
		}
		if(pMsg-> wParam== VK_DOWN)
		{
			KeyDown=true;
		}
		if(pMsg-> wParam== VK_LEFT)
		{
			KeyLeft=true;
		}
		if(pMsg-> wParam== VK_RIGHT)
		{
			KeyRight=true;
		}
		if(pMsg->wParam==VK_ESCAPE)
		{
			control=false;
			controlend=false;
		}
	 }
	if(pMsg-> message == WM_KEYUP)
	{
		if(pMsg-> wParam== VK_UP)
		{
			KeyUp=false;
		}
		if(pMsg-> wParam== VK_DOWN)
		{
			KeyDown=false;
		}
		if(pMsg-> wParam== VK_LEFT)
		{
			KeyLeft=false;
		}
		if(pMsg-> wParam== VK_RIGHT)
		{
			KeyRight=false;
		}
	}
	return CDialog::PreTranslateMessage(pMsg);
}

DWORD WINAPI PlayerMove(LPVOID lpParam)
{
	CTankGame1Dlg *c=(CTankGame1Dlg*)lpParam;
	while(c->controlend)
	{
		if(true==c->KeyUp)
		{
			c->Player.Direct=1;
			c->Player.Site.y-=c->Player.Speed;
			::Sleep(40);
			continue;
		}
		if(true==c->KeyDown)
		{
			c->Player.Direct=3;
			c->Player.Site.y+=c->Player.Speed;
			::Sleep(40);
			continue;
		}
		if(true==c->KeyLeft)
		{
			c->Player.Direct=4;
			c->Player.Site.x-=c->Player.Speed;
			::Sleep(40);
			continue;
		}
		if(true==c->KeyRight)
		{
			c->Player.Direct=2;
			c->Player.Site.x+=c->Player.Speed;
			::Sleep(40);
			continue;
		}
		
		::Sleep(1);
	}
	return TRUE;
}


 

上一节讲到的画图线程的改动如下同样在TankGame1.cpp里

DWORD WINAPI MyPaint(LPVOID lpParam)              //贴图线程
{
	CTankGame1Dlg *c=(CTankGame1Dlg*)lpParam;
	HWND hWnd= c->GetSafeHwnd();                   //获取屏幕的句柄
	c->hdc = ::GetDC(hWnd);                        //获取屏幕的DC 
	c->mdc =::CreateCompatibleDC(c->hdc);          //关联和屏幕兼容的内存DC
	c->bufdc =::CreateCompatibleDC(c->hdc);        //关联和屏幕兼容的缓冲DC
	RECT rect;   
	::GetWindowRect(hWnd,&rect);                   //获取屏幕的大小
	c->hBitmap =::CreateCompatibleBitmap(c->hdc,rect.right,rect.bottom);  //让内存DC关联的位图设置大小
	SelectObject(c->mdc,c->hBitmap); //进行关联
	c->Back.LoadBitmap(IDB_BITMAP1); //载入关卡的地图
	c->BackGround=HBITMAP(c->Back);  //转换光卡的地图格式
	while(c->control)
	{
		SelectObject(c->bufdc,c->BackGround);                               //缓冲DC关联关卡1的地图
		BitBlt(c->mdc,0,0,rect.right,rect.bottom,c->bufdc,0,0,SRCCOPY);     //从缓冲DC贴图到内存DC
	    if(1==c->Player.Attribute)
		{
			SelectObject(c->bufdc,c->Player.HImage);
			switch(c->Player.Direct)
			{
			case 1:TransparentBlt(c->mdc,c->Player.Site.x,c->Player.Site.y,60,60,c->bufdc,0,0,60,60,RGB(200,200,200));break;
			case 2:TransparentBlt(c->mdc,c->Player.Site.x,c->Player.Site.y,60,60,c->bufdc,60,0,60,60,RGB(200,200,200));break;
			case 3:TransparentBlt(c->mdc,c->Player.Site.x,c->Player.Site.y,60,60,c->bufdc,120,0,60,60,RGB(200,200,200));break;
			case 4:TransparentBlt(c->mdc,c->Player.Site.x,c->Player.Site.y,60,60,c->bufdc,180,0,60,60,RGB(200,200,200));break;
			}
		}
		BitBlt(c->hdc,0,0,rect.right,rect.bottom,c->mdc,0,0,SRCCOPY);       //从内存DC贴图到屏幕DC
		::Sleep(1);                                                         //休眠一个毫秒
	}
	//::ReleaseDC(c->hdc);
    ::ReleaseDC(hWnd,c->hdc);
	::DeleteDC(c->mdc);
	::DeleteDC(c->bufdc);
	return TRUE;
}


 

在初始化函数里面增加启动的两个线程

最后就能看见坦克平滑的四个方位的移动了

如下图

 

下一节会为大家讲解碰撞检测和AI寻找路径的问题。

附上这一节的代码。大家可以对着图文参考。不要任何下载积分。

点击打开链接

C++与MFC框架打造双人坦克大战游戏实战 本文还有配套的精品资源,点击获取 简介:《坦克大战双人版》是一款经典游戏,采用C++编程语言和Microsoft Foundation Classes (MFC)框架进行开发。游戏中C++的面向对象特性被充分利用,用于模拟坦克、子弹、障碍物等实体,并通过继承、封装和多态性设计游戏元素。MFC框架简化了Windows应用程序的开发,提供了用户界面构建和事件驱动编程的支持。双人... 阅读详情

相关推荐

MFC 实现的坦克大战

MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战MFC 实现的坦克大战

VC6.0 MFC 单文档 坦克大战游戏 基础入门

坦克大战游戏 一、游戏简述 在顶部随机产生三种不同形状的敌机(用矩形、三角形、圆形表示),每秒产生一个,产生哪一个是随机的(大量用到随机数)。横坐标是随机的,纵坐标开始都是0。敌机大小、速度随机。 下面有一个坦克,坦克的移动通过上下左右键控制,通过按键盘空格键发射子弹。子弹运动靠OnTimer实现,坦克运动靠OnKeyDown实现。 首先我们要定义数组(敌机数组(矩形、三角形、圆形)、子弹数组),然后进行初始化。 大概需要的函数有:Draw(坦克、子弹);Create敌机是1秒产生一个,Create子弹是按

青哥 2180

MFC坦克大战

学习课程资源,不是很好的资源,为学生们提供一点小参考

MFC小游戏之坦克大战

这是基于MFC下的坦克大战游戏,编程工具使用VC++6.0。 下面将详细介绍如何一步一步实现坦克大战小游戏。 1.新建MFC工程 新建一个MFC工程,应用程序类型选择单文档类型,点击完成即可。 2.新建坦克大战类 3.定义结构体及变量 根据分析可知,坦克大战游戏主要有三个部分,即坦克,敌机,子弹。故在类的头文件中定义相应的结构体和变量。 由于坦克只有一个,敌机和子弹有多个,因此敌机和子弹使用结构体定义,坦克使用变量定义。在TanKeWar.h添加代码具体如下 typedef s

Zgh12138的博客 4511

mfc与坦克大战

用mfc框架写的坦克大战的一个小游戏.写出来分享给大家.

MFC与坦克大战代码

可能rc资源被不小心删了又恢复。所以可能在vc里面打不开。不过可以用记事本打开。因为太大了。执行程序和代码分开上传。如果试玩最后的程序。可以在博客里面的链接里面下载。

MFC与坦克大战系列(奇迹冬瓜)---chapter4(坦克总程序代码)

今天是圣诞节。祝大家圣诞快乐。因为今天在尝试写个小的圣诞程序。进度如下。无法控制雪花的路径。 今天会为大家发放整个坦克大战的代码。本来计划再用两节结束的。但是快要期末考试了。等过了这阵。会为大家呈现新的游戏。现在把整个游戏代码发给大家参考。 链接如下。不要积分。 可能我在操作的时候把rc资源有点损坏。可能造成vc打不开的问题。但是主要代码可以用记事本打开。 再次截图 开场动画1

runner2012的专栏 5450

坦克大战 mfc版

坦克大战 mfc版 带详细注释 一共二十关 有五种道具

(游戏编程-01)MFC版坦克大战(奇迹冬瓜)

经过二次整合 重新放出MFC框架下的坦克大战 采用小窗口 多线程 双缓冲 动画帧化 碰撞检测 接口封装 混音 事件延迟等 力求做到代码与美工的双向化

runner2012的专栏 5345

VC6.0的MFC单文档实现坦克大战小游戏.rar

VC6.0的MFC单文档实现坦克大战小游戏。在顶部随机产生三种不同形状的敌机(用矩形、三角形、圆形表示),每秒产生一个,产生哪一个是随机的(大量用到随机数)。横坐标是随机的,纵坐标开始都是0。敌机大小、速度随机。 下面有一个坦克,坦克的移动通过上下左右键控制,通过按键盘空格键发射子弹。子弹运动靠OnTimer实现,坦克运动靠OnKeyDown实现。 首先我们要定义数组(敌机数组(矩形、三角形、圆形)、子弹数组),然后进行初始化。 大概需要的函数有:Draw(坦克、子弹);Create敌机是1秒产生一个,Create子弹是按空格键产生;Move(敌机、子弹)是0.1秒产生一个(设置两个时钟)。还

C++程序坦克大战MFC

我大学时候设计的一个最最简单的mfc坦克大战,适合最最最最最基础的人群,C++实现一个小demo,适合初级玩家试试水

MFC与坦克大战系列(奇迹冬瓜)---chapter2(photoshop与TransparentBlt---快速生成背景与透明位图处理)

今天继续MFC与坦克大战系列.做程序是要有团队合作。毕竟大多数程序员不可能做到美工和程序都精通。但是只有一个人的时候。就需要快捷的生成比较看的过去的图片供游戏所需。就拿坦克大战这个游戏程序来说。刚开始构思的时候就需要考虑到它的扩展性。所以在做坦克大战之前首先要做的就是地图编辑器。那么既然是个坦克大战。直白的说各种障碍该有吧、草坪、沙丘、海水、树木等。原来先用java写过一个地图编辑器先试验一下。之

runner2012的专栏 6630

坦克大战:(MFC])

用mfc编写的坦克大战源码,程序压缩包,比较完整的坦克大战版本

MFC游戏编程——有远见的坦克(坦克大战中坦克的寻路系统)未完结

思路 坦克大战中坦克是不能够遵循一套固定的向着己方坦克或者老家的寻路系统的,因为这样的话就会使坦克的行动路线过于固定,己方坦克不动的时候新生成的敌人会沿着固定的路线过来,可玩性大大降低。所以还是随机的寻路比较可行,原生的坦克大战也是这么做的。MFC是利用定时器进行刷新的,所以没有办法让坦克在每一帧的行进过程中完成寻路,所以我想到了提前算好线路,也就是有远见的坦克。 从生成坦克开始,坦克随机选择一...

weixin_42583946的博客 1135

VS平台下的MFC版坦克大战

C++ VS平台下的MFC 自己设计的图形界面 自带游戏各种声音

WIN32API 坦克大战

WIN32 API的坦克大战,没有MFC代码

上一篇: c语言版数据结构(奇迹冬瓜)-数组和广义表(十字链表稀疏矩阵的加法)
下一篇: MFC与坦克大战系列(奇迹冬瓜)---chapter4(坦克总程序代码)
utral董东东
博客等级 码龄16年 158粉丝 33原创
评论 12
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值