直接贴代码:

 


#include <Windows.h>


//全局函数声明
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance, int nShowCmd);
void MyPaint(HDC hdc);
BOOL Game_CleanUp(HWND hwnd);//在此函数中进行资源的清理
//****对战消息新增函数*********************************
void MsgInsert(char* str);

//****玩家怪物生命值判断函数*************************
void CheckDie(int hp, bool player);



#define WINDOW_WIDTH 640 //为窗口宽度定义的宏,以方便在此处修改窗口宽度
#define WINDOW_HEIGHT 480 //为窗口高度定义的宏,以方便在此处修改窗口高度
#define WINDOW_TITLE "游戏开发的梦想" //为窗口标题定义的宏

//定义结构
struct chr
{
    int        nHp;
    int        fHp;
    int        lv;
    int        w;
    int        kind;
};
//全局变量
HBITMAP    bg, sheep, girl, skill, slash, magic, recover, game;
HDC        hdc, mdc, bufdc;
HWND    hWnd;
DWORD    tPre, tNow;
int        pNum, f, txtNum;
bool    attack, over;
chr        player, monster;
char    text[5][100];
//--------------------------------------------WinMain() 入口函数-----------------------------------------------
//应用程序的入口函数
//-------------------------------------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    MSG msg = { 0 };//定义并初始化msg
    MyRegisterClass(hInstance);

    if (!InitInstance(hInstance, nShowCmd))
    {
        return FALSE;
    }

    //游戏循环
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            tNow = GetTickCount();
            if (tNow - tPre >= 40)//相差0.04秒时再进行重绘操作
                MyPaint(hdc);
        }
    }

    return msg.wParam;
}

//--------------------------------------------MyRegisterClass() 函数-------------------------------------------
//注册窗口
//-------------------------------------------------------------------------------------------------------------
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    //创建窗口第一步:开始设计一个完整的窗口类
    WNDCLASSEX wndClass;//定义一个窗口类
    wndClass.cbSize = sizeof(WNDCLASSEX);//设置结构体的字节数大小
    wndClass.style = CS_HREDRAW | CS_VREDRAW;//设置窗口的样式
    wndClass.lpfnWndProc = (WNDPROC)WndProc;//设置指向窗口过程函数的指针
    wndClass.cbClsExtra = 0;//窗口类的附加内存,取0就可以了
    wndClass.cbWndExtra = 0;//窗口的附加内存,依然取0就行了
    wndClass.hInstance = hInstance;//指定包含窗口过程的程序的实例句柄
    wndClass.hIcon = (HICON) ::LoadImage(NULL, "icon.ico", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);//加载自定义ico图标
    wndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);//指定窗口类的光标句柄
    wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//指定一个灰色画刷句柄
    wndClass.lpszMenuName = NULL;//用一个以空终止的字符串,指定菜单资源的名字.
    wndClass.lpszClassName = "GameClass";//指定窗口类的名称
    //wndClass.hIconsm = NULL;

    //创建窗口第二步:注册窗口类
    return RegisterClassEx(&wndClass);//设计完窗口后,需要对窗口类进行注册,这样才能创建该类型的窗口
}

