#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;
}