精华内容
下载资源
问答
  • MFC小游戏MFC小游戏MFC小游戏MFC小游戏

    千次下载 热门讨论 2010-08-13 21:29:42
    MFC小游戏MFC小游戏MFC小游戏MFC小游戏MFC小游戏 A D 左右 J 子弹
  • MFC 小游戏

    2012-11-13 13:12:01
    mfc实现点击屏幕生成一个随机大小随机颜色的小球,可控制小球上下左右移动
  • VC++MFC小游戏实例教程(实例)+MFC类库详解

    千次下载 热门讨论 2013-09-12 18:39:38
    VC++MFC小游戏实例教程(实例)+MFC类库详解 免费下载
  • vc++mfc小游戏贪吃蛇

    2011-04-15 22:07:51
    vc++ mfc 小游戏 贪吃蛇 用于学习
  • VC++MFC小游戏开发实例教程+扫雷+五子棋+俄罗斯+老鼠滚球 不要理论,直接实践,免费下载
  • 五子棋 MFC 小游戏

    2017-11-22 22:09:41
    VS2010平台 MFC 五子棋小游戏 鼠标操作 OpenCV 练手 暂不支持AI
  • MFC小游戏之贪吃蛇

    2020-10-13 02:01:43
    简单的MFC贪吃蛇,有三个等级可以玩。初学者可以先到我博客http://blog.csdn.net/hai8902882 看C的贪吃蛇, 即先了解思路在来弄MFC的贪吃蛇!
  • MFC小游戏代码:借鉴

    2009-07-07 14:48:17
    VC++ 的 MFC 小游戏编制 -- 思路源自 孙鑫 老师
  • MFC小游戏 贪吃蛇

    2011-12-15 14:50:49
    一个MFC小游戏,简单,提供给大家看看,并不是很好,仅供参考
  • MFC小游戏代码

    2018-01-07 12:08:12
    内含五个小游戏包括俄罗斯方块推箱子等,用vs可以打开,适合交期末作业!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!...
  • mfc小游戏是男人坚持20秒,资源用mfc编辑,开始之后子弹不断飞向飞机,直至飞机触碰子弹游戏结束
  • MFC小游戏的实现

    2018-05-08 11:30:01
    该资源主要是简单小游戏的呈现,模仿Java精灵的方式产生。
  • mfc小游戏源码

    2015-11-13 22:22:17
    mfc初学者程序应用,使用了双缓冲技术,位图掩码技术及mfc媒体。帮助初学者了解windows编程原理,windows消息机制。
  • MFC小游戏 迷宫追寻

    2015-06-26 14:07:18
    这个游戏为玩家控制红色方块,去吃掉棕色,绿色,蓝色的方块,一旦一个方块被吃,便会自动生成另一个相同颜色的方块。直到游戏时间结束为止, C++小游戏
  • mfc做的小游戏 刚学没多久 嘿嘿 还是可以的
  • 连连看MFC小游戏

    2012-01-24 16:25:47
    连连看小游戏,用C++写的,欢迎各位试玩,文件解压后有游戏说明,需要源代码的可以加我QQ:1031186480,注明需要源代码
  • 初学者自己编写的 MFC小游戏 横竖斜的图片排列不能相同
  • MFC小游戏之坦克大战

    2020-07-17 12:00:06
    下面将详细介绍如何一步一步实现坦克大战小游戏。 1.新建MFC工程 新建一个MFC工程,应用程序类型选择单文档类型,点击完成即可。 2.新建坦克大战类 3.定义结构体及变量 根据分析可知,坦克大战游戏主要有...

    这是基于MFC下的坦克大战游戏,编程工具使用VC++6.0。

    下面将详细介绍如何一步一步实现坦克大战小游戏。

    1.新建MFC工程

    新建一个MFC工程,应用程序类型选择单文档类型,点击完成即可。

    2.新建坦克大战类

    3.定义结构体及变量

    根据分析可知,坦克大战游戏主要有三个部分,即坦克,敌机,子弹。故在类的头文件中定义相应的结构体和变量。

    由于坦克只有一个,敌机和子弹有多个,因此敌机和子弹使用结构体定义,坦克使用变量定义。在TanKeWar.h添加代码具体如下

    typedef struct
    {
    	int x;//敌机坐标x
    	int y;//敌机坐标y
    	int v;//敌机速度
    	int Size;//敌机大小
    	int FS;//敌机分数
    }DiJi;
    typedef struct
    {
    	int x;//子弹坐标x
    	int y;//子弹坐标y
    	int v;//子弹速度
    	int Size;//子弹大小
    	int Colr;//子弹颜色
    }ZiDan;
    CDC *pDC;//定义pDC指向CDC类对象的指针
    
    DiJi m_JX[100];//矩形敌机
    DiJi m_SJX[100];//三角形敌机
    DiJi m_YX[100];//圆形敌机
    int m_nJX;//矩形敌机数
    int m_nSJX;//三角形敌机数
    int m_nYX;//圆形敌机数
    
    ZiDan m_ZD[100];//子弹
    int m_nZD;//子弹数
    	
    int m_r;//坦克圆半径
    int m_x;//坦克坐标x
    int m_y;//坦克坐标y
    int m_L1,m_L2;//坦克长
    int m_LPT;//坦克炮筒长
    int m_Dire;//坦克方向
    int m_V;//坦克移动速度
    
    int m_ZongFen;//总分
    int m_CiShu;//次数
    

    4.变量初始化及画图函数

    在构造函数中对变量进行初始化,并且新建画图成员函数,编写代码,调用画敌机函数,画子弹函数和画坦克函数,添加提示信息等。

    在类中新建成员函数

    构造函数中变量初始化

    画图函数中调用其他函数进行绘图

    5.敌机的实现

    通过分析可知,敌机主要有4个函数,创造敌机函数,画敌机函数,移动敌机函数和消除敌机函数。

    5.1创造敌机函数

    新建CreateDiJi()成员函数,并添加如下代码,根据随机数选择创造相应类型的敌机,设置敌机的各项参数的值,敌机总数加1。

    int sjs;//随机数
    sjs = rand()%3;//对3求余,即0,1,2
    switch(sjs)
    {
            case 0:
    		m_JX[m_nJX].x = rand()%700 + 50;
    		m_JX[m_nJX].y = 0;
    		m_JX[m_nJX].v = rand()%50 + 10;
    		m_JX[m_nJX].Size = rand()%20 + 10;
    		m_JX[m_nJX].FS = m_JX[m_nJX].v + 100/m_JX[m_nJX].Size;
    		m_nJX++;
    		break;
    	case 1:
    		m_SJX[m_nSJX].x = rand()%700 + 50;
    		m_SJX[m_nSJX].y = 0;
    		m_SJX[m_nSJX].v = rand()%30 + 10;
    		m_SJX[m_nSJX].Size = rand()%60 + 30;
    		m_SJX[m_nSJX].FS = m_SJX[m_nSJX].v + 300/m_SJX[m_nSJX].Size;
    		m_nSJX++;
    		break;
    	case 2:
    		m_YX[m_nYX].x = rand()%700 + 50;
    		m_YX[m_nYX].y = 0;
    		m_YX[m_nYX].v = rand()%40 + 10;
    		m_YX[m_nYX].Size = rand()%40 + 20;
    		m_YX[m_nYX].FS = m_YX[m_nYX].v + 200/m_YX[m_nYX].Size;
    		m_nYX++;
    		break;
    }
    

    5.2画敌机函数

    新建DrawDiJi()成员函数,并添加如下代码,分别画不同类型的敌机,此处注意画三角形敌机时使用了三角函数需将math.h包括进来,即在开头添加#include "math.h"代码,并且宏定义PI,即在开头添加#define PI 3.1415926代码。

    int i;
    int x,y,r;
    for(i=0;i<m_nJX;i++)
    {
    	x = m_JX[i].x;
    	y = m_JX[i].y;
    	r = m_JX[i].Size/2;
    	pDC->Rectangle(x,y,x + r,y + r);
    }
    for(i=0;i<m_nSJX;i++)
    {
    	x = m_SJX[i].x;
    	y = m_SJX[i].y;
    	r = m_SJX[i].Size/2;
    	pDC->MoveTo(x,y);
    	x -= r;
    	y += r*2*cos(PI/6);
    	pDC->LineTo(x,y);
    	x += 2*r;
    	pDC->LineTo(x,y);
    	x = m_SJX[i].x;
    	y = m_SJX[i].y;
    	pDC->LineTo(x,y);
    }	
    for(i=0;i<m_nYX;i++)
    {
    	x = m_YX[i].x;
    	y = m_YX[i].y;
    	r = m_YX[i].Size/2;
    	pDC->Ellipse(x - r,y - r,x + r,y + r);
    }
    

    5.3移动敌机函数

    新建MoveDiJi()成员函数,并添加如下代码,根据不同类型敌机的速度改变敌机的y坐标,并设定边界,大于该值时便消失。

    int i;
    for(i=0;i<m_nJX;i++)
    {
    	m_JX[i].y += m_JX[i].v * 0.1;
    	if(m_JX[i].y>750)
    		DeleteDiJi(0,i);
    }
    for(i=0;i<m_nSJX;i++)
    {
    	m_SJX[i].y += m_SJX[i].v * 0.3;
    	if(m_SJX[i].y>750)
    		DeleteDiJi(1,i);
    }	
    for(i=0;i<m_nYX;i++)
    {
    	m_YX[i].y += m_YX[i].v * 0.2;
    	if(m_YX[i].y>750)
    		DeleteDiJi(2,i);
    }

    5.4消除敌机函数

    新建DeleteDiJi(int xz,int n)成员函数,并添加如下代码,根据变量xz选择不同类型敌机,并使所要删除的第n个敌机变为最后一个敌机就行,敌机总数减1。

    switch(xz)
    {
    	case 0:
    		m_JX[n] = m_JX[m_nJX-1];
    		m_nJX--;
    		break;
    	case 1:
    		m_SJX[n] = m_SJX[m_nSJX-1];
    		m_nSJX--;
    		break;
    	case 2:
    		m_YX[n] = m_YX[m_nYX-1];
    		m_nYX--;
    		break;
    }
    

    6.子弹的实现

    通过分析可知,子弹和敌机类似,主要有4个函数,创造子弹函数,画子弹函数,移动子弹函数和消除子弹函数。

    6.1创造子弹函数

    新建CreateZiDan()成员函数,并添加如下代码,创造子弹,设置子弹的各项参数的值,子弹总数加1。

    m_ZD[m_nZD].x = m_x;
    m_ZD[m_nZD].v = rand()%50 + 25;
    m_ZD[m_nZD].Size = rand()%20 + 10;
    m_ZD[m_nZD].y = m_y - m_r*sqrt(3)/2 - m_LPT - m_ZD[m_nZD].Size/2;
    m_ZD[m_nZD].Colr = RGB(120,160,200);
    m_nZD++;

    6.2画子弹函数

    新建DrawZiDan()成员函数,并添加如下代码,画圆形子弹,并使用画刷填充子弹颜色。

    int i;
    int x,y,r;
    for(i=0;i<m_nZD;i++)
    {
    	x = m_ZD[i].x;
    	y = m_ZD[i].y;
    	r = m_ZD[i].Size/2;
    	CBrush brush;
    	brush.CreateSolidBrush(m_ZD[i].Colr);
    	pDC->SelectObject(&brush);
    	pDC->BeginPath();
    	pDC->Ellipse(x - r,y - r,x + r,y + r);
    	pDC->EndPath();
    	pDC->FillPath();
    }

    6.3移动子弹函数

    新建MoveZiDan()成员函数,并添加如下代码,根据子弹的速度改变子弹的y坐标,并设定边界,小于该值便消除子弹。

    int i;
    for(i=0;i<m_nZD;i++)
    {
    	m_ZD[i].y -= m_ZD[i].v * 0.2;
    	if(m_ZD[i].y < 75)
    		DeleteZiDan(i);
    }

    6.4消除子弹函数

    新建DeleteZiDan(int n)成员函数,并添加如下代码,根据变量n,删除第n个子弹,并使所要删除的第n个子弹变为最后一个子弹就行,子弹总数减1。

    m_ZD[n] = m_ZD[m_nZD-1];
    m_nZD--;

    7.坦克的实现

    通过分析可知,坦克主要有3个函数,画坦克函数,移动坦克函数,改变方向函数。

    7.1画坦克函数

    新建DrawTanKe()成员函数,并添加如下代码,画坦克。

    int x1,x2,y1,y2,z1,z2;
    x1 = m_L1/2;
    x2 = m_L2/2;
    y1 = 2*m_r;
    y2 = 3*m_r;
    pDC->Rectangle(m_x - x2,m_y - y2,m_x + x2,m_y + y2);
    pDC->Rectangle(m_x - x1,m_y - y1,m_x + x1,m_y + y1);
    pDC->Ellipse(m_x - m_r,m_y - m_r,m_x + m_r,m_y + m_r);
    z1 = m_r/2;
    z2 = m_r*sqrt(3)/2;
    pDC->MoveTo(m_x + z1,m_y - z2);
    pDC->LineTo(m_x + z1,m_y - z2 - m_LPT);
    pDC->LineTo(m_x - z1,m_y - z2 - m_LPT);
    pDC->LineTo(m_x - z1,m_y - z2);
    

    7.2移动坦克函数

    新建MoveTanKe()成员函数,并添加如下代码,根据不同的移动方向和移动速度来改变坦克的x和y坐标来实现移动坦克。

    if(m_Dire == 1) m_x -= m_V;
    if(m_Dire == 2) m_y -= m_V;
    if(m_Dire == 3) m_x += m_V;
    if(m_Dire == 4) m_y += m_V;

    7.3改变方向函数

    新建ChangeDire(int n)成员函数,并添加如下代码,根据变量n来识别按下的键盘是什么,从而通过键盘的上下左右键改变坦克的移动方向。

    switch(n)
    {
    	case 37:
    		m_Dire = 1;//向左
    		break;
    	case 38:
    		m_Dire = 2;//向上
    		break;
    	case 39:
    		m_Dire = 3;//向右
    		break;
    	case 40:
    		m_Dire = 4;//向下
    		break;
    }

    8.碰撞的实现

    碰撞即子弹击中敌机和敌机击中坦克两部分,故可以使用2个函数实现,碰撞敌机子弹函数和碰撞敌机坦克函数。

    8.1碰撞敌机子弹函数

    新建PengZhuangDiJiZiDan()成员函数,并添加如下代码,外层循环是子弹,内层循环是敌机,根据不同类型的敌机 ,分别计算敌机和子弹之间的距离,并判断该距离若小于两者半径之和时就视为击中,因此总分就增加该敌机的分数,且消除该敌机和该子弹,同时break此次循环,再判断j是否小于该敌机数,若小于则continue继续循环判断。

    int i,j;
    int d;
    for(i=0;i<m_nZD;i++)
    {	
    	for(j=0;j<m_nJX;j++)
    	{
    		d = sqrt((m_ZD[i].x - m_JX[j].x)*(m_ZD[i].x - m_JX[j].x)+(m_ZD[i].y - m_JX[j].y)*(m_ZD[i].y - m_JX[j].y));
    		if(d<m_ZD[i].Size/2 + m_JX[j].Size/2)
    		{
    			m_ZongFen += m_JX[j].FS;
    			DeleteDiJi(0,j);
    			DeleteZiDan(i);
    			break;
    		}
    	}
    	if(j<m_nJX)
    		continue;
    	for(j=0;j<m_nSJX;j++)
    	{
    		d = sqrt((m_ZD[i].x - m_SJX[j].x)*(m_ZD[i].x - m_SJX[j].x)+(m_ZD[i].y - m_SJX[j].y)*(m_ZD[i].y - m_SJX[j].y));
    		if(d<m_ZD[i].Size/2 + m_SJX[j].Size/2)
    		{
    			m_ZongFen += m_SJX[j].FS;
    			DeleteDiJi(1,j);
    			DeleteZiDan(i);
    			break;
    		}
    	}
    	if(j<m_nSJX)
    		continue;
    	for(j=0;j<m_nYX;j++)
    	{
    		d = sqrt((m_ZD[i].x - m_YX[j].x)*(m_ZD[i].x - m_YX[j].x)+(m_ZD[i].y - m_YX[j].y)*(m_ZD[i].y - m_YX[j].y));
    		if(d<m_ZD[i].Size/2 + m_YX[j].Size/2)
    		{
    			m_ZongFen += m_YX[j].FS;
    			DeleteDiJi(2,j);
    			DeleteZiDan(i);
    			break;
    		}
    	}
    	if(j<m_nYX)
    		continue;
    }

    8.2碰撞敌机坦克函数

    新建PengZhuangDiJiTanKe()成员函数,且该函数类型是int型,有一个返回值,返回值用于后面判断是否碰撞,并添加如下代码,循环是敌机,根据不同类型的敌机 ,分别计算敌机和坦克之间的距离,并判断该距离若小于两者半径与炮筒长之和时就视为击中,因此碰撞标志变为1,且消除该敌机,玩家游戏次数减1,返回碰撞标志。

    int i,d;
    int flag=0;
    for(i=0;i<m_nJX;i++)
    {
    	d = sqrt((m_JX[i].x - m_x)*(m_JX[i].x - m_x)+(m_JX[i].y - m_y)*(m_JX[i].y - m_y));
    	if(d<m_JX[i].Size/2+m_r*sqrt(3)/2+m_LPT)
    	{
    		flag=1;
    		DeleteDiJi(0,i);
    		m_CiShu--;
    		return flag;
    	}
    }
    for(i=0;i<m_nSJX;i++)
    {
    	d = sqrt((m_SJX[i].x - m_x)*(m_SJX[i].x - m_x)+(m_SJX[i].y - m_y)*(m_SJX[i].y - m_y));
    	if(d<m_SJX[i].Size/2+m_r*sqrt(3)/2+m_LPT)
    	{	
    		flag=1;
    		DeleteDiJi(1,i);
    		m_CiShu--;
    		return flag;
    	}
    }
    for(i=0;i<m_nYX;i++)
    {
    	d = sqrt((m_YX[i].x - m_x)*(m_YX[i].x - m_x)+(m_YX[i].y - m_y)*(m_YX[i].y - m_y));
    	if(d<m_YX[i].Size/2+m_r*sqrt(3)/2+m_LPT)
    	{	
    		flag=1;
    		DeleteDiJi(2,i);
    		m_CiShu--;
    		return flag;
    	}
    }
    

    9.视图类调用及新建菜单项目

    9.1新建菜单项目

    新建菜单栏,在这里设置2个功能栏,开始游戏和暂停游戏,并建立视图类向导。

    9.2视图类调用

    先在刚刚添加的2个消息响应函数中添加代码,在开始消息响应函数中设置2个定时器,一个时间间隔为1000毫秒即1秒,另一个时间间隔为100毫秒,在暂停消息响应函数中停止2个时钟。

    然后添加时钟控制函数和键盘控制函数。

    在添加代码之前,因要调用坦克大战类中的函数,故需要在视图类的头文件中定义一个对象,并包括坦克大战类的头文件,且在视图类的.cpp文件中也应包括坦克大战类的头文件。

    最后在OnDraw()中调用坦克大战类的画图函数,在OnKeyDown()中调用坦克大战类的改变方向函数,在OnTimer()中调用坦克大战类的创造函数,移动函数,碰撞函数,并且根据时钟号的不同设置调用时间间隔不同。创造函数每隔1秒调用一次,移动函数和碰撞函数每隔100毫秒调用一次。并且对于玩家游戏次数进行判断,若为0,则终止游戏。若不为0,则提示后继续游戏。

    在OnDraw()中添加代码

    tw.Draw(pDC);

    在OnKeyDown()中添加代码

    tw.ChangeDire(nChar);

    在OnTimer()中添加代码

    if(nIDEvent == 1)
    {
    	tw.CreateDiJi();
    	tw.CreateZiDan();
    	Invalidate(true);
    }
    if(nIDEvent == 2)
    {
    	tw.MoveDiJi();
    	tw.MoveZiDan();
    	tw.MoveTanKe();
    	tw.PengZhuangDiJiZiDan();
    	if(tw.m_CiShu != 0)
    	{
    		if(tw.PengZhuangDiJiTanKe()==1)
    		{
    			CString str;
    			str.Format("还剩%d条命!",tw.m_CiShu);
    			AfxMessageBox(str);
    			SetTimer(1,1000,NULL);
    			SetTimer(2,100,NULL);
    		}
    	}
    	else
    	{
    		KillTimer(1);
    		KillTimer(2);
    		AfxMessageBox("Game Over!");
    	}
    			
    	Invalidate(true);
    }

    为消除屏幕的闪烁问题,可用双缓存技术解决。先添加擦除背景函数并将返回值为true,然后将OnDraw()中代码变成如下代码。

    10.游戏效果展示

    总结

    这个基于MFC的坦克大战小游戏,可以说将面向对象思想和程序模块化思想体现的比较好。通过练习,对于这两种思想的理解会更进一步。

    源码下载地址,仅供参考。

    https://download.csdn.net/download/Zgh12138/12625604

    展开全文
  • MFC 小游戏贪吃蛇

    2009-05-29 11:52:40
    利用VC++编的小游戏 贪吃蛇 可能有些BUG 还待完善~
  • 初学学自己编写的小游戏 请大家自己参考参考
  • 课设的时候参看了别人的代码,结合自己的, 写了一个MFC的连连看, 用的是dota里面的图标。
  • MFC小游戏 -推箱子

    2014-11-27 15:24:46
    大学中第一个界面 软件,,推箱子 ,供大家参考
  • C++/MFC小游戏

    2011-06-14 00:16:13
    一款设计精致、构思巧妙的贪吃蛇小游戏,可以下载试试,
  • MFC写的 WM2003自带的那个小球游戏
  • MFC做的小游戏 测试点击鼠标的速度 学习MFC实例
  • MFC 小游戏之连连看

    千次阅读 2017-08-25 23:04:00
    最近在找工作因为没有什么拿的出手的项目所以就想做一个小游戏。因为连连看比较熟悉所以选择这个游戏。 这个游戏也是很好玩的,点击相同的图片如果两个图片能够通过直线或者一个折线或者两个折线相连的话,那么就...

    最近在找工作因为没有什么拿的出手的项目所以就想做一个小游戏。因为连连看比较熟悉所以选择这个游戏。

    这个游戏也是很好玩的,点击相同的图片如果两个图片能够通过直线或者一个折线或者两个折线相连的话,那么就消除这个图片并获得相应的分数,但是2个图片之间不能有其他的图片存在。

    首先,使用的图片是LOL 中的英雄图标格式是bmp格式的尺寸是64*64的数量是30个。那么在生成地图的时候就要注意,矩阵必须是偶数个比如30个图片每个图片可以出现四次,那么是就是120个格子另外还需要在生成矩阵的时候需要一边多留出一格这样防止数组越界,那么生成矩阵的行数和列数就是12*14的。而行数和列数必须是偶数。。。。。

    展开全文
  • MFC 小游戏之贪吃蛇

    千次阅读 2011-11-17 16:59:27
    弄了控制台的贪吃蛇等游戏后,学了一些MFC,即马上去弄MFC的贪吃蛇。写的时候由于学的MFC视频和实际操作还是有很大区别的,很多东西还是要自己去查MSDN或百度才知道的,在这里次MFC贪吃蛇中学到了很多知识!做出来后...
     
    

    弄了控制台的贪吃蛇等游戏后,学了一些MFC,即马上去弄MFC的贪吃蛇。写的时候由于学的MFC视频和实际操作还是有很大区别的,很多东西还是要自己去查MSDN或百度才知道的,在这里次MFC贪吃蛇中学到了很多知识!做出来后发现界面有闪烁的显现,后有前辈说可以采取双缓冲去避免闪烁,即百度查了不少这方面的资料,自己编写后还是闪烁,后问前辈是否写错,前辈说未写错,我就继续找度娘,找了很久没弄出来,最后就去csdn论坛去发了个帖子。呵,果然给力,一下解决了问题。即只要添加一个消息函数OnEraseBkgnd(CDC* pDC) 在加上之前的双缓冲即可避免不闪烁了!很是高兴啊!


    代码下载网址: http://download.csdn.net/detail/hai8902882/3823052 


    关于双缓冲 和 OnEraseBkgnd(CDC* pDC) 的资料请看我博客的文章。

     

    我是用VC6建立一个.exe 的文本空间,即再在view类中添加文件,我将这部分的代码贴出

    大家可以交流下,如有不好之处,请见谅!


    // mfc_snackeView.cpp : implementation of the CMfc_snackeView class
    //
    #include "stdafx.h"
    #include "mfc_snacke.h"
    #include "mfc_snackeDoc.h"
    #include "mfc_snackeView.h"
    #include <cstdlib>
    #include <ctime>
    #include <cmath>
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    /
    // CMfc_snackeView
    IMPLEMENT_DYNCREATE(CMfc_snackeView, CView)
    BEGIN_MESSAGE_MAP(CMfc_snackeView, CView)
     //{{AFX_MSG_MAP(CMfc_snackeView)
     ON_WM_TIMER()
     ON_WM_KEYDOWN()
     ON_COMMAND(IDS_EASY, OnEasy)
     ON_COMMAND(IDS_MEDIUM, OnMedium)
     ON_COMMAND(IDS_HARD, OnHard)
     ON_WM_ERASEBKGND()
     //}}AFX_MSG_MAP
     // Standard printing commands
     ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
     ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
     ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
    END_MESSAGE_MAP()
    /
    // CMfc_snackeView construction/destruction
    CMfc_snackeView::CMfc_snackeView()
    {
     // TODO: add construction code here
     m_Count = m_UseTime = 0;
     m_start = 0;   //记录玩家开始第几次玩
     m_speed = 500;  //初始化速度为0.5s
     H = 35;   //地图的high 和 length,实际x = (40,580), y = (40, 380)
     L = 55;   //这样主要是为了rand的方便
     srand(time(0));  //随机种子
     CMfc_snackeView::Initial_Game();  //初始化游戏的界面
    }
    CMfc_snackeView::~CMfc_snackeView()
    {
    }
    BOOL CMfc_snackeView::PreCreateWindow(CREATESTRUCT& cs)
    {
     // TODO: Modify the Window class or styles here by modifying
     //  the CREATESTRUCT cs
     
     return CView::PreCreateWindow(cs);
    }
    /
    // CMfc_snackeView drawing
    void CMfc_snackeView::OnDraw(CDC* pDC)   //画界面
    {
     CMfc_snackeDoc* pDoc = GetDocument();
     ASSERT_VALID(pDoc);
     //
        CDC MemDC;   //首先定义一个显示设备对象
     CBitmap MemBitmap;   //定义一个位图对象
        //随后建立与屏幕显示兼容的内存显示设备
     MemDC.CreateCompatibleDC(pDC);
     //这时还不能绘图,因为没有地方画
     //下面建立一个于屏幕显示兼容的位图,至于位图的大小嘛
     //可以用窗口的大小
     CRect rect;
     GetClientRect(&rect);
        MemBitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
     //将位图选入到内存显示设备中
     //只要有选入了位图的内存显示设备才有地方地方绘图,画到指定的位图上
     CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);
     //先用背景色将位图清除干净,这里我用的是白色作为背景
     //你也可以用自己应该用的颜色
     MemDC.FillSolidRect(0, 0, rect.Width(), rect.Height(), RGB(255, 255, 255));
     //绘图// 
     //draw border of game
     MemDC.Rectangle(CRect(39, 39, 601, 401));
     //Records cstring show
     CString s;
     s.Format("当前用时: %d", m_UseTime/(1000/m_speed));
     MemDC.TextOut(620, 60, s);
     s.Format("当前得分: %d", m_Count);
     MemDC.TextOut(620, 100, s);
     s.Format("版权所有: [菜菜]咸鱼");
     MemDC.TextOut(620, 140, s);
     s.Format("时间: 2011-10-22");
     MemDC.TextOut(620, 180, s);
     //draw snake
     //draw head of snake
     CPoint h;
     h = m_body.GetAt(0);
     MemDC.SelectStockObject(DKGRAY_BRUSH);
     switch(m_NowDir)
        {
        case 4: MemDC.Pie(CRect(h.x, h.y, h.x+20, h.y+20), CPoint(h.x+5, h.y), CPoint(h.x+15, h.y));
             MemDC.SelectStockObject(WHITE_BRUSH );  //蛇的眼睛
          MemDC.Ellipse(h.x+13, h.y+5, h.x+18, h.y+10);
          break;
     
     case 3: MemDC.Pie(CRect(h.x, h.y, h.x+20, h.y+20), CPoint(h.x+20, h.y+5), CPoint(h.x+20, h.y+15));
          MemDC.SelectStockObject(WHITE_BRUSH );
          MemDC.Ellipse(h.x+10, h.y+2, h.x+15, h.y+7);
          break;
       
     case 2: MemDC.Pie(CRect(h.x, h.y, h.x+20, h.y+20), CPoint(h.x+15, h.y+20), CPoint(h.x+5, h.y+20));
          MemDC.SelectStockObject(WHITE_BRUSH );
          MemDC.Ellipse(h.x+13, h.y+10, h.x+18, h.y+15);
          break;
     
     case 1: MemDC.Pie(CRect(h.x, h.y, h.x+20, h.y+20), CPoint(h.x, h.y+15), CPoint(h.x, h.y+5));
          MemDC.SelectStockObject(WHITE_BRUSH );
          MemDC.Ellipse(h.x+5, h.y+2, h.x+10, h.y+7);
          break;
     }
        //draw body of snake
     CPoint b;
     MemDC.SelectStockObject(GRAY_BRUSH);
     for(int i = 1; i <= m_body.GetUpperBound(); i++)
     {
      b = m_body.GetAt(i);
      MemDC.Rectangle(CRect(b.x, b.y, b.x+20, b.y+20));
     }
     //draw a food
     CBrush br;
     br.CreateSolidBrush(RGB(0, 255, 0));
     MemDC.SelectObject(br);
     MemDC.FillRect(CRect(m_food.x, m_food.y, m_food.x+20, m_food.y+20), &br);
        MemDC.Rectangle(CRect(m_food.x, m_food.y, m_food.x+20, m_food.y+20));
     
     //将内存中图拷贝到屏幕上进行显示
     pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &MemDC, 0, 0, SRCCOPY);
     //绘图完成后的清理
     MemBitmap.DeleteObject();
     MemDC.DeleteDC();
    }
    /
    // CMfc_snackeView printing
    BOOL CMfc_snackeView::OnPreparePrinting(CPrintInfo* pInfo)
    {
     // default preparation
     return DoPreparePrinting(pInfo);
    }
    void CMfc_snackeView::OnBeginPrinting(CDC* , CPrintInfo* )
    {
     // TODO: add extra initialization before printing
    }
    void CMfc_snackeView::OnEndPrinting(CDC* , CPrintInfo* )
    {
     // TODO: add cleanup after printing
    }
    /
    // CMfc_snackeView diagnostics
    #ifdef _DEBUG
    void CMfc_snackeView::AssertValid() const
    {
     CView::AssertValid();
    }
    void CMfc_snackeView::Dump(CDumpContext& dc) const
    {
     CView::Dump(dc);
    }
    CMfc_snackeDoc* CMfc_snackeView::GetDocument() // non-debug version is inline
    {
     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMfc_snackeDoc)));
     return (CMfc_snackeDoc*)m_pDocument;
    }
    #endif //_DEBUG
    /
    // CMfc_snackeView message handlers
    void CMfc_snackeView::Initial_Game()   //游戏地图的初始化
    {
     m_body.RemoveAll();
     
     //initial direciton
     m_NowDir = m_PreDir = 3; 
     //inital head of snake
     CPoint head;
     head.x = 100;  head.y = 100;
     m_body.Add(head);
     //create rand food
     CMfc_snackeView::Create_food();
    }
    void CMfc_snackeView::Create_food()
    {
     CPoint t;
        int x, y, prove;
        while(1)
     {
      x = rand()%L + 4;
            y = rand()%H + 4;
      if(x%2 == 0 && y%2 == 0)  //其实坐标是x=(40,580), y=(40,380)
      {                         //每一个图标如蛇头的high和length是占20, 20
       prove = 0;
       
       x *= 10;  y *= 10;
                //食物不能是蛇的地方
       for(int i = 0; i <= m_body.GetUpperBound(); i++)
       {
        t = m_body.GetAt(i);
        if(t.x == x && t.y == y)
        {
         prove = 1;
               break;
        }
       }
       
       if(!prove)
        break;
      }
     }
     m_food = CPoint(x, y);
    }
    void CMfc_snackeView::GameStart()  //开始游戏哦
    {   //玩家时间和得分数的初始化
     m_Count = m_UseTime = 0;
     m_start++;
     if(m_start > 1)
       CMfc_snackeView::Initial_Game();
     
     //每隔m_speed时间发送WM_TIMER消息
        Timer = SetTimer(1, m_speed, NULL);
    }
    void CMfc_snackeView::OnTimer(UINT nIDEvent) //WM_TIMER消息
    {
     // TODO: Add your message handler code here and/or call default
     m_UseTime++;  //时间记录
        //蛇移动
     CMfc_snackeView::Move();
     CView::OnTimer(nIDEvent);
    }
    void CMfc_snackeView::Move() //蛇移动函数
    {
        if(m_PreDir == m_NowDir || abs(m_PreDir-m_NowDir) == 2)
      m_NowDir = m_PreDir;
     else
      m_PreDir = m_NowDir;
     CPoint head;
     head = m_body.GetAt(0);
     
     //4个方向
     switch(m_NowDir)
     {
     case 4: head.y -= 20;
          break;
     
     case 3: head.x += 20;
          break;
     
     case 2: head.y += 20;
          break;
       
     case 1: head.x -= 20;
          break;
     } 
     
     int over = 0;
        CPoint t;
        //蛇头是否吃到自己
     for(int i = 0; i <= m_body.GetUpperBound(); i++)
     {
      t = m_body.GetAt(i);
      if(head.x == t.x && head.y == t.y)
      {
       over = 1;
       break;
      }
     }
     
     if(!Check(head) || over)
     { //结束Timer,并弹出一个结束的对话框
      KillTimer(Timer);
      MessageBox("Game is over! You are fail!");
     }
     else
     { 
      m_body.InsertAt(0, head);
            //蛇头吃到食物
      if(head.x == m_food.x && head.y == m_food.y)
      {
       m_Count++;
       Create_food();
      }
      else
       m_body.RemoveAt(m_body.GetUpperBound());
     }
        
     //使整个窗口客户区无效,意味着需要重绘,即调用OnDraw函数
     //InvalidateRect(CRect(39, 39, 839, 489));
        Invalidate();
    }
    //键盘按键判断
    void CMfc_snackeView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
     // TODO: Add your message handler code here and/or call default
        if(m_start)
     { 
      switch(nChar)
      {
         case 38:  //up
       m_NowDir = 4;
          break;
      case 39:  //right
          m_NowDir = 3;
          break;
         case 40:  //down
          m_NowDir = 2;
          break;
         case 37:  //left
          m_NowDir = 1;
          break;
      default:
       m_NowDir = m_PreDir;
       break;
      }
     }
     CView::OnKeyDown(nChar, nRepCnt, nFlags);
    }
    //判断是否出界
    int CMfc_snackeView::Check(CPoint head)
    {
     if(head.x < 40 || head.x > 580
     || head.y < 40 || head.y > 380)
         return 0;
     else
            return 1;
    }
    
    void CMfc_snackeView::OnEasy()
    {
     // TODO: Add your command handler code here
     m_speed = 500;
        CMfc_snackeView::GameStart();
    }
    void CMfc_snackeView::OnMedium()
    {
     // TODO: Add your command handler code here
     m_speed = 200;
        CMfc_snackeView::GameStart();
    }
    void CMfc_snackeView::OnHard()
    {
     // TODO: Add your command handler code here
     m_speed = 50;
        CMfc_snackeView::GameStart();
    }
    BOOL CMfc_snackeView::OnEraseBkgnd(CDC* pDC)
    {
     // TODO: Add your message handler code here and/or call default
     //即擦除背景由本函数处理,不需要OnPain()来擦除背景
     return true; 
    }


    展开全文
  • 一个用MFC写的俄罗斯方块。。。。。。。。。。。。。。。。。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,926
精华内容 5,570
关键字:

mfc小游戏