#include "game.h" #include 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; }