diff options
author | Oxore <oxore@protonmail.com> | 2018-07-12 04:13:15 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2018-07-12 04:13:15 +0300 |
commit | 9a9711945c2add826e5887aabe2330bee9042b4b (patch) | |
tree | fe67952f6cd8a020ec0b1cf1fabf91167e785c23 | |
parent | 2b265ea0eb5825eccd3b9b072b5014bacf0d16d7 (diff) |
Introduce pause mechanics, refactor a little
Introduce Pause mechanics and mention it in README.md.
Makefile: replace unnecessary "-MMD -MP" with just "-MD" flag, so it
allows to compile with tcc too.
Refactor: Rename game.isStarted field to game.started field. Move
arrKeys container to engine.c and remove it from main.c. Refactor char
iterator in utf8to32_strcpy function.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | dat/texts.yaml | 9 | ||||
-rw-r--r-- | include/common.h | 3 | ||||
-rw-r--r-- | src/engine.c | 102 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | src/text.c | 5 |
7 files changed, 111 insertions, 19 deletions
@@ -24,7 +24,7 @@ CFLAGS+=-std=c11 CFLAGS+=-fms-extensions CFLAGS+=-g3 CFLAGS+=-O0 -CFLAGS+=-MMD -MP +CFLAGS+=-MD LDFLAGS+=$(COMMON) LDFLAGS+=-lcsfml-graphics @@ -22,11 +22,12 @@ make all ``` File named "tetris" is the final binary. Run it. Hit *S* to start game. -- `s` - start a game. +- `S` - start a game. - `Left arrow` - move shape left. - `Right arrow` - move shape right. - `Up arrow` - rotate shape clockwise. - `Space` - hard drop. +- `P` - pause. Cleaning: ``` @@ -51,5 +52,6 @@ Look at the [repo releases](https://github.com/Oxore/tetris-csfml/releases)! Now - Change colorscheme and define new - Number of levels - [x] Three next shapes +- [x] Pause - Look with sprites and shaders - Interprocess communication interface for control from other process (I want to connect machine learning algorithm and make it play and learn) diff --git a/dat/texts.yaml b/dat/texts.yaml index dec419c..6f8f480 100644 --- a/dat/texts.yaml +++ b/dat/texts.yaml @@ -59,3 +59,12 @@ size: 20 x: 276 y: 200 + +- + type: "pause" + scene: "game" + text: "PAUSED" + font: "Arial" + size: 36 + x: 60 + y: 188 diff --git a/include/common.h b/include/common.h index ca2e499..3273c66 100644 --- a/include/common.h +++ b/include/common.h @@ -1,6 +1,7 @@ struct game { unsigned int level; - int isStarted; + int started; + int paused; int scoreCurrent; int moveLatency; int lines; diff --git a/src/engine.c b/src/engine.c index a087fd2..d9cfe98 100644 --- a/src/engine.c +++ b/src/engine.c @@ -20,6 +20,7 @@ #define LEFT (1 << 3) #define RIGHTHOLD (1 << 4) #define HARDDROP (1 << 5) +#define PAUSE (1 << 6) #define LEFTHOLD (1 << 7) int level_move_latency[] = { @@ -67,7 +68,7 @@ int rmlines_score[] = { extern struct game game; extern struct field fld, nxt; extern struct idlist *texts; -extern char arrKeys; +char arrKeys = 0; static void render_score_value(void *obj) { @@ -140,6 +141,20 @@ static void show_game_text(void *obj) text->attr &= ~TXT_ATTR_INVISIBLE; } +static void hide_pause_text(void *obj) +{ + struct text *text = obj; + if (!strcmp(text->scene, "game") && !strcmp(text->type, "pause")) + text->attr |= TXT_ATTR_INVISIBLE; +} + +static void show_pause_text(void *obj) +{ + struct text *text = obj; + if (!strcmp(text->scene, "game") && !strcmp(text->type, "pause")) + text->attr &= ~TXT_ATTR_INVISIBLE; +} + static void update_menu_text(void *obj) { struct text *text = obj; @@ -156,7 +171,7 @@ static void update_game_text(void *obj) static void transition_game_over() { - game.isStarted = 0; + game.started = 0; game.scoreCurrent = 0; game.level = 1; game.moveLatency = get_level_latency(game.level); @@ -207,9 +222,30 @@ static void transition_put_shape() level_up(&game); } +static void transition_pause() +{ + game.paused = 1; + int elapsed = sfClock_getElapsedTime(game.gameTick).microseconds; + if (game.moveLatency - elapsed >= 0) + game.moveLatency -= elapsed; + else + game.moveLatency = get_level_latency(game.level); + sfClock_restart(game.gameTick); + list_foreach(texts, show_pause_text); +} + +static void transition_unpause() +{ + game.paused = 0; + sfClock_restart(game.gameTick); + list_foreach(texts, hide_pause_text); +} + static void game_tick() { sfClock_restart(game.gameTick); + + game.moveLatency = get_level_latency(game.level); if (field_move_shape_down(&fld, 1)) { project_ghost_shape(&fld, 1, 0); sfClock_restart(game.putTick); @@ -221,6 +257,11 @@ static void game_tick() transition_put_shape(); sfClock_restart(game.putTick); } + + list_foreach(texts, render_score_value); + list_foreach(texts, render_level_value); + painter_update_field(fld.id, &fld); + painter_update_field(nxt.id, &nxt); } static void signal_up() @@ -267,8 +308,27 @@ static void signal_right() } } +static void signal_pause() +{ + if (game.paused) + transition_unpause(); + else + transition_pause(); + sfClock_restart(game.putTick); +} + static void game_keys() { + /* PAUSE */ + if (sfKeyboard_isKeyPressed(sfKeyP)) { + if (!(arrKeys & PAUSE)) { + arrKeys = arrKeys | PAUSE; + signal_pause(); + } + } else { + arrKeys = arrKeys & ~PAUSE; + } + /* UP */ if (sfKeyboard_isKeyPressed(sfKeyUp)) { if (!(arrKeys & UP)) { @@ -344,6 +404,19 @@ static void game_keys() } } +static void pause_keys() +{ + /* PAUSE */ + if (sfKeyboard_isKeyPressed(sfKeyP)) { + if (!(arrKeys & PAUSE)) { + arrKeys = arrKeys | PAUSE; + signal_pause(); + } + } else { + arrKeys = arrKeys & ~PAUSE; + } +} + static void menuTick() { sfClock_restart(game.mTick); @@ -361,7 +434,8 @@ void transition_init(void) static void transition_game_start() { - game.isStarted = 1; + game.started = 1; + game.paused = 0; field_clear(&fld); shape_gen_random(&fld.shape[1]); field_reset_walking_shape(&fld, 1); @@ -372,8 +446,11 @@ static void transition_game_start() nxt.attr &= ~FLD_ATTR_INVISIBLE; list_foreach(texts, hide_menu_text); list_foreach(texts, show_game_text); + list_foreach(texts, hide_pause_text); list_foreach(texts, update_menu_text); list_foreach(texts, update_game_text); + painter_update_field(fld.id, &fld); + painter_update_field(nxt.id, &nxt); sfClock_restart(game.gameTick); } @@ -382,7 +459,6 @@ static void menu_loop() { menuTick(); if (sfKeyboard_isKeyPressed(sfKeyS) == 1) transition_game_start(); - painter_draw(); } static void game_loop() { @@ -391,17 +467,25 @@ static void game_loop() { game_tick(); list_foreach(texts, render_score_value); list_foreach(texts, render_level_value); + list_foreach(texts, update_game_text); painter_update_field(fld.id, &fld); painter_update_field(nxt.id, &nxt); - list_foreach(texts, update_game_text); - painter_draw(); +} + +static void pause_loop() { + pause_keys(); } void main_loop() { - if (game.isStarted) - game_loop(); - else + if (game.started) { + if (game.paused) + pause_loop(); + else + game_loop(); + } else { menu_loop(); + } + painter_draw(); } @@ -21,15 +21,14 @@ struct idlist *texts; struct field fld, nxt; struct game game = { - .isStarted = 0, + .started = 0, + .paused = 0, .scoreCurrent = 0, .level = 1, .moveLatency = L00LATENCY, .lines = 0 }; -char arrKeys = 0; - static void handleWindowEvents() { sfEvent event; while (sfRenderWindow_pollEvent(window, &event)) @@ -43,20 +43,17 @@ void utf8to32_strcpy(wchar_t *dest, char *src) int clen = utf8_char_len(*c); if (clen == 1) { dc[len] = c[0] & 0x7f; - c += 1; } else if (clen == 2) { dc[len] = ((c[0] & 0x1f) << 6) | ((c[1] & 0x3f) << 0); - c += 2; } else if (clen == 3) { dc[len] = ((c[0] & 0x0f) << 12) | ((c[1] & 0x3f) << 6) | ((c[2] & 0x3f) << 0); - c += 3; } else if (clen == 4) { dc[len] = ((c[0] & 0x07) << 18) | ((c[1] & 0x3f) << 12) | ((c[2] & 0x3f) << 6) | ((c[3] & 0x3f) << 0); - c += 4; } else { dc[len] = 0; return; } + c += clen; ++len; } dc[len] = 0; |