diff options
| author | Thomas Guillermo Albers Raviola <thomas@thomaslabs.org> | 2026-01-16 23:26:01 +0100 |
|---|---|---|
| committer | Thomas Guillermo Albers Raviola <thomas@thomaslabs.org> | 2026-01-16 23:26:01 +0100 |
| commit | c15c603b35e86fd42e6db94a7382ba7a1ddadd6e (patch) | |
| tree | ab56040ce4768564bef5fbe9e65fe4c025cea6ce /player.c | |
Initial commit
Diffstat (limited to 'player.c')
| -rw-r--r-- | player.c | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/player.c b/player.c new file mode 100644 index 0000000..e05933d --- /dev/null +++ b/player.c @@ -0,0 +1,298 @@ +#include "game.h" +#include <string.h> + +void update_score(void) +{ + char buffer[48]; + struct Player *p1 = &game->players[0], *p2 = &game->players[1]; + + sprintf(buffer, "%s: %d - %s: %d", p1->name, p1->score, p2->name, p2->score); + set_text(game->score, buffer); + + p1->life = p2->life = 12; +} + +static const float reload_time = 2.0f; + +static void player_on_collision(struct Entity *this, struct Entity *other) +{ + struct Player *p = (struct Player *)this - offsetof(struct Player, entity); + + if(other->collidable && this->y <= other->y) + { + p->entity.i = 0; + p->on_ground = true; + this->d2y = 0.0f; + } + + if(!other->collidable) + { + struct Bullet *b = (struct Bullet *)other; + + if(b->owner == p) + return; + + p->life -= b->damage; + + int i; + + if(p->life > 8) + { + i = p->life - 8; + p->hearts[2]->src_rect.x = 16 * (4 - i); + p->hearts[1]->src_rect.x = 0; + p->hearts[0]->src_rect.x = 0; + + } + else if(p->life > 4) + { + i = p->life - 4; + p->hearts[2]->src_rect.x = 64; + p->hearts[1]->src_rect.x = 16 * (4 - i); + p->hearts[0]->src_rect.x = 0; + } + else + { + i = p->life; + p->hearts[2]->src_rect.x = 64; + p->hearts[1]->src_rect.x = 64; + p->hearts[0]->src_rect.x = 16 * (4 - i); + } + + if(p->life <= 0) + { + b->owner->score ++; + + p->hearts[2]->src_rect.x = 0; + p->hearts[1]->src_rect.x = 0; + p->hearts[0]->src_rect.x = 0; + + update_score(); + } + } +} + +void init_player(struct Player *p, struct PlayerKeys *keys, + float x, float y, const char *name) +{ + struct Entity *e; + p->keys = *keys; + e = &p->entity; + + e->texture = load_texture("resources/cowboy.png"); + e->use_src_rect = true; + e->src_rect.x = 0; + e->src_rect.y = 0; + e->src_rect.w = 43; + e->src_rect.h = 51; + + e->i = 0; + + e->x = x; + e->y = y; + + e->collidable = true; + e->w = 43; + e->h = 55; + e->on_collision = player_on_collision; + + p->reloading = false; + p->on_ground = false; + p->current_gun = REVOLVER; + p->life = 12; + p->counter = 0; + + p->guns[0] = (struct Gun) + { + .type = REVOLVER, + .angle = 0.0f, + .projectiles_per_shot = 1, + .cooldown = 0.5f, + .ready = true, + .sound_effect = game->revolver_sound, + .bullets = 6, + .max_bullets = 6, + .damage = 2, + }; + + p->guns[1] = (struct Gun) + { + .type = RIFLE, + .angle = 0.0f, + .projectiles_per_shot = 1, + .cooldown = 1.0f, + .ready = true, + .sound_effect = game->rifle_sound, + .bullets = 5, + .max_bullets = 5, + .damage = 3, + }; + + p->guns[2] = (struct Gun) + { + .type = SHOTGUN, + .angle = 5.0f, + .projectiles_per_shot = 5, + .cooldown = 2.0f, + .ready = true, + .sound_effect = game->rifle_sound, + .bullets = 2, + .max_bullets = 2, + .damage = 1, + }; + + if(strlen(name) > 16) + die("Player's name is too long: %s", name); + + strcpy(p->name, name); +} + +void update_player(struct Player *p) +{ + struct PlayerKeys *k = &p->keys; + struct Gun *g = &p->guns[p->current_gun]; + float dt = game->frame_time; + + // Movement related code + if(game->keys[k->left]) + { + p->entity.dx = -300.0f; + p->entity.mirror = true; + + p->counter ++; + + if(p->counter % 5 == 0 && p->on_ground) + { + p->entity.i ++; + p->entity.i %= 5; + } + } + else if(game->keys[k->right]) + { + p->entity.dx = 300.0f; + p->entity.mirror = false; + + p->counter ++; + + if(p->counter % 10 == 0 && p->on_ground) + { + p->entity.i ++; + p->entity.i %= 5; + } + } + else + { + p->counter = 0; + p->entity.d2x = -18.0f * p->entity.dx; + + if(p->on_ground) + { + p->entity.i = 0; + } + } + + if(p->entity.y < game->height - p->entity.h) + { + p->entity.d2y = game->gravity; + } + else + { + p->on_ground = true; + p->entity.d2y = 0; + p->entity.dy = 0; + p->entity.y = (game->height - p->entity.h); + + if(p->entity.i == 5) + p->entity.i = 0; + } + if(game->keys[k->jump] + && p->on_ground) + { + p->entity.dy = -700.0f; + p->on_ground = false; + p->entity.i = 5; + } + + p->entity.x += p->entity.dx * dt + (0.5f * p->entity.d2x * dt * dt); + p->entity.y += p->entity.dy * dt + (0.5f * p->entity.d2y * dt * dt); + + p->entity.dx += p->entity.d2x * dt; + p->entity.dy += p->entity.d2y * dt; + + if(p->entity.x + p->entity.w > game->width) + p->entity.x = game->width - p->entity.w; + else if(p->entity.x < 0) + p->entity.x = 0; + + if(p->entity.y < 0) + p->entity.y = 0; + + // Guns related code + if(game->keys[k->weaponds[0]]) + { + p->current_gun = REVOLVER; + p->reloading = false; + p->reload_time = 0.0f; + + p->gun->texture = game->guns[0]; + SDL_QueryTexture(game->guns[0], NULL, NULL, &p->gun->rect.w, &p->gun->rect.h); + p->gun->rect.w *= 2; + p->gun->rect.h *= 2; + } + else if(game->keys[k->weaponds[1]]) + { + p->current_gun = RIFLE; + p->reloading = false; + p->reload_time = 0.0f; + + p->gun->texture = game->guns[1]; + SDL_QueryTexture(game->guns[1], NULL, NULL, &p->gun->rect.w, &p->gun->rect.h); + p->gun->rect.w *= 2; + p->gun->rect.h *= 2; + } + else if(game->keys[k->weaponds[2]]) + { + p->current_gun = SHOTGUN; + p->reloading = false; + p->reload_time = 0.0f; + + p->gun->texture = game->guns[2]; + SDL_QueryTexture(game->guns[2], NULL, NULL, &p->gun->rect.w, &p->gun->rect.h); + p->gun->rect.w *= 2; + p->gun->rect.h *= 2; + } + + // Check & Update gun's cooldown + if(!g->ready) + { + g->cooldown_elapsed += game->frame_time; + + if(g->cooldown_elapsed >= g->cooldown) + g->ready = true; + } + + if(p->reload_time > 0) + p->reload_time -= game->frame_time; + if(p->reload_time < 0) + p->reload_time = 0.0f; + + if(p->reloading && p->reload_time == 0.0f) + { + g->bullets = g->max_bullets; + p->reloading = false; + } + + if(game->keys[k->fire]) + shoot_bullet(p); + + if(game->keys[k->reload]) + { + p->reloading = true; + p->reload_time = reload_time; + } + + p->entity.src_rect.x = p->entity.i * 43; + + // Add to game's entity list + game->entities[game->num_entities ++] = &p->entity; +} |
