小游戏“程序猿大战产品狗”

致大神“浅墨”,毛星云,网名「浅墨」,微软MVP,《Windows游戏编程之从零开始》作者。

不知还有多少人记得, 2021-12-13,知名游戏开发大神毛星云(网名「浅墨」)不幸去世。

我也是在网上看到他去世的消息后,才知道他是个大神级的人物的。做为一个热(上)爱(班)学(摸)习(鱼)的程序猿来说,学习一下游戏开发,也是挺让人高兴的一件事。于是下载了《Windows游戏编程之从零开始》,开始学习。

按照书上第9章《勇者斗恶龙》的内容,修改成了一个小游戏,《程序猿VS产品狗》,截图和代码如下,有兴趣的小伙伴,可以下载下来,运行Release里面的exe来玩耍。

大神“浅墨”R.I.P.

 

 

----->  代码下载  <-----

 

main.cpp

/*
    程序名称::Fighting
    2022/01/25 Create by Junior
*/

// 属性-常规页-字符集【使用 Unicode 字符集】

#include <Windows.h>
#include <time.h>
#include <tchar.h>
#pragma comment(lib,"winmm.lib")
#pragma  comment(lib,"Msimg32.lib")

#define WINDOW_WIDTH    800
#define WINDOW_HEIGHT    600
#define PARTICLE_NUMBER 50
#define WINDOW_TITLE    L"[ESC退出]~~~程序员 VS 产品狗~~~"

struct CHARACTER
{
    int NowHp;
    int MaxHp;
    int NowMp;
    int MaxMp;
    int Level;
    int Strength;
    int Intelligence;
    int Agility;
};
CHARACTER Coder, PM;

struct SNOW
{
    int x;
    int y;
    BOOL exist;
};

enum ActionTypes
{
    Action_Type_NORMAL,
    Action_Type_CRITICAL,
    Action_Type_MAGIC,
    Action_Type_MISS,
    Action_Type_RECOVER
};
ActionTypes CoderActionType, BossActionType;

HDC g_hdc = NULL, g_mdc=NULL, g_bufdc=NULL;
DWORD g_tPre = 0, g_tNow = 0;
RECT g_rect;
SNOW SnowFlowers[PARTICLE_NUMBER];
int g_SnowNumb = 0;
int g_iFrameNum, g_iTxtNum;
wchar_t text[8][100];
BOOL g_bCanAttack, g_bGameOver;

HBITMAP g_hBackGround, g_hGameOver, g_hVictory, g_hSnow;
HBITMAP g_hPMBitmap, g_hCoderBitmap, g_hRecoverSkill;
HBITMAP g_hSkillButton1, g_hSkillButton2, g_hSkillButton3, g_hSkillButton4;
HBITMAP g_hCoderSkill1, g_hCoderSkill2, g_hCoderSkill3;
HBITMAP g_hBossSkill1, g_hBossSkill2, g_hBossSkill3;

LRESULT CALLBACK    WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL Game_Init(HWND hwnd);
VOID Game_Main(HWND hwnd);
BOOL Game_ShutDown(HWND hwnd);

VOID Die_Check(int nowHp, bool isCoder);
VOID Message_Insert(wchar_t* str);
VOID CoderAction_Logic();
VOID BossAction_Logic();
VOID CoderAction_Paint();
VOID BossAction_Paint();
VOID Snow_Paint();
//-----------------------------------【WinMain( )函数】--------------------------------------
//    描述:Windows应用程序的入口函数,我们的程序从这里开始
//------------------------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    //【1】窗口创建四步曲之一:开始设计一个完整的窗口类
    WNDCLASSEX wndClass = { 0 };
    wndClass.cbSize = sizeof(WNDCLASSEX);
    wndClass.style = CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc = WndProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
    wndClass.hInstance = hInstance;
    wndClass.hIcon = (HICON)::LoadImage(NULL, L"icon.ico", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    //wndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = L"ForFnHC";

    //【2】窗口创建四步曲之二:注册窗口类
    if (!RegisterClassEx(&wndClass))
        return -1;

    //【3】窗口创建四步曲之三:正式创建窗口
    HWND hwnd = CreateWindow(L"ForFnHC", WINDOW_TITLE, WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT,
        WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);

    //【4】窗口创建四步曲之四:窗口的移动、显示与更新
    MoveWindow(hwnd, 250, 80, WINDOW_WIDTH, WINDOW_HEIGHT, true);
    ShowWindow(hwnd, nShowCmd);
    
    UpdateWindow(hwnd);

    if (!Game_Init(hwnd))
    {
        MessageBox(hwnd, L"资源初始化失败", L"消息窗口", 0);
        return FALSE;
    }
    PlaySound(L"GameMedia\\梦幻西游原声-战斗1-森林.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);

    //【5】消息循环过程
    MSG msg = { 0 };
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {            
            g_tNow = GetTickCount();
            if (g_tNow - g_tPre >= 60)
            {
                Game_Main(hwnd);
            }
        }
    }

    UnregisterClass(L"ForFnHC", wndClass.hInstance);
    return 0;
}


