aboutsummaryrefslogtreecommitdiff
path: root/player.c
diff options
context:
space:
mode:
Diffstat (limited to 'player.c')
-rw-r--r--player.c298
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;
+}