• Windows粒子系统


      1 #include <windows.h>
      2 #include <tchar.h>    //swprintf_s函数所需的头文件
      3 #include  <time.h>
      4 
      5 #pragma comment(lib, "winmm.lib")    //playSound
      6 #pragma comment(lib, "Msimg32.lib")    //TransparentBlt
      7 
      8 #define WINDOW_WIDTH    950
      9 #define WINDOW_HEIGHT    710
     10 #define WINDOW_TITLE    L"Windows粒子系统"
     11 // 表示粒子数量
     12 #define FLYSTAR_NUMBER    100    
     13 // 表示粒子持续帧数,修改每次星光绽放持续的时间   
     14 #define FLYSTAR_LASTED_FRAME 60                    
     15 
     16 
     17 struct FLYSTAR
     18 {
     19     int x;       //星光所在的x坐标
     20     int y;       //星光所在的y坐标
     21     int vx;      //星光x方向的速度
     22     int vy;      //星光y方向的速度
     23     int lasted;  //星光存在的时间
     24     BOOL exist;  //星光是否存在
     25 };
     26 // 环境,内存句柄
     27 HDC    g_hdc = NULL, g_mdc = NULL, g_bufdc = NULL;
     28 HBITMAP g_hStar = NULL, g_hBackGround = NULL;
     29 DWORD g_tPre = 0, g_tNow = 0;
     30 // 储存内部窗口区域的坐标
     31 RECT g_rect;
     32 FLYSTAR FlyStars[FLYSTAR_NUMBER]; 
     33 int g_StarNum = 0; 
     34 
     35 // 回调函数,窗口过程函数
     36 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
     37 BOOL Game_Init(HWND hwnd);
     38 VOID Game_Paint(HWND hwnd);
     39 BOOL Game_CleanUp(HWND hwnd);
     40 
     41 
     42 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
     43 {
     44     WNDCLASSEX wndClass = { 0 };
     45     wndClass.cbSize = sizeof(WNDCLASSEX);
     46     wndClass.style = CS_HREDRAW | CS_VREDRAW;
     47     wndClass.lpfnWndProc = WndProc;
     48     wndClass.cbClsExtra = 0;
     49     wndClass.cbWndExtra = 0;
     50     wndClass.hInstance = hInstance;
     51     wndClass.hIcon = 0;
     52     wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
     53     // 白色画刷句柄
     54     wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
     55     // 用一个以空终止的字符串,指定菜单资源的名字
     56     wndClass.lpszMenuName = NULL;
     57     //窗口类的名字
     58     wndClass.lpszClassName = L"Game Develop";
     59 
     60     if (!RegisterClassEx(&wndClass))
     61         return -1;
     62 
     63     // 正式创建窗口
     64     HWND hwnd = CreateWindow(L"Game Develop", WINDOW_TITLE,
     65         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
     66         WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
     67 
     68     MoveWindow(hwnd, 150, 50, WINDOW_WIDTH, WINDOW_HEIGHT, true);
     69     ShowWindow(hwnd, nShowCmd);
     70     UpdateWindow(hwnd);
     71 
     72     if (!Game_Init(hwnd))
     73     {
     74         MessageBox(hwnd, L"资源初始化失败", L"消息窗口", 0);
     75         return FALSE;
     76     }
     77 
     78     PlaySound(L"music.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
     79 
     80     MSG msg = { 0 };
     81     while (msg.message != WM_QUIT)
     82     {
     83         // 查看应用程序消息队列,有消息时将队列中的消息派发出去
     84         if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
     85         {
     86             TranslateMessage(&msg);
     87             DispatchMessage(&msg);
     88         }
     89         else
     90         {
     91             g_tNow = GetTickCount();
     92             // 重绘
     93             if (g_tNow - g_tPre >= 40)
     94                 Game_Paint(hwnd);
     95         }
     96     }
     97 
     98     // 程序准备结束,注销窗口类
     99     UnregisterClass(L"Game Develop", wndClass.hInstance);
    100     return 0;
    101 }
    102 
    103 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    104 {
    105     switch (message)
    106     {
    107     case WM_KEYDOWN:
    108         if (wParam == VK_ESCAPE)
    109             PostQuitMessage(0);
    110         break;
    111         
    112     case WM_DESTROY:
    113         Game_CleanUp(hwnd);
    114         PostQuitMessage(0);
    115         break;
    116 
    117         //调用缺省的窗口过程
    118     default:
    119         return DefWindowProc(hwnd, message, wParam, lParam);
    120     }
    121     return 0;
    122 }
    123 
    124 BOOL Game_Init(HWND hwnd)
    125 {
    126     // 用系统时间初始化 
    127     // 随机数发生器的初始化函数
    128     srand((unsigned)time(NULL));
    129 
    130     HBITMAP bmp;
    131     g_hdc = GetDC(hwnd);
    132     g_mdc = CreateCompatibleDC(g_hdc);
    133     g_bufdc = CreateCompatibleDC(g_hdc);
    134     bmp = CreateCompatibleBitmap(g_hdc, WINDOW_WIDTH, WINDOW_HEIGHT);
    135     
    136     SelectObject(g_mdc, bmp);
    137     g_hBackGround = (HBITMAP)LoadImage(NULL, L"bg.bmp", IMAGE_BITMAP, WINDOW_WIDTH, WINDOW_HEIGHT, LR_LOADFROMFILE);
    138     g_hStar = (HBITMAP)LoadImage(NULL, L"star.bmp", IMAGE_BITMAP, 30, 30, LR_LOADFROMFILE);
    139 
    140     // 取得内部窗口大小
    141     GetClientRect(hwnd, &g_rect);
    142 
    143     Game_Paint(hwnd);
    144     return TRUE;
    145 }
    146 
    147 VOID Game_Paint(HWND hwnd)
    148 {
    149     // 先在mdc中贴上背景图
    150     SelectObject(g_bufdc, g_hBackGround);
    151     // 将源矩形区域直接拷贝到目标矩形区域
    152     BitBlt(g_mdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_bufdc, 0, 0, SRCCOPY);
    153 
    154     // 创建粒子
    155     if (g_StarNum == 0)
    156     {
    157         // 随机设置爆炸点
    158         int x = rand() % g_rect.right;
    159         int y = rand() % g_rect.bottom;
    160 
    161         for (int i = 0; i < FLYSTAR_NUMBER; i++)
    162         {
    163             FlyStars[i].x = x;
    164             FlyStars[i].y = y;
    165             FlyStars[i].lasted = 0;
    166             // x,y方向的移动速度随机为1—15之间的一个值
    167             if (i % 4 == 0)
    168             {
    169                 FlyStars[i].vx = -(1 + rand() % 15);
    170                 FlyStars[i].vy = -(1 + rand() % 15);
    171             }
    172             if (i % 4 == 1)
    173             {
    174                 FlyStars[i].vx = (1 + rand() % 15);
    175                 FlyStars[i].vy = (1 + rand() % 15);
    176             }
    177             if (i % 4 == 2)
    178             {
    179                 FlyStars[i].vx = -(1 + rand() % 15);
    180                 FlyStars[i].vy = (1 + rand() % 15);
    181             }
    182             if (i % 4 == 3)
    183             {
    184                 FlyStars[i].vx = (1 + rand() % 15);
    185                 FlyStars[i].vy = -(1 + rand() % 15);
    186             }
    187             FlyStars[i].exist = true;
    188         }
    189         g_StarNum = FLYSTAR_NUMBER;
    190     }
    191 
    192     // 显示粒子
    193     for (int i = 0; i < FLYSTAR_NUMBER; i++)
    194     {
    195         if (FlyStars[i].exist)
    196         {
    197             SelectObject(g_bufdc, g_hStar);
    198             TransparentBlt(g_mdc, FlyStars[i].x, FlyStars[i].y, 30, 30, g_bufdc, 0, 0, 30, 30, RGB(0, 0, 0));
    199 
    200             // 下一次坐标
    201             FlyStars[i].x += FlyStars[i].vx;
    202             FlyStars[i].y += FlyStars[i].vy;
    203             // 在每进行一次贴图后,将粒子的存在时间累加1.
    204             FlyStars[i].lasted++;
    205             // 进行条件判断,若某粒子跑出窗口区域一定的范围,则将该粒子设为不存在,且粒子数随之递减
    206             if (FlyStars[i].x <= -10 || FlyStars[i].x>g_rect.right || FlyStars[i].y <= -10 || FlyStars[i].y>g_rect.bottom || FlyStars[i].lasted>FLYSTAR_LASTED_FRAME)
    207             {
    208                 FlyStars[i].exist = false;  //删除星光粒子 
    209                 g_StarNum--;                    //递减星光总数
    210             }
    211         }
    212     }
    213     BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);
    214     g_tPre = GetTickCount();
    215 }
    216 
    217 BOOL Game_CleanUp(HWND hwnd)
    218 {
    219     // 释放资源对象
    220     DeleteObject(g_hBackGround);
    221     DeleteObject(g_hStar);
    222     DeleteDC(g_bufdc);
    223     DeleteDC(g_mdc);
    224     ReleaseDC(hwnd, g_hdc);
    225     return TRUE;
    226 }
  • 相关阅读:
    创建Graphics对象与Pen对象
    GDI+图形图像处理技术——GDIPlus绘图基础
    WPF的组成架构
    文件监控只FileSystemWatcher控件
    文件夹选择之FolderBrowserDialog控件
    SaveFileDialog控件
    文件选择之OpenFileDialog控件
    编码与解码
    写一个翻译小工具
    【转】字符集与字符编码简介
  • 原文地址:https://www.cnblogs.com/ht-beyond/p/4445592.html
Copyright © 2020-2023  润新知