// 接口实现
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_SIZE:
        //MoveWindow(hwnd, 250, 80, WINDOW_WIDTH, WINDOW_HEIGHT, true);        
        break;
    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE)
            PostQuitMessage(0);
            //DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        Game_ShutDown(hwnd);
        PostQuitMessage(0);
        break;
    case WM_LBUTTONDOWN:
        if (!g_bCanAttack)
        {
            int x = LOWORD(lParam);
            int y = HIWORD(lParam);
            if (x >= 530 && x <= 570 && y >= 420 && y <= 470)
            {
                g_bCanAttack = true;
                CoderActionType = Action_Type_NORMAL;
            }
            if (x >= 590 && x <= 640 && y >= 420 && y <= 470)
            {
                g_bCanAttack = true;
                CoderActionType = Action_Type_MAGIC;
            }
            if (x >= 650 && x <= 700 && y >= 420 && y <= 470)
            {
                g_bCanAttack = true;
                CoderActionType = Action_Type_RECOVER;
            }
        }
        if (g_bGameOver)
        {
            Game_Init(hwnd);
        }
        break;
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }

    return 0;
}

BOOL Game_Init(HWND hwnd)
{
    srand((unsigned)time(NULL));

    HBITMAP bmp;
    g_hdc = GetDC(hwnd);
    g_mdc = CreateCompatibleDC(g_hdc);
    g_bufdc = CreateCompatibleDC(g_hdc);
    bmp = CreateCompatibleBitmap(g_hdc, WINDOW_WIDTH, WINDOW_HEIGHT);

    SelectObject(g_mdc, bmp);
    g_hGameOver = (HBITMAP)LoadImage(NULL, L"GameMedia\\gameover.bmp", IMAGE_BITMAP, 1086, 396, LR_LOADFROMFILE);
    g_hVictory = (HBITMAP)LoadImage(NULL, L"GameMedia\\victory.bmp", IMAGE_BITMAP, 800, 600, LR_LOADFROMFILE);
    g_hPMBitmap = (HBITMAP)LoadImage(NULL, L"GameMedia\\monster11.bmp", IMAGE_BITMAP, 280, 280, LR_LOADFROMFILE);
    g_hCoderBitmap = (HBITMAP)LoadImage(NULL, L"GameMedia\\hero11.bmp", IMAGE_BITMAP, 280, 280, LR_LOADFROMFILE);
    g_hCoderSkill1 = (HBITMAP)LoadImage(NULL, L"GameMedia\\heroslash.bmp", IMAGE_BITMAP, 364, 140, LR_LOADFROMFILE);
    g_hCoderSkill2 = (HBITMAP)LoadImage(NULL, L"GameMedia\\heromagic.bmp", IMAGE_BITMAP, 374, 288, LR_LOADFROMFILE);
    g_hCoderSkill3 = (HBITMAP)LoadImage(NULL, L"GameMedia\\herocritical.bmp", IMAGE_BITMAP, 574, 306, LR_LOADFROMFILE);
    g_hBackGround = (HBITMAP)LoadImage(NULL, L"GameMedia\\bg.bmp", IMAGE_BITMAP, WINDOW_WIDTH, WINDOW_HEIGHT, LR_LOADFROMFILE);
    // TODO: 图是64*64的,这里用的50*50?
    g_hSkillButton1 = (HBITMAP)LoadImage(NULL, L"GameMedia\\skillbutton1.bmp", IMAGE_BITMAP, 50, 50, LR_LOADFROMFILE);
    g_hSkillButton2 = (HBITMAP)LoadImage(NULL, L"GameMedia\\skillbutton2.bmp", IMAGE_BITMAP, 50, 50, LR_LOADFROMFILE);
    g_hSkillButton3 = (HBITMAP)LoadImage(NULL, L"GameMedia\\skillbutton3.bmp", IMAGE_BITMAP, 50, 50, LR_LOADFROMFILE);
    //g_hSkillButton4 = (HBITMAP)LoadImage(NULL, L"GameMedia\\skillbutton4.bmp", IMAGE_BITMAP, 50, 50, LR_LOADFROMFILE);

    g_hBossSkill1 = (HBITMAP)LoadImage(NULL, L"GameMedia\\monsterslash.bmp", IMAGE_BITMAP, 234, 188, LR_LOADFROMFILE);
    g_hBossSkill2 = (HBITMAP)LoadImage(NULL, L"GameMedia\\monstermagic.bmp", IMAGE_BITMAP, 387, 254, LR_LOADFROMFILE);
    g_hBossSkill3 = (HBITMAP)LoadImage(NULL, L"GameMedia\\monstercritical.bmp", IMAGE_BITMAP, 574, 306, LR_LOADFROMFILE);

    g_hSnow = (HBITMAP)LoadImage(NULL, L"GameMedia\\snow.bmp", IMAGE_BITMAP, 25, 25, LR_LOADFROMFILE);
    g_hRecoverSkill = (HBITMAP)LoadImage(NULL, L"GameMedia\\recover.bmp", IMAGE_BITMAP, 150, 150, LR_LOADFROMFILE);

    GetClientRect(hwnd, &g_rect);

    g_bGameOver = false;
    //Game_Paint(hwnd);
    Coder.NowHp = Coder.MaxHp = 1000;
    Coder.Level = 6;
    Coder.NowMp = Coder.MaxMp = 60;
    Coder.Strength = 10;
    Coder.Agility = 20;
    Coder.Intelligence = 10;

    PM.NowHp = PM.MaxHp = 2000;
    PM.Level = 10;
    PM.Strength = 10;
    PM.Agility = 10;
    PM.Intelligence = 10;

    g_iTxtNum = 0;

    // 设置字体
    HFONT hFont;
    hFont = CreateFont(20, 0, 0, 0, 700, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, TEXT("微软雅黑"));
    SelectObject(g_mdc, hFont);
    SetBkMode(g_mdc, TRANSPARENT);

    Game_Main(hwnd);

    return TRUE;
}
VOID Game_Main(HWND hwnd)
{
    wchar_t str[100];
    // 在mdc中贴上图片
    SelectObject(g_bufdc, g_hBackGround);
    BitBlt(g_mdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_bufdc, 0, 0, SRCCOPY);

    if (!g_bGameOver)
    {
        Snow_Paint();
    }
    SetTextColor(g_mdc, RGB(255, 53, 39));
    for (int i = 0; i < g_iTxtNum; i++)
    {
        TextOut(g_mdc, 20, 410 + i * 18, text[i], wcslen(text[i]));
    }
    // 贴上产品狗图及显示血量
    if (PM.NowHp > 0)
    {
        SelectObject(g_bufdc, g_hPMBitmap);
        TransparentBlt(g_mdc, 20, 60, 280, 280, g_bufdc, 0, 0, 280, 280, RGB(0, 0, 191));
        swprintf_s(str, L"%d / %d", PM.NowHp, PM.MaxHp);
        SetTextColor(g_mdc, RGB(255, 10, 10));
        TextOut(g_mdc, 100, 360, str, wcslen(str));
    }
    // 贴上程序猿图及显示血量/魔法值
    if (Coder.NowHp > 0)
    {
        SelectObject(g_bufdc, g_hCoderBitmap);
        TransparentBlt(g_mdc, 450, 60, 280, 280, g_bufdc, 0, 0, 280, 280, RGB(33, 150, 243));
        swprintf_s(str, L"%d / %d", Coder.NowHp, Coder.MaxHp);
        SetTextColor(g_mdc, RGB(255, 10, 10));
        TextOut(g_mdc, 580, 360, str, wcslen(str));
        swprintf_s(str, L"%d / %d", Coder.NowMp, Coder.MaxMp);
        SetTextColor(g_mdc, RGB(10, 10, 255));
        TextOut(g_mdc, 590, 380, str, wcslen(str));
    }

    if (g_bGameOver)
    {
        if (Coder.NowHp <= 0)
        {
            SelectObject(g_bufdc, g_hGameOver);
            BitBlt(g_mdc, 120, 60, 543, 396, g_bufdc, 543, 0, SRCAND);
            BitBlt(g_mdc, 120, 60, 543, 396, g_bufdc, 0, 0, SRCPAINT);
        }
        else
        {
            SelectObject(g_bufdc, g_hVictory);
            TransparentBlt(g_mdc, 0,0,800,600,g_bufdc,0,0,800,600,RGB(0,0,0));
        }
    }
    else if (!g_bCanAttack)
    {
        SelectObject(g_bufdc, g_hSkillButton1);
        BitBlt(g_mdc, 530, 420, 60, 50, g_bufdc, 0, 0, SRCAND);
        SelectObject(g_bufdc, g_hSkillButton2);
        BitBlt(g_mdc, 590, 420, 60, 50, g_bufdc, 0, 0, SRCAND);
        SelectObject(g_bufdc, g_hSkillButton3);
        BitBlt(g_mdc, 650, 420, 60, 50, g_bufdc, 0, 0, SRCAND);
        //SelectObject(g_bufdc, g_hSkillButton4);
        //BitBlt(g_mdc, 710, 420, 50, 50, g_bufdc, 0, 0, SRCAND);
    }
    else// 游戏没有结束,且程序猿为不可攻击状态
    {
        g_iFrameNum++;
        if (g_iFrameNum >= 5 && g_iFrameNum <= 10)
        {
            if (g_iFrameNum == 5)
            {
                CoderAction_Logic();
                Die_Check(PM.NowHp, false);
            }
            CoderAction_Paint();
        }
        if (g_iFrameNum == 15)
        {
            BossAction_Logic();
        }
        if (g_iFrameNum >= 26 && g_iFrameNum <= 30)
        {            
            BossAction_Paint();
        }
        if (g_iFrameNum == 30)
        {
            g_bCanAttack = false;
            g_iFrameNum = 0;

            if (!g_bGameOver)
            {
                int mpRecover = 2 * (rand() % Coder.Intelligence) + 6;
                Coder.NowMp += mpRecover;
                if (Coder.NowMp > Coder.MaxMp)
                    Coder.NowMp = Coder.MaxMp;

                swprintf_s(str, L"回合结束,程序猿恢复了【%d】点魔法值!", mpRecover);
                Message_Insert(str);
            }
        }
    }
    
    // 将 mdc的内容全部贴到 hdc 上
    BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);
    g_tPre = GetTickCount();
}


