diff --git a/Game.cpp b/Game.cpp new file mode 100644 index 0000000..c2e8c72 --- /dev/null +++ b/Game.cpp @@ -0,0 +1,186 @@ +#include "Game.h" +#include "Helper.h" +#include +#include + +#define WINDOW_WIDTH 700 +#define WINDOW_HEIGHT 500 + +bool keys[4] = {false, false, false, false}; + +void Opponent::move(int timeMultiplier) { + if (this->x < this->targetX) this->x += timeMultiplier; + if (this->x > this->targetX) this->x -= timeMultiplier; + if (this->y < this->targetY) this->y += timeMultiplier; + if (this->y > this->targetY) this->y -= timeMultiplier; +} + +void Player::moveX(int dx) { + if (x + dx < 0 || x + dx > WINDOW_WIDTH - 80) return; + if (y < 40 && this->x + dx < 30 * 3 + 15) return; + x += dx; +} + +void Player::moveY(int dy) { + if (y + dy < 0 || y + dy > WINDOW_HEIGHT - 96) return; + if (y + dy < 40 && this->x < 30 * 3 + 15) return; + y += dy; +} + +void Game::checkCollision() { +for (int i = 0; i < opponents.size(); i++) { + Opponent o = opponents[i]; + if (o.x == o.targetX && o.y == o.targetY) { + opponents.erase(opponents.begin() + i); + } + if (player.x < o.x + 80 && player.x + 80 > o.x && player.y < o.y + 96 && player.y + 96 > o.y) { + player.health--; + opponents.erase(opponents.begin() + i); + } + } +} + +void Game::renderHUD(SDL_Renderer *renderer, SDL_Texture *heart) { + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_Rect bgRect; + bgRect.x = 0; + bgRect.y = 0; + bgRect.w = 30 * 3 + 15; + bgRect.h = 40; + SDL_RenderFillRect(renderer, &bgRect); + + for (int i = 0; i < this->player.health; i++) { + drawTexture(renderer, heart, 10 + i * 30, 10, 24, 24); + } +} + +void Game::renderPlayer(SDL_Renderer *renderer, SDL_Texture *player, Player p) { + drawTexture(renderer, player, p.x, p.y, 80, 96); +} + +void Game::createOpponent() { + Opponent o; + + int edge = rand() % 4; + switch (edge) { + case 0: + o.x = rand() % WINDOW_WIDTH; + o.y = -96; + o.targetY = WINDOW_HEIGHT + 96; + o.targetX = rand() % WINDOW_WIDTH; + break; + case 1: + o.x = rand() % WINDOW_WIDTH; + o.y = WINDOW_HEIGHT; + o.targetY = -96; + o.targetX = rand() % WINDOW_WIDTH; + break; + case 2: + o.x = -80; + o.y = rand() % WINDOW_HEIGHT; + o.targetX = WINDOW_WIDTH + 80; + o.targetY = rand() % WINDOW_HEIGHT; + break; + case 3: + o.x = WINDOW_WIDTH; + o.y = rand() % WINDOW_HEIGHT; + o.targetX = -80; + o.targetY = rand() % WINDOW_HEIGHT; + break; + } + + opponents.push_back(o); +} + + +void Game::renderOpponent(SDL_Renderer *renderer, SDL_Texture *opponent, Player p) { + drawTexture(renderer, opponent, p.x, p.y, 80, 96); +} + +void Game::render(SDL_Renderer *renderer, SDL_Texture *bg) { + SDL_RenderClear(renderer); + + SDL_SetRenderDrawColor(renderer, 35, 39, 42, SDL_ALPHA_OPAQUE); + + drawTexture(renderer, bg, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); + + SDL_Texture *player = IMG_LoadTexture(renderer, "./res/player.png"); + renderPlayer(renderer, player, this->player); + + SDL_Texture *opponent = IMG_LoadTexture(renderer, "./res/opponent.png"); + + for (Opponent o: this->opponents) { + renderOpponent(renderer, opponent, o); + } + + SDL_Texture *heart = IMG_LoadTexture(renderer, "./res/heart.png"); + renderHUD(renderer, heart); + + TTF_Init(); + TTF_Font *font = TTF_OpenFont("./res/Arial.ttf", 24); + + drawText(renderer, font, "Time: " + std::to_string(timeMultiplier), 30 * 3 + 15 + 10, 10, 100, 30); + + SDL_DestroyTexture(player); + SDL_DestroyTexture(opponent); + SDL_DestroyTexture(heart); + + SDL_RenderPresent(renderer); +} + +void Game::run() { + SDL_Window *window = SDL_CreateWindow("Obstacle Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN); + SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE); + + SDL_Texture *background = IMG_LoadTexture(renderer, "./res/background.png"); + + int startTime = time(nullptr); + + bool gameOpen = true; + while (gameOpen) { + SDL_Event event; + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) gameOpen = false; + + if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) { + bool isPressed = (event.type == SDL_KEYDOWN); + switch (event.key.keysym.sym) { + case SDLK_w: + keys[0] = isPressed; + break; + case SDLK_a: + keys[1] = isPressed; + break; + case SDLK_s: + keys[2] = isPressed; + break; + case SDLK_d: + break; + } + } + } + + if (keys[0]) player.moveY(-20); + if (keys[1]) player.moveX(-20); + if (keys[2]) player.moveY(20); + if (keys[3]) player.moveX(20); + + checkCollision(); + + if (rand() % 50 == 0) createOpponent(); + + for (int i = 0; i < opponents.size(); i++) { + opponents[i].move(timeMultiplier); + } + + timeMultiplier= (int) (time(nullptr) - startTime) / 10 + 1; + + render(renderer, background); + SDL_Delay(16); + } + + SDL_DestroyTexture(background); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); +} \ No newline at end of file diff --git a/Game.h b/Game.h new file mode 100644 index 0000000..16c1726 --- /dev/null +++ b/Game.h @@ -0,0 +1,44 @@ +#include +#include + +#ifndef CPP_LEARNING_GAME_H +#define CPP_LEARNING_GAME_H + +#include +#include + +class Player { +public: + int x = 40; + int y = 40; + int health = 3; + + void moveX(int dx); + void moveY(int dy); +}; + +class Opponent: public Player { + +public: + int targetX = 0; + int targetY = 0; + void move(int multiplier); +}; + +class Game { + Player player; + std::vector opponents; + int timeMultiplier = 1; + + void renderPlayer(SDL_Renderer *renderer, SDL_Texture *player, Player p); + void renderOpponent(SDL_Renderer *renderer, SDL_Texture *opponent, Player p); +public: + void createOpponent(); + void checkCollision(); + void renderHUD(SDL_Renderer *renderer, SDL_Texture *heart); + void render(SDL_Renderer *renderer, SDL_Texture *bg); + void run(); +}; + + +#endif \ No newline at end of file