Skip to content

Commit

Permalink
Add rendering for shells
Browse files Browse the repository at this point in the history
  • Loading branch information
commandblockguy committed Aug 6, 2020
1 parent 79cd3da commit 844ab69
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 47 deletions.
4 changes: 2 additions & 2 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ tiles:
@$(MAKE) -C src/tiles --no-print-directory

SHELL = bash
IMAGE_NAMES = {pl,en}_{base,turret}_{0..8}
IMAGE_NAMES = {{pl,en}_{base,turret},shell}_{0..8}
CONVIMG_INPUT = $(shell echo src/gfx/trimmed/$(IMAGE_NAMES).png) src/gfx/tileset.png
CONVIMG_OUTPUT = $(shell echo src/gfx/$(IMAGE_NAMES).{c,h}) src/gfx/tileset.c src/gfx/tileset.h src/gfx/palette.c src/gfx/palette.h src/gfx/gfx.h
BLENDER_OUTPUT = $(shell echo src/gfx/rendered/$(IMAGE_NAMES).png)
Expand All @@ -38,7 +38,7 @@ src/gfx/trimmed/%.png src/gfx/offsets/%.h: src/gfx/rendered/%.png
src/gfx/offsets/offsets.h: $(OFFSET_FILES)
echo \#ifndef H_OFFSETS > src/gfx/offsets/offsets.h
echo \#define H_OFFSETS >> src/gfx/offsets/offsets.h
for CURRENT_TYPE in {pl,en}_{base,turret}_{0..8}; do \
for CURRENT_TYPE in $(IMAGE_NAMES); do \
echo \#include \"$$CURRENT_TYPE.h\" ; \
done >> src/gfx/offsets/offsets.h
echo \#endif >> src/gfx/offsets/offsets.h
Expand Down
4 changes: 2 additions & 2 deletions src/collision.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
#undef NDEBUG
#include <debug.h>

