D2.0とSDL/OpenGLでライフゲーム作った。
のっけから余談ですが、先日発売になった"EeePC901"を買ってしまった。
6万であの性能なら、まぁ文句は無いでしょう。
Dの開発環境も乗っけたし、これで何処でもDと一緒(^q^)
前回はD1.0を使っていたが、今回からはD2.0で行きます。
でも何故またD2.0に戻したか、といいますと。
少し前まではOpenGLのportingがデフォのままでは使えなかったのが
今回試してみたらバッチリ修正されていた為です。
(ちなみに問題だった部分は、D2.0から予約語登録された"ref"が
portingの中で仮引数に使われていた所だったはず。)
では今回もビクビクしながら晒します。
前回と比べると、マウスによる生死の操作ができなくなっています。
だって面倒なんだもの。
後は、OpenGLで"頂点配列"というものを使ってみたつもりです。
全然美しくないけど・・・。
/* 頂点配列を使ったバージョン */ import std.stdio; import std.conv; import std.random; import std.date; import std.string; import SDL; import opengl; import openglu; invariant int g_Magnification = 2; class fpsCounter { private: Uint32 m_StartTick; Uint32 m_EndTick; int m_Result; int m_Counter; public: this() { m_StartTick = SDL_GetTicks(); m_EndTick = 0; m_Result = 0; m_Counter = 0; } void calc() { m_EndTick = SDL_GetTicks(); if( m_EndTick - m_StartTick > 1000 ) { m_Result = m_Counter; m_Counter = 0; m_StartTick = m_EndTick; } else { m_Counter++; } } int Result() { return m_Result; } }; class island { private: typedef int[2] vertex; typedef vertex[4] inhabitant; const uint m_Width; const uint m_Height; inhabitant[] m_Inhabits; bool[][] m_Fields; bool m_Freezing = false; uint m_Generation = 1; public: this( int p_Width, int p_Height ) { m_Width = p_Width; m_Height = p_Height; m_Fields.length = m_Height; for( int y=0; y < m_Height; y++ ) { m_Fields[y].length = m_Width; for( int x=0; x < m_Width; x++ ) { m_Fields[y][x] = false; } } } //Setter void Freezing( bool p_Freezing ) { m_Freezing = p_Freezing; } //Getter bool Freezing() { return m_Freezing; } //Setter void Generation( uint p_Generation ) { m_Generation = p_Generation; } //Getter uint Generation() { return m_Generation; } bool opIndex( int p_x, int p_y ) { return m_Fields[p_y][p_x]; } void opIndexAssign( bool p_living, int p_x, int p_y ) { m_Fields[p_y][p_x] = p_living; } void randomize( int p_Probability ) { inhabitant l_Inhabit; bool l_living; for( int y=0; y < m_Height; y++ ) { for( int x=0; x < m_Width; x++ ) { if( rand()%100 <= p_Probability ) { m_Inhabits ~= cast(inhabitant)([ [x,y],[x+1,y],[x+1,y+1],[x,y+1] ]); this[x,y] = true; } } } m_Generation = 1; } void print() { clear(); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2 , GL_INT, 0 , cast(int*)m_Inhabits); glDrawArrays(GL_QUADS , 0 , m_Inhabits.length*4); flip(); } void next() { int l=0,r=0,u=0,d=0,i=0; bool[][] l_NextFields; l_NextFields.length = m_Height; for( i=0; i < m_Height; i++ ) l_NextFields[i].length = m_Width; if( ++m_Generation > 100000000 ) m_Generation = 1; m_Inhabits.length = 0; for( int y=0; y < m_Height; y++ ) { for( int x=0; x < m_Width; x++ ) { i = 0; l = (x + m_Width - 1) % m_Width; r = (x + 1) % m_Width; u = (y + m_Height - 1) % m_Height; d = (y + 1) % m_Height; if(this[l,u]) i++; if(this[x,u]) i++; if(this[r,u]) i++; if(this[l,y]) i++; if(this[r,y]) i++; if(this[l,d]) i++; if(this[x,d]) i++; if(this[r,d]) i++; if( ( (this[x,y]) && (i==2) ) ||(i==3) ) { m_Inhabits ~= cast(inhabitant)([ [x,y], [x+1,y], [x+1,y+1], [x,y+1] ]); l_NextFields[y][x] = true; } } } m_Fields = l_NextFields; } }; void clear() { glClear(GL_COLOR_BUFFER_BIT); return; } void flip() { SDL_GL_SwapBuffers(); return; } bool PropertysCheck( string[] p_args, out int p_Width, out int p_Height, out int p_Probability, out int p_StopCount ) { if( p_args.length <> 5 ) { writefln("Parameters Disposition Failed.\n1:Width, 2:Height, 3:Probability, 4:StopCount."); return false; } p_Width = toInt(p_args[1]); p_Height = toInt(p_args[2]); p_Probability = toInt(p_args[3]); p_StopCount = toInt(p_args[4]); if( (p_Width < 100) || (p_Width > 500) ) { writefln("Please Wedth length between 100 and 300."); return false; } if( (p_Height < 100) || (p_Height > 500) ) { writefln("Please Height length between 100 and 300."); return false; } if( (p_Probability <= 0) || (p_Probability >= 100) ) { writefln("Please Probability Value between 1 and 99."); return false; } if( p_StopCount < 0 ) { writefln("Please StopCount value over 0."); return false; } return true; } bool Init( int p_Width, int p_Height ) { SDL_VideoInfo* l_Info = null; writefln("SDL Initialize."); if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { writefln("SDL Initialize Failed. : %s.", SDL_GetError()); return false; } l_Info = SDL_GetVideoInfo(); SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); //SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0); if( SDL_SetVideoMode( p_Width * g_Magnification, p_Height * g_Magnification, l_Info.vfmt.BitsPerPixel, SDL_OPENGL ) == null ) { writefln("Set Video Mode Failed. :%s", SDL_GetError() ); return false; } glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, p_Width , 0, p_Height, 0, 10); glViewport(0, 0, p_Width * g_Magnification, p_Height * g_Magnification); glClearColor( 0, 0, 0, 0 ); //SDL_ShowCursor( SDL_DISABLE ); return true; } void End() { writefln("SDL Finalise."); SDL_Quit(); } bool PollEvent( ref island p_Island ) { SDL_Event l_Event; SDLKey* l_Key; while( SDL_PollEvent(&l_Event) ) { switch( l_Event.type ) { case SDL_QUIT:{ return false; }break; case SDL_KEYDOWN:{ l_Key = &(l_Event.key.keysym.sym); switch (*l_Key) { case SDLK_SPACE:{ p_Island.Freezing = !p_Island.Freezing; }break; case SDLK_ESCAPE:{ return false; }break; default:{ }break; } }break; default:{ }break; } } return true; } int main( string[] args ) { int l_Width = 0, l_Height = 0, l_Probability = 0, l_StopCount = 0; rand_seed( getUTCtime(), 0 ); //引数チェック if( !PropertysCheck( args, l_Width, l_Height, l_Probability, l_StopCount ) ) return -1; if( !Init( l_Width, l_Height ) ) return 0; fpsCounter l_FPS = new fpsCounter(); island l_Island = new island( l_Width, l_Height ); l_Island.randomize( l_Probability ); while( true ) { l_FPS.calc(); SDL_WM_SetCaption( cast(char*)toStringz(format("lifegame Generation:%d FPS:%6d", l_Island.Generation, l_FPS.Result)), null); l_Island.print(); if( !l_Island.Freezing) l_Island.next(); if( l_Island.Generation == l_StopCount ) l_Island.Freezing = true; if( !PollEvent( l_Island ) ) break; } End(); return 0; }
一応こんな感じになりました。
SDL版とFPS比較しても、そんな差は出ませんでした。
俺のコーディングが悪いんだ・・・。
とりあえずこれからも、ぼちぼちOpenGLを触って行こうかと思います。