Skip to content

Commit

Permalink
Add kill counter and mission/life counter banner
Browse files Browse the repository at this point in the history
  • Loading branch information
commandblockguy committed Aug 4, 2020
1 parent ed5ffab commit 374f31c
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/graphics.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "profiler.h"
#include "partial_redraw.h"
#include "dynamic_sprites.h"
#include "gui.h"

uint8_t tilemap[TILEMAP_HEIGHT][TILEMAP_WIDTH];
// For each tilemap tile, the level Y of the block that it's representing
Expand Down Expand Up @@ -282,6 +283,8 @@ void redraw_tile(uint8_t x, uint8_t y) {
void full_redraw(void) {
gfx_FillScreen(COL_WHITE);
gfx_Tilemap(&tilemap_config, 0, 0);
displayGameBanner(game.mission + 1, game.lives);
displayGameKillCounter();
}

// Convert a screenspace coordinate to a redraw tile
Expand Down Expand Up @@ -382,10 +385,13 @@ void render(level_t *level) {
gfx_SetDrawBuffer();
full_redraw();
pdraw_FreeAll();
updateGameKillCounter(game.total_kills, true);
needs_redraw = false;
profiler_end(tilemap);
}

updateGameKillCounter(game.total_kills, false);

profiler_start(undraw);
pdraw_RemoveSprites();
profiler_end(undraw);
Expand Down
81 changes: 81 additions & 0 deletions src/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <stdint.h>
#include <tice.h>
#include <keypadc.h>
#undef NDEBUG
#include <debug.h>


#include "gui.h"
Expand Down Expand Up @@ -177,3 +179,82 @@ void missionStartScreen(uint8_t mission, uint8_t lives, uint8_t num_tanks) {

gfx_BlitBuffer();
}

#define KILL_COUNTER_END_X (SCREEN_DELTA_X(2.75 * TILE_SIZE))
#define KILL_COUNTER_INNER_END_X (SCREEN_DELTA_X(2.4 * TILE_SIZE))
#define KILL_COUNTER_HEIGHT (SCREEN_DELTA_Y(2 * TILE_SIZE))
#define KILL_COUNTER_INNER_HEIGHT (SCREEN_DELTA_Y(1.5 * TILE_SIZE))
#define KILL_COUNTER_RADIUS (KILL_COUNTER_HEIGHT / 2)
#define KILL_COUNTER_INNER_RADIUS (KILL_COUNTER_INNER_HEIGHT / 2)
#define KILL_COUNTER_Y (SCREEN_Y(LEVEL_SIZE_Y * TILE_SIZE - TILE_SIZE))
#define KILL_COUNTER_INNER_Y (KILL_COUNTER_Y + KILL_COUNTER_RADIUS - KILL_COUNTER_INNER_RADIUS + 1)

void updateKillCounterCurrBuf(uint8_t kills) {
uint8_t digits = 1 + (kills > 9 ) + (kills > 99);
uint8_t width = gfx_GetCharWidth('1') * digits;
uint8_t x = KILL_COUNTER_INNER_END_X - KILL_COUNTER_INNER_RADIUS - width;
gfx_SetColor(COL_WHITE);
gfx_FillRectangle_NoClip(x, KILL_COUNTER_INNER_Y, width, KILL_COUNTER_INNER_HEIGHT);
gfx_SetTextFGColor(COL_LIVES_TXT);
gfx_SetTextXY(x, KILL_COUNTER_INNER_Y + 4);
gfx_PrintUInt(kills, digits);
}

void updateGameKillCounter(uint8_t kills, bool force) {
static uint8_t last = -1;
if(!force && last == kills) return;
last = kills;
gfx_SetDrawScreen();
updateKillCounterCurrBuf(kills);
gfx_SetDrawBuffer();
updateKillCounterCurrBuf(kills);
}

void displayGameKillCounter(void) {
gfx_SetColor(COL_LIVES_TXT); // todo: add a bluer color
gfx_FillCircle_NoClip(KILL_COUNTER_END_X - KILL_COUNTER_RADIUS, KILL_COUNTER_Y + KILL_COUNTER_RADIUS, KILL_COUNTER_RADIUS);
gfx_FillRectangle_NoClip(0, KILL_COUNTER_Y, KILL_COUNTER_END_X - KILL_COUNTER_RADIUS, KILL_COUNTER_HEIGHT + 1);

gfx_SetColor(COL_WHITE);
gfx_FillCircle_NoClip(KILL_COUNTER_INNER_END_X - KILL_COUNTER_INNER_RADIUS, KILL_COUNTER_INNER_Y + KILL_COUNTER_INNER_RADIUS - 1, KILL_COUNTER_INNER_RADIUS);
gfx_FillRectangle_NoClip(0, KILL_COUNTER_INNER_Y, KILL_COUNTER_INNER_END_X - KILL_COUNTER_INNER_RADIUS, KILL_COUNTER_INNER_HEIGHT);
}

void displayGameBanner(uint8_t mission, uint8_t lives) {
// todo: check if the compiler optimizes these properly
const uint8_t banner_width = SCREEN_DELTA_X(10.5 * TILE_SIZE);
const uint8_t banner_height = 14;
const uint24_t base_x = (LCD_WIDTH - banner_width) / 2;
const uint8_t base_y = SCREEN_Y(LEVEL_SIZE_Y * TILE_SIZE - TILE_SIZE) + 3;
const uint8_t text_x = base_x + 18;
const uint24_t text2_x = base_x + 122;
const uint8_t text_y = base_y + 3;
const uint8_t rhomb_width = 7;

gfx_SetColor(COL_RHOM_1);
gfx_HorizLine(base_x + 1, base_y, banner_width - 2);
gfx_HorizLine(base_x + 1, base_y + banner_height - 1, banner_width - 2);
gfx_FillRectangle_NoClip(base_x, base_y + 1, banner_width, banner_height - 2);

gfx_SetColor(COL_RHOM_2);
for(uint24_t x = base_x; x < base_x + banner_width; x += rhomb_width) {
gfx_FillTriangle_NoClip(x, base_y + banner_height / 2 - 1, x + rhomb_width - 1, base_y + banner_height / 2 - 1, x + rhomb_width / 2, base_y);
gfx_FillTriangle_NoClip(x, base_y + banner_height / 2 - 1, x + rhomb_width - 1, base_y + banner_height / 2 - 1, x + rhomb_width / 2, base_y + banner_height - 1);
}

gfx_SetTextXY(text_x + 1, text_y + 1);
gfx_SetTextFGColor(COL_TXT_SHADOW);
gfx_PrintString("Mission ");
gfx_PrintUInt(mission, 1);
gfx_SetTextXY(text2_x + 1, text_y + 1);
gfx_PrintString("x ");
gfx_PrintUInt(lives, 1);

gfx_SetTextXY(text_x, text_y);
gfx_SetTextFGColor(COL_BG);
gfx_PrintString("Mission ");
gfx_PrintUInt(mission, 1);
gfx_SetTextXY(text2_x, text_y);
gfx_PrintString("x ");
gfx_PrintUInt(lives, 1);
}
4 changes: 4 additions & 0 deletions src/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ void displayKillCounts(void);

void missionStartScreen(uint8_t mission, uint8_t lives, uint8_t num_tanks); //Display the mission start screen

void updateGameKillCounter(uint8_t kills, bool force);
void displayGameKillCounter(void);
void displayGameBanner(uint8_t mission, uint8_t lives);

#endif //TANKS_GUI_H
2 changes: 1 addition & 1 deletion src/mine.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void detonate(mine_t *mine) {
MINE_EXPLOSION_RADIUS)) {
tank->alive = false;
game.kills[tanks[j].type]++;
game.total_kills++;
if(tanks[j].type != PLAYER) game.total_kills++;
}
for(k = 0; k < max_shells[tank->type]; k++) {
shell_t* shell = &tank->shells[k];
Expand Down
2 changes: 1 addition & 1 deletion src/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void processShell(shell_t* shell, tank_t* tank) {
if(!tanks[j].alive) continue;

if(detectCollision(&shell->phys, &tanks[j].phys)) {
game.total_kills++;
if(tanks[j].type != PLAYER) game.total_kills++;
game.kills[tanks[j].type]++;
tanks[j].alive = false;
shell->alive = false;
Expand Down

0 comments on commit 374f31c

Please sign in to comment.