//--------------------------------------------InitInstance() 函数----------------------------------------------
//加载资源
//-------------------------------------------------------------------------------------------------------------
BOOL InitInstance(HINSTANCE hInstance, int nShowCmd)
{
    HBITMAP bmp;

    //创建窗口第三步:正式创建窗口
    //创建窗口函数
    hWnd = CreateWindow("GameClass", WINDOW_TITLE, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    if (!hWnd)
    {
        return FALSE;
    }
    //创建窗口第四步:窗口的移动,显示和更新
    MoveWindow(hWnd, 250, 80, WINDOW_WIDTH, WINDOW_HEIGHT, true);//调整窗口显示时的位置及窗口的大小
    ShowWindow(hWnd, nShowCmd);//设定显示窗口时的状态
    UpdateWindow(hWnd);//将窗口绘制于显示设备上

    hdc = GetDC(hWnd);
    mdc = CreateCompatibleDC(hdc);
    bufdc = CreateCompatibleDC(hdc);
    //建立空白的位图
    bmp = CreateCompatibleBitmap(hdc, 640, 480);
    SelectObject(mdc, bmp);
    //加载图片
    bg = (HBITMAP)LoadImage(NULL, "bg.bmp", IMAGE_BITMAP, 640, 480, LR_LOADFROMFILE);
    sheep = (HBITMAP)LoadImage(NULL, "sheep.bmp", IMAGE_BITMAP, 133, 220, LR_LOADFROMFILE);
    girl = (HBITMAP)LoadImage(NULL, "girl.bmp", IMAGE_BITMAP, 480, 148, LR_LOADFROMFILE);
    skill = (HBITMAP)LoadImage(NULL, "skill.bmp", IMAGE_BITMAP, 74, 60, LR_LOADFROMFILE);
    slash = (HBITMAP)LoadImage(NULL, "slash.bmp", IMAGE_BITMAP, 196, 162, LR_LOADFROMFILE);
    magic = (HBITMAP)LoadImage(NULL, "magic.bmp", IMAGE_BITMAP, 200, 100, LR_LOADFROMFILE);
    recover = (HBITMAP)LoadImage(NULL, "recover.bmp", IMAGE_BITMAP, 300, 150, LR_LOADFROMFILE);
    game = (HBITMAP)LoadImage(NULL, "over.bmp", IMAGE_BITMAP, 289, 74, LR_LOADFROMFILE);

    player.nHp = player.fHp = 50;    //
    player.lv = 2;                    //
    player.w = 4;                    //

    monster.nHp = monster.fHp = 100;    //
    monster.lv = 1;                        //
    monster.w = 1;                        //
    txtNum = 0;

    MyPaint(hdc);
    return TRUE;
}

//--------------------------------------------MyPaint() 函数---------------------------------------------------
//绘制图形
//-------------------------------------------------------------------------------------------------------------
void MyPaint(HDC hdc)
{
    char str[100];
    int i, damage;

    //贴上背景图
    SelectObject(bufdc, bg);
    BitBlt(mdc, 0, 0, 640, 480, bufdc, 0, 0, SRCCOPY);

    //显示对战消息
    for (i = 0; i<txtNum; i++)
        TextOut(mdc, 0, 360 + i * 18, text[i], strlen(text[i]));

    //贴上怪物图
    if (monster.nHp>0)
    {
        SelectObject(bufdc, sheep);
        BitBlt(mdc, 70, 180, 133, 110, bufdc, 0, 110, SRCAND);
        BitBlt(mdc, 70, 180, 133, 110, bufdc, 0, 0, SRCPAINT);
        wsprintf(str, "%d / %d", monster.nHp, monster.fHp);
        TextOut(mdc, 100, 320, str, strlen(str));
    }

    //帖上玩家图
    if (player.nHp > 0)
    {
        SelectObject(bufdc, girl);
        BitBlt(mdc, 500, 200, 60, 74, bufdc, pNum * 60, 74, SRCAND);
        BitBlt(mdc, 500, 200, 60, 74, bufdc, pNum * 60, 0, SRCPAINT);
        wsprintf(str, "%d / %d", player.nHp, player.fHp);
        TextOut(mdc, 510, 320, str, strlen(str));
    }

    if (over)                //帖上游戏结束图标
    {
        SelectObject(bufdc, game);
        BitBlt(mdc, 200, 200, 289, 37, bufdc, 0, 37, SRCAND);
        BitBlt(mdc, 200, 200, 289, 37, bufdc, 0, 0, SRCPAINT);
    }
    else if (!attack)        //贴上攻击命令图标
    {
        SelectObject(bufdc, skill);
        BitBlt(mdc, 500, 350, 74, 30, bufdc, 0, 30, SRCAND);
        BitBlt(mdc, 500, 350, 74, 30, bufdc, 0, 0, SRCPAINT);
    }
    else
    {
        f++;

        //第5—10个画面时显示玩家攻击图标
        if (f >= 5 && f <= 10)
        {
            SelectObject(bufdc, slash);
            BitBlt(mdc, 100, 160, 98, 162, bufdc, 98, 0, SRCAND);
            BitBlt(mdc, 100, 160, 98, 162, bufdc, 0, 0, SRCPAINT);

            //第10个画面时计算怪物受伤害程度并加入消息
            if (f == 10)
            {
                damage = rand() % 10 + player.lv*player.w;
                monster.nHp -= (int)damage;

                wsprintf(str, "玩家攻击...玩家对怪物造成了 %d 的伤害", damage);
                MsgInsert(str);

                CheckDie(monster.nHp, false);
            }
        }

        srand(tPre);

        //第15个画面时判断怪物进行哪项动作
        if (f == 15)
        {
            if (monster.nHp > 20)                //生命值大于20
            {
                if (rand() % 10 != 1)
                    monster.kind = 0;
                else
                    monster.kind = 1;
            }
            else                                //生命值小于20
            {
                switch (rand() % 5)
                {
                case 0:                        //普通攻击
                    monster.kind = 0;
                    break;
                case 1:                        //施放攻击魔法
                    monster.kind = 1;
                    break;
                case 2:                        //使尽全力攻击
                    monster.kind = 2;
                    break;
                case 3:                        //补血
                    monster.kind = 3;
                    break;
                case 4:                        //逃跑
                    monster.kind = 4;
                    break;
                }
            }
        }

        //第26-30个画面时显示玩家攻击图标
        if (f >= 26 && f <= 30)
        {
            switch (monster.kind)
            {
            case 0:                            //普通攻击
                SelectObject(bufdc, slash);
                BitBlt(mdc, 480, 150, 98, 162, bufdc, 98, 0, SRCAND);
                BitBlt(mdc, 480, 150, 98, 162, bufdc, 0, 0, SRCPAINT);

                //第30个画面时计算玩家受伤害程度并加入显示消息
                if (f == 30)
                {
                    damage = rand() % 10 + monster.lv*monster.w;
                    player.nHp -= (int)damage;

                    wsprintf(str, "怪物攻击...怪物对玩家造成了 %d 的伤害", damage);
                    MsgInsert(str);

                    CheckDie(player.nHp, true);
                }
                break;
            case 1:                            //施放攻击魔法
                SelectObject(bufdc, magic);
                BitBlt(mdc, 480, 190, 100, 100, bufdc, 100, 0, SRCAND);
                BitBlt(mdc, 480, 190, 100, 100, bufdc, 0, 0, SRCPAINT);

                //第30个画面时计算玩家受伤害程度并加入显示消息
                if (f == 30)
                {
                    damage = rand() % 10 + 3 * monster.w;
                    player.nHp -= (int)damage;

                    wsprintf(str, "怪物魔法攻击...怪物对玩家造成了 %d 的伤害", damage);
                    MsgInsert(str);

                    CheckDie(player.nHp, true);
                }
                break;
            case 2:                            //使尽全力攻击
                SelectObject(bufdc, slash);
                BitBlt(mdc, 480, 150, 98, 162, bufdc, 98, 0, SRCAND);
                BitBlt(mdc, 480, 150, 98, 162, bufdc, 0, 0, SRCPAINT);

                //第30个画面时计算玩家受伤害程度并加入显示消息
                if (f == 30)
                {
                    damage = rand() % 10 + monster.lv*monster.w * 5;
                    player.nHp -= (int)damage;

                    wsprintf(str, "怪物全力攻击...怪物对玩家造成了 %d 的伤害", damage);
                    MsgInsert(str);

                    CheckDie(player.nHp, true);
                }
                break;
            case 3:                            //补血
                SelectObject(bufdc, recover);
                BitBlt(mdc, 60, 160, 150, 150, bufdc, 150, 0, SRCAND);
                BitBlt(mdc, 60, 160, 150, 150, bufdc, 0, 0, SRCPAINT);

                //第30个画面时怪物恢复生命值并加入显示消息
                if (f == 30)
                {
                    monster.nHp += 30;

                    wsprintf(str, "怪物魔法补血...恢复了 30 生命值", damage);
                    MsgInsert(str);
                }
                break;
            case 4:
                //第30个画面时判断怪物是否逃跑成功
                if (f == 30)
                {
                    if (rand() % 3 == 1)    //逃跑成功几率为1/3
                    {
                        over = true;
                        monster.nHp = 0;

                        wsprintf(str, "怪物逃跑...逃跑成功");
                        MsgInsert(str);
                    }
                    else
                    {
                        wsprintf(str, "怪物逃跑...逃跑失败");
                        MsgInsert(str);
                    }
                }
                break;
            }
        }

        if (f == 30)            //回合结束
        {
            attack = false;
            f = 0;
        }
    }

    BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY);

    tPre = GetTickCount();

    pNum++;
    if (pNum == 8)
        pNum = 0;
}
//****对战消息新增函数*********************************
void MsgInsert(char* str)
{
    if (txtNum < 5)
    {
        wsprintf(text[txtNum], str);
        txtNum++;
    }
    else
    {
        for (int i = 0; i < txtNum; i++)
            wsprintf(text[i], text[i + 1]);

        wsprintf(text[4], str);
    }
}