BOOL Game_ShutDown(HWND hwnd)
{
    //释放资源对象
    DeleteObject(g_hBackGround);
    DeleteObject(g_hGameOver);
    DeleteObject(g_hVictory);    
    DeleteObject(g_hSnow);
    DeleteObject(g_hPMBitmap);
    DeleteObject(g_hCoderBitmap);
    DeleteObject(g_hRecoverSkill);
    DeleteObject(g_hSkillButton1);
    DeleteObject(g_hSkillButton2);
    DeleteObject(g_hSkillButton3);
    DeleteObject(g_hSkillButton4);
    DeleteObject(g_hCoderSkill1);
    DeleteObject(g_hCoderSkill2);
    DeleteObject(g_hCoderSkill3);
    DeleteObject(g_hBossSkill1);
    DeleteObject(g_hBossSkill2);
    DeleteObject(g_hBossSkill3);
    DeleteDC(g_bufdc);
    DeleteDC(g_mdc);
    ReleaseDC(hwnd, g_hdc);

    return TRUE;
}

VOID Message_Insert(wchar_t * str)
{
    if (g_iTxtNum < 8)
    {
        swprintf_s(text[g_iTxtNum], str);
        g_iTxtNum++;
    }
    else
    {
        for (int i = 0; i < g_iTxtNum; i++)
        {
            swprintf_s(text[i], text[i + 1]);
        }
        swprintf_s(text[7], str);
    }
}

