1 module d2d.toolkit.game; 2 3 import d2d; 4 5 import std.datetime.stopwatch; 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 Keyboard.instance.handle(event); 85 Mouse.instance.handle(event); 86 } 87 88 public: 89 /// Starts the window and calls all functions 90 void run() 91 { 92 start(); 93 94 _window = new Window(_width, _height, _title, _flags); 95 96 if (_icon is null) 97 { 98 //dfmt off 99 _icon = new Bitmap( 100 [ 101 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 102 0x00ffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00ffffff, 103 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff9c9c9c, 0xff000000, 0xff000000, 0xff000000, 0xff383838, 0xffcccccc, 0xffffffff, 104 0xffffffff, 0xff000000, 0xff303030, 0xff303030, 0xff303030, 0xff1c1c1c, 0xff000000, 0xff9c9c9c, 0xffcccccc, 0xff000000, 0xff292929, 0xff303030, 0xff292929, 0xff000000, 0xff6d6d6d, 0xffffffff, 105 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff707070, 0xff131313, 0xff000000, 0xffcccccc, 0xff303030, 0xffb7b7b7, 0xffcccccc, 0xffb7b7b7, 0xff131313, 0xff000000, 0xffffffff, 106 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff555555, 0xff000000, 0xff9c9c9c, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff1e1e1e, 0xff000000, 0xffffffff, 107 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffa7a7a7, 0xff000000, 0xff6d6d6d, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffb0b0b0, 0xff000000, 0xff555555, 0xffffffff, 108 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffb0b0b0, 0xff000000, 0xff727272, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff333333, 0xff0d0d0d, 0xffa7a7a7, 0xffffffff, 109 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff8b8b8b, 0xff000000, 0xff909090, 0xffcccccc, 0xffcccccc, 0xff545454, 0xff000000, 0xff5b5b5b, 0xffcccccc, 0xffffffff, 110 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff444444, 0xff060606, 0xffb7b7b7, 0xffcccccc, 0xff545454, 0xff000000, 0xff454545, 0xffcccccc, 0xffcccccc, 0xffffffff, 111 0xffffffff, 0xff000000, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xff545454, 0xff000000, 0xff343434, 0xffcccccc, 0xff545454, 0xff000000, 0xff303030, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffffffff, 112 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff303030, 0xffa7a7a7, 0xffb0b0b0, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 113 0xffffffff, 0xff303030, 0xff303030, 0xff303030, 0xff303030, 0xff454545, 0xffcccccc, 0xffcccccc, 0xffb7b7b7, 0xff303030, 0xff303030, 0xff303030, 0xff303030, 0xff303030, 0xff303030, 0xffffffff, 114 0x00ffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00ffffff, 115 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 116 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 117 ], 16, 16, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); 118 //dfmt on 119 } 120 121 _window.setIcon(_icon); 122 123 FPSLimiter limiter; 124 if (_fps > 0) 125 limiter = new FPSLimiter(_fps); 126 127 load(); 128 129 Event event; 130 Duration delta; 131 while (_window.open) 132 { 133 _stopwatch.start(); 134 while (_window.pollEvent(event)) 135 { 136 if (event.type == Event.Type.Quit) 137 _window.close(); 138 else 139 onEvent(event); 140 } 141 142 update(delta.total!"hnsecs" / 10_000_000.0f); 143 144 draw(); 145 146 if (_postShader !is null) 147 _window.display(_postShader); 148 else 149 _window.display(); 150 151 if (limiter !is null) 152 limiter.wait(); 153 154 _stopwatch.stop(); 155 delta = _stopwatch.peek(); 156 _stopwatch.reset(); 157 } 158 } 159 }