TOP >> マニアックなプログラミング
トリッキーコードネット トリッキーなコード

【7行プログラミング/ショートコーディング】グルグル回転する球を描画 (Win32API)

#include<windows.h> #include<math.h> int*P,y[1<<18],a=256,c,r,m[8],n,S=a/2,u,v;BITMAPINFO T={40,a,a,1,32};HWND g; float s,X,Y=-.57,Z,t,l,d;int WINAPI WinMain(HINSTANCE I,HINSTANCE,LPSTR,int) {WNDCLASS w={67,DefWindowProc,0,0,I,0,0,0,0,"0"};RegisterClass(&w);HDC h=GetDC( g=CreateWindow("0","○",513<<19,0,0,a,a,0,0,I,0));while(GetMessage((MSG*)m,g,0,0)!=-1) {if(m[1]==15){s+=.1;Z=Y*cos(s);X=Y*sin(s);P=y;for(v=S;v>-S;v--){for(u=-S;u0?t=sqrt(d),l=sqrt(u*u+v*v+t*t),n=(X*u/l+Y*v/l+Z*t/l)*255,n=n<0?0:n: n=64;*P++=n;}}SetDIBitsToDevice(h,0,0,a,a,0,0,0,a,y,&T,0);}else DispatchMessage((MSG*)m); InvalidateRect(g,0,0);}return 0;}
↑のコードをコンパイルして実行すると、以下の様な「グルグル回転する球」が表示されます。 キタ Y⌒Y⌒Y⌒Y⌒(。A。)!!! 回転する球:7行プログラミング (※ 実際にプログラムを実行すると、高速で球が回転している様子が表示されます。) Win32APIのコードの為、GUIがステキでいい感じ^^;) それでは、プログラムの解説に移ります。 冒頭のコードに、適当なインデント・スペースを入れて読みやすくした物が以下のコードです。↓↓
#include<windows.h> #include<math.h> int *P, y[1<<18], a=256, c, r, m[8], n, S = a/2, u, v; BITMAPINFO T = {40,a,a,1,32}; HWND g; float s, X, Y =- .57, Z, t, l, d; int WINAPI WinMain(HINSTANCE I, HINSTANCE, LPSTR, int) { WNDCLASS w = {67, DefWindowProc, 0,0,I,0,0,0,0,"0"}; RegisterClass(&w); HDC h = GetDC( g = CreateWindow("0", "○", 513<<19, 0, 0, a, a, 0, 0, I, 0) ); while(GetMessage((MSG*)m,g,0,0) != -1) { if (m[1] == 15) { s += .1; Z = Y * cos(s); X = Y * sin(s); P = y; for (v = S; v>-S; v--) { for (u =- S; u 0 ? t = sqrt(d), l = sqrt(u*u+v*v+t*t), n = (X*u/l+Y*v/l+Z*t/l)*255, n = n < 0 ? 0 : n : n = 64; *P++ = n; } } SetDIBitsToDevice(h,0,0,a,a,0,0,0,a,y,&T,0); } else DispatchMessage((MSG*)m); InvalidateRect(g,0,0); } return 0; }
まだまだ読みにくい部分がある為、変数名を変更し、一部のコードを修正します。 そして、定義済の名称(#defineされているもの)がある値は、定義済の名称に変更します。 また、VC++2005のデフォルトのコンパイルオプションで表示される、C4305, C4244の警告(double型からfloat型, int型からfloat型への変換警告)も、あわせて対処します。 それが以下のコードです。↓↓
1 : #include<windows.h> 2 : #include<math.h> 3 : 4 : int c, r, n, u, v; 5 : float s, X, Z, t, l, d; 6 : int *lpnBits, nBits[1<<18]; 7 : 8 : const float Y = -0.57f; 9 : int nWndSize = 256; 10 : int nHalfSize = nWndSize/2; 11 : 12 : BITMAPINFO bitmapInfo = {sizeof(BITMAPINFOHEADER), nWndSize, nWndSize, 1, 32}; 13 : HWND hWnd; 14 : MSG msg; 15 : 16 : int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int) 17 : { 18 : WNDCLASS wndclass = { 19 : CS_CLASSDC | CS_VREDRAW | CS_HREDRAW, 20 : DefWindowProc, 21 : 0, 0, hInst, NULL, NULL, NULL, NULL, 22 : "MyClass" 23 : }; 24 : RegisterClass(&wndclass); 25 : 26 : hWnd = CreateWindow( 27 : "MyClass", "○", 28 : WS_VISIBLE | WS_SYSMENU, 29 : 0, 0, nWndSize, nWndSize, 30 : NULL, NULL, hInst, NULL 31 : ); 32 : HDC hdc = GetDC(hWnd); 33 : 34 : while (GetMessage(&msg, hWnd, 0, 0) != -1) { 35 : if (msg.message == WM_PAINT) { 36 : s += .1f; 37 : Z = Y * cos(s); 38 : X = Y * sin(s); 39 : lpnBits = nBits; 40 : 41 : for (v = nHalfSize; v > -nHalfSize; v--) { 42 : for (u =- nHalfSize; u < nHalfSize; u++) { 43 : d = float(9999 - u*u - v*v); 44 : d > 0 ? 45 : t = sqrt(d), 46 : l = sqrt(u*u+v*v+t*t), 47 : n = int( (X*u/l+Y*v/l+Z*t/l) * 255), 48 : n = n < 0 ? 0 : n 49 : : 50 : n = 64; 51 : 52 : *lpnBits++ = n; 53 : } 54 : } 55 : 56 : SetDIBitsToDevice(hdc, 0, 0, nWndSize, nWndSize, 0, 0, 57 : 0, nWndSize, nBits, &bitmapInfo, 0); 58 : } 59 : else 60 : DispatchMessage(&msg); 61 : 62 : InvalidateRect(hWnd, NULL, FALSE); 63 : Sleep(10); 64 : } 65 : 66 : return 0; 67 : }
【変数名の変更点】
y</td>nBits
PlpnBits
anWndSize
SnHalfSize
ghWnd
TbitmapInfo
IhInst
wwndclass
hhdc
"0""MyClass"
【変数の型変更点】
int m[8]MSG msg
【定義済み名称への変更点】
12行目 40sizeof(BITMAPINFOHEADER)
19行目 67CS_CLASSDC | CS_VREDRAW | CS_HREDRAW
28行目 513<<19WS_VISIBLE | WS_SYSMENU
35行目 15WM_PAIN
随所FALSE または NULL
砂嵐プログラミング その4 のコードを理解していれば、わりと難なく読めるコードだと思います^^;) ちょっとだけ補足しておくと、 WM_PAINTメッセージの処理部分では、 nBitsにビットマップデータを保持するものとし、 lpnBitsにnBitsのアドレスを割り当て(←39行目)、 ループ内で 「 *lpnBits++ = n 」 (←52行目。ちなみに、nには計算結果が入る)をすることにより、 nBitsのビットマップデータが1つ1つ計算して埋められていきます。 そして最後に、SetDIBitsToDevice()でビットマップデータをウィンドウに描画(←56,57行目)して、球の表示処理終了!! というわけです^^;) さらに、WM_PAINTメッセージ処理で、球の描画を行う度に、変数sが「s += .1f」 (←36行目) されており、 その変数sをsin(), cos()に入れて変数Z, 変数Xの値を取得している(←37,38行目)事から、 変数Z, 変数Xへ周期的に同じ値が代入される事になり、 結果として、グルグル回転している球が表示されるというワケです^^;) いやぁ~、なかなかイキなコードだw
トリッキーコードネット の TOPへ HOTNEWS の 総合TOPへ