// ■手持ち花火のシミュレーション // 右ボタンをクリックすると停止。左ボタンで開始。 // 右ボタンをクリックしながら画面キャプチャすることができる。 #include "myWin.h" #include "stdio.h" #include "stdlib.h" #include "time.h" #include "math.h" #define frand()((double)rand()/(RAND_MAX+1)) #define NUMS 1000 #define HMAX 50 #define NSTEP 5 #define RED(X) ( X & 0xFF) #define GREEN(X) ((X>>8) & 0xFF) #define BLUE(X) ((X>>16) & 0xFF) #define PI 3.14159265358979 static HDC hBuff; static HBITMAP hBM; //ビットマップ表示用 typedef struct{ int R, G, B; double X, Y, VX, VY, m; } spark_data; spark_data sparks[NUMS][HMAX]; int step; double myu,G; double T, DT; int counter, tFact, fFact,KK; POINT rect[4],star[5]; void drawLine(int X1, int Y1, int X2, int Y2, int W, int Color){//■線分 HPEN pen=CreatePen(PS_SOLID,W, Color) ; SelectObject(hBuff, pen) ; MoveToEx(hBuff,X1,Y1,NULL);LineTo(hBuff, X2, Y2); DeleteObject(pen); } void drawEllipse(int X1, int Y1, int X2, int Y2, int lColor, int Color){//■線分 HBRUSH brush=CreateSolidBrush(Color) ; SelectObject(hBuff, brush) ; HPEN pen=CreatePen(PS_SOLID,1, lColor) ; SelectObject(hBuff, pen) ; Ellipse(hBuff,X1,Y1,X2,Y2);DeleteObject(pen);DeleteObject(brush); } void drawRectangle(int X1, int Y1, int X2, int Y2, int lColor, int bColor){//■矩形 HBRUSH brush=CreateSolidBrush(bColor) ; SelectObject(hBuff, brush) ; HPEN pen=CreatePen(PS_SOLID,1, lColor) ; SelectObject(hBuff, pen) ; Rectangle(hBuff,X1,Y1,X2,Y2);DeleteObject(pen);DeleteObject(brush); } void drawPolygon(POINT poly[],int N, int lineW, int lColor, int bColor){//■多角形 HPEN pen=CreatePen(PS_SOLID, lineW, lColor) ; SelectObject(hBuff, pen) ; HBRUSH brush=CreateSolidBrush(bColor) ; SelectObject(hBuff, brush); Polygon(hBuff,poly,N); DeleteObject(brush) ; DeleteObject(pen); } void drawStar(int X0, int Y0, int W, int Color){//■線分 HPEN pen=CreatePen(PS_SOLID,W, Color) ; SelectObject(hBuff, pen) ; MoveToEx(hBuff,X0,Y0,NULL);LineTo(hBuff, X0 , Y0-4); MoveToEx(hBuff,X0,Y0,NULL);LineTo(hBuff, X0-4, Y0-2); MoveToEx(hBuff,X0,Y0,NULL);LineTo(hBuff, X0+4, Y0-2); MoveToEx(hBuff,X0,Y0,NULL);LineTo(hBuff, X0-2, Y0+4); MoveToEx(hBuff,X0,Y0,NULL);LineTo(hBuff, X0+2, Y0+4); DeleteObject(pen); } void genSparks(){ if(step>NUMS-1)return; int i=step; int ct[][3]={{0xFF, 0,0},{0xFF, 0xCC, 0}, {0xFF, 0x77,0}, {0xFF,0, 0xCC}, {0xCC,0, 0xFF}}; int MD = i % 5; for(int j=0; j(3*NUMS/4)) V0=-20.0*(double)step/(double)NUMS+20; sparks[i][0].R=ct[MD][0]; sparks[i][0].G=ct[MD][1]; sparks[i][0].B=ct[MD][2]; double angle = (45+(frand()-0.5)*20)*PI/180, VV=V0*(1+frand()), XY=(frand()-0.5)*0.5; sparks[i][0].VX=VV*cos(angle); sparks[i][0].VY=-VV*sin(angle); sparks[i][0].X=-XY-10; sparks[i][0].Y=-XY+10; if(step<=NUMS-1) step++; } void initialize(){ step=0;counter=0;KK=10; G=0.98; myu=0.4;T=0; DT=0.01; tFact=(int)(DT*300);fFact=(int)(DT*100); int X=117, Y=285; rect[0].x=X ; rect[0].y=Y ; rect[1].x=X+ 15; rect[1].y=Y+ 15; rect[2].x=X- 75; rect[2].y=Y+105; rect[3].x=X-90; rect[3].y=Y+90; star[0].x=0;star[0].y=-2; star[1].x=-1;star[1].y=+2; star[2].x=2;star[2].y=0; star[3].x=-2;star[3].y=0; star[4].x=1;star[1].y=+2; genSparks(); } void comEq(){ double ACX,ACY; for(int l=0;l0;j--){ sparks[i][j].X=sparks[i][j-1].X; sparks[i][j].Y=sparks[i][j-1].Y; sparks[i][j].R =sparks[i][j-1].R-tFact;if(sparks[i][j].R<0)sparks[i][j].R=0; sparks[i][j].G =sparks[i][j-1].G-tFact;if(sparks[i][j].G<0)sparks[i][j].G=0; sparks[i][j].B =sparks[i][j-1].B-tFact;if(sparks[i][j].B<0)sparks[i][j].B=0; } ACY=G-sparks[i][0].VY*myu; ACX=-sparks[i][0].VX*myu; sparks[i][0].R-=fFact;if(sparks[i][0].R<0)sparks[i][0].R=0; sparks[i][0].G-=fFact;if(sparks[i][0].G<0)sparks[i][0].G=0; sparks[i][0].B-=fFact;if(sparks[i][0].B<0)sparks[i][0].B=0; sparks[i][0].VX += ACX*DT; sparks[i][0].VY += ACY*DT; sparks[i][0].X += sparks[i][0].VX*DT; sparks[i][0].Y += sparks[i][0].VY*DT; if(sparks[i][0].R==0 && sparks[i][0].G==0 && sparks[i][0].B==0) for(int j=0;j=0; j--){ if(sparks[i][j].R!=0 || sparks[i][j].G!=0 ||sparks[i][j].B!=0){ iflag=true; int X0=setX(sparks[i][j].X), Y0=setY(sparks[i][j].Y); int cl=RGB(sparks[i][j].R,sparks[i][j].G,sparks[i][j].B); //if(j==0) drawEllipse(X0-2, Y0-2, X0+2, Y0+2,cl,cl); if(j==0) drawStar(X0, Y0, 2, cl); else drawEllipse(X0-1, Y0-1, X0+1, Y0+1,cl,cl); } } } drawPolygon(rect,4, 1, 0xFFFF, 0x770077); return iflag; } void procTimer(HWND hw, WPARAM wp,LPARAM lp){ //■タイマー処理 comEq();int iflag=drawFig(); if(!iflag){ initialize(); drawFig(); KillTimer(hw,1);} InvalidateRect(hw,NULL,TRUE); } void procLButtonDown(HWND hw, WPARAM wp,LPARAM lp){ //■左ボタン処理 initialize(); SetTimer(hw,1,50,NULL); //画面キャプチャするときはここをコメント*/ } void procRButtonDown(HWND hw, WPARAM wp,LPARAM lp){ //■左ボタン処理 KillTimer(hw,1); comEq();int iflag=drawFig(); if(!iflag){ initialize(); drawFig();} InvalidateRect(hw,NULL,TRUE); } void initBitmap(HWND hw){ //■ビットマップ初期設定 HDC hdc=GetDC(hw); hBM=CreateCompatibleBitmap(hdc,1000,400); hBuff=CreateCompatibleDC(hdc); SelectObject(hBuff,hBM); clearBitmap(); ReleaseDC(hw,hdc); } void procCreate(HWND hw, WPARAM wp,LPARAM lp){ //■Create時処理 SetWindowText(hw,TEXT("花火シミュレーション その2")); MoveWindow(hw,0,0,450,450,TRUE); initBitmap(hw); initialize(); drawFig();InvalidateRect(hw,NULL,TRUE); //procLButtonDown(hw,wp,lp); } void procPaint(HWND hw, WPARAM wp,LPARAM lp){ //■Paint時処理 PAINTSTRUCT ps; HDC hdc=BeginPaint(hw, &ps); BitBlt(hdc, 0,0,1000,400,hBuff,0,0,SRCCOPY); EndPaint(hw,&ps); } LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp,LPARAM lp){//■Window Procedure switch(msg){ case WM_DESTROY : PostQuitMessage(0) ; return 0; case WM_CREATE : procCreate(hw,wp,lp) ; return 0; case WM_PAINT : procPaint(hw,wp,lp) ; return 0; case WM_TIMER : procTimer(hw,wp,lp) ; return 0; case WM_LBUTTONDOWN : procLButtonDown(hw,wp,lp) ; break; case WM_RBUTTONDOWN : procRButtonDown(hw,wp,lp) ; break; } return DefWindowProc(hw,msg,wp,lp); }