VOID Die_Check(int NowHp, bool isCoder)
{
    wchar_t str[100];
    if (NowHp <= 0)
    {
        g_bGameOver = true;
        if (isCoder)
        {
            PlaySound(L"GameMedia\\failure.wav", NULL, SND_FILENAME | SND_ASYNC);
            swprintf_s(str, L":( 胜败乃兵家常事,大侠请重新来过……");
            Message_Insert(str);
        }
        else
        {
            PlaySound(L"GameMedia\\victory.wav", NULL, SND_FILENAME | SND_ASYNC);
            swprintf_s(str, L"少年,你赢了,有两下子啊~~~!!!");
            Message_Insert(str);
        }
    }
}

VOID CoderAction_Logic()
{
    int damage = 0;
    wchar_t str[100];
    switch (CoderActionType)
    {
    case Action_Type_NORMAL:
        if (rand() % 4 == 1)
        {
            CoderActionType = Action_Type_CRITICAL;
            damage = (int)(4.5 * (3 * (rand() % Coder.Agility) + Coder.Level * Coder.Strength + 20));
            PM.NowHp -= damage;
            swprintf_s(str, L"【万键归宗】被触发,这下牛逼了,4.5倍暴击……对产品狗造成了【%d】点伤害!", damage);
        }
        else
        {
            damage = 3 * (rand() % Coder.Agility) + Coder.Level * Coder.Strength + 20;
            PM.NowHp -= damage;
            swprintf_s(str, L"程序猿使用了普通攻击【键盘斩】,伤害一般般……对产品狗造成了【%d】点伤害!", damage);
        }
        Message_Insert(str);
        break;
    case Action_Type_MAGIC:
        if (Coder.NowMp >= 30)
        {
            damage = 5 * (2 * (rand() % Coder.Agility) + Coder.Level * Coder.Intelligence);
            PM.NowHp -= damage;
            Coder.NowMp -= 30;
            swprintf_s(str, L"程序猿使用了【黑眼圈凝视】……对产品狗造成了【%d】点伤害!", damage);
        }
        else
        {
            CoderActionType = Action_Type_MISS;
            swprintf_s(str, L"魔法值不足30点,施法失败,这回合白费了~~~!!!");
        }
        Message_Insert(str);
        break;
    case Action_Type_RECOVER:
        if (Coder.NowMp >= 40)
        {
            Coder.NowMp -= 40;
            int recoverHp = 5 * (5 * (rand() % Coder.Intelligence) + 40);
            Coder.NowHp += recoverHp;
            if (Coder.NowHp > Coder.MaxHp)
                Coder.NowHp = Coder.MaxHp;

            swprintf_s(str, L"程序猿使用了【抽根烟】,恢复了【%d】点生命值!", recoverHp);
        }
        else
        {
            CoderActionType = Action_Type_MISS;
            swprintf_s(str, L"魔法值不足40点,施法失败,这回合白费了~~~!!!");
        }
        Message_Insert(str);
        break;
    }
}

