]> git.lizzy.rs Git - dungeon_game.git/commitdiff
Fancy up score display
authorElias Fleckenstein <eliasfleckenstein@web.de>
Mon, 14 Jun 2021 15:39:27 +0000 (17:39 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Mon, 14 Jun 2021 15:39:27 +0000 (17:39 +0200)
doc/GAMEPLAY.md
plugins/game/game.c
plugins/game/game.h
plugins/score/score.c
plugins/score/score.h

index bdcc1bb4d5ffff91b349bca38eab02cd9a0bcd77..5af13008de0b3e9af83d19b9d718f7b6fdfa6cc2 100644 (file)
@@ -8,6 +8,9 @@ You are in a pixely dungeon. There is no exit, the goal of the game is to surviv
 You can use WASD to move up / left / down / right. Use Q to quit and Space to shoot fireballs if you have them in your inventory. Use E to use your sword if you have one in your inventory.
 To navigate the inventory, use the arrow keys (up and down) to select an item and then press enter to use it.
 
+## Score
+You can gain score from various things explained later. You need a certain amount of score to reach the next level; e.g. to reach level 1 when you are level 0 you need 5 score, to reach level 2 you need 10, for level 3 15 and so on. When you reach a new level, your score is reset, to to reach level 3 you'll need 5 + 10 + 15 = 30 score in total.
+
 ## The map
 
 The map consists of nodes and entities. The nodes are static; they cannot move and you cannot break or replace them. They are automatically generated on startup. Some nodes are solid, which means entities collide with them, others are not.
@@ -64,9 +67,9 @@ In the lower center of your screen you can see 10 hearts. Depending on whether t
 
 If you use an item that needs to recharge after being used, a recharge meter will show. It tells you the recharge percentage and visualizes it using a bar. You cannot use
 
-### The score count
+### The score bar
 
-In the upper light corner there is a display that tells you your current score.
+On the top of the screen a green bar displays how close you are to reaching the next score level. It also shows the current level in roman numerals at the center (it will not display the level if the level is 0).
 
 ### The inventory
 
index 152a5c97200e75578a3139877929e6b03277fa75..94ad148d6930bd8266bcc4c415af76d34fb4f10f 100644 (file)
@@ -129,6 +129,48 @@ double calculate_dtime(struct timespec from, struct timespec to)
        return (double) (to.tv_sec - from.tv_sec) + (double) (to.tv_nsec - from.tv_nsec) / 1000000000.0;
 }
 
+/*struct roman_conversion_rule
+{
+       int number;
+       const char *symbol;
+};*/
+
+static struct
+{
+       int number;
+       const char *symbol;
+} roman_ct[13] = {
+       {1000, "M"},
+       {900, "CM"},
+       {500, "D"},
+       {400, "CD"},
+       {100, "C"},
+       {90, "XC"},
+       {50, "L"},
+       {40, "XL"},
+       {10, "X"},
+       {9, "IX"},
+       {5, "V"},
+       {4, "IV"},
+       {1, "I"}
+};
+
+void get_roman_numeral(int number, char **ptr, size_t *len)
+{
+       *ptr = NULL;
+       *len = 0;
+
+       for (int i = 0; i < 13; i++) {
+               while (number >= roman_ct[i].number) {
+                       number -= roman_ct[i].number;
+                       size_t old_len = *len;
+                       *len += 1 + i % 2;
+                       *ptr = realloc(*ptr, *len + 1);
+                       strcpy(*ptr + old_len, roman_ct[i].symbol);
+               }
+       }
+}
+
 /* Game-related utility functions */
 
 void quit()
index 60c1d615c0a1bac664dd4e537d03adcde0f234f9..21a94339eb0969bf680f1bd4ba4e4ac6e773b3d2 100644 (file)
@@ -113,6 +113,7 @@ int max(int a, int b);
 int min(int a, int b);
 void *make_buffer(void *ptr, size_t size);
 double calculate_dtime(struct timespec from, struct timespec to);
+void get_roman_numeral(int number, char **ptr, size_t *len);
 
 void quit();
 bool player_dead();
index 7ad8b66131abf95cb04529f2da9f073a5bd03fe9..c310d3b5696935cf2cc22ea22a193969e7f3d94c 100644 (file)
@@ -1,11 +1,40 @@
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
 #include "../game/game.h"
 
 static int score = 0;
+static int needed_score = 5;
+static int level = 0;
+static char *level_symbol = NULL;
+static size_t level_symbol_len = 0;
+static double score_timer = 0.0;
+static double level_timer = 0.0;
+
+static void level_up()
+{
+       level += 1;
+       needed_score = (level + 1) * 5;
+
+       if (level_symbol)
+               free(level_symbol);
+
+       get_roman_numeral(level, &level_symbol, &level_symbol_len);
+
+       level_timer = 2.0;
+}
 
 void add_score(int s)
 {
        score += s;
+
+       if (score >= needed_score) {
+               score -= needed_score;
+               level_up();
+       } else {
+               score_timer = 2.0;
+       }
 }
 
 int get_score()
@@ -13,14 +42,56 @@ int get_score()
        return score;
 }
 
+int get_level()
+{
+       return level;
+}
+
 static void render_score(struct winsize ws)
 {
-       (void) ws;
+       int bar_flash = clamp(score_timer * 255, 0, 255);
+       set_color((struct color) {bar_flash, 255, bar_flash}, true);
+
+       int level_flash = clamp(level_timer * 255, 0, 255);
+       set_color((struct color) {255, 255, 255 - level_flash}, false);
+
+       size_t level_len = level_symbol_len > 0 ? 6 + level_symbol_len + 1 : 0;
+       char level_display[level_len];
+
+       if (level_len > 0)
+               sprintf(level_display, "Level %s", level_symbol);
+
+       int bar = (double) score / (double) needed_score * ws.ws_col;
+       int level_start = (ws.ws_col - level_len) / 2;
+       int level_end = level_start + level_len - 1;
+
+       for (int i = 0; i < ws.ws_col; i++) {
+               if (i == bar)
+                       printf("\e[49m");
+
+               if (i >= level_start && i < level_end)
+                       printf("%c", level_display[i - level_start]);
+               else
+                       printf(" ");
+       }
+
+       printf("\n");
+}
+
+static void score_globalstep(double dtime)
+{
+       if (level_timer > 0.0)
+               level_timer -= dtime;
 
-       printf("\e[32m\e[3mScore:\e[23m %d", score);
+       if (score_timer > 0.0)
+               score_timer -= dtime * 3.0;
 }
 
 __attribute__ ((constructor)) static void init()
 {
        register_render_component(&render_score);
+       register_globalstep((struct globalstep) {
+               .run_if_dead = true,
+               .callback = &score_globalstep,
+       });
 }
index 8ee531aab6afd935c369a78952c0cbfb4260e797..4d029036ed717962a75d64f65ee06e2ad9a5aa62 100644 (file)
@@ -3,5 +3,6 @@
 
 void add_score(int s);
 int get_score();
+int get_level();
 
 #endif