标题:用Win API实现游戏《是男人就下100层》(游戏入门&追爱)
只看楼主
方寸
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2011-5-18
结帖率:0
已结贴  问题点数:20 回复次数:1 
用Win API实现游戏《是男人就下100层》(游戏入门&追爱)
此教程为追爱而写,
如果你觉得这篇教程还不错请在我的博客留言

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

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



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



是男人就下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(计时器)来实现板块的上移以及人物的自动下降6
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);
}
搜索更多相关主题的帖子: 游戏 教程 源代码下载 陌生人 
2012-11-11 11:14
w527705090
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:11
帖 子:441
专家分:1882
注 册:2011-6-28
得分:20 
支持   !!!去你博客留言了。。。

有心者,千方百计;无心者,千难万难。
2012-11-12 22:28



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-386699-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.072663 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved