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 }