1
+ #include < iostream>
2
+ #include < string>
3
+ #include < vector>
4
+ #include < map>
5
+ #include < windows.h>
6
+ #include " SDL.h"
7
+ #include " SDL_image.h"
8
+ using namespace std ;
9
+
10
+ class Images {
11
+ public:
12
+ void load_background () {
13
+ _background = IMG_Load (" assets/background.png" );
14
+ if (_background == nullptr ) {
15
+ exit (-1 );
16
+ }
17
+ _width = _background->w ;
18
+ _height = _background->h ;
19
+ }
20
+
21
+ void create_textures (SDL_Renderer* renderer) {
22
+ _renderer = renderer;
23
+
24
+ _textures[" background" ] = SDL_CreateTextureFromSurface (renderer, _background);
25
+ SDL_FreeSurface (_background);
26
+ _background = nullptr ;
27
+
28
+ char name[16 ], file[64 ];
29
+ for (int i = 0 ; i <= 3 ; i++) {
30
+ sprintf_s (name, " left%d" , i);
31
+ sprintf_s (file, " assets/%s.png" , name);
32
+ auto s = IMG_Load (file);
33
+ _textures[string (name)] = SDL_CreateTextureFromSurface (renderer, s);
34
+ SDL_FreeSurface (s);
35
+ }
36
+ for (int i = 0 ; i <= 5 ; i++) {
37
+ sprintf_s (name, " right%d" , i);
38
+ sprintf_s (file, " assets/%s.png" , name);
39
+ auto s = IMG_Load (file);
40
+ _textures[string (name)] = SDL_CreateTextureFromSurface (renderer, s);
41
+ SDL_FreeSurface (s);
42
+ }
43
+ }
44
+
45
+ pair<int ,int > get_window_size () {
46
+ return make_pair (_width, _height);
47
+ }
48
+
49
+ void render_background () {
50
+ SDL_RenderCopy (_renderer, _textures[" background" ], nullptr , nullptr );
51
+ }
52
+
53
+ void render_left (int i) {
54
+ string s (" left" );
55
+ s.push_back (' 0' + i);
56
+ SDL_RenderCopy (_renderer, _textures[s], nullptr , nullptr );
57
+ }
58
+
59
+ void render_right (int i) {
60
+ string s (" right" );
61
+ s.push_back (' 0' + i);
62
+ SDL_RenderCopy (_renderer, _textures[s], nullptr , nullptr );
63
+ }
64
+
65
+ private:
66
+ SDL_Surface* _background;
67
+ int _width, _height;
68
+ SDL_Renderer* _renderer;
69
+ map<string, SDL_Texture*> _textures;
70
+ };
71
+
72
+ static const int FPS = 60 ;
73
+ static const int FrameInterval = 1000 / FPS;
74
+ static const int CatResetDelay = 1000 ;
75
+
76
+ static const vector<int > Left2Keys = {VK_ESCAPE, ' 1' , ' 2' , ' 3' , VK_TAB, ' Q' , ' W' , ' E' , VK_CAPITAL, ' A' , ' S' , VK_LSHIFT, ' Z' , ' X' , VK_LCONTROL, VK_LWIN, VK_LMENU};
77
+ static const vector<int > Left3Keys = {' 4' , ' 5' , ' 6' , ' R' , ' T' , ' D' , ' F' , ' G' , ' C' , ' V' , ' B' , VK_SPACE};
78
+ static const vector<int > Right2Keys = {' 7' , ' 8' , ' 9' , ' Y' , ' U' , ' I' , ' O' , ' H' , ' J' , ' K' ,' N' , ' M' , VK_OEM_COMMA, VK_RMENU};
79
+ static const vector<int > Right3Keys = {' 0' , VK_OEM_MINUS, VK_OEM_PLUS, VK_BACK, ' P' , VK_OEM_4, VK_OEM_6, VK_OEM_5, ' L' , VK_OEM_1, VK_OEM_7, VK_RETURN, VK_OEM_PERIOD, VK_OEM_2, VK_RSHIFT, VK_RCONTROL, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT};
80
+ static const vector<int > MouseKeys = { VK_LBUTTON, VK_RBUTTON, VK_MBUTTON };
81
+
82
+ class Scene {
83
+ public:
84
+ void render (SDL_Renderer* renderer, Images *images) {
85
+ SDL_RenderClear (renderer);
86
+ images->render_background ();
87
+ images->render_left (_left_index);
88
+ images->render_right (_right_index);
89
+ SDL_RenderPresent (renderer);
90
+ }
91
+
92
+ void update (UINT32 tick) {
93
+ _update_states ();
94
+
95
+ if (_next_left > 0 ) {
96
+ _left_index = _next_left;
97
+ _left_reset_tick = 0 ;
98
+ } else if (_left_index == 2 || _left_index == 3 ) {
99
+ _left_index = 1 ;
100
+ _left_reset_tick = tick + CatResetDelay;
101
+ }
102
+
103
+ if (_next_right > 0 ) {
104
+ _right_index = _next_right;
105
+ _right_reset_tick = 0 ;
106
+ if (_next_right == 4 ) {
107
+ _right_reset_tick = tick + CatResetDelay;
108
+ }
109
+ } else if (_right_index == 2 || _right_index == 3 ) {
110
+ _right_index = 1 ;
111
+ _right_reset_tick = tick + CatResetDelay;
112
+ } else if (_right_index == 5 ) {
113
+ _right_index = 4 ;
114
+ _right_reset_tick = tick + CatResetDelay;
115
+ }
116
+
117
+ if (_left_reset_tick > 0 && tick >= _left_reset_tick) {
118
+ _left_index = 0 ;
119
+ _left_reset_tick = 0 ;
120
+ }
121
+ if (_right_reset_tick > 0 && tick >= _right_reset_tick) {
122
+ _right_index = 0 ;
123
+ _right_reset_tick = 0 ;
124
+ }
125
+ }
126
+
127
+ private:
128
+ bool _any_key_pressed (const vector<int >& keys) {
129
+ for (auto it = keys.begin (); it != keys.end (); it++) {
130
+ if (GetKeyState (*it) & 0x8000 ) {
131
+ return true ;
132
+ }
133
+ }
134
+ return false ;
135
+ }
136
+
137
+ bool _mouse_moved () {
138
+ POINT pt;
139
+ GetCursorPos (&pt);
140
+ bool changed = (pt.x != _cursor_pos.x || pt.y != _cursor_pos.y );
141
+ _cursor_pos = pt;
142
+ return changed;
143
+ }
144
+
145
+ void _update_states () {
146
+ _next_left = 0 ;
147
+ if (_any_key_pressed (Left2Keys)) {
148
+ _next_left = 2 ;
149
+ }
150
+ if (_any_key_pressed (Left3Keys)) {
151
+ _next_left = 3 ;
152
+ }
153
+ _next_right = 0 ;
154
+ if (_any_key_pressed (Right2Keys)) {
155
+ _next_right = 2 ;
156
+ }
157
+ if (_any_key_pressed (Right3Keys)) {
158
+ _next_right = 3 ;
159
+ }
160
+ if (_mouse_moved ()) {
161
+ _next_right = 4 ;
162
+ }
163
+ if (_any_key_pressed (MouseKeys)) {
164
+ _next_right = 5 ;
165
+ }
166
+ }
167
+
168
+ int _left_index = 0 ;
169
+ UINT32 _left_reset_tick = 0 ;
170
+ int _right_index = 0 ;
171
+ UINT32 _right_reset_tick = 0 ;
172
+
173
+ int _next_left = 0 ;
174
+ int _next_right = 0 ;
175
+ POINT _cursor_pos = { 0 ,0 };
176
+ };
177
+
178
+ int main (int argc, char * argv[]) {
179
+ SDL_Init (SDL_INIT_EVERYTHING);
180
+
181
+ Images images;
182
+ images.load_background ();
183
+ auto window_size = images.get_window_size ();
184
+
185
+ SDL_Window* window = SDL_CreateWindow (" Coding Cat" ,
186
+ SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
187
+ window_size.first , window_size.second , SDL_WINDOW_SHOWN | SDL_WINDOW_ALWAYS_ON_TOP);
188
+ SDL_Renderer* renderer = SDL_CreateRenderer (window, -1 , 0 );
189
+ images.create_textures (renderer);
190
+
191
+ Scene scene;
192
+ while (true ) {
193
+ auto tick = SDL_GetTicks ();
194
+ SDL_Event event;
195
+ while (SDL_PollEvent (&event)) {
196
+ if (event.type == SDL_QUIT) {
197
+ SDL_DestroyWindow (window);
198
+ SDL_DestroyRenderer (renderer);
199
+ SDL_Quit ();
200
+ return 0 ;
201
+ }
202
+ }
203
+ scene.update (tick);
204
+ scene.render (renderer, &images);
205
+ auto elapsed = SDL_GetTicks () - tick;
206
+ if (elapsed < FrameInterval) {
207
+ SDL_Delay (FrameInterval - elapsed);
208
+ }
209
+ }
210
+ }
0 commit comments