//****玩家怪物生命值判断函数*************************
void CheckDie(int hp, bool player)
{
    char str[100];

    if (hp <= 0)
    {
        over = true;
        if (player)
        {
            wsprintf(str, "你被怪物找败了...");
            MsgInsert(str);
        }
        else
        {
            wsprintf(str, "怪物歼灭...");
            MsgInsert(str);
        }
    }
}

//--------------------------------------------Game_CleanUp() 函数----------------------------------------------
//资源清理函数,在此函数中进行退出前的资源的清理工作
//-------------------------------------------------------------------------------------------------------------
BOOL Game_CleanUp()
{
    ClipCursor(NULL);            //解除鼠标限制

    DeleteDC(mdc);
    DeleteDC(bufdc);
    DeleteObject(bg);
    DeleteObject(sheep);
    DeleteObject(girl);
    DeleteObject(skill);
    DeleteObject(slash);
    DeleteObject(magic);
    DeleteObject(recover);
    DeleteObject(game);
    ReleaseDC(hWnd, hdc);
    return TRUE;
}

//--------------------------------------------WndProc() 窗口消息回调函数---------------------------------------
//窗口过程函数WndProc,对窗口消息进行处理
//-------------------------------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    int x, y;
    switch (message)
    {
    case WM_PAINT://窗口重绘消息
    {
                      hdc = BeginPaint(hwnd, &ps);
                      MyPaint(hdc);
                      EndPaint(hwnd, &ps);
    }
        break;
    case WM_LBUTTONDOWN://单击鼠标左键消息
    {
                            x = LOWORD(lParam);//取得鼠标X坐标
                            y = HIWORD(lParam);//取得鼠标Y坐标
                            if (x >= 500 && x <= 574 && y >= 350 && y <= 380)
                                attack = true;
    }
        break;
    case WM_KEYDOWN://若是键盘按下消息
    {
                        if (wParam == VK_ESCAPE)//如果按下的键是ESC
                        {
                            if (MessageBox(hwnd, "退出?", "提示", MB_YESNO | MB_ICONQUESTION) == IDYES)
                                DestroyWindow(hwnd);//销毁窗口,并发送一条WM_DESTROY消息
                        }
    }
        break;
    case WM_CLOSE://关闭按钮
    {
                      if (MessageBox(hwnd, "是否要退出?", "提示", MB_YESNO | MB_ICONQUESTION) == IDYES)
                          DestroyWindow(hwnd);//销毁窗口,并发送一条WM_DESTROY消息
                      else
                          return(0);
    }
        break;
    case WM_DESTROY://窗口结束消息
    {
                        //删除资源
                        Game_CleanUp();
                        PostQuitMessage(0);//向系统表明有个线程有终止的请求,用来响应WM_DESTROY消息
    }
        break;
    default://若是上述case条件都不符合,则执行该default语句
    {
                return DefWindowProc(hwnd, message, wParam, lParam);//调用默认的窗口过程
    }
    }
    return 0;//正常退出
}

 

posted on 2015-12-09 15:18  zishen  阅读(359)  评论(0编辑  收藏  举报