VOID CoderAction_Paint()
{
    switch (CoderActionType)
    {
    case Action_Type_NORMAL:
        SelectObject(g_bufdc, g_hCoderSkill1);
        TransparentBlt(g_mdc, 50, 170, 264, 140, g_bufdc, 0, 0, 364, 140, RGB(0, 0, 0));
        break;
    case Action_Type_CRITICAL:
        SelectObject(g_bufdc, g_hCoderSkill3);
        TransparentBlt(g_mdc, 20, 60, 574, 306, g_bufdc, 0, 0, 574, 306, RGB(0, 0, 0));
        break;
    case Action_Type_MAGIC:
        SelectObject(g_bufdc, g_hCoderSkill2);
        TransparentBlt(g_mdc, 50, 100, 374, 288, g_bufdc, 0, 0, 374, 288, RGB(0, 0, 0));
        break;
    case Action_Type_RECOVER:
        SelectObject(g_bufdc, g_hRecoverSkill);
        TransparentBlt(g_mdc, 560, 170, 150, 150, g_bufdc, 0, 0, 150, 150, RGB(0, 0, 0));
        break;
    }
}

VOID BossAction_Logic()
{
    srand((unsigned)time(NULL));
    if (PM.NowHp > PM.MaxHp / 2)
    {
        switch (rand() % 3)
        {
        case 0:
            BossActionType = Action_Type_NORMAL;
            break;
        case 1:
            BossActionType = Action_Type_CRITICAL;
            break;
        case 2:
            BossActionType = Action_Type_MAGIC;
            break;
        }
    }
    else
    {
        switch (rand() % 3)
        {
        case 0:
            BossActionType = Action_Type_MAGIC;
            break;
        case 1:
            BossActionType = Action_Type_CRITICAL;
            break;
        case 2:
            BossActionType = Action_Type_RECOVER;
            break;
        }
    }
}

