1 module d2d.toolkit.game; 2 3 import d2d; 4 5 import std.datetime; 6 7 /// Class for easily creating a window 8 abstract class Game 9 { 10 private: 11 int _width = 800, _height = 480; 12 Bitmap _icon = null; 13 Window _window = null; 14 string _title = "Game"; 15 int _fps = 60; 16 StopWatch _stopwatch; 17 WindowFlags _flags = WindowFlags.Default; 18 ShaderProgram _postShader = null; 19 20 protected: 21 /// Window start width, will not update afterwards 22 @property ref int windowWidth() 23 { 24 return _width; 25 } 26 27 /// Window start height, will not update afterwards 28 @property ref int windowHeight() 29 { 30 return _height; 31 } 32 33 /// Window icon, will not update afterwards 34 @property ref Bitmap windowIcon() 35 { 36 return _icon; 37 } 38 39 /// Window title, will not update afterwards 40 @property ref string windowTitle() 41 { 42 return _title; 43 } 44 45 /// Max FPS, will not update afterwards 46 @property ref int maxFPS() 47 { 48 return _fps; 49 } 50 51 /// Window start flags, will not update afterwards 52 @property ref WindowFlags flags() 53 { 54 return _flags; 55 } 56 57 /// Handle to the window. 58 @property Window window() 59 { 60 return _window; 61 } 62 63 /// Optional post processing shader. 64 @property ref ShaderProgram postShader() 65 { 66 return _postShader; 67 } 68 69 /// Start function will get called before window is created. Variables can be changed here. 70 abstract void start(); 71 72 /// Load function thats meant for loading content. 73 abstract void load(); 74 75 /// Will get called every frame before `draw`. 76 abstract void update(float delta); 77 78 /// Draw code goes here, `window.display` is not needed. 79 abstract void draw(); 80 81 /// Happens when some window event gets called. 82 void onEvent(Event event); 83 84 public: 85 /// Starts the window and calls all functions 86 void run() 87 { 88 start(); 89 90 _window = new Window(_width, _height, _title, _flags); 91 92 if (_icon is null) 93 { 94 _icon = new Bitmap( 95 [ 96 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 97 0x00ffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00ffffff, 98 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff9c9c9c, 0xff000000, 0xff000000, 0xff000000, 0xff383838, 0xffcccccc, 0xffffffff, 99 0xffffffff, 0xff000000, 0xff303030, 0xff303030, 0xff303030, 0xff1c1c1c, 0xff000000, 0xff9c9c9c, 0xffcccccc, 0xff000000, 0xff292929, 0xff303030, 0xff292929, 0xff000000, 0xff6d6d6d, 0xffffffff, 100 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff707070, 0xff131313, 0xff000000, 0xffcccccc, 0xff303030, 0xffb7b7b7, 0xffcccccc, 0xffb7b7b7, 0xff131313, 0xff000000, 0xffffffff, 101 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff555555, 0xff000000, 0xff9c9c9c, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff1e1e1e, 0xff000000, 0xffffffff, 102 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffa7a7a7, 0xff000000, 0xff6d6d6d, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffb0b0b0, 0xff000000, 0xff555555, 0xffffffff, 103 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffb0b0b0, 0xff000000, 0xff727272, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff333333, 0xff0d0d0d, 0xffa7a7a7, 0xffffffff, 104 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff8b8b8b, 0xff000000, 0xff909090, 0xffcccccc, 0xffcccccc, 0xff545454, 0xff000000, 0xff5b5b5b, 0xffcccccc, 0xffffffff, 105 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff444444, 0xff060606, 0xffb7b7b7, 0xffcccccc, 0xff545454, 0xff000000, 0xff454545, 0xffcccccc, 0xffcccccc, 0xffffffff, 106 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff545454, 0xff000000, 0xff343434, 0xffcccccc, 0xff545454, 0xff000000, 0xff303030, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffffffff, 107 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff303030, 0xffa7a7a7, 0xffb0b0b0, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 108 0xffffffff, 0xff303030, 0xff303030, 0xff303030, 0xff303030, 0xff454545, 0xffcccccc, 0xffcccccc, 0xffb7b7b7, 0xff303030, 0xff303030, 0xff303030, 0xff303030, 0xff303030, 0xff303030, 0xffffffff, 109 0x00ffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00ffffff, 110 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 111 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 112 ], 16, 16, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); 113 } 114 115 _window.setIcon(_icon); 116 117 FPSLimiter limiter; 118 if (_fps > 0) 119 limiter = new FPSLimiter(_fps); 120 121 load(); 122 123 Event event; 124 TickDuration delta; 125 while (_window.open) 126 { 127 _stopwatch.start(); 128 while (_window.pollEvent(event)) 129 { 130 if (event.type == Event.Type.Quit) 131 _window.close(); 132 else 133 onEvent(event); 134 } 135 136 update(delta.to!("seconds", float)); 137 138 draw(); 139 140 if (_postShader !is null) 141 _window.display(_postShader); 142 else 143 _window.display(); 144 145 if (limiter !is null) 146 limiter.wait(); 147 148 _stopwatch.stop(); 149 delta = _stopwatch.peek(); 150 _stopwatch.reset(); 151 } 152 } 153 }