#include <windows.h>
#include <vector>
#include <direct.h>
#include <math.h>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <tchar.h>
#include <time.h>
#include <d3d9.h>
#define _Time long long
#pragma comment(lib,"d3d9.lib")
#include <d3dx9.h>
#pragma comment(lib,"d3dx9.lib")
using namespace std;
const int WINDOWS_WIDTH = 1920;
const int WINDOWS_HEIGHT = 1080;
const double DENSITY = 0.00001;
const double PI = 3.1415926535897932384626433832795;
const int DMARGIN = 6;
const int RedrawTimeDifference = 1000;
double KineticEnergyPre = 0;
RECT rect;
double clientx;
double clienty;
_Time tPrevious = 0, tPresent = 0;
HWND sShWnd = NULL, ShWnd = NULL;
HINSTANCE ShInstance = NULL;
LPDIRECT3D9 SD3D = nullptr;
LPDIRECT3DDEVICE9 SDevice = NULL;
LPD3DXSPRITE SSprite = nullptr;
typedef struct Round
{
double v, angle, m, r;
D3DXVECTOR2 Position;
LPDIRECT3DTEXTURE9 RoundTextture;
D3DXIMAGE_INFO ImageInformation;
}*sRound;
vector<sRound> SRound;
double GetModDecimals(double d, double mod)
{
return ((long long)(d * 10000000000) % (long long)(mod * 10000000000)) / 10000000000.0;
}
double GetKineticEnergy()
{
double kineticenergy = 0;
for (int i = 0; i < SRound.size(); i++)
{
kineticenergy += SRound.at(i)->m * pow(SRound.at(i)->v, 2.0) / 2.0;
}
return kineticenergy;
}
bool OnInit()
{
SD3D = Direct3DCreate9(D3D_SDK_VERSION);
D3DDISPLAYMODE D3DDisplayMode;
ZeroMemory(&D3DDisplayMode, sizeof(D3DDISPLAYMODE));
if (FAILED(SD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &D3DDisplayMode)))
{
return false;
}
D3DPRESENT_PARAMETERS D3DPresent_Parameters;
ZeroMemory(&D3DPresent_Parameters, sizeof(D3DPRESENT_PARAMETERS));
D3DPresent_Parameters.BackBufferCount = 1;
D3DPresent_Parameters.Windowed = TRUE;
D3DPresent_Parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
if (FAILED(SD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, ShWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &D3DPresent_Parameters, &SDevice)))
{
return false;
}
if (FAILED(D3DXCreateSprite(SDevice, &SSprite)))
{
return false;
}
string CurrentPath = _getcwd(NULL, 0);
CurrentPath += "\\image\\";
string FileName[] = { "bubble0.png", "bubble1.png", "bubble2.png", "bubble3.png", "bubble4.png", "bubble5.png", "bubble6.png" };
for (int i = 0; i < _countof(FileName); i++)
{
Round* round = new Round();
ZeroMemory(round, sizeof(round));
if (FAILED(D3DXCreateTextureFromFileEx(SDevice, (CurrentPath + FileName[i]).c_str(), D3DX_FROM_FILE, D3DX_FROM_FILE,
0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR, D3DCOLOR_XRGB(255, 255, 255),
&(round->ImageInformation), nullptr, &(round->RoundTextture))))
{
MessageBox(NULL, "资源加载失败:image/下找不到image资源!", "错误", MB_ICONINFORMATION | MB_OK);
return false;
}
round->v = rand() % 8;
round->angle = rand() % 360 / 360.0 * PI * 2;
round->r = (round->ImageInformation.Width - DMARGIN) / 2.0;
round->m = PI * round->r * round->r * DENSITY;
SRound.push_back(round);
}
GetClientRect(ShWnd, &rect);
clientx = rect.right - rect.left;
clienty = rect.bottom - rect.top;
for (int i = 0; i < SRound.size(); i++)
{
LOOP:
SRound.at(i)->Position.x = rand() % WINDOWS_WIDTH;
SRound.at(i)->Position.y = rand() % WINDOWS_HEIGHT;
if (SRound.at(i)->Position.x < SRound.at(i)->r || SRound.at(i)->Position.x > clientx - SRound.at(i)->r
|| SRound.at(i)->Position.y < SRound.at(i)->r || SRound.at(i)->Position.y > clienty - SRound.at(i)->r)
{
goto LOOP;
}
for (int j = 0; j < i; j++)
{
int distance = sqrt(pow(SRound.at(i)->Position.x - SRound.at(j)->Position.x, 2)
+ pow(SRound.at(i)->Position.y - SRound.at(j)->Position.y, 2));
int limitdistance = SRound.at(i)->r + SRound.at(j)->r;
if (distance < limitdistance)
{
goto LOOP;
}
}
}
KineticEnergyPre = GetKineticEnergy();
return true;
}
void OnRender()
{
SDevice->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_XRGB(100, 100, 100), 1.0, 0);
SDevice->BeginScene();
SSprite->Begin(D3DXSPRITE_ALPHABLEND);
for (int i = 0; i < SRound.size(); i++)
{
for (int j = i + 1; j < SRound.size(); j++)
{
double distance = sqrt(pow(SRound.at(i)->Position.x - SRound.at(j)->Position.x, 2)
+ pow(SRound.at(i)->Position.y - SRound.at(j)->Position.y, 2));
double limitdistance = SRound.at(i)->r + SRound.at(j)->r;
if (distance < limitdistance)
{
double forecastix = SRound.at(i)->Position.x + SRound.at(i)->v * cos(SRound.at(i)->angle);
double forecastiy = SRound.at(i)->Position.y + SRound.at(i)->v * sin(SRound.at(i)->angle);
double forecastjx = SRound.at(j)->Position.x + SRound.at(j)->v * cos(SRound.at(j)->angle);
double forecastjy = SRound.at(j)->Position.y + SRound.at(j)->v * sin(SRound.at(j)->angle);
double forecastdistance = sqrt(pow(forecastix - forecastjx, 2) + pow(forecastiy - forecastjy, 2));
if (forecastdistance < distance)
{
double rotation = atan((SRound.at(i)->Position.y - SRound.at(j)->Position.y) / (SRound.at(i)->Position.x - SRound.at(j)->Position.x));
double anglei = SRound.at(i)->angle - rotation, anglej = SRound.at(j)->angle - rotation;
double algebraicexpression1 = SRound.at(j)->m / SRound.at(i)->m;
double algebraicexpression2 = SRound.at(i)->v * cos(anglei)
+ algebraicexpression1 * SRound.at(j)->v * cos(anglej);
double algebraicexpression3 = pow(SRound.at(i)->v * cos(anglei), 2)
+ algebraicexpression1 * pow(SRound.at(j)->v * cos(anglej), 2);
double v1 = (algebraicexpression2 - sqrt((algebraicexpression3 + algebraicexpression3 * algebraicexpression1
- pow(algebraicexpression2, 2)) / algebraicexpression1)) / (algebraicexpression1 + 1);
double v2 = (algebraicexpression2 + sqrt((algebraicexpression3 + algebraicexpression3
* algebraicexpression1 - pow(algebraicexpression2, 2)) / algebraicexpression1)) / (algebraicexpression1 + 1);
double vxi = 0, vxj = 0;
if (SRound.at(i)->Position.x < SRound.at(j)->Position.x)
{
vxi = v1;
vxj = v2;
}
else if (SRound.at(i)->Position.x > SRound.at(j)->Position.x)
{
vxi = v2;
vxj = v1;
}
else
{
if (SRound.at(i)->Position.y < SRound.at(j)->Position.y)
{
vxi = v2;
vxj = v1;
}
else if (SRound.at(i)->Position.y > SRound.at(j)->Position.y)
{
vxi = v1;
vxj = v2;
}
}
if (vxi == 0 && SRound.at(i)->v * sin(SRound.at(i)->angle) != 0)
{
if (SRound.at(i)->v * sin(SRound.at(i)->angle) > 0)
anglei = PI / 2.0;
else
anglei = 3 * PI / 2.0;
}
else if (vxi != 0 && SRound.at(i)->v * sin(SRound.at(i)->angle) == 0)
{
if (vxi > 0)
anglei = 0.0;
else
anglei = PI;
}
else if (vxi != 0 && SRound.at(i)->v * sin(SRound.at(i)->angle) != 0)
{
if (vxi > 0)
anglei = GetModDecimals(2 * PI + atan(SRound.at(i)->v * sin(SRound.at(i)->angle) / vxi), 2 * PI);
else
anglei = PI + atan(SRound.at(i)->v * sin(SRound.at(i)->angle) / vxi);
}
if (vxj == 0 && SRound.at(j)->v * sin(SRound.at(j)->angle) != 0)
{
if (SRound.at(j)->v * sin(SRound.at(j)->angle) > 0)
anglej = PI / 2.0;
else
anglej = 3 * PI / 2.0;
}
else if (vxj != 0 && SRound.at(j)->v * sin(SRound.at(j)->angle) == 0)
{
if (vxj > 0)
anglej = 0.0;
else
anglej = PI;
}
else if (vxj != 0 && SRound.at(j)->v * sin(SRound.at(j)->angle) != 0)
{
if (vxj > 0)
anglej = GetModDecimals(2 * PI + atan(SRound.at(j)->v * sin(SRound.at(j)->angle) / vxj), 2 * PI);
else
anglej = PI + atan(SRound.at(j)->v * sin(SRound.at(j)->angle) / vxj);
}
SRound.at(i)->v = sqrt(pow(vxi, 2) + pow(SRound.at(i)->v * sin(SRound.at(i)->angle), 2));
SRound.at(j)->v = sqrt(pow(vxj, 2) + pow(SRound.at(j)->v * sin(SRound.at(j)->angle), 2));
SRound.at(i)->angle = GetModDecimals(anglei + rotation, 2 * PI);
SRound.at(j)->angle = GetModDecimals(anglej + rotation, 2 * PI);
}
}
}
if (SRound.at(i)->Position.x < SRound.at(i)->r || SRound.at(i)->Position.x > clientx - SRound.at(i)->r)
{
SRound.at(i)->angle = GetModDecimals(3 * PI - SRound.at(i)->angle, 2 * PI);
}
if (SRound.at(i)->Position.y < SRound.at(i)->r || SRound.at(i)->Position.y > clienty - SRound.at(i)->r)
{
SRound.at(i)->angle = 2 * PI - SRound.at(i)->angle;
}
SRound.at(i)->Position.x += SRound.at(i)->v * cos(SRound.at(i)->angle);
SRound.at(i)->Position.y += SRound.at(i)->v * sin(SRound.at(i)->angle);
SSprite->Draw(SRound.at(i)->RoundTextture, nullptr, &D3DXVECTOR3(SRound.at(i)->ImageInformation.Width / 2.0f,
SRound.at(i)->ImageInformation.Height / 2.0f, 0.0f), &D3DXVECTOR3(SRound.at(i)->Position.x,
SRound.at(i)->Position.y, 0.0), 0xffffffff);//D3DCOLOR_XRGB(0, 0, 0)
}
SSprite->End();
SDevice->EndScene();
SDevice->Present(nullptr, nullptr, 0, nullptr);
}
void OnDestroy()
{
SRound.clear();
SSprite->Release();
SDevice->Release();
SD3D->Release();
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SIZE:
{
LONG_PTR Style = GetWindowLongPtr(ShWnd, GWL_STYLE);
Style &= ~WS_CAPTION & ~WS_SYSMENU & ~WS_SIZEBOX | WS_EX_TOOLWINDOW;
SetWindowLongPtr(ShWnd, GWL_STYLE, Style);
DWORD exStyle = GetWindowLong(ShWnd, GWL_EXSTYLE);
exStyle |= WS_EX_LAYERED;
SetWindowLong(ShWnd, GWL_EXSTYLE, exStyle);
SetLayeredWindowAttributes(ShWnd, RGB(100, 100, 100), 99, LWA_ALPHA | LWA_COLORKEY);
break;
}
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd)
{
WNDCLASS wc;
ZeroMemory(&wc, sizeof(WNDCLASS));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("ii");
RegisterClass(&wc);
sShWnd = CreateWindow(wc.lpszClassName, TEXT("iii"), WS_EX_TOOLWINDOW, 0, 0, WINDOWS_WIDTH, WINDOWS_HEIGHT, NULL, NULL, hInstance, NULL);
if (!sShWnd)
return 0;
ShWnd = CreateWindow(wc.lpszClassName, TEXT("iiii"), WS_OVERLAPPEDWINDOW, 0, 0, WINDOWS_WIDTH, WINDOWS_HEIGHT, sShWnd, NULL, hInstance, NULL);
SetWindowPos(ShWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE); //设置窗口最顶层
srand(timeGetTime());
if (ShWnd)
{
if (OnInit())
{
ShowWindow(ShWnd, SW_NORMAL);
UpdateWindow(ShWnd);
}
else
{
MessageBox(NULL, "错误", "初始化失败!", MB_ICONINFORMATION | MB_OK);
return 0;
}
}
MSG msg;
GetMessage(&msg, NULL, NULL, NULL);
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
tPresent = timeGetTime();
if (tPresent - tPrevious > 10)
{
OnRender();
tPrevious = tPresent;
}
}
Sleep(0);
}
OnDestroy();
UnregisterClass(wc.lpszClassName, hInstance);
return 0;
}
自己用DirectX做的简单2D桌面动画一睡眠就卡死
最新推荐文章于 2021-10-23 11:20:11 发布