VOID BossAction_Paint()
{
    int damage = 0, recover = 0;
    wchar_t str[100];
    switch (BossActionType)
    {
    case Action_Type_NORMAL:
        SelectObject(g_bufdc, g_hBossSkill1);
        TransparentBlt(g_mdc, 500, 150, 234, 188, g_bufdc, 0, 0, 234, 188, RGB(0, 0, 0));
        if (g_iFrameNum == 30)
        {
            damage = rand() % PM.Agility + PM.Level * PM.Strength;
            Coder.NowHp -= damage;
            swprintf_s(str, L"产品狗释放了【薅头发】……,对程序猿造成了【%d】点伤害!", damage);
            Message_Insert(str);
            Die_Check(Coder.NowHp, true);
        }
        break;
    case Action_Type_CRITICAL:
        SelectObject(g_bufdc, g_hBossSkill3);
        TransparentBlt(g_mdc, 280, 100, 574, 306, g_bufdc, 0, 0, 574, 306, RGB(0, 0, 0));
        if (g_iFrameNum == 30)
        {
            damage = 2 * (rand() % PM.Agility + PM.Level * PM.Strength);
            Coder.NowHp -= damage;
            swprintf_s(str, L"产品狗使用了【老板说的】……,对程序猿造成了【%d】点伤害!", damage);
            Message_Insert(str);
            Die_Check(Coder.NowHp, true);
        }
        break;
    case Action_Type_MAGIC:
        SelectObject(g_bufdc, g_hBossSkill2);
        TransparentBlt(g_mdc, 450, 150, 387, 254, g_bufdc, 0, 0, 387, 254, RGB(0, 0, 0));
        if (g_iFrameNum == 30)
        {
            damage = 2* (2*rand() % PM.Agility + PM.Intelligence * PM.Strength);
            Coder.NowHp -= damage;
            recover = (int)(damage * 0.2);
            PM.NowHp += recover;
            swprintf_s(str, L"产品狗释放了【猴子偷桃】……,对程序猿造成了【%d】点伤害,自身恢复【%d】点生命值!", damage, recover);
            Message_Insert(str);
            Die_Check(Coder.NowHp, true);
        }
        break;
    case Action_Type_RECOVER:
        SelectObject(g_bufdc, g_hRecoverSkill);
        TransparentBlt(g_mdc, 150, 150, 150, 150, g_bufdc, 0, 0, 150, 150, RGB(0, 0, 0));
        if (g_iFrameNum == 30)
        {
            recover = 2 * PM.Intelligence * PM.Intelligence;
            PM.NowHp += recover;
            swprintf_s(str, L"产品狗使用了【去找老板谈】……,恢复了【%d】点生命值!", recover);
            Message_Insert(str);            
        }
        break;
    }
}

VOID Snow_Paint()
{
    if (g_SnowNumb < PARTICLE_NUMBER)
    {
        SnowFlowers[g_SnowNumb].x = rand() % g_rect.right;
        SnowFlowers[g_SnowNumb].y = 0;
        SnowFlowers[g_SnowNumb].exist = true;
        g_SnowNumb++;
    }
    for (int i = 0; i < PARTICLE_NUMBER; i++)
    {
        if (SnowFlowers[i].exist)
        {
            SelectObject(g_bufdc, g_hSnow);
            TransparentBlt(g_mdc, SnowFlowers[i].x, SnowFlowers[i].y, 25, 25, g_bufdc, 0, 0, 25, 25, RGB(158, 158, 158));
            if (rand() % 2 == 0)
                SnowFlowers[i].x += rand() % 6;
            else
                SnowFlowers[i].x -= rand() % 6;

            SnowFlowers[i].y += 10;
            if (SnowFlowers[i].y > g_rect.bottom)
            {
                SnowFlowers[i].x = rand() % g_rect.right;
                SnowFlowers[i].y = 0;
            }
        }
    }
}

 

posted @ 2022-02-10 14:49  baby_cz  阅读(101)  评论(0编辑  收藏  举报