-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathscene.hpp
384 lines (332 loc) · 10.5 KB
/
scene.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
#include "chunk.hpp"
#include "game.hpp"
#include "camera.hpp"
#include "chunkindex.hpp"
#include "testshapes.hpp"
#include "util.hpp"
#include <vector>
#include <bitset>
extern Camera g_cam;
extern void UpdateSimpleTexturePerSceneCB(const float x, const float y, const float alpha);
class GameScene {
public:
virtual void PrepareSpriteListForRender() = 0;
virtual void PreRender() = 0;
virtual std::vector<Sprite*>* GetSpriteListForRender() = 0;
#ifdef WIN32
virtual void PrepareLights() = 0;
virtual void RenderLights();
virtual void RenderHUD_D3D11() = 0;
virtual void RenderHUD_D3D12() = 0;
#endif
virtual void PostRender() = 0;
virtual void RenderHUD() = 0;
virtual void Update(float) = 0;
virtual void OnKeyPressed(char key) { };
virtual void OnKeyReleased(char key) { };
virtual void OnMouseMove(int mx, int my) { };
virtual void OnMouseDown() { };
virtual void OnMouseUp() { };
Camera* camera;
GameScene() : camera(&g_cam) { }
virtual bool CanHideMenu() = 0;
};
class TestShapesScene : public GameScene {
public:
Sprite* test_sprite, *test_background;
FullScreenQuad* fsquad;
ChunkSprite* global_xyz;
void PreRender() { }
void PostRender() { }
std::vector<Sprite*> sprite_render_list;
void PrepareSpriteListForRender();
std::vector<Sprite*>* GetSpriteListForRender();
void Update(float secs) { };
void RenderHUD() { };
#ifdef WIN32
void RenderHUD_D3D11() { };
void RenderHUD_D3D12() { };
void PrepareLights() { };
#endif
bool CanHideMenu() {
return true;
}
};
class ClimbScene : public GameScene {
public:
void RenderLights() override;
// Static level info
class LevelData {
public:
struct PlatformEntry {
float x, y;
std::string tag;
PlatformEntry() : x(0), y(0), tag("") {}
};
int bgid;
std::vector<PlatformEntry> entries;
LevelData() : bgid(0) {}
void AddEntry(float x, float y, const std::string& tag) {
PlatformEntry e;
e.x = x;
e.y = y;
e.tag = tag;
entries.push_back(e);
}
bool Empty() {
return entries.empty();
}
void Print() {
printf("bgid=%d, %zu entries\n", bgid, entries.size());
}
};
void LoadLevelData();
std::vector<LevelData> levels;
LevelData editing_level; // The level being currently edited
class GameObject {
public:
bool marked_for_removal = false;
void Remove() {
marked_for_removal = true;
}
};
class Platform : public GameObject {
public:
Sprite* sprite;
virtual Sprite* GetSpriteForDisplay() = 0;
virtual Sprite* GetSpriteForCollision() = 0;
virtual glm::vec3 GetOriginalPos() = 0;
virtual void Update(float) { }
~Platform() { delete sprite; }
};
class NormalPlatform : public Platform {
public:
NormalPlatform(Sprite* _s) {
sprite = _s;
}
Sprite* GetSpriteForDisplay() { return sprite; }
Sprite* GetSpriteForCollision() { return sprite; }
glm::vec3 GetOriginalPos() { return sprite->pos; }
};
class DamagablePlatform : public Platform {
public:
bool damaged;
DamagablePlatform(Sprite* _s) {
sprite = _s;
// 复制体素信息
ChunkSprite* cs = (ChunkSprite*)(sprite);
ChunkGrid* g = (ChunkGrid*)(cs->chunk);
cs->chunk = new ChunkGrid(*g);
damaged = false;
}
Sprite* GetSpriteForDisplay() { return sprite; }
Sprite* GetSpriteForCollision() { return sprite; }
glm::vec3 GetOriginalPos() { return sprite->pos; }
void DoDamage(const glm::vec3& world_x);
};
class ExitPlatform : public Platform {
public:
enum State {
Hidden,
FlyingIn,
Visible
};
State state;
static int FLY_IN_DURATION;
int fly_in_end_millis;
ExitPlatform(Sprite* _s) {
sprite = _s;
state = Hidden;
fly_in_end_millis = 0;
}
Sprite* GetSpriteForDisplay() {
if (state != Hidden) return sprite;
else return nullptr;
}
void Update(float secs);
Sprite* GetSpriteForCollision() {
if (state != Visible) return nullptr;
else return sprite;
}
glm::vec3 GetOriginalPos() { return sprite->pos; }
void FlyIn();
};
//
static ClimbScene* instance;
// 模型
static std::vector<ChunkGrid*> model_platforms;
static std::vector<ChunkGrid*> model_backgrounds1, model_backgrounds2;
static ChunkGrid* model_exit;
static ChunkGrid* model_char;
static ChunkGrid* unit_sq;
static ChunkGrid* model_anchor;
static ChunkGrid* model_coin;
Sprite* player, *player_disp;
glm::vec3 curr_player_rope_endpoint = PLAYER_ROPE_ENDPOINT[2];
float player_x_thrust;
int anchor_levels; // 按键层数
bool is_debug;
glm::vec3 debug_vel;
ChunkSprite* anchor;
glm::vec3 anchor_rope_endpoint;
std::vector<Platform*> platforms;
AABB cam_aabb;
std::vector<Sprite*> rope_segments;
std::vector<ChunkSprite*> backgrounds0, backgrounds1;
std::vector<Sprite*> coins, initial_coins;
int num_coins, num_coins_total;
int curr_level;
int curr_bgid;
float curr_level_time;
static void InitStatic();
// 资源
#ifdef WIN32
static ID3D11Resource* helpinfo_res, *keys_res;
static ID3D11ShaderResourceView* helpinfo_srv, *keys_srv;
#endif
static const float SPRING_K; // 弹力系数
static const float L0 ; // 绳子的初始长度
static const float GRAVITY; // 重力加速度
static const float X_THRUST; // 荡秋千带来的横向加速度
static const int NUM_SEGMENTS; // 画的时候有几段
static const float PROBE_DIST; // 探出的距离
static const int PROBE_DURATION; // 探出时所用时间
static const float ANCHOR_LEN; // 锚的长度 [-----绳子---------]-[--锚--> ]
static const float PLAYER_DISP_DELTAZ; // 显示玩家时的Z平移量
static const float X_VEL_DAMP;
static const float Y_VEL_DAMP;
static const glm::vec3 RELEASE_THRUST; // 松开绳子时给的向上的冲量
static const float CAM_FOLLOW_DAMP; // 视角跟随的阻尼系数
static const float BACKGROUND_SCALE; // 背景放大倍数
static const int COUNTDOWN_MILLIS; // 开始游戏之前的倒计时
static const int LEVEL_FINISH_SEQ_MILLIS; // 关卡完成序列的倒计时
static const int LEVEL_FINISH_JUMP_PERIOD;
static const glm::vec3 PLAYER_ROPE_ENDPOINT[8]; // 手抓绳子的局部坐标,八个方向
static const float INVERSE_INERTIA; // 转动惯量的倒数
std::bitset<10> keyflags;
bool is_key_pressed;
enum RopeState {
Hidden, Probing, Anchored, Retracting
};
RopeState rope_state;
glm::vec3 probe_delta;
float probe_remaining_millis;
enum ClimbGameState {
ClimbGameStateNotStarted,
ClimbGameStateInGame,
ClimbGameStateStartCountdown,
ClimbGameStateLevelFinishSequence,
ClimbGameStateLevelEndWaitKey,
ClimbGameStateInEditing,
};
// 这个结构控制游戏状态从 ClimbGameStateLevelFinishSequene 到
// ClimbGameStateLevelEndWaitKey 之间的过程。
struct LevelFinishState {
// for level finish
ClimbScene* parent; // singleton
glm::vec3 pos0, pos1;
float GetCompletion() {
return 1.0f - (1.0f * parent->countdown_millis / LEVEL_FINISH_SEQ_MILLIS);
}
};
ClimbGameState game_state;
float countdown_millis;
LevelFinishState level_finish_state;
int is_all_rockets_collected;
ClimbScene();
void Init();
void PreRender();
void PostRender() { }
std::vector<Sprite*> sprite_render_list;
void PrepareSpriteListForRender();
std::vector<Sprite*>* GetSpriteListForRender();
void Update(float secs);
void RenderHUD();
void RenderHUD_D3D11();
void RenderHUD_D3D12();
void do_RenderHUD(GraphicsAPI api);
virtual void OnKeyPressed(char);
virtual void OnKeyReleased(char);
void SetAnchorPoint(glm::vec3 anchor_p, glm::vec3 anchor_dir);
DirectionalLight* lights[16];
float light_phase = 0.0;
void PrepareLights();
// 每帧更新时做的事情
void RotateCoins(float secs);
void CameraFollow(float secs);
void LayoutBackground();
void HideRope();
glm::vec3 GetPlayerInitPos();
glm::vec3 GetPlayerInitVel();
glm::vec3 GetPlayerEffectivePos(); // 中心
glm::vec3 GetPlayerEffectiveRopeEndpoint(); // 头顶
void SpawnPlayer();
void do_StartLevel(LevelData& ldata);
void StartEditingLevel();
bool StartLevel(int levelid);
void DumpCurrentLevelToText();
void SaveCurrentLevelToEditingLevel();
void ComputeCamBB(); // Cam Bounding Box
void SetBackground(int bgid);
void SetGameState(ClimbGameState gs);
void RevealExit();
void LayoutRocketsOnExit(const glm::vec3& exit_pos);
void BeginLevelCompleteSequence();
bool is_test_playing; // 是否是从试玩模式进入
std::vector<Sprite*> cursor_sprites;
int curr_edit_option; // 0, 1, 2, 3: 平台; 4: 指针
Sprite* CurrentCursorSprite();
Sprite* highlight_sprite;
bool CanHideMenu();
int drag_mouse_x0, drag_mouse_y0;
glm::vec3 drag_pos0, dragged_sprite_pos0;
int mouse_x, mouse_y;
bool is_dragging = false;
ChunkSprite* dragged_sprite, *hovered_sprite;
virtual void OnMouseMove(int mx, int my);
virtual void OnMouseDown();
virtual void OnMouseUp();
bool is_shift_down = false; // Align to 1?
};
class LightTestScene : public GameScene {
public:
enum MacroState { OLD_YEAR, NEW_YEAR };
MacroState macro_state;
static float ACTOR_INIT_Y;
static void InitStatic();
static std::vector<ChunkGrid*> model_backgrounds;
static std::map<char, ChunkGrid*> model_digits;
ChunkSprite* bg_sprites[6];
static ChunkGrid* model_clock;
ChunkSprite* clock_sprite;
ChunkSprite* digit_sprites[20];
struct DigitState {
char old_char, new_char;
float tween_end_sec;
};
DigitState digit_states[20];
std::string status_string;
constexpr static int NUM_ACTORS = 16;
ChunkSprite* char_sprites[NUM_ACTORS];
float deltays[NUM_ACTORS];
float total_secs;
float last_update_total_secs;
int last_sec;
DirectionalLight* lights[16];
float curr_light_angle;
LightTestScene();
void PreRender() { }
void PostRender() { }
std::vector<Sprite*> sprite_render_list;
void PrepareSpriteListForRender();
std::vector<Sprite*>* GetSpriteListForRender();
void Update(float secs);
void RenderHUD() { };
void RenderHUD_D3D11() { };
void RenderHUD_D3D12() { };
void PrepareLights();
MacroState GetMacroState(int* curr_sec);
bool CanHideMenu() {
return true;
}
};