用Win API实现游戏《是男人就下100层》(游戏入门&追爱)

fangcunx 2012-11-11 10:43:41
此教程为追爱而写,
如果你觉得这篇教程还不错请在我的博客留言


为了向一个女孩证明自己决定寻找一千个陌生人祝福,
希望你能留下你的祝福
谢谢

地址:
http://blog.sina.com.cn/s/blog_b2bbe82101016jum.html

还有写的其它教程,也是为此而写
用VB6实现俄罗斯方块游戏(游戏编程入门教程)&追爱
http://bbs.csdn.net/topics/390270254



源代码下载
http://fangcun.ys168.com/
游戏目录下

是男人就下100层,是一个蛮好玩的游戏,
相信很多朋友都曾玩过,
那么你是否想自己做一个呢。

那让我们一起来吧!

首先是数据结构

//常量
//窗口大小
#define WINDOW_WIDTH 320
#define WINDOW_HEIGHT 320
//计时器ID
#define TIMER 1
//板块类型
//石板
#define BOARD_STONE 0
//木板
#define BOARD_WOOD 1
//钉板
#define BOARD_DOG 2
//弹簧
#define BOARD_SPRING 3
//板块元素数
#define BOARD_COUNT 10
//角色高度
#define ROLE_HEIGHT 32
//角色宽度
#define ROLE_WIDTH 32
//角色状态
//向左
#define ROLE_LEFT 0
//向右
#define ROLE_RIGHT 1
//发呆
#define ROLE_LOGY 2

//全局变量
HDC g_hDrawDC;//绘制设备上下文
HBITMAP g_hDrawBmp;//绘制位图
bool g_bStart=false;//指示是否开始游戏
HWND g_hMainWnd;//主窗口句柄
HINSTANCE g_hInstance;//程序实例句柄
struct Board//板块描述
{
int nType;//板块类型
int nState;//板块状态
int nStep;//计数
int x,y;//板块位置
};
Board g_Board[BOARD_COUNT];
struct Role//角色信息
{
int nState;//角色状态用于绘制图片0,向左,1,向右,2发呆
int nStep;//向左向右的步数0~2
int nFloorCount;//当前层数
int x,y;//角色位置
int Count;//角色生命数
} g_Role;
char g_strInfo[10];//提示信息


这些描述整个游戏的状态
游戏中使用Timer(计时器)来实现板块的上移以及人物的自动下降
case WM_TIMER:
if(g_bStart)//游戏已开始
{
//板块上升
BoardDeal();
Draw();
}
break;

//板块上升处理,构成循环
//同时处理角色上升
void BoardDeal()
{
int i;
int j;
int nMaxY;
bool bMoved=false;//角色是否移动过

for(i=0;i<BOARD_COUNT;i++)
{
g_Board[i].y-=5;
if(g_Board[i].y<-16)
{
j=0;
//寻找最大y坐标
nMaxY=0;
for(;j<BOARD_COUNT;j++)
{
if(g_Board[j].y>nMaxY)
{
nMaxY=g_Board[j].y;
}
}
g_Role.nFloorCount++;
g_Board[i].nType=rand()%4;
g_Board[i].x=rand()%145;
g_Board[i].y=nMaxY+64;
g_Board[i].nStep=0;
g_Board[i].nState=0;
}
if(g_Board[i].nState>0) g_Board[i].nState++;
if(g_Board[i].nState>4) g_Board[i].nState=0;

if(g_Board[i].nType==BOARD_WOOD)
{
if(g_Board[i].nState==4)
{
g_Board[i].nStep++;
g_Board[i].nState=1;
if(g_Board[i].nStep>2)
{
j=0;
//寻找最大y坐标
nMaxY=0;
for(;j<BOARD_COUNT;j++)
{
if(g_Board[j].y>nMaxY)
{
nMaxY=g_Board[j].y;
}
}
g_Board[i].nType=rand()%4;
g_Board[i].x=rand()%145;
g_Board[i].y=nMaxY+64;
g_Board[i].nStep=0;
g_Board[i].nState=0;
}
}
}

if(g_Role.y+ROLE_HEIGHT>=g_Board[i].y-8 && g_Role.y+ROLE_HEIGHT<=g_Board[i].y+8 &&
g_Role.x>=g_Board[i].x-16 && g_Role.x+ROLE_WIDTH<=g_Board[i].x+96+16)
{
g_Role.y=g_Board[i].y-ROLE_HEIGHT;

if(g_Board[i].nType==BOARD_WOOD)
{
if(g_Board[i].nState==0)
{
g_Board[i].nState=1;
strcpy(g_strInfo,"木板要碎了");
}
}
else if(g_Board[i].nType==BOARD_SPRING)
{
if(g_Board[i].nState==0)
{
g_Board[i].nState=1;
strcpy(g_strInfo,"跳啊跳");
}
if(g_Board[i].nState==4)
{
g_Role.y-=48;
}
}
else if(g_Board[i].nType==BOARD_DOG)
{
char str[20];
char str2[20];
g_Role.Count--;
if(g_Role.Count<0)
{
g_bStart=false;
strcpy(str,"你输了!成绩为");
itoa(g_Role.nFloorCount,str2,10);
strcat(str,str2);
MessageBox(g_hMainWnd,str,"TheMan",MB_OK);
g_bStart=true;
GameInit();
return;
}
g_bStart=false;
strcpy(g_strInfo,"生命-1");
Draw();
Sleep(1000);
g_bStart=true;
//寻找y坐标次大的板块
j=0;
int nT;

nT=i;
for(;j<BOARD_COUNT;j++)//找到最大板块
{
if(g_Board[nT].y<g_Board[j].y)
nT=j;
}
for(j=0;j<BOARD_COUNT;j++)
{
if(g_Board[j].y<g_Board[nT].y && g_Board[j].y>g_Board[i].y)
{
nT=j;
}
}
g_Board[nT].nState=0;
g_Board[nT].nType=BOARD_STONE;
g_Role.y=g_Board[nT].y-ROLE_HEIGHT;
g_Role.x=g_Board[nT].x+(96/2)-(32/2);
}
else if(g_Board[i].nType==BOARD_STONE)
{
strcpy(g_strInfo,"");
}

bMoved=true;

}
}

if(!bMoved)
{
g_Role.y+=8;
}
if(g_Role.y>320 || g_Role.y<12)
{
Role tR;
int x,y;

char str[20];
char str2[20];
g_Role.Count--;
if(g_Role.Count<0)
{
g_bStart=false;
strcpy(str,"你输了!成绩为");
itoa(g_Role.nFloorCount,str2,10);
strcat(str,str2);
MessageBox(g_hMainWnd,str,"TheMan",MB_OK);
g_bStart=true;
GameInit();
return;
}
g_bStart=false;
strcpy(g_strInfo,"生命-1");
Draw();
Sleep(1000);
g_bStart=true;
memcpy(&tR,&g_Role,sizeof(g_Role));
GameInit();
x=g_Role.x;
y=g_Role.y;
memcpy(&g_Role,&tR,sizeof(g_Role));
g_Role.x=x;
g_Role.y=y;
}
}