uint24_t centerX(physicsBody_t* p) {
uint24_t centerX(const physicsBody_t *p) {
return p->position_x + p->width / 2;
}

uint24_t centerY(physicsBody_t* p) {
uint24_t centerY(const physicsBody_t *p) {
return p->position_y + p->height / 2;
}

Expand Down
4 changes: 2 additions & 2 deletions src/collision.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ typedef struct {
uint32_t updateTime;
} physicsBody_t;

uint24_t centerX(physicsBody_t* p); //Get the center coords of a AABB
uint24_t centerY(physicsBody_t* p);
uint24_t centerX(const physicsBody_t *p); //Get the center coords of a AABB
uint24_t centerY(const physicsBody_t *p);

//Determine if two bounding boxes are intersecting
bool detectCollision(physicsBody_t* p1, physicsBody_t* p2);
Expand Down
77 changes: 71 additions & 6 deletions src/dynamic_sprites.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@ gfx_UninitedSprite(pl_turret_13, pl_turret_3_width, pl_turret_3_height);
gfx_UninitedSprite(pl_turret_14, pl_turret_2_width, pl_turret_2_height);
gfx_UninitedSprite(pl_turret_15, pl_turret_1_width, pl_turret_1_height);

gfx_sprite_t *tank_bases[NUM_TANK_TYPES][16] = {
gfx_UninitedSprite(shell_9, shell_7_width, shell_7_height);
gfx_UninitedSprite(shell_10, shell_6_width, shell_6_height);
gfx_UninitedSprite(shell_11, shell_5_width, shell_5_height);
gfx_UninitedSprite(shell_12, shell_4_width, shell_4_height);
gfx_UninitedSprite(shell_13, shell_3_width, shell_3_height);
gfx_UninitedSprite(shell_14, shell_2_width, shell_2_height);
gfx_UninitedSprite(shell_15, shell_1_width, shell_1_height);

gfx_sprite_t * const tank_bases[NUM_TANK_TYPES][16] = {
{
pl_base_0,
pl_base_1,
Expand All @@ -43,7 +51,7 @@ gfx_sprite_t *tank_bases[NUM_TANK_TYPES][16] = {
}
};

gfx_sprite_t *tank_turrets[NUM_TANK_TYPES][16] = {
gfx_sprite_t * const tank_turrets[NUM_TANK_TYPES][16] = {
{
pl_turret_0,
pl_turret_1,
Expand All @@ -64,7 +72,26 @@ gfx_sprite_t *tank_turrets[NUM_TANK_TYPES][16] = {
}
};

const uint8_t base_x_offsets[16] = {
gfx_sprite_t * const shell_sprites[16] = {
shell_0,
shell_1,
shell_2,
shell_3,
shell_4,
shell_5,
shell_6,
shell_7,
shell_8,
(gfx_sprite_t*)shell_9_data,
(gfx_sprite_t*)shell_10_data,
(gfx_sprite_t*)shell_11_data,
(gfx_sprite_t*)shell_12_data,
(gfx_sprite_t*)shell_13_data,
(gfx_sprite_t*)shell_14_data,
(gfx_sprite_t*)shell_15_data,
};

const uint8_t base_x_offsets[16] = {
pl_base_0_offset_x,
pl_base_1_offset_x,
pl_base_2_offset_x,
Expand All @@ -83,7 +110,7 @@ const uint8_t base_x_offsets[16] = {
tank_sprite_total_width - pl_base_1_offset_x - pl_base_1_width,
};

const uint8_t base_y_offsets[16] = {
const uint8_t base_y_offsets[16] = {
pl_base_0_offset_y,
pl_base_1_offset_y,
pl_base_2_offset_y,
Expand All @@ -102,7 +129,7 @@ const uint8_t base_y_offsets[16] = {
pl_base_1_offset_y,
};

const uint8_t turret_x_offsets[16] = {
const uint8_t turret_x_offsets[16] = {
pl_turret_0_offset_x,
pl_turret_1_offset_x,
pl_turret_2_offset_x,
Expand All @@ -121,7 +148,7 @@ const uint8_t turret_x_offsets[16] = {
tank_sprite_total_width - pl_turret_1_offset_x - pl_turret_1_width,
};

const uint8_t turret_y_offsets[16] = {
const uint8_t turret_y_offsets[16] = {
pl_turret_0_offset_y,
pl_turret_1_offset_y,
pl_turret_2_offset_y,
Expand All @@ -139,3 +166,41 @@ const uint8_t turret_y_offsets[16] = {
pl_turret_2_offset_y,
pl_turret_1_offset_y,
};

const uint8_t shell_x_offsets[16] = {
shell_0_offset_x,
shell_1_offset_x,
shell_2_offset_x,
shell_3_offset_x,
shell_4_offset_x,
shell_5_offset_x,
shell_6_offset_x,
shell_7_offset_x,
shell_8_offset_x,
tank_sprite_total_width - shell_7_offset_x - shell_7_width,
tank_sprite_total_width - shell_6_offset_x - shell_6_width,
tank_sprite_total_width - shell_5_offset_x - shell_5_width,
tank_sprite_total_width - shell_4_offset_x - shell_4_width,
tank_sprite_total_width - shell_3_offset_x - shell_3_width,
tank_sprite_total_width - shell_2_offset_x - shell_2_width,
tank_sprite_total_width - shell_1_offset_x - shell_1_width,
};

const uint8_t shell_y_offsets[16] = {
shell_0_offset_y,
shell_1_offset_y,
shell_2_offset_y,
shell_3_offset_y,
shell_4_offset_y,
shell_5_offset_y,
shell_6_offset_y,
shell_7_offset_y,
shell_8_offset_y,
shell_7_offset_y,
shell_6_offset_y,
shell_5_offset_y,
shell_4_offset_y,
shell_3_offset_y,
shell_2_offset_y,
shell_1_offset_y,
};
13 changes: 9 additions & 4 deletions src/dynamic_sprites.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
#ifndef TANKS_DYNAMIC_SPRITES_H
#define TANKS_DYNAMIC_SPRITES_H

extern gfx_sprite_t *tank_bases[NUM_TANK_TYPES][16];
extern gfx_sprite_t *tank_turrets[NUM_TANK_TYPES][16];
extern gfx_sprite_t * tank_bases[NUM_TANK_TYPES][16];
extern gfx_sprite_t * tank_turrets[NUM_TANK_TYPES][16];

gfx_sprite_t * const enemy_bases_unconv[9];
gfx_sprite_t * const enemy_turrets_unconv[9];
extern gfx_sprite_t * shell_sprites[16];

extern gfx_sprite_t * const enemy_bases_unconv[9];
extern gfx_sprite_t * const enemy_turrets_unconv[9];

extern const uint8_t base_x_offsets[16];
extern const uint8_t base_y_offsets[16];
extern const uint8_t turret_x_offsets[16];
extern const uint8_t turret_y_offsets[16];

extern const uint8_t shell_x_offsets[16];
extern const uint8_t shell_y_offsets[16];

#endif //TANKS_DYNAMIC_SPRITES_H
1 change: 1 addition & 0 deletions src/gfx/convimg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ converts:
- tileset.png
images:
- trimmed/pl_*.png
- trimmed/shell_*.png
- name: enemy
palette: enemy_palette
images:
Expand Down
63 changes: 36 additions & 27 deletions src/graphics.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ void initGraphics(void) {
for(uint8_t i = 1; i < 8; i++) {
gfx_FlipSpriteY(tank_bases[PLAYER][i], tank_bases[PLAYER][16 - i]);
gfx_FlipSpriteY(tank_turrets[PLAYER][i], tank_turrets[PLAYER][16 - i]);
gfx_FlipSpriteY(shell_sprites[i], shell_sprites[16 - i]);
}
}

Expand Down Expand Up @@ -319,45 +320,53 @@ void draw_aim_dots(void) {
profiler_end(aim_indicator);
}

void render_obscured_object(gfx_sprite_t **sprites, const uint8_t *offsets_x, const uint8_t *offsets_y, const physicsBody_t *phys, uint8_t rotation) {
uint24_t base_x = SCREEN_X(centerX(phys)) - SPRITE_OFFSET_X;
uint8_t base_y = SCREEN_Y(centerY(phys)) - SPRITE_OFFSET_Y;
uint8_t tile_x, tile_y;
uint8_t end_x = screen_to_tm_x(base_x + SPRITE_SIZE_X);
uint8_t end_y = screen_to_tm_y(base_y + SPRITE_SIZE_Y);
uint8_t tank_y = ptToYTile(phys->position_y + phys->height - 1); // -1 is to round down if exactly on the edge

pdraw_TransparentSprite_NoClip(sprites[rotation],
base_x + offsets_x[rotation],
base_y + offsets_y[rotation]);

// todo: make this next part use offsets
for(tile_x = screen_to_tm_x(base_x); tile_x <= end_x; tile_x++) {
for(tile_y = screen_to_tm_y(base_y); tile_y <= end_y; tile_y++) {
int8_t world_tile_y = depthmap[tile_y][tile_x];
if(world_tile_y >= tank_y && tilemap[tile_y][tile_x] != TS_NONE) {
redraw_tile(tile_x, tile_y);
}
}
}
}

void render_shell(shell_t *shell) {
if(shell->alive) {
uint8_t sprite = shell->direction;
render_obscured_object(shell_sprites, shell_x_offsets, shell_y_offsets, &shell->phys, sprite);
}
}

void render_tank(tank_t *tank) {
int j;

if(tank->alive) {
uint24_t base_x = SCREEN_X(tank->phys.position_x) - TANK_SPRITE_OFFSET_X;
uint8_t base_y = SCREEN_Y(tank->phys.position_y) - TANK_SPRITE_OFFSET_Y;
uint8_t base_sprite = (((uint8_t)-((tank->tread_rot >> 16) - 64)) >> 3) & 0xF;
uint8_t turret_sprite = ((uint8_t)-((tank->barrel_rot >> 16) - 64)) >> 4;
uint8_t tile_x, tile_y;
uint8_t end_x = screen_to_tm_x(base_x + TANK_SPRITE_SIZE_X);
uint8_t end_y = screen_to_tm_y(base_y + TANK_SPRITE_SIZE_Y);
uint8_t tank_y = ptToYTile(tank->phys.position_y + TANK_SIZE - 1); // -1 is to round down if exactly on the edge

pdraw_TransparentSprite_NoClip(tank_bases[tank->type][base_sprite],
base_x + base_x_offsets[base_sprite],
base_y + base_y_offsets[base_sprite]);
pdraw_TransparentSprite_NoClip(tank_turrets[tank->type][turret_sprite],
base_x + turret_x_offsets[turret_sprite],
base_y + turret_y_offsets[turret_sprite]);

// todo: make this next part use offsets
// todo: figure out why the turret is visible through blocks in some cases

for(tile_x = screen_to_tm_x(base_x); tile_x <= end_x; tile_x++) {
for(tile_y = screen_to_tm_y(base_y); tile_y <= end_y; tile_y++) {
int8_t world_tile_y = depthmap[tile_y][tile_x];
if(world_tile_y >= tank_y && tilemap[tile_y][tile_x] != TS_NONE) {
redraw_tile(tile_x, tile_y);
}
}
}
render_obscured_object(tank_bases[tank->type], base_x_offsets, base_y_offsets, &tank->phys, base_sprite);
render_obscured_object(tank_turrets[tank->type], turret_x_offsets, turret_y_offsets, &tank->phys, turret_sprite);

// todo: figure out why the turret is visible through blocks in some cases
}

//draw shell hitboxes until I can get sprites
for(j = max_shells[tank->type] - 1; j >= 0; j--) {
shell_t* shell = &tank->shells[j];
if(!(shell->alive)) continue;
gfx_SetColor(COL_BLACK);
renderPhysicsBody(&shell->phys);
if(shell->alive) render_shell(shell);
}
//draw mine hitboxes
for(j = max_mines[tank->type] - 1; j >= 0; j--) {
Expand Down
8 changes: 4 additions & 4 deletions src/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ typedef struct {
#define SCREEN_X(x) (SCREEN_DELTA_X(x) + MAP_OFFSET_X)
#define SCREEN_Y(y) (SCREEN_DELTA_Y(y) + MAP_OFFSET_Y)

#define TANK_SPRITE_OFFSET_X 11
#define TANK_SPRITE_OFFSET_Y 16
#define TANK_SPRITE_SIZE_X 40
#define TANK_SPRITE_SIZE_Y 30
#define SPRITE_OFFSET_X 20
#define SPRITE_OFFSET_Y 22
#define SPRITE_SIZE_X 40
#define SPRITE_SIZE_Y 30

// todo: get an actual value?
#define AIM_INDICATOR_DOT_DISTANCE (2 * TILE_SIZE)
Expand Down
7 changes: 7 additions & 0 deletions src/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,19 @@ bool shellRicochet(shell_t* shell, direction_t dir) {
//shell_t is still alive
if(dir & UP || dir & DOWN) {
shell->phys.velocity_y *= -1;
updateShellDirection(shell);
shell->bounces--;
}
if(dir & LEFT || dir & RIGHT) {
shell->phys.velocity_x *= -1;
updateShellDirection(shell);
shell->bounces--;
}

return true;
}

void updateShellDirection(shell_t* shell) {
angle_t angle = fast_atan2(shell->phys.velocity_y, shell->phys.velocity_x);
shell->direction = angleToShellDirection(angle);
}
6 changes: 6 additions & 0 deletions src/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,16 @@ typedef struct {
physicsBody_t phys;
uint8_t bounces; //Number of times the shell can bounce off a wall without exploding
bool left_tank_hitbox; //Whether the shell has exited the tank hitbox yet. Used to stop shells from blowing up the tank that fired them.
uint8_t direction;
} shell_t;

//Bounce a shell off a wall
//Returns whether or not the shell is still alive
bool shellRicochet(shell_t* shell, direction_t dir);

uint8_t inline angleToShellDirection(angle_t angle) {
return ((uint8_t)-((angle >> 16) - 64)) >> 4;
}
void updateShellDirection(shell_t* shell);

#endif //TANKS_SHELL_H
1 change: 1 addition & 0 deletions src/tank.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ bool fireShell(tank_t* tank) {
shell->phys.velocity_x = SHELL_SPEED_STANDARD * vector_x / TRIG_SCALE;
shell->phys.velocity_y = SHELL_SPEED_STANDARD * vector_y / TRIG_SCALE;
}
shell->direction = angleToShellDirection(tank->barrel_rot);
return true;
}
return false;
Expand Down
Binary file modified tank.blend
Binary file not shown.

0 comments on commit 844ab69

Please sign in to comment.