按键有WM_KEYDOWN处理
case WM_KEYDOWN://键入按键
nKey=(int)wParam;
if(!g_bStart)//游戏开始
{
GameInit();
g_bStart=true;
Draw();
}
else
{
if(nKey==VK_LEFT)
{
g_Role.nState=ROLE_LEFT;
g_Role.nStep=(g_Role.nStep+1)%3;
g_Role.x-=10;
if(g_Role.x<0) g_Role.x=0;
}
else if(nKey==VK_RIGHT)
{
g_Role.nState=ROLE_RIGHT;
g_Role.nStep=(g_Role.nStep+1)%3;
g_Role.x+=10;
if(g_Role.x>240-ROLE_WIDTH) g_Role.x=240-ROLE_WIDTH;
}
Draw();
}
break;


游戏画面在一个函数Draw中绘制出来并在WM_PAINT中调用复制画面
case WM_PAINT://窗口被重画
BitBlt(GetDC(hWnd),0,0,WINDOW_WIDTH,WINDOW_HEIGHT,g_hDrawDC,0,0,SRCCOPY);
break;


//绘制游戏画面
void Draw()
{
HDC hDC;
HBITMAP hBmp;
HBITMAP hOldBmp;

//创建临时DC
hDC=CreateCompatibleDC(GetDC(g_hMainWnd));

//绘制白色底色
RECT rt;
rt.left=0;
rt.top=0;
rt.right=WINDOW_WIDTH;
rt.bottom=WINDOW_HEIGHT;
FillRect(g_hDrawDC,&rt,NULL);

//绘制木板
int i;

for(i=0;i<BOARD_COUNT;i++)
{
if(g_Board[i].nType==BOARD_STONE)//绘制石板
{
hBmp=LoadBitmap(g_hInstance,"石板");

//绑定位图
hOldBmp=(HBITMAP)SelectObject(hDC,hBmp);
TransparentBlt(g_hDrawDC,g_Board[i].x,g_Board[i].y,96,16,hDC,0,0,96,16,0xFF00FF);
SelectObject(hDC,hOldBmp);
DeleteObject(hBmp);
}
else if(g_Board[i].nType==BOARD_WOOD)//绘制木板
{
if(g_Board[i].nState==0)
{
hBmp=LoadBitmap(g_hInstance,"木板");

//绑定位图
hOldBmp=(HBITMAP)SelectObject(hDC,hBmp);
TransparentBlt(g_hDrawDC,g_Board[i].x,g_Board[i].y,96,16,hDC,0,0,96,16,0xFF00FF);
}
else if(g_Board[i].nState<4)
{
hBmp=LoadBitmap(g_hInstance,"碎木板");

//绑定位图
hOldBmp=(HBITMAP)SelectObject(hDC,hBmp);
TransparentBlt(g_hDrawDC,g_Board[i].x,g_Board[i].y,96,16,hDC,0,0,96,16,0xFF00FF);
}

SelectObject(hDC,hOldBmp);
DeleteObject(hBmp);
}
else if(g_Board[i].nType==BOARD_DOG)//绘制钉板
{
hBmp=LoadBitmap(g_hInstance,"钉板");

//绑定位图
hOldBmp=(HBITMAP)SelectObject(hDC,hBmp);
TransparentBlt(g_hDrawDC,g_Board[i].x,g_Board[i].y,96,16,hDC,0,0,96,16,0xFF00FF);
SelectObject(hDC,hOldBmp);
DeleteObject(hBmp);
}
else if(g_Board[i].nType==BOARD_SPRING)//绘制弹簧
{
if(g_Board[i].nState==0)
{
hBmp=LoadBitmap(g_hInstance,"弹簧");

//绑定位图
hOldBmp=(HBITMAP)SelectObject(hDC,hBmp);
TransparentBlt(g_hDrawDC,g_Board[i].x,g_Board[i].y,96,16,hDC,0,0,96,16,0xFF00FF);
}
else if(g_Board[i].nState<=4)
{

hBmp=LoadBitmap(g_hInstance,"弹簧压缩");

//绑定位图
hOldBmp=(HBITMAP)SelectObject(hDC,hBmp);
TransparentBlt(g_hDrawDC,g_Board[i].x,g_Board[i].y,96,8,hDC,0,0,96,8,0xFF00FF);
}

SelectObject(hDC,hOldBmp);
DeleteObject(hBmp);
}
}

//绘制狗牙

hBmp=LoadBitmap(g_hInstance,"狗牙");

//绑定位图
hOldBmp=(HBITMAP)SelectObject(hDC,hBmp);
TransparentBlt(g_hDrawDC,0,0,240,16,hDC,0,0,240,16,0xFF00FF);
SelectObject(hDC,hOldBmp);
DeleteObject(hBmp);

//绘制角色
if(g_Role.nState==ROLE_LEFT)//向左
{
hBmp=LoadBitmap(g_hInstance,"左");

//绑定位图
hOldBmp=(HBITMAP)SelectObject(hDC,hBmp);
TransparentBlt(g_hDrawDC,g_Role.x,g_Role.y,ROLE_WIDTH,ROLE_HEIGHT,hDC,g_Role.nStep*ROLE_WIDTH,0,ROLE_WIDTH,ROLE_HEIGHT,0xFF00FF);
SelectObject(hDC,hOldBmp);
DeleteObject(hBmp);
}
else if(g_Role.nState==ROLE_RIGHT)//向右
{
hBmp=LoadBitmap(g_hInstance,"右");

//绑定位图
hOldBmp=(HBITMAP)SelectObject(hDC,hBmp);
TransparentBlt(g_hDrawDC,g_Role.x,g_Role.y,ROLE_WIDTH,ROLE_HEIGHT,hDC,g_Role.nStep*ROLE_WIDTH,0,ROLE_WIDTH,ROLE_HEIGHT,0xFF00FF);
SelectObject(hDC,hOldBmp);
DeleteObject(hBmp);
}
else if(g_Role.nState==ROLE_LOGY)//发呆
{
hBmp=LoadBitmap(g_hInstance,"发呆");

//绑定位图
hOldBmp=(HBITMAP)SelectObject(hDC,hBmp);
TransparentBlt(g_hDrawDC,g_Role.x,g_Role.y,ROLE_WIDTH,ROLE_HEIGHT,hDC,0,0,ROLE_WIDTH,ROLE_HEIGHT,0xFF00FF);
SelectObject(hDC,hOldBmp);
DeleteObject(hBmp);
}

DeleteDC(hDC);
//绘制分界线
MoveToEx(g_hDrawDC,240,0,NULL);
LineTo(g_hDrawDC,240,320);

HBRUSH hBr;

rt.left=241;
rt.top=0;
rt.bottom=320;
rt.right=320;

hBr=CreateSolidBrush(0xFFFFFF);
FillRect(g_hDrawDC,&rt,hBr);
DeleteObject(hBr);

char str[20];

strcpy(str,"层数:");
TextOut(g_hDrawDC,241,20,str,strlen(str));
itoa(g_Role.nFloorCount,str,10);
TextOut(g_hDrawDC,250,40,str,strlen(str));
strcpy(str,"生命:");
//绘制状态信息
TextOut(g_hDrawDC,241,70,str,strlen(str));
itoa(g_Role.Count,str,10);
TextOut(g_hDrawDC,250,90,str,strlen(str));
TextOut(g_hDrawDC,241,150,g_strInfo,strlen(g_strInfo));

BitBlt(GetDC(g_hMainWnd),0,0,WINDOW_WIDTH,WINDOW_HEIGHT,g_hDrawDC,0,0,SRCCOPY);
}
...全文
107 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
fangcunx 2012-11-11
  • 打赏
  • 举报
回复
不能编辑回复,因为长,开来不能分开编辑啊,版主删二楼回复
fangcunx 2012-11-11
  • 打赏
  • 举报
回复
占楼11111111111111111一会发

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